Decompiled source of Rustheim modpack v15.0.8

Bestiary.dll

Decompiled 4 months ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Bestiary.Managers;
using HarmonyLib;
using JetBrains.Annotations;
using LocalizationManager;
using Microsoft.CodeAnalysis;
using ServerSync;
using TMPro;
using UnityEngine;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.BufferedDeserialization;
using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators;
using YamlDotNet.Serialization.Converters;
using YamlDotNet.Serialization.EventEmitters;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.NodeDeserializers;
using YamlDotNet.Serialization.NodeTypeResolvers;
using YamlDotNet.Serialization.ObjectFactories;
using YamlDotNet.Serialization.ObjectGraphTraversalStrategies;
using YamlDotNet.Serialization.ObjectGraphVisitors;
using YamlDotNet.Serialization.Schemas;
using YamlDotNet.Serialization.TypeInspectors;
using YamlDotNet.Serialization.TypeResolvers;
using YamlDotNet.Serialization.Utilities;
using YamlDotNet.Serialization.ValueDeserializers;

[assembly: AssemblyFileVersion("1.0.0")]
[assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")]
[assembly: ComVisible(false)]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyProduct("Bestiary")]
[assembly: AssemblyCompany("RustyMods")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyTitle("Bestiary")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[<e3261256-8b63-4807-8638-e2c6159f199b>Embedded]
	internal sealed class <e3261256-8b63-4807-8638-e2c6159f199b>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[<e3261256-8b63-4807-8638-e2c6159f199b>Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class <ee909b8e-360a-4106-bf5d-9643cb184aaf>NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public <ee909b8e-360a-4106-bf5d-9643cb184aaf>NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public <ee909b8e-360a-4106-bf5d-9643cb184aaf>NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[<e3261256-8b63-4807-8638-e2c6159f199b>Embedded]
	[CompilerGenerated]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class <bc81c85a-17ab-456a-9686-bd620947be46>NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public <bc81c85a-17ab-456a-9686-bd620947be46>NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace LocalizationManager
{
	[<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(1)]
	[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(0)]
	[PublicAPI]
	public class Localizer
	{
		private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors;

		private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts;

		private static readonly ConditionalWeakTable<Localization, string> localizationLanguage;

		private static readonly List<WeakReference<Localization>> localizationObjects;

		[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(2)]
		private static BaseUnityPlugin _plugin;

		private static readonly List<string> fileExtensions;

		private static BaseUnityPlugin plugin
		{
			get
			{
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: Expected O, but got Unknown
				if (_plugin == null)
				{
					IEnumerable<TypeInfo> source;
					try
					{
						source = Assembly.GetExecutingAssembly().DefinedTypes.ToList();
					}
					catch (ReflectionTypeLoadException ex)
					{
						source = from t in ex.Types
							where t != null
							select t.GetTypeInfo();
					}
					_plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First([<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
				}
				return _plugin;
			}
		}

		private static void UpdatePlaceholderText(Localization localization, string key)
		{
			localizationLanguage.TryGetValue(localization, out var value);
			string text = loadedTexts[value][key];
			if (PlaceholderProcessors.TryGetValue(key, out var value2))
			{
				text = value2.Aggregate(text, [<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value()));
			}
			localization.AddWord(key, text);
		}

		public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, [<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(new byte[] { 2, 1, 1 })] Func<T, string> convertConfigValue = null)
		{
			if (convertConfigValue == null)
			{
				convertConfigValue = [<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] [return: <ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(1)] (T val) => val.ToString();
			}
			if (!PlaceholderProcessors.ContainsKey(key))
			{
				PlaceholderProcessors[key] = new Dictionary<string, Func<string>>();
			}
			config.SettingChanged += [<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdatePlaceholder();
			};
			if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage()))
			{
				UpdatePlaceholder();
			}
			void UpdatePlaceholder()
			{
				PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value);
				UpdatePlaceholderText(Localization.instance, key);
			}
		}

		public static void AddText(string key, string text)
		{
			List<WeakReference<Localization>> list = new List<WeakReference<Localization>>();
			foreach (WeakReference<Localization> localizationObject in localizationObjects)
			{
				if (localizationObject.TryGetTarget(out var target))
				{
					Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)];
					if (!target.m_translations.ContainsKey(key))
					{
						dictionary[key] = text;
						target.AddWord(key, text);
					}
				}
				else
				{
					list.Add(localizationObject);
				}
			}
			foreach (WeakReference<Localization> item in list)
			{
				localizationObjects.Remove(item);
			}
		}

		public static void Load()
		{
			LoadLocalization(Localization.instance, Localization.instance.GetSelectedLanguage());
		}

		private static void LoadLocalization(Localization __instance, string language)
		{
			if (!localizationLanguage.Remove(__instance))
			{
				localizationObjects.Add(new WeakReference<Localization>(__instance));
			}
			localizationLanguage.Add(__instance, language);
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			foreach (string item in from f in Directory.GetFiles(Path.GetDirectoryName(Paths.PluginPath), plugin.Info.Metadata.Name + ".*", SearchOption.AllDirectories)
				where fileExtensions.IndexOf(Path.GetExtension(f)) >= 0
				select f)
			{
				string text = Path.GetFileNameWithoutExtension(item).Split(new char[1] { '.' })[1];
				if (dictionary.ContainsKey(text))
				{
					Debug.LogWarning((object)("Duplicate key " + text + " found for " + plugin.Info.Metadata.Name + ". The duplicate file found at " + item + " will be skipped."));
				}
				else
				{
					dictionary[text] = item;
				}
			}
			byte[] array = LoadTranslationFromAssembly("English");
			if (array == null)
			{
				throw new Exception("Found no English localizations in mod " + plugin.Info.Metadata.Name + ". Expected an embedded resource translations/English.json or translations/English.yml.");
			}
			Dictionary<string, string> dictionary2 = new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(Encoding.UTF8.GetString(array));
			if (dictionary2 == null)
			{
				throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Localization file was empty.");
			}
			string text2 = null;
			if (language != "English")
			{
				if (dictionary.ContainsKey(language))
				{
					text2 = File.ReadAllText(dictionary[language]);
				}
				else
				{
					byte[] array2 = LoadTranslationFromAssembly(language);
					if (array2 != null)
					{
						text2 = Encoding.UTF8.GetString(array2);
					}
				}
			}
			if (text2 == null && dictionary.ContainsKey("English"))
			{
				text2 = File.ReadAllText(dictionary["English"]);
			}
			if (text2 != null)
			{
				foreach (KeyValuePair<string, string> item2 in new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text2) ?? new Dictionary<string, string>())
				{
					dictionary2[item2.Key] = item2.Value;
				}
			}
			loadedTexts[language] = dictionary2;
			foreach (KeyValuePair<string, string> item3 in dictionary2)
			{
				UpdatePlaceholderText(__instance, item3.Key);
			}
		}

		static Localizer()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>();
			loadedTexts = new Dictionary<string, Dictionary<string, string>>();
			localizationLanguage = new ConditionalWeakTable<Localization, string>();
			localizationObjects = new List<WeakReference<Localization>>();
			fileExtensions = new List<string> { ".json", ".yml" };
			Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager");
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		[return: <ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(2)]
		private static byte[] LoadTranslationFromAssembly(string language)
		{
			foreach (string fileExtension in fileExtensions)
			{
				byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension);
				if (array != null)
				{
					return array;
				}
			}
			return null;
		}

		[<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(2)]
		public static byte[] ReadEmbeddedFileBytes([<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(1)] string resourceFileName, Assembly containingAssembly = null)
		{
			using MemoryStream memoryStream = new MemoryStream();
			if ((object)containingAssembly == null)
			{
				containingAssembly = Assembly.GetCallingAssembly();
			}
			string text = containingAssembly.GetManifestResourceNames().FirstOrDefault([<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal));
			if (text != null)
			{
				containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream);
			}
			return (memoryStream.Length == 0L) ? null : memoryStream.ToArray();
		}
	}
}
namespace Bestiary
{
	[<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(1)]
	[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(0)]
	[BepInPlugin("RustyMods.Bestiary", "Bestiary", "1.0.0")]
	public class BestiaryPlugin : BaseUnityPlugin
	{
		[<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)]
		private enum Toggle
		{
			On = 1,
			Off = 0
		}

