Decompiled source of MoreMonsters v2.0.2

plugins/MoreMonsters.dll

Decompiled 33 minutes ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using Microsoft.CodeAnalysis;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("MoreMonsters")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+7f96bbc17733f661ae61317e555408d81bbe3f9e")]
[assembly: AssemblyProduct("MoreMonsters")]
[assembly: AssemblyTitle("MoreMonsters")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MoreMonsters
{
	internal sealed class MonsterDef
	{
		public byte Id;

		public string Name;

		public string Model;

		public bool Flies;

		public bool Ranged;

		public string Blurb;

		public string BaseEnemy;

		public float Chance;

		public float Health;

		public float Damage;

		public float Speed;

		public float Size;

		public int FirstWave;

		public bool InWaves = true;

		public ConfigEntry<bool> Enabled;

		public ConfigEntry<float> ChanceCfg;

		public ConfigEntry<float> HealthCfg;

		public ConfigEntry<float> DamageCfg;

		public ConfigEntry<float> SpeedCfg;

		public ConfigEntry<float> SizeCfg;

		public ConfigEntry<int> FirstWaveCfg;

		public ConfigEntry<string> BaseCfg;

		public bool On
		{
			get
			{
				if (Enabled != null)
				{
					return Enabled.Value;
				}
				return true;
			}
		}
	}
	internal static class Defs
	{
		internal static readonly List<MonsterDef> All = new List<MonsterDef>
		{
			new MonsterDef
			{
				Id = 1,
				Name = "Zanne",
				Model = "Big_Orc",
				Blurb = "A big green orc with a spiked club: tough, slow, hits hard, and little orcs jump out when she falls.",
				BaseEnemy = "Crabling",
				Chance = 5f,
				FirstWave = 2,
				Health = 6f,
				Damage = 1.5f,
				Speed = 0.75f,
				Size = 2.2f
			},
			new MonsterDef
			{
				Id = 2,
				Name = "ZanneSmall",
				Model = "Blob_Orc",
				InWaves = false,
				Blurb = "The little orcs that jump out of Zanne.",
				BaseEnemy = "Crabling",
				Chance = 0f,
				FirstWave = 1,
				Health = 1.5f,
				Damage = 1f,
				Speed = 1.25f,
				Size = 1.1f
			},
			new MonsterDef
			{
				Id = 3,
				Name = "Boomshroom",
				Model = "Blob_Mushnub_Evolved",
				Blurb = "A spiky mushroom that waddles up to you and explodes.",
				BaseEnemy = "ExplodingTick",
				Chance = 3f,
				FirstWave = 3,
				Health = 1.5f,
				Damage = 1.3f,
				Speed = 1f,
				Size = 1.4f
			},
			new MonsterDef
			{
				Id = 4,
				Name = "Cactoro",
				Model = "Big_Cactoro",
				Ranged = true,
				Blurb = "A cactus in a sombrero that keeps its distance and spits at you.",
				BaseEnemy = "Spitter",
				Chance = 3f,
				FirstWave = 4,
				Health = 2f,
				Damage = 1f,
				Speed = 1f,
				Size = 1.6f
			},
			new MonsterDef
			{
				Id = 5,
				Name = "Wraith",
				Model = "Flying_Ghost",
				Flies = true,
				Blurb = "A ghost: fast and fragile, flies straight at you.",
				BaseEnemy = "Crabling",
				Chance = 3f,
				FirstWave = 1,
				Health = 0.6f,
				Damage = 1f,
				Speed = 1.7f,
				Size = 1.3f
			},
			new MonsterDef
			{
				Id = 6,
				Name = "Prickles",
				Model = "Blob_GreenSpikyBlob",
				Blurb = "A spiky green blob: slow, very tough, and it hurts to touch.",
				BaseEnemy = "FleshCrab",
				Chance = 3f,
				FirstWave = 5,
				Health = 3f,
				Damage = 1.5f,
				Speed = 0.7f,
				Size = 1.5f
			},
			new MonsterDef
			{
				Id = 7,
				Name = "Buzz",
				Model = "Flying_Armabee_Evolved",
				Flies = true,
				Blurb = "An armoured bee that flies in from above.",
				BaseEnemy = "FlyingManta",
				Chance = 3f,
				FirstWave = 6,
				Health = 1.2f,
				Damage = 1f,
				Speed = 1.2f,
				Size = 1.2f
			},
			new MonsterDef
			{
				Id = 8,
				Name = "Yeti",
				Model = "Big_Yeti",
				Blurb = "A yeti: slow and very tough, punches hard.",
				BaseEnemy = "FleshCrab",
				Chance = 2f,
				FirstWave = 6,
				Health = 4f,
				Damage = 1.4f,
				Speed = 0.8f,
				Size = 2f
			},
			new MonsterDef
			{
				Id = 9,
				Name = "Demon",
				Model = "Big_Demon",
				Blurb = "A red demon with a trident.",
				BaseEnemy = "Crabling",
				Chance = 2f,
				FirstWave = 5,
				Health = 2.5f,
				Damage = 1.5f,
				Speed = 1.1f,
				Size = 1.7f
			},
			new MonsterDef
			{
				Id = 10,
				Name = "Dragon",
				Model = "Flying_Dragon_Evolved",
				Flies = true,
				Blurb = "A winged dragon: tough and hits hard.",
				BaseEnemy = "FlyingManta",
				Chance = 2f,
				FirstWave = 8,
				Health = 4f,
				Damage = 1.5f,
				Speed = 1f,
				Size = 1.8f
			},
			new MonsterDef
			{
				Id = 11,
				Name = "Ninja",
				Model = "Big_Ninja",
				Blurb = "A ninja: very fast, not very tough.",
				BaseEnemy = "Crabling",
				Chance = 2f,
				FirstWave = 4,
				Health = 1.2f,
				Damage = 1.2f,
				Speed = 1.6f,
				Size = 1.5f
			},
			new MonsterDef
			{
				Id = 12,
				Name = "MushroomKing",
				Model = "Big_MushroomKing",
				Blurb = "A rare giant: the Mushroom King and his mace. Huge health.",
				BaseEnemy = "FleshCrab",
				Chance = 0.5f,
				FirstWave = 10,
				Health = 15f,
				Damage = 2f,
				Speed = 0.7f,
				Size = 3f
			},
			new MonsterDef
			{
				Id = 13,
				Name = "Squidle",
				Model = "Flying_Squidle",
				Flies = true,
				Ranged = true,
				Blurb = "A horned flying imp that spits from a distance.",
				BaseEnemy = "Spitter",
				Chance = 2f,
				FirstWave = 7,
				Health = 1.5f,
				Damage = 1f,
				Speed = 1f,
				Size = 1.5f
			},
			new MonsterDef
			{
				Id = 14,
				Name = "Tribal",
				Model = "Big_Tribal",
				Blurb = "A masked warrior.",
				BaseEnemy = "Crabling",
				Chance = 2f,
				FirstWave = 9,
				Health = 3f,
				Damage = 1.5f,
				Speed = 1f,
				Size = 1.8f
			}
		};

		internal static MonsterDef ById(int id)
		{
			foreach (MonsterDef item in All)
			{
				if (item.Id == id)
				{
					return item;
				}
			}
			return null;
		}

		internal static MonsterDef ByName(string name)
		{
			foreach (MonsterDef item in All)
			{
				if (item.Name == name)
				{
					return item;
				}
			}
			return null;
		}

		internal static void Bind(ConfigFile cfg)
		{
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Expected O, but got Unknown
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Expected O, but got Unknown
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Expected O, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			foreach (MonsterDef item in All)
			{
				string name = item.Name;
				if (item.InWaves)
				{
					item.Enabled = cfg.Bind<bool>(name, "Enabled", true, item.Blurb + " (host)");
					item.ChanceCfg = cfg.Bind<float>(name, "ChancePercent", item.Chance, new ConfigDescription("Chance that a normal wave enemy is a " + name + " instead.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
					item.FirstWaveCfg = cfg.Bind<int>(name, "FirstWave", item.FirstWave, new ConfigDescription("First wave of a run a " + name + " can appear in.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), Array.Empty<object>()));
				}
				item.BaseCfg = cfg.Bind<string>(name, "BaseEnemy", item.BaseEnemy, "The game enemy a " + name + " is built on: its movement and attacks (an EnemyType name: Crabling, FleshCrab, Spitter, ExplodingTick, FlyingManta, Toad...).");
				item.HealthCfg = cfg.Bind<float>(name, "HealthMultiplier", item.Health, new ConfigDescription("Health compared to the enemy it's built on.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 100f), Array.Empty<object>()));
				item.DamageCfg = cfg.Bind<float>(name, "DamageMultiplier", item.Damage, new ConfigDescription("Touch damage compared to the enemy it's built on.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
				item.SpeedCfg = cfg.Bind<float>(name, "SpeedMultiplier", item.Speed, new ConfigDescription("Speed compared to the enemy it's built on.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>()));
				item.SizeCfg = cfg.Bind<float>(name, "Size", item.Size, new ConfigDescription("Size compared to the enemy it's built on.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 6f), Array.Empty<object>()));
			}
		}
	}
	internal static class HostConfig
	{
		private static ConfigFile cfg;

		private static string messageName;

		private static string[] personal;

		private static Dictionary<string, string> whenHostLacksMod;

		private static Func<bool> active;

		private static HandleNamedMessageDelegate handler;

		private static IntPtr registeredOn;

		private static float nextSend;

		private static float joinedAt;

		private static string lastSent;

		private static string lastApplied;

		private static bool overriding;

		private static bool heardFromHost;

		private static bool warnedMissing;

		private static bool savedFlag;

		private static bool savingPersonal;

		private static readonly Dictionary<ConfigEntryBase, string> originals = new Dictionary<ConfigEntryBase, string>();

		internal static bool FromHost
		{
			get
			{
				if (overriding)
				{
					return heardFromHost;
				}
				return false;
			}
		}

		internal static void Init(BasePlugin plugin, string guid, string[] personalKeys, Dictionary<string, string> offWithoutHost, Func<bool> isActive = null)
		{
			cfg = plugin.Config;
			messageName = guid + ".HostConfig";
			personal = personalKeys ?? Array.Empty<string>();
			whenHostLacksMod = offWithoutHost ?? new Dictionary<string, string>();
			active = isActive;
			cfg.SettingChanged += OnSettingChanged;
			plugin.AddComponent<HostConfigRunner>();
		}

		private static void OnSettingChanged(object sender, SettingChangedEventArgs e)
		{
			try
			{
				if (overriding && !savingPersonal && IsPersonal(e.ChangedSetting.Definition))
				{
					SavePersonal();
				}
			}
			catch
			{
			}
		}

		private static string Id(ConfigDefinition d)
		{
			return d.Section + "." + d.Key;
		}

		private static bool IsPersonal(ConfigDefinition d)
		{
			string[] array = personal;
			foreach (string text in array)
			{
				if (text.EndsWith(".*") ? (d.Section == text.Substring(0, text.Length - 2)) : (Id(d) == text))
				{
					return true;
				}
			}
			return false;
		}

		internal static void Tick()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			try
			{
				NetworkManager singleton = NetworkManager.Singleton;
				bool flag = (Object)(object)singleton != (Object)null && singleton.IsListening;
				if (!flag || singleton.IsServer || (active != null && !active()))
				{
					if (overriding)
					{
						Restore();
					}
					if (flag && singleton.IsServer)
					{
						HostTick(singleton);
					}
					if (!flag)
					{
						registeredOn = IntPtr.Zero;
					}
				}
				else
				{
					ClientTick(singleton);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag2 = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(15, 1, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Host settings: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogError(val);
			}
		}

		private static void HostTick(NetworkManager nm)
		{
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			if (Time.unscaledTime < nextSend || nm.CustomMessagingManager == null)
			{
				return;
			}
			nextSend = Time.unscaledTime + 1.5f;
			List<string> list = new List<string>();
			foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in cfg)
			{
				if (!IsPersonal(item.Key))
				{
					list.Add(item.Key.Section + "\u001f" + item.Key.Key + "\u001f" + item.Value.GetSerializedValue());
				}
			}
			string text = string.Join("\u001e", list);
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(text.Length * 2 + 64, (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe(text, false);
				nm.CustomMessagingManager.SendNamedMessageToAll(messageName, val, (NetworkDelivery)4);
			}
			finally
			{
				((FastBufferWriter)(ref val)).Dispose();
			}
			if (text != lastSent)
			{
				lastSent = text;
				Plugin.Log.LogInfo((object)"Sending this game's settings to all players.");
			}
		}

		private static void ClientTick(NetworkManager nm)
		{
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			CustomMessagingManager customMessagingManager = nm.CustomMessagingManager;
			if (customMessagingManager != null && registeredOn != ((Il2CppObjectBase)customMessagingManager).Pointer)
			{
				if (handler == null)
				{
					handler = DelegateSupport.ConvertDelegate<HandleNamedMessageDelegate>((Delegate)new Action<ulong, FastBufferReader>(OnReceived));
				}
				customMessagingManager.RegisterNamedMessageHandler(messageName, handler);
				registeredOn = ((Il2CppObjectBase)customMessagingManager).Pointer;
			}
			if (!overriding)
			{
				Begin();
				joinedAt = Time.unscaledTime;
				foreach (KeyValuePair<string, string> item in whenHostLacksMod)
				{
					Set(item.Key, item.Value);
				}
			}
			if (!heardFromHost && !warnedMissing && Time.unscaledTime - joinedAt > 15f)
			{
				warnedMissing = true;
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(88, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("No settings from the host: the host doesn't seem to have ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("MoreMonsters");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", so it stays off in this game.");
				}
				log.LogWarning(val);
			}
		}

		private static void OnReceived(ulong sender, FastBufferReader reader)
		{
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			bool flag = default(bool);
			try
			{
				string text = default(string);
				((FastBufferReader)(ref reader)).ReadValueSafe(ref text, false);
				if (!overriding)
				{
					Begin();
				}
				heardFromHost = true;
				if (text == lastApplied)
				{
					return;
				}
				lastApplied = text;
				int num = 0;
				string[] array = text.Split('\u001e');
				for (int i = 0; i < array.Length; i++)
				{
					string[] array2 = array[i].Split('\u001f');
					if (array2.Length == 3)
					{
						ConfigDefinition d = new ConfigDefinition(array2[0], array2[1]);
						if (!IsPersonal(d) && Set(Id(d), array2[2]))
						{
							num++;
						}
					}
				}
				ManualLogSource log = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(36, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Using the host's settings (");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" values).");
				}
				log.LogInfo(val);
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(25, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Host settings (receive): ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				log2.LogError(val2);
			}
		}

		private static void Begin()
		{
			overriding = true;
			heardFromHost = false;
			warnedMissing = false;
			lastApplied = null;
			savedFlag = cfg.SaveOnConfigSet;
			cfg.SaveOnConfigSet = false;
		}

		private static bool Set(string id, string value)
		{
			foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in cfg)
			{
				if (!(Id(item.Key) != id))
				{
					ConfigEntryBase value2 = item.Value;
					if (!originals.ContainsKey(value2))
					{
						originals[value2] = value2.GetSerializedValue();
					}
					if (value2.GetSerializedValue() != value)
					{
						value2.SetSerializedValue(value);
					}
					return true;
				}
			}
			return false;
		}

		private static void SavePersonal()
		{
			savingPersonal = true;
			Dictionary<ConfigEntryBase, string> dictionary = new Dictionary<ConfigEntryBase, string>();
			try
			{
				foreach (KeyValuePair<ConfigEntryBase, string> original in originals)
				{
					dictionary[original.Key] = original.Key.GetSerializedValue();
					original.Key.SetSerializedValue(original.Value);
				}
				cfg.Save();
			}
			finally
			{
				foreach (KeyValuePair<ConfigEntryBase, string> item in dictionary)
				{
					try
					{
						item.Key.SetSerializedValue(item.Value);
					}
					catch
					{
					}
				}
				savingPersonal = false;
			}
		}

		private static void Restore()
		{
			foreach (KeyValuePair<ConfigEntryBase, string> original in originals)
			{
				try
				{
					original.Key.SetSerializedValue(original.Value);
				}
				catch
				{
				}
			}
			originals.Clear();
			overriding = false;
			heardFromHost = false;
			lastApplied = null;
			cfg.SaveOnConfigSet = savedFlag;
			try
			{
				cfg.Save();
			}
			catch
			{
			}
			Plugin.Log.LogInfo((object)"Left the game; back to this computer's own settings.");
		}
	}
	public class HostConfigRunner : MonoBehaviour
	{
		public HostConfigRunner(IntPtr ptr)
			: base(ptr)
		{
		}

		private void Update()
		{
			HostConfig.Tick();
		}
	}
	[HarmonyPatch]
	internal static class Monsters
	{
		private const string MessageName = "girthy_mods.MoreMonsters.Marks";

		private static HandleNamedMessageDelegate handler;

		private static IntPtr registeredOn;

		private static MonsterDef pending;

		private static int pendingFrame;

		private static readonly Dictionary<ulong, MonsterDef> marked = new Dictionary<ulong, MonsterDef>();

		private static readonly HashSet<IntPtr> applied = new HashSet<IntPtr>();

		private static readonly Dictionary<ulong, (MonsterDef def, float until)> waiting = new Dictionary<ulong, (MonsterDef, float)>();

		private static readonly List<(Vector3 pos, int count)> splits = new List<(Vector3, int)>();

		private static readonly HashSet<string> missingBase = new HashSet<string>();

		private static readonly HashSet<string> seenThisRun = new HashSet<string>();

		private static float nextBroadcast;

		private static float nextLookup;

		private static int debugNext;

		private static bool IsHost
		{
			get
			{
				try
				{
					NetworkManager singleton = NetworkManager.Singleton;
					return (Object)(object)singleton == (Object)null || !singleton.IsListening || singleton.IsServer;
				}
				catch
				{
					return true;
				}
			}
		}

		[HarmonyPatch(typeof(EnemySpawner), "GetRandomEnemyForWave")]
		[HarmonyPostfix]
		private static void WavePick_Postfix(EnemySpawner __instance, ref NetworkObject __result)
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			try
			{
				if ((Object)(object)__result == (Object)null || !IsHost)
				{
					return;
				}
				int num = WaveNumber();
				float num2 = Random.value * 100f;
				foreach (MonsterDef item in Defs.All)
				{
					if (!item.InWaves || !item.On || num < item.FirstWaveCfg.Value)
					{
						continue;
					}
					num2 -= item.ChanceCfg.Value;
					if (!(num2 >= 0f))
					{
						NetworkObject val = BasePrefab(__instance, item);
						if (!((Object)(object)val == (Object)null))
						{
							__result = val;
							pending = item;
							pendingFrame = Time.frameCount;
						}
						break;
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(26, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("MoreMonsters (wave pick): ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				log.LogError(val2);
			}
		}

		[HarmonyPatch(typeof(EnemySpawner), "SpawnEnemy")]
		[HarmonyPrefix]
		private static void SpawnEnemy_Prefix()
		{
			if (pending != null && pendingFrame != Time.frameCount)
			{
				pending = null;
			}
		}

		[HarmonyPatch(typeof(EnemyHealthContainer), "CalculateMaxHealth")]
		[HarmonyPostfix]
		private static void MaxHealth_Postfix(ref float __result)
		{
			if (pending != null)
			{
				__result *= pending.HealthCfg.Value;
			}
		}

		[HarmonyPatch(typeof(EnemySpawner), "SpawnEnemy")]
		[HarmonyPostfix]
		private static void SpawnEnemy_Postfix(NetworkObject __result)
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			MonsterDef monsterDef = pending;
			pending = null;
			if (monsterDef == null || (Object)(object)__result == (Object)null)
			{
				return;
			}
			bool flag = default(bool);
			try
			{
				marked[__result.NetworkObjectId] = monsterDef;
				Enemy component = ((Component)__result).GetComponent<Enemy>();
				if ((Object)(object)component != (Object)null)
				{
					SetSpeed(component, monsterDef.SpeedCfg.Value);
					Apply(component, monsterDef);
				}
				nextBroadcast = 0f;
				if (monsterDef.InWaves && seenThisRun.Add(monsterDef.Name))
				{
					ManualLogSource log = Plugin.Log;
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(32, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("First ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(monsterDef.Name);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" of this run has appeared.");
					}
					log.LogInfo(val);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(28, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("MoreMonsters (after spawn): ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				log2.LogError(val2);
			}
		}

		private static NetworkObject BasePrefab(EnemySpawner s, MonsterDef d)
		{
			//IL_0022: 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_005a: Expected O, but got Unknown
			Dictionary<EnemyType, NetworkObject> enemyTypeToPrefab = s.enemyTypeToPrefab;
			if (enemyTypeToPrefab == null)
			{
				return null;
			}
			NetworkObject val = default(NetworkObject);
			if (Enum.TryParse<EnemyType>(d.BaseCfg.Value, ignoreCase: true, out EnemyType result) && enemyTypeToPrefab.TryGetValue(result, ref val) && (Object)(object)val != (Object)null)
			{
				return val;
			}
			if (missingBase.Add(d.Name))
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(53, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(d.Name);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": no '");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(d.BaseCfg.Value);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' enemy in this game; using a Crabling instead.");
				}
				log.LogWarning(val2);
			}
			NetworkObject result2 = default(NetworkObject);
			if (!enemyTypeToPrefab.TryGetValue((EnemyType)0, ref result2))
			{
				return null;
			}
			return result2;
		}

		private static void SetSpeed(Enemy e, float mult)
		{
			if (Mathf.Approximately(mult, 1f))
			{
				return;
			}
			try
			{
				NavMeshEnemyNavigator componentInChildren = ((Component)e).GetComponentInChildren<NavMeshEnemyNavigator>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.baseSpeed *= mult;
				}
			}
			catch
			{
			}
			try
			{
				NavMeshAgent componentInChildren2 = ((Component)e).GetComponentInChildren<NavMeshAgent>();
				if ((Object)(object)componentInChildren2 != (Object)null)
				{
					componentInChildren2.speed *= mult;
				}
			}
			catch
			{
			}
		}

		private static int WaveNumber()
		{
			try
			{
				RunManager val = Object.FindObjectOfType<RunManager>();
				return (((val != null) ? val.CurrentWave : null) != null) ? (val.CurrentWave.Value + 1) : 0;
			}
			catch
			{
				return 0;
			}
		}

		[HarmonyPatch(typeof(EnemyHealthContainer), "SetHealthDepletedOnOwner")]
		[HarmonyPostfix]
		private static void Depleted_Postfix(EnemyHealthContainer __instance)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!IsHost)
				{
					return;
				}
				NetworkObject componentInParent = ((Component)__instance).GetComponentInParent<NetworkObject>();
				if (!((Object)(object)componentInParent == (Object)null) && marked.TryGetValue(componentInParent.NetworkObjectId, out var value))
				{
					marked.Remove(componentInParent.NetworkObjectId);
					if (value.Name == "Zanne" && Plugin.ZanneSplits.Value > 0)
					{
						splits.Add((((Component)componentInParent).transform.position, Plugin.ZanneSplits.Value));
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(22, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("MoreMonsters (death): ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogError(val);
			}
		}

		private static void SpawnSplits()
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			if (splits.Count == 0)
			{
				return;
			}
			MonsterDef monsterDef = Defs.ByName("ZanneSmall");
			EnemySpawner val = Spawner();
			NetworkObject val2 = (((Object)(object)val != (Object)null && monsterDef != null) ? BasePrefab(val, monsterDef) : null);
			List<(Vector3, int)> list = new List<(Vector3, int)>(splits);
			splits.Clear();
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			foreach (var item3 in list)
			{
				Vector3 item = item3.Item1;
				int item2 = item3.Item2;
				for (int i = 0; i < item2; i++)
				{
					float num = ((float)i + Random.value * 0.5f) / (float)item2 * (float)Math.PI * 2f;
					SpawnOne(val, val2, item + new Vector3(Mathf.Cos(num), 0f, Mathf.Sin(num)) * 1.6f, monsterDef);
				}
			}
		}

		private static void SpawnOne(EnemySpawner s, NetworkObject prefab, Vector3 at, MonsterDef def)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			pending = def;
			pendingFrame = Time.frameCount;
			try
			{
				s.SpawnEnemy(prefab, at, (EnemySpawnRotation)0);
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(23, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("MoreMonsters (spawn ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(def.Name);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("): ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogError(val);
			}
			finally
			{
				pending = null;
			}
		}

		private static EnemySpawner Spawner()
		{
			try
			{
				return Object.FindObjectOfType<EnemySpawner>();
			}
			catch
			{
				return null;
			}
		}

		private static void SpawnKey()
		{
			//IL_001e: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: 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)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Expected O, but got Unknown
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			string value = Plugin.SpawnKey.Value;
			if (string.IsNullOrEmpty(value) || !Enum.TryParse<Key>(value, ignoreCase: true, out Key result) || (int)result == 0)
			{
				return;
			}
			Keyboard current = Keyboard.current;
			KeyControl val = ((current != null) ? current[result] : null);
			if (val == null || !((ButtonControl)val).wasPressedThisFrame)
			{
				return;
			}
			List<MonsterDef> list = Defs.All.FindAll((MonsterDef d) => d.InWaves);
			if (list.Count == 0)
			{
				return;
			}
			MonsterDef monsterDef = list[debugNext++ % list.Count];
			EnemySpawner val2 = Spawner();
			NetworkObject val3 = (((Object)(object)val2 != (Object)null) ? BasePrefab(val2, monsterDef) : null);
			if ((Object)(object)val3 == (Object)null)
			{
				Plugin.Log.LogWarning((object)"MoreMonsters: no run (or no enemy to build on) right now.");
				return;
			}
			Vector3 val4 = Vector3.zero;
			foreach (GameplayPlayer item in Object.FindObjectsOfType<GameplayPlayer>())
			{
				if ((Object)(object)item != (Object)null && ((NetworkBehaviour)item).IsOwner)
				{
					val4 = ((Component)item).transform.position;
					break;
				}
			}
			Vector2 insideUnitCircle = Random.insideUnitCircle;
			Vector2 val5 = ((Vector2)(ref insideUnitCircle)).normalized * 7f;
			SpawnOne(val2, val3, val4 + new Vector3(val5.x, 0f, val5.y), monsterDef);
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val6 = new BepInExInfoLogInterpolatedStringHandler(23, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("Spawned a ");
				((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<string>(monsterDef.Name);
				((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(" (debug key).");
			}
			log.LogInfo(val6);
		}

		private static void Apply(Enemy e, MonsterDef def)
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)e == (Object)null || def == null || !applied.Add(((Il2CppObjectBase)e).Pointer))
			{
				return;
			}
			try
			{
				Transform transform = ((Component)e).transform;
				transform.localScale *= def.SizeCfg.Value;
			}
			catch
			{
			}
			if (!Mathf.Approximately(def.DamageCfg.Value, 1f))
			{
				try
				{
					e.contactDamage *= def.DamageCfg.Value;
					e.SetDamageInfo();
				}
				catch (Exception ex)
				{
					ManualLogSource log = Plugin.Log;
					bool flag = default(bool);
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(11, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(def.Name);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (damage): ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
					}
					log.LogWarning(val);
				}
			}
			Visuals.Attach(e, def);
		}

		[HarmonyPatch(typeof(EnemyHealthContainer), "PerformHitFeedback")]
		[HarmonyPostfix]
		private static void Hit_Postfix(EnemyHealthContainer __instance)
		{
			try
			{
				Enemy componentInParent = ((Component)__instance).GetComponentInParent<Enemy>();
				if ((Object)(object)componentInParent != (Object)null && Visuals.Has(componentInParent))
				{
					Visuals.Hit(componentInParent);
				}
			}
			catch
			{
			}
		}

		[HarmonyPatch(typeof(EnemyHealthContainer), "HealthDepleted")]
		[HarmonyPostfix]
		private static void Died_Postfix(EnemyHealthContainer __instance)
		{
			try
			{
				Enemy componentInParent = ((Component)__instance).GetComponentInParent<Enemy>();
				if ((Object)(object)componentInParent != (Object)null && Visuals.Has(componentInParent))
				{
					Visuals.Died(componentInParent);
				}
			}
			catch
			{
			}
		}

		[HarmonyPatch(typeof(RunManager), "OnDestroy")]
		[HarmonyPostfix]
		private static void RunEnded()
		{
			marked.Clear();
			applied.Clear();
			waiting.Clear();
			splits.Clear();
			missingBase.Clear();
			seenThisRun.Clear();
			Visuals.Clear();
		}

		internal static void Tick()
		{
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Expected O, but got Unknown
			try
			{
				NetworkManager singleton = NetworkManager.Singleton;
				bool flag = (Object)(object)singleton != (Object)null && singleton.IsListening;
				if (flag && singleton.CustomMessagingManager != null && registeredOn != ((Il2CppObjectBase)singleton.CustomMessagingManager).Pointer)
				{
					if (handler == null)
					{
						handler = DelegateSupport.ConvertDelegate<HandleNamedMessageDelegate>((Delegate)new Action<ulong, FastBufferReader>(OnMessage));
					}
					singleton.CustomMessagingManager.RegisterNamedMessageHandler("girthy_mods.MoreMonsters.Marks", handler);
					registeredOn = ((Il2CppObjectBase)singleton.CustomMessagingManager).Pointer;
				}
				if (!flag)
				{
					registeredOn = IntPtr.Zero;
				}
				if (IsHost)
				{
					SpawnSplits();
					SpawnKey();
					if (flag && Time.unscaledTime >= nextBroadcast)
					{
						nextBroadcast = Time.unscaledTime + 2f;
						Broadcast(singleton);
					}
				}
				else if (waiting.Count > 0 && Time.unscaledTime >= nextLookup)
				{
					nextLookup = Time.unscaledTime + 0.1f;
					Resolve(singleton);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag2 = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(14, 1, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("MoreMonsters: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogError(val);
			}
			try
			{
				Visuals.Tick();
			}
			catch
			{
			}
		}

		private static void Broadcast(NetworkManager nm)
		{
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			if (nm.CustomMessagingManager == null)
			{
				return;
			}
			NetworkSpawnManager spawnManager = nm.SpawnManager;
			Dictionary<ulong, NetworkObject> val = ((spawnManager != null) ? spawnManager.SpawnedObjects : null);
			if (val != null)
			{
				List<ulong> list = new List<ulong>();
				foreach (ulong key in marked.Keys)
				{
					if (!val.ContainsKey(key))
					{
						list.Add(key);
					}
				}
				foreach (ulong item in list)
				{
					marked.Remove(item);
				}
			}
			if (marked.Count == 0)
			{
				return;
			}
			StringBuilder stringBuilder = new StringBuilder();
			foreach (KeyValuePair<ulong, MonsterDef> item2 in marked)
			{
				if (stringBuilder.Length > 0)
				{
					stringBuilder.Append(',');
				}
				stringBuilder.Append(item2.Key.ToString(CultureInfo.InvariantCulture)).Append(':').Append(item2.Value.Id);
			}
			string text = stringBuilder.ToString();
			FastBufferWriter val2 = default(FastBufferWriter);
			((FastBufferWriter)(ref val2))..ctor(text.Length * 2 + 64, (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val2)).WriteValueSafe(text, false);
				nm.CustomMessagingManager.SendNamedMessageToAll("girthy_mods.MoreMonsters.Marks", val2, (NetworkDelivery)4);
			}
			finally
			{
				((FastBufferWriter)(ref val2)).Dispose();
			}
		}

		private static void OnMessage(ulong sender, FastBufferReader reader)
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			try
			{
				string text = default(string);
				((FastBufferReader)(ref reader)).ReadValueSafe(ref text, false);
				float item = Time.unscaledTime + 10f;
				string[] array = text.Split(',');
				foreach (string text2 in array)
				{
					int num = text2.IndexOf(':');
					if (num > 0 && ulong.TryParse(text2.Substring(0, num), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) && int.TryParse(text2.Substring(num + 1), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2))
					{
						MonsterDef monsterDef = Defs.ById(result2);
						if (monsterDef != null && !waiting.ContainsKey(result))
						{
							waiting[result] = (monsterDef, item);
						}
					}
				}
				Resolve(NetworkManager.Singleton);
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(24, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("MoreMonsters (receive): ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogError(val);
			}
		}

		private static void Resolve(NetworkManager nm)
		{
			object obj;
			if (nm == null)
			{
				obj = null;
			}
			else
			{
				NetworkSpawnManager spawnManager = nm.SpawnManager;
				obj = ((spawnManager != null) ? spawnManager.SpawnedObjects : null);
			}
			Dictionary<ulong, NetworkObject> val = (Dictionary<ulong, NetworkObject>)obj;
			if (val == null)
			{
				return;
			}
			List<ulong> list = new List<ulong>();
			NetworkObject val2 = default(NetworkObject);
			foreach (KeyValuePair<ulong, (MonsterDef, float)> item in waiting)
			{
				if (val.TryGetValue(item.Key, ref val2) && (Object)(object)val2 != (Object)null)
				{
					Enemy component = ((Component)val2).GetComponent<Enemy>();
					if ((Object)(object)component != (Object)null)
					{
						Apply(component, item.Value.Item1);
					}
					list.Add(item.Key);
				}
				else if (Time.unscaledTime > item.Value.Item2)
				{
					list.Add(item.Key);
				}
			}
			foreach (ulong item2 in list)
			{
				waiting.Remove(item2);
			}
		}
	}
	public class Runner : MonoBehaviour
	{
		public Runner(IntPtr ptr)
			: base(ptr)
		{
		}

		private void Update()
		{
			Monsters.Tick();
		}
	}
	[BepInPlugin("girthy_mods.MoreMonsters", "MoreMonsters", "2.0.2")]
	public class Plugin : BasePlugin
	{
		public const string Guid = "girthy_mods.MoreMonsters";

		public const string Name = "MoreMonsters";

		public const string Version = "2.0.2";

		internal static ManualLogSource Log;

		internal static ConfigEntry<int> ZanneSplits;

		internal static ConfigEntry<string> SpawnKey;

		public override void Load()
		{
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Expected O, but got Unknown
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Expected O, but got Unknown
			Log = ((BasePlugin)this).Log;
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			foreach (MonsterDef item in Defs.All)
			{
				if (item.InWaves)
				{
					dictionary[item.Name + ".Enabled"] = "false";
				}
			}
			HostConfig.Init((BasePlugin)(object)this, "girthy_mods.MoreMonsters", new string[1] { "Debug.SpawnKey" }, dictionary);
			Defs.Bind(((BasePlugin)this).Config);
			ZanneSplits = ((BasePlugin)this).Config.Bind<int>("Zanne", "SplitsInto", 3, new ConfigDescription("Small Zannes that pop out when she dies (0 = none). Their stats are under [ZanneSmall].", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 8), Array.Empty<object>()));
			SpawnKey = ((BasePlugin)this).Config.Bind<string>("Debug", "SpawnKey", "F2", "Host: key that spawns a monster near you to try it out; each press brings the next kind (Unity Input System key name). Empty = no key.");
			int num = Visuals.LoadAll();
			ManualLogSource log = Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(22, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Loaded ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" monster looks.");
			}
			log.LogInfo(val);
			new Harmony("girthy_mods.MoreMonsters").PatchAll(typeof(Monsters));
			((BasePlugin)this).AddComponent<Runner>();
			ManualLogSource log2 = Log;
			val = new BepInExInfoLogInterpolatedStringHandler(8, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("MoreMonsters");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("2.0.2");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ready.");
			}
			log2.LogInfo(val);
		}
	}
	internal static class Visuals
	{
		private sealed class Clip
		{
			public string Name;

			public float Fps;

			public int Frames;

			public int Bones;

			public float[] Data;

			public float Length => Mathf.Max(0.01f, (float)(Frames - 1) / Fps);
		}

		private sealed class Model
		{
			public string Name;

			public Mesh Mesh;

			public int Bones;

			public Material Mat;

			public Clip Idle;

			public Clip Walk;

			public Clip Run;

			public Clip Attack;

			public Clip Hit;

			public Clip Death;

			public float AttackHit;
		}

		private enum Act
		{
			Idle,
			Walk,
			Run,
			Attack,
			Hit,
			Death
		}

		private sealed class View
		{
			public MonsterDef Def;

			public Model Model;

			public Enemy Enemy;

			public Transform Root;

			public Transform Visuals;

			public Transform T;

			public GameObject Go;

			public SkinnedMeshRenderer Renderer;

			public Transform[] Bones;

			public Vector3[] LastScale;

			public readonly List<Renderer> Hidden = new List<Renderer>();

			public float Width = 1f;

			public float Lift;

			public float Speed;

			public float SpawnedAt;

			public float FlashUntil;

			public float NextHide;

			public float NextAttack;

			public float NextHit;

			public float DiedAt = -1f;

			public Vector3 LastPos;

			public Quaternion Facing = Quaternion.identity;

			public bool Detached;

			public Act Act;

			public Clip Cur;

			public Clip Prev;

			public float CurT;

			public float PrevT;

			public float FadeStart = -9f;

			public float FadeLen = 0.15f;

			public float Rate = 1f;

			public bool OneShot;

			public int Slot;

			public int Posed;

			public float[] PoseA;

			public float[] PoseB;
		}

		private static readonly Dictionary<string, Model> models = new Dictionary<string, Model>();

		private static Texture2D atlas;

		private static Texture2D white;

		private static Material flash;

		private static Shader shader;

		private static bool shaderSearched;

		private static readonly string[] ShaderNames = new string[6] { "Universal Render Pipeline/Lit", "Universal Render Pipeline/Simple Lit", "Universal Render Pipeline/Baked Lit", "Universal Render Pipeline/Unlit", "Standard", "Unlit/Texture" };

		private static readonly Dictionary<IntPtr, View> views = new Dictionary<IntPtr, View>();

		private static int Busy;

		private static int nextSlot;

		private static readonly List<View> corpses = new List<View>();

		private static readonly HashSet<string> loggedLook = new HashSet<string>();

		private static readonly List<Transform> players = new List<Transform>();

		private static float nextPlayerScan;

		private static int frameNo;

		internal static int LoadAll()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Expected O, but got Unknown
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			white = MakeTexture(1, 1, (Color32[])(object)new Color32[1]
			{
				new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue)
			}, (FilterMode)0);
			atlas = LoadTexture("Atlas");
			if ((Object)(object)atlas == (Object)null)
			{
				Plugin.Log.LogError((object)"The monsters' colour atlas is missing.");
			}
			int num = 0;
			bool flag = default(bool);
			foreach (MonsterDef item in Defs.All)
			{
				if (models.ContainsKey(item.Model))
				{
					continue;
				}
				try
				{
					Model model = Load(item.Model);
					if (model == null)
					{
						ManualLogSource log = Plugin.Log;
						BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(17, 2, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(item.Name);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": model ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(item.Model);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" missing.");
						}
						log.LogError(val);
					}
					else
					{
						models[item.Model] = model;
						num++;
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log2 = Plugin.Log;
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(10, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(item.Name);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'s model: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
					}
					log2.LogError(val);
				}
			}
			return num;
		}

		private static Stream Resource(string name)
		{
			return typeof(Visuals).Assembly.GetManifestResourceStream("MoreMonsters." + name);
		}

		private static string ReadName(BinaryReader r)
		{
			int count = r.ReadUInt16();
			return Encoding.UTF8.GetString(r.ReadBytes(count));
		}

		private static Model Load(string name)
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d8: Expected O, but got Unknown
			//IL_0642: Unknown result type (might be due to invalid IL or missing references)
			//IL_0649: Expected O, but got Unknown
			using Stream stream = Resource(name + ".mon");
			if (stream == null)
			{
				return null;
			}
			using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress);
			using MemoryStream memoryStream = new MemoryStream();
			gZipStream.CopyTo(memoryStream);
			memoryStream.Position = 0L;
			using BinaryReader binaryReader = new BinaryReader(memoryStream);
			if (new string(binaryReader.ReadChars(4)) != "MON1")
			{
				throw new InvalidDataException("not a monster file");
			}
			int num = binaryReader.ReadInt32();
			int num2 = binaryReader.ReadInt32();
			int num3 = binaryReader.ReadInt32();
			int num4 = binaryReader.ReadInt32();
			Il2CppStructArray<Vector3> val = new Il2CppStructArray<Vector3>((long)num);
			Il2CppStructArray<Vector3> val2 = new Il2CppStructArray<Vector3>((long)num);
			Il2CppStructArray<Vector2> val3 = new Il2CppStructArray<Vector2>((long)num);
			Il2CppStructArray<BoneWeight> val4 = new Il2CppStructArray<BoneWeight>((long)num);
			for (int i = 0; i < num; i++)
			{
				((Il2CppArrayBase<Vector3>)(object)val)[i] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				((Il2CppArrayBase<Vector3>)(object)val2)[i] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				((Il2CppArrayBase<Vector2>)(object)val3)[i] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle());
				byte boneIndex = binaryReader.ReadByte();
				byte boneIndex2 = binaryReader.ReadByte();
				byte boneIndex3 = binaryReader.ReadByte();
				byte boneIndex4 = binaryReader.ReadByte();
				int num5 = i;
				BoneWeight val5 = default(BoneWeight);
				((BoneWeight)(ref val5)).boneIndex0 = boneIndex;
				((BoneWeight)(ref val5)).boneIndex1 = boneIndex2;
				((BoneWeight)(ref val5)).boneIndex2 = boneIndex3;
				((BoneWeight)(ref val5)).boneIndex3 = boneIndex4;
				((BoneWeight)(ref val5)).weight0 = binaryReader.ReadSingle();
				((BoneWeight)(ref val5)).weight1 = binaryReader.ReadSingle();
				((BoneWeight)(ref val5)).weight2 = binaryReader.ReadSingle();
				((BoneWeight)(ref val5)).weight3 = binaryReader.ReadSingle();
				((Il2CppArrayBase<BoneWeight>)(object)val4)[num5] = val5;
			}
			Il2CppStructArray<int> val6 = new Il2CppStructArray<int>((long)(num2 * 3));
			for (int j = 0; j < num2 * 3; j++)
			{
				((Il2CppArrayBase<int>)(object)val6)[j] = binaryReader.ReadInt32();
			}
			Il2CppStructArray<Matrix4x4> val7 = new Il2CppStructArray<Matrix4x4>((long)num3);
			for (int k = 0; k < num3; k++)
			{
				ReadName(binaryReader);
				Vector4[] array = (Vector4[])(object)new Vector4[4];
				for (int l = 0; l < 4; l++)
				{
					array[l] = new Vector4(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				}
				((Il2CppArrayBase<Matrix4x4>)(object)val7)[k] = new Matrix4x4(array[0], array[1], array[2], array[3]);
			}
			Model model = new Model
			{
				Name = name,
				Bones = num3
			};
			Model model2;
			for (int m = 0; m < num4; m++)
			{
				Clip clip = new Clip
				{
					Name = ReadName(binaryReader),
					Fps = binaryReader.ReadSingle(),
					Frames = binaryReader.ReadInt32(),
					Bones = num3
				};
				clip.Data = new float[clip.Frames * num3 * 10];
				for (int n = 0; n < clip.Data.Length; n++)
				{
					clip.Data[n] = binaryReader.ReadSingle();
				}
				switch (clip.Name)
				{
				case "Idle":
				case "Flying_Idle":
					model2 = model;
					if (model2.Idle == null)
					{
						model2.Idle = clip;
					}
					break;
				case "Walk":
					model.Walk = clip;
					break;
				case "Fast_Flying":
				case "Run":
					model.Run = clip;
					break;
				case "Punch":
				case "Bite_Front":
				case "Headbutt":
				case "Weapon":
				case "Bite_InPlace":
					model2 = model;
					if (model2.Attack == null)
					{
						model2.Attack = clip;
					}
					break;
				case "HitRecieve":
				case "HitReact":
					model.Hit = clip;
					break;
				case "Death":
					model.Death = clip;
					break;
				}
			}
			model2 = model;
			if (model2.Walk == null)
			{
				model2.Walk = model.Run ?? model.Idle;
			}
			model2 = model;
			if (model2.Run == null)
			{
				model2.Run = model.Walk;
			}
			model2 = model;
			if (model2.Idle == null)
			{
				model2.Idle = model.Walk;
			}
			model.AttackHit = 0.45f;
			Mesh val8 = new Mesh
			{
				name = "MoreMonsters." + name
			};
			if (num > 65000)
			{
				val8.indexFormat = (IndexFormat)1;
			}
			val8.vertices = val;
			val8.normals = val2;
			val8.uv = val3;
			val8.triangles = val6;
			val8.boneWeights = val4;
			val8.bindposes = val7;
			val8.RecalculateBounds();
			((Object)val8).hideFlags = (HideFlags)61;
			model.Mesh = val8;
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val9 = new BepInExInfoLogInterpolatedStringHandler(34, 4, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val9).AppendFormatted<string>(name);
				((BepInExLogInterpolatedStringHandler)val9).AppendLiteral(": ");
				((BepInExLogInterpolatedStringHandler)val9).AppendFormatted<int>(num2);
				((BepInExLogInterpolatedStringHandler)val9).AppendLiteral(" triangles, ");
				((BepInExLogInterpolatedStringHandler)val9).AppendFormatted<int>(num3);
				((BepInExLogInterpolatedStringHandler)val9).AppendLiteral(" bones, ");
				((BepInExLogInterpolatedStringHandler)val9).AppendFormatted<int>(num4);
				((BepInExLogInterpolatedStringHandler)val9).AppendLiteral(" animations.");
			}
			log.LogInfo(val9);
			return model;
		}

		private static Texture2D LoadTexture(string name)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			using Stream stream = Resource(name + ".tex");
			if (stream == null)
			{
				return null;
			}
			using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress);
			using MemoryStream memoryStream = new MemoryStream();
			gZipStream.CopyTo(memoryStream);
			byte[] array = memoryStream.ToArray();
			int num = BitConverter.ToInt32(array, 0);
			int num2 = BitConverter.ToInt32(array, 4);
			Texture2D val = new Texture2D(num, num2, (TextureFormat)4, false);
			Il2CppStructArray<byte> val2 = new Il2CppStructArray<byte>((long)(num * num2 * 4));
			for (int i = 0; i < ((Il2CppArrayBase<byte>)(object)val2).Length; i++)
			{
				((Il2CppArrayBase<byte>)(object)val2)[i] = array[8 + i];
			}
			val.LoadRawTextureData(val2);
			val.Apply(false, false);
			((Texture)val).filterMode = (FilterMode)1;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			((Object)val).hideFlags = (HideFlags)61;
			return val;
		}

		private static Texture2D MakeTexture(int tw, int th, Color32[] px, FilterMode filter)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			Texture2D val = new Texture2D(tw, th, (TextureFormat)4, false);
			val.SetPixels32(new Il2CppStructArray<Color32>(px));
			val.Apply();
			((Texture)val).filterMode = filter;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			((Object)val).hideFlags = (HideFlags)61;
			return val;
		}

		private static Shader FindShader()
		{
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Expected O, but got Unknown
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Expected O, but got Unknown
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Expected O, but got Unknown
			if (shaderSearched)
			{
				return shader;
			}
			shaderSearched = true;
			bool flag = default(bool);
			try
			{
				Il2CppArrayBase<Shader> val = Resources.FindObjectsOfTypeAll<Shader>();
				Dictionary<string, Shader> dictionary = new Dictionary<string, Shader>();
				for (int i = 0; i < val.Length; i++)
				{
					Shader val2 = val[i];
					if (!((Object)(object)val2 == (Object)null))
					{
						string name = ((Object)val2).name;
						if (!string.IsNullOrEmpty(name) && !dictionary.ContainsKey(name))
						{
							dictionary[name] = val2;
						}
					}
				}
				string[] shaderNames = ShaderNames;
				foreach (string key in shaderNames)
				{
					if (dictionary.TryGetValue(key, out var value) && value.isSupported)
					{
						shader = value;
						break;
					}
				}
				if ((Object)(object)shader == (Object)null)
				{
					List<string> list = new List<string>();
					foreach (string key2 in dictionary.Keys)
					{
						if (list.Count < 40)
						{
							list.Add(key2);
						}
					}
					ManualLogSource log = Plugin.Log;
					BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(43, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("No plain lit shader found. Shaders loaded: ");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(string.Join(", ", list));
					}
					log.LogWarning(val3);
				}
				else
				{
					ManualLogSource log2 = Plugin.Log;
					BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(17, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("Monster shader: ");
						((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(((Object)shader).name);
						((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(".");
					}
					log2.LogInfo(val4);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log3 = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val5 = new BepInExErrorLogInterpolatedStringHandler(18, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("Finding a shader: ");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(ex.Message);
				}
				log3.LogError(val5);
			}
			return shader;
		}

		private static Material MakeMaterial(Texture2D t)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			Shader val = FindShader();
			Material val2 = null;
			try
			{
				if ((Object)(object)val != (Object)null)
				{
					val2 = new Material(val);
				}
			}
			catch
			{
			}
			if ((Object)(object)val2 == (Object)null)
			{
				return null;
			}
			try
			{
				val2.mainTexture = (Texture)(object)t;
			}
			catch
			{
			}
			try
			{
				val2.color = Color.white;
			}
			catch
			{
			}
			try
			{
				val2.SetFloat("_Smoothness", 0.12f);
			}
			catch
			{
			}
			try
			{
				val2.SetFloat("_Metallic", 0f);
			}
			catch
			{
			}
			((Object)val2).hideFlags = (HideFlags)61;
			return val2;
		}

		private static Material MaterialFor(Model m)
		{
			if ((Object)(object)m.Mat == (Object)null || ((Il2CppObjectBase)m.Mat).WasCollected)
			{
				m.Mat = MakeMaterial(atlas ?? white);
			}
			return m.Mat;
		}

		private static Material Flash()
		{
			if ((Object)(object)flash == (Object)null || ((Il2CppObjectBase)flash).WasCollected)
			{
				flash = MakeMaterial(white);
			}
			return flash;
		}

		internal static bool Has(Enemy e)
		{
			if ((Object)(object)e != (Object)null)
			{
				return views.ContainsKey(((Il2CppObjectBase)e).Pointer);
			}
			return false;
		}

		internal static void Attach(Enemy e, MonsterDef def)
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_046c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0473: Expected O, but got Unknown
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Expected O, but got Unknown
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0390: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)e == (Object)null || def == null || views.ContainsKey(((Il2CppObjectBase)e).Pointer) || !models.TryGetValue(def.Model, out var value))
			{
				return;
			}
			Material val = MaterialFor(value);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Transform transform = ((Component)e).transform;
			Transform val2 = null;
			try
			{
				val2 = e.visualsRoot;
			}
			catch
			{
			}
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = transform;
			}
			View view = new View
			{
				Def = def,
				Model = value,
				Enemy = e,
				Root = transform,
				Visuals = val2,
				SpawnedAt = Time.time,
				LastPos = transform.position,
				Slot = nextSlot++
			};
			Bounds val3 = default(Bounds);
			bool flag = false;
			foreach (Renderer componentsInChild in ((Component)val2).GetComponentsInChildren<Renderer>(true))
			{
				if ((Object)(object)componentsInChild == (Object)null)
				{
					continue;
				}
				string name = ((MemberInfo)((Object)componentsInChild).GetIl2CppType()).Name;
				if (name != "MeshRenderer" && name != "SkinnedMeshRenderer")
				{
					continue;
				}
				try
				{
					if (componentsInChild.enabled && ((Component)componentsInChild).gameObject.activeInHierarchy)
					{
						if (!flag)
						{
							val3 = componentsInChild.bounds;
							flag = true;
						}
						else
						{
							((Bounds)(ref val3)).Encapsulate(componentsInChild.bounds);
						}
					}
					componentsInChild.forceRenderingOff = true;
					view.Hidden.Add(componentsInChild);
				}
				catch
				{
				}
			}
			foreach (Animator componentsInChild2 in ((Component)e).GetComponentsInChildren<Animator>(true))
			{
				try
				{
					componentsInChild2.cullingMode = (AnimatorCullingMode)0;
				}
				catch
				{
				}
			}
			float num = Mathf.Max(0.01f, transform.lossyScale.x);
			view.Width = (flag ? Mathf.Clamp(Mathf.Max(((Bounds)(ref val3)).size.x, ((Bounds)(ref val3)).size.z) / num, 0.6f, 2.5f) : 1.2f);
			if (flag && def.Flies)
			{
				view.Lift = Mathf.Max(0f, transform.InverseTransformPoint(((Bounds)(ref val3)).min).y);
			}
			GameObject val4 = new GameObject("MoreMonsters." + def.Name);
			val4.layer = ((Component)val2).gameObject.layer;
			Transform transform2 = val4.transform;
			transform2.SetParent(transform, false);
			transform2.localPosition = new Vector3(0f, view.Lift, 0f);
			transform2.localScale = Vector3.zero;
			view.Bones = (Transform[])(object)new Transform[value.Bones];
			view.LastScale = (Vector3[])(object)new Vector3[value.Bones];
			Il2CppReferenceArray<Transform> val5 = new Il2CppReferenceArray<Transform>((long)value.Bones);
			for (int i = 0; i < value.Bones; i++)
			{
				Transform transform3 = new GameObject("b" + i).transform;
				transform3.SetParent(transform2, false);
				view.Bones[i] = transform3;
				((Il2CppArrayBase<Transform>)(object)val5)[i] = transform3;
			}
			SkinnedMeshRenderer val6 = val4.AddComponent<SkinnedMeshRenderer>();
			val6.sharedMesh = value.Mesh;
			val6.bones = val5;
			val6.rootBone = transform2;
			((Renderer)val6).sharedMaterial = val;
			val6.updateWhenOffscreen = false;
			((Renderer)val6).localBounds = new Bounds(new Vector3(0f, 0.5f, 0f), new Vector3(1.6f, 1.6f, 1.6f));
			try
			{
				((Renderer)val6).shadowCastingMode = (ShadowCastingMode)1;
			}
			catch
			{
			}
			try
			{
				val6.quality = (SkinQuality)4;
			}
			catch
			{
			}
			view.Go = val4;
			view.T = transform2;
			view.Renderer = val6;
			view.PoseA = new float[value.Bones * 10];
			view.PoseB = new float[value.Bones * 10];
			view.NextAttack = Time.time + Random.Range(0.3f, 1.2f);
			Play(view, Act.Idle, value.Idle, oneShot: false, 0f);
			Animate(view, Time.time, 0.016f);
			views[((Il2CppObjectBase)e).Pointer] = view;
			if (!loggedLook.Add(def.Name))
			{
				return;
			}
			try
			{
				ManualLogSource log = Plugin.Log;
				bool flag2 = default(bool);
				BepInExInfoLogInterpolatedStringHandler val7 = new BepInExInfoLogInterpolatedStringHandler(59, 7, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<string>(def.Name);
					((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("'s look: ");
					((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<string>(value.Name);
					((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(" on ");
					((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<EnemyType>(e.EnemyType);
					((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(" (");
					((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<int>(view.Hidden.Count);
					((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(" parts hidden, ");
					((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<float>(view.Width, "0.##");
					((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(" wide, lifted ");
					((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<float>(view.Lift, "0.##");
					((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("), drawn with ");
					Shader obj6 = val.shader;
					((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<string>((obj6 != null) ? ((Object)obj6).name : null);
					((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(".");
				}
				log.LogInfo(val7);
			}
			catch
			{
			}
		}

		internal static void Hit(Enemy e)
		{
			if (!((Object)(object)e == (Object)null) && views.TryGetValue(((Il2CppObjectBase)e).Pointer, out var value))
			{
				float time = Time.time;
				value.FlashUntil = time + 0.08f;
				if (value.Model.Hit != null && time >= value.NextHit && value.Act != Act.Attack && value.Act != Act.Death)
				{
					value.NextHit = time + Random.Range(2.2f, 3.5f);
					Play(value, Act.Hit, value.Model.Hit, oneShot: true, 0.08f);
				}
			}
		}

		internal static void Died(Enemy e)
		{
			if ((Object)(object)e == (Object)null || !views.TryGetValue(((Il2CppObjectBase)e).Pointer, out var value) || value.DiedAt >= 0f)
			{
				return;
			}
			value.DiedAt = Time.time;
			try
			{
				if ((Object)(object)value.Go != (Object)null && value.Model.Death != null)
				{
					value.T.SetParent((Transform)null, true);
					value.Detached = true;
					views.Remove(((Il2CppObjectBase)e).Pointer);
					corpses.Add(value);
					Play(value, Act.Death, value.Model.Death, oneShot: true, 0.08f);
				}
			}
			catch
			{
			}
		}

		internal static void Clear()
		{
			views.Clear();
			foreach (View corpse in corpses)
			{
				try
				{
					if ((Object)(object)corpse.Go != (Object)null && !((Il2CppObjectBase)corpse.Go).WasCollected)
					{
						Object.Destroy((Object)(object)corpse.Go);
					}
				}
				catch
				{
				}
			}
			corpses.Clear();
		}

		private static void ScanPlayers(float now)
		{
			if (now < nextPlayerScan)
			{
				return;
			}
			nextPlayerScan = now + 1.5f;
			players.Clear();
			try
			{
				foreach (GameplayPlayer item in Object.FindObjectsOfType<GameplayPlayer>())
				{
					if ((Object)(object)item != (Object)null && ((Component)item).gameObject.activeInHierarchy)
					{
						players.Add(((Component)item).transform);
					}
				}
			}
			catch
			{
			}
		}

		private static float NearestPlayer(Vector3 at)
		{
			//IL_002f: 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_0035: 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)
			float num = float.MaxValue;
			foreach (Transform player in players)
			{
				try
				{
					if (!((Object)(object)player == (Object)null) && !((Il2CppObjectBase)player).WasCollected)
					{
						Vector3 val = player.position - at;
						val.y = 0f;
						num = Mathf.Min(num, ((Vector3)(ref val)).magnitude);
					}
				}
				catch
				{
				}
			}
			return num;
		}

		internal static void Tick()
		{
			if (views.Count == 0 && corpses.Count == 0)
			{
				return;
			}
			frameNo++;
			Busy = views.Count + corpses.Count;
			float time = Time.time;
			float dt = Mathf.Max(Time.deltaTime, 0.0001f);
			ScanPlayers(time);
			List<IntPtr> list = null;
			foreach (KeyValuePair<IntPtr, View> view2 in views)
			{
				View value = view2.Value;
				try
				{
					if ((Object)(object)value.Enemy == (Object)null || ((Il2CppObjectBase)value.Enemy).WasCollected || (Object)(object)value.Go == (Object)null || ((Il2CppObjectBase)value.Go).WasCollected)
					{
						(list ?? (list = new List<IntPtr>())).Add(view2.Key);
					}
					else if (((Component)value.Enemy).gameObject.activeInHierarchy)
					{
						Decide(value, time, dt);
						Animate(value, time, dt);
					}
				}
				catch
				{
					(list ?? (list = new List<IntPtr>())).Add(view2.Key);
				}
			}
			if (list != null)
			{
				foreach (IntPtr item in list)
				{
					views.Remove(item);
				}
			}
			for (int num = corpses.Count - 1; num >= 0; num--)
			{
				View view = corpses[num];
				bool flag;
				try
				{
					flag = (Object)(object)view.Go == (Object)null || ((Il2CppObjectBase)view.Go).WasCollected || !Corpse(view, time, dt);
				}
				catch
				{
					flag = true;
				}
				if (flag)
				{
					try
					{
						if ((Object)(object)view.Go != (Object)null && !((Il2CppObjectBase)view.Go).WasCollected)
						{
							Object.Destroy((Object)(object)view.Go);
						}
					}
					catch
					{
					}
					corpses.RemoveAt(num);
				}
			}
		}

		private static void Decide(View v, float now, float dt)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			if (now >= v.NextHide)
			{
				v.NextHide = now + 0.5f;
				foreach (Renderer item in v.Hidden)
				{
					try
					{
						if ((Object)(object)item != (Object)null && !item.forceRenderingOff)
						{
							item.forceRenderingOff = true;
						}
					}
					catch
					{
					}
				}
			}
			Vector3 position = v.Root.position;
			Vector3 val = position - v.LastPos;
			val.y = 0f;
			v.LastPos = position;
			float num = ((Vector3)(ref val)).magnitude / dt;
			if (num > 40f)
			{
				num = 0f;
			}
			v.Speed = Mathf.Lerp(v.Speed, num, 1f - Mathf.Exp(-8f * dt));
			Vector3 val2 = v.Visuals.forward;
			val2.y = 0f;
			if (((Vector3)(ref val2)).sqrMagnitude < 0.01f && ((Vector3)(ref val)).sqrMagnitude > 0.0001f)
			{
				val2 = val;
			}
			if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f)
			{
				v.Facing = Quaternion.LookRotation(((Vector3)(ref val2)).normalized, Vector3.up);
			}
			Model model = v.Model;
			float num2 = v.Width * Mathf.Max(0.01f, v.Root.lossyScale.x);
			if (v.OneShot && v.CurT < v.Cur.Length)
			{
				return;
			}
			float num3 = (v.Def.Ranged ? 13f : (0.9f + num2 * 0.7f));
			if (model.Attack != null && now >= v.NextAttack && (!v.Def.Ranged || v.Speed < 1.2f) && NearestPlayer(position) <= num3)
			{
				v.NextAttack = now + (v.Def.Ranged ? Random.Range(2.2f, 3.2f) : Random.Range(1.2f, 1.8f));
				Play(v, Act.Attack, model.Attack, oneShot: true, 0.1f);
				return;
			}
			float num4 = v.Speed / Mathf.Max(0.2f, num2);
			if (num4 < 0.15f)
			{
				Play(v, Act.Idle, model.Idle, oneShot: false, 0.25f);
			}
			else if (num4 > 1.6f && model.Run != model.Walk)
			{
				Play(v, Act.Run, model.Run, oneShot: false, 0.2f);
			}
			else
			{
				Play(v, Act.Walk, model.Walk, oneShot: false, 0.2f);
			}
			if (v.Act == Act.Walk)
			{
				v.Rate = Mathf.Clamp(num4 / 0.9f, 0.6f, 1.8f);
			}
			else if (v.Act == Act.Run)
			{
				v.Rate = Mathf.Clamp(num4 / 2.2f, 0.7f, 1.6f);
			}
			else
			{
				v.Rate = 1f;
			}
		}

		private static void Play(View v, Act act, Clip clip, bool oneShot, float fade)
		{
			if (clip != null && (oneShot || v.Act != act || v.Cur != clip))
			{
				if (v.Cur != null)
				{
					v.Prev = v.Cur;
					v.PrevT = v.CurT;
					v.FadeStart = Time.time;
					v.FadeLen = Mathf.Max(0.01f, fade);
				}
				v.Act = act;
				v.Cur = clip;
				v.CurT = 0f;
				v.OneShot = oneShot;
				v.Rate = 1f;
			}
		}

		private static void Animate(View v, float now, float dt)
		{
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			v.CurT += dt * v.Rate;
			float num = ((v.Prev != null) ? Mathf.Clamp01((now - v.FadeStart) / v.FadeLen) : 1f);
			if (num < 1f)
			{
				v.PrevT += dt;
			}
			else
			{
				v.Prev = null;
			}
			bool flag = v.Posed == 0 || Busy <= 10 || ((frameNo + v.Slot) & 1) == 0;
			if (flag && v.Posed > 0)
			{
				try
				{
					flag = ((Renderer)v.Renderer).isVisible;
				}
				catch
				{
				}
			}
			if (flag)
			{
				Sample(v.Cur, v.CurT, !v.OneShot, v.PoseA);
				if (v.Prev != null)
				{
					Sample(v.Prev, v.PrevT, loop: true, v.PoseB);
					Blend(v.PoseB, v.PoseA, num, v.PoseA);
				}
				Apply(v);
				v.Posed++;
			}
			float num2 = Mathf.Clamp01((now - v.SpawnedAt) / 0.35f);
			float num3 = v.Width * ((num2 < 1f) ? EaseOutBack(num2) : 1f);
			if (!v.Detached)
			{
				v.T.rotation = v.Facing;
				v.T.localScale = new Vector3(num3, num3, num3);
				v.T.localPosition = new Vector3(0f, v.Lift, 0f);
			}
			Material val = ((now < v.FlashUntil) ? Flash() : v.Model.Mat);
			if ((Object)(object)val != (Object)null && (Object)(object)((Renderer)v.Renderer).sharedMaterial != (Object)(object)val)
			{
				((Renderer)v.Renderer).sharedMaterial = val;
			}
		}

		private static bool Corpse(View v, float now, float dt)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			Animate(v, now, dt);
			float num = now - v.DiedAt - (v.Cur?.Length ?? 0f);
			if (num > 0.7f)
			{
				if ((num - 0.7f) / 0.6f >= 1f)
				{
					return false;
				}
				Transform t = v.T;
				t.position += Vector3.down * (dt * 1.2f * v.T.lossyScale.y);
			}
			return now - v.DiedAt < 8f;
		}

		private static void Sample(Clip c, float t, bool loop, float[] outPose)
		{
			float num = t * c.Fps;
			int num2 = c.Frames - 1;
			if (loop && num2 > 0)
			{
				num %= (float)num2;
				if (num < 0f)
				{
					num += (float)num2;
				}
			}
			else
			{
				num = Mathf.Clamp(num, 0f, (float)num2);
			}
			int num3 = Mathf.Min((int)num, num2);
			int num4 = Mathf.Min(num3 + 1, num2);
			float num5 = num - (float)num3;
			int num6 = c.Bones * 10;
			int num7 = num3 * num6;
			int num8 = num4 * num6;
			float[] data = c.Data;
			int num9 = 0;
			int num10 = 0;
			while (num9 < c.Bones)
			{
				int num11 = num7 + num10;
				int num12 = num8 + num10;
				for (int i = 0; i < 3; i++)
				{
					outPose[num10 + i] = data[num11 + i] + (data[num12 + i] - data[num11 + i]) * num5;
				}
				float num13 = ((data[num11 + 3] * data[num12 + 3] + data[num11 + 4] * data[num12 + 4] + data[num11 + 5] * data[num12 + 5] + data[num11 + 6] * data[num12 + 6] < 0f) ? (-1f) : 1f);
				float num14 = 0f;
				for (int j = 3; j < 7; j++)
				{
					outPose[num10 + j] = data[num11 + j] + (num13 * data[num12 + j] - data[num11 + j]) * num5;
					num14 += outPose[num10 + j] * outPose[num10 + j];
				}
				num14 = ((num14 > 1E-12f) ? (1f / Mathf.Sqrt(num14)) : 1f);
				for (int k = 3; k < 7; k++)
				{
					outPose[num10 + k] *= num14;
				}
				for (int l = 7; l < 10; l++)
				{
					outPose[num10 + l] = data[num11 + l] + (data[num12 + l] - data[num11 + l]) * num5;
				}
				num9++;
				num10 += 10;
			}
		}

		private static void Blend(float[] from, float[] to, float a, float[] outPose)
		{
			for (int i = 0; i < from.Length; i += 10)
			{
				for (int j = 0; j < 3; j++)
				{
					outPose[i + j] = from[i + j] + (to[i + j] - from[i + j]) * a;
				}
				float num = ((from[i + 3] * to[i + 3] + from[i + 4] * to[i + 4] + from[i + 5] * to[i + 5] + from[i + 6] * to[i + 6] < 0f) ? (-1f) : 1f);
				float num2 = 0f;
				for (int k = 3; k < 7; k++)
				{
					outPose[i + k] = from[i + k] + (num * to[i + k] - from[i + k]) * a;
					num2 += outPose[i + k] * outPose[i + k];
				}
				num2 = ((num2 > 1E-12f) ? (1f / Mathf.Sqrt(num2)) : 1f);
				for (int l = 3; l < 7; l++)
				{
					outPose[i + l] *= num2;
				}
				for (int m = 7; m < 10; m++)
				{
					outPose[i + m] = from[i + m] + (to[i + m] - from[i + m]) * a;
				}
			}
		}

		private static void Apply(View v)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			float[] poseA = v.PoseA;
			int num = 0;
			int num2 = 0;
			Vector3 val2 = default(Vector3);
			while (num < v.Bones.Length)
			{
				Transform val = v.Bones[num];
				val.SetLocalPositionAndRotation(new Vector3(poseA[num2], poseA[num2 + 1], poseA[num2 + 2]), new Quaternion(poseA[num2 + 3], poseA[num2 + 4], poseA[num2 + 5], poseA[num2 + 6]));
				((Vector3)(ref val2))..ctor(poseA[num2 + 7], poseA[num2 + 8], poseA[num2 + 9]);
				Vector3 val3 = val2 - v.LastScale[num];
				if (((Vector3)(ref val3)).sqrMagnitude > 1E-06f)
				{
					val.localScale = val2;
					v.LastScale[num] = val2;
				}
				num++;
				num2 += 10;
			}
		}

		private static float EaseOutBack(float x)
		{
			return 1f + 2.70158f * Mathf.Pow(x - 1f, 3f) + 1.70158f * Mathf.Pow(x - 1f, 2f);
		}
	}
}