Decompiled source of OdinHorse v1.5.8

OdinHorse.dll

Decompiled 2 weeks 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.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using CreatureManager;
using HarmonyLib;
using ItemManager;
using JetBrains.Annotations;
using LocalizationManager;
using Microsoft.CodeAnalysis;
using PieceManager;
using ServerSync;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
using YamlDotNet.Serialization;
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.2.7.0")]
[assembly: Guid("150DFDAF-FF35-4302-B2CC-BEDCE69118D5")]
[assembly: ComVisible(false)]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCopyright("Copyright ©  2022")]
[assembly: AssemblyProduct("OdinHorse")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyDescription("https://valheim.thunderstore.io/package/OdinPlus/OdinHorse")]
[assembly: AssemblyTitle("OdinHorse")]
[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.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.7.0")]
[module: <ea22076b-4562-4aa9-8982-d676ef923f2d>RefSafetyRules(11)]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[<e2827e73-3f00-4759-8482-5d78783f71e7>Embedded]
	internal sealed class <e2827e73-3f00-4759-8482-5d78783f71e7>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	[<e2827e73-3f00-4759-8482-5d78783f71e7>Embedded]
	internal sealed class <294acbb2-4027-423d-bec5-ab4f5aa48c99>NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public <294acbb2-4027-423d-bec5-ab4f5aa48c99>NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public <294acbb2-4027-423d-bec5-ab4f5aa48c99>NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	[<e2827e73-3f00-4759-8482-5d78783f71e7>Embedded]
	internal sealed class <759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public <759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[<e2827e73-3f00-4759-8482-5d78783f71e7>Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class <ea22076b-4562-4aa9-8982-d676ef923f2d>RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public <ea22076b-4562-4aa9-8982-d676ef923f2d>RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace OdinHorse
{
	[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(0)]
	[BepInPlugin("Raelaziel.OdinHorse", "OdinHorse", "1.5.8")]
	[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(1)]
	public class OdinHorse : BaseUnityPlugin
	{
		[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)]
		private enum Toggle
		{
			On = 1,
			Off = 0
		}

		[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(0)]
		[HarmonyPatch(typeof(Character), "Awake")]
		public static class CharacterAwakePatch
		{
			[CompilerGenerated]
			private sealed class <ApplyHorseMaterial>d__1 : IEnumerator<object>, IDisposable, IEnumerator
			{
				private int <>1__state;

				[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(0)]
				private object <>2__current;

				[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(0)]
				public Character character;

				[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(0)]
				public ZNetView znv;

				[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(0)]
				private SkinnedMeshRenderer <renderer>5__1;

				private int <materialIndex>5__2;

				object IEnumerator<object>.Current
				{
					[DebuggerHidden]
					[return: <294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(0)]
					get
					{
						return <>2__current;
					}
				}

				object IEnumerator.Current
				{
					[DebuggerHidden]
					[return: <294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(0)]
					get
					{
						return <>2__current;
					}
				}

				[DebuggerHidden]
				public <ApplyHorseMaterial>d__1(int <>1__state)
				{
					this.<>1__state = <>1__state;
				}

				[DebuggerHidden]
				void IDisposable.Dispose()
				{
					<renderer>5__1 = null;
					<>1__state = -2;
				}

				private bool MoveNext()
				{
					//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
					//IL_00ae: Expected O, but got Unknown
					//IL_0141: Unknown result type (might be due to invalid IL or missing references)
					//IL_014b: Expected O, but got Unknown
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>2__current = null;
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -1;
						<renderer>5__1 = ((Component)character).GetComponentInChildren<SkinnedMeshRenderer>();
						if ((Object)(object)<renderer>5__1 == (Object)null)
						{
							return false;
						}
						<materialIndex>5__2 = znv.GetZDO().GetInt("HorseMaterial", -1);
						if (<materialIndex>5__2 == -1)
						{
							<>2__current = (object)new WaitForSeconds(0.5f);
							<>1__state = 2;
							return true;
						}
						break;
					case 2:
						<>1__state = -1;
						<materialIndex>5__2 = znv.GetZDO().GetInt("HorseMaterial", -1);
						if (<materialIndex>5__2 == -1 && znv.IsOwner())
						{
							<materialIndex>5__2 = Random.Range(0, horseMaterials.Count);
							znv.GetZDO().Set("HorseMaterial", <materialIndex>5__2);
						}
						else if (<materialIndex>5__2 == -1)
						{
							<>2__current = (object)new WaitForSeconds(1f);
							<>1__state = 3;
							return true;
						}
						break;
					case 3:
						<>1__state = -1;
						<materialIndex>5__2 = znv.GetZDO().GetInt("HorseMaterial", 0);
						break;
					}
					if (<materialIndex>5__2 < 0 || <materialIndex>5__2 >= horseMaterials.Count)
					{
						<materialIndex>5__2 = 0;
					}
					((Renderer)<renderer>5__1).material = horseMaterials[<materialIndex>5__2];
					return false;
				}

				bool IEnumerator.MoveNext()
				{
					//ILSpy generated this explicit interface implementation from .override directive in MoveNext
					return this.MoveNext();
				}

				[DebuggerHidden]
				void IEnumerator.Reset()
				{
					throw new NotSupportedException();
				}
			}

			private static void Postfix(Character __instance)
			{
				if (!(((Object)__instance).name != "rae_OdinHorse(Clone)"))
				{
					ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
					if (!((Object)(object)component == (Object)null) && component.IsValid())
					{
						((MonoBehaviour)__instance).StartCoroutine(ApplyHorseMaterial(__instance, component));
					}
				}
			}

			[IteratorStateMachine(typeof(<ApplyHorseMaterial>d__1))]
			private static IEnumerator ApplyHorseMaterial(Character character, ZNetView znv)
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <ApplyHorseMaterial>d__1(0)
				{
					character = character,
					znv = znv
				};
			}
		}

		[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)]
		[HarmonyPatch(typeof(Character), "SetLevel")]
		public static class Character_SetLevel_Patch
		{
			[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(1)]
			private static void Postfix(Character __instance)
			{
				if (!((Object)((Component)__instance).gameObject).name.Contains("rae_OdinHorse"))
				{
					return;
				}
				ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
				if ((Object)(object)component == (Object)null || !component.IsValid())
				{
					return;
				}
				SkinnedMeshRenderer componentInChildren = ((Component)__instance).GetComponentInChildren<SkinnedMeshRenderer>();
				if (!((Object)(object)componentInChildren == (Object)null))
				{
					int @int = component.GetZDO().GetInt("HorseMaterial", -1);
					if (@int >= 0 && @int < horseMaterials.Count)
					{
						((Renderer)componentInChildren).material = horseMaterials[@int];
					}
				}
			}
		}

		[HarmonyPatch(typeof(Tameable), "Awake")]
		[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)]
		private static class AddRPCForHorseArmorTameableAwakePatch
		{
			[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(1)]
			private static void Postfix(Tameable __instance)
			{
				if (!((Object)((Component)((Component)__instance).transform.root).gameObject).name.Contains("rae_OdinHorse"))
				{
					return;
				}
				if ((Object)(object)__instance.m_character != (Object)null)
				{
					Character character = __instance.m_character;
					character.m_onDeath = (Action)Delegate.Remove(character.m_onDeath, new Action(__instance.OnHorseDeath));
					Character character2 = __instance.m_character;
					character2.m_onDeath = (Action)Delegate.Combine(character2.m_onDeath, new Action(__instance.OnHorseDeath));
				}
				if (!((Object)(object)__instance.m_nview == (Object)null) && __instance.m_nview.IsValid())
				{
					__instance.m_nview.Register("AddArmor", (Action<long>)delegate(long sender)
					{
						__instance.RPC_AddArmor(sender);
					});
					__instance.m_nview.Register<bool>("SetArmor", (Action<long, bool>)delegate(long sender, bool enabled)
					{
						__instance.RPC_SetArmor(sender, enabled);
					});
					__instance.m_nview.Register<Vector3>("RemoveArmor", (Action<long, Vector3>)delegate(long sender, Vector3 position)
					{
						//IL_0007: Unknown result type (might be due to invalid IL or missing references)
						__instance.RPC_RemoveArmor(sender, position);
					});
					__instance.m_nview.Register("ToggleWait", (Action<long>)delegate(long sender)
					{
						__instance.RPC_ToggleWait(sender);
					});
					__instance.m_nview.Register<bool>("SetWait", (Action<long, bool>)delegate(long sender, bool enabled)
					{
						__instance.RPC_SetWait(sender, enabled);
					});
					__instance.SetArmor(__instance.HaveArmor());
					__instance.SetWaitAnimation(__instance.IsWaiting());
				}
			}
		}

		[HarmonyPatch(typeof(Tameable), "GetHoverText")]
		[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)]
		private static class AddTextForRemovalOfArmorTameableGetHoverTextPatch
		{
			[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(1)]
			private static void Postfix(Tameable __instance, ref string __result)
			{
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00be: Unknown result type (might be due to invalid IL or missing references)
				//IL_0162: Unknown result type (might be due to invalid IL or missing references)
				//IL_0167: Unknown result type (might be due to invalid IL or missing references)
				//IL_0086: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				//IL_011f: 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)
				if (!((Object)((Component)((Component)__instance).transform.root).gameObject).name.Contains("rae_OdinHorse"))
				{
					return;
				}
				if (!__instance.m_nview.IsValid())
				{
					__result = __result ?? "";
				}
				KeyboardShortcut value;
				if (__instance.HaveArmor() && __instance.m_character.IsTamed())
				{
					string obj = __result;
					string text;
					if (ZInput.IsNonClassicFunctionality() && ZInput.IsGamepadActive())
					{
						Localization instance = Localization.instance;
						value = RemoveArmorHotKey.Value;
						text = instance.Localize("\n[<color=yellow><b>" + ((object)(KeyboardShortcut)(ref value)).ToString() + " + $KEY_Use</b></color>] Remove Armor");
					}
					else
					{
						Localization instance2 = Localization.instance;
						value = RemoveArmorHotKey.Value;
						text = instance2.Localize("\n[<color=yellow><b>" + ((object)(KeyboardShortcut)(ref value)).ToString() + " + $KEY_Use</b></color>] Remove Armor");
					}
					__result = obj + text;
				}
				if (__instance.m_character.IsTamed())
				{
					bool flag = __instance.IsWaiting();
					string obj2 = __result;
					string text2;
					if (ZInput.IsNonClassicFunctionality() && ZInput.IsGamepadActive())
					{
						Localization instance3 = Localization.instance;
						value = WaitHotKey.Value;
						text2 = instance3.Localize("\n[<color=yellow><b>" + ((object)(KeyboardShortcut)(ref value)).ToString() + " + $KEY_Use</b></color>] " + (flag ? "Resume" : "Wait Here"));
					}
					else
					{
						Localization instance4 = Localization.instance;
						value = WaitHotKey.Value;
						text2 = instance4.Localize("\n[<color=yellow><b>" + ((object)(KeyboardShortcut)(ref value)).ToString() + " + $KEY_Use</b></color>] " + (flag ? "Resume" : "Wait Here"));
					}
					__result = obj2 + text2;
				}
			}
		}

		[HarmonyPatch(typeof(Tameable), "Interact")]
		[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)]
		private static class RemoveArmorTameableInteractPatch
		{
			[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(1)]
			private static bool Prefix(Tameable __instance, Humanoid user, bool hold, bool alt)
			{
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_009b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				if (!__instance.m_nview.IsValid() || hold)
				{
					return false;
				}
				if (!((Object)((Component)((Component)__instance).transform.root).gameObject).name.Contains("rae_OdinHorse"))
				{
					return true;
				}
				if (RemoveArmorHotKey.Value.IsKeyHeld() && __instance.HaveArmor())
				{
					__instance.m_nview.InvokeRPC("RemoveArmor", new object[1] { ((Component)user).transform.position });
					return false;
				}
				if (WaitHotKey.Value.IsKeyHeld())
				{
					__instance.m_nview.InvokeRPC("ToggleWait", Array.Empty<object>());
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(Tameable), "Interact")]
		[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)]
		private static class CycleHorseStateTameableInteractPatch
		{
			[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(1)]
			private static void Postfix(Tameable __instance, Humanoid user, bool hold, bool alt, bool __result)
			{
				//IL_0049: 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)
				if (!(!__instance.m_nview.IsValid() || hold || alt) && ((Object)((Component)((Component)__instance).transform.root).gameObject).name.Contains("rae_OdinHorse") && !RemoveArmorHotKey.Value.IsKeyHeld() && !WaitHotKey.Value.IsKeyHeld() && __instance.IsTamed() && __instance.IsWaiting())
				{
					__instance.m_nview.InvokeRPC("ToggleWait", Array.Empty<object>());
				}
			}
		}

		[HarmonyPatch(typeof(Tameable), "UseItem")]
		[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)]
		private static class UseArmorOnHorseTameableUseItemPatch
		{
			[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(1)]
			private static void Postfix(Tameable __instance, Humanoid user, ItemData item)
			{
				if (((Object)((Component)((Component)__instance).transform.root).gameObject).name.Contains("rae_OdinHorse") && __instance.m_nview.IsValid() && !((Object)(object)__instance.GetArmorItem() == (Object)null) && __instance.m_character.IsTamed() && !(item.m_shared.m_name != __instance.GetArmorItem().m_itemData.m_shared.m_name))
				{
					if (__instance.HaveArmor())
					{
						((Character)user).Message((MessageType)2, __instance.m_character.GetHoverName() + " Armor Already equipped", 0, (Sprite)null);
						return;
					}
					__instance.m_nview.InvokeRPC("AddArmor", new object[1] { ZNet.GetUID() });
					user.GetInventory().RemoveOneItem(item);
					((Character)user).Message((MessageType)2, __instance.m_character.GetHoverName() + " Armor added", 0, (Sprite)null);
				}
			}
		}

		[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)]
		public enum HorseBeasts
		{
			player,
			horse
		}

		[HarmonyPatch(typeof(Vagon), "LateUpdate")]
		[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)]
		private class LateUpdate_Vagon_Patch
		{
			[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(1)]
			private static void Prefix(ref Vagon __instance, ref ConfigurableJoint ___m_attachJoin, ref Rigidbody ___m_body)
			{
				try
				{
					if ((Object)(object)___m_attachJoin != (Object)null && (Object)(object)((Joint)___m_attachJoin).connectedBody == (Object)null)
					{
						__instance.Detach();
					}
				}
				catch (Exception ex)
				{
					Debug.LogError((object)ex);
				}
			}
		}

		[HarmonyPatch(typeof(Vagon), "InUse")]
		[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)]
		private class InUse_Vagon_Patch
		{
			[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(1)]
			private static bool Prefix(ref bool __result, ref Vagon __instance)
			{
				if (Object.op_Implicit((Object)(object)__instance.m_container) && __instance.m_container.IsInUse())
				{
					__result = true;
				}
				else if (__instance.IsAttached())
				{
					__result = Object.op_Implicit((Object)(object)((Component)((Joint)__instance.m_attachJoin).connectedBody).gameObject.GetComponent<Player>());
				}
				else
				{
					__result = false;
				}
				return false;
			}
		}

		[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)]
		[HarmonyPatch(typeof(Vagon), "FixedUpdate")]
		private class Vagon_FixedUpdate_Patch
		{
			[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(1)]
			private static bool Prefix(Vagon __instance)
			{
				//IL_0131: Unknown result type (might be due to invalid IL or missing references)
				if (!__instance.m_nview.IsValid())
				{
					return false;
				}
				if (__instance.IsAttached())
				{
					ConfigurableJoint attachJoin = __instance.m_attachJoin;
					if ((Object)(object)((attachJoin != null) ? ((Joint)attachJoin).connectedBody : null) == (Object)null)
					{
						__instance.Detach();
						return false;
					}
				}
				__instance.UpdateAudio(Time.fixedDeltaTime);
				if (__instance.m_nview.IsOwner())
				{
					if (Object.op_Implicit((Object)(object)__instance.m_useRequester))
					{
						if (__instance.IsAttached())
						{
							__instance.Detach();
						}
						else
						{
							Character val = FindClosestAttachableAnimal(__instance);
							if ((Object)(object)val != (Object)null)
							{
								AttachCartTo(val, __instance);
							}
							else if (__instance.CanAttach(((Component)__instance.m_useRequester).gameObject))
							{
								AttachCartTo((Character)(object)__instance.m_useRequester, __instance);
							}
							else
							{
								((Character)__instance.m_useRequester).Message((MessageType)2, "Not in the right position", 0, (Sprite)null);
							}
						}
						__instance.m_useRequester = null;
					}
					if (__instance.IsAttached())
					{
						__instance.m_detachDistance = GetCartDetachDistance(AttachedCharacter(__instance));
						if (!__instance.CanAttach(((Component)((Joint)__instance.m_attachJoin).connectedBody).gameObject))
						{
							__instance.Detach();
						}
					}
				}
				else if (__instance.IsAttached())
				{
					__instance.Detach();
				}
				return false;
			}
		}

		[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)]
		[HarmonyPatch(typeof(BaseAI), "Follow")]
		private class Tamed_Follow_patch
		{
			[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(1)]
			private static bool Prefix(GameObject go, float dt, ref BaseAI __instance)
			{
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: 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)
				if (!__instance.m_character.IsTamed())
				{
					return true;
				}
				BaseAI obj = __instance;
				if ((Object)(object)((MonsterAI)((obj is MonsterAI) ? obj : null)).GetFollowTarget().GetComponent<Player>() == (Object)null)
				{
					return true;
				}
				float num = Vector3.Distance(go.transform.position, ((Component)__instance).transform.position);
				HorseBeasts horseBeasts = ParseCharacterType(__instance.m_character);
				HorseBeasts horseBeasts2 = horseBeasts;
				if (horseBeasts2 == HorseBeasts.horse)
				{
					float num2 = 3f;
					bool flag = num > num2 * 3f;
					if (num < num2)
					{
						__instance.StopMoving();
					}
					else
					{
						__instance.MoveTo(dt, go.transform.position, 0f, flag);
					}
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(MonsterAI), "UpdateAI")]
		[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)]
		private class MonsterAI_UpdateAI_WaitPatch
		{
			[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(1)]
			private static bool Prefix(MonsterAI __instance, ref bool __result)
			{
				if ((Object)(object)__instance == (Object)null)
				{
					return true;
				}
				if ((Object)(object)((Component)__instance).gameObject == (Object)null)
				{
					return true;
				}
				if (!((Object)((Component)__instance).gameObject).name.Contains("rae_OdinHorse"))
				{
					return true;
				}
				Tameable component = ((Component)__instance).GetComponent<Tameable>();
				if ((Object)(object)component != (Object)null && component.IsWaiting())
				{
					((BaseAI)__instance).StopMoving();
					__result = true;
					return false;
				}
				return true;
			}
		}

		[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)]
		[HarmonyPatch(typeof(Sadle), "UseItem")]
		private class Sadle_UseItem_Patch
		{
			[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(1)]
			private static void Postfix(Sadle __instance, bool __result)
			{
				if (__result)
				{
					Tameable componentInParent = ((Component)__instance).GetComponentInParent<Tameable>();
					if ((Object)(object)componentInParent != (Object)null && componentInParent.IsWaiting())
					{
						componentInParent.m_nview.InvokeRPC("ToggleWait", Array.Empty<object>());
					}
				}
			}
		}

		[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)]
		[HarmonyPatch(typeof(Character), "Damage")]
		private class Character_Damage_Patch
		{
			[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(1)]
			private static void Postfix(Character __instance, HitData hit)
			{
				if (((Object)((Component)__instance).gameObject).name.Contains("rae_OdinHorse"))
				{
					Tameable component = ((Component)__instance).GetComponent<Tameable>();
					if ((Object)(object)component != (Object)null && component.IsWaiting())
					{
						component.m_nview.InvokeRPC("ToggleWait", Array.Empty<object>());
					}
				}
			}
		}

		[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(0)]
		public static class CustomMapPins
		{
			[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(0)]
			public class CustomPinhandlerHorse : MonoBehaviour
			{
				public Sprite icon;

				public string pinName;

				private PinData pin;

				private void Awake()
				{
					//IL_0026: Unknown result type (might be due to invalid IL or missing references)
					//IL_0030: Expected O, but got Unknown
					//IL_0037: Unknown result type (might be due to invalid IL or missing references)
					//IL_0063: Unknown result type (might be due to invalid IL or missing references)
					//IL_0068: Unknown result type (might be due to invalid IL or missing references)
					//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
					//IL_00ae: Invalid comparison between Unknown and I4
					//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
					//IL_00dd: Expected O, but got Unknown
					if (!((Component)this).gameObject.GetComponent<Tameable>().HaveSaddle())
					{
						Object.DestroyImmediate((Object)(object)this);
						return;
					}
					pin = new PinData();
					pin.m_type = (PinType)0;
					pin.m_name = Localization.instance.Localize(pinName);
					pin.m_pos = ((Component)this).transform.position;
					pin.m_icon = icon;
					pin.m_save = false;
					pin.m_checked = false;
					pin.m_ownerID = 0L;
					RectTransform val = (((int)Minimap.instance.m_mode == 2) ? Minimap.instance.m_pinNameRootLarge : Minimap.instance.m_pinNameRootSmall);
					pin.m_NamePinData = new PinNameData(pin);
					Minimap.instance.CreateMapNamePin(pin, val);
					pin.m_NamePinData.PinNameText.richText = true;
					pin.m_NamePinData.PinNameText.overrideColorTags = false;
					Minimap.instance?.m_pins?.Add(pin);
				}

				private void LateUpdate()
				{
					//IL_0019: Unknown result type (might be due to invalid IL or missing references)
					//IL_001e: Unknown result type (might be due to invalid IL or missing references)
					pin.m_checked = false;
					pin.m_pos = ((Component)this).transform.position;
				}

				private void OnDestroy()
				{
					if (pin != null)
					{
						if (Object.op_Implicit((Object)(object)pin.m_uiElement))
						{
							Minimap.instance.DestroyPinMarker(pin);
						}
						Minimap.instance?.m_pins?.Remove(pin);
					}
				}
			}

			public static void RegisterCustomPin(GameObject go, string name, Sprite icon)
			{
				CustomPinhandlerHorse customPinhandlerHorse = go.AddComponent<CustomPinhandlerHorse>();
				customPinhandlerHorse.pinName = name;
				customPinhandlerHorse.icon = icon;
			}
		}

		[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(0)]
		public static class CustomMapPins_Cart
		{
			[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(0)]
			public class CustomPinhandler_Generic_Cart : MonoBehaviour
			{
				public Sprite icon;

				public string pinName;

				private PinData pin;

				private void Awake()
				{
					//IL_0002: Unknown result type (might be due to invalid IL or missing references)
					//IL_000c: Expected O, but got Unknown
					//IL_0013: Unknown result type (might be due to invalid IL or missing references)
					//IL_003f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0044: Unknown result type (might be due to invalid IL or missing references)
					//IL_0084: Unknown result type (might be due to invalid IL or missing references)
					//IL_008a: Invalid comparison between Unknown and I4
					//IL_00af: Unknown result type (might be due to invalid IL or missing references)
					//IL_00b9: Expected O, but got Unknown
					pin = new PinData();
					pin.m_type = (PinType)0;
					pin.m_name = Localization.instance.Localize(pinName);
					pin.m_pos = ((Component)this).transform.position;
					pin.m_icon = icon;
					pin.m_save = false;
					pin.m_checked = false;
					pin.m_ownerID = 0L;
					RectTransform val = (((int)Minimap.instance.m_mode == 2) ? Minimap.instance.m_pinNameRootLarge : Minimap.instance.m_pinNameRootSmall);
					pin.m_NamePinData = new PinNameData(pin);
					Minimap.instance.CreateMapNamePin(pin, val);
					pin.m_NamePinData.PinNameText.richText = true;
					pin.m_NamePinData.PinNameText.overrideColorTags = false;
					Minimap.instance?.m_pins?.Add(pin);
				}

				private void LateUpdate()
				{
					//IL_0019: Unknown result type (might be due to invalid IL or missing references)
					//IL_001e: Unknown result type (might be due to invalid IL or missing references)
					pin.m_checked = false;
					pin.m_pos = ((Component)this).transform.position;
				}

				private void OnDestroy()
				{
					if (pin != null)
					{
						if ((Object)(object)pin.m_uiElement != (Object)null)
						{
							Minimap.instance.DestroyPinMarker(pin);
						}
						Minimap.instance?.m_pins?.Remove(pin);
					}
				}
			}

			public static void RegisterCustomPinGeneric(GameObject go, string name, Sprite icon)
			{
				CustomPinhandler_Generic_Cart customPinhandler_Generic_Cart = go.AddComponent<CustomPinhandler_Generic_Cart>();
				customPinhandler_Generic_Cart.pinName = name;
				customPinhandler_Generic_Cart.icon = icon;
			}
		}

		private const string ModName = "OdinHorse";

		private const string ModVersion = "1.5.8";

		private const string ModGUID = "Raelaziel.OdinHorse";

		private static readonly ConfigSync configSync = new ConfigSync("OdinHorse")
		{
			DisplayName = "OdinHorse",
			CurrentVersion = "1.5.8",
			MinimumRequiredVersion = "1.5.8"
		};

		private static ConfigEntry<Toggle> serverConfigLocked = null;

		internal static Creature raeHorse;

		internal static ConfigEntry<bool> ServerConfigLocked = null;

		internal static ConfigEntry<int> HorseRunningSpeed = null;

		internal static ConfigEntry<int> HorseWalkingSpeed = null;

		internal static ConfigEntry<int> HorseSpeed = null;

		internal static ConfigEntry<int> HorseTurnSpeed = null;

		internal static ConfigEntry<int> HorseRunningTurnSpeed = null;

		internal static ConfigEntry<int> HorseHealth = null;

		internal static ConfigEntry<float> HorseStamina = null;

		internal static ConfigEntry<float> HorseStaminaRegen = null;

		internal static ConfigEntry<float> HorseStaminaRegenHungry = null;

		internal static ConfigEntry<float> HorseProcreationUpdateInterval;

		internal static ConfigEntry<float> HorseProcreationTotalCheckRange;

		internal static ConfigEntry<int> HorseProcreationMaxCreatures;

		internal static ConfigEntry<float> HorseProcreationPartnerCheckRange;

		internal static ConfigEntry<float> HorseProcreationPregnancyChance;

		internal static ConfigEntry<float> HorseProcreationPregnancyDuration;

		internal static ConfigEntry<int> HorseProcreationRequiredLovePoints;

		internal static ConfigEntry<int> HorseOffspringHealth = null;

		internal static ConfigEntry<int> HorseOffspringGrowupTime = null;

		internal static ConfigEntry<float> HorseOffspringMeatDropChance = null;

		internal static ConfigEntry<int> HorseOffspringMeatDropMinimum = null;

		internal static ConfigEntry<int> HorseOffspringMeatDropMaximum = null;

		internal static ConfigEntry<float> HorseOffspringHideDropChance = null;

		internal static ConfigEntry<int> HorseOffspringHideDropMinimum = null;

		internal static ConfigEntry<int> HorseOffspringHideDropMaximum = null;

		internal static ConfigEntry<KeyboardShortcut> RemoveArmorHotKey = null;

		internal static ConfigEntry<KeyboardShortcut> WaitHotKey = null;

		internal static ConfigEntry<bool> HideHorsePin;

		internal static ConfigEntry<bool> HideCartPin;

		private static List<Material> horseMaterials;

		private static AssetBundle horseAssetBundle;

		private ConfigEntry<T> config<[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(2)] T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true)
		{
			ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, description);
			SyncedConfigEntry<T> syncedConfigEntry = configSync.AddConfigEntry<T>(val);
			syncedConfigEntry.SynchronizedConfig = synchronizedSetting;
			return val;
		}

		private ConfigEntry<T> config<[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(2)] T>(string group, string name, T value, string description, bool synchronizedSetting = true)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting);
		}

		public void Awake()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Expected O, but got Unknown
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Expected O, but got Unknown
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Expected O, but got Unknown
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Expected O, but got Unknown
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Expected O, but got Unknown
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Expected O, but got Unknown
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Expected O, but got Unknown
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Expected O, but got Unknown
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Expected O, but got Unknown
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Expected O, but got Unknown
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0376: Expected O, but got Unknown
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Expected O, but got Unknown
			//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Expected O, but got Unknown
			//IL_03db: Unknown result type (might be due to invalid IL or missing references)
			//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f6: Expected O, but got Unknown
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_041d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Expected O, but got Unknown
			//IL_0fac: Unknown result type (might be due to invalid IL or missing references)
			//IL_1021: Unknown result type (might be due to invalid IL or missing references)
			//IL_1300: Unknown result type (might be due to invalid IL or missing references)
			//IL_1305: Unknown result type (might be due to invalid IL or missing references)
			//IL_1311: Unknown result type (might be due to invalid IL or missing references)
			//IL_1321: Unknown result type (might be due to invalid IL or missing references)
			//IL_1331: Unknown result type (might be due to invalid IL or missing references)
			//IL_1341: Unknown result type (might be due to invalid IL or missing references)
			//IL_1348: Unknown result type (might be due to invalid IL or missing references)
			//IL_1354: Expected O, but got Unknown
			//IL_1361: Unknown result type (might be due to invalid IL or missing references)
			//IL_1366: Unknown result type (might be due to invalid IL or missing references)
			//IL_1372: Unknown result type (might be due to invalid IL or missing references)
			//IL_1382: Unknown result type (might be due to invalid IL or missing references)
			//IL_1392: Unknown result type (might be due to invalid IL or missing references)
			//IL_13a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_13a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_13b5: Expected O, but got Unknown
			//IL_146e: Unknown result type (might be due to invalid IL or missing references)
			//IL_1475: Expected O, but got Unknown
			Localizer.Load();
			LoadAssetBundle();
			serverConfigLocked = config("General", "Lock Configuration", Toggle.On, "If on, the configuration is locked and can be changed by server admins only.");
			configSync.AddLockingConfigEntry<Toggle>(serverConfigLocked);
			HorseRunningSpeed = config("Horse", "Running Speed", 12, new ConfigDescription("Declare running speed for Horse", (AcceptableValueBase)null, Array.Empty<object>()));
			HorseWalkingSpeed = config("Horse", "Walking Speed", 5, new ConfigDescription("Declare walking speed for Horse", (AcceptableValueBase)null, Array.Empty<object>()));
			HorseSpeed = config("Horse", "Speed Modifier", 1, new ConfigDescription("Declare speed modified for Horse", (AcceptableValueBase)null, Array.Empty<object>()));
			HorseTurnSpeed = config("Horse", "Turn Speed", 75, new ConfigDescription("Declare turning speed for Horse", (AcceptableValueBase)null, Array.Empty<object>()));
			HorseRunningTurnSpeed = config("Horse", "Run Turn Speed", 120, new ConfigDescription("Declare turning speed when running for Horse", (AcceptableValueBase)null, Array.Empty<object>()));
			HorseHealth = config("Horse", "Health", 200, new ConfigDescription("Declare health points for Horse", (AcceptableValueBase)null, Array.Empty<object>()));
			HorseStamina = config("Horse", "Stamina", 400f, new ConfigDescription("Declare stamina for Horse", (AcceptableValueBase)null, Array.Empty<object>()));
			HorseStaminaRegen = config("Horse", "Stamina Regen", 2f, new ConfigDescription("Declare stamina regen for Horse", (AcceptableValueBase)null, Array.Empty<object>()));
			HorseStaminaRegenHungry = config("Horse", "Stamina Regen Hungry", 1f, new ConfigDescription("Declare stamina regen when hungry for Horse", (AcceptableValueBase)null, Array.Empty<object>()));
			HorseProcreationUpdateInterval = config("Horse Procreation", "Update Interval", 10f, "Time interval in seconds to check for procreation.");
			HorseProcreationTotalCheckRange = config("Horse Procreation", "Total Check Range", 10f, "Range in meters to check for total creatures.");
			HorseProcreationMaxCreatures = config("Horse Procreation", "Max Creatures", 4, "Maximum number of creatures allowed in range.");
			HorseProcreationPartnerCheckRange = config("Horse Procreation", "Partner Check Range", 3f, "Range in meters to find a procreation partner.");
			HorseProcreationPregnancyChance = config("Horse Procreation", "Pregnancy Chance", 0.5f, "Chance of becoming pregnant per check.");
			HorseProcreationPregnancyDuration = config("Horse Procreation", "Pregnancy Duration", 10f, "Duration of pregnancy in seconds.");
			HorseProcreationRequiredLovePoints = config("Horse Procreation", "Required Love Points", 4, "Number of love points required to trigger pregnancy.");
			HorseOffspringHealth = config("Horse Offspring", "Health", 60, new ConfigDescription("Declare health points for Horse Offspring", (AcceptableValueBase)null, Array.Empty<object>()));
			HorseOffspringGrowupTime = config("Horse Offspring", "Grow-up time", 2000, new ConfigDescription("Declare growup time needed to convert offspring into Horse. Time in seconds.", (AcceptableValueBase)null, Array.Empty<object>()));
			HorseOffspringMeatDropChance = config("Horse Offspring", "Meat Drop Chance", 1f, new ConfigDescription("Declare drop chance for Horse Meat from offspring", (AcceptableValueBase)null, Array.Empty<object>()));
			HorseOffspringMeatDropMinimum = config("Horse Offspring", "Meat Amount Min", 1, new ConfigDescription("Declare minimum amount of Horse Meat to drop from offspring", (AcceptableValueBase)null, Array.Empty<object>()));
			HorseOffspringMeatDropMaximum = config("Horse Offspring", "Meat Amount Max", 2, new ConfigDescription("Declare maximum amount of Horse Meat to drop from offspring", (AcceptableValueBase)null, Array.Empty<object>()));
			HorseOffspringHideDropChance = config("Horse Offspring", "Hide Drop Chance", 0.33f, new ConfigDescription("Declare drop chance for Horse Hide from offspring", (AcceptableValueBase)null, Array.Empty<object>()));
			HorseOffspringHideDropMinimum = config("Horse Offspring", "Hide Amount Min", 1, new ConfigDescription("Declare minimum amount of Horse Hide to drop from offspring", (AcceptableValueBase)null, Array.Empty<object>()));
			HorseOffspringHideDropMaximum = config("Horse Offspring", "Hide Amount Max", 1, new ConfigDescription("Declare maximum amount of Horse Hide to drop from offspring", (AcceptableValueBase)null, Array.Empty<object>()));
			RemoveArmorHotKey = config<KeyboardShortcut>("Hotkeys", "Remove Armor Key", new KeyboardShortcut((KeyCode)114, Array.Empty<KeyCode>()), new ConfigDescription("The key needed to be held while interacting with the horse to remove the armor.", (AcceptableValueBase)null, Array.Empty<object>()));
			WaitHotKey = config<KeyboardShortcut>("Hotkeys", "Wait Here Key", new KeyboardShortcut((KeyCode)116, Array.Empty<KeyCode>()), new ConfigDescription("The key needed to be held while interacting with the horse to make it wait in place.", (AcceptableValueBase)null, Array.Empty<object>()));
			HideHorsePin = config("Map Icons", "HideHorsePin", value: false, "If true, disables the map icon for the Odin Horse.");
			HideCartPin = config("Map Icons", "HideCartPin", value: false, "If true, disables the map icon for the Odin Cart.");
			Item item = new Item("horsesets", "rae_HorseMeat");
			Item item2 = new Item("horsesets", "rae_HorseHide");
			Item item3 = new Item("horsesets", "rae_OdinHorse_Trophy");
			Item item4 = new Item("horsesets", "rae_CookedHorseMeat");
			Item item5 = new Item("horsesets", "rae_SaddleHorse");
			item5.Crafting.Add(ItemManager.CraftingTable.Workbench, 1);
			item5.MaximumRequiredStationLevel = 5;
			item5.RequiredItems.Add("Bronze", 1);
			item5.RequiredItems.Add("rae_HorseHide", 8);
			item5.CraftAmount = 1;
			Item item6 = new Item("horsesets", "rae_iron_HorseArmor");
			item6.Crafting.Add(ItemManager.CraftingTable.Forge, 1);
			item6.MaximumRequiredStationLevel = 5;
			item6.RequiredItems.Add("Iron", 10);
			item6.RequiredItems.Add("rae_HorseHide", 20);
			item6.CraftAmount = 1;
			TameableExtensions.m_armorItem = item6.Prefab.GetComponent<ItemDrop>();
			Item item7 = new Item("horsesets", "rae_HorseSticks");
			item7.Configurable = Configurability.Full;
			item7.Crafting.Add(ItemManager.CraftingTable.Cauldron, 1);
			item7.MaximumRequiredStationLevel = 10;
			item7.RequiredItems.Add("rae_HorseMeat", 3);
			item7.RequiredItems.Add("Coal", 1);
			item7.RequiredItems.Add("Dandelion", 2);
			item7.CraftAmount = 2;
			Item item8 = new Item("horsesets", "rae_HorseSoup");
			item8.Configurable = Configurability.Full;
			item8.Crafting.Add(ItemManager.CraftingTable.Cauldron, 1);
			item8.MaximumRequiredStationLevel = 10;
			item8.RequiredItems.Add("rae_HorseMeat", 2);
			item8.RequiredItems.Add("Carrot", 2);
			item8.RequiredItems.Add("Dandelion", 3);
			item8.CraftAmount = 1;
			Item item9 = new Item("horsesets", "rae_HorseMeatSkewer");
			item9.Configurable = Configurability.Full;
			item9.Crafting.Add(ItemManager.CraftingTable.Cauldron, 2);
			item9.MaximumRequiredStationLevel = 10;
			item9.RequiredItems.Add("rae_HorseMeat", 3);
			item9.RequiredItems.Add("Mushroom", 2);
			item9.RequiredItems.Add("NeckTail", 1);
			item9.CraftAmount = 2;
			Item item10 = new Item("horsesets", "rae_Horseaker");
			item10.Configurable = Configurability.Full;
			item10.Crafting.Add(ItemManager.CraftingTable.Forge, 1);
			item10.MaximumRequiredStationLevel = 10;
			item10.RequiredItems.Add("Iron", 20);
			item10.RequiredItems.Add("rae_OdinHorse_Trophy", 1);
			item10.RequiredItems.Add("ElderBark", 35);
			item10.RequiredUpgradeItems.Add("Iron", 5);
			item10.RequiredUpgradeItems.Add("ElderBark", 10);
			item10.CraftAmount = 1;
			Item item11 = new Item("horsesets", "rae_OdinHorse_Helmet");
			item11.Configurable = Configurability.Full;
			item11.Crafting.Add(ItemManager.CraftingTable.Workbench, 1);
			item11.MaximumRequiredStationLevel = 10;
			item11.RequiredItems.Add("Tin", 10);
			item11.RequiredItems.Add("rae_OdinHorse_Trophy", 1);
			item11.RequiredItems.Add("rae_HorseHide", 5);
			item11.RequiredUpgradeItems.Add("rae_HorseHide", 4);
			item11.RequiredUpgradeItems.Add("Tin", 2);
			item11.CraftAmount = 1;
			Item item12 = new Item("horsesets", "rae_CapeHorseHide");
			item12.Configurable = Configurability.Full;
			item12.Crafting.Add(ItemManager.CraftingTable.Workbench, 1);
			item12.MaximumRequiredStationLevel = 10;
			item12.RequiredItems.Add("rae_HorseHide", 10);
			item12.RequiredItems.Add("rae_OdinHorse_Trophy", 1);
			item12.RequiredItems.Add("Tin", 2);
			item12.RequiredUpgradeItems.Add("rae_HorseHide", 10);
			item12.RequiredUpgradeItems.Add("Tin", 2);
			item12.CraftAmount = 1;
			Item item13 = new Item("horsesets", "ArmorHorseClothHelmet_T1");
			item13.Configurable = Configurability.Full;
			item13.Crafting.Add(ItemManager.CraftingTable.Workbench, 1);
			item13.MaximumRequiredStationLevel = 10;
			item13.RequiredItems.Add("rae_HorseHide", 4);
			item13.RequiredItems.Add("LeatherScraps", 6);
			item13.RequiredItems.Add("rae_OdinHorse_Trophy", 1);
			item13.RequiredUpgradeItems.Add("rae_HorseHide", 2);
			item13.RequiredUpgradeItems.Add("LeatherScraps", 3);
			item13.CraftAmount = 1;
			Item item14 = new Item("horsesets", "ArmorHorseClothHelmet_T2");
			item14.Configurable = Configurability.Full;
			item14.Crafting.Add(ItemManager.CraftingTable.Forge, 1);
			item14.MaximumRequiredStationLevel = 10;
			item14.RequiredItems.Add("rae_HorseHide", 6);
			item14.RequiredItems.Add("Iron", 15);
			item14.RequiredItems.Add("LeatherScraps", 4);
			item14.RequiredItems.Add("rae_OdinHorse_Trophy", 1);
			item14.RequiredUpgradeItems.Add("rae_HorseHide", 3);
			item14.RequiredUpgradeItems.Add("Iron", 5);
			item14.RequiredUpgradeItems.Add("LeatherScraps", 2);
			item14.CraftAmount = 1;
			Item item15 = new Item("horsesets", "ArmorHorseClothChest_T1");
			item15.Configurable = Configurability.Full;
			item15.Crafting.Add(ItemManager.CraftingTable.Workbench, 1);
			item15.MaximumRequiredStationLevel = 10;
			item15.RequiredItems.Add("rae_HorseHide", 4);
			item15.RequiredItems.Add("LeatherScraps", 8);
			item15.RequiredUpgradeItems.Add("rae_HorseHide", 2);
			item15.RequiredUpgradeItems.Add("LeatherScraps", 4);
			item15.CraftAmount = 1;
			Item item16 = new Item("horsesets", "ArmorHorseClothChest_T2");
			item16.Configurable = Configurability.Full;
			item16.Crafting.Add(ItemManager.CraftingTable.Forge, 1);
			item16.MaximumRequiredStationLevel = 10;
			item16.RequiredItems.Add("rae_HorseHide", 6);
			item16.RequiredItems.Add("Iron", 20);
			item16.RequiredItems.Add("LeatherScraps", 8);
			item16.RequiredUpgradeItems.Add("rae_HorseHide", 2);
			item16.RequiredUpgradeItems.Add("Iron", 5);
			item16.RequiredUpgradeItems.Add("LeatherScraps", 4);
			item16.CraftAmount = 1;
			Item item17 = new Item("horsesets", "ArmorHorseClothLegs_T1");
			item17.Configurable = Configurability.Full;
			item17.Crafting.Add(ItemManager.CraftingTable.Workbench, 1);
			item17.MaximumRequiredStationLevel = 10;
			item17.RequiredItems.Add("rae_HorseHide", 4);
			item17.RequiredItems.Add("LeatherScraps", 8);
			item17.RequiredUpgradeItems.Add("rae_HorseHide", 2);
			item17.RequiredUpgradeItems.Add("LeatherScraps", 4);
			item17.CraftAmount = 1;
			Item item18 = new Item("horsesets", "ArmorHorseClothLegs_T2");
			item18.Configurable = Configurability.Full;
			item18.Crafting.Add(ItemManager.CraftingTable.Forge, 1);
			item18.MaximumRequiredStationLevel = 10;
			item18.RequiredItems.Add("rae_HorseHide", 6);
			item18.RequiredItems.Add("Iron", 20);
			item18.RequiredItems.Add("LeatherScraps", 8);
			item18.RequiredUpgradeItems.Add("rae_HorseHide", 2);
			item18.RequiredUpgradeItems.Add("Iron", 5);
			item18.RequiredUpgradeItems.Add("LeatherScraps", 4);
			item18.CraftAmount = 1;
			BuildPiece buildPiece = new BuildPiece("horsesets", "rae_OdinHorse_Rug");
			buildPiece.RequiredItems.Add("rae_HorseHide", 20, recover: true);
			buildPiece.Category.Set(BuildPieceCategory.Furniture);
			buildPiece.Crafting.Set(PieceManager.CraftingTable.Workbench);
			BuildPiece buildPiece2 = new BuildPiece("horsesets", "rae_OdinHorse_Rug_Headless");
			buildPiece2.RequiredItems.Add("rae_HorseHide", 20, recover: true);
			buildPiece2.Category.Set(BuildPieceCategory.Furniture);
			buildPiece2.Crafting.Set(PieceManager.CraftingTable.Workbench);
			BuildPiece buildPiece3 = new BuildPiece("horsesets", "rae_HorseChair");
			buildPiece3.RequiredItems.Add("rae_HorseHide", 2, recover: true);
			buildPiece3.RequiredItems.Add("FineWood", 3, recover: true);
			buildPiece3.Category.Set(BuildPieceCategory.Furniture);
			buildPiece3.Crafting.Set(PieceManager.CraftingTable.Workbench);
			BuildPiece buildPiece4 = new BuildPiece("horsesets", "rae_HorseCart");
			buildPiece4.RequiredItems.Add("BronzeNails", 60, recover: true);
			buildPiece4.RequiredItems.Add("FineWood", 40, recover: true);
			buildPiece4.Category.Set(BuildPieceCategory.Misc);
			buildPiece4.Crafting.Set(PieceManager.CraftingTable.Workbench);
			buildPiece4.Prefab.GetComponent<Vagon>().m_breakForce = float.MaxValue;
			GameObject val = ItemManager.PrefabManager.RegisterPrefab("horsesets", "horse_bite_attack");
			GameObject val2 = ItemManager.PrefabManager.RegisterPrefab("horsesets", "rae_Offspring_Normal");
			GameObject val3 = ItemManager.PrefabManager.RegisterPrefab("horsesets", "rae_Offspring_Normal_ragdoll");
			GameObject val4 = ItemManager.PrefabManager.RegisterPrefab("horsesets", "rae_OdinHorse_ragdoll");
			GameObject val5 = ItemManager.PrefabManager.RegisterPrefab("horsesets", "sfx_horse_idle");
			GameObject val6 = ItemManager.PrefabManager.RegisterPrefab("horsesets", "sfx_horse_birth");
			GameObject val7 = ItemManager.PrefabManager.RegisterPrefab("horsesets", "vfx_horse_birth");
			GameObject val8 = ItemManager.PrefabManager.RegisterPrefab("horsesets", "sfx_horse_hit");
			GameObject val9 = ItemManager.PrefabManager.RegisterPrefab("horsesets", "vfx_horse_death");
			GameObject val10 = ItemManager.PrefabManager.RegisterPrefab("horsesets", "Sfx_horse_love");
			GameObject val11 = ItemManager.PrefabManager.RegisterPrefab("horsesets", "vfx_horse_love");
			raeHorse = new Creature("horsesets", "rae_OdinHorse")
			{
				ConfigurationEnabled = true,
				TamingTime = 1600f,
				FedDuration = 300f,
				Biome = (Biome)1,
				CanSpawn = true,
				CanBeTamed = true,
				CanHaveStars = true,
				FoodItems = "Blueberries, Carrot, Cloudberry, Barley",
				SpawnChance = 15f,
				GroupSize = new CreatureManager.Range(1f, 2f),
				CheckSpawnInterval = 2000,
				SpecificSpawnTime = SpawnTime.Day,
				SpecificSpawnArea = SpawnArea.Center,
				RequiredWeather = Weather.ClearSkies,
				AttackImmediately = false,
				ForestSpawn = Forest.Both,
				CreatureFaction = (Faction)2,
				Maximum = 1
			};
			raeHorse.Drops["rae_HorseMeat"].Amount = new CreatureManager.Range(1f, 2f);
			raeHorse.Drops["rae_HorseMeat"].DropChance = 100f;
			raeHorse.Drops["rae_HorseHide"].Amount = new CreatureManager.Range(1f, 2f);
			raeHorse.Drops["rae_HorseHide"].DropChance = 100f;
			raeHorse.Drops["rae_OdinHorse_Trophy"].Amount = new CreatureManager.Range(1f, 2f);
			raeHorse.Drops["rae_OdinHorse_Trophy"].DropChance = 10f;
			((Character)raeHorse.Prefab.GetComponent<Humanoid>()).m_runSpeed = HorseRunningSpeed.Value;
			((Character)raeHorse.Prefab.GetComponent<Humanoid>()).m_walkSpeed = HorseWalkingSpeed.Value;
			((Character)raeHorse.Prefab.GetComponent<Humanoid>()).m_speed = HorseSpeed.Value;
			((Character)raeHorse.Prefab.GetComponent<Humanoid>()).m_turnSpeed = HorseTurnSpeed.Value;
			((Character)raeHorse.Prefab.GetComponent<Humanoid>()).m_runTurnSpeed = HorseRunningTurnSpeed.Value;
			((Character)raeHorse.Prefab.GetComponent<Humanoid>()).m_health = HorseHealth.Value;
			raeHorse.Prefab.GetComponentInChildren<Sadle>(true).m_maxStamina = HorseStamina.Value;
			raeHorse.Prefab.GetComponentInChildren<Sadle>(true).m_staminaRegen = HorseStaminaRegen.Value;
			raeHorse.Prefab.GetComponentInChildren<Sadle>(true).m_staminaRegenHungry = HorseStaminaRegenHungry.Value;
			raeHorse.Prefab.GetComponentInChildren<Procreation>(true).m_updateInterval = HorseProcreationUpdateInterval.Value;
			raeHorse.Prefab.GetComponentInChildren<Procreation>(true).m_totalCheckRange = HorseProcreationTotalCheckRange.Value;
			raeHorse.Prefab.GetComponentInChildren<Procreation>(true).m_maxCreatures = HorseProcreationMaxCreatures.Value;
			raeHorse.Prefab.GetComponentInChildren<Procreation>(true).m_partnerCheckRange = HorseProcreationPartnerCheckRange.Value;
			raeHorse.Prefab.GetComponentInChildren<Procreation>(true).m_pregnancyChance = HorseProcreationPregnancyChance.Value;
			raeHorse.Prefab.GetComponentInChildren<Procreation>(true).m_pregnancyDuration = HorseProcreationPregnancyDuration.Value;
			raeHorse.Prefab.GetComponentInChildren<Procreation>(true).m_requiredLovePoints = HorseProcreationRequiredLovePoints.Value;
			val2.GetComponent<CharacterDrop>().m_drops.Add(new Drop
			{
				m_prefab = item2.Prefab,
				m_amountMin = HorseOffspringHideDropMinimum.Value,
				m_amountMax = HorseOffspringHideDropMaximum.Value,
				m_chance = HorseOffspringHideDropChance.Value,
				m_levelMultiplier = true,
				m_onePerPlayer = false
			});
			val2.GetComponent<CharacterDrop>().m_drops.Add(new Drop
			{
				m_prefab = item.Prefab,
				m_amountMin = HorseOffspringMeatDropMinimum.Value,
				m_amountMax = HorseOffspringMeatDropMaximum.Value,
				m_chance = HorseOffspringMeatDropChance.Value,
				m_levelMultiplier = true,
				m_onePerPlayer = false
			});
			((Character)val2.GetComponent<Humanoid>()).m_health = HorseOffspringHealth.Value;
			val2.GetComponent<Growup>().m_growTime = HorseOffspringGrowupTime.Value;
			if (!HideHorsePin.Value)
			{
				CustomMapPins.RegisterCustomPin(raeHorse.Prefab, "$horse_odin", item3.Prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_icons[0]);
			}
			if (!HideCartPin.Value)
			{
				CustomMapPins_Cart.RegisterCustomPinGeneric(buildPiece4.Prefab, "$pin_cart", buildPiece4.Prefab.GetComponent<Piece>().m_icon);
			}
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			Harmony val12 = new Harmony("Raelaziel.OdinHorse");
			val12.PatchAll(executingAssembly);
		}

		private void LoadAssetBundle()
		{
			string text = "OdinHorse.assets.horsesets";
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(text);
			if (stream == null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Failed to load embedded resource: " + text));
				return;
			}
			horseAssetBundle = AssetBundle.LoadFromStream(stream);
			if ((Object)(object)horseAssetBundle == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Failed to load AssetBundle from stream.");
				return;
			}
			horseMaterials = new List<Material>
			{
				horseAssetBundle.LoadAsset<Material>("Horse_color_Black_Tobiano_pinto"),
				horseAssetBundle.LoadAsset<Material>("Horse_color_brown"),
				horseAssetBundle.LoadAsset<Material>("Horse_color_grays"),
				horseAssetBundle.LoadAsset<Material>("Horse_color_palomino"),
				horseAssetBundle.LoadAsset<Material>("Horse_color_white"),
				horseAssetBundle.LoadAsset<Material>("Horse_color_dark_grey")
			};
		}

		private void RegisterHorseWithCreatureManager()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			Creature creature = new Creature("horsesets", "rae_OdinHorse")
			{
				ConfigurationEnabled = true,
				TamingTime = 1600f,
				FedDuration = 300f,
				Biome = (Biome)1,
				CanSpawn = true,
				CanBeTamed = true,
				CanHaveStars = true,
				FoodItems = "Blueberries, Carrot, Cloudberry, Barley",
				SpawnChance = 15f,
				GroupSize = new CreatureManager.Range(1f, 2f),
				CheckSpawnInterval = 2000,
				SpecificSpawnTime = SpawnTime.Day,
				SpecificSpawnArea = SpawnArea.Center,
				RequiredWeather = Weather.ClearSkies,
				AttackImmediately = false,
				ForestSpawn = Forest.Both,
				CreatureFaction = (Faction)2,
				Maximum = 1
			};
			creature.Drops["rae_HorseMeat"].Amount = new CreatureManager.Range(1f, 2f);
			creature.Drops["rae_HorseMeat"].DropChance = 100f;
			creature.Drops["rae_HorseHide"].Amount = new CreatureManager.Range(1f, 2f);
			creature.Drops["rae_HorseHide"].DropChance = 100f;
			creature.Drops["rae_OdinHorse_Trophy"].Amount = new CreatureManager.Range(1f, 2f);
			creature.Drops["rae_OdinHorse_Trophy"].DropChance = 10f;
		}

		private void OnPrefabPostLoad(GameObject prefab)
		{
			SkinnedMeshRenderer componentInChildren = prefab.GetComponentInChildren<SkinnedMeshRenderer>();
			if (!((Object)(object)componentInChildren == (Object)null))
			{
				((Renderer)componentInChildren).material = horseMaterials[0];
			}
		}

		public static HorseBeasts ParseCharacterType(Character c)
		{
			if (c.IsPlayer())
			{
				return HorseBeasts.player;
			}
			if (c.m_nview.IsValid())
			{
				string name = ((Object)ZNetScene.instance.GetPrefab(c.m_nview.GetZDO().GetPrefab())).name;
				string text = name;
				if (text == "rae_OdinHorse")
				{
					return HorseBeasts.horse;
				}
				return HorseBeasts.horse;
			}
			return HorseBeasts.horse;
		}

		public static Vector3 GetCartOffsetVectorForCharacter(Character c)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)c))
			{
				return new Vector3(0f, 0.8f, 0f - c.GetRadius());
			}
			return new Vector3(0f, 0.8f, 0f);
		}

		public static bool IsAttachableCharacter(Character c)
		{
			return ParseCharacterType(c) switch
			{
				HorseBeasts.player => false, 
				HorseBeasts.horse => true, 
				_ => true, 
			};
		}

		public static float GetCartDetachDistance(Character c)
		{
			if (Object.op_Implicit((Object)(object)c))
			{
				if (c.IsPlayer())
				{
					return 2f;
				}
				return c.GetRadius() * 3f;
			}
			return 0f;
		}

		private static Character FindClosestAttachableAnimal(Vagon cart)
		{
			//IL_00cd: 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_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)cart == (Object)null || (Object)(object)cart.m_attachPoint == (Object)null)
			{
				return null;
			}
			Transform attachPoint = cart.m_attachPoint;
			Character result = null;
			float num = float.MaxValue;
			if (!Object.op_Implicit((Object)(object)cart.m_attachPoint))
			{
				return null;
			}
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if (!((Object)(object)allCharacter == (Object)null) && allCharacter.m_nview.IsValid() && !allCharacter.IsDead() && Object.op_Implicit((Object)(object)allCharacter) && !allCharacter.IsPlayer() && allCharacter.IsTamed() && IsAttachableCharacter(allCharacter))
				{
					Vector3 cartOffsetVectorForCharacter = GetCartOffsetVectorForCharacter(allCharacter);
					Vector3 position = ((Component)allCharacter).transform.position;
					float num2 = Vector3.Distance(position + cartOffsetVectorForCharacter, attachPoint.position);
					float cartDetachDistance = GetCartDetachDistance(allCharacter);
					if (num2 < cartDetachDistance && num2 < num)
					{
						result = allCharacter;
						num = num2;
					}
				}
			}
			return result;
		}

		private static Character AttachedCharacter(Vagon cart)
		{
			if (Object.op_Implicit((Object)(object)cart) && cart.IsAttached())
			{
				return ((Component)((Joint)cart.m_attachJoin).connectedBody).gameObject.GetComponent<Character>();
			}
			return null;
		}

		private static void LogCartContents(Vagon cart)
		{
			Container container = cart.m_container;
			foreach (ItemData allItem in container.GetInventory().GetAllItems())
			{
			}
		}

		private static void AttachCartTo(Character attachTarget, Vagon cart)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			cart.m_attachOffset = GetCartOffsetVectorForCharacter(attachTarget);
			cart.m_attachJoin = ((Component)cart).gameObject.AddComponent<ConfigurableJoint>();
			((Joint)cart.m_attachJoin).autoConfigureConnectedAnchor = false;
			((Joint)cart.m_attachJoin).anchor = cart.m_attachPoint.localPosition;
			((Joint)cart.m_attachJoin).connectedAnchor = cart.m_attachOffset;
			((Joint)cart.m_attachJoin).breakForce = cart.m_breakForce;
			cart.m_attachJoin.xMotion = (ConfigurableJointMotion)1;
			cart.m_attachJoin.yMotion = (ConfigurableJointMotion)1;
			cart.m_attachJoin.zMotion = (ConfigurableJointMotion)1;
			SoftJointLimit linearLimit = default(SoftJointLimit);
			((SoftJointLimit)(ref linearLimit)).limit = 0.05f;
			cart.m_attachJoin.linearLimit = linearLimit;
			SoftJointLimitSpring linearLimitSpring = default(SoftJointLimitSpring);
			((SoftJointLimitSpring)(ref linearLimitSpring)).spring = cart.m_spring;
			((SoftJointLimitSpring)(ref linearLimitSpring)).damper = cart.m_springDamping;
			cart.m_attachJoin.linearLimitSpring = linearLimitSpring;
			cart.m_attachJoin.zMotion = (ConfigurableJointMotion)0;
			((Joint)cart.m_attachJoin).connectedBody = ((Component)attachTarget).gameObject.GetComponent<Rigidbody>();
		}
	}
	public static class KeyboardExtensions
	{
		public static bool IsKeyDown(this KeyboardShortcut shortcut)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return (int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey) && ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey);
		}

		public static bool IsKeyHeld(this KeyboardShortcut shortcut)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return (int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKey(((KeyboardShortcut)(ref shortcut)).MainKey) && ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey);
		}
	}
	[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(0)]
	[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(1)]
	public static class TameableExtensions
	{
		public static ItemDrop m_armorItem = null;

		public static readonly int s_haveArmorHash = StringExtensionMethods.GetStableHashCode("HaveArmor");

		public static readonly int s_isWaitingHash = StringExtensionMethods.GetStableHashCode("IsWaiting");

		public static ItemDrop GetArmorItem(this Tameable tameable)
		{
			return m_armorItem;
		}

		public static bool IsWaiting(this Tameable tameable)
		{
			return tameable.m_nview.IsValid() && tameable.m_nview.GetZDO().GetBool(s_isWaitingHash, false);
		}

		public static void RPC_ToggleWait(this Tameable tameable, long sender)
		{
			if (tameable.m_nview.IsOwner())
			{
				bool flag = !tameable.IsWaiting();
				tameable.m_nview.GetZDO().Set(s_isWaitingHash, flag);
				tameable.m_nview.InvokeRPC(ZNetView.Everybody, "SetWait", new object[1] { flag });
			}
		}

		public static void RPC_SetWait(this Tameable tameable, long sender, bool enabled)
		{
			tameable.SetWaitAnimation(enabled);
		}

		public static void SetWaitAnimation(this Tameable tameable, bool enabled)
		{
			MonsterAI component = ((Component)tameable).GetComponent<MonsterAI>();
			if ((Object)(object)component != (Object)null && (Object)(object)((BaseAI)component).m_animator != (Object)null)
			{
				((BaseAI)component).m_animator.SetBool("isWaiting", enabled);
			}
		}

		public static void RPC_AddArmor(this Tameable tameable, long sender)
		{
			if (tameable.m_nview.IsOwner() && !tameable.HaveArmor())
			{
				float num = tameable.m_character.GetHealth() / tameable.m_character.GetMaxHealth();
				tameable.m_character.SetMaxHealth(tameable.m_character.GetMaxHealth() + 200f);
				tameable.m_character.SetHealth(tameable.m_character.GetMaxHealth() * num);
				tameable.m_nview.GetZDO().Set(s_haveArmorHash, true);
				tameable.m_nview.InvokeRPC(ZNetView.Everybody, "SetArmor", new object[1] { true });
			}
		}

		public static void RPC_SetArmor(this Tameable tameable, long sender, bool enabled)
		{
			tameable.SetArmor(enabled);
		}

		public static void RPC_RemoveArmor(this Tameable tameable, long sender, Vector3 userPoint)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			if (tameable.m_nview.IsOwner())
			{
				Character character = tameable.m_character;
				float num = character.GetHealth() / character.GetMaxHealth();
				character.SetMaxHealth(character.GetMaxHealth() - 200f);
				character.SetHealth(character.GetMaxHealth() * num);
				tameable.DropArmor(userPoint);
			}
		}

		public static void SetArmor(this Tameable tameable, bool enabled)
		{
			ZLog.Log((object)("Setting armor:" + enabled));
			if (!((Object)(object)tameable.GetArmorItem() == (Object)null))
			{
				SetArmorObjectsOn(tameable, enabled);
			}
		}

		public static void SetArmorObjectsOn(Tameable tameable, bool enabled)
		{
			((Component)Utils.FindChild(((Component)tameable).transform, "Horse_mask", (IterativeSearchType)0)).gameObject.SetActive(enabled);
			((Component)Utils.FindChild(((Component)tameable).transform, "horse_armor", (IterativeSearchType)0)).gameObject.SetActive(enabled);
		}

		public static bool HaveArmor(this Tameable tameable)
		{
			return tameable.m_nview.IsValid() && tameable.m_nview.GetZDO().GetBool(s_haveArmorHash, false);
		}

		public static bool DropArmor(this Tameable tameable, Vector3 userPoint)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			if (!tameable.HaveArmor())
			{
				return false;
			}
			tameable.m_nview.GetZDO().Set(s_haveArmorHash, false);
			tameable.m_nview.InvokeRPC(ZNetView.Everybody, "SetArmor", new object[1] { false });
			tameable.SpawnArmor(userPoint - ((Component)tameable).transform.position);
			return true;
		}

		public static void SpawnArmor(this Tameable tameable, Vector3 flyDirection)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			Rigidbody component = Object.Instantiate<GameObject>(((Component)m_armorItem).gameObject, ((Component)tameable).transform.TransformPoint(tameable.m_dropSaddleOffset), Quaternion.identity).GetComponent<Rigidbody>();
			if (Object.op_Implicit((Object)(object)component))
			{
				Vector3 val = Vector3.up;
				if ((double)((Vector3)(ref flyDirection)).magnitude > 0.10000000149011612)
				{
					flyDirection.y = 0f;
					((Vector3)(ref flyDirection)).Normalize();
					val += flyDirection;
				}
				component.AddForce(val * tameable.m_dropItemVel, (ForceMode)2);
			}
		}

		public static void OnHorseDeath(this Tameable tameable)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			ZLog.Log((object)("Valid " + tameable.m_nview.IsValid()));
			ZLog.Log((object)("On death " + tameable.HaveArmor()));
			if (tameable.HaveArmor() && tameable.m_dropSaddleOnDeath)
			{
				ZLog.Log((object)"Spawning armor ");
				tameable.SpawnArmor(Vector3.zero);
			}
		}
	}
	[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(0)]
	[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(1)]
	[HarmonyPatch(typeof(CookingStation))]
	public static class CookingStationPatch
	{
		private static bool ConversionAdded;

		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		public static void Awake_Postfix(CookingStation __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				Debug.LogError((object)"CookingStation instance is null in Awake_Postfix.");
				return;
			}
			if (__instance.m_conversion == null)
			{
				__instance.m_conversion = new List<ItemConversion>();
			}
			AddCustomConversion(__instance);
		}

		private static void AddCustomConversion(CookingStation station)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			try
			{
				if ((Object)(object)station == (Object)null || station.m_conversion == null)
				{
					Debug.LogError((object)"CookingStation or m_conversion is null during AddCustomConversion.");
				}
				else
				{
					if (station.m_conversion.Exists([<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)] (ItemConversion c) => ((Object)c.m_from).name == "rae_HorseMeat" && ((Object)c.m_to).name == "rae_CookedHorseMeat"))
					{
						return;
					}
					ItemConversion val = new ItemConversion
					{
						m_from = ObjectDB.instance.GetItemPrefab("rae_HorseMeat").GetComponent<ItemDrop>(),
						m_to = ObjectDB.instance.GetItemPrefab("rae_CookedHorseMeat").GetComponent<ItemDrop>(),
						m_cookTime = 25f
					};
					if ((Object)(object)val.m_from == (Object)null || (Object)(object)val.m_to == (Object)null)
					{
						Debug.LogError((object)"Could not find prefabs for 'rae_HorseMeat' or 'rae_CookedHorseMeat'.");
						return;
					}
					station.m_conversion.Add(val);
					if (!ConversionAdded)
					{
						Debug.Log((object)$"Added custom conversion: {((Object)val.m_from).name} -> {((Object)val.m_to).name} with cook time {val.m_cookTime}s.");
						ConversionAdded = true;
					}
				}
			}
			catch (Exception arg)
			{
				Debug.LogError((object)$"Exception in AddCustomConversion: {arg}");
			}
		}
	}
}
namespace CreatureManager
{
	public enum Toggle
	{
		On,
		Off
	}
	[PublicAPI]
	public enum GlobalKey
	{
		[InternalName("")]
		None,
		[InternalName("defeated_bonemass")]
		KilledBonemass,
		[InternalName("defeated_gdking")]
		KilledElder,
		[InternalName("defeated_goblinking")]
		KilledYagluth,
		[InternalName("defeated_dragon")]
		KilledModer,
		[InternalName("defeated_eikthyr")]
		KilledEikthyr,
		[InternalName("KilledTroll")]
		KilledTroll,
		[InternalName("killed_surtling")]
		KilledSurtling
	}
	[PublicAPI]
	[Flags]
	public enum Weather
	{
		[InternalName("")]
		None = 0,
		[InternalName("Clear")]
		ClearSkies = 1,
		[InternalName("Heath clear")]
		MeadowsClearSkies = 4,
		[InternalName("LightRain")]
		LightRain = 8,
		[InternalName("Rain")]
		Rain = 0x10,
		[InternalName("ThunderStorm")]
		ThunderStorm = 0x20,
		[InternalName("nofogts")]
		ClearThunderStorm = 0x40,
		[InternalName("SwampRain")]
		SwampRain = 0x80,
		[InternalName("Darklands_dark")]
		MistlandsDark = 0x100,
		[InternalName("Ashrain")]
		AshlandsAshrain = 0x200,
		[InternalName("Snow")]
		MountainSnow = 0x400,
		[InternalName("SnowStorm")]
		MountainBlizzard = 0x800,
		[InternalName("DeepForest Mist")]
		BlackForestFog = 0x1000,
		[InternalName("Misty")]
		Fog = 0x2000,
		[InternalName("Twilight_Snow")]
		DeepNorthSnow = 0x4000,
		[InternalName("Twilight_SnowStorm")]
		DeepNorthSnowStorm = 0x8000,
		[InternalName("Twilight_Clear")]
		DeepNorthClear = 0x10000,
		[InternalName("Eikthyr")]
		EikthyrsThunderstorm = 0x20000,
		[InternalName("GDKing")]
		EldersHaze = 0x40000,
		[InternalName("Bonemass")]
		BonemassDownpour = 0x80000,
		[InternalName("Moder")]
		ModersVortex = 0x100000,
		[InternalName("GoblinKing")]
		YagluthsMagicBlizzard = 0x200000,
		[InternalName("Crypt")]
		Crypt = 0x400000,
		[InternalName("SunkenCrypt")]
		SunkenCrypt = 0x800000
	}
	[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(1)]
	[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(0)]
	public class InternalName : Attribute
	{
		public readonly string internalName;