		[<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)]
		private class ConfigurationManagerAttributes
		{
			[UsedImplicitly]
			public int? Order;

			[UsedImplicitly]
			public bool? Browsable;

			[UsedImplicitly]
			[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(2)]
			public string Category;

			[UsedImplicitly]
			[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(new byte[] { 2, 1 })]
			public Action<ConfigEntryBase> CustomDrawer;
		}

		internal const string ModName = "Bestiary";

		internal const string ModVersion = "1.0.0";

		internal const string Author = "RustyMods";

		private const string ModGUID = "RustyMods.Bestiary";

		private static readonly string ConfigFileName = "RustyMods.Bestiary.cfg";

		private static readonly string ConfigFileFullPath;

		internal static string ConnectionError;

		private readonly Harmony _harmony = new Harmony("RustyMods.Bestiary");

		public static readonly ManualLogSource BestiaryLogger;

		private static readonly ConfigSync ConfigSync;

		public static GameObject _Root;

		public static BestiaryPlugin _Plugin;

		public static readonly AssetBundle _CreatureBundle;

		private static readonly AssetBundle _BlobIceBundle;

		private static ConfigEntry<Toggle> _serverConfigLocked;

		private static AssetBundle GetAssetBundle(string fileName)
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string name = executingAssembly.GetManifestResourceNames().Single([<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (string str) => str.EndsWith(fileName));
			using Stream stream = executingAssembly.GetManifestResourceStream(name);
			return AssetBundle.LoadFromStream(stream);
		}

		public void Awake()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			_Plugin = this;
			_Root = new GameObject("root");
			_Root.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)_Root);
			Localizer.Load();
			_serverConfigLocked = config("1 - General", "Lock Configuration", Toggle.On, "If on, the configuration is locked and can be changed by server admins only.");
			ConfigSync.AddLockingConfigEntry<Toggle>(_serverConfigLocked);
			LoadFaunaAssets();
			LoadItems();
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			_harmony.PatchAll(executingAssembly);
			SetupWatcher();
		}

		private static void LoadFaunaAssets()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0709: Unknown result type (might be due to invalid IL or missing references)
			//IL_0875: Unknown result type (might be due to invalid IL or missing references)
			FaunaManager.Critter critter = new FaunaManager.Critter("BlobTar", "SnowBlob", new Color32((byte)155, byte.MaxValue, byte.MaxValue, byte.MaxValue), clone: true, "BlobIce")
			{
				m_biome = (Biome)64,
				m_spawnDistance = 20f,
				m_spawnRadiusMin = 20f,
				m_spawnRadiusMax = 100f
			};
			critter.AddDrop("FreezeGland", 1, 2, 1f);
			critter.AddDrop("Ice", 1, 1, 0.5f);
			critter.m_characterData.m_faction = (Faction)5;
			critter.m_characterData.m_health = 300f;
			critter.AddHitEffect("vfx_HitSparks");
			critter.AddHitEffect("sfx_greydwarf_attack_hit");
			critter.AddDeathEffect("vfx_blobice_death");
			critter.AddDeathEffect("sfx_blob_death");
			critter.ReplaceAttack("blobice_attack", _BlobIceBundle, new List<string> { "sfx_blobtar_attack_spit" }, new List<string> { "sfx_GoblinShaman_fireball_launch" });
			FaunaManager.Critter critter2 = new FaunaManager.Critter("Creeper", _CreatureBundle)
			{
				m_biome = (Biome)64,
				m_spawnDistance = 20f,
				m_spawnRadiusMin = 20f,
				m_spawnRadiusMax = 100f
			};
			critter2.AddDrop("FreezeGland", 1, 2, 1f);
			critter2.AddDrop("TrophyCreeper", 1, 1, 0.3f);
			critter2.AddHitEffect("vfx_HitSparks");
			critter2.AddHitEffect("sfx_greydwarf_attack_hit");
			critter2.AddDeathEffect("vfx_hatchling_death");
			critter2.AddDeathEffect("sfx_greydwarf_death");
			critter2.CloneFootStepsFrom("Fenring");
			critter2.AddAlertedEffect("sfx_fenring_alerted");
			critter2.AddIdleSound("sfx_fenring_idle");
			critter2.EditAttack("Creeper_throw", null, new List<string> { "sfx_asksvin_alert" });
			FaunaManager.Critter critter3 = new FaunaManager.Critter("SaddleBeast", _CreatureBundle)
			{
				m_biome = (Biome)64,
				m_spawnDistance = 20f,
				m_spawnRadiusMin = 20f,
				m_spawnRadiusMax = 100f
			};
			critter3.AddDrop("FreezeGland", 1, 2, 1f);
			critter3.AddDrop("TrophySaddleBeast", 1, 1, 0.3f);
			critter3.AddDrop("BeastHeart", 1, 1, 1f);
			critter3.AddDrop("SaddleBeastMeatRaw", 1, 1, 1f);
			critter3.AddHitEffect("vfx_HitSparks");
			critter3.AddHitEffect("sfx_greydwarf_attack_hit");
			critter3.AddDeathEffect("vfx_hatchling_death");
			critter3.AddDeathEffect("sfx_greydwarf_death");
			critter3.CloneFootStepsFrom("Lox");
			critter3.AddAlertedEffect("sfx_fenring_alerted");
			critter3.AddIdleSound("sfx_fenring_idle");
			critter3.SetSaddleItem("BeastSaddle");
			critter3.EditAttack("SadleBeast_taunt", null, new List<string> { "sfx_asksvin_alert" });
			critter3.EditAttack("SadleBeast_attack_jump", hitEffects: new List<string> { "vfx_HitSparks", "sfx_fenring_claw_hit" }, startEffects: new List<string> { "sfx_asksvin_pounce" }, triggerEffects: new List<string> { "sfx_fenring_jump_trigger" });
			critter3.EditAttack("SadleBeast_attack_claw", hitEffects: new List<string> { "vfx_HitSparks", "sfx_asksvin_bite" }, startEffects: new List<string> { "sfx_fenring_claw_start" }, triggerEffects: null, trailEffects: new List<string> { "sfx_fenring_claw_trailstart" });
			critter3.AddTameEffect("fx_lox_tamed");
			critter3.AddSootheEffect("vfx_lox_soothed");
			critter3.AddPetEffect("fx_lox_pet");
			critter3.AddConsumeEffect("sfx_creature_consume");
			critter3.AddConsumeItem("CookedBugMeat");
			critter3.AddConsumeItem("MushroomJotunPuffs");
			critter3.AddConsumeItem("LizardMeatRaw");
			FaunaManager.Critter critter4 = new FaunaManager.Critter("LizardFish", _CreatureBundle)
			{
				m_biome = (Biome)64,
				m_spawnDistance = 20f,
				m_spawnRadiusMin = 20f,
				m_spawnRadiusMax = 100f
			};
			critter4.AddDrop("FreezeGland", 1, 2, 1f);
			critter4.AddDrop("TrophyLizardFish", 1, 1, 0.3f);
			critter4.AddDrop("LizardMeatRaw", 1, 1, 1f);
			critter4.AddHitEffect("vfx_HitSparks");
			critter4.AddHitEffect("sfx_greydwarf_attack_hit");
			critter4.AddDeathEffect("vfx_hatchling_death");
			critter4.AddDeathEffect("sfx_greydwarf_death");
			critter4.CloneFootStepsFrom("Fenring");
			critter4.AddAlertedEffect("sfx_fenring_alerted");
			critter4.AddIdleSound("sfx_fenring_idle");
			critter4.EditAttack("LizardFish_throw", null, null, null, new List<string> { "fx_blobice_snowball_hit" });
			FaunaManager.Critter critter5 = new FaunaManager.Critter("CatFish", _CreatureBundle)
			{
				m_biome = (Biome)64,
				m_spawnDistance = 20f,
				m_spawnRadiusMin = 20f,
				m_spawnRadiusMax = 100f
			};
			critter5.AddDrop("FreezeGland", 1, 2, 1f);
			critter5.AddHitEffect("vfx_HitSparks");
			critter5.AddHitEffect("sfx_greydwarf_attack_hit");
			critter5.AddDeathEffect("vfx_hatchling_death");
			critter5.AddDeathEffect("sfx_greydwarf_death");
			critter5.AddWaterEffect("vfx_water_surface");
			critter5.CloneFootStepsFrom("Fenring");
			critter5.AddAlertedEffect("sfx_fenring_alerted");
			critter5.AddIdleSound("sfx_fenring_idle");
			critter5.EditAttack("CatFish_throw", null, null, null, new List<string> { "vfx_HitSparks", "sfx_spear_hit" });
			critter5.EditAttack("CatFish_attack", null, null, null, new List<string> { "vfx_HitSparks", "sfx_spear_hit" });
			FaunaManager.Critter critter6 = new FaunaManager.Critter("Rake", _CreatureBundle)
			{
				m_biome = (Biome)64,
				m_spawnDistance = 20f,
				m_spawnRadiusMin = 20f,
				m_spawnRadiusMax = 100f
			};
			critter6.AddDrop("FreezeGland", 1, 2, 1f);
			critter6.AddHitEffect("vfx_HitSparks");
			critter6.AddHitEffect("sfx_greydwarf_attack_hit");
			critter6.AddDeathEffect("vfx_hatchling_death");
			critter6.AddDeathEffect("sfx_greydwarf_death");
			critter6.AddWaterEffect("vfx_water_surface");
			critter6.CloneFootStepsFrom("Troll");
			critter6.AddAlertedEffect("sfx_fenring_alerted");
			critter6.AddIdleSound("sfx_fenring_idle");
			critter6.EditAttack("Rake_Attack_Bite", null, null, null, new List<string> { "vfx_HitSparks", "sfx_spear_hit" });
			critter6.EditAttack("Rake_Attack_Claw", null, null, null, new List<string> { "vfx_HitSparks", "sfx_spear_hit" });
			FaunaManager.Critter critter7 = new FaunaManager.Critter("WereWolf", _CreatureBundle)
			{
				m_biome = (Biome)64,
				m_spawnDistance = 20f,
				m_spawnRadiusMin = 20f,
				m_spawnRadiusMax = 100f
			};
			critter7.AddDrop("FreezeGland", 1, 2, 1f);
			critter7.AddHitEffect("vfx_HitSparks");
			critter7.AddHitEffect("sfx_greydwarf_attack_hit");
			critter7.AddDeathEffect("vfx_hatchling_death");
			critter7.AddDeathEffect("sfx_greydwarf_death");
			critter7.AddWaterEffect("vfx_water_surface");
			critter7.CloneFootStepsFrom("Fenring");
			critter7.AddAlertedEffect("sfx_fenring_alerted");
			critter7.AddIdleSound("sfx_fenring_idle");
			critter7.EditAttack("WereWolf_attack_iceclaw_double", null, null, null, new List<string> { "vfx_HitSparks", "sfx_spear_hit" });
			critter7.EditAttack("WereWolf_attack_iceclaw", null, null, null, new List<string> { "vfx_HitSparks", "sfx_spear_hit" });
			critter7.EditAttack("WereWolf_attack_frost", null, null, null, new List<string> { "vfx_HitSparks", "sfx_spear_hit" });
			critter7.EditAttack("WereWolf_attack_IceNova", null, null, null, new List<string> { "vfx_HitSparks", "sfx_spear_hit" });
			FaunaManager.Critter critter8 = new FaunaManager.Critter("BookCreep", _CreatureBundle)
			{
				m_biome = (Biome)2,
				m_spawnDistance = 20f,
				m_spawnRadiusMin = 20f,
				m_spawnRadiusMax = 100f
			};
			critter8.AddDrop("Entrails", 1, 2, 1f);
			critter8.AddDrop("Bloodbag", 1, 2, 1f);
			critter8.AddHitEffect("vfx_draugr_hit");
			critter8.AddHitEffect("sfx_draugr_hit");
			critter8.AddDeathEffect("vfx_draugr_death");
			critter8.AddDeathEffect("sfx_draugr_death");
			critter8.AddWaterEffect("vfx_water_surface");
			critter8.AddAlertedEffect("sfx_charred_alert");
			critter8.AddAlertedEffect("sfx_wraith_alerted");
			critter8.AddIdleSound("sfx_dverger_vo_alerted");
			critter8.AddIdleSound("sfx_wraith_idle");
			critter8.AddIdleSound("sfx_vulture_alert");
			critter8.AddWaterEffect("vfx_water_surface");
			critter8.CloneFootStepsFrom("Draugr");
			critter8.EditAttack("BookCreep_Attack_Double", hitEffects: new List<string> { "vfx_clubhit", "sfx_axe_hit" }, triggerEffects: new List<string> { "sfx_asksvin_pounce" }, startEffects: new List<string> { "sfx_gdking_shoot_start" });
			critter8.EditAttack("BookCreep_Attack", null, hitEffects: new List<string> { "vfx_clubhit", "sfx_axe_hit" }, triggerEffects: new List<string> { "sfx_asksvin_pounce" });
			critter8.EditAttack("BookCreep_Cast", hitEffects: new List<string> { "vfx_clubhit", "sfx_axe_hit" }, startEffects: new List<string> { "sfx_gdking_shoot_start" });
			FaunaManager.RegisterAssetToZNetScene("fx_blobice_snowball_hit", _BlobIceBundle);
			FaunaManager.RegisterAssetToZNetScene("vfx_blobice_death", _BlobIceBundle);
			FaunaManager.RegisterAssetToZNetScene("fat_dragon_ice_projectile", _CreatureBundle);
			FaunaManager.ProjectileData projectileData = new FaunaManager.ProjectileData("blobice_projectile_snowball", _BlobIceBundle);
			FaunaManager.ProjectileData projectileData2 = new FaunaManager.ProjectileData("LizardFish_throw_projectile", _CreatureBundle);
			projectileData2.AddHitEffect("fx_blobice_snowball_hit");
			projectileData2.AddHitEffect("sfx_ice_destroyed");
			FaunaManager.ProjectileData projectileData3 = new FaunaManager.ProjectileData("BookCreep_Projectile", _CreatureBundle);
			projectileData3.AddHitEffect("vfx_gdking_projectile_hit");
			projectileData3.AddHitEffect("sfx_gdking_projectile_hit");
			projectileData3.AddSpawnOnHit("TentaRoot");
			FaunaManager.Bird bird = new FaunaManager.Bird("MysticalButterfly", _CreatureBundle);
			bird.AddDestroyedEffect("vfx_greydwarf_death");
			bird.AddDestroyedEffect("sfx_crow_death");
			bird.SetHealth(1);
			bird.SetRange(10f);
			bird.SetSpeed(2f);
			bird.SetBiome((Biome)8);
			bird.SetMaxSpawned(1);
			bird.SetSpawnInterval(100f);
			bird.AddDrop("Honey", 1, 2, 1f);
			bird.SetShader("Custom/Creature");
		}

		private static void LoadItems()
		{
			ItemManager.Item item = new ItemManager.Item("SaddleLox", "BeastSaddle");
			ItemManager.Item item2 = new ItemManager.Item("HealthUpgrade_Bonemass", "BeastHeart");
			item2.SetFood(50f, 25f, 20f, 1000f, 3f);
			item2.m_data.m_maxStack = 10;
			ItemManager.Item item3 = new ItemManager.Item("TrophySaddleBeast", _CreatureBundle);
			ItemManager.Item item4 = new ItemManager.Item("TrophyCreeper", _CreatureBundle);
			ItemManager.Item item5 = new ItemManager.Item("TrophyLizardFish", _CreatureBundle);
			ItemManager.Item item6 = new ItemManager.Item("LizardMeatRaw", _CreatureBundle);
			ItemManager.Item item7 = new ItemManager.Item("LizardMeatCooked", _CreatureBundle);
			ItemManager.Conversion conversion = new ItemManager.Conversion("piece_cookingstation_iron", "LizardMeatRaw", "LizardMeatCooked", 60f);
			ItemManager.Item item8 = new ItemManager.Item("SaddleBeastMeatRaw", _CreatureBundle);
			ItemManager.Item item9 = new ItemManager.Item("SaddleBeastMeatCooked", _CreatureBundle);
			ItemManager.Conversion conversion2 = new ItemManager.Conversion("piece_cookingstation_iron", "SaddleBeastMeatRaw", "SaddleBeastMeatCooked", 60f);
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
		}

		private void SetupWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName);
			fileSystemWatcher.Changed += ReadConfigValues;
			fileSystemWatcher.Created += ReadConfigValues;
			fileSystemWatcher.Renamed += ReadConfigValues;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		private void ReadConfigValues(object sender, FileSystemEventArgs e)
		{
			if (!File.Exists(ConfigFileFullPath))
			{
				return;
			}
			try
			{
				BestiaryLogger.LogDebug((object)"ReadConfigValues called");
				((BaseUnityPlugin)this).Config.Reload();
			}
			catch
			{
				BestiaryLogger.LogError((object)("There was an issue loading your " + ConfigFileName));
				BestiaryLogger.LogError((object)"Please check your config entries for spelling and format!");
			}
		}

		public ConfigEntry<T> config<[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(2)] T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			ConfigDescription val = new ConfigDescription(description.Description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]"), description.AcceptableValues, description.Tags);
			ConfigEntry<T> val2 = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, val);
			SyncedConfigEntry<T> syncedConfigEntry = ConfigSync.AddConfigEntry<T>(val2);
			syncedConfigEntry.SynchronizedConfig = synchronizedSetting;
			return val2;
		}

		public ConfigEntry<T> config<[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(2)] T>(string group, string name, T value, string description, bool synchronizedSetting = true)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting);
		}

		static BestiaryPlugin()
		{
			string configPath = Paths.ConfigPath;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName;
			ConnectionError = "";
			BestiaryLogger = Logger.CreateLogSource("Bestiary");
			ConfigSync = new ConfigSync("RustyMods.Bestiary")
			{
				DisplayName = "Bestiary",
				CurrentVersion = "1.0.0",
				MinimumRequiredVersion = "1.0.0"
			};
			_Root = null;
			_Plugin = null;
			_CreatureBundle = GetAssetBundle("northcreaturebundle");
			_BlobIceBundle = GetAssetBundle("blobicebundle");
			_serverConfigLocked = null;
		}
	}
	[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
	public static class RegisterAndCheckVersion
	{
		[<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(1)]
		private static void Prefix(ZNetPeer peer, ref ZNet __instance)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			BestiaryPlugin.BestiaryLogger.LogDebug((object)"Registering version RPC handler");
			peer.m_rpc.Register<ZPackage>("Bestiary_VersionCheck", (Action<ZRpc, ZPackage>)RpcHandlers.RPC_Bestiary_Version);
			BestiaryPlugin.BestiaryLogger.LogInfo((object)"Invoking version check");
			ZPackage val = new ZPackage();
			val.Write("1.0.0");
			peer.m_rpc.Invoke("Bestiary_VersionCheck", new object[1] { val });
		}
	}
	[<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(1)]
	[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(0)]
	[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
	public static class VerifyClient
	{
		private static bool Prefix(ZRpc rpc, ZPackage pkg, ref ZNet __instance)
		{
			if (!__instance.IsServer() || RpcHandlers.ValidatedPeers.Contains(rpc))
			{
				return true;
			}
			BestiaryPlugin.BestiaryLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") never sent version or couldn't due to previous disconnect, disconnecting"));
			rpc.Invoke("Error", new object[1] { 3 });
			return false;
		}

		private static void Postfix(ZNet __instance)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "BestiaryRequestAdminSync", new object[1] { (object)new ZPackage() });
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "ShowConnectError")]
	public class ShowConnectionError
	{
		[<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(1)]
		private static void Postfix(FejdStartup __instance)
		{
			if (__instance.m_connectionFailedPanel.activeSelf)
			{
				__instance.m_connectionFailedError.fontSizeMax = 25f;
				__instance.m_connectionFailedError.fontSizeMin = 15f;
				TMP_Text connectionFailedError = __instance.m_connectionFailedError;
				connectionFailedError.text = connectionFailedError.text + "\n" + BestiaryPlugin.ConnectionError;
			}
		}
	}
	[HarmonyPatch(typeof(ZNet), "Disconnect")]
	public static class RemoveDisconnectedPeerFromVerified
	{
		[<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(1)]
		private static void Prefix(ZNetPeer peer, ref ZNet __instance)
		{
			if (__instance.IsServer())
			{
				BestiaryPlugin.BestiaryLogger.LogInfo((object)("Peer (" + peer.m_rpc.m_socket.GetHostName() + ") disconnected, removing from validated list"));
				RpcHandlers.ValidatedPeers.Remove(peer.m_rpc);
			}
		}
	}
	[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(0)]
	[<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(1)]
	public static class RpcHandlers
	{
		public static readonly List<ZRpc> ValidatedPeers = new List<ZRpc>();

		public static void RPC_Bestiary_Version(ZRpc rpc, ZPackage pkg)
		{
			string text = pkg.ReadString();
			BestiaryPlugin.BestiaryLogger.LogInfo((object)("Version check, local: 1.0.0,  remote: " + text));
			if (text != "1.0.0")
			{
				BestiaryPlugin.ConnectionError = "Bestiary Installed: 1.0.0\n Needed: " + text;
				if (ZNet.instance.IsServer())
				{
					BestiaryPlugin.BestiaryLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") has incompatible version, disconnecting..."));
					rpc.Invoke("Error", new object[1] { 3 });
				}
			}
			else if (!ZNet.instance.IsServer())
			{
				BestiaryPlugin.BestiaryLogger.LogInfo((object)"Received same version from server!");
			}
			else
			{
				BestiaryPlugin.BestiaryLogger.LogInfo((object)("Adding peer (" + rpc.m_socket.GetHostName() + ") to validated list"));
				ValidatedPeers.Add(rpc);
			}
		}

		public static string ComputeHashForMod()
		{
			using SHA256 sHA = SHA256.Create();
			byte[] array = sHA.ComputeHash(File.ReadAllBytes(Assembly.GetExecutingAssembly().Location));
			StringBuilder stringBuilder = new StringBuilder();
			byte[] array2 = array;
			foreach (byte b in array2)
			{
				stringBuilder.Append(b.ToString("X2"));
			}
			return stringBuilder.ToString();
		}
	}
}
namespace Bestiary.StatusEffects
{
	public class SE_BeastHeart : StatusEffect
	{
		public override void ModifyHealthRegen(ref float regenMultiplier)
		{
			regenMultiplier *= 0.1f;
		}

