Decompiled source of PerfectPetTransit v0.0.63

PerfectPetTransit.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Splatform;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PerfectPetTransit")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.0.63.0")]
[assembly: AssemblyInformationalVersion("0.0.63")]
[assembly: AssemblyProduct("PerfectPetTransit")]
[assembly: AssemblyTitle("PerfectPetTransit")]
[assembly: AssemblyVersion("0.0.63.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PerfectPetTransit
{
	[BepInPlugin("perfect.pet.transit", "Perfect Pet Transit", "0.0.63")]
	public sealed class Plugin : BaseUnityPlugin
	{
		private sealed class Attachment
		{
			public Transform PreviousParent;

			public Rigidbody Body;

			public bool WasKinematic;

			public bool HadGravity;

			public RigidbodyConstraints PreviousConstraints;

			public Ship Ship;
		}

		private sealed class ColliderPair
		{
			public Collider Pet;

			public Collider Ship;
		}

		[HarmonyPatch]
		private static class SuppressCameraMouseLookWhileWheelOpenPatch
		{
			private static MethodBase TargetMethod()
			{
				Type type = AccessTools.TypeByName("GameCamera");
				if (!(type == null))
				{
					return AccessTools.Method(type, "UpdateCamera", (Type[])null, (Type[])null);
				}
				return null;
			}

			private static float CameraInputAxis(string axis)
			{
				if ((Object)(object)Instance != (Object)null && Instance.menuOpen)
				{
					switch (axis)
					{
					case "Mouse X":
					case "Mouse Y":
					case "MouseX":
					case "MouseY":
						return 0f;
					}
				}
				return Input.GetAxis(axis);
			}

			private static float CameraInputAxisRaw(string axis)
			{
				if ((Object)(object)Instance != (Object)null && Instance.menuOpen)
				{
					switch (axis)
					{
					case "Mouse X":
					case "Mouse Y":
					case "MouseX":
					case "MouseY":
						return 0f;
					}
				}
				return Input.GetAxisRaw(axis);
			}

			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				MethodInfo getAxis = AccessTools.Method(typeof(Input), "GetAxis", new Type[1] { typeof(string) }, (Type[])null);
				MethodInfo getAxisRaw = AccessTools.Method(typeof(Input), "GetAxisRaw", new Type[1] { typeof(string) }, (Type[])null);
				MethodInfo replaceAxis = AccessTools.Method(typeof(SuppressCameraMouseLookWhileWheelOpenPatch), "CameraInputAxis", (Type[])null, (Type[])null);
				MethodInfo replaceRaw = AccessTools.Method(typeof(SuppressCameraMouseLookWhileWheelOpenPatch), "CameraInputAxisRaw", (Type[])null, (Type[])null);
				foreach (CodeInstruction instruction in instructions)
				{
					if (CodeInstructionExtensions.Calls(instruction, getAxis))
					{
						instruction.operand = replaceAxis;
					}
					else if (CodeInstructionExtensions.Calls(instruction, getAxisRaw))
					{
						instruction.operand = replaceRaw;
					}
					yield return instruction;
				}
			}
		}

		[HarmonyPatch]
		private static class BlockWheelAttackPatch
		{
			private static MethodBase TargetMethod()
			{
				MethodInfo[] methods = typeof(Humanoid).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.Name == "StartAttack" && methodInfo.ReturnType == typeof(bool))
					{
						return methodInfo;
					}
				}
				return null;
			}

			private static bool Prefix(Humanoid __instance, ref bool __result)
			{
				if ((Object)(object)Instance != (Object)null && (Instance.menuOpen || Time.frameCount <= Instance.suppressMenuUntilFrame) && (Object)(object)__instance == (Object)(object)Player.m_localPlayer)
				{
					__result = false;
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch]
		private static class BlockPlayerAttackInputPatch
		{
			private static IEnumerable<MethodBase> TargetMethods()
			{
				MethodInfo[] methods = typeof(Player).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.Name.IndexOf("Attack", StringComparison.OrdinalIgnoreCase) >= 0 && !(methodInfo.Name == "StartAttack") && !methodInfo.IsAbstract && !methodInfo.ContainsGenericParameters && methodInfo.ReturnType == typeof(void))
					{
						yield return methodInfo;
					}
				}
			}

			private static bool Prefix(Player __instance)
			{
				if (!((Object)(object)Instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
				{
					if (!Instance.menuOpen)
					{
						return Time.frameCount > Instance.suppressMenuUntilFrame;
					}
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch]
		private static class BlockGameMenuPatch
		{
			private static MethodBase TargetMethod()
			{
				Type type = AccessTools.TypeByName("Menu");
				if (!(type == null))
				{
					return AccessTools.Method(type, "Update", (Type[])null, (Type[])null);
				}
				return null;
			}

			private static bool Prefix()
			{
				if (!((Object)(object)Instance == (Object)null))
				{
					if (!Instance.menuOpen)
					{
						return Time.frameCount > Instance.suppressMenuUntilFrame;
					}
					return false;
				}
				return true;
			}
		}

		private struct DeckLayout
		{
			public float Side;

			public float[] Rows;

			public float Spacing;

			public DeckLayout(float side, float spacing, params float[] rows)
			{
				Side = side;
				Spacing = spacing;
				Rows = rows;
			}
		}

		[HarmonyPatch(typeof(Tameable), "GetHoverText")]
		private static class TameableHoverPatch
		{
			private static void Postfix(Tameable __instance, ref string __result)
			{
				if ((Object)(object)Instance != (Object)null && Instance.menuOpen)
				{
					__result = "";
					return;
				}
				Character component = ((Component)__instance).GetComponent<Character>();
				if (!Object.op_Implicit((Object)(object)component) || !component.IsTamed() || Weight(PrefabName(((Component)component).gameObject)) < 0)
				{
					return;
				}
				string[] array = (__result ?? "").Split('\n');
				List<string> list = new List<string>();
				string[] array2 = array;
				foreach (string text in array2)
				{
					if (text.IndexOf("Shift", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Alt", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Посадить", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Высадить", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Следовать", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Оставаться", StringComparison.OrdinalIgnoreCase) < 0 && (text.IndexOf("[E]", StringComparison.OrdinalIgnoreCase) >= 0 || list.Count == 0))
					{
						list.Add(text);
					}
				}
				if (list.Count == 0)
				{
					list.Add(PrefabName(((Component)component).gameObject));
				}
				list.RemoveAll((string line) => line.IndexOf("[E]", StringComparison.OrdinalIgnoreCase) >= 0);
				ZNetView component2 = ((Component)component).GetComponent<ZNetView>();
				bool flag = Object.op_Implicit((Object)(object)component2) && component2.IsValid() && component2.GetZDO().GetBool("ppt_follow", false);
				string text2 = ((PrefabName(((Component)component).gameObject) == "Boar") ? Tr("Приласкать") : (flag ? Tr("Стоять") : Tr("Следовать")));
				__result = string.Join("\n", list.ToArray()) + "\n[<color=yellow>E</color>] " + text2 + "\n[<color=yellow>Shift + E</color>] " + Tr("Меню взаимодействия");
			}
		}

		[HarmonyPatch(typeof(Tameable), "Interact")]
		private static class TameableInteractPatch
		{
			private static bool Prefix(Tameable __instance, Humanoid user, bool hold, bool alt, ref bool __result)
			{
				if ((Object)(object)Instance == (Object)null || Instance.nativeRenameInProgress)
				{
					return true;
				}
				Character component = ((Component)__instance).GetComponent<Character>();
				if (!Object.op_Implicit((Object)(object)component) || !component.IsTamed() || Weight(PrefabName(((Component)component).gameObject)) < 0)
				{
					return true;
				}
				if (alt || Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303))
				{
					if (!hold)
					{
						Instance.OpenPetMenu(component);
					}
					__result = true;
					return false;
				}
				if (!hold && (IsRideable(component) || PrefabName(((Component)component).gameObject) == "Wolf"))
				{
					ZNetView component2 = ((Component)component).GetComponent<ZNetView>();
					if (Object.op_Implicit((Object)(object)component2) && component2.IsValid())
					{
						Instance.SetFollow(component, !component2.GetZDO().GetBool("ppt_follow", false));
					}
					__result = true;
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(BaseAI), "UpdateAI")]
		private static class SuppressTetheredAI
		{
			private static bool Prefix(BaseAI __instance)
			{
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
				if (Object.op_Implicit((Object)(object)component) && component.IsValid())
				{
					ZDOID zDOID = component.GetZDO().GetZDOID("ppt_ship");
					return ((ZDOID)(ref zDOID)).Equals(ZDOID.None);
				}
				return true;
			}
		}

		private static readonly Dictionary<string, Dictionary<string, string>> Translations = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase)
		{
			{
				"English",
				new Dictionary<string, string>
				{
					{ "Следуй за мной", "Follow me" },
					{ "Надеть седло", "Equip saddle" },
					{ "Закрыть", "Close" },
					{ "Переименовать", "Rename" },
					{ "Посадить на корабль", "Board ship" },
					{ "Стой на месте", "Stay here" },
					{ "Спустить с корабля", "Disembark" },
					{ "Снять седло", "Remove saddle" },
					{ "Голоден", "Hungry" },
					{ "Сыт", "Fed" },
					{ "Приручен", "Tamed" },
					{ "Беременность", "Pregnant" },
					{ "Приласкать", "Pet" },
					{ "Стоять", "Stay" },
					{ "Следовать", "Follow" },
					{ "Меню взаимодействия", "Interaction menu" },
					{ "Не найден компонент седла", "Saddle component not found" },
					{ "Невозможно снять седло: API игры изменился", "Cannot remove saddle: game API changed" },
					{ "В инвентаре нет подходящего седла", "No suitable saddle in inventory" },
					{ "Невозможно надеть седло: API игры изменился", "Cannot equip saddle: game API changed" },
					{ "Не удалось надеть седло", "Failed to equip saddle" },
					{ "Ошибка седла — см. BepInEx LogOutput.log", "Saddle error — see BepInEx LogOutput.log" },
					{ "Не удалось открыть стандартное переименование — см. лог", "Could not open vanilla rename — see log" },
					{ "Питомец не найден. Подойдите ближе и наведитесь на животное", "Pet not found. Move closer and aim at the animal" },
					{ "Животное не приручено", "Animal is not tamed" },
					{ "Нет безопасного берега для высадки", "No safe shore for disembarking" },
					{ "Питомец высажен на берег", "Pet disembarked ashore" },
					{ "Рядом нет подходящего корабля", "No suitable ship nearby" },
					{ "Это животное нельзя перевозить на данном корабле", "This animal cannot travel on this ship" },
					{ "На корабле недостаточно места", "Not enough room on the ship" },
					{ "Не удалось найти место на палубе", "Could not find room on deck" },
					{ "Питомец привязан к мачте", "Pet secured to the mast" },
					{ "Наведитесь на приручённого питомца", "Aim at a tamed pet" },
					{ "Сначала высадите питомца с корабля", "Disembark the pet first" },
					{ "Питомец следует за вами", "Pet is following you" },
					{ "Питомец остаётся на месте", "Pet is staying here" }
				}
			},
			{
				"German",
				new Dictionary<string, string>
				{
					{ "Следуй за мной", "Folge mir" },
					{ "Надеть седло", "Sattel anlegen" },
					{ "Закрыть", "Schließen" },
					{ "Переименовать", "Umbenennen" },
					{ "Посадить на корабль", "Auf Schiff bringen" },
					{ "Стой на месте", "Hier bleiben" },
					{ "Спустить с корабля", "Von Bord bringen" },
					{ "Снять седло", "Sattel abnehmen" },
					{ "Голоден", "Hungrig" },
					{ "Сыт", "Satt" },
					{ "Приручен", "Gezähmt" },
					{ "Беременность", "Trächtig" },
					{ "Приласкать", "Streicheln" },
					{ "Стоять", "Bleiben" },
					{ "Следовать", "Folgen" },
					{ "Меню взаимодействия", "Interaktionsmenü" },
					{ "Не найден компонент седла", "Saddle component not found" },
					{ "Невозможно снять седло: API игры изменился", "Cannot remove saddle: game API changed" },
					{ "В инвентаре нет подходящего седла", "No suitable saddle in inventory" },
					{ "Невозможно надеть седло: API игры изменился", "Cannot equip saddle: game API changed" },
					{ "Не удалось надеть седло", "Failed to equip saddle" },
					{ "Ошибка седла — см. BepInEx LogOutput.log", "Saddle error — see BepInEx LogOutput.log" },
					{ "Не удалось открыть стандартное переименование — см. лог", "Could not open vanilla rename — see log" },
					{ "Питомец не найден. Подойдите ближе и наведитесь на животное", "Pet not found. Move closer and aim at the animal" },
					{ "Животное не приручено", "Animal is not tamed" },
					{ "Нет безопасного берега для высадки", "No safe shore for disembarking" },
					{ "Питомец высажен на берег", "Pet disembarked ashore" },
					{ "Рядом нет подходящего корабля", "No suitable ship nearby" },
					{ "Это животное нельзя перевозить на данном корабле", "This animal cannot travel on this ship" },
					{ "На корабле недостаточно места", "Not enough room on the ship" },
					{ "Не удалось найти место на палубе", "Could not find room on deck" },
					{ "Питомец привязан к мачте", "Pet secured to the mast" },
					{ "Наведитесь на приручённого питомца", "Aim at a tamed pet" },
					{ "Сначала высадите питомца с корабля", "Disembark the pet first" },
					{ "Питомец следует за вами", "Pet is following you" },
					{ "Питомец остаётся на месте", "Pet is staying here" }
				}
			},
			{
				"French",
				new Dictionary<string, string>
				{
					{ "Следуй за мной", "Suis-moi" },
					{ "Надеть седло", "Mettre la selle" },
					{ "Закрыть", "Fermer" },
					{ "Переименовать", "Renommer" },
					{ "Посадить на корабль", "Embarquer" },
					{ "Стой на месте", "Reste ici" },
					{ "Спустить с корабля", "Débarquer" },
					{ "Снять седло", "Retirer la selle" },
					{ "Голоден", "Affamé" },
					{ "Сыт", "Rassasié" },
					{ "Приручен", "Apprivoisé" },
					{ "Беременность", "Gestation" },
					{ "Приласкать", "Caresser" },
					{ "Стоять", "Rester" },
					{ "Следовать", "Suivre" },
					{ "Меню взаимодействия", "Menu d’interaction" },
					{ "Не найден компонент седла", "Saddle component not found" },
					{ "Невозможно снять седло: API игры изменился", "Cannot remove saddle: game API changed" },
					{ "В инвентаре нет подходящего седла", "No suitable saddle in inventory" },
					{ "Невозможно надеть седло: API игры изменился", "Cannot equip saddle: game API changed" },
					{ "Не удалось надеть седло", "Failed to equip saddle" },
					{ "Ошибка седла — см. BepInEx LogOutput.log", "Saddle error — see BepInEx LogOutput.log" },
					{ "Не удалось открыть стандартное переименование — см. лог", "Could not open vanilla rename — see log" },
					{ "Питомец не найден. Подойдите ближе и наведитесь на животное", "Pet not found. Move closer and aim at the animal" },
					{ "Животное не приручено", "Animal is not tamed" },
					{ "Нет безопасного берега для высадки", "No safe shore for disembarking" },
					{ "Питомец высажен на берег", "Pet disembarked ashore" },
					{ "Рядом нет подходящего корабля", "No suitable ship nearby" },
					{ "Это животное нельзя перевозить на данном корабле", "This animal cannot travel on this ship" },
					{ "На корабле недостаточно места", "Not enough room on the ship" },
					{ "Не удалось найти место на палубе", "Could not find room on deck" },
					{ "Питомец привязан к мачте", "Pet secured to the mast" },
					{ "Наведитесь на приручённого питомца", "Aim at a tamed pet" },
					{ "Сначала высадите питомца с корабля", "Disembark the pet first" },
					{ "Питомец следует за вами", "Pet is following you" },
					{ "Питомец остаётся на месте", "Pet is staying here" }
				}
			},
			{
				"Spanish",
				new Dictionary<string, string>
				{
					{ "Следуй за мной", "Sígueme" },
					{ "Надеть седло", "Poner silla" },
					{ "Закрыть", "Cerrar" },
					{ "Переименовать", "Renombrar" },
					{ "Посадить на корабль", "Embarcar" },
					{ "Стой на месте", "Quédate aquí" },
					{ "Спустить с корабля", "Desembarcar" },
					{ "Снять седло", "Quitar silla" },
					{ "Голоден", "Hambriento" },
					{ "Сыт", "Saciado" },
					{ "Приручен", "Domesticado" },
					{ "Беременность", "Embarazo" },
					{ "Приласкать", "Acariciar" },
					{ "Стоять", "Quedarse" },
					{ "Следовать", "Seguir" },
					{ "Меню взаимодействия", "Menú de interacción" },
					{ "Не найден компонент седла", "Saddle component not found" },
					{ "Невозможно снять седло: API игры изменился", "Cannot remove saddle: game API changed" },
					{ "В инвентаре нет подходящего седла", "No suitable saddle in inventory" },
					{ "Невозможно надеть седло: API игры изменился", "Cannot equip saddle: game API changed" },
					{ "Не удалось надеть седло", "Failed to equip saddle" },
					{ "Ошибка седла — см. BepInEx LogOutput.log", "Saddle error — see BepInEx LogOutput.log" },
					{ "Не удалось открыть стандартное переименование — см. лог", "Could not open vanilla rename — see log" },
					{ "Питомец не найден. Подойдите ближе и наведитесь на животное", "Pet not found. Move closer and aim at the animal" },
					{ "Животное не приручено", "Animal is not tamed" },
					{ "Нет безопасного берега для высадки", "No safe shore for disembarking" },
					{ "Питомец высажен на берег", "Pet disembarked ashore" },
					{ "Рядом нет подходящего корабля", "No suitable ship nearby" },
					{ "Это животное нельзя перевозить на данном корабле", "This animal cannot travel on this ship" },
					{ "На корабле недостаточно места", "Not enough room on the ship" },
					{ "Не удалось найти место на палубе", "Could not find room on deck" },
					{ "Питомец привязан к мачте", "Pet secured to the mast" },
					{ "Наведитесь на приручённого питомца", "Aim at a tamed pet" },
					{ "Сначала высадите питомца с корабля", "Disembark the pet first" },
					{ "Питомец следует за вами", "Pet is following you" },
					{ "Питомец остаётся на месте", "Pet is staying here" }
				}
			},
			{
				"Italian",
				new Dictionary<string, string>
				{
					{ "Следуй за мной", "Seguimi" },
					{ "Надеть седло", "Metti la sella" },
					{ "Закрыть", "Chiudi" },
					{ "Переименовать", "Rinomina" },
					{ "Посадить на корабль", "Imbarca" },
					{ "Стой на месте", "Resta qui" },
					{ "Спустить с корабля", "Sbarca" },
					{ "Снять седло", "Togli la sella" },
					{ "Голоден", "Affamato" },
					{ "Сыт", "Sazio" },
					{ "Приручен", "Addomesticato" },
					{ "Беременность", "Gravidanza" },
					{ "Приласкать", "Accarezza" },
					{ "Стоять", "Resta" },
					{ "Следовать", "Segui" },
					{ "Меню взаимодействия", "Menu interazione" },
					{ "Не найден компонент седла", "Saddle component not found" },
					{ "Невозможно снять седло: API игры изменился", "Cannot remove saddle: game API changed" },
					{ "В инвентаре нет подходящего седла", "No suitable saddle in inventory" },
					{ "Невозможно надеть седло: API игры изменился", "Cannot equip saddle: game API changed" },
					{ "Не удалось надеть седло", "Failed to equip saddle" },
					{ "Ошибка седла — см. BepInEx LogOutput.log", "Saddle error — see BepInEx LogOutput.log" },
					{ "Не удалось открыть стандартное переименование — см. лог", "Could not open vanilla rename — see log" },
					{ "Питомец не найден. Подойдите ближе и наведитесь на животное", "Pet not found. Move closer and aim at the animal" },
					{ "Животное не приручено", "Animal is not tamed" },
					{ "Нет безопасного берега для высадки", "No safe shore for disembarking" },
					{ "Питомец высажен на берег", "Pet disembarked ashore" },
					{ "Рядом нет подходящего корабля", "No suitable ship nearby" },
					{ "Это животное нельзя перевозить на данном корабле", "This animal cannot travel on this ship" },
					{ "На корабле недостаточно места", "Not enough room on the ship" },
					{ "Не удалось найти место на палубе", "Could not find room on deck" },
					{ "Питомец привязан к мачте", "Pet secured to the mast" },
					{ "Наведитесь на приручённого питомца", "Aim at a tamed pet" },
					{ "Сначала высадите питомца с корабля", "Disembark the pet first" },
					{ "Питомец следует за вами", "Pet is following you" },
					{ "Питомец остаётся на месте", "Pet is staying here" }
				}
			},
			{
				"Portuguese",
				new Dictionary<string, string>
				{
					{ "Следуй за мной", "Segue-me" },
					{ "Надеть седло", "Equipar sela" },
					{ "Закрыть", "Fechar" },
					{ "Переименовать", "Renomear" },
					{ "Посадить на корабль", "Embarcar" },
					{ "Стой на месте", "Fica aqui" },
					{ "Спустить с корабля", "Desembarcar" },
					{ "Снять седло", "Remover sela" },
					{ "Голоден", "Com fome" },
					{ "Сыт", "Saciado" },
					{ "Приручен", "Domesticado" },
					{ "Беременность", "Gravidez" },
					{ "Приласкать", "Acariciar" },
					{ "Стоять", "Ficar" },
					{ "Следовать", "Seguir" },
					{ "Меню взаимодействия", "Menu de interação" },
					{ "Не найден компонент седла", "Saddle component not found" },
					{ "Невозможно снять седло: API игры изменился", "Cannot remove saddle: game API changed" },
					{ "В инвентаре нет подходящего седла", "No suitable saddle in inventory" },
					{ "Невозможно надеть седло: API игры изменился", "Cannot equip saddle: game API changed" },
					{ "Не удалось надеть седло", "Failed to equip saddle" },
					{ "Ошибка седла — см. BepInEx LogOutput.log", "Saddle error — see BepInEx LogOutput.log" },
					{ "Не удалось открыть стандартное переименование — см. лог", "Could not open vanilla rename — see log" },
					{ "Питомец не найден. Подойдите ближе и наведитесь на животное", "Pet not found. Move closer and aim at the animal" },
					{ "Животное не приручено", "Animal is not tamed" },
					{ "Нет безопасного берега для высадки", "No safe shore for disembarking" },
					{ "Питомец высажен на берег", "Pet disembarked ashore" },
					{ "Рядом нет подходящего корабля", "No suitable ship nearby" },
					{ "Это животное нельзя перевозить на данном корабле", "This animal cannot travel on this ship" },
					{ "На корабле недостаточно места", "Not enough room on the ship" },
					{ "Не удалось найти место на палубе", "Could not find room on deck" },
					{ "Питомец привязан к мачте", "Pet secured to the mast" },
					{ "Наведитесь на приручённого питомца", "Aim at a tamed pet" },
					{ "Сначала высадите питомца с корабля", "Disembark the pet first" },
					{ "Питомец следует за вами", "Pet is following you" },
					{ "Питомец остаётся на месте", "Pet is staying here" }
				}
			},
			{
				"Brazilian",
				new Dictionary<string, string>
				{
					{ "Следуй за мной", "Siga-me" },
					{ "Надеть седло", "Equipar sela" },
					{ "Закрыть", "Fechar" },
					{ "Переименовать", "Renomear" },
					{ "Посадить на корабль", "Embarcar" },
					{ "Стой на месте", "Fique aqui" },
					{ "Спустить с корабля", "Desembarcar" },
					{ "Снять седло", "Remover sela" },
					{ "Голоден", "Faminto" },
					{ "Сыт", "Satisfeito" },
					{ "Приручен", "Domesticado" },
					{ "Беременность", "Gravidez" },
					{ "Приласкать", "Acariciar" },
					{ "Стоять", "Ficar" },
					{ "Следовать", "Seguir" },
					{ "Меню взаимодействия", "Menu de interação" },
					{ "Не найден компонент седла", "Saddle component not found" },
					{ "Невозможно снять седло: API игры изменился", "Cannot remove saddle: game API changed" },
					{ "В инвентаре нет подходящего седла", "No suitable saddle in inventory" },
					{ "Невозможно надеть седло: API игры изменился", "Cannot equip saddle: game API changed" },
					{ "Не удалось надеть седло", "Failed to equip saddle" },
					{ "Ошибка седла — см. BepInEx LogOutput.log", "Saddle error — see BepInEx LogOutput.log" },
					{ "Не удалось открыть стандартное переименование — см. лог", "Could not open vanilla rename — see log" },
					{ "Питомец не найден. Подойдите ближе и наведитесь на животное", "Pet not found. Move closer and aim at the animal" },
					{ "Животное не приручено", "Animal is not tamed" },
					{ "Нет безопасного берега для высадки", "No safe shore for disembarking" },
					{ "Питомец высажен на берег", "Pet disembarked ashore" },
					{ "Рядом нет подходящего корабля", "No suitable ship nearby" },
					{ "Это животное нельзя перевозить на данном корабле", "This animal cannot travel on this ship" },
					{ "На корабле недостаточно места", "Not enough room on the ship" },
					{ "Не удалось найти место на палубе", "Could not find room on deck" },
					{ "Питомец привязан к мачте", "Pet secured to the mast" },
					{ "Наведитесь на приручённого питомца", "Aim at a tamed pet" },
					{ "Сначала высадите питомца с корабля", "Disembark the pet first" },
					{ "Питомец следует за вами", "Pet is following you" },
					{ "Питомец остаётся на месте", "Pet is staying here" }
				}
			},
			{
				"Polish",
				new Dictionary<string, string>
				{
					{ "Следуй за мной", "Chodź za mną" },
					{ "Надеть седло", "Załóż siodło" },
					{ "Закрыть", "Zamknij" },
					{ "Переименовать", "Zmień nazwę" },
					{ "Посадить на корабль", "Wejdź na statek" },
					{ "Стой на месте", "Zostań tutaj" },
					{ "Спустить с корабля", "Zejdź ze statku" },
					{ "Снять седло", "Zdejmij siodło" },
					{ "Голоден", "Głodny" },
					{ "Сыт", "Najedzony" },
					{ "Приручен", "Oswojony" },
					{ "Беременность", "Ciąża" },
					{ "Приласкать", "Pogłaszcz" },
					{ "Стоять", "Zostań" },
					{ "Следовать", "Podążaj" },
					{ "Меню взаимодействия", "Menu interakcji" },
					{ "Не найден компонент седла", "Saddle component not found" },
					{ "Невозможно снять седло: API игры изменился", "Cannot remove saddle: game API changed" },
					{ "В инвентаре нет подходящего седла", "No suitable saddle in inventory" },
					{ "Невозможно надеть седло: API игры изменился", "Cannot equip saddle: game API changed" },
					{ "Не удалось надеть седло", "Failed to equip saddle" },
					{ "Ошибка седла — см. BepInEx LogOutput.log", "Saddle error — see BepInEx LogOutput.log" },
					{ "Не удалось открыть стандартное переименование — см. лог", "Could not open vanilla rename — see log" },
					{ "Питомец не найден. Подойдите ближе и наведитесь на животное", "Pet not found. Move closer and aim at the animal" },
					{ "Животное не приручено", "Animal is not tamed" },
					{ "Нет безопасного берега для высадки", "No safe shore for disembarking" },
					{ "Питомец высажен на берег", "Pet disembarked ashore" },
					{ "Рядом нет подходящего корабля", "No suitable ship nearby" },
					{ "Это животное нельзя перевозить на данном корабле", "This animal cannot travel on this ship" },
					{ "На корабле недостаточно места", "Not enough room on the ship" },
					{ "Не удалось найти место на палубе", "Could not find room on deck" },
					{ "Питомец привязан к мачте", "Pet secured to the mast" },
					{ "Наведитесь на приручённого питомца", "Aim at a tamed pet" },
					{ "Сначала высадите питомца с корабля", "Disembark the pet first" },
					{ "Питомец следует за вами", "Pet is following you" },
					{ "Питомец остаётся на месте", "Pet is staying here" }
				}
			},
			{
				"Ukrainian",
				new Dictionary<string, string>
				{
					{ "Следуй за мной", "Іди за мною" },
					{ "Надеть седло", "Одягнути сідло" },
					{ "Закрыть", "Закрити" },
					{ "Переименовать", "Перейменувати" },
					{ "Посадить на корабль", "Посадити на корабель" },
					{ "Стой на месте", "Залишайся тут" },
					{ "Спустить с корабля", "Висадити з корабля" },
					{ "Снять седло", "Зняти сідло" },
					{ "Голоден", "Голодний" },
					{ "Сыт", "Ситий" },
					{ "Приручен", "Приручений" },
					{ "Беременность", "Вагітність" },
					{ "Приласкать", "Погладити" },
					{ "Стоять", "Стояти" },
					{ "Следовать", "Слідувати" },
					{ "Меню взаимодействия", "Меню взаємодії" },
					{ "Не найден компонент седла", "Saddle component not found" },
					{ "Невозможно снять седло: API игры изменился", "Cannot remove saddle: game API changed" },
					{ "В инвентаре нет подходящего седла", "No suitable saddle in inventory" },
					{ "Невозможно надеть седло: API игры изменился", "Cannot equip saddle: game API changed" },
					{ "Не удалось надеть седло", "Failed to equip saddle" },
					{ "Ошибка седла — см. BepInEx LogOutput.log", "Saddle error — see BepInEx LogOutput.log" },
					{ "Не удалось открыть стандартное переименование — см. лог", "Could not open vanilla rename — see log" },
					{ "Питомец не найден. Подойдите ближе и наведитесь на животное", "Pet not found. Move closer and aim at the animal" },
					{ "Животное не приручено", "Animal is not tamed" },
					{ "Нет безопасного берега для высадки", "No safe shore for disembarking" },
					{ "Питомец высажен на берег", "Pet disembarked ashore" },
					{ "Рядом нет подходящего корабля", "No suitable ship nearby" },
					{ "Это животное нельзя перевозить на данном корабле", "This animal cannot travel on this ship" },
					{ "На корабле недостаточно места", "Not enough room on the ship" },
					{ "Не удалось найти место на палубе", "Could not find room on deck" },
					{ "Питомец привязан к мачте", "Pet secured to the mast" },
					{ "Наведитесь на приручённого питомца", "Aim at a tamed pet" },
					{ "Сначала высадите питомца с корабля", "Disembark the pet first" },
					{ "Питомец следует за вами", "Pet is following you" },
					{ "Питомец остаётся на месте", "Pet is staying here" }
				}
			},
			{
				"Swedish",
				new Dictionary<string, string>
				{
					{ "Следуй за мной", "Följ mig" },
					{ "Надеть седло", "Sätt på sadel" },
					{ "Закрыть", "Stäng" },
					{ "Переименовать", "Byt namn" },
					{ "Посадить на корабль", "Gå ombord" },
					{ "Стой на месте", "Stanna här" },
					{ "Спустить с корабля", "Gå i land" },
					{ "Снять седло", "Ta av sadel" },
					{ "Голоден", "Hungrig" },
					{ "Сыт", "Mätt" },
					{ "Приручен", "Tam" },
					{ "Беременность", "Dräktig" },
					{ "Приласкать", "Klappa" },
					{ "Стоять", "Stanna" },
					{ "Следовать", "Följ" },
					{ "Меню взаимодействия", "Interaktionsmeny" },
					{ "Не найден компонент седла", "Saddle component not found" },
					{ "Невозможно снять седло: API игры изменился", "Cannot remove saddle: game API changed" },
					{ "В инвентаре нет подходящего седла", "No suitable saddle in inventory" },
					{ "Невозможно надеть седло: API игры изменился", "Cannot equip saddle: game API changed" },
					{ "Не удалось надеть седло", "Failed to equip saddle" },
					{ "Ошибка седла — см. BepInEx LogOutput.log", "Saddle error — see BepInEx LogOutput.log" },
					{ "Не удалось открыть стандартное переименование — см. лог", "Could not open vanilla rename — see log" },
					{ "Питомец не найден. Подойдите ближе и наведитесь на животное", "Pet not found. Move closer and aim at the animal" },
					{ "Животное не приручено", "Animal is not tamed" },
					{ "Нет безопасного берега для высадки", "No safe shore for disembarking" },
					{ "Питомец высажен на берег", "Pet disembarked ashore" },
					{ "Рядом нет подходящего корабля", "No suitable ship nearby" },
					{ "Это животное нельзя перевозить на данном корабле", "This animal cannot travel on this ship" },
					{ "На корабле недостаточно места", "Not enough room on the ship" },
					{ "Не удалось найти место на палубе", "Could not find room on deck" },
					{ "Питомец привязан к мачте", "Pet secured to the mast" },
					{ "Наведитесь на приручённого питомца", "Aim at a tamed pet" },
					{ "Сначала высадите питомца с корабля", "Disembark the pet first" },
					{ "Питомец следует за вами", "Pet is following you" },
					{ "Питомец остаётся на месте", "Pet is staying here" }
				}
			},
			{
				"Dutch",
				new Dictionary<string, string>
				{
					{ "Следуй за мной", "Volg mij" },
					{ "Надеть седло", "Zadel omdoen" },
					{ "Закрыть", "Sluiten" },
					{ "Переименовать", "Hernoemen" },
					{ "Посадить на корабль", "Aan boord" },
					{ "Стой на месте", "Blijf hier" },
					{ "Спустить с корабля", "Van boord" },
					{ "Снять седло", "Zadel afdoen" },
					{ "Голоден", "Hongerig" },
					{ "Сыт", "Verzadigd" },
					{ "Приручен", "Getemd" },
					{ "Беременность", "Drachtig" },
					{ "Приласкать", "Aaien" },
					{ "Стоять", "Blijven" },
					{ "Следовать", "Volgen" },
					{ "Меню взаимодействия", "Interactiemenu" },
					{ "Не найден компонент седла", "Saddle component not found" },
					{ "Невозможно снять седло: API игры изменился", "Cannot remove saddle: game API changed" },
					{ "В инвентаре нет подходящего седла", "No suitable saddle in inventory" },
					{ "Невозможно надеть седло: API игры изменился", "Cannot equip saddle: game API changed" },
					{ "Не удалось надеть седло", "Failed to equip saddle" },
					{ "Ошибка седла — см. BepInEx LogOutput.log", "Saddle error — see BepInEx LogOutput.log" },
					{ "Не удалось открыть стандартное переименование — см. лог", "Could not open vanilla rename — see log" },
					{ "Питомец не найден. Подойдите ближе и наведитесь на животное", "Pet not found. Move closer and aim at the animal" },
					{ "Животное не приручено", "Animal is not tamed" },
					{ "Нет безопасного берега для высадки", "No safe shore for disembarking" },
					{ "Питомец высажен на берег", "Pet disembarked ashore" },
					{ "Рядом нет подходящего корабля", "No suitable ship nearby" },
					{ "Это животное нельзя перевозить на данном корабле", "This animal cannot travel on this ship" },
					{ "На корабле недостаточно места", "Not enough room on the ship" },
					{ "Не удалось найти место на палубе", "Could not find room on deck" },
					{ "Питомец привязан к мачте", "Pet secured to the mast" },
					{ "Наведитесь на приручённого питомца", "Aim at a tamed pet" },
					{ "Сначала высадите питомца с корабля", "Disembark the pet first" },
					{ "Питомец следует за вами", "Pet is following you" },
					{ "Питомец остаётся на месте", "Pet is staying here" }
				}
			},
			{
				"Japanese",
				new Dictionary<string, string>
				{
					{ "Следуй за мной", "ついてきて" },
					{ "Надеть седло", "鞍を装備" },
					{ "Закрыть", "閉じる" },
					{ "Переименовать", "名前を変更" },
					{ "Посадить на корабль", "船に乗せる" },
					{ "Стой на месте", "ここで待て" },
					{ "Спустить с корабля", "船から降ろす" },
					{ "Снять седло", "鞍を外す" },
					{ "Голоден", "空腹" },
					{ "Сыт", "満腹" },
					{ "Приручен", "手なずけ済み" },
					{ "Беременность", "妊娠中" },
					{ "Приласкать", "なでる" },
					{ "Стоять", "待機" },
					{ "Следовать", "追従" },
					{ "Меню взаимодействия", "操作メニュー" },
					{ "Не найден компонент седла", "Saddle component not found" },
					{ "Невозможно снять седло: API игры изменился", "Cannot remove saddle: game API changed" },
					{ "В инвентаре нет подходящего седла", "No suitable saddle in inventory" },
					{ "Невозможно надеть седло: API игры изменился", "Cannot equip saddle: game API changed" },
					{ "Не удалось надеть седло", "Failed to equip saddle" },
					{ "Ошибка седла — см. BepInEx LogOutput.log", "Saddle error — see BepInEx LogOutput.log" },
					{ "Не удалось открыть стандартное переименование — см. лог", "Could not open vanilla rename — see log" },
					{ "Питомец не найден. Подойдите ближе и наведитесь на животное", "Pet not found. Move closer and aim at the animal" },
					{ "Животное не приручено", "Animal is not tamed" },
					{ "Нет безопасного берега для высадки", "No safe shore for disembarking" },
					{ "Питомец высажен на берег", "Pet disembarked ashore" },
					{ "Рядом нет подходящего корабля", "No suitable ship nearby" },
					{ "Это животное нельзя перевозить на данном корабле", "This animal cannot travel on this ship" },
					{ "На корабле недостаточно места", "Not enough room on the ship" },
					{ "Не удалось найти место на палубе", "Could not find room on deck" },
					{ "Питомец привязан к мачте", "Pet secured to the mast" },
					{ "Наведитесь на приручённого питомца", "Aim at a tamed pet" },
					{ "Сначала высадите питомца с корабля", "Disembark the pet first" },
					{ "Питомец следует за вами", "Pet is following you" },
					{ "Питомец остаётся на месте", "Pet is staying here" }
				}
			},
			{
				"Korean",
				new Dictionary<string, string>
				{
					{ "Следуй за мной", "따라와" },
					{ "Надеть седло", "안장 장착" },
					{ "Закрыть", "닫기" },
					{ "Переименовать", "이름 변경" },
					{ "Посадить на корабль", "배에 태우기" },
					{ "Стой на месте", "여기 있어" },
					{ "Спустить с корабля", "배에서 내리기" },
					{ "Снять седло", "안장 제거" },
					{ "Голоден", "배고픔" },
					{ "Сыт", "배부름" },
					{ "Приручен", "길들여짐" },
					{ "Беременность", "임신" },
					{ "Приласкать", "쓰다듬기" },
					{ "Стоять", "대기" },
					{ "Следовать", "따르기" },
					{ "Меню взаимодействия", "상호작용 메뉴" },
					{ "Не найден компонент седла", "Saddle component not found" },
					{ "Невозможно снять седло: API игры изменился", "Cannot remove saddle: game API changed" },
					{ "В инвентаре нет подходящего седла", "No suitable saddle in inventory" },
					{ "Невозможно надеть седло: API игры изменился", "Cannot equip saddle: game API changed" },
					{ "Не удалось надеть седло", "Failed to equip saddle" },
					{ "Ошибка седла — см. BepInEx LogOutput.log", "Saddle error — see BepInEx LogOutput.log" },
					{ "Не удалось открыть стандартное переименование — см. лог", "Could not open vanilla rename — see log" },
					{ "Питомец не найден. Подойдите ближе и наведитесь на животное", "Pet not found. Move closer and aim at the animal" },
					{ "Животное не приручено", "Animal is not tamed" },
					{ "Нет безопасного берега для высадки", "No safe shore for disembarking" },
					{ "Питомец высажен на берег", "Pet disembarked ashore" },
					{ "Рядом нет подходящего корабля", "No suitable ship nearby" },
					{ "Это животное нельзя перевозить на данном корабле", "This animal cannot travel on this ship" },
					{ "На корабле недостаточно места", "Not enough room on the ship" },
					{ "Не удалось найти место на палубе", "Could not find room on deck" },
					{ "Питомец привязан к мачте", "Pet secured to the mast" },
					{ "Наведитесь на приручённого питомца", "Aim at a tamed pet" },
					{ "Сначала высадите питомца с корабля", "Disembark the pet first" },
					{ "Питомец следует за вами", "Pet is following you" },
					{ "Питомец остаётся на месте", "Pet is staying here" }
				}
			},
			{
				"Chinese",
				new Dictionary<string, string>
				{
					{ "Следуй за мной", "跟随我" },
					{ "Надеть седло", "装备鞍具" },
					{ "Закрыть", "关闭" },
					{ "Переименовать", "重命名" },
					{ "Посадить на корабль", "登船" },
					{ "Стой на месте", "原地待命" },
					{ "Спустить с корабля", "下船" },
					{ "Снять седло", "卸下鞍具" },
					{ "Голоден", "饥饿" },
					{ "Сыт", "饱食" },
					{ "Приручен", "已驯服" },
					{ "Беременность", "怀孕" },
					{ "Приласкать", "抚摸" },
					{ "Стоять", "待命" },
					{ "Следовать", "跟随" },
					{ "Меню взаимодействия", "交互菜单" },
					{ "Не найден компонент седла", "Saddle component not found" },
					{ "Невозможно снять седло: API игры изменился", "Cannot remove saddle: game API changed" },
					{ "В инвентаре нет подходящего седла", "No suitable saddle in inventory" },
					{ "Невозможно надеть седло: API игры изменился", "Cannot equip saddle: game API changed" },
					{ "Не удалось надеть седло", "Failed to equip saddle" },
					{ "Ошибка седла — см. BepInEx LogOutput.log", "Saddle error — see BepInEx LogOutput.log" },
					{ "Не удалось открыть стандартное переименование — см. лог", "Could not open vanilla rename — see log" },
					{ "Питомец не найден. Подойдите ближе и наведитесь на животное", "Pet not found. Move closer and aim at the animal" },
					{ "Животное не приручено", "Animal is not tamed" },
					{ "Нет безопасного берега для высадки", "No safe shore for disembarking" },
					{ "Питомец высажен на берег", "Pet disembarked ashore" },
					{ "Рядом нет подходящего корабля", "No suitable ship nearby" },
					{ "Это животное нельзя перевозить на данном корабле", "This animal cannot travel on this ship" },
					{ "На корабле недостаточно места", "Not enough room on the ship" },
					{ "Не удалось найти место на палубе", "Could not find room on deck" },
					{ "Питомец привязан к мачте", "Pet secured to the mast" },
					{ "Наведитесь на приручённого питомца", "Aim at a tamed pet" },
					{ "Сначала высадите питомца с корабля", "Disembark the pet first" },
					{ "Питомец следует за вами", "Pet is following you" },
					{ "Питомец остаётся на месте", "Pet is staying here" }
				}
			},
			{
				"Turkish",
				new Dictionary<string, string>
				{
					{ "Следуй за мной", "Beni takip et" },
					{ "Надеть седло", "Eyer tak" },
					{ "Закрыть", "Kapat" },
					{ "Переименовать", "Yeniden adlandır" },
					{ "Посадить на корабль", "Gemiye bindir" },
					{ "Стой на месте", "Burada kal" },
					{ "Спустить с корабля", "Gemiden indir" },
					{ "Снять седло", "Eyeri çıkar" },
					{ "Голоден", "Aç" },
					{ "Сыт", "Tok" },
					{ "Приручен", "Evcilleştirilmiş" },
					{ "Беременность", "Hamile" },
					{ "Приласкать", "Sev" },
					{ "Стоять", "Bekle" },
					{ "Следовать", "Takip et" },
					{ "Меню взаимодействия", "Etkileşim menüsü" },
					{ "Не найден компонент седла", "Saddle component not found" },
					{ "Невозможно снять седло: API игры изменился", "Cannot remove saddle: game API changed" },
					{ "В инвентаре нет подходящего седла", "No suitable saddle in inventory" },
					{ "Невозможно надеть седло: API игры изменился", "Cannot equip saddle: game API changed" },
					{ "Не удалось надеть седло", "Failed to equip saddle" },
					{ "Ошибка седла — см. BepInEx LogOutput.log", "Saddle error — see BepInEx LogOutput.log" },
					{ "Не удалось открыть стандартное переименование — см. лог", "Could not open vanilla rename — see log" },
					{ "Питомец не найден. Подойдите ближе и наведитесь на животное", "Pet not found. Move closer and aim at the animal" },
					{ "Животное не приручено", "Animal is not tamed" },
					{ "Нет безопасного берега для высадки", "No safe shore for disembarking" },
					{ "Питомец высажен на берег", "Pet disembarked ashore" },
					{ "Рядом нет подходящего корабля", "No suitable ship nearby" },
					{ "Это животное нельзя перевозить на данном корабле", "This animal cannot travel on this ship" },
					{ "На корабле недостаточно места", "Not enough room on the ship" },
					{ "Не удалось найти место на палубе", "Could not find room on deck" },
					{ "Питомец привязан к мачте", "Pet secured to the mast" },
					{ "Наведитесь на приручённого питомца", "Aim at a tamed pet" },
					{ "Сначала высадите питомца с корабля", "Disembark the pet first" },
					{ "Питомец следует за вами", "Pet is following you" },
					{ "Питомец остаётся на месте", "Pet is staying here" }
				}
			},
			{
				"Czech",
				new Dictionary<string, string>
				{
					{ "Следуй за мной", "Následuj mě" },
					{ "Надеть седло", "Nasadit sedlo" },
					{ "Закрыть", "Zavřít" },
					{ "Переименовать", "Přejmenovat" },
					{ "Посадить на корабль", "Nalodit" },
					{ "Стой на месте", "Zůstaň zde" },
					{ "Спустить с корабля", "Vylodit" },
					{ "Снять седло", "Sundat sedlo" },
					{ "Голоден", "Hladový" },
					{ "Сыт", "Sytý" },
					{ "Приручен", "Ochočený" },
					{ "Беременность", "Březost" },
					{ "Приласкать", "Pohladit" },
					{ "Стоять", "Zůstat" },
					{ "Следовать", "Následovat" },
					{ "Меню взаимодействия", "Nabídka interakcí" },
					{ "Не найден компонент седла", "Saddle component not found" },
					{ "Невозможно снять седло: API игры изменился", "Cannot remove saddle: game API changed" },
					{ "В инвентаре нет подходящего седла", "No suitable saddle in inventory" },
					{ "Невозможно надеть седло: API игры изменился", "Cannot equip saddle: game API changed" },
					{ "Не удалось надеть седло", "Failed to equip saddle" },
					{ "Ошибка седла — см. BepInEx LogOutput.log", "Saddle error — see BepInEx LogOutput.log" },
					{ "Не удалось открыть стандартное переименование — см. лог", "Could not open vanilla rename — see log" },
					{ "Питомец не найден. Подойдите ближе и наведитесь на животное", "Pet not found. Move closer and aim at the animal" },
					{ "Животное не приручено", "Animal is not tamed" },
					{ "Нет безопасного берега для высадки", "No safe shore for disembarking" },
					{ "Питомец высажен на берег", "Pet disembarked ashore" },
					{ "Рядом нет подходящего корабля", "No suitable ship nearby" },
					{ "Это животное нельзя перевозить на данном корабле", "This animal cannot travel on this ship" },
					{ "На корабле недостаточно места", "Not enough room on the ship" },
					{ "Не удалось найти место на палубе", "Could not find room on deck" },
					{ "Питомец привязан к мачте", "Pet secured to the mast" },
					{ "Наведитесь на приручённого питомца", "Aim at a tamed pet" },
					{ "Сначала высадите питомца с корабля", "Disembark the pet first" },
					{ "Питомец следует за вами", "Pet is following you" },
					{ "Питомец остаётся на месте", "Pet is staying here" }
				}
			},
			{
				"Hungarian",
				new Dictionary<string, string>
				{
					{ "Следуй за мной", "Kövess" },
					{ "Надеть седло", "Nyereg fel" },
					{ "Закрыть", "Bezárás" },
					{ "Переименовать", "Átnevezés" },
					{ "Посадить на корабль", "Hajóra szállás" },
					{ "Стой на месте", "Maradj itt" },
					{ "Спустить с корабля", "Partra szállás" },
					{ "Снять седло", "Nyereg le" },
					{ "Голоден", "Éhes" },
					{ "Сыт", "Jóllakott" },
					{ "Приручен", "Szelídített" },
					{ "Беременность", "Vemhes" },
					{ "Приласкать", "Simogatás" },
					{ "Стоять", "Marad" },
					{ "Следовать", "Követ" },
					{ "Меню взаимодействия", "Interakciós menü" },
					{ "Не найден компонент седла", "Saddle component not found" },
					{ "Невозможно снять седло: API игры изменился", "Cannot remove saddle: game API changed" },
					{ "В инвентаре нет подходящего седла", "No suitable saddle in inventory" },
					{ "Невозможно надеть седло: API игры изменился", "Cannot equip saddle: game API changed" },
					{ "Не удалось надеть седло", "Failed to equip saddle" },
					{ "Ошибка седла — см. BepInEx LogOutput.log", "Saddle error — see BepInEx LogOutput.log" },
					{ "Не удалось открыть стандартное переименование — см. лог", "Could not open vanilla rename — see log" },
					{ "Питомец не найден. Подойдите ближе и наведитесь на животное", "Pet not found. Move closer and aim at the animal" },
					{ "Животное не приручено", "Animal is not tamed" },
					{ "Нет безопасного берега для высадки", "No safe shore for disembarking" },
					{ "Питомец высажен на берег", "Pet disembarked ashore" },
					{ "Рядом нет подходящего корабля", "No suitable ship nearby" },
					{ "Это животное нельзя перевозить на данном корабле", "This animal cannot travel on this ship" },
					{ "На корабле недостаточно места", "Not enough room on the ship" },
					{ "Не удалось найти место на палубе", "Could not find room on deck" },
					{ "Питомец привязан к мачте", "Pet secured to the mast" },
					{ "Наведитесь на приручённого питомца", "Aim at a tamed pet" },
					{ "Сначала высадите питомца с корабля", "Disembark the pet first" },
					{ "Питомец следует за вами", "Pet is following you" },
					{ "Питомец остаётся на месте", "Pet is staying here" }
				}
			},
			{
				"Finnish",
				new Dictionary<string, string>
				{
					{ "Следуй за мной", "Seuraa minua" },
					{ "Надеть седло", "Laita satula" },
					{ "Закрыть", "Sulje" },
					{ "Переименовать", "Nimeä uudelleen" },
					{ "Посадить на корабль", "Nouse laivaan" },
					{ "Стой на месте", "Pysy tässä" },
					{ "Спустить с корабля", "Poistu laivasta" },
					{ "Снять седло", "Poista satula" },
					{ "Голоден", "Nälkäinen" },
					{ "Сыт", "Kylläinen" },
					{ "Приручен", "Kesytetty" },
					{ "Беременность", "Tiineenä" },
					{ "Приласкать", "Silitä" },
					{ "Стоять", "Pysy" },
					{ "Следовать", "Seuraa" },
					{ "Меню взаимодействия", "Toimintovalikko" },
					{ "Не найден компонент седла", "Saddle component not found" },
					{ "Невозможно снять седло: API игры изменился", "Cannot remove saddle: game API changed" },
					{ "В инвентаре нет подходящего седла", "No suitable saddle in inventory" },
					{ "Невозможно надеть седло: API игры изменился", "Cannot equip saddle: game API changed" },
					{ "Не удалось надеть седло", "Failed to equip saddle" },
					{ "Ошибка седла — см. BepInEx LogOutput.log", "Saddle error — see BepInEx LogOutput.log" },
					{ "Не удалось открыть стандартное переименование — см. лог", "Could not open vanilla rename — see log" },
					{ "Питомец не найден. Подойдите ближе и наведитесь на животное", "Pet not found. Move closer and aim at the animal" },
					{ "Животное не приручено", "Animal is not tamed" },
					{ "Нет безопасного берега для высадки", "No safe shore for disembarking" },
					{ "Питомец высажен на берег", "Pet disembarked ashore" },
					{ "Рядом нет подходящего корабля", "No suitable ship nearby" },
					{ "Это животное нельзя перевозить на данном корабле", "This animal cannot travel on this ship" },
					{ "На корабле недостаточно места", "Not enough room on the ship" },
					{ "Не удалось найти место на палубе", "Could not find room on deck" },
					{ "Питомец привязан к мачте", "Pet secured to the mast" },
					{ "Наведитесь на приручённого питомца", "Aim at a tamed pet" },
					{ "Сначала высадите питомца с корабля", "Disembark the pet first" },
					{ "Питомец следует за вами", "Pet is following you" },
					{ "Питомец остаётся на месте", "Pet is staying here" }
				}
			},
			{
				"Danish",
				new Dictionary<string, string>
				{
					{ "Следуй за мной", "Følg mig" },
					{ "Надеть седло", "Sæt sadel på" },
					{ "Закрыть", "Luk" },
					{ "Переименовать", "Omdøb" },
					{ "Посадить на корабль", "Gå om bord" },
					{ "Стой на месте", "Bliv her" },
					{ "Спустить с корабля", "Gå fra borde" },
					{ "Снять седло", "Tag sadel af" },
					{ "Голоден", "Sulten" },
					{ "Сыт", "Mæt" },
					{ "Приручен", "Tæmmet" },
					{ "Беременность", "Drægtig" },
					{ "Приласкать", "Kæl" },
					{ "Стоять", "Bliv" },
					{ "Следовать", "Følg" },
					{ "Меню взаимодействия", "Interaktionsmenu" },
					{ "Не найден компонент седла", "Saddle component not found" },
					{ "Невозможно снять седло: API игры изменился", "Cannot remove saddle: game API changed" },
					{ "В инвентаре нет подходящего седла", "No suitable saddle in inventory" },
					{ "Невозможно надеть седло: API игры изменился", "Cannot equip saddle: game API changed" },
					{ "Не удалось надеть седло", "Failed to equip saddle" },
					{ "Ошибка седла — см. BepInEx LogOutput.log", "Saddle error — see BepInEx LogOutput.log" },
					{ "Не удалось открыть стандартное переименование — см. лог", "Could not open vanilla rename — see log" },
					{ "Питомец не найден. Подойдите ближе и наведитесь на животное", "Pet not found. Move closer and aim at the animal" },
					{ "Животное не приручено", "Animal is not tamed" },
					{ "Нет безопасного берега для высадки", "No safe shore for disembarking" },
					{ "Питомец высажен на берег", "Pet disembarked ashore" },
					{ "Рядом нет подходящего корабля", "No suitable ship nearby" },
					{ "Это животное нельзя перевозить на данном корабле", "This animal cannot travel on this ship" },
					{ "На корабле недостаточно места", "Not enough room on the ship" },
					{ "Не удалось найти место на палубе", "Could not find room on deck" },
					{ "Питомец привязан к мачте", "Pet secured to the mast" },
					{ "Наведитесь на приручённого питомца", "Aim at a tamed pet" },
					{ "Сначала высадите питомца с корабля", "Disembark the pet first" },
					{ "Питомец следует за вами", "Pet is following you" },
					{ "Питомец остаётся на месте", "Pet is staying here" }
				}
			},
			{
				"Norwegian",
				new Dictionary<string, string>
				{
					{ "Следуй за мной", "Følg meg" },
					{ "Надеть седло", "Sett på sal" },
					{ "Закрыть", "Lukk" },
					{ "Переименовать", "Gi nytt navn" },
					{ "Посадить на корабль", "Gå om bord" },
					{ "Стой на месте", "Bli her" },
					{ "Спустить с корабля", "Gå i land" },
					{ "Снять седло", "Ta av sal" },
					{ "Голоден", "Sulten" },
					{ "Сыт", "Mett" },
					{ "Приручен", "Temmet" },
					{ "Беременность", "Drektig" },
					{ "Приласкать", "Klapp" },
					{ "Стоять", "Bli" },
					{ "Следовать", "Følg" },
					{ "Меню взаимодействия", "Interaksjonsmeny" },
					{ "Не найден компонент седла", "Saddle component not found" },
					{ "Невозможно снять седло: API игры изменился", "Cannot remove saddle: game API changed" },
					{ "В инвентаре нет подходящего седла", "No suitable saddle in inventory" },
					{ "Невозможно надеть седло: API игры изменился", "Cannot equip saddle: game API changed" },
					{ "Не удалось надеть седло", "Failed to equip saddle" },
					{ "Ошибка седла — см. BepInEx LogOutput.log", "Saddle error — see BepInEx LogOutput.log" },
					{ "Не удалось открыть стандартное переименование — см. лог", "Could not open vanilla rename — see log" },
					{ "Питомец не найден. Подойдите ближе и наведитесь на животное", "Pet not found. Move closer and aim at the animal" },
					{ "Животное не приручено", "Animal is not tamed" },
					{ "Нет безопасного берега для высадки", "No safe shore for disembarking" },
					{ "Питомец высажен на берег", "Pet disembarked ashore" },
					{ "Рядом нет подходящего корабля", "No suitable ship nearby" },
					{ "Это животное нельзя перевозить на данном корабле", "This animal cannot travel on this ship" },
					{ "На корабле недостаточно места", "Not enough room on the ship" },
					{ "Не удалось найти место на палубе", "Could not find room on deck" },
					{ "Питомец привязан к мачте", "Pet secured to the mast" },
					{ "Наведитесь на приручённого питомца", "Aim at a tamed pet" },
					{ "Сначала высадите питомца с корабля", "Disembark the pet first" },
					{ "Питомец следует за вами", "Pet is following you" },
					{ "Питомец остаётся на месте", "Pet is staying here" }
				}
			}
		};

		private static string cachedLanguage = "English";

		private static float nextLanguageCheck = -1f;

		private static Dictionary<string, string> activeTranslations = Translations["English"];

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

		private static Type localizationType;

		private static FieldInfo localizationInstanceField;

		private static PropertyInfo localizationInstanceProperty;

		private static MethodInfo selectedLanguageMethod;

		private static bool localizationReflectionInitialized;

		internal const string ShipKey = "ppt_ship";

		internal const string OffsetKey = "ppt_offset";

		internal const string FollowKey = "ppt_follow";

		internal const string FollowOwnerKey = "ppt_follow_owner";

		internal static Plugin Instance;

		internal static readonly Dictionary<string, int> Capacities = new Dictionary<string, int>
		{
			{ "Raft", 1 },
			{ "Karve", 2 },
			{ "VikingShip", 6 },
			{ "VikingShip_Ashlands", 11 }
		};

		private Harmony harmony;

		private readonly Dictionary<ZDOID, LineRenderer> ropes = new Dictionary<ZDOID, LineRenderer>();

		private readonly Dictionary<ZDOID, GameObject> followDestinations = new Dictionary<ZDOID, GameObject>();

		private Material ropeMaterial;

		private float scanAt;

		private Character menuPet;

		private bool menuOpen;

		private int menuOpenedFrame;

		private int suppressMenuUntilFrame;

		private Font wheelGameFont;

		private Font wheelActionFont;

		private Texture2D petWheelTexture;

		private readonly Dictionary<string, Texture2D> wheelArtCache = new Dictionary<string, Texture2D>();

		private static readonly string[] WheelIconsFive = new string[5] { "Follow", "Saddle", "Close", "Rename", "Ship" };

		private static readonly string[] WheelIconsFour = new string[4] { "Follow", "Rename", "Close", "Ship" };

		private GUIStyle cachedWheelTextStyle;

		private GUIStyle cachedWheelCenterStyle;

		private GUIStyle cachedWheelStatusStyle;

		private GUIStyle cachedWheelActionStyle;

		private bool wheelFontsSearched;

		private string[] wheelLabels;

		private float wheelLabelsRefreshAt;

		private string wheelPetName;

		private string wheelPetStatus;

		private int wheelHighlighted = -2;

		private int wheelCount = 4;

		private Vector2 wheelCursor;

		private bool wheelCursorInitialized;

		private Texture2D wheelPointerTexture;

		private bool nativeRenameInProgress;

		private bool wheelMouseDown;

		private CursorLockMode previousCursorLock;

		private bool previousCursorVisible;

		private readonly Dictionary<string, Sprite> commandIcons = new Dictionary<string, Sprite>();

		private readonly List<Texture2D> commandTextures = new List<Texture2D>();

		private readonly Dictionary<ZDOID, PinData> petPins = new Dictionary<ZDOID, PinData>();

		private readonly Dictionary<string, Sprite> petIcons = new Dictionary<string, Sprite>();

		private readonly List<Texture2D> petTextures = new List<Texture2D>();

		private readonly Dictionary<int, Dictionary<int, AnimatorControllerParameterType>> movementParameters = new Dictionary<int, Dictionary<int, AnimatorControllerParameterType>>();

		private readonly Dictionary<ZDOID, List<ColliderPair>> ignoredCollisions = new Dictionary<ZDOID, List<ColliderPair>>();

		private readonly Dictionary<ZDOID, Attachment> attachments = new Dictionary<ZDOID, Attachment>();

		private static void RefreshLanguage()
		{
			float unscaledTime = Time.unscaledTime;
			if (nextLanguageCheck >= 0f && unscaledTime < nextLanguageCheck)
			{
				return;
			}
			nextLanguageCheck = unscaledTime + 1f;
			string text = "English";
			try
			{
				if (!localizationReflectionInitialized)
				{
					localizationReflectionInitialized = true;
					localizationType = AccessTools.TypeByName("Localization");
					if (localizationType != null)
					{
						localizationInstanceField = localizationType.GetField("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
						localizationInstanceProperty = localizationType.GetProperty("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
						selectedLanguageMethod = AccessTools.Method(localizationType, "GetSelectedLanguage", Type.EmptyTypes, (Type[])null);
					}
				}
				object obj = ((localizationInstanceField != null) ? localizationInstanceField.GetValue(null) : ((localizationInstanceProperty != null) ? localizationInstanceProperty.GetValue(null, null) : null));
				if (obj != null && selectedLanguageMethod != null)
				{
					text = Convert.ToString(selectedLanguageMethod.Invoke(obj, null));
				}
			}
			catch
			{
				text = cachedLanguage;
			}
			if (string.IsNullOrEmpty(text))
			{
				text = "English";
			}
			if (text.Equals("Chinese Simplified", StringComparison.OrdinalIgnoreCase) || text.Equals("Chinese Traditional", StringComparison.OrdinalIgnoreCase) || text.Equals("Chinese_Simplified", StringComparison.OrdinalIgnoreCase))
			{
				text = "Chinese";
			}
			if (text.Equals("Portuguese (Brazil)", StringComparison.OrdinalIgnoreCase) || text.Equals("Portuguese-Brazil", StringComparison.OrdinalIgnoreCase))
			{
				text = "Brazilian";
			}
			if (!string.Equals(cachedLanguage, text, StringComparison.OrdinalIgnoreCase))
			{
				cachedLanguage = text;
				if (!Translations.TryGetValue(text, out activeTranslations))
				{
					activeTranslations = Translations["English"];
				}
				translatedCache.Clear();
			}
		}

		private static string Tr(string key)
		{
			RefreshLanguage();
			if (cachedLanguage.Equals("Russian", StringComparison.OrdinalIgnoreCase))
			{
				return key;
			}
			if (translatedCache.TryGetValue(key, out var value))
			{
				return value;
			}
			if (!activeTranslations.TryGetValue(key, out value) && !Translations["English"].TryGetValue(key, out value))
			{
				value = key;
			}
			translatedCache[key] = value;
			return value;
		}

		private void Awake()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			Instance = this;
			LoadPetIcons();
			LoadCommandIcons();
			for (int i = 4; i <= 5; i++)
			{
				wheelCount = i;
				for (int j = -1; j < i; j++)
				{
					BuildWheelTexture(j);
				}
			}
			petWheelTexture = null;
			wheelHighlighted = -2;
			harmony = new Harmony("perfect.pet.transit");
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Perfect Pet Transit 0.0.52 loaded; radial menu fixes");
		}

		private void OnDestroy()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			foreach (ZDOID item in new List<ZDOID>(attachments.Keys))
			{
				ReleaseAttachment(item);
			}
			foreach (ZDOID item2 in new List<ZDOID>(ignoredCollisions.Keys))
			{
				RestoreCollisions(item2);
			}
			foreach (LineRenderer value in ropes.Values)
			{
				if (Object.op_Implicit((Object)(object)value))
				{
					Object.Destroy((Object)(object)((Component)value).gameObject);
				}
			}
			foreach (GameObject value2 in followDestinations.Values)
			{
				if (Object.op_Implicit((Object)(object)value2))
				{
					Object.Destroy((Object)(object)value2);
				}
			}
			followDestinations.Clear();
			if (Object.op_Implicit((Object)(object)ropeMaterial))
			{
				Object.Destroy((Object)(object)ropeMaterial);
			}
			foreach (Texture2D value3 in wheelArtCache.Values)
			{
				if (Object.op_Implicit((Object)(object)value3))
				{
					Object.Destroy((Object)(object)value3);
				}
			}
			wheelArtCache.Clear();
			petWheelTexture = null;
			ClearPetPins();
			foreach (Sprite value4 in petIcons.Values)
			{
				if (Object.op_Implicit((Object)(object)value4))
				{
					Object.Destroy((Object)(object)value4);
				}
			}
			foreach (Texture2D petTexture in petTextures)
			{
				if (Object.op_Implicit((Object)(object)petTexture))
				{
					Object.Destroy((Object)(object)petTexture);
				}
			}
			foreach (Sprite value5 in commandIcons.Values)
			{
				if (Object.op_Implicit((Object)(object)value5))
				{
					Object.Destroy((Object)(object)value5);
				}
			}
			foreach (Texture2D commandTexture in commandTextures)
			{
				if (Object.op_Implicit((Object)(object)commandTexture))
				{
					Object.Destroy((Object)(object)commandTexture);
				}
			}
		}

		private static string PrefabName(GameObject go)
		{
			if (!((Object)(object)go == (Object)null))
			{
				return ((Object)go).name.Replace("(Clone)", "").Trim();
			}
			return string.Empty;
		}

		private static int Weight(string animal)
		{
			return animal switch
			{
				"Boar" => 1, 
				"Wolf" => 2, 
				"Asksvin" => 3, 
				"Moose" => 3, 
				"Lox" => 11, 
				_ => -1, 
			};
		}

		private static bool Allowed(string ship, string animal)
		{
			switch (ship)
			{
			case "Raft":
				return animal == "Boar";
			case "Karve":
				if (!(animal == "Boar"))
				{
					return animal == "Wolf";
				}
				return true;
			case "VikingShip":
				switch (animal)
				{
				default:
					return animal == "Moose";
				case "Boar":
				case "Wolf":
				case "Asksvin":
					return true;
				}
			case "VikingShip_Ashlands":
				return Weight(animal) > 0;
			default:
				return false;
			}
		}

		private static int Limit(string ship, string animal)
		{
			switch (ship)
			{
			case "Raft":
				return (animal == "Boar") ? 1 : 0;
			case "Karve":
				if (!(animal == "Boar") && !(animal == "Wolf"))
				{
					return 0;
				}
				return 1;
			case "VikingShip":
				switch (animal)
				{
				default:
					return 0;
				case "Asksvin":
				case "Moose":
					return 1;
				case "Wolf":
					return 2;
				case "Boar":
					return 3;
				}
			case "VikingShip_Ashlands":
				switch (animal)
				{
				default:
					return (animal == "Lox") ? 1 : 0;
				case "Asksvin":
				case "Moose":
					return 2;
				case "Boar":
				case "Wolf":
					return 3;
				}
			default:
				return 0;
			}
		}

		private void Update()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || !Object.op_Implicit((Object)(object)ZNetScene.instance))
			{
				return;
			}
			if (menuOpen)
			{
				if (!Object.op_Implicit((Object)(object)menuPet) || Vector3.Distance(((Component)Player.m_localPlayer).transform.position, ((Component)menuPet).transform.position) > 5f)
				{
					ClosePetMenu();
					return;
				}
				Cursor.lockState = (CursorLockMode)1;
				Cursor.visible = false;
				if (Input.GetKeyDown((KeyCode)27))
				{
					suppressMenuUntilFrame = Time.frameCount + 2;
					ClosePetMenu();
					return;
				}
				wheelCursor.x = Mathf.Clamp(wheelCursor.x + Input.GetAxisRaw("Mouse X") * 20f, 0f, (float)Screen.width);
				wheelCursor.y = Mathf.Clamp(wheelCursor.y - Input.GetAxisRaw("Mouse Y") * 20f, 0f, (float)Screen.height);
				if (Input.GetMouseButtonDown(0))
				{
					wheelMouseDown = true;
				}
				if (Input.GetMouseButtonUp(0) && Time.frameCount > menuOpenedFrame + 1)
				{
					int num = SelectedWheelSector(wheelCursor);
					if (num >= 0)
					{
						ExecutePetCommand(num);
					}
					wheelMouseDown = false;
					return;
				}
				if (Input.GetKeyDown((KeyCode)49))
				{
					ExecutePetCommand(0);
				}
				if (Input.GetKeyDown((KeyCode)50))
				{
					ExecutePetCommand(1);
				}
				if (Input.GetKeyDown((KeyCode)51))
				{
					ExecutePetCommand(2);
				}
				if (Input.GetKeyDown((KeyCode)52))
				{
					ExecutePetCommand(3);
				}
				if (Input.GetKeyDown((KeyCode)53) && wheelCount == 5)
				{
					ExecutePetCommand(4);
				}
			}
			else if (Input.GetKeyDown((KeyCode)101) && (Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303)))
			{
				OpenPetMenu();
			}
			else if (!(Time.time < scanAt))
			{
				scanAt = Time.time + 0.1f;
				UpdateTethers();
				UpdateFollowPets();
			}
		}

		private void OpenPetMenu()
		{
			Player localPlayer = Player.m_localPlayer;
			Camera main = Camera.main;
			if (Object.op_Implicit((Object)(object)localPlayer) && Object.op_Implicit((Object)(object)main))
			{
				Character val = FindTargetPet(localPlayer, main);
				if (Object.op_Implicit((Object)(object)val) && val.IsTamed() && Weight(PrefabName(((Component)val).gameObject)) >= 0)
				{
					OpenPetMenu(val);
				}
			}
		}

		private void OpenPetMenu(Character pet)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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)
			if (Object.op_Implicit((Object)(object)pet) && !menuOpen)
			{
				menuPet = pet;
				menuOpen = true;
				menuOpenedFrame = Time.frameCount;
				previousCursorLock = Cursor.lockState;
				previousCursorVisible = Cursor.visible;
				wheelCount = (IsRideable(pet) ? 5 : 4);
				wheelHighlighted = -2;
				wheelLabelsRefreshAt = 0f;
				wheelFontsSearched = false;
				cachedWheelTextStyle = null;
				cachedWheelCenterStyle = null;
				cachedWheelStatusStyle = null;
				cachedWheelActionStyle = null;
				wheelMouseDown = false;
				wheelCursor = new Vector2((float)Screen.width * 0.5f, (float)Screen.height * 0.5f);
				wheelCursorInitialized = true;
				Cursor.lockState = (CursorLockMode)1;
				Cursor.visible = false;
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Opened pet wheel for " + PrefabName(((Component)pet).gameObject) + ", actions=" + wheelCount));
			}
		}

		private static bool IsRideable(Character pet)
		{
			if (!Object.op_Implicit((Object)(object)pet))
			{
				return false;
			}
			string text = PrefabName(((Component)pet).gameObject);
			if (!(text == "Lox") && !(text == "Asksvin"))
			{
				return text == "Moose";
			}
			return true;
		}

		private int SelectedWheelSector(Vector2 mouse)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = mouse - new Vector2((float)Screen.width * 0.5f, (float)Screen.height * 0.5f);
			float magnitude = ((Vector2)(ref val)).magnitude;
			if (magnitude < 138f || magnitude > 372f)
			{
				return -1;
			}
			float num = Mathf.Atan2(val.x, 0f - val.y) * 57.29578f;
			if (num < 0f)
			{
				num += 360f;
			}
			return Mathf.FloorToInt((num + 180f / (float)wheelCount) / (360f / (float)wheelCount)) % wheelCount;
		}

		private void ExecutePetCommand(int sector)
		{
			if (!Object.op_Implicit((Object)(object)menuPet))
			{
				ClosePetMenu();
			}
			else if (sector == 0)
			{
				ZNetView component = ((Component)menuPet).GetComponent<ZNetView>();
				if (Object.op_Implicit((Object)(object)component) && component.IsValid())
				{
					SetFollow(menuPet, !component.GetZDO().GetBool("ppt_follow", false));
				}
				ClosePetMenu();
			}
			else if (wheelCount == 5 && sector == 1)
			{
				Character animal = menuPet;
				ClosePetMenu();
				ToggleNativeSaddle(animal);
			}
			else if (sector == ((wheelCount != 5) ? 1 : 3))
			{
				Character animal2 = menuPet;
				ClosePetMenu();
				((MonoBehaviour)this).StartCoroutine(OpenNativeRenameNextFrame(animal2));
			}
			else if (sector == ((wheelCount == 5) ? 2 : 2))
			{
				ClosePetMenu();
			}
			else if (sector == ((wheelCount == 5) ? 4 : 3))
			{
				TogglePet(menuPet);
				ClosePetMenu();
			}
		}

		private static bool HasNativeSaddle(Tameable tameable)
		{
			if (!Object.op_Implicit((Object)(object)tameable))
			{
				return false;
			}
			try
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(Tameable), "HaveSaddle", Type.EmptyTypes, (Type[])null);
				if (methodInfo != null && methodInfo.ReturnType == typeof(bool))
				{
					return (bool)methodInfo.Invoke(tameable, null);
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)Instance).Logger.LogWarning((object)("HaveSaddle: " + ex.Message));
			}
			return false;
		}

		private void ToggleNativeSaddle(Character animal)
		{
			Player localPlayer = Player.m_localPlayer;
			Tameable val = (Object.op_Implicit((Object)(object)animal) ? ((Component)animal).GetComponent<Tameable>() : null);
			if (!Object.op_Implicit((Object)(object)localPlayer) || !Object.op_Implicit((Object)(object)animal) || !Object.op_Implicit((Object)(object)val) || !animal.IsTamed())
			{
				return;
			}
			try
			{
				if (HasNativeSaddle(val))
				{
					object? obj = AccessTools.Field(typeof(Tameable), "m_saddle")?.GetValue(val);
					Sadle val2 = (Sadle)((obj is Sadle) ? obj : null);
					if (!Object.op_Implicit((Object)(object)val2))
					{
						val2 = ((Component)val).GetComponentInChildren<Sadle>(true);
					}
					if (!Object.op_Implicit((Object)(object)val2))
					{
						MessageHud instance = MessageHud.instance;
						if (instance != null)
						{
							instance.ShowMessage((MessageType)2, Tr("Не найден компонент седла"), 0, (Sprite)null, false, true);
						}
						return;
					}
					MethodInfo methodInfo = AccessTools.Method(typeof(Sadle), "Interact", new Type[3]
					{
						typeof(Humanoid),
						typeof(bool),
						typeof(bool)
					}, (Type[])null);
					if (methodInfo == null)
					{
						MessageHud instance2 = MessageHud.instance;
						if (instance2 != null)
						{
							instance2.ShowMessage((MessageType)2, Tr("Невозможно снять седло: API игры изменился"), 0, (Sprite)null, false, true);
						}
					}
					else
					{
						methodInfo.Invoke(val2, new object[3] { localPlayer, false, true });
					}
					return;
				}
				string text = PrefabName(((Component)animal).gameObject) switch
				{
					"Moose" => "SaddleMoose", 
					"Asksvin" => "SaddleAsksvin", 
					"Lox" => "SaddleLox", 
					_ => null, 
				};
				if (text == null)
				{
					return;
				}
				ItemData val3 = null;
				foreach (ItemData allItem in ((Humanoid)localPlayer).GetInventory().GetAllItems())
				{
					if (Object.op_Implicit((Object)(object)allItem?.m_dropPrefab) && ((Object)allItem.m_dropPrefab).name == text)
					{
						val3 = allItem;
						break;
					}
				}
				if (val3 == null)
				{
					MessageHud instance3 = MessageHud.instance;
					if (instance3 != null)
					{
						instance3.ShowMessage((MessageType)2, Tr("В инвентаре нет подходящего седла"), 0, (Sprite)null, false, true);
					}
					return;
				}
				MethodInfo methodInfo2 = AccessTools.Method(typeof(Tameable), "UseItem", new Type[2]
				{
					typeof(Humanoid),
					typeof(ItemData)
				}, (Type[])null);
				if (methodInfo2 == null)
				{
					MessageHud instance4 = MessageHud.instance;
					if (instance4 != null)
					{
						instance4.ShowMessage((MessageType)2, Tr("Невозможно надеть седло: API игры изменился"), 0, (Sprite)null, false, true);
					}
					return;
				}
				object obj2 = methodInfo2.Invoke(val, new object[2] { localPlayer, val3 });
				if (obj2 is bool && !(bool)obj2)
				{
					MessageHud instance5 = MessageHud.instance;
					if (instance5 != null)
					{
						instance5.ShowMessage((MessageType)2, Tr("Не удалось надеть седло"), 0, (Sprite)null, false, true);
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Saddle action failed: " + ex));
				MessageHud instance6 = MessageHud.instance;
				if (instance6 != null)
				{
					instance6.ShowMessage((MessageType)2, Tr("Ошибка седла — см. BepInEx LogOutput.log"), 0, (Sprite)null, false, true);
				}
			}
		}

		private void ClosePetMenu(bool closeWheel = true)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			suppressMenuUntilFrame = Mathf.Max(suppressMenuUntilFrame, Time.frameCount + 3);
			menuOpen = false;
			menuPet = null;
			Cursor.lockState = previousCursorLock;
			Cursor.visible = previousCursorVisible;
		}

		private void LoadCommandIcons()
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			string[] array = new string[5] { "Follow", "Ship", "Rename", "Close", "Saddle" };
			foreach (string text in array)
			{
				try
				{
					string text2 = "PerfectPetTransit.assets." + text + ".png";
					using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(text2);
					if (stream == null)
					{
						((BaseUnityPlugin)this).Logger.LogError((object)("MISSING icon resource: " + text2));
						continue;
					}
					byte[] array2 = new byte[stream.Length];
					stream.Read(array2, 0, array2.Length);
					Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
					if (!ImageConversion.LoadImage(val, array2))
					{
						Object.Destroy((Object)(object)val);
						continue;
					}
					((Texture)val).filterMode = (FilterMode)1;
					commandTextures.Add(val);
					commandIcons[text] = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
					((BaseUnityPlugin)this).Logger.LogInfo((object)("Stone icon loaded: " + text + " (" + ((Texture)val).width + "x" + ((Texture)val).height + ")"));
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Icon " + text + ": " + ex.Message));
				}
			}
		}

		private void BuildWheelTexture(int selected)
		{
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			string text = "PerfectPetTransit.assets.Wheel" + wheelCount + "_" + selected + ".png";
			if (wheelArtCache.TryGetValue(text, out var value))
			{
				petWheelTexture = value;
				wheelHighlighted = selected;
				return;
			}
			try
			{
				using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(text);
				if (stream == null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Missing wheel art: " + text));
					wheelHighlighted = selected;
					return;
				}
				byte[] array = new byte[stream.Length];
				int num;
				for (int i = 0; i < array.Length; i += num)
				{
					num = stream.Read(array, i, array.Length - i);
					if (num <= 0)
					{
						break;
					}
				}
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				if (!ImageConversion.LoadImage(val, array))
				{
					Object.Destroy((Object)(object)val);
					wheelHighlighted = selected;
					return;
				}
				((Texture)val).filterMode = (FilterMode)1;
				wheelArtCache[text] = val;
				petWheelTexture = val;
				wheelHighlighted = selected;
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Wheel art: " + ex.Message));
				wheelHighlighted = selected;
			}
		}

		private static string GetLocalizedPetName(Character pet)
		{
			if (!Object.op_Implicit((Object)(object)pet))
			{
				return string.Empty;
			}
			try
			{
				Tameable component = ((Component)pet).GetComponent<Tameable>();
				if (Object.op_Implicit((Object)(object)component))
				{
					MethodInfo methodInfo = AccessTools.Method(((object)component).GetType(), "GetText", Type.EmptyTypes, (Type[])null);
					if (methodInfo != null)
					{
						string text = methodInfo.Invoke(component, null) as string;
						if (!string.IsNullOrWhiteSpace(text))
						{
							return text;
						}
					}
				}
				string text2 = null;
				FieldInfo fieldInfo = AccessTools.Field(typeof(Character), "m_name");
				if (fieldInfo != null)
				{
					text2 = fieldInfo.GetValue(pet) as string;
				}
				if (string.IsNullOrEmpty(text2))
				{
					MethodInfo methodInfo2 = AccessTools.Method(((object)pet).GetType(), "GetHoverName", Type.EmptyTypes, (Type[])null);
					if (methodInfo2 != null)
					{
						text2 = methodInfo2.Invoke(pet, null) as string;
					}
				}
				if (!string.IsNullOrEmpty(text2))
				{
					Type type = AccessTools.TypeByName("Localization");
					if (type != null)
					{
						FieldInfo field = type.GetField("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
						PropertyInfo property = type.GetProperty("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
						object obj = ((field != null) ? field.GetValue(null) : ((property != null) ? property.GetValue(null, null) : null));
						MethodInfo methodInfo3 = AccessTools.Method(type, "Localize", new Type[1] { typeof(string) }, (Type[])null);
						if (obj != null && methodInfo3 != null)
						{
							string text3 = methodInfo3.Invoke(obj, new object[1] { text2 }) as string;
							if (!string.IsNullOrEmpty(text3))
							{
								return text3;
							}
						}
					}
				}
				return string.IsNullOrEmpty(text2) ? PrefabName(((Component)pet).gameObject) : text2;
			}
			catch
			{
				return PrefabName(((Component)pet).gameObject);
			}
		}

		private static string GetPetStatus(Character pet)
		{
			if (!Object.op_Implicit((Object)(object)pet))
			{
				return "";
			}
			bool flag = false;
			bool flag2 = false;
			try
			{
				Tameable component = ((Component)pet).GetComponent<Tameable>();
				MonsterAI component2 = ((Component)pet).GetComponent<MonsterAI>();
				object[] array = new object[2] { component, component2 };
				foreach (object obj in array)
				{
					if (obj != null)
					{
						MethodInfo method = obj.GetType().GetMethod("IsHungry", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
						if (!(method == null) && !(method.ReturnType != typeof(bool)))
						{
							flag = (bool)method.Invoke(obj, null);
							flag2 = true;
							break;
						}
					}
				}
			}
			catch
			{
			}
			bool flag3 = false;
			try
			{
				Procreation component3 = ((Component)pet).GetComponent<Procreation>();
				if (Object.op_Implicit((Object)(object)component3))
				{
					MethodInfo method2 = ((object)component3).GetType().GetMethod("IsPregnant", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
					if (method2 != null && method2.ReturnType == typeof(bool))
					{
						flag3 = (bool)method2.Invoke(component3, null);
					}
				}
			}
			catch
			{
			}
			string text = ((!flag2) ? Tr("Приручен") : (flag ? Tr("Голоден") : Tr("Сыт")));
			if (!flag3)
			{
				return text;
			}
			return text + "\n" + Tr("Беременность");
		}

		private static Font FindWheelFont()
		{
			Font result = null;
			Font[] array = Resources.FindObjectsOfTypeAll<Font>();
			foreach (Font val in array)
			{
				if (!Object.op_Implicit((Object)(object)val))
				{
					continue;
				}
				string text = ((Object)val).name.ToLowerInvariant();
				switch (text)
				{
				case "norse":
				case "norsebold":
				case "norse-bold":
					return val;
				}
				if (text.Contains("norse"))
				{
					result = val;
				}
			}
			return result;
		}

		private static Font FindActionFont()
		{
			Font result = null;
			Font[] array = Resources.FindObjectsOfTypeAll<Font>();
			foreach (Font val in array)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					string text = ((Object)val).name.ToLowerInvariant().Replace(" ", "").Replace("-", "")
						.Replace("_", "");
					if (text.Contains("averia") && text.Contains("bold"))
					{
						return val;
					}
					if (text.Contains("averia"))
					{
						result = val;
					}
				}
			}
			return result;
		}

		private void OnGUI()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Invalid comparison between Unknown and I4
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Expected O, but got Unknown
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0486: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_0370: Expected O, but got Unknown
			//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d0: Expected O, but got Unknown
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_0425: Unknown result type (might be due to invalid IL or missing references)
			//IL_042f: Expected O, but got Unknown
			//IL_05fe: 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_0620: Unknown result type (might be due to invalid IL or missing references)
			//IL_055a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0566: Unknown result type (might be due to invalid IL or missing references)
			//IL_057c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0691: Unknown result type (might be due to invalid IL or missing references)
			//IL_069d: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d5: Unknown result type (might be due to invalid IL or missing references)