		public InternalName(string internalName)
		{
			this.internalName = internalName;
		}
	}
	public enum DropOption
	{
		Disabled,
		Default,
		Custom
	}
	public enum SpawnOption
	{
		Disabled,
		Default,
		Custom
	}
	public enum SpawnTime
	{
		Day,
		Night,
		Always
	}
	public enum SpawnArea
	{
		Center,
		Edge,
		Everywhere
	}
	public enum Forest
	{
		Yes,
		No,
		Both
	}
	[PublicAPI]
	public struct Range
	{
		public float min;

		public float max;

		public Range(float min, float max)
		{
			this.min = min;
			this.max = max;
		}
	}
	[PublicAPI]
	[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(0)]
	[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(1)]
	public class Creature
	{
		[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(0)]
		[PublicAPI]
		public class DropList
		{
			[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(0)]
			internal class SerializedDrops
			{
				[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(new byte[] { 1, 0, 1, 1 })]
				public readonly List<KeyValuePair<string, Drop>> Drops;

				public SerializedDrops(DropList drops, Creature creature)
				{
					Drops = (drops.drops ?? creature.Prefab.GetComponent<CharacterDrop>()?.m_drops.ToDictionary([<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)] (Drop drop) => ((Object)drop.m_prefab).name, [<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)] (Drop drop) => new Drop
					{
						Amount = new Range(drop.m_amountMin, drop.m_amountMax),
						DropChance = drop.m_chance,
						DropOnePerPlayer = drop.m_onePerPlayer,
						MultiplyDropByLevel = drop.m_levelMultiplier
					}) ?? new Dictionary<string, Drop>()).ToList();
				}