		public override void ModifyMaxCarryWeight(float baseLimit, ref float limit)
		{
			limit += 50f;
		}

		[<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(1)]
		public override string GetTooltipString()
		{
			return "$se_beastheart_tooltip\n$se_healthregen: <color=orange>10%</color>\n$se_max_carryweight: <color=orange>50</color>";
		}
	}
}
namespace Bestiary.Managers
{
	[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(0)]
	[<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(1)]
	public class CreatureStatus : StatusEffect
	{
		public FaunaManager.Critter.StatusEffectData m_data = null;

		public override void OnDamaged(HitData hit, Character attacker)
		{
			hit.ApplyModifier(m_data.m_armorMultiplier.Value);
		}

		public override void ModifyAttack(SkillType skill, ref HitData hitData)
		{
			hitData.ApplyModifier(m_data.m_damageMultiplier.Value);
		}
	}
	[<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(1)]
	[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(0)]
	public class FaunaManager
	{
		[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(0)]
		public class ProjectileData
		{
			public readonly string m_name;

			public readonly List<string> m_hitEffects = new List<string>();

			public readonly List<string> m_hitWaterEffects = new List<string>();

			public string m_spawnOnHit = "";

			public float m_spawnOnHitChance = 1f;

			public readonly List<string> m_randomSpawnOnHit = new List<string>();

			public readonly AssetBundle m_bundle;

			public ProjectileData(string name, AssetBundle bundle)
			{
				m_name = name;
				m_bundle = bundle;
				m_projectiles.Add(this);
			}

			public void AddHitEffect(string effectName)
			{
				m_hitEffects.Add(effectName);
			}

			public void AddHitWaterEffect(string effectName)
			{
				m_hitWaterEffects.Add(effectName);
			}

			public void AddSpawnOnHit(string name)
			{
				m_spawnOnHit = name;
			}

