Decompiled source of LetMeTameYou v0.0.1

LetMeTameYou.dll

Decompiled a day 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.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using LetMeTameYou.RPC;
using LocalizationManager;
using Microsoft.CodeAnalysis;
using ServerSync;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.ObjectPool;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.BufferedDeserialization;
using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators;
using YamlDotNet.Serialization.Callbacks;
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: AssemblyCopyright("Copyright ©  2025")]
[assembly: Guid("d8b8b522-7ea7-41eb-a21a-d076e3ab8dc5")]
[assembly: ComVisible(false)]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyProduct("LetMeTameYou")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyTitle("LetMeTameYou")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyDescription("")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace LetMeTameYou
{
	internal static class BetterTameHover
	{
		public static float max_interact_default = 3.5f;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ItemDrop), "GetHoverText")]
		private static void ID_GetHoverText(ItemDrop __instance, ref string __result)
		{
			EggGrow val = default(EggGrow);
			if (!Object.op_Implicit((Object)(object)__instance.m_nview) || !__instance.m_nview.IsValid() || !((Component)__instance).gameObject.TryGetComponent<EggGrow>(ref val))
			{
				return;
			}
			Component[] components = ((Component)__instance).gameObject.GetComponents(typeof(Component));
			int num = 999;
			int num2 = 999;
			for (int i = 0; i < components.Length; i++)
			{
				if (((object)components[i]).GetType() == typeof(ItemDrop))
				{
					num = i;
					break;
				}
				if (((object)components[i]).GetType() == typeof(EggGrow))
				{
					num2 = i;
					break;
				}
			}
			if (num <= num2)
			{
				bool flag = __instance.m_nview.GetZDO().GetFloat(ZDOVars.s_growStart, 0f) > 0f;
				string text = ((__instance.m_itemData.m_stack > 1) ? "$item_chicken_egg_stacked" : (flag ? "$item_chicken_egg_warm" : "$item_chicken_egg_cold"));
				string text2 = __result;
				int num3 = text2.IndexOf('\n');
				if (num3 > 0)
				{
					__result = text2.Substring(0, num3) + " " + Localization.instance.Localize(text) + text2.Substring(num3);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Procreation), "Procreate")]
		private static void Proc_proc(Procreation __instance)
		{
			if (Object.op_Implicit((Object)(object)__instance.m_nview) && __instance.m_nview.IsValid())
			{
				__instance.m_nview.GetZDO().Set("LMTY_ProcTime", Time.time);
			}
		}

		[HarmonyPatch(typeof(Tameable), "GetHoverText")]
		[HarmonyPostfix]
		private static void Tameable_GetHoverText(Tameable __instance, ref string __result)
		{
			if (!TameManager.hasTamingKeysAndLevel(__instance))
			{
				string oldValue = Localization.instance.Localize("$hud_wild");
				__result = Localization.instance.Localize(__result.Replace(oldValue, "$lmty_feral"));
			}
		}

		[HarmonyPostfix]
		[HarmonyPriority(395)]
		[HarmonyPatch(typeof(Character), "GetHoverText")]
		public static void Char_GetHoverText(Character __instance, ref string __result)
		{
			if (LetMeTameYou.useTamingTool.Value)
			{
				GetTamingText(__instance, ref __result);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Tameable), "DecreaseRemainingTime")]
		[HarmonyPriority(10)]
		private static void PostFix_DecreaseRemainingTime(Tameable __instance, ref float time)
		{
			__instance.m_nview.GetZDO().Set("LMTY_TameStep", time);
		}

		public static void GetTamingText(Character __instance, ref string __result)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)((Humanoid)localPlayer).GetCurrentWeapon().m_dropPrefab == (Object)null || LetMeTameYou.tamingtoolPrefabName != ((Object)((Humanoid)localPlayer).GetCurrentWeapon().m_dropPrefab).name)
			{
				return;
			}
			Tameable componentInParent = ((Component)__instance).GetComponentInParent<Tameable>();
			string text = "\n";
			if (Terminal.m_cheat && LetMeTameYou.debugout.Value && Input.GetKeyDown((KeyCode)Enum.Parse(typeof(KeyCode), "Z")))
			{
				sendGrowProcreate(__instance);
			}
			if ((Object)(object)componentInParent == (Object)null)
			{
				if (ShowDebug(localPlayer))
				{
					text += "Not tameable \n";
					text = text + "Prefab name is: " + ((Object)__instance).name;
					text = text.Replace("(Clone)", "");
					__result += text;
				}
				return;
			}
			MonsterAI componentInParent2 = ((Component)__instance).GetComponentInParent<MonsterAI>();
			Procreation componentInParent3 = ((Component)__instance).GetComponentInParent<Procreation>();
			bool flag = true;
			if (__instance.m_tamed)
			{
				if (ShowDebug(localPlayer))
				{
					text += ("Prefab is: " + ((Object)__instance).name + ", is commandable= " + componentInParent.m_commandable + "\n").Replace("(Clone)", "");
				}
				if ((Object)(object)componentInParent3 != (Object)null)
				{
					if (componentInParent3.IsDue())
					{
						text += "$lmty_is_due ";
						flag = false;
					}
					else if (componentInParent3.IsPregnant())
					{
						text += "$lmty_is_pregnant";
						DateTime dateTime = new DateTime(componentInParent3.m_nview.GetZDO().GetLong("pregnant", 0L));
						double num = (double)componentInParent3.m_pregnancyDuration - (ZNet.instance.GetTime() - dateTime).TotalSeconds;
						if (num > 0.0)
						{
							text = text + ": " + (int)num + "$lmty_seconds_left \n";
						}
						flag = false;
					}
					else if (!componentInParent3.ReadyForProcreation())
					{
						text += "$lmty_needs_food";
					}
					else
					{
						if (ShowDebug(localPlayer))
						{
							text += GetPregStats(componentInParent3);
							__result += Localization.instance.Localize(text);
							return;
						}
						switch (getInstNum(componentInParent3)[0])
						{
						case 1:
							text += "$lmty_crowded \n";
							break;
						default:
							text += "$lmty_needs_mate \n";
							break;
						case 0:
							break;
						}
						text = ((!(componentInParent3.m_pregnancyChance < 1f)) ? (text + "Pregnancy chance is too high: " + componentInParent3.m_pregnancyChance + "\n Check the config and reduce") : (text + "$lmty_ready_to_proc"));
					}
				}
				else
				{
					text += "$lmty_cannot_proc";
				}
				if (flag)
				{
					text += "\n$lmty_possible_consume ";
				}
			}
			else
			{
				LMTY_Interactable lMTY_Interactable = default(LMTY_Interactable);
				if (((Component)__instance).gameObject.TryGetComponent<LMTY_Interactable>(ref lMTY_Interactable))
				{
					text += "$lmty_trade_for_tame ";
					int num2 = 20;
					foreach (KeyValuePair<string, int> item in lMTY_Interactable.tradelist)
					{
						text = text + item.Value + " " + item.Key + ", ";
						if (text.Length - num2 > 50)
						{
							num2 = text.Length;
							text += "\n";
						}
					}
					text = text.Remove(text.Length - 2) + "\n";
				}
				if (!(componentInParent.m_tamingTime > 0f))
				{
					__result += Localization.instance.Localize(text);
					return;
				}
				text += "$lmty_taming_time ";
				float remainingTime = componentInParent.GetRemainingTime();
				if (remainingTime != componentInParent.m_tamingTime)
				{
					text = text + (int)remainingTime + "s\\";
				}
				text = text + componentInParent.m_tamingTime + "s";
				if (!componentInParent.IsHungry())
				{
					ZDO zDO = componentInParent.m_nview.GetZDO();
					if (zDO != null)
					{
						float @float = zDO.GetFloat("LMTY_TameStep", 0f);
						if (@float > 3f)
						{
							text = text + " (<color=#5CEB59><b>" + (int)(3f / @float * remainingTime) + "s</b></color>)";
						}
					}
				}
				if (flag)
				{
					text += "\n$lmty_possible_consume ";
				}
			}
			if (!flag)
			{
				__result += Localization.instance.Localize(text);
				return;
			}
			int num3 = 15;
			if (componentInParent2.m_consumeItems.Count < num3)
			{
				foreach (ItemDrop consumeItem in componentInParent2.m_consumeItems)
				{
					text = text + consumeItem.m_itemData.m_shared.m_name + ", ";
				}
			}
			else
			{
				int num4 = (int)Mathf.Ceil((float)componentInParent2.m_consumeItems.Count / (float)num3);
				int num5 = (int)Math.Round((float)(componentInParent2.m_consumeItems.Count / num4) + 0.49f);
				int num6 = (int)(Time.fixedTime * 0.23f) % num4 * num5;
				int num7 = num6;
				for (int i = 0; i < num5 && i <= componentInParent2.m_consumeItems.Count; i++)
				{
					text = text + componentInParent2.m_consumeItems[num7].m_itemData.m_shared.m_name + ", ";
					num7++;
				}
			}
			text = Localization.instance.Localize(text.TrimEnd(' ', ','));
			__result += text;
		}

		[HarmonyPatch(typeof(Player), "FindHoverObject")]
		[HarmonyPrefix]
		private static void FindHoverObject_Prefix(Player __instance, GameObject hover, Character hoverCreature)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			if (LetMeTameYou.useTamingTool.Value && (Object)(object)((Humanoid)__instance).GetCurrentWeapon().m_dropPrefab == (Object)(object)ZNetScene.instance.GetPrefab(LetMeTameYou.tamingtoolPrefabName))
			{
				EggGrow thisGrow = default(EggGrow);
				if (Object.op_Implicit((Object)(object)hoverCreature))
				{
					__instance.m_maxInteractDistance = LetMeTameYou.increasedInteractDistance.Value;
				}
				else if (Object.op_Implicit((Object)(object)hover) && Terminal.m_cheat && LetMeTameYou.debugout.Value && hover.TryGetComponent<EggGrow>(ref thisGrow) && Input.GetKeyDown((KeyCode)Enum.Parse(typeof(KeyCode), "Z")))
				{
					sendGrowEgg(thisGrow);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "FindHoverObject")]
		[HarmonyPostfix]
		private static void Postfix(Player __instance, ref GameObject hover, ref Character hoverCreature)
		{
			if (Object.op_Implicit((Object)(object)hoverCreature) && !Object.op_Implicit((Object)(object)hover) && setHoverCreature(__instance, hoverCreature))
			{
				hover = ((Component)hoverCreature).gameObject;
			}
			__instance.m_maxInteractDistance = max_interact_default;
		}

		private static void sendGrowProcreate(Character thisChar)
		{
			Procreation component = ((Component)thisChar).gameObject.GetComponent<Procreation>();
			Growup component2 = ((Component)thisChar).gameObject.GetComponent<Growup>();
			if (!Object.op_Implicit((Object)(object)component) && !Object.op_Implicit((Object)(object)component2))
			{
				DBG.blogWarning("Could not find Procreation or Growup in creature, exiting command");
			}
			else if (Object.op_Implicit((Object)(object)component))
			{
				component.m_pregnancyDuration = 3f;
				component.MakePregnant();
			}
			else
			{
				component2.m_growTime = 5f;
			}
		}

		private static void sendGrowEgg(EggGrow thisGrow)
		{
			if (!Object.op_Implicit((Object)(object)thisGrow))
			{
				DBG.blogWarning("Could not find Procreation or EggGrow in Item, exiting command");
				return;
			}
			thisGrow.m_growTime = 5f;
			thisGrow.m_requireUnderRoof = false;
			thisGrow.m_requireNearbyFire = false;
		}

		public static bool setHoverCreature(Player plr, Character hoverChar)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (Vector3.Distance(((Character)plr).m_eye.position, ((Component)hoverChar).transform.position) < plr.m_maxInteractDistance)
			{
				return true;
			}
			return false;
		}

		public static bool ShowDebug(Player plr)
		{
			if (LetMeTameYou.debugout.Value && !((Character)plr).IsCrouching())
			{
				return true;
			}
			return false;
		}

		public static int[] getInstNum(Procreation _proc)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			int[] array = new int[4];
			int num = -10;
			int num2 = -10;
			int num3 = 0;
			bool flag = true;
			try
			{
				if ((Object)(object)_proc.m_offspringPrefab == (Object)null)
				{
					string prefabName = Utils.GetPrefabName(((Object)_proc.m_offspring).name);
					_proc.m_offspringPrefab = ZNetScene.instance.GetPrefab(prefabName);
					int prefab = _proc.m_nview.GetZDO().GetPrefab();
					_proc.m_myPrefab = ZNetScene.instance.GetPrefab(prefab);
				}
				num = SpawnSystem.GetNrOfInstances(_proc.m_myPrefab, ((Component)_proc).gameObject.transform.position, _proc.m_totalCheckRange, false, false);
				num2 = SpawnSystem.GetNrOfInstances(_proc.m_offspringPrefab, ((Component)_proc).gameObject.transform.position, _proc.m_totalCheckRange, false, false);
				num3 = SpawnSystem.GetNrOfInstances(_proc.m_myPrefab, ((Component)_proc).transform.position, _proc.m_partnerCheckRange, false, true);
				flag = num + num2 < _proc.m_maxCreatures && num3 >= 2;
			}
			catch (Exception ex)
			{
				DBG.blogDebug("Error: " + ex.Message);
				DBG.blogDebug("Error: " + ex.StackTrace);
				array[0] = -1;
				return array;
			}
			array[1] = num;
			array[2] = num2;
			array[3] = num3;
			if (flag)
			{
				array[0] = 0;
				return array;
			}
			if (num + num2 > _proc.m_maxCreatures - 1)
			{
				array[0] = 1;
				return array;
			}
			array[0] = 2;
			return array;
		}

		public static double PercentSuccess(Procreation _proc)
		{
			int num = ((_proc.m_spawnOffsetMax > 0f) ? 1 : (-1));
			if (Random.value > _proc.m_pregnancyChance)
			{
				_proc.m_spawnOffsetMax += 1E-05f * (float)num;
			}
			else
			{
				_proc.m_spawnOffsetMax += 1E-07f * (float)num;
			}
			float num2 = _proc.m_spawnOffsetMax % 0.001f * 100000f * (float)num;
			float num3 = num2 % 1f * 100f;
			if (num2 > 98f || num3 == 99f)
			{
				float num4 = (float)Math.Round(0.1f * num2 / (num2 + num3), 3);
				if ((double)num4 > 0.1 || num4 < 0f)
				{
					DBG.blogDebug("invalid ratio");
				}
				num4 = (num4 + 1E-08f) * (float)num;
				_proc.m_spawnOffsetMax = (float)(int)(_proc.m_spawnOffsetMax * 10f) / 10f + num4;
				DBG.blogDebug("success=" + Math.Round(num2) + ", failed=" + Math.Round(num3) + ", ratio=" + num4);
			}
			return (int)(_proc.m_spawnOffsetMax % 0.1f * 1000f * (float)num);
		}

		public static string GetPregStats(Procreation _proc)
		{
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			string text = "";
			bool flag = !_proc.m_nview.IsValid() || !_proc.m_nview.IsOwner() || !_proc.m_character.IsTamed();
			text = text + "isValid: " + !flag;
			text = text + "\nPregchance= " + _proc.m_pregnancyChance;
			text = text + "\nIsNotAlerted= " + !_proc.m_baseAI.IsAlerted();
			text = text + "\nIsNotHungry= " + !_proc.m_tameable.IsHungry();
			double num = PercentSuccess(_proc);
			text = text + "\nChanceToBreed: " + ((num > 0.0) ? ("True(" + num + "%)") : "False");
			int[] instNum = getInstNum(_proc);
			switch (instNum[0])
			{
			case 0:
				text += "\nLess than max instance: True";
				break;
			case 1:
				text += "\nLess than max instance: False";
				text = text + "\nMax=" + _proc.m_maxCreatures + ", Mates=" + (instNum[1] - 1) + ", Offspring=" + instNum[2];
				break;
			case 2:
				text += "\nLess than max instance: False (needs mate)";
				text = text + "\nReady Mates=" + (instNum[3] - 1) + ", Offspring=" + instNum[2];
				text = text + "\nClosest 3 Creatures within range of " + _proc.m_totalCheckRange + " units are:\n";
				text += GetCloseInstances(((Component)_proc).gameObject, ((Component)_proc).gameObject.transform.position, _proc.m_totalCheckRange);
				break;
			default:
				text += "\nLess than max instance: Error";
				break;
			}
			text = ((!((MonoBehaviour)_proc).IsInvoking()) ? (text + "\nis not invoking") : ((!((MonoBehaviour)_proc).IsInvoking("Procreate")) ? (text + "\nis invoking but not Procreate") : (text + "\nis invoking Procreate")));
			text = text + " " + (int)(Time.time - _proc.m_nview.GetZDO().GetFloat("LMTY_ProcTime", 0f)) + "s";
			int @int = _proc.m_nview.GetZDO().GetInt("lovePoints", 0);
			return text + "\nLovePoints: " + @int + " out of " + _proc.m_requiredLovePoints;
		}

		private static string GetCloseInstances(GameObject instance, Vector3 center, float maxRange)
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			float num = 999999f;
			float num2 = 999999f;
			float num3 = 999999f;
			string text = "n/a";
			string text2 = "n/a2";
			string text3 = "n/a3";
			BaseAI componentInParent = instance.GetComponentInParent<BaseAI>();
			List<Character> allCharacters = Character.GetAllCharacters();
			foreach (Character item in allCharacters)
			{
				if (!((Object)(object)((Component)item).gameObject == (Object)(object)((Component)componentInParent).gameObject) && !item.IsPlayer() && ((Component)item).GetComponent<ZNetView>().IsValid())
				{
					float num4 = Vector3.Distance(((Component)item).transform.position, instance.transform.position);
					if (num4 < num)
					{
						text = ((Object)item).name;
						num = num4;
						text = ((!item.IsTamed()) ? ((!((Object)(object)((Component)item).gameObject.GetComponent<Tameable>() != (Object)null)) ? (text + "(NotTameable)") : (text + "(Untamed)")) : (text + "(Tamed)"));
					}
					else if (num4 < num2)
					{
						text2 = ((Object)item).name;
						num2 = num4;
						text2 = ((!item.IsTamed()) ? ((!((Object)(object)((Component)item).gameObject.GetComponent<Tameable>() != (Object)null)) ? (text2 + "(NotTameable)") : (text2 + "(Untamed)")) : (text2 + "(Tamed)"));
					}
					else if (num4 < num3)
					{
						text3 = ((Object)item).name;
						num3 = num4;
						text3 = ((!item.IsTamed()) ? ((!((Object)(object)((Component)item).gameObject.GetComponent<Tameable>() != (Object)null)) ? (text3 + "(NotTameable)") : (text3 + "(Untamed)")) : (text3 + "(Tamed)"));
					}
				}
			}
			return (text + ":" + text2 + ":" + text3).Replace("(Clone)", "");
		}
	}
	public class ZDOChanger : MonoBehaviour
	{
		public string newName = null;

		private void Awake()
		{
			ZNetView component = ((Component)this).gameObject.GetComponent<ZNetView>();
			if (!Object.op_Implicit((Object)(object)component) || !component.IsValid())
			{
				DBG.blogDebug(" ZDOChanger invalid ZNetView");
				return;
			}
			if (newName == null)
			{
				newName = ((Object)((Component)this).gameObject).name.Replace("_tamed", "").Replace("(Clone)", "");
				DBG.blogDebug("Replaced Name");
			}
			if (!Object.op_Implicit((Object)(object)ZNetScene.instance.GetPrefab(StringExtensionMethods.GetStableHashCode(newName))))
			{
				DBG.blogWarning("Did not find Prefab " + newName + " in ZNetView");
				return;
			}
			((Object)((Component)this).gameObject).name = newName + "(Clone)";
			component.GetZDO().SetPrefab(StringExtensionMethods.GetStableHashCode(newName));
			DBG.blogDebug("Set new ZDO Prefab");
		}
	}
	internal class SpawnedHostilePatches
	{
		private static void SetTamedAttacks(Character character)
		{
			Humanoid val = (Humanoid)(object)((character is Humanoid) ? character : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			Inventory inventory = val.m_inventory;
			if (inventory == null)
			{
				return;
			}
			if (inventory.NrOfItems() > 0)
			{
				for (int num = inventory.m_inventory.Count - 1; num >= 0; num--)
				{
					if (!((Object)(object)inventory.m_inventory[num].m_dropPrefab == (Object)null) && TameManager.TamedAttackVariants.TryGetValue(((Object)inventory.m_inventory[num].m_dropPrefab).name, out var value))
					{
						inventory.RemoveItem(num);
						inventory.AddItem(value, 1);
						DBG.blogWarning("Changed to tamed attack in inv " + ((Object)value).name);
					}
				}
				return;
			}
			for (int i = 0; i < val.m_defaultItems.Length; i++)
			{
				if (TameManager.TamedAttackVariants.TryGetValue(((Object)val.m_defaultItems[i]).name, out var value2))
				{
					val.m_defaultItems[i] = value2;
					DBG.blogWarning("Changed to tamed attack as default " + ((Object)value2).name);
				}
			}
		}

		public static void findTamedAttackVariants(Humanoid humanoid)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if (humanoid.m_defaultItems == null)
			{
				return;
			}
			int num = humanoid.m_defaultItems.Length;
			Projectile val = default(Projectile);
			SpawnAbility spawnAbility = default(SpawnAbility);
			SpawnAbility spawnAbility2 = default(SpawnAbility);
			for (int i = 0; i < num; i++)
			{
				if (TameManager.TamedAttackVariants.ContainsKey(((Object)humanoid.m_defaultItems[i]).name))
				{
					continue;
				}
				Transform transform = new GameObject(((Object)humanoid.m_defaultItems[i]).name + "_base").transform;
				((Component)transform).gameObject.SetActive(false);
				bool flag = false;
				bool flag2 = false;
				ItemDrop component = humanoid.m_defaultItems[i].GetComponent<ItemDrop>();
				string text = "0";
				GameObject copy = null;
				if (Object.op_Implicit((Object)(object)component))
				{
					text += "1";
					GameObject attackProjectile = component.m_itemData.m_shared.m_attack.m_attackProjectile;
					if (Object.op_Implicit((Object)(object)attackProjectile))
					{
						text += "2";
						GameObject copy2 = null;
						if (attackProjectile.TryGetComponent<Projectile>(ref val))
						{
							text += "3";
							GameObject spawnOnHit = val.m_spawnOnHit;
							if (Object.op_Implicit((Object)(object)spawnOnHit))
							{
								text += "4";
								GameObject[] newSpawnPref = null;
								if (spawnOnHit.TryGetComponent<SpawnAbility>(ref spawnAbility))
								{
									flag |= findTamedAttackinSpawnAbility(spawnAbility, ref newSpawnPref, transform);
								}
								if (flag && SaveAttackPart(spawnOnHit, ref copy2, transform))
								{
									copy2.GetComponent<SpawnAbility>().m_spawnPrefab = newSpawnPref;
								}
							}
							if (flag && (SaveAttackPart(attackProjectile, ref copy, transform) || flag2))
							{
								copy.GetComponent<Projectile>().m_spawnOnHit = copy2;
							}
						}
						GameObject[] newSpawnPref2 = null;
						if (attackProjectile.TryGetComponent<SpawnAbility>(ref spawnAbility2))
						{
							flag2 |= findTamedAttackinSpawnAbility(spawnAbility2, ref newSpawnPref2, transform);
						}
						if (flag2 && (SaveAttackPart(attackProjectile, ref copy, transform) || flag))
						{
							copy.GetComponent<SpawnAbility>().m_spawnPrefab = newSpawnPref2;
						}
					}
				}
				if (flag || flag2)
				{
					GameObject val2 = Object.Instantiate<GameObject>(humanoid.m_defaultItems[i], transform);
					((Object)val2).name = ((Object)val2).name.Replace("(Clone)", "_tamed");
					ItemDrop component2 = val2.GetComponent<ItemDrop>();
					component2.m_itemData.m_shared.m_attack.m_attackProjectile = copy;
					component2.m_itemData.m_dropPrefab = val2;
					component2.Save();
					Utils.addItemToODB(val2, ObjectDB.instance);
					int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)val2).name);
					if (!ObjectDB.instance.m_itemByHash.ContainsKey(stableHashCode))
					{
						ObjectDB.instance.m_items.Add(val2);
						ObjectDB.instance.m_itemByHash.Add(stableHashCode, val2);
					}
					TameManager.TamedAttackVariants.Add(((Object)humanoid.m_defaultItems[i]).name, val2);
					((Component)transform).transform.parent = TameManager.Root.transform;
					DBG.blogDebug("New Attack made: " + ((Object)val2).name);
				}
			}
		}

		public static bool findTamedAttackinSpawnAbility(SpawnAbility spawnAbility, ref GameObject[] newSpawnPref, Transform base_go)
		{
			bool result = false;
			GameObject[] spawnPrefab = spawnAbility.m_spawnPrefab;
			newSpawnPref = (GameObject[])(object)new GameObject[spawnPrefab.Length];
			Tameable val = default(Tameable);
			for (int i = 0; i < spawnPrefab.Length; i++)
			{
				if (!Object.op_Implicit((Object)(object)spawnPrefab[i].GetComponent<Character>()))
				{
					newSpawnPref[i] = spawnPrefab[i];
					continue;
				}
				if (SaveAttackPart(spawnPrefab[i], ref newSpawnPref[i], base_go))
				{
					ZDOChanger zDOChanger = newSpawnPref[i].AddComponent<ZDOChanger>();
					zDOChanger.newName = ((Object)newSpawnPref[i]).name.Replace("_tamed", "");
					if (!newSpawnPref[i].TryGetComponent<Tameable>(ref val))
					{
						val = newSpawnPref[i].AddComponent<Tameable>();
					}
					val.m_startsTamed = true;
				}
				result = true;
			}
			return result;
		}

		public static bool SaveAttackPart(GameObject go, ref GameObject copy, Transform base_go)
		{
			string text = ((Object)go).name.Replace("(Clone)", "") + "_tamed";
			int stableHashCode = StringExtensionMethods.GetStableHashCode(text);
			if (ZNetScene.instance.m_namedPrefabs.ContainsKey(stableHashCode))
			{
				copy = ZNetScene.instance.GetPrefab(stableHashCode);
				return false;
			}
			copy = Object.Instantiate<GameObject>(go, base_go);
			((Object)copy).name = text;
			Utils.addToZNS(copy);
			DBG.blogDebug(((Object)copy).name + " registered to ZNetScene");
			return true;
		}

		[HarmonyPatch(typeof(Character), "Awake")]
		[HarmonyPostfix]
		private static void CharacterSetTamedPostfix(Character __instance)
		{
			if (__instance.m_tamed)
			{
				SetTamedAttacks(__instance);
			}
		}

		[HarmonyPatch(typeof(Character), "SetTamed")]
		[HarmonyPostfix]
		private static void CharacterSetTamedPostfix(Character __instance, bool tamed)
		{
			if (tamed)
			{
				SetTamedAttacks(__instance);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(CharacterDrop), "GenerateDropList")]
		private static void PrefixGenerateDropList(CharacterDrop __instance)
		{
			if (!Object.op_Implicit((Object)(object)__instance.m_character))
			{
				DBG.blogWarning("No Valid Character");
			}
			else
			{
				if (!__instance.m_character.m_tamed)
				{
					return;
				}
				foreach (Drop drop in __instance.m_drops)
				{
					if (!Object.op_Implicit((Object)(object)drop.m_prefab))
					{
						DBG.blogDebug("Drop Does not Have Prefab");
					}
					else if (Object.op_Implicit((Object)(object)drop.m_prefab.GetComponent<Tameable>()))
					{
						drop.m_prefab = Object.Instantiate<GameObject>(drop.m_prefab);
						drop.m_prefab.GetComponent<Tameable>().m_startsTamed = true;
						DBG.blogDebug("Set OnDeath Creature to Tamed");
					}
				}
			}
		}
	}
	public class PrefabManager : MonoBehaviour
	{
		public GameObject Root;

		private static AssetBundle Assets;

		public const string assetBundleName = "lmty_assets";

		public const string assetPath = "Assets/LMTY/";

		public static GameObject TameStickPrefab;

		public static Dictionary<string, Shader> ShaderDict = new Dictionary<string, Shader>();

		private void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			Root = new GameObject("PrefabList");
			Root.transform.SetParent(LetMeTameYou.Root.transform);
			Root.SetActive(false);
			Assets = Utils.LoadAssetBundle("lmty_assets", Assembly.GetExecutingAssembly());
			TameStickPrefab = Assets.LoadAsset<GameObject>("Assets/LMTY/LMTY_TamingTool.prefab");
		}

		public static AssetBundle getAssetBundle()
		{
			return Assets;
		}

		public static void ItemReg()
		{
			DBG.blogDebug("ItemReg");
			if (LetMeTameYou.useTamingTool.Value)
			{
				addItem(TameStickPrefab, LetMeTameYou.TamingTool_Recipe.Value, LetMeTameYou.TamingTool_Station.Value);
			}
			else
			{
				removeItem("LMTY_TamingTool");
			}
		}

		private static void removeItem(string prefabName)
		{
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefabName);
			if (!Object.op_Implicit((Object)(object)itemPrefab))
			{
				DBG.blogWarning("cannot remove: " + prefabName + " as not in OBjectDB");
			}
			else
			{
				ObjectDB.instance.m_items.Remove(itemPrefab);
			}
		}

		public static void addItem(GameObject go, string recipe, string station)
		{
			if (Object.op_Implicit((Object)(object)ObjectDB.instance.GetItemPrefab(((Object)go).name)))
			{
				if (Object.op_Implicit((Object)(object)ZNetScene.instance))
				{
					DBG.blogWarning("addItem resetting: " + ((Object)go).name + " recipe");
					ResetRecipe(recipe, station, ((Object)go).name);
				}
				DBG.blogDebug("already in oDB: " + ((Object)go).name);
				return;
			}
			DBG.blogDebug("addItem adding: " + ((Object)go).name + " to ObjectDB: " + ((Object)ObjectDB.instance).name);
			Utils.addItemToODB(TameStickPrefab, ObjectDB.instance);
			DBG.blogDebug("Amount in objectDB=" + ObjectDB.instance.m_itemByHash.Count);
			if (Object.op_Implicit((Object)(object)ZNetScene.instance))
			{
				ResetRecipe(recipe, station, ((Object)go).name);
			}
		}

		private static Recipe ResetRecipe(string recipeConfig, string craftingStation, string item)
		{
			if (recipeConfig == "" || craftingStation == "")
			{
				return null;
			}
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item);
			DBG.blogDebug("resetting: " + item + " recipe");
			if ((Object)(object)itemPrefab == (Object)null)
			{
				DBG.blogWarning(item + " is null");
				return null;
			}
			ItemDrop item2 = default(ItemDrop);
			if (!itemPrefab.TryGetComponent<ItemDrop>(ref item2))
			{
				DBG.blogWarning(item + " does not have itemDrop");
				return null;
			}
			Recipe val = ScriptableObject.CreateInstance<Recipe>();
			((Object)val).name = "Recipe_" + item;
			val.m_item = item2;
			string[] array = craftingStation.Split(new char[1] { ':' });
			GameObject prefab = ZNetScene.instance.GetPrefab(array[0]);
			CraftingStation val2 = default(CraftingStation);
			if ((Object)(object)prefab == (Object)null || !prefab.TryGetComponent<CraftingStation>(ref val2))
			{
				DBG.blogWarning("invalid crafting station: " + array[0]);
				return null;
			}
			val.m_craftingStation = val2;
			val.m_repairStation = val2;
			if (array.Length > 1 && int.TryParse(array[1], out var result))
			{
				val.m_minStationLevel = result;
			}
			else
			{
				val.m_minStationLevel = 5;
			}
			string[] array2 = recipeConfig.Split(new char[1] { ',' });
			int amt = 1;
			int upgrade_amt = 1;
			List<Requirement> list = new List<Requirement>();
			for (int i = 0; i < array2.Length; i++)
			{
				string[] array3 = array2[i].Split(new char[1] { ':' });
				if (array3.Length > 1 && int.TryParse(array3[1], out var result2))
				{
					if (array3.Length > 2 && int.TryParse(array3[2], out var result3))
					{
						amt = result2;
						upgrade_amt = result3;
					}
					else
					{
						amt = result2;
						upgrade_amt = Mathf.RoundToInt((float)result2 * 0.75f);
					}
				}
				Requirement val3 = makeRequirment(array3[0], amt, upgrade_amt);
				if (val3 == null)
				{
					return null;
				}
				list.Add(val3);
			}
			val.m_resources = list.ToArray();
			ObjectDB.instance.m_recipes.Add(val);
			return val;
		}

		private static Requirement makeRequirment(string itemStr, int amt, int upgrade_amt)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			Requirement val = new Requirement();
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(itemStr);
			ItemDrop resItem = default(ItemDrop);
			if (!Object.op_Implicit((Object)(object)itemPrefab) || !itemPrefab.TryGetComponent<ItemDrop>(ref resItem))
			{
				DBG.blogDebug("Ingredient: " + itemStr + " is not found");
				return null;
			}
			val.m_amount = amt;
			val.m_amountPerLevel = upgrade_amt;
			val.m_resItem = resItem;
			return val;
		}

		public static void FixShaders(GameObject go)
		{
			DBG.blogDebug("Start Fixing SHaders for " + ((Object)go).name);
			Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>();
			Renderer[] array = componentsInChildren;
			foreach (Renderer val in array)
			{
				Material[] materials = val.materials;
				foreach (Material val2 in materials)
				{
					string name = ((Object)val2.shader).name;
					DBG.blogDebug("Shader " + name + " is attempting to be switched");
					if (name == "Standard")
					{
						DBG.blogDebug("Skipping Standard");
						continue;
					}
					Shader fixedShader = getFixedShader(name);
					if ((Object)(object)fixedShader != (Object)null)
					{
						val2.shader = fixedShader;
						DBG.blogDebug("Switched Shader for " + ((Object)go).name);
					}
				}
			}
		}

		private static GameObject FindShaderObject(string name)
		{
			ZNetScene val = ZNetScene.instance;
			if ((Object)(object)val == (Object)null)
			{
				val = TameManager.zns;
			}
			if (val.m_namedPrefabs.Count > 0)
			{
				DBG.blogDebug("znet has init when setting shader: " + name);
				return val.GetPrefab(name);
			}
			DBG.blogDebug("znet is init when setting shader: " + name);
			return val.m_prefabs.Find((GameObject x) => ((Object)x).name.Contains(name));
		}

		private static Shader getFixedShader(string shaderName)
		{
			if (ShaderDict.TryGetValue(shaderName, out var value))
			{
				return value;
			}
			Shader val = null;
			try
			{
				string text = shaderName;
				string text2 = text;
				GameObject val2;
				if (!(text2 == "Custom/Vegetation"))
				{
					if (text2 == "Standard")
					{
						return null;
					}
					if (ShaderDict.TryGetValue("Standard", out var value2))
					{
						return value2;
					}
					val2 = FindShaderObject("AmberPearl");
					if ((Object)(object)val2 != (Object)null)
					{
						val = val2.GetComponentInChildren<Renderer>().material.shader;
						shaderName = "Standard";
						ShaderDict.Add(shaderName, val);
					}
					return val;
				}
				val2 = FindShaderObject("AshlandsBranch1");
				if ((Object)(object)val2 != (Object)null)
				{
					val = ((Component)val2.transform.GetChild(0)).GetComponent<Renderer>().material.shader;
				}
			}
			catch
			{
				DBG.blogWarning("Failed shader fix with " + shaderName);
				if (ShaderDict.TryGetValue("Standard", out var value3))
				{
					return value3;
				}
				GameObject val2 = FindShaderObject("AmberPearl");
				if ((Object)(object)val2 != (Object)null)
				{
					val = val2.GetComponentInChildren<Renderer>().material.shader;
					shaderName = "Standard";
					ShaderDict.Add(shaderName, val);
					return val;
				}
				DBG.blogWarning("Failed secondary fix with " + shaderName);
			}
			if (((Object)(object)val != (Object)null) & !ShaderDict.ContainsKey(shaderName))
			{
				ShaderDict.Add(shaderName, val);
			}
			return val;
		}
	}
	[Serializable]
	public class TradeAmount
	{
		public string tradeItem;

		public int tradeAmt;
	}
	public class LMTY_Interactable : MonoBehaviour, Hoverable, Interactable
	{
		public Character m_character;

		public ZNetView m_nview;

		public Dictionary<string, int> tradelist = new Dictionary<string, int>();

		public void Awake()
		{
			m_nview = ((Component)this).GetComponent<ZNetView>();
			m_character = ((Component)this).GetComponent<Character>();
		}

		public void initTradeList(string all_trades)
		{
			tradelist.Clear();
			string[] array = all_trades.Split(new char[1] { ',' });
			string o = ((Object)this).name + " trades:";
			string[] array2 = array;
			foreach (string text in array2)
			{
				string[] array3 = text.Split(new char[1] { ':' });
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(array3[0]);
				if ((Object)(object)itemPrefab == (Object)null)
				{
					DBG.blogWarning("Wrong item name " + array3[0] + ", skipping as a trade");
				}
				int result = 1;
				if (array3.Length != 0)
				{
					int.TryParse(array3[1], out result);
				}
				tradelist.Add(array3[0], result);
			}
			DBG.blogDebug(o);
		}

		public virtual string GetHoverText()
		{
			Tameable component = ((Component)this).GetComponent<Tameable>();
			if (Object.op_Implicit((Object)(object)component))
			{
				return component.GetHoverText();
			}
			return "";
		}

		public virtual string GetHoverName()
		{
			Tameable component = ((Component)this).GetComponent<Tameable>();
			if (Object.op_Implicit((Object)(object)component))
			{
				return component.GetHoverName();
			}
			return Localization.instance.Localize(m_character.m_name);
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			return true;
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Expected O, but got Unknown
			if (!m_nview.IsValid())
			{
				return false;
			}
			try
			{
				foreach (KeyValuePair<string, int> item2 in tradelist)
				{
					DBG.blogDebug("Allowed Trades: " + item2.Key + " with amount " + item2.Value);
				}
				DBG.blogDebug("Tradelist size=" + tradelist.Count);
				DBG.blogDebug("item.m_dropPrefab.name=" + ((Object)item.m_dropPrefab).name);
				if (!tradelist.TryGetValue(((Object)item.m_dropPrefab).name, out var value))
				{
					DBG.blogDebug(((Object)item.m_dropPrefab).name + " is not in trade list");
					return false;
				}
				Inventory inventory = user.GetInventory();
				int num = inventory.CountItems(item.m_shared.m_name, -1, true);
				if (num >= value)
				{
					DBG.blogDebug("Attempting Trade");
					if (m_character.IsTamed())
					{
						return false;
					}
					Tameable val = new Tameable();
					val = ((Component)m_character).gameObject.GetComponent<Tameable>();
					if (!((Object)(object)val != (Object)null))
					{
						DBG.blogDebug("Not tameable");
						return false;
					}
					val.Tame();
					bool flag = inventory.RemoveItem(item, value);
					DBG.blogDebug("Recruited " + m_character.m_name);
				}
				else
				{
					DBG.blogDebug("Not enough " + item.m_shared.m_name + ", need " + value);
					string text = Localization.instance.Localize("$lmty_need_more_trade");
					if (text.Contains("{0}"))
					{
						if (text.Contains("{1}"))
						{
							((Character)user).Message((MessageType)2, string.Format(text, item.m_shared.m_name, value), 0, (Sprite)null);
						}
						else
						{
							((Character)user).Message((MessageType)2, string.Format(text, item.m_shared.m_name), 0, (Sprite)null);
						}
					}
					else
					{
						((Character)user).Message((MessageType)2, text, 0, (Sprite)null);
					}
				}
			}
			catch (Exception)
			{
			}
			return true;
		}
	}
	public class LMTY_AnimalAI : MonsterAI
	{
		public float m_timeToSafe = 4f;

		public override bool UpdateAI(float dt)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			if (((BaseAI)this).m_afraidOfFire && ((BaseAI)this).AvoidFire(dt, (Character)null, true))
			{
				return true;
			}
			base.m_updateTargetTimer -= dt;
			if (base.m_updateTargetTimer <= 0f)
			{
				base.m_updateTargetTimer = (Character.IsCharacterInRange(((Component)this).transform.position, 32f) ? 2f : 10f);
				Character val = ((BaseAI)this).FindEnemy();
				if (Object.op_Implicit((Object)(object)val))
				{
					base.m_targetCreature = val;
				}
			}
			if (Object.op_Implicit((Object)(object)((BaseAI)this).m_tamable) && Object.op_Implicit((Object)(object)((BaseAI)this).m_tamable.m_saddle) && ((BaseAI)this).m_tamable.m_saddle.UpdateRiding(dt))
			{
				return true;
			}
			if (Object.op_Implicit((Object)(object)base.m_targetCreature) && base.m_targetCreature.IsDead())
			{
				base.m_targetCreature = null;
			}
			if (Object.op_Implicit((Object)(object)base.m_targetCreature))
			{
				bool flag = ((BaseAI)this).CanSenseTarget(base.m_targetCreature);
				((BaseAI)this).SetTargetInfo(base.m_targetCreature.GetZDOID());
				if (flag)
				{
					((BaseAI)this).SetAlerted(true);
				}
			}
			else
			{
				((BaseAI)this).SetTargetInfo(ZDOID.None);
			}
			if (((BaseAI)this).IsAlerted())
			{
				base.m_timeSinceSensedTargetCreature += dt;
				if (base.m_timeSinceSensedTargetCreature > m_timeToSafe)
				{
					base.m_targetCreature = null;
					((BaseAI)this).SetAlerted(false);
				}
			}
			if ((!((BaseAI)this).IsAlerted() || ((Object)(object)base.m_targetStatic == (Object)null && (Object)(object)base.m_targetCreature == (Object)null)) && ((MonsterAI)this).UpdateConsumeItem((Humanoid)/*isinst with value type is only supported in some contexts*/, dt))
			{
				return true;
			}
			if (Object.op_Implicit((Object)(object)base.m_targetCreature))
			{
				((BaseAI)this).Flee(dt, ((Component)base.m_targetCreature).transform.position);
				base.m_targetCreature.OnTargeted(false, false);
				return true;
			}
			if (Object.op_Implicit((Object)(object)base.m_follow))
			{
				((BaseAI)this).Follow(base.m_follow, dt);
			}
			else
			{
				((BaseAI)this).IdleMovement(dt);
				((BaseAI)this).m_randomMoveUpdateTimer = ((BaseAI)this).m_randomMoveUpdateTimer - dt;
			}
			((BaseAI)this).ChargeStop();
			((BaseAI)this).UpdateRegeneration(dt);
			return true;
		}
	}
	public class TameManager : MonoBehaviour
	{
		public enum AddedClass
		{
			Tameable,
			Procreation,
			LMTY_AnimalAI,
			LMTY_Interactable
		}

		public class ModifiedTame
		{
			public GameObject go { get; set; } = null;


			public List<AddedClass> addedClasses { get; set; } = new List<AddedClass>();


			public ModifiedTame(GameObject gameObject)
			{
				go = gameObject;
			}
		}

		public static ZNetScene zns;

		public static GameObject Root;

		public static bool hasInitBaseObj;

		public static bool hasInitTames;

		private static Tameable wtame;

		public static GameObject heartEffectGO;

		public static GameObject DrakeEggPrefab;

		public static GameObject ChickenEggPrefab;

		public static GameObject AsksvinEggPrefab;

		public static GameObject CustDrakeEggPrefab;

		public static bool SetEggs = false;

		public static bool AlteredBaseEggs = false;

		public static bool OverwroteDragonEgg = false;

		private static int maxtamingLvl = -1;

		public static Dictionary<string, GameObject> TamedAttackVariants = new Dictionary<string, GameObject>();

		public static Dictionary<string, List<string>> RequiredTamingKeys = new Dictionary<string, List<string>>();

		private static List<ModifiedTame> modifiedTameList = new List<ModifiedTame>();

		private void Awake()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			Root = new GameObject("MiniOnes");
			Root.transform.SetParent(((Component)this).gameObject.transform);
			Root.SetActive(false);
			maxtamingLvl = LetMeTameYou.maxTamingLevel.Value;
		}

		public static void SetupAllCreatures()
		{
			DBG.blogDebug("SetUp All Creatures");
			InitBaseObjects(ObjectDB.instance);
			AlterEggs();
			maxtamingLvl = LetMeTameYou.maxTamingLevel.Value;
		}

		public static void UpdatesFromServer()
		{
			SetupAllCreatures();
			zns = ((Component)ObjectDB.instance).gameObject.GetComponent<ZNetScene>();
			LoadInCreatures(LetMeTameYou.customTamesList);
			ObjectDB.instance.UpdateRegisters();
			DBG.blogInfo("Succesfully Loaded Config from server");
		}

		private static void LoadInCreatures(Dictionary<string, LetMeTameYou.TameConfig> tamesList)
		{
			DBG.blogDebug("Loading in Creatures");
			foreach (KeyValuePair<string, LetMeTameYou.TameConfig> tames in tamesList)
			{
				string key = tames.Key;
				if ((Object)(object)zns.GetPrefab(key) == (Object)null)
				{
					DBG.blogWarning("Cant find Prefab Check your name : " + key);
				}
				else
				{
					AddTame(zns.GetPrefab(key), tames.Value);
				}
			}
			hasInitTames = true;
		}

		public static void clearTameClasses()
		{
			foreach (ModifiedTame modifiedTame in modifiedTameList)
			{
				foreach (AddedClass addedClass in modifiedTame.addedClasses)
				{
					DBG.blogDebug("Removing " + addedClass.ToString() + " from " + ((Object)modifiedTame.go).name);
					Object.Destroy((Object)(object)((Component)modifiedTame.go.transform).GetComponent(addedClass.ToString()));
					if (addedClass == AddedClass.Tameable)
					{
						MonsterAI component = modifiedTame.go.GetComponent<MonsterAI>();
						if ((Object)(object)component != (Object)null)
						{
							component.m_consumeItems.Clear();
						}
					}
				}
			}
		}

		public static void AddTame(GameObject go, LetMeTameYou.TameConfig tb)
		{
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Expected O, but got Unknown
			if (tb.removeTameable)
			{
				DBG.blogDebug("Removing Tameable from " + ((Object)go).name);
				if ((Object)(object)go.GetComponent<Tameable>() != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)go.GetComponent<Tameable>());
				}
				if ((Object)(object)go.GetComponent<Procreation>() != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)go.GetComponent<Procreation>());
				}
				return;
			}
			if ((Object)(object)go.GetComponent<MonsterAI>() == (Object)null)
			{
				if (!((Object)(object)go.GetComponent<AnimalAI>() != (Object)null))
				{
					DBG.blogWarning(((Object)go).name + " can't be added,Remove it in your cfg");
					return;
				}
				CloneAnimalAI(go);
			}
			MonsterAI component = go.GetComponent<MonsterAI>();
			Humanoid component2 = go.GetComponent<Humanoid>();
			if (tb.specialGroup != "")
			{
				((Character)component2).m_group = tb.specialGroup;
			}
			else if (!tb.hostileToSelf)
			{
				((Character)component2).m_group = ((Object)go).name;
			}
			else
			{
				((Character)component2).m_group = "";
			}
			SpawnedHostilePatches.findTamedAttackVariants(component2);
			ModifiedTame modifiedTame = new ModifiedTame(go);
			Tameable val = default(Tameable);
			if (!go.TryGetComponent<Tameable>(ref val))
			{
				val = go.AddComponent<Tameable>();
				modifiedTame.addedClasses.Add(AddedClass.Tameable);
			}
			LMTY_Interactable lMTY_Interactable = default(LMTY_Interactable);
			if (tb.trade != "" && !go.TryGetComponent<LMTY_Interactable>(ref lMTY_Interactable))
			{
				DBG.blogDebug("Adding LMTY_Interactable");
				lMTY_Interactable = go.AddComponent<LMTY_Interactable>();
				modifiedTame.addedClasses.Add(AddedClass.LMTY_Interactable);
				DBG.blogDebug("Added LMTY_Interactable");
			}
			if (val.m_petEffect.m_effectPrefabs.Length == 0)
			{
				int num = 0;
				string text = "Effect List: ";
				EffectData[] array = (EffectData[])(object)new EffectData[10];
				EffectData[] effectPrefabs = ((BaseAI)component).m_idleSound.m_effectPrefabs;
				EffectData[] array2 = effectPrefabs;
				foreach (EffectData val2 in array2)
				{
					try
					{
						text = text + num + ":" + ((Object)val2.m_prefab).name;
						array[num] = val2;
					}
					catch
					{
					}
					num++;
				}
				DBG.blogDebug(text);
				int num2 = effectPrefabs.Length;
				if (((BaseAI)component).m_idleSound.m_effectPrefabs.Length != 0)
				{
					EffectData val3 = new EffectData();
					val3.m_prefab = heartEffectGO;
					Array.Resize(ref array, num2 + 1);
					array[num2] = val3;
					val.m_petEffect.m_effectPrefabs = array;
				}
				else
				{
					val.m_petEffect = wtame.m_petEffect;
				}
			}
			val.m_sootheEffect = val.m_petEffect;
			val.m_tamedEffect = wtame.m_tamedEffect;
			val.m_commandable = tb.commandable;
			val.m_tamingTime = tb.tamingTime;
			val.m_fedDuration = tb.fedDuration;
			component.m_consumeRange = tb.consumeRange;
			component.m_consumeSearchInterval = tb.consumeSearchInterval;
			component.m_consumeSearchRange = tb.consumeSearchRange;
			if (component.m_enableHuntPlayer)
			{
				component.m_wakeupRange = 150f;
				component.m_enableHuntPlayer = false;
			}
			component.m_consumeItems = new List<ItemDrop>();
			List<string> list = tb.consumeItems.Split(new char[1] { ',' }).ToList();
			if (!string.IsNullOrEmpty(list[0]) | (list.Count > 1))
			{
				foreach (string item in list)
				{
					GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item);
					if ((Object)(object)itemPrefab == (Object)null)
					{
						DBG.blogWarning("Wrong food name :" + item);
					}
					else
					{
						component.m_consumeItems.Add(itemPrefab.GetComponent<ItemDrop>());
					}
				}
			}
			else
			{
				DBG.blogInfo("Cannot be tamed by food");
			}
			if (tb.requiredWorldKeys != "")
			{
				List<string> value = tb.requiredWorldKeys.Split(new char[1] { ',' }).ToList();
				if (RequiredTamingKeys.ContainsKey(((Object)go).name))
				{
					RequiredTamingKeys.Remove(((Object)go).name);
				}
				RequiredTamingKeys.Add(((Object)go).name, value);
			}
			if (tb.procreation)
			{
				bool flag = true;
				Procreation val4 = default(Procreation);
				if (!go.TryGetComponent<Procreation>(ref val4))
				{
					val4 = go.AddComponent<Procreation>();
					modifiedTame.addedClasses.Add(AddedClass.Procreation);
					flag = false;
				}
				val4.m_maxCreatures = tb.maxCreatures;
				val4.m_pregnancyChance = tb.pregnancyChance;
				if (val4.m_pregnancyChance > 1f)
				{
					Procreation obj2 = val4;
					obj2.m_pregnancyChance *= 0.01f;
				}
				if (val4.m_pregnancyChance > 1f)
				{
					val4.m_pregnancyChance = 0.66f;
				}
				val4.m_pregnancyDuration = tb.pregnancyDuration;
				if (val4.m_updateInterval < 20f)
				{
					val4.m_updateInterval = 20f;
				}
				val4.m_partnerCheckRange = 4f * tb.size;
				val4.m_totalCheckRange = 10f * tb.size;
				if ((tb.egg ?? "") != "")
				{
					SetNewEgg(go, val4, tb);
				}
				else if (flag && (Object)(object)val4.m_offspring != (Object)null && !tb.offspringOverwrite)
				{
					GameObject offspring = val4.m_offspring;
					Growup component3 = offspring.GetComponent<Growup>();
					if (Object.op_Implicit((Object)(object)component3))
					{
						component3.m_growTime = tb.growTime;
					}
					else
					{
						EggGrow component4 = offspring.GetComponent<EggGrow>();
						if (Object.op_Implicit((Object)(object)component4))
						{
							Growup component5 = component4.m_grownPrefab.GetComponent<Growup>();
							if (Object.op_Implicit((Object)(object)component5))
							{
								component5.m_growTime = tb.growTime;
								DBG.blogWarning(((Object)go).name + " has egg as offspring, modified hatched prefab growtime");
							}
						}
						else
						{
							DBG.blogWarning("Failed to set grow time for " + ((Object)go).name);
						}
					}
					string name = ((Object)offspring).name;
					int stableHashCode = StringExtensionMethods.GetStableHashCode(name);
					if (zns.m_namedPrefabs.ContainsKey(stableHashCode))
					{
						DBG.blogDebug("Already has " + name + " in ObjectDB, only changing growup time");
					}
					else
					{
						DBG.blogDebug("Had to Register " + name + " in ObjectDB");
						Utils.addToZNS(offspring);
					}
					DBG.blogDebug(((Object)go).name + " already has offspring, modified tameable");
				}
				else if (((Object)go).name == "Hatchling" && LetMeTameYou.hatchlingEgg.Value)
				{
					val4.m_offspring = DrakeEggPrefab;
					DrakeEggPrefab.GetComponent<EggGrow>().m_grownPrefab = SpawnMini(go, tb.growTime);
				}
				else
				{
					val4.m_offspring = SpawnMini(go, tb.growTime);
				}
				if (ZNet.instance.IsServer() & ZNet.instance.IsDedicated())
				{
					GameObject prefab = ZNetScene.instance.GetPrefab(((Object)go).name);
					string text2 = " is not Tameable";
					if (((Behaviour)prefab.GetComponent<Tameable>()).enabled)
					{
						text2 = " is Tameable";
					}
					DBG.blogDebug("******* " + ((Object)prefab).name + text2 + " ********");
				}
			}
			else
			{
				if ((Object)(object)go.GetComponent<Procreation>() != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)go.GetComponent<Procreation>());
				}
				DBG.blogDebug("Added ability to tame to " + ((Object)go).name);
			}
			if (modifiedTame.addedClasses.Count > 0)
			{
				modifiedTameList.Add(modifiedTame);
			}
		}

		public static GameObject SpawnMini(GameObject prefab, float growup_time = 1800f)
		{
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			string text = ((Object)prefab).name;
			string text2 = (LetMeTameYou.customTamesList.TryGetValue(text, out var value) ? value.offspringName : "");
			text2 = text2.Replace("_", " ");
			GameObject val = Object.Instantiate<GameObject>(zns.GetPrefab(text), Root.transform);
			if (text.Contains("(Clone)"))
			{
				text = Utils.GetPrefabName(((Object)prefab).name);
			}
			string text3 = "$lmty_mini_prefix";
			((Object)val).name = "Mini" + text;
			string name = ((Object)val).name;
			int stableHashCode = StringExtensionMethods.GetStableHashCode(name);
			if (zns.m_namedPrefabs.ContainsKey(stableHashCode))
			{
				DBG.blogDebug("Already has " + name + " in ObjectDB, changed growup time");
				GameObject prefab2 = zns.GetPrefab(stableHashCode);
				Growup component = prefab2.GetComponent<Growup>();
				component.m_growTime = growup_time;
				return prefab2;
			}
			Transform transform = val.transform;
			transform.localScale *= 0.5f;
			Character component2 = val.GetComponent<Character>();
			if ((Object)(object)component2 != (Object)null)
			{
				if ((text2 ?? "") == "")
				{
					text2 = text3 + " " + component2.m_name;
				}
				component2.m_name = text2;
			}
			component2.m_flying = false;
			if ((Object)(object)val.GetComponent<MonsterAI>() != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)val.GetComponent<MonsterAI>());
			}
			if ((Object)(object)val.GetComponent<VisEquipment>() != (Object)null)
			{
				removeWeaponsFromSets(val);
			}
			if ((Object)(object)val.GetComponent<CharacterDrop>() != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)val.GetComponent<CharacterDrop>());
			}
			if ((Object)(object)val.GetComponent<Tameable>() != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)val.GetComponent<Tameable>());
			}
			if ((Object)(object)val.GetComponent<Procreation>() != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)val.GetComponent<Procreation>());
			}
			if ((Object)(object)val.GetComponent<NpcTalk>() != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)val.GetComponent<NpcTalk>());
			}
			AnimalAI val2 = default(AnimalAI);
			if (!val.TryGetComponent<AnimalAI>(ref val2))
			{
				MonsterAI component3 = prefab.GetComponent<MonsterAI>();
				val2 = val.AddComponent<AnimalAI>();
				((Component)(object)val2).CopyBroComponent<AnimalAI, MonsterAI>(component3);
			}
			((BaseAI)val2).m_randomFly = false;
			Growup val3 = val.AddComponent<Growup>();
			val3.m_grownPrefab = zns.GetPrefab(text);
			if (value != null)
			{
				val3.m_growTime = value.growTime;
			}
			else
			{
				val3.m_growTime = growup_time;
			}
			if (zns.m_namedPrefabs.ContainsKey(stableHashCode))
			{
				zns.m_namedPrefabs.Remove(stableHashCode);
			}
			Utils.addToZNS(val);
			if ((Object)(object)ZNetScene.instance.GetPrefab(((Object)val).name) != (Object)null)
			{
				DBG.blogDebug("Successfully added Tame and Procreation to " + ((Object)prefab).name);
			}
			return val;
		}

		private static GameObject InitEgg(GameObject prefab, LetMeTameYou.TameConfig tb, float hatchTime, int EggType = 0, string color = "default", float size = 1f)
		{
			//IL_051f: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_060a: Unknown result type (might be due to invalid IL or missing references)
			//IL_061b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0620: Unknown result type (might be due to invalid IL or missing references)
			//IL_065f: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_06fa: Expected O, but got Unknown
			//IL_0705: Unknown result type (might be due to invalid IL or missing references)
			//IL_0716: Unknown result type (might be due to invalid IL or missing references)
			//IL_071d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0670: Unknown result type (might be due to invalid IL or missing references)
			//IL_0672: Unknown result type (might be due to invalid IL or missing references)
			//IL_067c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0694: Unknown result type (might be due to invalid IL or missing references)
			//IL_0699: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_06be: Unknown result type (might be due to invalid IL or missing references)
			DBG.blogDebug("Creating Egg");
			GameObject prefab2 = zns.GetPrefab(((Object)prefab).name + "Egg_LMTY");
			if (Object.op_Implicit((Object)(object)prefab2))
			{
				DBG.blogDebug("zns Already Egg with name " + ((Object)prefab).name + "Egg_LMTY, skipping creation");
				int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)prefab2).name);
				if (!Object.op_Implicit((Object)(object)ObjectDB.instance.GetItemPrefab(stableHashCode)))
				{
					ObjectDB.instance.m_items.Add(prefab2);
				}
				return prefab2;
			}
			prefab2 = (GameObject)(EggType switch
			{
				0 => Object.Instantiate<GameObject>(DrakeEggPrefab, Root.transform), 
				1 => Object.Instantiate<GameObject>(ChickenEggPrefab, Root.transform), 
				_ => Object.Instantiate<GameObject>(AsksvinEggPrefab, Root.transform), 
			});
			((Object)prefab2).name = ((Object)prefab).name + "Egg_LMTY";
			int stableHashCode2 = StringExtensionMethods.GetStableHashCode(((Object)prefab2).name);
			if (!Object.op_Implicit((Object)(object)ObjectDB.instance.GetItemPrefab(stableHashCode2)))
			{
				ObjectDB.instance.m_items.Add(prefab2);
			}
			ItemDrop[] components = prefab2.GetComponents<ItemDrop>();
			if (components.Length > 1)
			{
				Object.DestroyImmediate((Object)(object)components[0]);
			}
			ItemDrop component = prefab2.GetComponent<ItemDrop>();
			ItemData itemData = component.m_itemData;
			Character component2 = prefab.GetComponent<Character>();
			if (Object.op_Implicit((Object)(object)component2))
			{
				itemData.m_shared.m_name = component2.m_name + " $lmty_egg";
				DBG.blogDebug("char name =" + component2.m_name);
			}
			else
			{
				itemData.m_shared.m_name = ((Object)prefab).name + " $lmty_egg";
			}
			itemData.m_shared.m_description = "$lmty_egg_desc_prefix " + ((Object)prefab).name + ", $lmty_egg_desc_sufix";
			float num = 3f;
			if (size > 1f)
			{
				num = 2.2f;
			}
			float num2 = ((EggType != 2) ? 1 : 30);
			itemData.m_shared.m_weight = itemData.m_shared.m_weight * num2 * Mathf.Pow(size, num);
			itemData.m_shared.m_teleportable = true;
			itemData.m_dropPrefab = prefab2;
			if (ObjectDB.instance.m_itemByHash.TryGetValue(stableHashCode2, out var value))
			{
				DBG.blogDebug("Set drop prefab to object db");
				itemData.m_dropPrefab = value;
			}
			else
			{
				DBG.blogDebug("Adding to objectdb hash");
				ObjectDB.instance.m_itemByHash.Add(stableHashCode2, prefab2);
				DBG.blogDebug("Hash =" + stableHashCode2);
			}
			component.Save();
			EggGrow component3 = prefab2.GetComponent<EggGrow>();
			component3.m_growTime = hatchTime;
			bool flag = true;
			MonsterAI component4 = prefab.GetComponent<MonsterAI>();
			if ((Object)(object)component4 != (Object)null && component4.m_avoidLand)
			{
				component3.m_requireNearbyFire = false;
				component3.m_requireUnderRoof = false;
			}
			Procreation val = default(Procreation);
			if (prefab.TryGetComponent<Procreation>(ref val) && Object.op_Implicit((Object)(object)val.m_offspring) && !tb.offspringOverwrite && !((Object)val.m_offspring).name.Contains("Egg_LMTY"))
			{
				flag = false;
				component3.m_grownPrefab = val.m_offspring;
				DBG.blogDebug("Copied Offspring from Parent");
				string name = ((Object)component3.m_grownPrefab).name;
				int stableHashCode3 = StringExtensionMethods.GetStableHashCode(name);
				if (zns.m_namedPrefabs.ContainsKey(stableHashCode3))
				{
					DBG.blogDebug("Egg Offspring Already has " + name + " in ObjectDB, only changing growup time");
					component3.m_grownPrefab = zns.GetPrefab(stableHashCode3);
				}
				else
				{
					DBG.blogDebug("Egg had to Register " + name + " in ObjectDB");
					Utils.addToZNS(component3.m_grownPrefab);
				}
			}
			if (flag)
			{
				component3.m_grownPrefab = SpawnMini(prefab);
				string name2 = ((Object)component3.m_grownPrefab).name;
				int stableHashCode4 = StringExtensionMethods.GetStableHashCode(name2);
				if (zns.m_namedPrefabs.ContainsKey(stableHashCode4))
				{
					DBG.blogDebug("Create Offspring Already has " + name2 + " in ObjectDB, only changing growup time");
					component3.m_grownPrefab = zns.GetPrefab(stableHashCode4);
				}
				else
				{
					DBG.blogDebug("Egg2 had to Register " + name2 + " in ObjectDB");
					Utils.addToZNS(component3.m_grownPrefab);
				}
			}
			GameObject val2 = ((EggType != 0) ? ((Component)((Component)prefab2.transform.Find("attach").Find("default")).transform).gameObject : ((Component)((Component)prefab2.transform.Find("attach").Find("model")).transform).gameObject);
			if (size != 1f)
			{
				prefab2.transform.Find("attach").localScale = new Vector3(size, size, size);
				LODGroup component5 = val2.GetComponent<LODGroup>();
				if (Object.op_Implicit((Object)(object)component5))
				{
					component5.size = Mathf.Max(9.3f - 2.14f * size, 5f);
				}
				DBG.blogDebug("Changed Size");
			}
			if (color != "default")
			{
				DBG.blogDebug("changing color");
				Material material = ((Renderer)val2.GetComponent<MeshRenderer>()).material;
				if (color.Length == 7 && color[0] == '#')
				{
					DBG.blogDebug("attempting hex for " + color);
					Color val3 = Utils.colFromHex(color);
					string text = "NewChickenEgg";
					switch (EggType)
					{
					case 0:
					{
						material.color = val3;
						material.SetColor("_EmissionColor", val3 * new Color(1f, 3f, 1f));
						text = "NewDragonEgg";
						Light component6 = ((Component)((Component)prefab2.transform.Find("attach").Find("Point light")).transform).gameObject.GetComponent<Light>();
						component6.color = val3;
						break;
					}
					case 1:
						material.color = 1.2f * val3 * new Color(0.9f * val3.r - 0.1f, 0.95f, 1.3f);
						break;
					default:
						material.color = val3 * new Color(1.1f, 1f, 1.1f);
						text = "NewRockyEgg";
						break;
					}
					Object[] array = PrefabManager.getAssetBundle().LoadAssetWithSubAssets("Assets/LMTY/" + text + ".png");
					Sprite val4 = (Sprite)array[1];
					Texture2D texture = val4.texture;
					texture = Utils.changeEggTex(texture, val3, EggType == 0);
					Sprite val5 = Sprite.Create(texture, val4.rect, val4.pivot);
					itemData.m_shared.m_icons[0] = val5;
				}
				else
				{
					DBG.blogWarning("Not correctly formatted as HEX color");
				}
			}
			else
			{
				DBG.blogDebug("Keeping color default");
			}
			try
			{
				Utils.addToZNS(prefab2);
				DBG.blogInfo("Succesfully registered " + ((Object)prefab2).name);
			}
			catch
			{
				DBG.blogInfo("Already Registered " + ((Object)prefab2).name);
			}
			return prefab2;
		}

		private static void SetNewEgg(GameObject go, Procreation proc, LetMeTameYou.TameConfig tb)
		{
			int EggType = 2;
			float hatchtime = 1800f;
			string colorstr = "default";
			float size = 1f;
			parseEggValue(tb.egg, ref EggType, ref hatchtime, ref colorstr, ref size);
			GameObject offspring = InitEgg(go, tb, hatchtime, EggType, colorstr, size);
			if ((Object)(object)proc != (Object)null)
			{
				proc.m_offspring = offspring;
			}
		}

		public static void parseEggValue(string eggStr, ref int EggType, ref float hatchtime, ref string colorstr, ref float size)
		{
			string text = eggStr.Replace(")", "");
			string[] array = text.Split(new char[1] { '(' });
			if (array[0].ToLower() == "chicken")
			{
				EggType = 1;
			}
			else if (array[0].ToLower() == "drake")
			{
				EggType = 0;
			}
			if (array.Length < 2)
			{
				return;
			}
			string[] array2 = array[1].Split(new char[1] { ':' });
			try
			{
				hatchtime = float.Parse(array2[0], CultureInfo.InvariantCulture.NumberFormat);
			}
			catch
			{
				DBG.blogWarning("value for egg hatchtime, make sure the config is written correctly");
			}
			if (array2.Length < 2)
			{
				return;
			}
			colorstr = array2[1];
			if (array2.Length < 3)
			{
				return;
			}
			try
			{
				size = float.Parse(array2[2], CultureInfo.InvariantCulture.NumberFormat);
			}
			catch
			{
				DBG.blogWarning("value for egg is invalid, make sure the config is written correctly");
			}
		}

		private static void RemoveBossAndAggravateable(BaseAI baseAI)
		{
			Character character = baseAI.m_character;
			if (!Object.op_Implicit((Object)(object)character))
			{
				return;
			}
			if (character.m_tamed)
			{
				baseAI.m_aggravatable = false;
				if (character.m_boss)
				{
					DBG.blogDebug("setting boss to not boss");
					baseAI.SetAlerted(false);
					character.m_dontHideBossHud = false;
					EnemyHud.instance.LateUpdate();
					character.m_boss = false;
				}
			}
			else if (character.m_boss)
			{
				baseAI.SetAlerted(true);
			}
		}

		public static void removeWeaponsFromSets(GameObject go)
		{
			DBG.blogDebug("in removeWeapons");
			Humanoid component = go.GetComponent<Humanoid>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return;
			}
			component.m_utilityItem = null;
			component.m_randomWeapon = null;
			ItemSet[] randomSets = component.m_randomSets;
			List<ItemType> list = new List<ItemType>();
			list.Add((ItemType)6);
			list.Add((ItemType)7);
			list.Add((ItemType)10);
			list.Add((ItemType)12);
			list.Add((ItemType)11);
			list.Add((ItemType)17);
			if (randomSets != null)
			{
				ItemSet[] array = randomSets;
				foreach (ItemSet val in array)
				{
					if (val != null)
					{
						val.m_items = cleanedSet(val.m_items, list);
					}
				}
			}
			if (component.m_defaultItems != null)
			{
				component.m_defaultItems = cleanedSet(component.m_defaultItems, list);
			}
		}

		public static GameObject[] cleanedSet(GameObject[] dirtySet, List<ItemType> keepList)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			List<GameObject> list = new List<GameObject>();
			list.AddRange(dirtySet);
			ItemDrop val2 = default(ItemDrop);
			for (int num = list.Count - 1; num >= 0; num--)
			{
				GameObject val = list[num];
				if (val.TryGetComponent<ItemDrop>(ref val2))
				{
					SharedData shared = val2.m_itemData.m_shared;
					if (!keepList.Contains(shared.m_itemType))
					{
						list.Remove(val);
					}
				}
			}
			return list.ToArray();
		}

		public static void CloneAnimalAI(GameObject go)
		{
			if ((Object)(object)go.GetComponent<LMTY_AnimalAI>() == (Object)null)
			{
				DBG.blogDebug("Fixing AI for " + ((Object)go).name);
				MonsterAI component = zns.GetPrefab("Boar").GetComponent<MonsterAI>();
				Humanoid val = default(Humanoid);
				if (!go.TryGetComponent<Humanoid>(ref val))
				{
					val = go.AddComponent<Humanoid>();
					((Character)val).m_eye = go.transform.GetChild(0);
				}
				AnimalAI component2 = go.GetComponent<AnimalAI>();
				Character component3 = go.GetComponent<Character>();
				LMTY_AnimalAI lMTY_AnimalAI = go.AddComponent<LMTY_AnimalAI>();
				Utils.cloneProperties<LMTY_AnimalAI, MonsterAI>(lMTY_AnimalAI, component);
				Utils.cloneProperties<LMTY_AnimalAI, AnimalAI>(lMTY_AnimalAI, component2);
				Utils.cloneProperties<Humanoid, Character>(val, component3);
				((BaseAI)lMTY_AnimalAI).m_character = (Character)(object)val;
				if (((BaseAI)lMTY_AnimalAI).m_randomMoveInterval > 30f)
				{
					((BaseAI)lMTY_AnimalAI).m_randomMoveInterval = 30f;
				}
				Object.DestroyImmediate((Object)(object)go.GetComponent<AnimalAI>());
				Object.DestroyImmediate((Object)(object)go.GetComponent<Character>());
			}
		}

		private static void AlterEggs()
		{
			DBG.blogDebug("Alter Eggs");
			DBG.tryblogDebug("Chicken Egg=" + ((Object)(object)ChickenEggPrefab != (Object)null), "failed Chicken");
			DBG.tryblogDebug("Asksvin Egg=" + ((Object)(object)AsksvinEggPrefab != (Object)null), "failed Asksvin");
			DBG.tryblogDebug("Dragon Egg=" + ((Object)(object)DrakeEggPrefab != (Object)null), "failed Drake");
			if (!AlteredBaseEggs)
			{
				ItemDrop component = ChickenEggPrefab.GetComponent<ItemDrop>();
				component.m_itemData.m_shared.m_maxQuality = 50;
				component.SetQuality(0);
				component.m_autoPickup = false;
				component.m_itemData.m_shared.m_maxStackSize = 20;
				ItemDrop component2 = AsksvinEggPrefab.GetComponent<ItemDrop>();
				component2.m_itemData.m_shared.m_maxQuality = 50;
				component2.SetQuality(0);
				component2.m_autoPickup = false;
				component2.m_itemData.m_shared.m_maxStackSize = 20;
				ItemDrop component3 = DrakeEggPrefab.GetComponent<ItemDrop>();
				component3.m_itemData.m_shared.m_maxQuality = 50;
				component3.SetQuality(0);
				component3.m_autoPickup = false;
				component3.m_itemData.m_shared.m_maxStackSize = 20;
				AlteredBaseEggs = true;
			}
			if (LetMeTameYou.hatchlingEgg.Value && OverwroteDragonEgg)
			{
				DBG.blogDebug("Skipping modify Dragon egg as already correct setting");
			}
			else if (!LetMeTameYou.hatchlingEgg.Value && OverwroteDragonEgg)
			{
				DBG.blogDebug("in 1");
				SetCustDragonEgg();
				GameObject val = zns.m_prefabs.Find((GameObject x) => ((Object)x).name == "DragonEgg");
				EggGrow val2 = default(EggGrow);
				if (val.TryGetComponent<EggGrow>(ref val2))
				{
					Object.DestroyImmediate((Object)(object)val2);
					DBG.blogDebug("Destroyed EggGrow");
				}
				Transform val3 = val.transform.Find("Not Growing");
				if ((Object)(object)val3 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)((Component)val3).gameObject);
					DBG.blogDebug("Destroyed Not Growing");
				}
				OverwroteDragonEgg = false;
			}
			else if (!LetMeTameYou.hatchlingEgg.Value && !OverwroteDragonEgg)
			{
				DBG.blogDebug("in 3");
				SetCustDragonEgg();
			}
			else
			{
				DBG.blogDebug("in 2");
				DrakeEggPrefab = zns.m_prefabs.Find((GameObject x) => ((Object)x).name == "DragonEgg");
				OverwroteDragonEgg = true;
				cloneChickenEgg(DrakeEggPrefab);
			}
		}

		private static void SetCustDragonEgg()
		{
			if ((Object)(object)CustDrakeEggPrefab == (Object)null)
			{
				CustDrakeEggPrefab = Object.Instantiate<GameObject>(DrakeEggPrefab, Root.transform);
			}
			DrakeEggPrefab = CustDrakeEggPrefab;
			EggGrow component = DrakeEggPrefab.GetComponent<EggGrow>();
			if ((Object)(object)component == (Object)null)
			{
				cloneChickenEgg(DrakeEggPrefab);
			}
			else
			{
				component.m_growTime = LetMeTameYou.hatchingTime.Value;
			}
		}

		private static void cloneChickenEgg(GameObject destination_go)
		{
			if ((Object)(object)destination_go.GetComponent<EggGrow>() != (Object)null)
			{
				DBG.blogDebug("Already added EggGrow To Dragon Egg, skipping");
				return;
			}
			DBG.blogDebug("cloning chicken");
			Transform val = Root.transform.Find("chickenEggClone_at");
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = Object.Instantiate<GameObject>(ChickenEggPrefab, Root.transform).transform;
				((Object)val).name = "chickenEggClone_at";
			}
			DBG.blogDebug("cloned chiken=" + ((Object)(object)val != (Object)null));
			GameObject gameObject = ((Component)Utils.CopyIntoParent<Transform>(val.Find("Not Growing"), destination_go.transform)).gameObject;
			EggGrow val2 = destination_go.AddComponent<EggGrow>(((Component)val).GetComponent<EggGrow>());
			val2.m_notGrowingObject = gameObject;
			val2.m_growTime = LetMeTameYou.hatchingTime.Value;
			val2.m_tamed = true;
			((Component)val2).tag = "spawned";
			val2.m_grownPrefab = zns.m_prefabs.Find((GameObject x) => ((Object)x).name == "Hatchling");
			DBG.blogDebug("Added EggGrow To Dragon Egg");
		}

		private static void InitBaseObjects(ObjectDB oDB)
		{
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Expected O, but got Unknown
			DBG.blogWarning("Init Base Objects");
			if (hasInitBaseObj)
			{
				DBG.blogWarning("Already Init Base Objects");
				return;
			}
			if (Object.op_Implicit((Object)(object)oDB))
			{
				DBG.blogWarning("Setting new zns");
				zns = ((Component)oDB).gameObject.GetComponent<ZNetScene>();
			}
			else
			{
				DBG.blogWarning("odb null");
				if (!Object.op_Implicit((Object)(object)zns))
				{
					DBG.blogWarning("zns also null");
					return;
				}
			}
			if (!Object.op_Implicit((Object)(object)zns))
			{
				DBG.blogWarning("zns null");
				return;
			}
			DBG.blogWarning("prefab size=" + zns.m_prefabs.Count);
			wtame = zns.m_prefabs.Find((GameObject x) => ((Object)x).name == "Wolf").GetComponent<Tameable>();
			if ((Object)(object)wtame != (Object)null)
			{
				createHeartEffect();
			}
			else
			{
				DBG.blogWarning("Wolf tame is null, creating null pet effect");
				heartEffectGO = new GameObject("failedHeartEffect");
				heartEffectGO.transform.parent = Root.transform;
				Object.DontDestroyOnLoad((Object)(object)heartEffectGO);
			}
			ChickenEggPrefab = zns.m_prefabs.Find((GameObject x) => ((Object)x).name == "ChickenEgg");
			DrakeEggPrefab = zns.m_prefabs.Find((GameObject x) => ((Object)x).name == "DragonEgg");
			AsksvinEggPrefab = zns.m_prefabs.Find((GameObject x) => ((Object)x).name == "AsksvinEgg");
			PrefabManager.FixShaders(((Component)PrefabManager.TameStickPrefab.transform.GetChild(0)).gameObject);
			DBG.blogDebug("is null3=" + (object)heartEffectGO == null);
			hasInitBaseObj = true;
		}

		public static void createHeartEffect()
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			DBG.blogDebug("Making HeartEffect");
			bool flag = false;
			if ((Object)(object)wtame == (Object)null)
			{
				DBG.blogWarning("wolf tame is null");
				flag = true;
			}
			if ((Object)(object)Root == (Object)null)
			{
				DBG.blogWarning("Root is null");
			}
			if (!flag)
			{
				DBG.blogDebug("has Wolf");
				heartEffectGO = Object.Instantiate<GameObject>(wtame.m_petEffect.m_effectPrefabs[0].m_prefab, Root.transform);
				DBG.blogDebug("removing child");
				heartEffectGO.transform.GetChild(1).parent = null;
				heartEffectGO.SetActive(false);
			}
			else
			{
				heartEffectGO = new GameObject("failed2HeartEffect");
				heartEffectGO.transform.parent = Root.transform;
			}
			DBG.blogDebug("Created HeartEffect");
		}

		public static void resetTameManager()
		{
			RequiredTamingKeys.Clear();
			TamedAttackVariants.Clear();
			clearTameClasses();
			hasInitTames = false;
		}

		public static bool hasTamingKeysAndLevel(Tameable tameable)
		{
			if (maxtamingLvl > 0 && tameable.m_character.GetLevel() > maxtamingLvl)
			{
				return false;
			}
			string key = ((Object)tameable).name.Replace("(Clone)", "");
			if (RequiredTamingKeys.TryGetValue(key, out var value))
			{
				bool flag = true;
				foreach (string item in value)
				{
					if (!ZoneSystem.instance.CheckKey(item, (GameKeyType)0, true))
					{
						flag = false;
					}
				}
				if (!flag)
				{
					return false;
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(Character), "RPC_Heal")]
		[HarmonyPrefix]
		private static void Prefix(out bool __state, long sender, float hp, ref bool showText)
		{
			__state = showText;
			if (hp < 0.1f)
			{
				showText = false;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(MonsterAI), "UpdateConsumeItem")]
		private static bool Prefix(MonsterAI __instance, Humanoid humanoid, ref bool __result)
		{
			if (((Character)humanoid).m_tamed)
			{
				return true;
			}
			Tameable tamable = ((BaseAI)__instance).m_tamable;
			if ((Object)(object)tamable == (Object)null)
			{
				return true;
			}
			__result = hasTamingKeysAndLevel(tamable);
			if (!__result)
			{
				tamable.m_nview.GetZDO().Set(ZDOVars.s_tameLastFeeding, 0L);
				tamable.m_nview.GetZDO().Set(ZDOVars.s_tameTimeLeft, tamable.m_tamingTime);
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(Tameable), "Tame")]
		[HarmonyPostfix]
		private static void Postfix_Tame(Tameable __instance)
		{
			__instance.m_fedDuration *= LetMeTameYou.TamedFedMultiplier.Value;
			RemoveBossAndAggravateable((BaseAI)(object)__instance.m_monsterAI);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Character), "SetTamed")]
		private static void Postfix_SetTame(Character __instance, bool tamed)
		{
			if (tamed && !((Object)(object)__instance.m_baseAI == (Object)null))
			{
				RemoveBossAndAggravateable(__instance.m_baseAI);
			}
		}

		[HarmonyPatch(typeof(BaseAI), "Awake")]
		[HarmonyPostfix]
		private static void PostfixBaseAIFindEnemy(BaseAI __instance)
		{
			RemoveBossAndAggravateable(__instance);
		}

		[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
		[HarmonyPrefix]
		private static void Prefix_ObjectDB_CopyOther(ObjectDB __instance, ObjectDB other)
		{
			InitBaseObjects(other);
			if ((Object)(object)other != (Object)null && ((Object)other).name == "_NetScene")
			{
				Utils.addItemToODB(PrefabManager.TameStickPrefab, other);
			}
		}

		[HarmonyPatch(typeof(ZNetScene), "Awake")]
		[HarmonyPrefix]
		private static void PostFix_ZNetScene_Awake(ObjectDB __instance)
		{
			SetupAllCreatures();
		}

		[HarmonyPriority(5)]
		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		[HarmonyPostfix]
		private static void Postfix_ODB_Awake(ObjectDB __instance)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			DBG.blogDebug("In main Load");
			if (!LetMeTameYou.localizeLoaded)
			{
				Localizer.Load();
				LetMeTameYou.localizeLoaded = true;
			}
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name != "main")
			{
				DBG.blogDebug("Not Main Scene");
				return;
			}
			if (!Object.op_Implicit((Object)(object)ZNet.instance))
			{
				DBG.blogDebug("No instance of ZNet");
				return;
			}
			if (!ZNet.instance.IsServer())
			{
				DBG.blogDebug("ZNet not server");
				return;
			}
			DBG.blogDebug("Copying Creature Prefabs for Procreation");
			if (LetMeTameYou.customTamesList.Count() < 1)
			{
				DBG.blogDebug("Grabing creature config again");
				YAMLReadWrite.UseFileOpenReadTextWithSystemTextYaml();
				if (LetMeTameYou.customTamesList.Count() < 1)
				{
					DBG.blogWarning("Failed second attempt at setting the tamelist, all tames may not work");
				}
			}
			if (!hasInitTames)
			{
				zns = ((Component)__instance).gameObject.GetComponent<ZNetScene>();
				LoadInCreatures(LetMeTameYou.customTamesList);
			}
			PrefabManager.ItemReg();
		}
	}
	internal class DBG
	{
		public static void blogInfo(object o)
		{
			LetMeTameYou.logger.LogInfo(o);
		}

		public static void blogWarning(object o)
		{
			LetMeTameYou.logger.LogWarning(o);
		}

		public static void blogDebug(object o)
		{
			if (LetMeTameYou.debugout.Value)
			{
				LetMeTameYou.logger.LogWarning(o);
			}
		}

		public static void tryblogDebug(object o, object o_backup)
		{
			try
			{
				if (LetMeTameYou.debugout.Value)
				{
					LetMeTameYou.logger.LogWarning(o);
				}
			}
			catch
			{
				LetMeTameYou.logger.LogWarning(o_backup);
			}
		}
	}
	[BepInPlugin("meldurson.LetMeTameYou", "LetMeTameYou", "0.0.1")]
	public class LetMeTameYou : BaseUnityPlugin
	{
		[Serializable]
		public class TameConfig : ICloneable
		{
			public string PrefabName { get; set; } = "";


			public bool commandable { get; set; } = true;


			public float tamingTime { get; set; } = 1800f;


			public float fedDuration { get; set; } = 600f;


			public float consumeRange { get; set; } = 2f;


			public float consumeSearchInterval { get; set; } = 10f;


			public float consumeSearchRange { get; set; } = 10f;


			public string consumeItems { get; set; } = "RawMeat";


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


			public bool procreation { get; set; } = true;


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


			public int maxCreatures { get; set; } = 5;


			public float pregnancyChance { get; set; } = 0.33f;


			public float pregnancyDuration { get; set; } = 60f;


			public float growTime { get; set; } = 3000f;


			public float size { get; set; } = 1f;


			public float followDistMulti { get; set; } = 1f;


			public string specialGroup { get; set; } = "";


			public string egg { get; set; } = "";


			public string offspringName { get; set; } = "";


			public string requiredWorldKeys { get; set; } = "";


			public string trade { get; set; } = "";


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


			public object Clone()
			{
				return MemberwiseClone();
			}
		}

		[Serializable]
		public class specificMates : ICloneable
		{
			public string prefabName { get; set; } = "";


			public List<chanceOffspring> possibleOffspring { get; set; } = new List<chanceOffspring>();


			public object Clone()
			{
				return MemberwiseClone();
			}
		}

		[Serializable]
		public class chanceOffspring : ICloneable
		{
			public GameObject offspring { get; set; } = null;


			public float chance { get; set; } = 100f;


			public object Clone()
			{
				return MemberwiseClone();
			}
		}

		[HarmonyPatch(typeof(BaseAI), "Follow")]
		public static class InterceptFollow
		{
			[CompilerGenerated]
			private sealed class <Transpiler>d__1 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator
			{
				private int <>1__state;

				private CodeInstruction <>2__current;

				private int <>l__initialThreadId;

				private IEnumerable<CodeInstruction> instructions;

				public IEnumerable<CodeInstruction> <>3__instructions;

				private MethodInfo <followDistHook>5__1;

				private bool <addHook>5__2;

				private bool <hasAddedHook>5__3;

				private IEnumerator<CodeInstruction> <>s__4;

				private CodeInstruction <instruction>5__5;

				CodeInstruction IEnumerator<CodeInstruction>.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				object IEnumerator.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				[DebuggerHidden]
				public <Transpiler>d__1(int <>1__state)
				{
					this.<>1__state = <>1__state;
					<>l__initialThreadId = Environment.CurrentManagedThreadId;
				}

				[DebuggerHidden]
				void IDisposable.Dispose()
				{
					int num = <>1__state;
					if (num == -3 || (uint)(num - 1) <= 2u)
					{
						try
						{
						}
						finally
						{
							<>m__Finally1();
						}
					}
					<followDistHook>5__1 = null;
					<>s__4 = null;
					<instruction>5__5 = null;
					<>1__state = -2;
				}

				private bool MoveNext()
				{
					//IL_012e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0138: Expected O, but got Unknown
					//IL_0105: Unknown result type (might be due to invalid IL or missing references)
					//IL_010f: Expected O, but got Unknown
					try
					{
						switch (<>1__state)
						{
						default:
							return false;
						case 0:
							<>1__state = -1;
							<followDistHook>5__1 = AccessTools.DeclaredMethod(typeof(InterceptFollow), "FollowDist", (Type[])null, (Type[])null);
							<addHook>5__2 = false;
							<hasAddedHook>5__3 = false;
							<>s__4 = instructions.GetEnumerator();
							<>1__state = -3;
							break;
						case 1:
							<>1__state = -3;
							goto IL_015a;
						case 2:
							<>1__state = -3;
							<>2__current = new CodeInstruction(OpCodes.Call, (object)<followDistHook>5__1);
							<>1__state = 3;
							return true;
						case 3:
							{
								<>1__state = -3;
								<addHook>5__2 = false;
								<hasAddedHook>5__3 = true;
								goto IL_015a;
							}
							IL_015a:
							<instruction>5__5 = null;
							break;
						}
						if (<>s__4.MoveNext())
						{
							<instruction>5__5 = <>s__4.Current;
							if (!<addHook>5__2)
							{
								if (<instruction>5__5.opcode == OpCodes.Stloc_0 && !<hasAddedHook>5__3)
								{
									<addHook>5__2 = true;
								}
								<>2__current = <instruction>5__5;
								<>1__state = 1;
								return true;
							}
							<>2__current = new CodeInstruction(OpCodes.Ldarg_0, (object)null);
							<>1__state = 2;
							return true;
						}
						<>m__Finally1();
						<>s__4 = null;
						return false;
					}
					catch
					{
						//try-fault
						((IDisposable)this).Dispose();
						throw;
					}
				}

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

				private void <>m__Finally1()
				{
					<>1__state = -1;
					if (<>s__4 != null)
					{
						<>s__4.Dispose();
					}
				}

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

				[DebuggerHidden]
				IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
				{
					<Transpiler>d__1 <Transpiler>d__;
					if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
					{
						<>1__state = 0;
						<Transpiler>d__ = this;
					}
					else
					{
						<Transpiler>d__ = new <Transpiler>d__1(0);
					}
					<Transpiler>d__.instructions = <>3__instructions;
					return <Transpiler>d__;
				}

				[DebuggerHidden]
				IEnumerator IEnumerable.GetEnumerator()
				{
					return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
				}
			}

			private static float FollowDist(BaseAI baseAI)
			{
				if (customTamesList.TryGetValue(((Object)baseAI).name.Replace("(Clone)", ""), out var value))
				{
					return value.size * 2.2f * followDistMulti.Value * value.followDistMulti;
				}
				return 3f * followDistMulti.Value;
			}

			[IteratorStateMachine(typeof(<Transpiler>d__1))]
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <Transpiler>d__1(-2)
				{
					<>3__instructions = instructions
				};
			}
		}

		public const string versionNumber = "0.0.1";

		public const string versionMinimum = "0.0.1";

		public const string modName = "LetMeTameYou";

		public const string GUID = "meldurson.LetMeTameYou";

		public static ManualLogSource logger;

		public static string tamingtoolPrefabName = "LMTY_TamingTool";

		public static Dictionary<string, TameConfig> customTamesList = new Dictionary<string, TameConfig>();

		public static GameObject Root;

		public static TameManager tameManager;

		public static PrefabManager prefabManager;

		public static CfgPackage CfgPackage;

		public static bool ServerConfigReceived = false;

		public static bool localizeLoaded = false;

		public static Harmony harmony = new Harmony("meldurson.LetMeTameYou");

		public static ConfigEntry<bool> debugout;

		public static ConfigEntry<int> increasedInteractDistance;

		public static ConfigEntry<bool> hatchlingEgg;

		public static ConfigEntry<float> hatchingTime;

		public static ConfigEntry<int> maxTamingLevel;

		public static ConfigEntry<bool> useTamingTool;

		public static ConfigEntry<string> TamingTool_Recipe;

		public static ConfigEntry<string> TamingTool_Station;

		public static ConfigEntry<float> followDistMulti;

		public static ConfigEntry<bool> increaseHoverWidth;

		public static ConfigEntry<float> TamedFedMultiplier;

		public static ConfigEntry<float> IncreasedLevelTamingTime;

		public static ConfigSync configSync = new ConfigSync("meldurson.LetMeTameYou")
		{
			DisplayName = "LetMeTameYou",
			CurrentVersion = "0.0.1",
			MinimumRequiredVersion = "0.0.1"
		};

		private void Awake()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Expected O, but got Unknown
			logger = ((BaseUnityPlugin)this).Logger;
			debugout = config("1:General", "Debug Output", value: true, new ConfigDescription("Determines if debug is output to bepinex log", (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting: false);
			hatchlingEgg = config("1:General", "Hatchling Egg", value: true, "Determines if you want Dragon Eggs to hatch and become hatchlings");
			hatchingTime = config("1:General", "Hatching Time", 1800f, "Determines time it takes for Dragon Egg to hatch");
			useTamingTool = config("1:General", "useTamingTool", value: true, "Use a taming tool to have an overlay when hovering over a creature");
			maxTamingLevel = config("1:General", "maxTamingLevel", -1, "Determines what the maximum wild creature level you can tame is (-1 is no limit)");
			increasedInteractDistance = config("1:General", "Increased Interact Distance", 20, "When using the taming stick, how far away can you interact with creatures");
			increaseHoverWidth = config("1:General", "Increased Hover Width", value: true, "Increase the width of the hover text box to have less word wrap");
			followDistMulti = config("1:General", "Follow Distance Multiplier", 1f, "Multiplies the distance that creatures will follow at");
			TamedFedMultiplier = config("1:General", "TamedFedMultiplier", 4f, "Determines if after being tamed how much longer the creature will stay fed");
			TamingTool_Recipe = config("2: Recipes", "TamingTool Recipe", "RawMeat:1,Carrot:1,Mushroom:1,Resin:5", "What is the recipe for crafting the Taming Tool, separate initial amount and upgrade amounts with : and different items with ,");
			TamingTool_Station = config("2: Recipes", "TamingTool Station", "piece_workbench:1", "What is the required Crafting Station and Level, separated by a : such as piece_workbench:3 would be lvl 3 Workbench (vanilla stations are: piece_workbench, forge, piece_cauldron, piece_stonecutter, piece_artisanstation, blackforge, piece_magetable, piece_MeadCauldron, piece_preptable");
			((BaseUnityPlugin)this).Config.Save();
			YAMLReadWrite.UseFileOpenReadTextWithSystemTextYaml();
			Root = new GameObject("TameManager Root");
			prefabManager = Root.AddComponent<PrefabManager>();
			tameManager = Root.AddComponent<TameManager>();
			Object.DontDestroyOnLoad((Object)(object)Root);
			PerformPatches();
		}

		public void PerformPatches()
		{
			harmony.PatchAll(typeof(LetMeTameYou));
			harmony.PatchAll(typeof(InterceptFollow));
			harmony.PatchAll(typeof(TameManager));
			harmony.PatchAll(typeof(SpawnedHostilePatches));
			harmony.PatchAll(typeof(BetterTameHover));
			harmony.PatchAll(typeof(CfgPackage));
			harmony.PatchAll(typeof(CfgPackage.GameStartPatch));
			IEnumerable<MethodBase> patchedMethods = harmony.GetPatchedMethods();
			DBG.blogDebug("Patched Methods=");
			foreach (MethodBase item in patchedMethods)
			{
				DBG.blogDebug(item.ReflectedType?.ToString() + ":" + item.Name + " is patched");
			}
		}

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

		private ConfigEntry<T> config<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);
		}

		[HarmonyPatch(typeof(ZNetScene), "Shutdown")]
		[HarmonyPostfix]
		private static void Postfix()
		{
			DBG.blogInfo("Reseting TameLists");
			customTamesList.Clear();
			TameManager.resetTameManager();
			YAMLReadWrite.baseConfig = new TameConfig();
			YAMLReadWrite.groupConfigs = new Dictionary<string, YAMLReadWrite.TameConfigYML>();
			YAMLReadWrite.UseFileOpenReadTextWithSystemTextYaml();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(TMP_Text), "GetPreferredValues", new Type[]
		{
			typeof(float),
			typeof(float)
		})]
		private static void TMPro_TMP_Text_GetValues(TMP_Text __instance, ref Vector2 __result)
		{
			if (increaseHoverWidth.Value && ((Object)__instance).name == "HoverName")
			{
				__result.x *= 1.6f;
				DBG.blogDebug("Increasing hover with to " + __result.x);
			}
		}
	}
	public static class Utils
	{
		public static AssetBundle LoadAssetBundle(string bundleName, Assembly assembly)
		{
			string text = null;
			try
			{
				text = assembly.GetManifestResourceNames().Single((string str) => str.EndsWith(bundleName));
			}
			catch
			{
			}
			if (text == null)
			{
				DBG.blogWarning("Could not find asset by the name " + bundleName);
				return null;
			}
			Stream manifestResourceStream = assembly.GetManifestResourceStream(text);
			AssetBundle result;
			using (manifestResourceStream)
			{
				result = AssetBundle.LoadFromStream(manifestResourceStream);
			}
			return result;
		}

		public static T CopyBroComponent<T, TU>(this Component comp, TU other) where T : Component
		{
			Type baseType = ((object)comp).GetType().BaseType;
			IEnumerable<FieldInfo> fields = baseType.GetFields();
			foreach (FieldInfo item in fields)
			{
				object value = item.GetValue(other);
				try
				{
					item.SetValue(comp, value);
				}
				catch
				{
					DBG.blogDebug("Failed bro copy for: " + item);
				}
			}
			return (T)(object)((comp is T) ? comp : null);
		}

		public static string GetPrefabName(string name)
		{
			int num = name.IndexOfAny(new char[2] { '(', ' ' });
			if (num != -1)
			{
				return name.Remove(num);
			}
			return name;
		}

		public static bool addToZNS(GameObject go)
		{
			ZNetScene instance = ZNetScene.instance;
			if (!Object.op_Implicit((Object)(object)instance))
			{
				return false;
			}
			int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)go).name);
			if (instance.m_namedPrefabs.ContainsKey(stableHashCode))
			{
				DBG.blogDebug("ZNS already has " + ((Object)go).name);
				return false;
			}
			if (Object.op_Implicit((Object)(object)go.GetComponent<ZNetView>()))
			{
				instance.m_prefabs.Add(go);
			}
			else
			{
				instance.m_nonNetViewPrefabs.Add(go);
			}
			instance.m_namedPrefabs.Add(stableHashCode, go);
			DBG.blogDebug("Added " + ((Object)go).name + " to zns");
			return true;
		}

		public static bool addItemToODB(GameObject go, ObjectDB odb)
		{
			int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)go).name);
			if ((Object)(object)go.GetComponent<ItemDrop>() == (Object)null)
			{
				DBG.blogDebug("Does not have ItemDrop: " + ((Object)go).name);
				return false;
			}
			if (odb.m_itemByHash.ContainsKey(stableHashCode))
			{
				DBG.blogDebug("Already added item " + ((Object)go).name);
				return false;
			}
			addToZNS(go);
			odb.m_items.Add(go);
			odb.m_itemByHash.Add(stableHashCode, go);
			return true;
		}

		public static void cloneProperties<TOne, TTwo>(TOne copyTo, TTwo CopyFrom) where TOne : Component where TTwo : Component
		{
			FieldInfo[] fields = ((object)CopyFrom).GetType().GetFields();
			foreach (FieldInfo fieldInfo in fields)
			{
				try
				{
					if ((fieldInfo.GetValue(copyTo) != null) & (fieldInfo.GetValue(CopyFrom) != fieldInfo.GetValue(copyTo)))
					{
						fieldInfo.SetValue(copyTo, fieldInfo.GetValue(CopyFrom));
						DBG.blogDebug("From " + ((object)CopyFrom).GetType()?.ToString() + fieldInfo.Name + " set to " + fieldInfo.GetValue(copyTo));
					}
				}
				catch
				{
					DBG.blogDebug(((object)copyTo).GetType()?.ToString() + " does not have " + fieldInfo.Name);
				}
			}
		}

		public static Color colFromHex(string hexStr)
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				DBG.blogDebug("in colfromhex");
				int num = int.Parse(hexStr.Replace("#", ""), NumberStyles.HexNumber);
				float num2 = num & 0xFF;
				float num3 = (num >> 8) & 0xFF;
				float num4 = (num >> 16) & 0xFF;
				DBG.blogDebug("r,g,b=" + num4 + "," + num3 + "," + num2);
				Color result = default(Color);
				((Color)(ref result))..ctor(num4 / 255f, num3 / 255f, num2 / 255f);
				return result;
			}
			catch
			{
				DBG.blogWarning("Not a valid hex color code");
				return Color.white;
			}
		}

		public static Texture2D changeEggTex(Texture2D oldTex, Color col, bool invertShadow)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might