				public SerializedDrops([<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(new byte[] { 1, 0, 1, 1 })] List<KeyValuePair<string, Drop>> drops)
				{
					Drops = drops;
				}

				public SerializedDrops(string reqs)
				{
					Drops = (from r in reqs.Split(new char[1] { ',' })
						select r.Split(new char[1] { ':' })).ToDictionary([<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)] (string[] l) => l[0], [<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)] (string[] parts) =>
					{
						Range amount = new Range(1f, 1f);
						if (parts.Length > 1)
						{
							string[] array = parts[1].Split(new char[1] { '-' });
							if (!int.TryParse(array[0], out var result))
							{
								result = 1;
							}
							if (array.Length == 1 || !int.TryParse(array[0], out var result2))
							{
								result2 = result;
							}
							amount = new Range(result, result2);
						}
						float result3;
						return new Drop
						{
							Amount = amount,
							DropChance = ((parts.Length > 2 && float.TryParse(parts[2], out result3)) ? result3 : 100f),
							DropOnePerPlayer = (parts.Length > 3 && parts[3] == "onePerPlayer"),
							MultiplyDropByLevel = (parts.Length > 4 && parts[4] == "multiplyByLevel")
						};
					}).ToList();
				}

				public override string ToString()
				{
					return string.Join(",", Drops.Select([<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)] (KeyValuePair<string, Drop> kv) => string.Format("{0}:{1}-{2}:{3}:{4}:{5}", kv.Key, kv.Value.Amount.min, kv.Value.Amount.max, kv.Value.DropChance, kv.Value.DropOnePerPlayer ? "onePerPlayer" : "unrestricted", kv.Value.MultiplyDropByLevel ? "multiplyByLevel" : "unaffectedByLevel")));
				}
			}

			[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(new byte[] { 2, 1, 1 })]
			private Dictionary<string, Drop> drops = null;

			public Drop this[string prefabName]
			{
				get
				{
					Drop result;
					if (!(drops ?? (drops = new Dictionary<string, Drop>())).TryGetValue(prefabName, out var value))
					{
						Drop drop2 = (drops[prefabName] = new Drop());
						result = drop2;
					}
					else
					{
						result = value;
					}
					return result;
				}
			}

			public void None()
			{
				drops = new Dictionary<string, Drop>();
			}

			[HarmonyPriority(700)]
			internal static void AddDropsToCreature()
			{
				foreach (Creature registeredCreature in registeredCreatures)
				{
					UpdateDrops(registeredCreature);
				}
			}

			internal static void UpdateDrops(Creature creature)
			{
				DropOption dropOption = creatureConfigs[creature].Drops.get();
				if (dropOption == DropOption.Default && creature.Drops.drops == null)
				{
					return;
				}
				CharacterDrop val = creature.Prefab.GetComponent<CharacterDrop>() ?? creature.Prefab.AddComponent<CharacterDrop>();
				DropOption dropOption2 = creatureConfigs[creature].Drops.get();
				if (1 == 0)
				{
				}
				List<KeyValuePair<string, Drop>> source = dropOption2 switch
				{
					DropOption.Custom => new SerializedDrops(creatureConfigs[creature].CustomDrops.get()).Drops, 
					DropOption.Disabled => new List<KeyValuePair<string, Drop>>(), 
					_ => creature.Drops.drops.ToList(), 
				};
				if (1 == 0)
				{
				}
				val.m_drops = (from d in ((IEnumerable<KeyValuePair<string, Drop>>)source).Select((Func<KeyValuePair<string, Drop>, Drop>)([<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)] (KeyValuePair<string, Drop> kv) =>
					{
						//IL_0079: 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_0085: Unknown result type (might be due to invalid IL or missing references)
						//IL_009d: Unknown result type (might be due to invalid IL or missing references)
						//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
						//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
						//IL_00df: Unknown result type (might be due to invalid IL or missing references)
						//IL_00f2: Expected O, but got Unknown
						if (kv.Key == "" || ZNetScene.instance == null)
						{
							return null;
						}
						GameObject prefab = ZNetScene.instance.GetPrefab(kv.Key);
						if (prefab == null)
						{
							Debug.LogWarning((object)("Found invalid prefab name " + kv.Key + " for creature " + ((Object)creature.Prefab).name));
							return null;
						}
						return new Drop
						{
							m_prefab = prefab,
							m_amountMin = (int)kv.Value.Amount.min,
							m_amountMax = (int)kv.Value.Amount.max,
							m_chance = kv.Value.DropChance / 100f,
							m_onePerPlayer = kv.Value.DropOnePerPlayer,
							m_levelMultiplier = kv.Value.MultiplyDropByLevel
						};
					}))
					where d != null
					select d).ToList();
			}
		}

		[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)]
		[PublicAPI]
		public class Drop
		{
			public Range Amount = new Range(1f, 1f);

			public float DropChance = 100f;

			public bool DropOnePerPlayer = false;

			public bool MultiplyDropByLevel = true;
		}

		[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)]
		private class CustomConfig<[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(2)] T>
		{
			[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(1)]
			public Func<T> get = null;

			[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(new byte[] { 2, 1 })]
			public ConfigEntry<T> config = null;
		}

		[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(0)]
		private class CreatureConfig
		{
			public readonly CustomConfig<SpawnOption> Spawn = new CustomConfig<SpawnOption>();

			public readonly CustomConfig<Toggle> CanBeTamed = new CustomConfig<Toggle>();

			public readonly CustomConfig<string> ConsumesItemName = new CustomConfig<string>();

			public readonly CustomConfig<float> FedDuration = new CustomConfig<float>();

			public readonly CustomConfig<float> TamingTime = new CustomConfig<float>();

			public readonly CustomConfig<Toggle> SpawnsTamed = new CustomConfig<Toggle>();

			public readonly CustomConfig<Faction> CreatureFaction = new CustomConfig<Faction>();

			public readonly CustomConfig<SpawnTime> SpecificSpawnTime = new CustomConfig<SpawnTime>();

			public readonly CustomConfig<Range> RequiredAltitude = new CustomConfig<Range>();

			public readonly CustomConfig<Range> RequiredOceanDepth = new CustomConfig<Range>();

			public readonly CustomConfig<GlobalKey> RequiredGlobalKey = new CustomConfig<GlobalKey>();

			public readonly CustomConfig<Range> GroupSize = new CustomConfig<Range>();

			public readonly CustomConfig<Biome> Biome = new CustomConfig<Biome>();

			public readonly CustomConfig<SpawnArea> SpecificSpawnArea = new CustomConfig<SpawnArea>();

			public readonly CustomConfig<Weather> RequiredWeather = new CustomConfig<Weather>();

			public readonly CustomConfig<float> SpawnAltitude = new CustomConfig<float>();

			public readonly CustomConfig<Toggle> CanHaveStars = new CustomConfig<Toggle>();

			public readonly CustomConfig<Toggle> AttackImmediately = new CustomConfig<Toggle>();

			public readonly CustomConfig<int> CheckSpawnInterval = new CustomConfig<int>();

			public readonly CustomConfig<float> SpawnChance = new CustomConfig<float>();

			public readonly CustomConfig<Forest> ForestSpawn = new CustomConfig<Forest>();

			public readonly CustomConfig<int> Maximum = new CustomConfig<int>();

			public readonly CustomConfig<DropOption> Drops = new CustomConfig<DropOption>();

			public readonly CustomConfig<string> CustomDrops = new CustomConfig<string>();
		}

		[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)]
		private class ConfigurationManagerAttributes
		{
			[UsedImplicitly]
			public int? Order;

			[UsedImplicitly]
			public bool? Browsable;

			[UsedImplicitly]
			[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(2)]
			public string Category;

			[UsedImplicitly]
			[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(new byte[] { 2, 1 })]
			public Action<ConfigEntryBase> CustomDrawer;
		}

		[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(0)]
		private class AcceptableEnumValues<[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(0)] T> : AcceptableValueBase where T : struct, IConvertible
		{
			[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(new byte[] { 1, 0 })]
			[PublicAPI]
			public virtual T[] AcceptableValues
			{
				[return: <294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(new byte[] { 1, 0 })]
				get;
			}

			public AcceptableEnumValues([<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(new byte[] { 1, 0 })] params T[] acceptableValues)
				: base(typeof(T))
			{
				AcceptableValues = acceptableValues;
			}

			public override object Clamp(object value)
			{
				return ((AcceptableValueBase)this).IsValid(value) ? value : ((object)AcceptableValues[0]);
			}

			public override bool IsValid(object value)
			{
				return AcceptableValues.Contains((T)value);
			}

			public override string ToDescriptionString()
			{
				return string.Join(", ", AcceptableValues);
			}
		}

		public bool ConfigurationEnabled = true;

		public readonly GameObject Prefab;

		public DropList Drops = new DropList();

		public bool CanSpawn = true;

		public bool CanBeTamed = false;

		[Description("List of items the creature consumes to get tame.\nFor multiple item names, separate them with a comma.")]
		public string FoodItems;

		[Description("How long the creature remains fed after eating.")]
		public float FedDuration;

		[Description("Time it takes to tame the creature.")]
		public float TamingTime;

		[Description("If the creature spawns tamed.")]
		public bool SpawnsTamed;

		[Description("The creature faction the creature belongs to.")]
		public Faction CreatureFaction;

		[Description("Sets the time of day the creature can spawn.")]
		public SpawnTime SpecificSpawnTime = SpawnTime.Always;

		[Description("Sets the minimum and maximum altitude for the creature to spawn.")]
		public Range RequiredAltitude = new Range(5f, 1000f);

		[Description("Sets the minimum and maximum depth of the ocean for the creature to spawn.")]
		public Range RequiredOceanDepth = new Range(0f, 0f);

		[Description("Sets a global key required for the creature to spawn.")]
		public GlobalKey RequiredGlobalKey = GlobalKey.None;

		[Description("Sets a range for the group size the creature spawns in.")]
		public Range GroupSize = new Range(1f, 1f);

		[Description("Sets the biome the creature spawns in.")]
		public Biome Biome = (Biome)1;

		[Description("Sets spawning area for the creature inside the biome.\nUse SpawnArea.Edge, to make the creature spawn more towards the edge of the biome.\nUse SpawnArea.Center, to make the creature spawn more towards the center of the biome.")]
		public SpawnArea SpecificSpawnArea = SpawnArea.Everywhere;

		[Description("Sets the weather condition for the creature to spawn.\nUse the Weather enum for easy configuration.")]
		public Weather RequiredWeather = Weather.None;

		[Description("Sets altitude relative to the current ground level for the creature to spawn.\nShould be a higher number for flying creatures, so they spawn in the sky.")]
		public float SpawnAltitude = 0.5f;

		public bool CanHaveStars = true;

		[Description("Controls the first AI command right after spawn.\nSet to true for the creature to immediately start to hunt down the player.")]
		public bool AttackImmediately = false;

		[Description("The time between attempts to spawn the creature in.")]
		public int CheckSpawnInterval = 600;

		[Description("The chance in percent for the creature to spawn, every time Valheim checks if it should spawn.")]
		public float SpawnChance = 100f;

		[Description("Can be used to make the creature spawn in forests or prevent it from spawning in forests.\nUse the Forest enum for easy configuration.")]
		public Forest ForestSpawn = Forest.Both;

		[Description("Sets the maximum number of the creature that can be near the player, before Valheim disables its spawn.")]
		public int Maximum = 1;

		private static readonly List<Creature> registeredCreatures = new List<Creature>();

		private static Dictionary<Creature, CreatureConfig> creatureConfigs = new Dictionary<Creature, CreatureConfig>();

		[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(2)]
		private static object configManager;

		private static List<SpawnData> lastRegisteredSpawns = new List<SpawnData>();

		[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(2)]
		private static Localization _english;

		[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(2)]
		private static BaseUnityPlugin _plugin;

		private static bool hasConfigSync = true;

		[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(2)]
		private static object _configSync;

		private static Localization english => _english ?? (_english = LocalizationCache.ForLanguage("English"));

		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([<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)] (TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
				}
				return _plugin;
			}
		}

		[<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(2)]
		private static object configSync
		{
			[<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(2)]
			get
			{
				if (_configSync == null && hasConfigSync)
				{
					Type type = Assembly.GetExecutingAssembly().GetType("ServerSync.ConfigSync");
					if ((object)type != null)
					{
						_configSync = Activator.CreateInstance(type, plugin.Info.Metadata.GUID + " CreatureManager");
						type.GetField("CurrentVersion").SetValue(_configSync, plugin.Info.Metadata.Version.ToString());
						type.GetProperty("IsLocked").SetValue(_configSync, true);
					}
					else
					{
						hasConfigSync = false;
					}
				}
				return _configSync;
			}
		}

		public Creature(string assetBundleFileName, string prefabName, string folderName = "assets")
			: this(PrefabManager.RegisterAssetBundle(assetBundleFileName, folderName), prefabName)
		{
		}

		public Creature(AssetBundle bundle, string prefabName)
			: this(PrefabManager.RegisterPrefab(bundle, prefabName))
		{
		}

		public Creature(GameObject creature)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			Prefab = creature;
			registeredCreatures.Add(this);
			CanBeTamed = Object.op_Implicit((Object)(object)creature.GetComponent<Tameable>());
			FoodItems = string.Join(",", (from i in creature.GetComponent<MonsterAI>()?.m_consumeItems
				where Object.op_Implicit((Object)(object)i.m_itemData.m_dropPrefab)
				select ((Object)i.m_itemData.m_dropPrefab).name) ?? Enumerable.Empty<string>());
		}

		public LocalizeKey Localize()
		{
			return new LocalizeKey(Prefab.GetComponent<Character>().m_name);
		}

		internal static void Patch_FejdStartup()
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Expected O, but got Unknown
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Expected O, but got Unknown
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Expected O, but got Unknown
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Expected O, but got Unknown
			//IL_07ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c4: Expected O, but got Unknown
			Type type = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault([<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)] (Assembly a) => a.GetName().Name == "ConfigurationManager")?.GetType("ConfigurationManager.ConfigurationManager");
			configManager = ((type == null) ? null : Chainloader.ManagerObject.GetComponent(type));
			if (!TomlTypeConverter.CanConvert(typeof(Range)))
			{
				TomlTypeConverter.AddConverter(typeof(Range), new TypeConverter
				{
					ConvertToObject = [<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)] (string s, Type _) =>
					{
						Match match = Regex.Match(s, "^(-?\\d+(?:\\.\\d*)?)\\s*-\\s*(-?\\d+(?:\\.\\d*)?)$");
						return match.Success ? new Range(float.Parse(match.Groups[1].Value), float.Parse(match.Groups[2].Value)) : default(Range);
					},
					ConvertToString = [<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)] (object obj, Type _) =>
					{
						Range range = (Range)obj;
						return $"{range.min} - {range.max}";
					}
				});
			}
			bool saveOnConfigSet = plugin.Config.SaveOnConfigSet;
			plugin.Config.SaveOnConfigSet = false;
			foreach (Creature registeredCreature in registeredCreatures)
			{
				Creature creature = registeredCreature;
				CreatureConfig creatureConfig2 = (creatureConfigs[creature] = new CreatureConfig());
				CreatureConfig cfg = creatureConfig2;
				string name2 = creature.Prefab.GetComponent<Character>().m_name;
				string englishName = new Regex("['[\"\\]]").Replace(english.Localize(name2), "").Trim();
				string localizedName = Localization.instance.Localize(name2).Trim();
				int order = 0;
				ConfigurationManagerAttributes tameConfigVisibility = new ConfigurationManagerAttributes();
				config<Toggle>(cfg.CanBeTamed, () => (!creature.CanBeTamed) ? Toggle.Off : Toggle.On, delegate
				{
					tameConfigVisibility.Browsable = cfg.CanBeTamed.get() == Toggle.On;
					reloadConfigDisplay();
					updateAI();
				}, "Can be tamed", "Decides, if the creature can be tamed.");
				tameConfigVisibility.Browsable = cfg.CanBeTamed.get() == Toggle.On;
				configWithDesc<string>(cfg.ConsumesItemName, [<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)] () => creature.FoodItems, updateAI, "Food items", new ConfigDescription("The items the creature consumes to get tame.", (AcceptableValueBase)null, new object[1] { tameConfigVisibility }));
				configWithDesc<float>(cfg.FedDuration, () => creature.FedDuration, updateAI, "Fed Duration", new ConfigDescription("How long the creature stays fed after eating, in seconds.", (AcceptableValueBase)null, new object[1] { tameConfigVisibility }));
				configWithDesc<float>(cfg.TamingTime, () => creature.TamingTime, updateAI, "Time to Tame", new ConfigDescription("The time it takes to tame the creature.", (AcceptableValueBase)null, new object[1] { tameConfigVisibility }));
				configWithDesc<Toggle>(cfg.SpawnsTamed, () => (!creature.SpawnsTamed) ? Toggle.Off : Toggle.On, updateAI, "Spawns Tamed", new ConfigDescription("If on, the creature spawns tamed.", (AcceptableValueBase)null, new object[1] { tameConfigVisibility }));
				ConfigurationManagerAttributes spawnConfigVisibility = new ConfigurationManagerAttributes();
				ConfigurationManagerAttributes dropConfigVisibility = new ConfigurationManagerAttributes();
				config<SpawnOption>(cfg.Spawn, () => creature.CanSpawn ? SpawnOption.Default : SpawnOption.Disabled, delegate
				{
					spawnConfigVisibility.Browsable = cfg.Spawn.get() == SpawnOption.Custom;
					reloadConfigDisplay();
					updateAllSpawnConfigs();
				}, "Spawn", "Configures the spawn for the creature.");
				spawnConfigVisibility.Browsable = cfg.Spawn.get() == SpawnOption.Custom;
				spawnConfig<SpawnTime>(cfg.SpecificSpawnTime, () => creature.SpecificSpawnTime, "Spawn time", "Configures the time of day for the creature to spawn.");
				spawnConfig<Range>(cfg.RequiredAltitude, () => creature.RequiredAltitude, "Required altitude", "Configures the altitude required for the creature to spawn.");
				spawnConfig<Range>(cfg.RequiredOceanDepth, () => creature.RequiredOceanDepth, "Required ocean depth", "Configures the ocean depth required for the creature to spawn.");
				spawnConfig<GlobalKey>(cfg.RequiredGlobalKey, () => creature.RequiredGlobalKey, "Required global key", "Configures the global key required for the creature to spawn.");
				spawnConfig<Range>(cfg.GroupSize, () => creature.GroupSize, "Group size", "Configures the size of the groups in which the creature spawns.");
				spawnConfig<Biome>(cfg.Biome, () => creature.Biome, "Biome", "Configures the biome required for the creature to spawn.");
				spawnConfig<SpawnArea>(cfg.SpecificSpawnArea, () => creature.SpecificSpawnArea, "Spawn area", "Configures if the creature spawns more towards the center or the edge of the biome.");
				spawnConfig<Weather>(cfg.RequiredWeather, () => creature.RequiredWeather, "Required weather", "Configures the weather required for the creature to spawn.");
				spawnConfig<float>(cfg.SpawnAltitude, () => creature.SpawnAltitude, "Spawn altitude", "Configures the height from the ground in which the creature will spawn.");
				spawnConfig<Toggle>(cfg.CanHaveStars, () => (!creature.CanHaveStars) ? Toggle.Off : Toggle.On, "Can have stars", "If the creature can have stars.");
				spawnConfig<Toggle>(cfg.AttackImmediately, () => (!creature.AttackImmediately) ? Toggle.Off : Toggle.On, "Hunt player", "Makes the creature immediately hunt down the player after it spawns.");
				spawnConfig<int>(cfg.CheckSpawnInterval, () => creature.CheckSpawnInterval, "Maximum spawn interval", "Configures the timespan that Valheim has to make the creature spawn.");
				spawnConfig<float>(cfg.SpawnChance, () => creature.SpawnChance, "Spawn chance", "Sets the chance for the creature to be spawned, every time Valheim checks the spawn.");
				spawnConfig<Forest>(cfg.ForestSpawn, () => creature.ForestSpawn, "Forest condition", "If the creature can spawn in forests or cannot spawn in forests. Or both.");
				spawnConfig<int>(cfg.Maximum, () => creature.Maximum, "Maximum creature count", "The maximum number of this creature near the player, before Valheim stops spawning it in. Setting this lower than the upper limit of the group size does not make sense.");
				config<DropOption>(cfg.Drops, () => DropOption.Default, delegate
				{
					dropConfigVisibility.Browsable = cfg.Drops.get() == DropOption.Custom;
					reloadConfigDisplay();
					DropList.UpdateDrops(creature);
				}, "Drops", "Configures the drops for the creature.");
				dropConfigVisibility.Browsable = cfg.Drops.get() == DropOption.Custom;
				configWithDesc<string>(cfg.CustomDrops, [<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)] () => new DropList.SerializedDrops(creature.Drops, creature).ToString(), delegate
				{
					DropList.UpdateDrops(creature);
				}, "Drop config", new ConfigDescription("", (AcceptableValueBase)null, new object[1] { dropConfigVisibility }));
				config<Faction>(cfg.CreatureFaction, () => creature.CreatureFaction, updateCharacterAttributes, "Creature Faction", "The creature faction the creature belongs to.");
				void config<T>([<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(new byte[] { 1, 0 })] CustomConfig<T> customConfig, [<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(new byte[] { 1, 0 })] Func<T> getter, Action configChanged, string name, string desc)
				{
					//IL_000e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0018: Expected O, but got Unknown
					configWithDesc<T>(customConfig, getter, configChanged, name, new ConfigDescription(desc, (AcceptableValueBase)null, Array.Empty<object>()));
				}
				void configWithDesc<T>([<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(new byte[] { 1, 0 })] CustomConfig<T> customConfig, [<294acbb2-4027-423d-bec5-ab4f5aa48c99>Nullable(new byte[] { 1, 0 })] Func<T> getter, Action configChanged, string name, ConfigDescription desc)
				{
					//IL_0107: Unknown result type (might be due to invalid IL or missing references)
					//IL_0111: Expected O, but got Unknown
					if (creature.ConfigurationEnabled)
					{
						customConfig.config = pluginConfig(englishName, name, getter(), new ConfigDescription(desc.Description, desc.AcceptableValues, desc.Tags.Concat(new ConfigurationManagerAttributes[1]
						{
							new ConfigurationManagerAttributes
							{
								Order = (order -= 1),
								CustomDrawer = ((customConfig == cfg.CustomDrops) ? new Action<ConfigEntryBase>(drawConfigTable) : ((typeof(T) == typeof(Range)) ? new Action<ConfigEntryBase>(drawRange) : null)),
								Category = localizedName
							}
						}).ToArray()));
						customConfig.config.SettingChanged += [<759a1d65-f704-449f-bbb0-1443af4eaea1>NullableContext(0)] (object _, Eve