			public void SetSpawnOnHitChance(float value)
			{
				m_spawnOnHitChance = value;
			}

			public void AddRandomSpawnOnHit(string name)
			{
				m_randomSpawnOnHit.Add(name);
			}
		}

		[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(0)]
		public class Bird
		{
			public readonly string m_name = "";

			public readonly GameObject m_prefab;

			public ConfigEntry<int> m_health = null;

			public ConfigEntry<float> m_range = null;

			public ConfigEntry<float> m_speed = null;

			public ConfigEntry<Biome> m_biome = null;

			public readonly BiomeArea m_biomeArea = (BiomeArea)3;

			public ConfigEntry<int> m_maxSpawned = null;

			public ConfigEntry<float> m_spawnInterval = null;

			public float m_spawnDistance = 50f;

			public float m_spawnRadiusMin = 10f;

			public float m_spawnRadiusMax = 100f;

			public string m_requiredGlobalKey = "";

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

			public int m_groupSizeMin = 0;

			public int m_groupSizeMax = 1;

			public float m_groupRadius = 50f;

			public bool m_spawnAtNight = true;

			public bool m_spawnAtDay = true;

			public float m_minAltitude = -1000f;

			public float m_maxAltitude = 1000f;

			public float m_minTilt = 0f;

			public float m_maxTilt = 50f;

			public bool m_huntPlayer = false;

			public float m_groundOffset = 0.5f;

			public int m_maxLevel = 3;

			public int m_minLevel = 1;

			public float m_levelUpMinCenterDistance = 1f;

			public float m_overrideLevelUpChance = 0f;

			public bool m_foldout = false;

			public readonly List<string> m_destroyedEffects = new List<string>();

			public readonly List<Critter.DropData> m_dropData = new List<Critter.DropData>();

			public string m_shader = "";

			public Bird(string name, AssetBundle assetBundle)
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				m_prefab = assetBundle.LoadAsset<GameObject>(name);
				m_name = name;
				m_birds.Add(this);
			}

			public void SetShader(string shader)
			{
				m_shader = shader;
			}

			public void AddDestroyedEffect(string name)
			{
				m_destroyedEffects.Add(name);
			}

			public void SetHealth(int health)
			{
				m_health = BestiaryPlugin._Plugin.config(m_name, "Health", health, "Set health");
			}

			public void SetRange(float range)
			{
				m_range = BestiaryPlugin._Plugin.config(m_name, "Range", range, "Set fly range");
			}

			public void SetSpeed(float speed)
			{
				m_speed = BestiaryPlugin._Plugin.config(m_name, "Speed", speed, "Set fly speed");
			}

			public void SetBiome(Biome biome)
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				m_biome = BestiaryPlugin._Plugin.config<Biome>(m_name, "Biome", biome, "Set biome");
			}

			public void SetMaxSpawned(int max)
			{
				m_maxSpawned = BestiaryPlugin._Plugin.config(m_name, "Max Spawned", max, "Set max spawned");
			}

			public void SetSpawnInterval(float interval)
			{
				m_spawnInterval = BestiaryPlugin._Plugin.config(m_name, "Spawn Interval", interval, "Set interval");
			}

			public void AddDrop(string prefabName, int min, int max, float chance, bool onePerPlayer = false, bool levelMultiplier = false, bool doNotScale = false)
			{
				Critter.DropData item = new Critter.DropData
				{
					m_prefabName = prefabName,
					m_min = min,
					m_max = max,
					m_chance = chance,
					m_onePerPlayer = onePerPlayer,
					m_levelMultiplier = levelMultiplier,
					m_doNotScale = doNotScale
				};
				m_dropData.Add(item);
			}

			public SpawnData GetSpawnData()
			{
				//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_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: 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)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: 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_0064: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_0094: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dc: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
				//IL_0100: 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_0118: Unknown result type (might be due to invalid IL or missing references)
				//IL_0124: 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_013c: 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_0154: Unknown result type (might be due to invalid IL or missing references)
				//IL_0161: Expected O, but got Unknown
				return new SpawnData
				{
					m_name = m_name,
					m_enabled = true,
					m_prefab = m_prefab,
					m_biome = m_biome.Value,
					m_biomeArea = m_biomeArea,
					m_maxSpawned = m_maxSpawned.Value,
					m_spawnInterval = m_spawnInterval.Value,
					m_spawnDistance = m_spawnDistance,
					m_spawnRadiusMin = m_spawnRadiusMin,
					m_spawnRadiusMax = m_spawnRadiusMax,
					m_requiredGlobalKey = m_requiredGlobalKey,
					m_requiredEnvironments = m_requiredEnvironments,
					m_groupSizeMin = m_groupSizeMin,
					m_groupSizeMax = m_groupSizeMax,
					m_groupRadius = m_groupRadius,
					m_spawnAtNight = m_spawnAtNight,
					m_spawnAtDay = m_spawnAtDay,
					m_minAltitude = m_minAltitude,
					m_maxAltitude = m_maxAltitude,
					m_minTilt = m_minTilt,
					m_maxTilt = m_maxTilt,
					m_huntPlayer = m_huntPlayer,
					m_groundOffset = m_groundOffset,
					m_maxLevel = m_maxLevel,
					m_minLevel = m_minLevel,
					m_levelUpMinCenterDistance = m_levelUpMinCenterDistance,
					m_overrideLevelupChance = m_overrideLevelUpChance,
					m_foldout = m_foldout
				};
			}
		}

		[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(0)]
		public class Critter
		{
			[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(0)]
			public class CharacterData
			{
				public Faction m_faction = (Faction)0;

				public readonly bool m_isBoss = false;

				public readonly string m_bossEvent = "";

				public float m_speed;

				public bool m_tolerateWater;

				public bool m_tolerateFire;

				public bool m_tolerateSmoke;

				public bool m_tolerateTar;

				public float m_health;

				public DamageModifiers m_damageModifiers = default(DamageModifiers);

				public readonly List<string> m_hitEffects = new List<string>();

				public readonly List<string> m_deathEffects = new List<string>();

				public readonly List<string> m_jumpEffects = new List<string>();

				public readonly List<string> m_consumeItemEffects = new List<string>();

				public readonly List<string> m_waterEffects = new List<string>();

				public readonly List<string> m_equipEffects = new List<string>();

				public float m_damageMultiplier;
			}

			[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(0)]
			public class Tame
			{
				public float FedDuration;

				public float TameTime;

				public bool StartTamed;

				public readonly List<string> TamedEffects = new List<string>();

				public readonly List<string> SootheEffects = new List<string>();

				public readonly List<string> PetEffects = new List<string>();

				public bool Command;

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

				public SkillType LevelUpSkill = (SkillType)110;

				[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(2)]
				public Sprite SaddleIcon;
			}

			[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(0)]
			public class MonsterAIData
			{
				public readonly string m_spawnMessage = "";

				public readonly string m_deathMessage = "";

				public readonly List<string> m_alertedEffects = new List<string>();

				public readonly List<string> m_idleSounds = new List<string>();

				public readonly List<string> m_consumeItems = new List<string>();
			}

			[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(0)]
			public class Attack
			{
				[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(2)]
				public GameObject Prefab;

				public readonly bool m_custom;

				public string m_prefabName;

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

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

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

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

				public Attack(string prefabName, AssetBundle bundle)
				{
					Prefab = bundle.LoadAsset<GameObject>(prefabName);
					m_prefabName = prefabName;
					m_custom = true;
				}

				public Attack(string prefabName)
				{
					m_prefabName = prefabName;
				}
			}

			[<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)]
			public class DropData
			{
				[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(1)]
				public string m_prefabName = null;

				public int m_min;

				public int m_max;

				public float m_chance;

				public bool m_onePerPlayer;

				public bool m_levelMultiplier;

				public bool m_doNotScale;
			}

			[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(0)]
			public class StatusEffectData
			{
				public ConfigEntry<float> m_damageMultiplier = null;

				public ConfigEntry<float> m_armorMultiplier = null;
			}

			public string m_saddleItem = "";

			public readonly bool isCustom;

			public readonly bool isClone;

			public Color32 m_color;

			[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(2)]
			public Texture m_texture;

			public readonly string m_cloneName;

			public readonly string m_creatureName;

			public readonly string m_name;

			public readonly bool m_enabled = true;

			public GameObject m_prefab = null;

			public Biome m_biome = (Biome)0;

			public readonly BiomeArea m_biomeArea = (BiomeArea)3;

			public int m_maxSpawned = 1;

			public float m_spawnInterval = 100f;

			public float m_spawnDistance = 50f;

			public float m_spawnRadiusMin = 10f;

			public float m_spawnRadiusMax = 100f;

			public string m_requiredGlobalKey = "";

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

			public int m_groupSizeMin = 0;

			public int m_groupSizeMax = 1;

			public float m_groupRadius = 50f;

			public bool m_spawnAtNight = true;

			public bool m_spawnAtDay = true;

			public float m_minAltitude = -1000f;

			public float m_maxAltitude = 1000f;

			public float m_minTilt = 0f;

			public float m_maxTilt = 50f;

			public bool m_huntPlayer = false;

			public float m_groundOffset = 0.5f;

			public int m_maxLevel = 3;

			public int m_minLevel = 1;

			public float m_levelUpMinCenterDistance = 1f;

			public float m_overrideLevelUpChance = 0f;

			public bool m_foldout = false;

			public readonly CharacterData m_characterData = new CharacterData();

			public readonly Tame m_tame = new Tame();

			public DamageTypes m_damages = default(DamageTypes);

			public readonly MonsterAIData m_monsterData = new MonsterAIData();

			public readonly List<Attack> m_attacks = new List<Attack>();

			public bool m_replaceAttacks;

			public string m_footStepClone = "";

			public readonly List<DropData> m_dropData = new List<DropData>();

			[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(2)]
			public readonly StatusEffectData m_statusEffect;

			[<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(2)]
			public CreatureStatus m_effect;

			public void SetMainTexture(Texture texture)
			{
				m_texture = texture;
			}

			public void SetSaddleItem(string item)
			{
				m_saddleItem = item;
			}

			public void AddTameEffect(string effectName)
			{
				m_tame.TamedEffects.Add(effectName);
			}

			public void AddSootheEffect(string effectName)
			{
				m_tame.SootheEffects.Add(effectName);
			}

			public void AddPetEffect(string effectName)
			{
				m_tame.PetEffects.Add(effectName);
			}

			public void AddConsumeEffect(string effectName)
			{
				m_characterData.m_consumeItemEffects.Add(effectName);
			}

			public void AddWaterEffect(string effectName)
			{
				m_characterData.m_waterEffects.Add(effectName);
			}

			public void SetSaddleIcon(Sprite sprite)
			{
				m_tame.SaddleIcon = sprite;
			}

			public void MultiplyDefaultItems(float amount)
			{
				m_characterData.m_damageMultiplier = amount;
			}

			public void AddDamage(DamageType type, float amount)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				//IL_0004: Unknown result type (might be due to invalid IL or missing references)
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Invalid comparison between Unknown and I4
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Invalid comparison between Unknown and I4
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Invalid comparison between Unknown and I4
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0073: Invalid comparison between Unknown and I4
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Invalid comparison between Unknown and I4
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Invalid comparison between Unknown and I4
				//IL_000e: 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_0026: Expected I4, but got Unknown
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0080: Invalid comparison between Unknown and I4
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: Invalid comparison between Unknown and I4
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Invalid comparison between Unknown and I4
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Invalid comparison between Unknown and I4
				if ((int)type <= 32)
				{
					if ((int)type <= 8)
					{
						switch (type - 1)
						{
						case 0:
							m_damages.m_blunt += amount;
							return;
						case 1:
							m_damages.m_slash += amount;
							return;
						case 3:
							m_damages.m_pierce += amount;
							return;
						case 2:
							return;
						}
						if ((int)type == 8)
						{
							m_damages.m_chop += amount;
						}
					}
					else if ((int)type != 16)
					{
						if ((int)type == 32)
						{
							m_damages.m_fire += amount;
						}
					}
					else
					{
						m_damages.m_pickaxe += amount;
					}
				}
				else if ((int)type <= 128)
				{
					if ((int)type != 64)
					{
						if ((int)type == 128)
						{
							m_damages.m_lightning += amount;
						}
					}
					else
					{
						m_damages.m_frost += amount;
					}
				}
				else if ((int)type != 256)
				{
					if ((int)type == 512)
					{
						m_damages.m_spirit += amount;
					}
				}
				else
				{
					m_damages.m_poison += amount;
				}
			}

			public void AddHitEffect(string effectName)
			{
				m_characterData.m_hitEffects.Add(effectName);
			}

			public void AddDeathEffect(string effectName)
			{
				m_characterData.m_deathEffects.Add(effectName);
			}

			public void AddJumpEffect(string effectName)
			{
				m_characterData.m_jumpEffects.Add(effectName);
			}

			public void AddEquipEffect(string effectName)
			{
				m_characterData.m_equipEffects.Add(effectName);
			}

			public void AddConsumeItem(string name)
			{
				m_monsterData.m_consumeItems.Add(name);
			}

			public void AddAlertedEffect(string effectName)
			{
				m_monsterData.m_alertedEffects.Add(effectName);
			}

			public void AddIdleSound(string effectName)
			{
				m_monsterData.m_idleSounds.Add(effectName);
			}

			public void ReplaceAttack(string attackName, AssetBundle bundleName, [<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(new byte[] { 2, 1 })] List<string> triggerEffects = null, [<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(new byte[] { 2, 1 })] List<string> trailEffects = null)
			{
				Attack attack = new Attack(attackName, bundleName);
				if (triggerEffects != null)
				{
					attack.m_triggerEffects = triggerEffects;
				}
				if (trailEffects != null)
				{
					attack.m_trailStartEffects = trailEffects;
				}
				m_attacks.Add(attack);
				m_replaceAttacks = true;
			}

			public void EditAttack(string attackName, [<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(new byte[] { 2, 1 })] List<string> startEffects = null, [<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(new byte[] { 2, 1 })] List<string> triggerEffects = null, [<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(new byte[] { 2, 1 })] List<string> trailEffects = null, [<ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(new byte[] { 2, 1 })] List<string> hitEffects = null)
			{
				Attack attack = new Attack(attackName);
				if (triggerEffects != null)
				{
					attack.m_triggerEffects = triggerEffects;
				}
				if (trailEffects != null)
				{
					attack.m_trailStartEffects = trailEffects;
				}
				if (startEffects != null)
				{
					attack.m_startEffects = startEffects;
				}
				if (hitEffects != null)
				{
					attack.m_hitEffects = hitEffects;
				}
				m_attacks.Add(attack);
			}

			public void CloneFootStepsFrom(string prefabName)
			{
				m_footStepClone = prefabName;
			}

			public void AddDrop(string prefabName, int min, int max, float chance, bool onePerPlayer = false, bool levelMultiplier = false, bool doNotScale = false)
			{
				DropData item = new DropData
				{
					m_prefabName = prefabName,
					m_min = min,
					m_max = max,
					m_chance = chance,
					m_onePerPlayer = onePerPlayer,
					m_levelMultiplier = levelMultiplier,
					m_doNotScale = doNotScale
				};
				m_dropData.Add(item);
			}

			public Critter(string creatureName, string name, Color32 color = default(Color32), bool clone = false, string cloneName = "")
			{
				//IL_001b: 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_011c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0165: Unknown result type (might be due to invalid IL or missing references)
				//IL_0166: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b6: Expected O, but got Unknown
				//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f0: Expected O, but got Unknown
				m_creatureName = creatureName;
				m_name = name;
				m_color = color;
				isClone = clone;
				m_cloneName = cloneName;
				m_statusEffect = new StatusEffectData
				{
					m_damageMultiplier = BestiaryPlugin._Plugin.config(name, "Damage Multiplier", 1f, new ConfigDescription("Set damage multiplier", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())),
					m_armorMultiplier = BestiaryPlugin._Plugin.config(name, "Damage Taken", 1f, new ConfigDescription("Set the damage reduction multiplier", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()))
				};
				m_critters.Add(this);
			}

			public Critter(string creatureName, AssetBundle bundle)
			{
				//IL_001b: 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_011c: Unknown result type (might be due to invalid IL or missing references)
				//IL_01af: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ba: Expected O, but got Unknown
				//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f4: Expected O, but got Unknown
				m_creatureName = creatureName;
				m_cloneName = creatureName;
				m_name = creatureName;
				m_prefab = bundle.LoadAsset<GameObject>(creatureName);
				isCustom = true;
				m_statusEffect = new StatusEffectData
				{
					m_damageMultiplier = BestiaryPlugin._Plugin.config(creatureName, "Damage Multiplier", 1f, new ConfigDescription("Set damage multiplier", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())),
					m_armorMultiplier = BestiaryPlugin._Plugin.config(creatureName, "Armor Multiplier", 1f, new ConfigDescription("Set the damage reduction multiplier", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()))
				};
				m_critters.Add(this);
			}

			public SpawnData GetSpawnData()
			{
				//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_0012: 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_002a: 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)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: 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_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0096: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c6: 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_00de: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
				//IL_0102: Unknown result type (might be due to invalid IL or missing references)
				//IL_010e: Unknown result type (might be due to invalid IL or missing references)
				//IL_011a: 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_0132: Unknown result type (might be due to invalid IL or missing references)
				//IL_013e: Unknown result type (might be due to invalid IL or missing references)
				//IL_014a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0157: Expected O, but got Unknown
				return new SpawnData
				{
					m_name = m_name,
					m_enabled = m_enabled,
					m_prefab = m_prefab,
					m_biome = m_biome,
					m_biomeArea = m_biomeArea,
					m_maxSpawned = m_maxSpawned,
					m_spawnInterval = m_spawnInterval,
					m_spawnDistance = m_spawnDistance,
					m_spawnRadiusMin = m_spawnRadiusMin,
					m_spawnRadiusMax = m_spawnRadiusMax,
					m_requiredGlobalKey = m_requiredGlobalKey,
					m_requiredEnvironments = m_requiredEnvironments,
					m_groupSizeMin = m_groupSizeMin,
					m_groupSizeMax = m_groupSizeMax,
					m_groupRadius = m_groupRadius,
					m_spawnAtNight = m_spawnAtNight,
					m_spawnAtDay = m_spawnAtDay,
					m_minAltitude = m_minAltitude,
					m_maxAltitude = m_maxAltitude,
					m_minTilt = m_minTilt,
					m_maxTilt = m_maxTilt,
					m_huntPlayer = m_huntPlayer,
					m_groundOffset = m_groundOffset,
					m_maxLevel = m_maxLevel,
					m_minLevel = m_minLevel,
					m_levelUpMinCenterDistance = m_levelUpMinCenterDistance,
					m_overrideLevelupChance = m_overrideLevelUpChance,
					m_foldout = m_foldout
				};
			}
		}

		private static readonly List<Critter> m_critters;

		private static readonly List<Bird> m_birds;

		private static readonly Dictionary<string, AssetBundle> m_effects;

		private static readonly HashSet<Shader> m_cachedShaders;

		private static readonly int MainTex;

		private static readonly List<ProjectileData> m_projectiles;

		private static readonly int Hue;

		static FaunaManager()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Expected O, but got Unknown
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Expected O, but got Unknown
			m_critters = new List<Critter>();
			m_birds = new List<Bird>();
			m_effects = new Dictionary<string, AssetBundle>();
			m_cachedShaders = new HashSet<Shader>();
			MainTex = Shader.PropertyToID("_MainTex");
			m_projectiles = new List<ProjectileData>();
			Hue = Shader.PropertyToID("_Hue");
			Harmony val = new Harmony("org.bepinex.helpers.FaunaManager");
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ZNetScene), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(FaunaManager), "Load_Fauna_Patch", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(SpawnSystem), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(FaunaManager), "Patch_SpawnSystem_Awake", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ObjectDB), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(FaunaManager), "ObjectDB_RegisterCustomItems_Patch", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Character), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(FaunaManager), "AddCreatureStatus", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		internal static void AddCreatureStatus(Character __instance)
		{
			if (Object.op_Implicit((Object)(object)__instance))
			{
				Critter critter = m_critters.Find((Critter x) => x.m_name == ((Object)__instance).name.Replace("(Clone)", string.Empty));
				if (critter != null && (Object)(object)critter.m_effect != (Object)null)
				{
					__instance.GetSEMan().AddStatusEffect((StatusEffect)(object)critter.m_effect, false, 0, 0f);
				}
			}
		}

		[HarmonyPriority(0)]
		internal static void ObjectDB_RegisterCustomItems_Patch(ObjectDB __instance)
		{
			if (!Object.op_Implicit((Object)(object)ZNetScene.instance))
			{
				return;
			}
			Humanoid val = default(Humanoid);
			foreach (Critter critter in m_critters)
			{
				if (!Object.op_Implicit((Object)(object)critter.m_prefab))
				{
					continue;
				}
				if (critter.m_statusEffect != null)
				{
					CreatureStatus creatureStatus = ScriptableObject.CreateInstance<CreatureStatus>();
					creatureStatus.m_data = critter.m_statusEffect;
					((Object)creatureStatus).name = "SE_" + critter.m_name;
					if (!__instance.m_StatusEffects.Contains((StatusEffect)(object)creatureStatus))
					{
						__instance.m_StatusEffects.Add((StatusEffect)(object)creatureStatus);
					}
					critter.m_effect = creatureStatus;
				}
				if (!critter.m_prefab.TryGetComponent<Humanoid>(ref val))
				{
					continue;
				}
				if (critter.m_characterData.m_damageMultiplier > 0f)
				{
					ManipulateItemArray(ZNetScene.instance, __instance, critter, ref val.m_defaultItems);
					ManipulateItemArray(ZNetScene.instance, __instance, critter, ref val.m_randomWeapon);
				}
				if (((DamageTypes)(ref critter.m_damages)).HaveDamage())
				{
					AddDamages(critter, ref val.m_defaultItems);
					AddDamages(critter, ref val.m_randomWeapon);
				}
				AddCharacterDrops(ZNetScene.instance, critter, critter.m_prefab);
				AddSaddle(__instance, critter);
				AddConsumeItems(__instance, critter);
				GameObject[] defaultItems = val.m_defaultItems;
				foreach (GameObject val2 in defaultItems)
				{
					if (Object.op_Implicit((Object)(object)val2.GetComponent<ZNetView>()))
					{
						RegisterToObjectDB(__instance, val2);
						RegisterToZNetScene(ZNetScene.instance, val2);
					}
				}
			}
			GameObject prefab = ZNetScene.instance.GetPrefab("SaddleBeast");
			GameObject itemPrefab = __instance.GetItemPrefab("TrophySaddleBeast");
			Sadle componentInChildren = prefab.GetComponentInChildren<Sadle>(true);
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				componentInChildren.m_mountIcon = itemPrefab.GetComponent<ItemDrop>().m_itemData.GetIcon();
			}
		}

		private static void EditTame(ZNetScene __instance, Critter critter)
		{
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Expected O, but got Unknown
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Expected O, but got Unknown
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Expected O, but got Unknown
			Tameable val = default(Tameable);
			if (Object.op_Implicit((Object)(object)critter.m_prefab) && critter.m_prefab.TryGetComponent<Tameable>(ref val))
			{
				List<EffectData> list = (from name in critter.m_tame.TamedEffects
					select __instance.GetPrefab(name) into effect
					where Object.op_Implicit((Object)(object)effect)
					select effect).Select((Func<GameObject, EffectData>)([<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (GameObject effect) => new EffectData
				{
					m_prefab = effect,
					m_enabled = true
				})).ToList();
				List<EffectData> list2 = (from name in critter.m_tame.SootheEffects
					select __instance.GetPrefab(name) into effect
					where Object.op_Implicit((Object)(object)effect)
					select effect).Select((Func<GameObject, EffectData>)([<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (GameObject effect) => new EffectData
				{
					m_prefab = effect,
					m_enabled = true
				})).ToList();
				List<EffectData> list3 = (from name in critter.m_tame.PetEffects
					select __instance.GetPrefab(name) into effect
					where Object.op_Implicit((Object)(object)effect)
					select effect).Select((Func<GameObject, EffectData>)([<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (GameObject effect) => new EffectData
				{
					m_prefab = effect,
					m_enabled = true
				})).ToList();
				val.m_tamedEffect = new EffectList
				{
					m_effectPrefabs = list.ToArray()
				};
				val.m_sootheEffect = new EffectList
				{
					m_effectPrefabs = list2.ToArray()
				};
				val.m_petEffect = new EffectList
				{
					m_effectPrefabs = list3.ToArray()
				};
			}
		}

		private static void AddSaddle(ObjectDB __instance, Critter critter)
		{
			if (!Utility.IsNullOrWhiteSpace(critter.m_saddleItem))
			{
				GameObject itemPrefab = __instance.GetItemPrefab(critter.m_saddleItem);
				ItemDrop saddleItem = default(ItemDrop);
				Tameable val = default(Tameable);
				if (Object.op_Implicit((Object)(object)itemPrefab) && itemPrefab.TryGetComponent<ItemDrop>(ref saddleItem) && critter.m_prefab.TryGetComponent<Tameable>(ref val))
				{
					val.m_saddleItem = saddleItem;
				}
			}
		}

		private static void RegisterToObjectDB(ObjectDB __instance, GameObject prefab)
		{
			if (!__instance.m_items.Contains(prefab))
			{
				__instance.m_items.Add(prefab);
			}
			__instance.m_itemByHash[StringExtensionMethods.GetStableHashCode(((Object)prefab).name)] = prefab;
		}

		public static void RegisterAssetToZNetScene(string EffectName, AssetBundle bundle)
		{
			m_effects[EffectName] = bundle;
		}

		internal static void Load_Fauna_Patch(ZNetScene __instance)
		{
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			RegisterCustomAssets(__instance);
			SpawnSystemList root = BestiaryPlugin._Root.AddComponent<SpawnSystemList>();
			List<SpawnData> list = new List<SpawnData>();
			foreach (Critter critter in m_critters)
			{
				if (!critter.isCustom)
				{
					GameObject prefab = GetPrefab(__instance, critter);
					if ((Object)(object)prefab == (Object)null)
					{
						continue;
					}
					critter.m_prefab = prefab;
				}
				else
				{
					EditHumanoid(__instance, critter.m_prefab, critter);
					EditMonsterAI(__instance, critter.m_prefab, critter);
					EditTame(__instance, critter);
					CloneFootSteps(__instance, critter);
					RegisterToZNetScene(__instance, critter.m_prefab);
				}
				SpawnData data = critter.GetSpawnData();
				ConfigEntry<Biome> biome = BestiaryPlugin._Plugin.config<Biome>(critter.m_name, "Biome", data.m_biome, "Set biome");
				ConfigEntry<float> interval = BestiaryPlugin._Plugin.config(critter.m_name, "Spawn Interval", data.m_spawnInterval, "Set spawn interval");
				ConfigEntry<int> max = BestiaryPlugin._Plugin.config(critter.m_name, "Max Spawned", data.m_maxSpawned, "Set max amount spawned");
				biome.SettingChanged += [<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (object sender, EventArgs args) =>
				{
					//IL_0042: Unknown result type (might be due to invalid IL or missing references)
					//IL_0047: Unknown result type (might be due to invalid IL or missing references)
					SpawnData val3 = list.Find((SpawnData x) => x.m_name == data.m_name);
					if (val3 != null)
					{
						val3.m_biome = biome.Value;
					}
				};
				interval.SettingChanged += [<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (object sender, EventArgs args) =>
				{
					SpawnData val2 = list.Find((SpawnData x) => x.m_name == data.m_name);
					if (val2 != null)
					{
						val2.m_spawnInterval = interval.Value;
					}
				};
				max.SettingChanged += [<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (object sender, EventArgs args) =>
				{
					SpawnData val = list.Find((SpawnData x) => x.m_name == data.m_name);
					if (val != null)
					{
						val.m_maxSpawned = max.Value;
					}
				};
				data.m_biome = biome.Value;
				data.m_spawnInterval = interval.Value;
				data.m_maxSpawned = max.Value;
				list.Add(data);
			}
			root.m_spawners = list;
			AddBirds(__instance, ref root);
		}

		private static void AddBirds(ZNetScene __instance, ref SpawnSystemList root)
		{
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: 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_02ab: Expected O, but got Unknown
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Expected O, but got Unknown
			//IL_069f: Unknown result type (might be due to invalid IL or missing references)
			//IL_06aa: Expected O, but got Unknown
			//IL_04c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_051f: Unknown result type (might be due to invalid IL or missing references)
			List<SpawnData> list = root.m_spawners;
			RandomFlyingBird randomFlyingBird = default(RandomFlyingBird);
			Destructible destructible = default(Destructible);
			DropOnDestroyed dropOnDestroyed = default(DropOnDestroyed);
			foreach (Bird bird in m_birds)
			{
				if (bird.m_prefab.TryGetComponent<RandomFlyingBird>(ref randomFlyingBird))
				{
					randomFlyingBird.m_flyRange = bird.m_range.Value;
					randomFlyingBird.m_minAlt = 5f;
					randomFlyingBird.m_maxAlt = 20f;
					randomFlyingBird.m_speed = bird.m_speed.Value;
					randomFlyingBird.m_turnRate = 10f;
					randomFlyingBird.m_wpDuration = 1f;
					randomFlyingBird.m_flapDuration = 2f;
					randomFlyingBird.m_sailDuration = 0.2f;
					randomFlyingBird.m_landChance = 0.2f;
					randomFlyingBird.m_landDuration = 10f;
					randomFlyingBird.m_avoidDangerDistance = 10f;
					randomFlyingBird.m_noRandomFlightAtNight = false;
					randomFlyingBird.m_randomNoiseIntervalMin = 5f;
					randomFlyingBird.m_randomNoiseIntervalMax = 10f;
					randomFlyingBird.m_noNoiseAtNight = true;
					randomFlyingBird.m_singleModel = true;
					bird.m_range.SettingChanged += [<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (object sender, EventArgs args) =>
					{
						randomFlyingBird.m_flyRange = bird.m_range.Value;
					};
					bird.m_speed.SettingChanged += [<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (object sender, EventArgs args) =>
					{
						randomFlyingBird.m_speed = bird.m_speed.Value;
					};
				}
				if (bird.m_prefab.TryGetComponent<Destructible>(ref destructible))
				{
					destructible.m_health = bird.m_health.Value;
					bird.m_health.SettingChanged += [<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (object sender, EventArgs args) =>
					{
						destructible.m_health = bird.m_health.Value;
					};
					List<EffectData> list2 = new List<EffectData>();
					foreach (string destroyedEffect in bird.m_destroyedEffects)
					{
						GameObject prefab = __instance.GetPrefab(destroyedEffect);
						if (Object.op_Implicit((Object)(object)prefab))
						{
							list2.Add(new EffectData
							{
								m_prefab = prefab,
								m_enabled = true
							});
						}
					}
					destructible.m_destroyedEffect = new EffectList
					{
						m_effectPrefabs = list2.ToArray()
					};
				}
				if (bird.m_prefab.TryGetComponent<DropOnDestroyed>(ref dropOnDestroyed))
				{
					List<DropData> list3 = new List<DropData>();
					List<string> list4 = new List<string>();
					foreach (Critter.DropData dropDatum in bird.m_dropData)
					{
						GameObject prefab2 = __instance.GetPrefab(dropDatum.m_prefabName);
						if (Object.op_Implicit((Object)(object)prefab2))
						{
							list4.Add($"{((Object)prefab2).name}:{dropDatum.m_min}:{dropDatum.m_max}:{dropDatum.m_chance}");
						}
					}
					ConfigEntry<string> config = BestiaryPlugin._Plugin.config(bird.m_name, "Drops", string.Join(",", list4), "Set drops, [item]:[min]:[max]:[weight]");
					string[] array = config.Value.Split(new char[1] { ',' });
					foreach (string text in array)
					{
						string[] array2 = text.Split(new char[1] { ':' });
						if (array2.Length >= 4)
						{
							GameObject prefab3 = __instance.GetPrefab(array2[0]);
							if (Object.op_Implicit((Object)(object)prefab3))
							{
								list3.Add(new DropData
								{
									m_item = prefab3,
									m_stackMin = ((!int.TryParse(array2[1], out var result)) ? 1 : result),
									m_stackMax = ((!int.TryParse(array2[2], out var result2)) ? 1 : result2),
									m_weight = (float.TryParse(array2[3], out var result3) ? result3 : 1f)
								});
							}
						}
					}
					dropOnDestroyed.m_dropWhenDestroyed.m_drops = list3;
					config.SettingChanged += [<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (object sender, EventArgs args) =>
					{
						//IL_008a: 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)
						List<DropData> list5 = new List<DropData>();
						string[] array3 = config.Value.Split(new char[1] { ',' });
						foreach (string text2 in array3)
						{
							string[] array4 = text2.Split(new char[1] { ':' });
							if (array4.Length >= 4)
							{
								GameObject prefab4 = __instance.GetPrefab(array4[0]);
								if (Object.op_Implicit((Object)(object)prefab4))
								{
									list5.Add(new DropData
									{
										m_item = prefab4,
										m_stackMin = ((!int.TryParse(array4[1], out var result4)) ? 1 : result4),
										m_stackMax = ((!int.TryParse(array4[2], out var result5)) ? 1 : result5),
										m_weight = (float.TryParse(array4[3], out var result6) ? result6 : 1f)
									});
								}
							}
						}
						dropOnDestroyed.m_dropWhenDestroyed.m_drops = list5;
					};
				}
				if (!Utility.IsNullOrWhiteSpace(bird.m_shader))
				{
					GetShadersFromBundles();
					Renderer[] componentsInChildren = bird.m_prefab.GetComponentsInChildren<Renderer>(true);
					foreach (Renderer val in componentsInChildren)
					{
						Material[] sharedMaterials = val.sharedMaterials;
						foreach (Material material in sharedMaterials)
						{
							if ((Object)(object)material == (Object)null)
							{
								continue;
							}
							material.shader = GetShader(bird.m_shader, material.shader);
							if (material.HasProperty(Hue))
							{
								ConfigEntry<float> hue = BestiaryPlugin._Plugin.config(bird.m_name, "Hue", material.GetFloat(Hue), new ConfigDescription("Set hue", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.5f, 0.5f), Array.Empty<object>()));
								hue.SettingChanged += [<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (object sender, EventArgs args) =>
								{
									material.SetFloat(Hue, hue.Value);
								};
							}
						}
					}
				}
				RegisterToZNetScene(__instance, bird.m_prefab);
				SpawnData data = bird.GetSpawnData();
				bird.m_biome.SettingChanged += [<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (object sender, EventArgs args) =>
				{
					//IL_0047: Unknown result type (might be due to invalid IL or missing references)
					//IL_004c: Unknown result type (might be due to invalid IL or missing references)
					SpawnData val4 = list.Find([<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (SpawnData x) => x.m_name == data.m_name);
					val4.m_biome = bird.m_biome.Value;
				};
				bird.m_maxSpawned.SettingChanged += [<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (object sender, EventArgs args) =>
				{
					SpawnData val3 = list.Find([<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (SpawnData x) => x.m_name == data.m_name);
					val3.m_maxSpawned = bird.m_maxSpawned.Value;
				};
				bird.m_spawnInterval.SettingChanged += [<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (object sender, EventArgs args) =>
				{
					SpawnData val2 = list.Find([<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (SpawnData x) => x.m_name == data.m_name);
					val2.m_spawnInterval = bird.m_spawnInterval.Value;
				};
				list.Add(data);
			}
			root.m_spawners = list;
		}

		private static Shader GetShader(string name, Shader original)
		{
			foreach (Shader cachedShader in m_cachedShaders)
			{
				if (((Object)cachedShader).name == name)
				{
					return cachedShader;
				}
			}
			return original;
		}

		private static void GetShadersFromBundles()
		{
			if (m_cachedShaders.Count != 0)
			{
				return;
			}
			AssetBundle[] array = Resources.FindObjectsOfTypeAll<AssetBundle>();
			foreach (AssetBundle val in array)
			{
				IEnumerable<Shader> enumerable3;
				try
				{
					IEnumerable<Shader> enumerable2;
					if (!val.isStreamedSceneAssetBundle || !Object.op_Implicit((Object)(object)val))
					{
						IEnumerable<Shader> enumerable = val.LoadAllAssets<Shader>();
						enumerable2 = enumerable;
					}
					else
					{
						enumerable2 = from shader in ((IEnumerable<string>)val.GetAllAssetNames()).Select((Func<string, Shader>)val.LoadAsset<Shader>)
							where (Object)(object)shader != (Object)null
							select shader;
					}
					enumerable3 = enumerable2;
				}
				catch (Exception)
				{
					continue;
				}
				if (enumerable3 == null)
				{
					continue;
				}
				foreach (Shader item in enumerable3)
				{
					m_cachedShaders.Add(item);
				}
			}
		}

		private static void CloneFootSteps(ZNetScene __instance, Critter critter)
		{
			FootStep val = default(FootStep);
			if (Object.op_Implicit((Object)(object)critter.m_prefab) && !Utility.IsNullOrWhiteSpace(critter.m_footStepClone) && critter.m_prefab.TryGetComponent<FootStep>(ref val))
			{
				GameObject prefab = __instance.GetPrefab(critter.m_footStepClone);
				FootStep val2 = default(FootStep);
				if (Object.op_Implicit((Object)(object)prefab) && prefab.TryGetComponent<FootStep>(ref val2))
				{
					val.m_effects = val2.m_effects;
				}
			}
		}

		internal static void Patch_SpawnSystem_Awake(SpawnSystem __instance)
		{
			SpawnSystemList item = default(SpawnSystemList);
			if (BestiaryPlugin._Root.TryGetComponent<SpawnSystemList>(ref item))
			{
				__instance.m_spawnLists.Add(item);
			}
		}

		[return: <ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(2)]
		private static GameObject GetPrefab(ZNetScene __instance, Critter critter)
		{
			GameObject result;
			if (critter.isClone)
			{
				GameObject val = CreateClone(__instance, critter);
				if ((Object)(object)val == (Object)null)
				{
					return null;
				}
				result = val;
			}
			else
			{
				GameObject original = GetOriginal(__instance, critter);
				if ((Object)(object)original == (Object)null)
				{
					return null;
				}
				result = original;
			}
			return result;
		}

		[return: <ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(2)]
		private static GameObject GetOriginal(ZNetScene __instance, Critter critter)
		{
			return __instance.GetPrefab(critter.m_creatureName);
		}

		[return: <ee909b8e-360a-4106-bf5d-9643cb184aaf>Nullable(2)]
		private static GameObject CreateClone(ZNetScene __instance, Critter critter)
		{
			GameObject prefab = __instance.GetPrefab(critter.m_creatureName);
			if (!Object.op_Implicit((Object)(object)prefab))
			{
				return null;
			}
			GameObject val = Object.Instantiate<GameObject>(prefab, BestiaryPlugin._Root.transform, false);
			((Object)val).name = critter.m_cloneName;
			ManipulateMaterial(__instance, val, critter);
			if (critter.m_cloneName == "BlobIce")
			{
				Transform val2 = Utils.FindChild(val.transform, "particles", (IterativeSearchType)0);
				Object.Destroy((Object)(object)((Component)val2).gameObject);
			}
			EditHumanoid(__instance, val, critter);
			EditMonsterAI(__instance, val, critter);
			CreateNewRagdoll(__instance, critter, val);
			RegisterToZNetScene(__instance, val);
			return val;
		}

		private static void EditMonsterAI(ZNetScene __instance, GameObject prefab, Critter critter)
		{
			MonsterAI val = default(MonsterAI);
			if (prefab.TryGetComponent<MonsterAI>(ref val))
			{
				((BaseAI)val).m_spawnMessage = critter.m_monsterData.m_spawnMessage;
				((BaseAI)val).m_deathMessage = critter.m_monsterData.m_deathMessage;
				AddAlertedEffects(__instance, val, critter);
				AddIdleSounds(__instance, val, critter);
			}
		}

		private static void AddConsumeItems(ObjectDB __instance, Critter critter)
		{
			MonsterAI monsterAI = default(MonsterAI);
			if (!Object.op_Implicit((Object)(object)critter.m_prefab) || !critter.m_prefab.TryGetComponent<MonsterAI>(ref monsterAI))
			{
				return;
			}
			List<ItemDrop> list = new List<ItemDrop>();
			ItemDrop item = default(ItemDrop);
			foreach (GameObject item4 in from prefab in ((IEnumerable<string>)critter.m_monsterData.m_consumeItems).Select((Func<string, GameObject>)__instance.GetItemPrefab)
				where Object.op_Implicit((Object)(object)prefab)
				select prefab)
			{
				if (item4.TryGetComponent<ItemDrop>(ref item))
				{
					list.Add(item);
				}
			}
			monsterAI.m_consumeItems = list;
			List<string> values = monsterAI.m_consumeItems.Select([<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (ItemDrop x) => ((Object)x).name).ToList();
			ConfigEntry<string> config = BestiaryPlugin._Plugin.config(critter.m_name, "Consume Items", string.Join(",", values), "Set items creature can consume");
			List<ItemDrop> list2 = new List<ItemDrop>();
			string[] source = config.Value.Split(new char[1] { ',' });
			ItemDrop item2 = default(ItemDrop);
			foreach (GameObject item5 in from prefab in ((IEnumerable<string>)source).Select((Func<string, GameObject>)__instance.GetItemPrefab)
				where Object.op_Implicit((Object)(object)prefab)
				select prefab)
			{
				if (item5.TryGetComponent<ItemDrop>(ref item2))
				{
					list2.Add(item2);
				}
			}
			monsterAI.m_consumeItems = list2;
			config.SettingChanged += [<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (object sender, EventArgs args) =>
			{
				List<ItemDrop> list3 = new List<ItemDrop>();
				string[] source2 = config.Value.Split(new char[1] { ',' });
				ItemDrop item3 = default(ItemDrop);
				foreach (GameObject item6 in from prefab in ((IEnumerable<string>)source2).Select((Func<string, GameObject>)__instance.GetItemPrefab)
					where Object.op_Implicit((Object)(object)prefab)
					select prefab)
				{
					if (item6.TryGetComponent<ItemDrop>(ref item3))
					{
						list3.Add(item3);
					}
				}
				monsterAI.m_consumeItems = list3;
			};
		}

		private static void AddIdleSounds(ZNetScene __instance, MonsterAI monsterAI, Critter critter)
		{
			//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)
			//IL_00a4: Expected O, but got Unknown
			if (critter.m_monsterData.m_idleSounds.Count > 0)
			{
				((BaseAI)monsterAI).m_idleSound = new EffectList
				{
					m_effectPrefabs = (from name in critter.m_monsterData.m_idleSounds
						select __instance.GetPrefab(name) into effect
						where Object.op_Implicit((Object)(object)effect)
						select effect).Select((Func<GameObject, EffectData>)([<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (GameObject effect) => new EffectData
					{
						m_prefab = effect,
						m_enabled = true
					})).ToArray()
				};
			}
		}

		private static void AddAlertedEffects(ZNetScene __instance, MonsterAI monsterAI, Critter critter)
		{
			//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)
			//IL_00a4: Expected O, but got Unknown
			if (critter.m_monsterData.m_alertedEffects.Count > 0)
			{
				((BaseAI)monsterAI).m_alertedEffects = new EffectList
				{
					m_effectPrefabs = (from name in critter.m_monsterData.m_alertedEffects
						select __instance.GetPrefab(name) into effect
						where Object.op_Implicit((Object)(object)effect)
						select effect).Select((Func<GameObject, EffectData>)([<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (GameObject effect) => new EffectData
					{
						m_prefab = effect,
						m_enabled = true
					})).ToArray()
				};
			}
		}

		private static void EditHumanoid(ZNetScene __instance, GameObject prefab, Critter critter)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Invalid comparison between Unknown and I4
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			Humanoid humanoid = default(Humanoid);
			if (prefab.TryGetComponent<Humanoid>(ref humanoid))
			{
				((Character)humanoid).m_name = "$enemy_" + critter.m_cloneName.ToLower();
				((Character)humanoid).m_defeatSetGlobalKey = "defeated_" + critter.m_cloneName.ToLower();
				if (critter.m_characterData.m_health > 0f)
				{
					((Character)humanoid).m_health = critter.m_characterData.m_health;
				}
				if ((int)critter.m_characterData.m_faction != 0)
				{
					((Character)humanoid).m_faction = critter.m_characterData.m_faction;
				}
				((Character)humanoid).m_boss = critter.m_characterData.m_isBoss;
				((Character)humanoid).m_bossEvent = critter.m_characterData.m_bossEvent;
				AddCustomEffectList(critter.m_characterData.m_hitEffects, ref ((Character)humanoid).m_hitEffects, __instance);
				AddCustomEffectList(critter.m_characterData.m_deathEffects, ref ((Character)humanoid).m_deathEffects, __instance);
				AddCustomEffectList(critter.m_characterData.m_jumpEffects, ref ((Character)humanoid).m_jumpEffects, __instance);
				AddCustomEffectList(critter.m_characterData.m_consumeItemEffects, ref humanoid.m_consumeItemEffects, __instance);
				AddCustomEffectList(critter.m_characterData.m_waterEffects, ref ((Character)humanoid).m_waterEffects, __instance);
				AddCustomEffectList(critter.m_characterData.m_equipEffects, ref humanoid.m_equipEffects, __instance);
				EditAttackItems(__instance, critter, humanoid);
				ConfigEntry<Faction> faction = BestiaryPlugin._Plugin.config<Faction>(critter.m_name, "Faction", ((Character)humanoid).m_faction, "Set faction");
				faction.SettingChanged += [<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (object sender, EventArgs args) =>
				{
					//IL_000d: 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)
					((Character)humanoid).m_faction = faction.Value;
				};
				((Character)humanoid).m_faction = faction.Value;
				ConfigEntry<float> health = BestiaryPlugin._Plugin.config(critter.m_name, "Health", ((Character)humanoid).m_health, "Set Health");
				health.SettingChanged += [<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (object sender, EventArgs args) =>
				{
					((Character)humanoid).m_health = health.Value;
				};
				((Character)humanoid).m_health = health.Value;
			}
		}

		private static void EditAttackItems(ZNetScene __instance, Critter critter, Humanoid humanoid)
		{
			Dictionary<string, GameObject> dictionary = new Dictionary<string, GameObject>();
			if (!critter.m_replaceAttacks)
			{
				GameObject[] defaultItems = humanoid.m_defaultItems;
				foreach (GameObject val in defaultItems)
				{
					dictionary[((Object)val).name] = val;
				}
			}
			ItemDrop val2 = default(ItemDrop);
			foreach (Critter.Attack attack in critter.m_attacks)
			{
				if (!attack.m_custom)
				{
					attack.Prefab = ((IEnumerable<GameObject>)humanoid.m_defaultItems).FirstOrDefault((Func<GameObject, bool>)([<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (GameObject x) => ((Object)x).name == attack.m_prefabName));
				}
				if ((Object)(object)attack.Prefab != (Object)null && attack.Prefab.TryGetComponent<ItemDrop>(ref val2))
				{
					AddCustomEffectList(attack.m_triggerEffects, ref val2.m_itemData.m_shared.m_attack.m_triggerEffect, __instance);
					AddCustomEffectList(attack.m_trailStartEffects, ref val2.m_itemData.m_shared.m_attack.m_trailStartEffect, __instance);
					AddCustomEffectList(attack.m_startEffects, ref val2.m_itemData.m_shared.m_attack.m_startEffect, __instance);
					AddCustomEffectList(attack.m_hitEffects, ref val2.m_itemData.m_shared.m_attack.m_hitEffect, __instance);
					dictionary[((Object)attack.Prefab).name] = attack.Prefab;
				}
			}
			humanoid.m_defaultItems = dictionary.Values.ToArray();
		}

		private static void AddDamages(Critter critter, ref GameObject[] array)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if (array.Length == 0)
			{
				return;
			}
			GameObject[] array2 = array;
			ItemDrop val2 = default(ItemDrop);
			foreach (GameObject val in array2)
			{
				if (val.TryGetComponent<ItemDrop>(ref val2))
				{
					((DamageTypes)(ref val2.m_itemData.m_shared.m_damages)).Add(critter.m_damages, 1);
				}
			}
		}

		private static void ManipulateItemArray(ZNetScene __instance, ObjectDB db, Critter critter, ref GameObject[] array)
		{
			if (array.Length == 0)
			{
				return;
			}
			Dictionary<string, GameObject> dictionary = new Dictionary<string, GameObject>();
			GameObject[] array2 = array;
			foreach (GameObject val in array2)
			{
				dictionary[((Object)val).name] = val;
			}
			Dictionary<string, GameObject> m_clones = new Dictionary<string, GameObject>();
			ItemDrop val3 = default(ItemDrop);
			foreach (KeyValuePair<string, GameObject> item in dictionary)
			{
				GameObject val2 = Object.Instantiate<GameObject>(item.Value, BestiaryPlugin._Root.transform, false);
				((Object)val2).name = ((Object)item.Value).name + "_clone";
				if (val2.TryGetComponent<ItemDrop>(ref val3))
				{
					((DamageTypes)(ref val3.m_itemData.m_shared.m_damages)).Modify(critter.m_characterData.m_damageMultiplier);
					val3.m_itemData.m_dropPrefab = item.Value;
					RegisterToZNetScene(__instance, val2);
					RegisterToObjectDB(db, val2);
					m_clones[item.Key] = val2;
				}
			}
			GameObject[] array3 = array.Select([<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (GameObject prefab) => m_clones[((Object)prefab).name]).ToArray();
			array = array3;
		}

		private static void AddCharacterDrops(ZNetScene __instance, Critter critter, GameObject clone)
		{
			//IL_0089: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Expected O, but got Unknown
			CharacterDrop component = default(CharacterDrop);
			if (!clone.TryGetComponent<CharacterDrop>(ref component) || critter.m_dropData.Count == 0)
			{
				return;
			}
			List<Drop> list = new List<Drop>();
			foreach (Critter.DropData dropDatum in critter.m_dropData)
			{
				GameObject prefab = __instance.GetPrefab(dropDatum.m_prefabName);
				if (Object.op_Implicit((Object)(object)prefab))
				{
					list.Add(new Drop
					{
						m_prefab = prefab,
						m_amountMin = dropDatum.m_min,
						m_amountMax = dropDatum.m_max,
						m_chance = dropDatum.m_chance,
						m_levelMultiplier = dropDatum.m_levelMultiplier,
						m_onePerPlayer = dropDatum.m_onePerPlayer,
						m_dontScale = dropDatum.m_doNotScale
					});
				}
			}
			component.m_drops = list;
			List<string> list2 = new List<string>();
			foreach (Drop drop in component.m_drops)
			{
				list2.Add($"{((Object)drop.m_prefab).name}:{drop.m_amountMin}:{drop.m_amountMax}:{drop.m_chance}");
			}
			ConfigEntry<string> itemConfig = BestiaryPlugin._Plugin.config(critter.m_name, "Drops", string.Join(",", list2), "Set the character drops, [prefabName]:[min]:[max]:[chance], ... ,");
			itemConfig.SettingChanged += [<bc81c85a-17ab-456a-9686-bd620947be46>NullableContext(0)] (object sender, EventArgs args) =>
			{
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00eb: Expected O, but got Unknown
				string[] array = itemConfig.Value.Split(new char[1] { ',' });
				List<Drop> list3 = new List<Drop>();
				string[] array2 = array;
				foreach (string text in array2)
				{
					string[] array3 = text.Split(new char[1] { ':' });
					if (array3.Length >= 4)
					{
						string text2 = array3[0];
						string s = array3[1];
						string s2 = array3[2];
						string s3 = array3[3];
						GameObject prefab2 = __instance.GetPrefab(text2);
						if (Object.op_Implicit((Object)(object)prefab2))
						{
							list3.Add(new Drop
							{
								m_prefab = prefab2,
								m_amountMin = (int.TryParse(s, out var result) ? result : 0),
								m_amountMax = ((!int.TryParse(s2, out var result2)) ? 1 : result2),
								m_chance = (float.TryParse(s3, out var result3) ? result3 : 1f)
							});
						}
					}
				}
				component.m_drops = list3;
			};
			AddConfigDrops(__instance, component, itemConfig);
		}

		private static void AddConfigDrops(ZNetScene __instance, CharacterDrop component, ConfigEntry<string> itemConfig)
		{
			//IL_0089: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			string[] array = itemConfig.Value.Split(new char[1] { ',' });
			List<Drop> list = new List<Drop>();
			string[] array2 = array;
			foreach (string text in array2)
			{
				string[] array3 = text.Split(new char[1] { ':' });
				if (array3.Length >= 4)
				{
					string text2 = array3[0];
					string s = array3[1];
					string s2 = array3[2];
					string s3 = array3[3];
					GameObject prefab = __instance.GetPrefab(text2);
					if (Object.op_Implicit((Object)(object)prefab))
					{
						list.Add(new Drop
						{
							m_prefab = prefab,
							m_amountMin = (int.TryParse(s, out var result) ? result : 0),
							m_amountMax = ((!int.TryParse(s2, out var result2)) ? 1 : result2),
							m_chance = (float.TryParse(s3, out var result3) ? result3 : 1f)
						});
					}
				}
			}
			component.m_drops = list;
		}

		private static void ManipulateMaterial(ZNetScene __instance, GameObject clone, Critter critter)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			SkinnedMeshRenderer componentInChildren = clone.GetComponentInChildren<SkinnedMeshRenderer>();
			List<Material> list = new List<Material>();
			Material[] materials = ((Renderer)componentInChildren).materials;
			foreach (Material val in materials)
			{
				Material v