Decompiled source of SakeysPocketDvergr v1.0.0

BepInEx/plugins/Sakey's Pocket Dvergr/Sakey's Pocket Dvergr.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Sakey's Pocket Dvergr")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Sakey's Pocket Dvergr")]
[assembly: AssemblyTitle("Sakey's Pocket Dvergr")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SakeysPocketDverger;

[BepInPlugin("com.sakey.pocketdverger", "Sakey's Pocket Dvergr", "0.1.35")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
	public const string PluginGUID = "com.sakey.pocketdverger";

	public const string PluginName = "Sakey's Pocket Dvergr";

	public const string PluginVersion = "0.1.35";

	private const string ASSET_BUNDLE_NAME = "pocketdvergr";

	private const float STAND_DOLL_MODEL_SCALE = 1.5f;

	private const float STAND_SUPPORT_MODEL_SCALE = 0.25f;

	private const float STAND_DOLL_MODEL_Y_OFFSET = 0.25f;

	private const float STAND_SUPPORT_MODEL_Y_OFFSET = 0.18f;

	private const float WORLD_DOLL_MODEL_SCALE = 1.5f;

	private const float WORLD_SUPPORT_MODEL_SCALE = 0.25f;

	public const string ROGUE_DOLL_MODEL = "PokeDve_Rogue";

	public const string SUPPORT_DOLL_MODEL = "PokeDve_Support";

	public const string MAGE_DOLL_MODEL = "PokeDve_Mage";

	private const string ROGUE_ICON = "icon_pokedverogue";

	private const string SUPPORT_ICON = "icon_pokedvesupport";

	private const string MAGE_ICON = "icon_pokedvemage";

	public const string ROGUE_ITEM = "PokeDve_RogueContract";

	public const string SUPPORT_ITEM = "PokeDve_SupportContract";

	public const string MAGE_ITEM = "PokeDve_MageContract";

	public const string ROGUE_BROKEN_ITEM = "PokeDve_RogueBroken";

	public const string SUPPORT_BROKEN_ITEM = "PokeDve_SupportBroken";

	public const string MAGE_BROKEN_ITEM = "PokeDve_MageBroken";

	public const string DVERGR_FAVORITE_ITEM = "PokeDve_DvergrFavorite";

	public const string ROGUE_SOURCE = "Dverger";

	public const string SUPPORT_SOURCE = "DvergerMageSupport";

	public const string MAGE_SOURCE = "DvergerMageIce";

	internal static ConfigEntry<KeyboardShortcut> CommandKey;

	internal static ConfigEntry<int> RoguePrice;

	internal static ConfigEntry<int> SupportPrice;

	internal static ConfigEntry<int> MagePrice;

	internal static ConfigEntry<int> FavoritePrice;

	internal static ConfigEntry<float> FollowLeashDistance;

	internal static ConfigEntry<float> FollowTargetDistance;

	internal static ConfigEntry<float> FollowViewRangeMultiplier;

	internal static ConfigEntry<float> FollowHearRangeMultiplier;

	internal static ConfigEntry<bool> EmergencyRecallOnHostility;

	internal static ItemDrop DvergrFavoriteItem;

	private AssetBundle pocketBundle;

	private readonly Dictionary<PocketDvergerType, ItemDrop> activeItems = new Dictionary<PocketDvergerType, ItemDrop>();

	private readonly Dictionary<PocketDvergerType, ItemDrop> brokenItems = new Dictionary<PocketDvergerType, ItemDrop>();

	private void Awake()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		new Harmony("com.sakey.pocketdverger").PatchAll();
		CommandKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "CommandKey", new KeyboardShortcut((KeyCode)284, Array.Empty<KeyCode>()), "Pocket Dvergr command selection key. F3 cycles Follow/Stay -> Retrieve.");
		RoguePrice = ((BaseUnityPlugin)this).Config.Bind<int>("Shop - Haldor", "RoguePrice", 1000, "Price of the Dvergr Rogue friend.");
		SupportPrice = ((BaseUnityPlugin)this).Config.Bind<int>("Shop - Haldor", "SupportPrice", 1000, "Price of the Dvergr Supporter friend.");
		MagePrice = ((BaseUnityPlugin)this).Config.Bind<int>("Shop - Haldor", "MagePrice", 1000, "Price of the Dvergr Mage friend.");
		FavoritePrice = ((BaseUnityPlugin)this).Config.Bind<int>("Shop - Haldor", "FavoritePrice", 10, "Price of the Dvergr Favorite.");
		RoguePrice.SettingChanged += delegate
		{
			RefreshHaldorPrice(PocketDvergerType.Rogue, RoguePrice.Value);
		};
		SupportPrice.SettingChanged += delegate
		{
			RefreshHaldorPrice(PocketDvergerType.Support, SupportPrice.Value);
		};
		MagePrice.SettingChanged += delegate
		{
			RefreshHaldorPrice(PocketDvergerType.Mage, MagePrice.Value);
		};
		FavoritePrice.SettingChanged += delegate
		{
			RefreshDvergrFavoritePrice(FavoritePrice.Value);
		};
		FollowLeashDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Follow AI", "MaxFollowLeash", 20f, "Maximum distance in meters from the owner before the companion drops its enemy target and returns. This only applies while Follow is active.");
		FollowTargetDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Follow AI", "MaxEnemyDistanceFromOwner", 10f, "Maximum distance in meters an enemy may be from the owner while the companion is following. Targets farther away are ignored/dropped.");
		FollowViewRangeMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Follow AI", "ViewRangeMultiplier", 0.65f, "Multiplier for Dvergr sight range while Follow is active. Lower values reduce unnecessary enemy detection.");
		FollowHearRangeMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Follow AI", "HearRangeMultiplier", 0.65f, "Multiplier for Dvergr hearing range while Follow is active. Lower values reduce unnecessary enemy detection.");
		EmergencyRecallOnHostility = ((BaseUnityPlugin)this).Config.Bind<bool>("Safety", "EmergencyRecallOnHostility", true, "If a Pocket Dvergr is attacked by its owner or becomes hostile toward its owner, immediately return all active Pocket Dvergrs to their 0-durability dolls.");
		SetupLocalization();
		PrefabManager.OnVanillaPrefabsAvailable += RegisterAll;
	}

	private void RegisterAll()
	{
		try
		{
			LoadAssetBundle();
			RegisterActiveItem(PocketDvergerType.Rogue, "PokeDve_RogueContract", "PokeDve_Rogue", "icon_pokedverogue");
			RegisterActiveItem(PocketDvergerType.Support, "PokeDve_SupportContract", "PokeDve_Support", "icon_pokedvesupport");
			RegisterActiveItem(PocketDvergerType.Mage, "PokeDve_MageContract", "PokeDve_Mage", "icon_pokedvemage");
			RegisterBrokenItem(PocketDvergerType.Rogue, "PokeDve_RogueBroken", "PokeDve_Rogue", "icon_pokedverogue");
			RegisterBrokenItem(PocketDvergerType.Support, "PokeDve_SupportBroken", "PokeDve_Support", "icon_pokedvesupport");
			RegisterBrokenItem(PocketDvergerType.Mage, "PokeDve_MageBroken", "PokeDve_Mage", "icon_pokedvemage");
			RegisterDvergrFavorite();
			RegisterRepairRecipe(PocketDvergerType.Rogue, "PokeDve_RogueBroken", "PokeDve_RogueContract", "PokeDve_DvergrFavorite");
			RegisterRepairRecipe(PocketDvergerType.Support, "PokeDve_SupportBroken", "PokeDve_SupportContract", "PokeDve_DvergrFavorite");
			RegisterRepairRecipe(PocketDvergerType.Mage, "PokeDve_MageBroken", "PokeDve_MageContract", "PokeDve_DvergrFavorite");
			RegisterCompanionSafe("PokeDve_RogueCompanion", "Dverger", PocketDvergerType.Rogue);
			RegisterCompanionSafe("PokeDve_SupportCompanion", "DvergerMageSupport", PocketDvergerType.Support);
			RegisterCompanionSafe("PokeDve_MageCompanion", "DvergerMageIce", PocketDvergerType.Mage);
			AddActiveItemsToHaldor();
			AddDvergrFavoriteToHaldor();
			Logger.LogInfo((object)"Pocket Dverger: registration completed.");
		}
		catch (Exception arg)
		{
			Logger.LogError((object)$"Pocket Dverger registration failed: {arg}");
		}
		finally
		{
			PrefabManager.OnVanillaPrefabsAvailable -= RegisterAll;
		}
	}

	private void LoadAssetBundle()
	{
		string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? string.Empty, "pocketdvergr");
		pocketBundle = AssetBundle.LoadFromFile(text);
		if ((Object)(object)pocketBundle == (Object)null)
		{
			throw new InvalidOperationException("Pocket Dverger AssetBundle could not be loaded: " + text);
		}
		Logger.LogInfo((object)("Pocket Dverger: AssetBundle loaded: " + text));
	}

	private GameObject LoadDollModel(string assetName)
	{
		if ((Object)(object)pocketBundle == (Object)null)
		{
			throw new InvalidOperationException("Pocket Dverger AssetBundle is not loaded.");
		}
		GameObject obj = pocketBundle.LoadAsset<GameObject>(assetName);
		if ((Object)(object)obj == (Object)null)
		{
			throw new InvalidOperationException("Pocket Dverger model not found in AssetBundle: " + assetName);
		}
		return obj;
	}

	private Sprite LoadIcon(string assetName)
	{
		if ((Object)(object)pocketBundle == (Object)null)
		{
			throw new InvalidOperationException("Pocket Dverger AssetBundle is not loaded.");
		}
		Sprite obj = pocketBundle.LoadAsset<Sprite>(assetName);
		if ((Object)(object)obj == (Object)null)
		{
			throw new InvalidOperationException("Pocket Dverger icon not found in AssetBundle: " + assetName);
		}
		return obj;
	}

	private void AddDollVisual(GameObject itemPrefab, string modelName, string iconName)
	{
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		Sprite val = LoadIcon(iconName);
		GameObject obj = LoadDollModel(modelName);
		Transform val2 = itemPrefab.transform.Find("attach");
		if ((Object)(object)val2 == (Object)null)
		{
			val2 = new GameObject("attach").transform;
			val2.SetParent(itemPrefab.transform, false);
		}
		GameObject val3 = Object.Instantiate<GameObject>(obj, val2);
		((Object)val3).name = modelName;
		val3.transform.localRotation = Quaternion.Euler(0f, 180f, 0f);
		float num = ((modelName == "PokeDve_Support") ? 0.25f : 1.5f);
		val3.transform.localScale = Vector3.one * num;
		float num2 = ((modelName == "PokeDve_Support") ? 0.18f : 0.25f);
		val3.transform.localPosition = new Vector3(0f, num2, 0f);
		PrepareDollRenderers(val3);
		GameObject val4 = Object.Instantiate<GameObject>(obj, itemPrefab.transform);
		((Object)val4).name = "worldVisual";
		val4.transform.localRotation = Quaternion.Euler(0f, 180f, 0f);
		float num3 = ((modelName == "PokeDve_Support") ? 0.25f : 1.5f);
		val4.transform.localScale = Vector3.one * num3;
		val4.transform.localPosition = Vector3.zero;
		PrepareDollRenderers(val4);
		val4.SetActive(false);
		PocketDvergerWorldVisual pocketDvergerWorldVisual = itemPrefab.GetComponent<PocketDvergerWorldVisual>();
		if ((Object)(object)pocketDvergerWorldVisual == (Object)null)
		{
			pocketDvergerWorldVisual = itemPrefab.AddComponent<PocketDvergerWorldVisual>();
		}
		pocketDvergerWorldVisual.AttachRoot = ((Component)val2).gameObject;
		pocketDvergerWorldVisual.WorldVisual = val4;
		ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
		if ((Object)(object)component == (Object)null || component.m_itemData == null || component.m_itemData.m_shared == null)
		{
			throw new InvalidOperationException("ItemDrop/SharedData missing on " + ((Object)itemPrefab).name);
		}
		component.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { val };
		component.m_itemData.m_variant = 0;
	}

	private void PrepareDollRenderers(GameObject model)
	{
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Expected O, but got Unknown
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
		Shader val = Shader.Find("Custom/Creature");
		Shader val2 = Shader.Find("Standard");
		Renderer[] componentsInChildren = model.GetComponentsInChildren<Renderer>(true);
		Collider[] componentsInChildren2;
		foreach (Renderer val3 in componentsInChildren)
		{
			if (val3 is ParticleSystemRenderer)
			{
				val3.enabled = false;
				continue;
			}
			Collider component = ((Component)val3).GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				component.enabled = false;
			}
			componentsInChildren2 = ((Component)val3).GetComponentsInChildren<Collider>(true);
			for (int j = 0; j < componentsInChildren2.Length; j++)
			{
				componentsInChildren2[j].enabled = false;
			}
			Material[] sharedMaterials = val3.sharedMaterials;
			Material[] array = (Material[])(object)new Material[sharedMaterials.Length];
			for (int k = 0; k < sharedMaterials.Length; k++)
			{
				Material val4 = sharedMaterials[k];
				if ((Object)(object)val4 == (Object)null)
				{
					array[k] = null;
					continue;
				}
				Shader val5 = (((Object)(object)val != (Object)null) ? val : val2);
				if ((Object)(object)val5 == (Object)null)
				{
					array[k] = val4;
					continue;
				}
				Material val6 = new Material(val5);
				((Object)val6).name = ((Object)val4).name + "_PocketDvergrRuntime";
				Texture val7 = null;
				if (val4.HasProperty("_MainTex"))
				{
					val7 = val4.GetTexture("_MainTex");
				}
				else if (val4.HasProperty("_BaseMap"))
				{
					val7 = val4.GetTexture("_BaseMap");
				}
				if ((Object)(object)val7 != (Object)null && val6.HasProperty("_MainTex"))
				{
					val6.SetTexture("_MainTex", val7);
				}
				if (val4.HasProperty("_Color") && val6.HasProperty("_Color"))
				{
					val6.SetColor("_Color", val4.GetColor("_Color"));
				}
				if (val4.HasProperty("_EmissionColor") && val6.HasProperty("_EmissionColor"))
				{
					val6.SetColor("_EmissionColor", val4.GetColor("_EmissionColor"));
				}
				array[k] = val6;
			}
			val3.sharedMaterials = array;
		}
		componentsInChildren2 = model.GetComponentsInChildren<Collider>(true);
		for (int i = 0; i < componentsInChildren2.Length; i++)
		{
			componentsInChildren2[i].enabled = false;
		}
	}

	private CustomItem CreateEmptyItem(string prefabName)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Expected O, but got Unknown
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		CustomItem val = new CustomItem(prefabName, true);
		if ((Object)(object)val.ItemDrop == (Object)null)
		{
			throw new InvalidOperationException("CustomItem created without ItemDrop: " + prefabName);
		}
		GameObject itemPrefab = val.ItemPrefab;
		Renderer[] components = itemPrefab.GetComponents<Renderer>();
		for (int i = 0; i < components.Length; i++)
		{
			components[i].enabled = false;
		}
		if ((Object)(object)itemPrefab.GetComponent<Rigidbody>() == (Object)null)
		{
			Rigidbody obj = itemPrefab.AddComponent<Rigidbody>();
			obj.mass = 0.1f;
			obj.useGravity = true;
			obj.isKinematic = false;
			obj.detectCollisions = true;
			obj.interpolation = (RigidbodyInterpolation)1;
			obj.collisionDetectionMode = (CollisionDetectionMode)2;
		}
		if ((Object)(object)itemPrefab.GetComponent<ZNetView>() == (Object)null)
		{
			itemPrefab.AddComponent<ZNetView>().m_persistent = true;
		}
		if ((Object)(object)itemPrefab.GetComponent<ZSyncTransform>() == (Object)null)
		{
			itemPrefab.AddComponent<ZSyncTransform>();
		}
		if ((Object)(object)itemPrefab.GetComponent<Collider>() == (Object)null)
		{
			SphereCollider obj2 = itemPrefab.AddComponent<SphereCollider>();
			obj2.radius = 0.15f;
			obj2.center = new Vector3(0f, 0.05f, 0f);
		}
		int num = LayerMask.NameToLayer("item");
		if (num >= 0)
		{
			itemPrefab.layer = num;
		}
		return val;
	}

	private void RegisterActiveItem(PocketDvergerType type, string prefabName, string modelName, string iconName)
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		CustomItem val = CreateEmptyItem(prefabName);
		ItemDrop itemDrop = val.ItemDrop;
		SharedData shared = itemDrop.m_itemData.m_shared;
		shared.m_name = GetActiveName(type);
		shared.m_description = GetActiveDescription(type);
		shared.m_itemType = (ItemType)16;
		shared.m_maxStackSize = 1;
		shared.m_weight = 1f;
		shared.m_questItem = false;
		shared.m_trophyPos = Vector2Int.zero;
		shared.m_useDurability = false;
		shared.m_maxDurability = 0f;
		shared.m_durabilityPerLevel = 0f;
		shared.m_destroyBroken = false;
		shared.m_canBeReparied = false;
		shared.m_movementModifier = 0f;
		AddDollVisual(val.ItemPrefab, modelName, iconName);
		itemDrop.m_itemData.m_dropPrefab = val.ItemPrefab;
		if (!ItemManager.Instance.AddItem(val))
		{
			throw new InvalidOperationException("Failed to register active item: " + prefabName);
		}
		activeItems[type] = itemDrop;
		Logger.LogInfo((object)("Pocket Dverger: active item registered: " + prefabName));
	}

	private void RegisterBrokenItem(PocketDvergerType type, string prefabName, string modelName, string iconName)
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		CustomItem val = CreateEmptyItem(prefabName);
		ItemDrop itemDrop = val.ItemDrop;
		SharedData shared = itemDrop.m_itemData.m_shared;
		shared.m_name = GetBrokenName(type);
		shared.m_description = GetBrokenDescription(type);
		shared.m_itemType = (ItemType)16;
		shared.m_maxStackSize = 20;
		shared.m_weight = 1f;
		shared.m_questItem = false;
		shared.m_trophyPos = Vector2Int.zero;
		shared.m_useDurability = true;
		shared.m_maxDurability = 100f;
		shared.m_durabilityPerLevel = 0f;
		shared.m_destroyBroken = false;
		shared.m_canBeReparied = false;
		shared.m_movementModifier = 0f;
		AddDollVisual(val.ItemPrefab, modelName, iconName);
		itemDrop.m_itemData.m_durability = 0f;
		itemDrop.m_itemData.m_dropPrefab = val.ItemPrefab;
		if (!ItemManager.Instance.AddItem(val))
		{
			throw new InvalidOperationException("Failed to register broken item: " + prefabName);
		}
		brokenItems[type] = itemDrop;
		Logger.LogInfo((object)("Pocket Dverger: broken item registered: " + prefabName));
	}

	private void RegisterDvergrFavorite()
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		CustomItem val = new CustomItem("PokeDve_DvergrFavorite", "Sausages");
		ItemDrop itemDrop = val.ItemDrop;
		if ((Object)(object)itemDrop == (Object)null || itemDrop.m_itemData == null || itemDrop.m_itemData.m_shared == null)
		{
			throw new InvalidOperationException("Dvergr favorite item could not be cloned from Sausages.");
		}
		SharedData shared = itemDrop.m_itemData.m_shared;
		shared.m_name = "$SakeysPocketDverger_FavoriteName";
		shared.m_description = "$SakeysPocketDverger_FavoriteDesc";
		shared.m_itemType = (ItemType)2;
		shared.m_maxStackSize = 20;
		shared.m_consumeStatusEffect = null;
		shared.m_attackStatusEffect = null;
		shared.m_equipStatusEffect = null;
		shared.m_setStatusEffect = null;
		itemDrop.m_itemData.m_dropPrefab = val.ItemPrefab;
		if (!ItemManager.Instance.AddItem(val))
		{
			throw new InvalidOperationException("Failed to register Dvergr favorite item.");
		}
		DvergrFavoriteItem = itemDrop;
	}

	private void AddActiveItemsToHaldor()
	{
		GameObject prefab = PrefabManager.Instance.GetPrefab("Haldor");
		Trader val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Trader>() : null);
		if ((Object)(object)val == (Object)null)
		{
			throw new InvalidOperationException("Haldor Trader not found.");
		}
		if (val.m_items == null)
		{
			val.m_items = new List<TradeItem>();
		}
		if (val.m_useItems == null)
		{
			val.m_useItems = new List<TraderUseItem>();
		}
		AddTraderItem(val, PocketDvergerType.Rogue, RoguePrice.Value);
		AddTraderItem(val, PocketDvergerType.Support, SupportPrice.Value);
		AddTraderItem(val, PocketDvergerType.Mage, MagePrice.Value);
		SanitizeTraderItems(val);
	}

	private void AddTraderItem(Trader trader, PocketDvergerType type, int price)
	{
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Expected O, but got Unknown
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Expected O, but got Unknown
		if (!((Object)(object)trader == (Object)null) && trader.m_items != null)
		{
			if (!activeItems.TryGetValue(type, out var item) || (Object)(object)item == (Object)null)
			{
				throw new InvalidOperationException($"Active item missing for {type}");
			}
			if (!trader.m_items.Any((TradeItem x) => x != null && (Object)(object)x.m_prefab == (Object)(object)item))
			{
				Sprite safeIcon = GetSafeIcon(item);
				trader.m_items.Add(new TradeItem
				{
					m_prefab = item,
					m_stack = 1,
					m_price = Mathf.Max(0, price),
					m_requiredGlobalKey = string.Empty,
					m_levelUpEffect = false,
					m_buyPlayerEffects = new EffectList(),
					m_icon = safeIcon,
					m_name = (item.m_itemData.m_shared.m_name ?? string.Empty),
					m_tooltip = (item.m_itemData.m_shared.m_description ?? string.Empty),
					m_buyKey = string.Empty,
					m_incrementKey = string.Empty,
					m_incrementAmount = 0
				});
			}
		}
	}

	private void RefreshHaldorPrice(PocketDvergerType type, int price)
	{
		GameObject val = ((PrefabManager.Instance != null) ? PrefabManager.Instance.GetPrefab("Haldor") : null);
		Trader val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Trader>() : null);
		if ((Object)(object)val2 == (Object)null)
		{
			return;
		}
		EnsureHaldorRuntimeLists(val2);
		if (activeItems.TryGetValue(type, out var item) && !((Object)(object)item == (Object)null))
		{
			TradeItem val3 = ((IEnumerable<TradeItem>)val2.m_items).FirstOrDefault((Func<TradeItem, bool>)((TradeItem x) => x != null && (Object)(object)x.m_prefab == (Object)(object)item));
			if (val3 != null)
			{
				val3.m_price = Mathf.Max(0, price);
			}
			SanitizeTraderItems(val2);
		}
	}

	private static Sprite GetSafeIcon(ItemDrop item)
	{
		if ((Object)(object)item == (Object)null || item.m_itemData == null || item.m_itemData.m_shared == null)
		{
			return null;
		}
		Sprite[] icons = item.m_itemData.m_shared.m_icons;
		if (icons == null || icons.Length == 0)
		{
			return null;
		}
		int num = item.m_itemData.m_variant;
		if (num < 0 || num >= icons.Length)
		{
			num = 0;
		}
		return icons[num];
	}

	internal static void EnsureHaldorRuntimeListsForHarmony(Trader trader)
	{
		if (!((Object)(object)trader == (Object)null))
		{
			if (trader.m_items == null)
			{
				trader.m_items = new List<TradeItem>();
			}
			if (trader.m_useItems == null)
			{
				trader.m_useItems = new List<TraderUseItem>();
			}
		}
	}

	internal static void SanitizeTraderItems(Trader trader)
	{
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Expected O, but got Unknown
		if ((Object)(object)trader == (Object)null || trader.m_items == null)
		{
			return;
		}
		foreach (TradeItem item in trader.m_items)
		{
			if (item == null)
			{
				continue;
			}
			if (item.m_requiredGlobalKey == null)
			{
				item.m_requiredGlobalKey = string.Empty;
			}
			if (item.m_buyPlayerEffects == null)
			{
				item.m_buyPlayerEffects = new EffectList();
			}
			if (item.m_buyKey == null)
			{
				item.m_buyKey = string.Empty;
			}
			if (item.m_incrementKey == null)
			{
				item.m_incrementKey = string.Empty;
			}
			if ((Object)(object)item.m_prefab != (Object)null && item.m_prefab.m_itemData != null && item.m_prefab.m_itemData.m_shared != null)
			{
				if (item.m_name == null)
				{
					item.m_name = item.m_prefab.m_itemData.m_shared.m_name ?? string.Empty;
				}
				if (item.m_tooltip == null)
				{
					item.m_tooltip = item.m_prefab.m_itemData.m_shared.m_description ?? string.Empty;
				}
				if ((Object)(object)item.m_icon == (Object)null)
				{
					item.m_icon = GetSafeIcon(item.m_prefab);
				}
			}
			else
			{
				if (item.m_name == null)
				{
					item.m_name = string.Empty;
				}
				if (item.m_tooltip == null)
				{
					item.m_tooltip = string.Empty;
				}
			}
		}
	}

	private void AddDvergrFavoriteToHaldor()
	{
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_0190: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ca: Expected O, but got Unknown
		//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ff: 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_0223: Unknown result type (might be due to invalid IL or missing references)
		//IL_022e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0239: Unknown result type (might be due to invalid IL or missing references)
		//IL_0245: Expected O, but got Unknown
		GameObject prefab = PrefabManager.Instance.GetPrefab("Haldor");
		Trader val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Trader>() : null);
		if ((Object)(object)val == (Object)null)
		{
			Logger.LogError((object)"Pocket Dvergr: Haldor Trader component not found.");
			return;
		}
		EnsureHaldorRuntimeLists(val);
		ItemDrop item = DvergrFavoriteItem;
		if ((Object)(object)item == (Object)null || item.m_itemData == null || item.m_itemData.m_shared == null)
		{
			Logger.LogError((object)"Pocket Dvergr: Dvergr Favorite ItemDrop is missing.");
			return;
		}
		TradeItem val2 = ((IEnumerable<TradeItem>)val.m_items).FirstOrDefault((Func<TradeItem, bool>)((TradeItem x) => x != null && (Object)(object)x.m_prefab == (Object)(object)item));
		if (val2 != null)
		{
			val2.m_price = Mathf.Max(0, FavoritePrice.Value);
			val2.m_stack = 1;
			val2.m_requiredGlobalKey = string.Empty;
			val2.m_levelUpEffect = false;
			val2.m_buyPlayerEffects = (EffectList)(((object)val2.m_buyPlayerEffects) ?? ((object)new EffectList()));
			val2.m_icon = GetSafeIcon(item);
			val2.m_name = item.m_itemData.m_shared.m_name ?? string.Empty;
			val2.m_tooltip = item.m_itemData.m_shared.m_description ?? string.Empty;
			val2.m_buyKey = val2.m_buyKey ?? string.Empty;
			val2.m_incrementKey = val2.m_incrementKey ?? string.Empty;
			val2.m_incrementAmount = 0;
			SanitizeTraderItems(val);
		}
		else
		{
			val.m_items.Add(new TradeItem
			{
				m_prefab = item,
				m_stack = 1,
				m_price = Mathf.Max(0, FavoritePrice.Value),
				m_requiredGlobalKey = string.Empty,
				m_levelUpEffect = false,
				m_buyPlayerEffects = new EffectList(),
				m_icon = GetSafeIcon(item),
				m_name = (item.m_itemData.m_shared.m_name ?? string.Empty),
				m_tooltip = (item.m_itemData.m_shared.m_description ?? string.Empty),
				m_buyKey = string.Empty,
				m_incrementKey = string.Empty,
				m_incrementAmount = 0
			});
			SanitizeTraderItems(val);
			Logger.LogInfo((object)$"Pocket Dvergr: Dvergr Favorite added to Haldor for {FavoritePrice.Value} coins.");
		}
	}

	private void RefreshDvergrFavoritePrice(int price)
	{
		GameObject val = ((PrefabManager.Instance != null) ? PrefabManager.Instance.GetPrefab("Haldor") : null);
		Trader val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Trader>() : null);
		if (!((Object)(object)val2 == (Object)null) && val2.m_items != null && !((Object)(object)DvergrFavoriteItem == (Object)null))
		{
			TradeItem val3 = ((IEnumerable<TradeItem>)val2.m_items).FirstOrDefault((Func<TradeItem, bool>)((TradeItem x) => x != null && (Object)(object)x.m_prefab == (Object)(object)DvergrFavoriteItem));
			if (val3 != null)
			{
				val3.m_price = Mathf.Max(0, price);
			}
			EnsureHaldorRuntimeLists(val2);
			SanitizeTraderItems(val2);
		}
	}

	private static void EnsureHaldorRuntimeLists(Trader trader)
	{
		if (!((Object)(object)trader == (Object)null))
		{
			if (trader.m_items == null)
			{
				trader.m_items = new List<TradeItem>();
			}
			if (trader.m_useItems == null)
			{
				trader.m_useItems = new List<TraderUseItem>();
			}
		}
	}

	private void RegisterRepairRecipe(PocketDvergerType type, string brokenPrefab, string repairedPrefab, string materialPrefab)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Expected O, but got Unknown
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Expected O, but got Unknown
		RecipeConfig val = new RecipeConfig
		{
			Name = $"SakeysPocketDverger_Repair_{type}",
			Item = repairedPrefab,
			Amount = 1,
			CraftingStation = "piece_workbench",
			MinStationLevel = 1
		};
		val.AddRequirement(brokenPrefab, 1, 0);
		val.AddRequirement(materialPrefab, 1, 0);
		if (!ItemManager.Instance.AddRecipe(new CustomRecipe(val)))
		{
			throw new InvalidOperationException($"Failed to register repair recipe for {type}");
		}
		Logger.LogInfo((object)$"Pocket Dverger: repair recipe registered: {type} + {materialPrefab}");
	}

	private void RegisterCompanionSafe(string newPrefabName, string sourcePrefabName, PocketDvergerType type)
	{
		try
		{
			RegisterCompanion(newPrefabName, sourcePrefabName, type);
		}
		catch (Exception arg)
		{
			Logger.LogError((object)$"Pocket Dverger: companion registration failed: {newPrefabName}: {arg}");
		}
	}

	private void RegisterCompanion(string newPrefabName, string sourcePrefabName, PocketDvergerType type)
	{
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Expected O, but got Unknown
		if (!((Object)(object)PrefabManager.Instance.GetPrefab(newPrefabName) != (Object)null))
		{
			if ((Object)(object)PrefabManager.Instance.GetPrefab(sourcePrefabName) == (Object)null)
			{
				throw new InvalidOperationException("Source companion prefab not found: " + sourcePrefabName);
			}
			GameObject val = PrefabManager.Instance.CreateClonedPrefab(newPrefabName, sourcePrefabName);
			if ((Object)(object)val == (Object)null)
			{
				throw new InvalidOperationException("Failed to clone " + sourcePrefabName);
			}
			Humanoid component = val.GetComponent<Humanoid>();
			if ((Object)(object)component != (Object)null)
			{
				((Character)component).m_faction = (Faction)0;
				((Character)component).m_name = GetCompanionName(type);
			}
			Character component2 = val.GetComponent<Character>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.m_faction = (Faction)0;
			}
			Tameable component3 = val.GetComponent<Tameable>();
			if ((Object)(object)component3 != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component3);
			}
			CharacterDrop component4 = val.GetComponent<CharacterDrop>();
			if ((Object)(object)component4 != (Object)null)
			{
				component4.m_drops.Clear();
			}
			NpcTalk component5 = val.GetComponent<NpcTalk>();
			if ((Object)(object)component5 != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component5);
			}
			PocketDvergerCompanion pocketDvergerCompanion = val.GetComponent<PocketDvergerCompanion>();
			if ((Object)(object)pocketDvergerCompanion == (Object)null)
			{
				pocketDvergerCompanion = val.AddComponent<PocketDvergerCompanion>();
			}
			pocketDvergerCompanion.CompanionType = type;
			PrefabManager.Instance.AddPrefab(new CustomPrefab(val, true));
			PrefabManager.Instance.RegisterToZNetScene(val);
			Logger.LogInfo((object)("Pocket Dverger: companion registered: " + newPrefabName + " from " + sourcePrefabName));
		}
	}

	private void SetupLocalization()
	{
		CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
		string text = "Japanese";
		localization.AddTranslation(ref text, new Dictionary<string, string>
		{
			{ "SakeysPocketDverger_RogueName", "お友達のドヴェルグ" },
			{ "SakeysPocketDverger_SupportName", "お友達のサポーター" },
			{ "SakeysPocketDverger_MageName", "お友達のメイジ" },
			{ "SakeysPocketDverger_RogueDollName", "ドヴェルグのならず者の人形" },
			{ "SakeysPocketDverger_SupportDollName", "ドヴェルグのサポートの人形" },
			{ "SakeysPocketDverger_MageDollName", "ドヴェルグの魔術師の人形" },
			{ "SakeysPocketDverger_ModeFollow", "追従/待機" },
			{ "SakeysPocketDverger_ModeRetrieve", "回収" },
			{ "SakeysPocketDverger_RogueDesc", "ドヴェルグが封印されてる人形。お友達が出てくる。怒らせてはいけない。" },
			{ "SakeysPocketDverger_SupportDesc", "ドヴェルグが封印されてる人形。お友達が出てくる。怒らせてはいけない。" },
			{ "SakeysPocketDverger_MageDesc", "ドヴェルグが封印されてる人形。お友達が出てくる。怒らせてはいけない。" },
			{ "SakeysPocketDverger_RogueBrokenName", "ドヴェルグのならず者の人形" },
			{ "SakeysPocketDverger_SupportBrokenName", "ドヴェルグのサポートの人形" },
			{ "SakeysPocketDverger_MageBrokenName", "ドヴェルグの魔術師の人形" },
			{ "SakeysPocketDverger_RogueBrokenDesc", "ドヴェルグが人形になって戻ってこないときは、作業台でドヴェルグの好物をあげてみよう。きっと帰ってくる。" },
			{ "SakeysPocketDverger_SupportBrokenDesc", "ドヴェルグが人形になって戻ってこないときは、作業台でドヴェルグの好物をあげてみよう。きっと帰ってくる。" },
			{ "SakeysPocketDverger_MageBrokenDesc", "ドヴェルグが人形になって戻ってこないときは、作業台でドヴェルグの好物をあげてみよう。きっと帰ってくる。" },
			{ "SakeysPocketDverger_FavoriteName", "ドヴェルグの好物" },
			{ "SakeysPocketDverger_FavoriteDesc", "ドヴェルグの好物。人形になって戻ってこないときは、作業台でこれをあげてみよう。きっと帰ってくる。" },
			{ "SakeysPocketDverger_EmergencyRecall", "ドヴェルグが敵対したため、人形に戻った。" },
			{ "SakeysPocketDverger_AlreadyOut", "このお友達はすでに一緒に旅をしている。" },
			{ "SakeysPocketDverger_Follow", "ドヴェルグがついてくる。" },
			{ "SakeysPocketDverger_Stay", "ドヴェルグがここで待機する。" },
			{ "SakeysPocketDverger_Retrieved", "ドヴェルグを人形に戻した。" },
			{ "SakeysPocketDverger_RogueFollow", "ドヴェルグがついてくる。" },
			{ "SakeysPocketDverger_RogueStay", "ドヴェルグがここで待機する。" },
			{ "SakeysPocketDverger_RogueRetrieved", "ドヴェルグを人形に戻した。" },
			{ "SakeysPocketDverger_SupportFollow", "サポートドヴェルグがついてくる。" },
			{ "SakeysPocketDverger_SupportStay", "サポートドヴェルグがここで待機する。" },
			{ "SakeysPocketDverger_SupportRetrieved", "サポートドヴェルグを人形に戻した。" },
			{ "SakeysPocketDverger_MageFollow", "メイジドヴェルグがついてくる。" },
			{ "SakeysPocketDverger_MageStay", "メイジドヴェルグがここで待機する。" },
			{ "SakeysPocketDverger_MageRetrieved", "メイジドヴェルグを人形に戻した。" },
			{ "SakeysPocketDverger_Hover", "<color=yellow>$SakeysPocketDverger_DisplayName</color>" },
			{ "SakeysPocketDverger_DisplayName", "お友達" }
		});
		text = "English";
		localization.AddTranslation(ref text, new Dictionary<string, string>
		{
			{ "SakeysPocketDverger_RogueName", "Your Dvergr Friend" },
			{ "SakeysPocketDverger_SupportName", "Your Supporter Friend" },
			{ "SakeysPocketDverger_MageName", "Your Mage Friend" },
			{ "SakeysPocketDverger_RogueDollName", "Dvergr Rogue Doll" },
			{ "SakeysPocketDverger_SupportDollName", "Dvergr Support Doll" },
			{ "SakeysPocketDverger_MageDollName", "Dvergr Mage Doll" },
			{ "SakeysPocketDverger_ModeFollow", "Follow / Stay" },
			{ "SakeysPocketDverger_ModeRetrieve", "Retrieve" },
			{ "SakeysPocketDverger_RogueDesc", "A Dvergr is sealed inside. Your friend will come out. Don't make them angry." },
			{ "SakeysPocketDverger_SupportDesc", "A Dvergr is sealed inside. Your friend will come out. Don't make them angry." },
			{ "SakeysPocketDverger_MageDesc", "A Dvergr is sealed inside. Your friend will come out. Don't make them angry." },
			{ "SakeysPocketDverger_RogueBrokenName", "Dvergr Rogue Doll" },
			{ "SakeysPocketDverger_SupportBrokenName", "Dvergr Support Doll" },
			{ "SakeysPocketDverger_MageBrokenName", "Dvergr Mage Doll" },
			{ "SakeysPocketDverger_RogueBrokenDesc", "If your Dvergr has returned to its doll and will not come back, try giving it a Dvergr Favorite at a workbench. It will surely return." },
			{ "SakeysPocketDverger_SupportBrokenDesc", "If your Dvergr has returned to its doll and will not come back, try giving it a Dvergr Favorite at a workbench. It will surely return." },
			{ "SakeysPocketDverger_MageBrokenDesc", "If your Dvergr has returned to its doll and will not come back, try giving it a Dvergr Favorite at a workbench. It will surely return." },
			{ "SakeysPocketDverger_FavoriteName", "Dvergr Favorite" },
			{ "SakeysPocketDverger_FavoriteDesc", "A Dvergr favorite. If your doll does not come back, give this to it at a workbench. It will surely return." },
			{ "SakeysPocketDverger_EmergencyRecall", "The Dvergr became hostile, so they returned to their dolls." },
			{ "SakeysPocketDverger_AlreadyOut", "This friend is already traveling with you." },
			{ "SakeysPocketDverger_Follow", "The Dvergr will follow you." },
			{ "SakeysPocketDverger_Stay", "The Dvergr will stay here." },
			{ "SakeysPocketDverger_Retrieved", "The Dvergr has been returned to the doll." },
			{ "SakeysPocketDverger_RogueFollow", "The Dvergr will follow you." },
			{ "SakeysPocketDverger_RogueStay", "The Dvergr will stay here." },
			{ "SakeysPocketDverger_RogueRetrieved", "The Dvergr has been returned to the doll." },
			{ "SakeysPocketDverger_SupportFollow", "The Support Dvergr will follow you." },
			{ "SakeysPocketDverger_SupportStay", "The Support Dvergr will stay here." },
			{ "SakeysPocketDverger_SupportRetrieved", "The Support Dvergr has been returned to the doll." },
			{ "SakeysPocketDverger_MageFollow", "The Mage Dvergr will follow you." },
			{ "SakeysPocketDverger_MageStay", "The Mage Dvergr will stay here." },
			{ "SakeysPocketDverger_MageRetrieved", "The Mage Dvergr has been returned to the doll." },
			{ "SakeysPocketDverger_Hover", "<color=yellow>$SakeysPocketDverger_DisplayName</color>" },
			{ "SakeysPocketDverger_DisplayName", "Friend" }
		});
	}

	internal static string GetCompanionName(PocketDvergerType type)
	{
		return type switch
		{
			PocketDvergerType.Rogue => "$SakeysPocketDverger_RogueName", 
			PocketDvergerType.Support => "$SakeysPocketDverger_SupportName", 
			_ => "$SakeysPocketDverger_MageName", 
		};
	}

	internal static string GetFollowMessage(PocketDvergerType type)
	{
		return type switch
		{
			PocketDvergerType.Rogue => "$SakeysPocketDverger_RogueFollow", 
			PocketDvergerType.Support => "$SakeysPocketDverger_SupportFollow", 
			_ => "$SakeysPocketDverger_MageFollow", 
		};
	}

	internal static string GetStayMessage(PocketDvergerType type)
	{
		return type switch
		{
			PocketDvergerType.Rogue => "$SakeysPocketDverger_RogueStay", 
			PocketDvergerType.Support => "$SakeysPocketDverger_SupportStay", 
			_ => "$SakeysPocketDverger_MageStay", 
		};
	}

	internal static string GetRetrievedMessage(PocketDvergerType type)
	{
		return type switch
		{
			PocketDvergerType.Rogue => "$SakeysPocketDverger_RogueRetrieved", 
			PocketDvergerType.Support => "$SakeysPocketDverger_SupportRetrieved", 
			_ => "$SakeysPocketDverger_MageRetrieved", 
		};
	}

	internal static string GetActiveName(PocketDvergerType type)
	{
		return type switch
		{
			PocketDvergerType.Rogue => "$SakeysPocketDverger_RogueDollName", 
			PocketDvergerType.Support => "$SakeysPocketDverger_SupportDollName", 
			_ => "$SakeysPocketDverger_MageDollName", 
		};
	}

	internal static string GetActiveDescription(PocketDvergerType type)
	{
		return type switch
		{
			PocketDvergerType.Rogue => "$SakeysPocketDverger_RogueDesc", 
			PocketDvergerType.Support => "$SakeysPocketDverger_SupportDesc", 
			_ => "$SakeysPocketDverger_MageDesc", 
		};
	}

	internal static string GetBrokenName(PocketDvergerType type)
	{
		return type switch
		{
			PocketDvergerType.Rogue => "$SakeysPocketDverger_RogueBrokenName", 
			PocketDvergerType.Support => "$SakeysPocketDverger_SupportBrokenName", 
			_ => "$SakeysPocketDverger_MageBrokenName", 
		};
	}

	internal static string GetBrokenDescription(PocketDvergerType type)
	{
		return type switch
		{
			PocketDvergerType.Rogue => "$SakeysPocketDverger_RogueBrokenDesc", 
			PocketDvergerType.Support => "$SakeysPocketDverger_SupportBrokenDesc", 
			_ => "$SakeysPocketDverger_MageBrokenDesc", 
		};
	}

	internal static string GetActivePrefab(PocketDvergerType type)
	{
		return type switch
		{
			PocketDvergerType.Rogue => "PokeDve_RogueContract", 
			PocketDvergerType.Support => "PokeDve_SupportContract", 
			_ => "PokeDve_MageContract", 
		};
	}

	internal static string GetBrokenPrefab(PocketDvergerType type)
	{
		return type switch
		{
			PocketDvergerType.Rogue => "PokeDve_RogueBroken", 
			PocketDvergerType.Support => "PokeDve_SupportBroken", 
			_ => "PokeDve_MageBroken", 
		};
	}

	internal static string GetCompanionPrefab(PocketDvergerType type)
	{
		return type switch
		{
			PocketDvergerType.Rogue => "PokeDve_RogueCompanion", 
			PocketDvergerType.Support => "PokeDve_SupportCompanion", 
			_ => "PokeDve_MageCompanion", 
		};
	}

	private static IEnumerable<ZDO> GetLoadedZDOs()
	{
		if (ZDOMan.instance == null)
		{
			yield break;
		}
		FieldInfo field = typeof(ZDOMan).GetField("m_objectsByID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (field == null || !(field.GetValue(ZDOMan.instance) is IDictionary dictionary))
		{
			yield break;
		}
		foreach (DictionaryEntry item in dictionary)
		{
			object? value = item.Value;
			ZDO val = (ZDO)((value is ZDO) ? value : null);
			if (val != null)
			{
				yield return val;
			}
		}
	}

	internal static bool TryGetActive(long ownerId, PocketDvergerType type, out PocketDvergerCompanion found)
	{
		found = null;
		PocketDvergerCompanion[] array = Object.FindObjectsOfType<PocketDvergerCompanion>();
		foreach (PocketDvergerCompanion pocketDvergerCompanion in array)
		{
			if (!((Object)(object)pocketDvergerCompanion == (Object)null) && pocketDvergerCompanion.GetOwnerID() == ownerId && pocketDvergerCompanion.CompanionType == type)
			{
				found = pocketDvergerCompanion;
				return true;
			}
		}
		return false;
	}
}
internal class PocketDvergerWorldVisual : MonoBehaviour
{
	public GameObject AttachRoot;

	public GameObject WorldVisual;

	private void Start()
	{
		if ((Object)(object)AttachRoot != (Object)null)
		{
			AttachRoot.SetActive(false);
		}
		if ((Object)(object)WorldVisual != (Object)null)
		{
			WorldVisual.SetActive(true);
		}
	}
}
public enum PocketDvergerType
{
	Rogue,
	Support,
	Mage
}
public static class PocketDvergerContractUse
{
	public static bool TrySummon(Player owner, PocketDvergerType contractType, ItemData item, out PocketDvergerCompanion spawnedCompanion)
	{
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		spawnedCompanion = null;
		if ((Object)(object)owner == (Object)null || item == null)
		{
			return false;
		}
		if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer())
		{
			return false;
		}
		GameObject prefab = PrefabManager.Instance.GetPrefab(Plugin.GetCompanionPrefab(contractType));
		if ((Object)(object)prefab == (Object)null)
		{
			Logger.LogError((object)$"Pocket Dvergr companion prefab missing: {contractType}");
			return false;
		}
		Vector3 val = ((Component)owner).transform.position + ((Component)owner).transform.forward * 1.2f + Vector3.up * 0.1f;
		GameObject val2 = Object.Instantiate<GameObject>(prefab, val, ((Component)owner).transform.rotation);
		if ((Object)(object)val2 == (Object)null)
		{
			return false;
		}
		ZNetView component = val2.GetComponent<ZNetView>();
		if ((Object)(object)component == (Object)null || !component.IsValid())
		{
			Object.Destroy((Object)(object)val2);
			return false;
		}
		ZDO zDO = component.GetZDO();
		if (zDO == null)
		{
			Object.Destroy((Object)(object)val2);
			return false;
		}
		zDO.Set("SakeysPocketDverger_Owner", owner.GetPlayerID());
		zDO.Set("SakeysPocketDverger_Type", (int)contractType);
		zDO.Set("SakeysPocketDverger_Contract", Plugin.GetActivePrefab(contractType));
		PocketDvergerCompanion pocketDvergerCompanion = val2.GetComponent<PocketDvergerCompanion>();
		if ((Object)(object)pocketDvergerCompanion == (Object)null)
		{
			pocketDvergerCompanion = val2.AddComponent<PocketDvergerCompanion>();
		}
		pocketDvergerCompanion.CompanionType = contractType;
		pocketDvergerCompanion.Initialize(owner.GetPlayerID());
		spawnedCompanion = pocketDvergerCompanion;
		return true;
	}
}
internal static class PocketDvergerUseHelper
{
	public enum InventorySummonResult
	{
		NotPocketDvergr,
		Summoned,
		Failed
	}

	public static bool TryGetContractType(ItemData item, out PocketDvergerType type)
	{
		type = PocketDvergerType.Rogue;
		if (item == null || (Object)(object)item.m_dropPrefab == (Object)null)
		{
			return false;
		}
		switch (((Object)item.m_dropPrefab).name)
		{
		case "PokeDve_RogueContract":
			type = PocketDvergerType.Rogue;
			return true;
		case "PokeDve_SupportContract":
			type = PocketDvergerType.Support;
			return true;
		case "PokeDve_MageContract":
			type = PocketDvergerType.Mage;
			return true;
		default:
			return false;
		}
	}

	public static bool IsOnItemStand(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return false;
		}
		GameObject hoverObject = ((Humanoid)player).GetHoverObject();
		if ((Object)(object)hoverObject != (Object)null)
		{
			return (Object)(object)hoverObject.GetComponentInParent<ItemStand>() != (Object)null;
		}
		return false;
	}

	public static InventorySummonResult TrySummonFromInventory(Player player, Inventory inventory, ItemData item)
	{
		if ((Object)(object)player == (Object)null || item == null)
		{
			return InventorySummonResult.Failed;
		}
		if (!TryGetContractType(item, out var type))
		{
			return InventorySummonResult.NotPocketDvergr;
		}
		Inventory val = inventory ?? ((Humanoid)player).GetInventory();
		if (val == null || !val.ContainsItem(item))
		{
			return InventorySummonResult.Failed;
		}
		if (!PocketDvergerContractUse.TrySummon(player, type, item, out var spawnedCompanion))
		{
			return InventorySummonResult.Failed;
		}
		if (!val.RemoveOneItem(item))
		{
			Logger.LogError((object)"Pocket Dvergr: companion summoned but contract item could not be removed.");
			if ((Object)(object)spawnedCompanion != (Object)null)
			{
				if ((Object)(object)ZNetScene.instance != (Object)null)
				{
					ZNetScene.instance.Destroy(((Component)spawnedCompanion).gameObject);
				}
				else
				{
					Object.Destroy((Object)(object)((Component)spawnedCompanion).gameObject);
				}
			}
			return InventorySummonResult.Failed;
		}
		return InventorySummonResult.Summoned;
	}
}
[HarmonyPatch(typeof(Humanoid), "DropItem", new Type[]
{
	typeof(Inventory),
	typeof(ItemData),
	typeof(int)
})]
internal static class PocketDvergerHumanoidDropItemPatch
{
	private static bool Prefix(Humanoid __instance, Inventory inventory, ItemData item, int amount)
	{
		Player val = (Player)(object)((__instance is Player) ? __instance : null);
		if ((Object)(object)val == (Object)null || item == null || inventory == null)
		{
			return true;
		}
		if (amount != 1)
		{
			return true;
		}
		if (!PocketDvergerUseHelper.TryGetContractType(item, out var _))
		{
			return true;
		}
		return PocketDvergerUseHelper.TrySummonFromInventory(val, inventory, item) != PocketDvergerUseHelper.InventorySummonResult.Summoned;
	}
}
[HarmonyPatch(typeof(Trader), "OnBought")]
internal static class PocketDvergerHaldorOnBoughtPatch
{
	private static void Prefix(Trader __instance)
	{
		if (!((Object)(object)__instance == (Object)null) && string.Equals(((Object)((Component)__instance).gameObject).name.Replace("(Clone)", "").Trim(), "Haldor", StringComparison.OrdinalIgnoreCase))
		{
			Plugin.EnsureHaldorRuntimeListsForHarmony(__instance);
			Plugin.SanitizeTraderItems(__instance);
		}
	}
}
[HarmonyPatch(typeof(StoreGui), "FillList")]
internal static class PocketDvergerStoreGuiFillListPatch
{
	private static void Prefix(StoreGui __instance)
	{
		if ((Object)(object)__instance == (Object)null)
		{
			return;
		}
		try
		{
			Trader value = Traverse.Create((object)__instance).Field("m_trader").GetValue<Trader>();
			if ((Object)(object)value != (Object)null && string.Equals(((Object)((Component)value).gameObject).name.Replace("(Clone)", "").Trim(), "Haldor", StringComparison.OrdinalIgnoreCase))
			{
				Plugin.EnsureHaldorRuntimeListsForHarmony(value);
				Plugin.SanitizeTraderItems(value);
			}
		}
		catch (Exception ex)
		{
			Logger.LogDebug((object)("Pocket Dvergr: Haldor TradeItem sanitization skipped: " + ex.Message));
		}
	}
}
internal static class PocketDvergerEmergencyRecall
{
	private static bool running;

	public static void Trigger(Player owner, string reason)
	{
		if (running || (Object)(object)owner == (Object)null || !Plugin.EmergencyRecallOnHostility.Value || (Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer())
		{
			return;
		}
		running = true;
		try
		{
			PocketDvergerCompanion[] array = Object.FindObjectsOfType<PocketDvergerCompanion>();
			foreach (PocketDvergerCompanion pocketDvergerCompanion in array)
			{
				if (!((Object)(object)pocketDvergerCompanion == (Object)null) && pocketDvergerCompanion.GetOwnerID() == owner.GetPlayerID())
				{
					DropBrokenDoll(pocketDvergerCompanion);
				}
			}
			((Character)owner).Message((MessageType)2, "$SakeysPocketDverger_EmergencyRecall", 0, (Sprite)null, false);
		}
		finally
		{
			running = false;
		}
	}

	internal static void DropNaturalDeathDoll(PocketDvergerCompanion companion)
	{
		if (!((Object)(object)companion == (Object)null))
		{
			DropBrokenDoll(companion);
		}
	}

	private static void DropBrokenDoll(PocketDvergerCompanion companion)
	{
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: 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_0098: 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)
		companion.MarkEmergencyHandled();
		GameObject prefab = PrefabManager.Instance.GetPrefab(Plugin.GetBrokenPrefab(companion.CompanionType));
		if ((Object)(object)prefab == (Object)null)
		{
			Logger.LogError((object)$"Pocket Dvergr: emergency broken doll prefab missing for {companion.CompanionType}.");
			return;
		}
		ItemDrop component = prefab.GetComponent<ItemDrop>();
		if (!((Object)(object)component == (Object)null) && component.m_itemData != null)
		{
			ItemData obj = component.m_itemData.Clone();
			obj.m_dropPrefab = prefab;
			obj.m_stack = 1;
			obj.m_durability = 0f;
			ItemDrop val = ItemDrop.DropItem(obj, 1, ((Component)companion).transform.position + Vector3.up * 0.25f, Quaternion.identity);
			if ((Object)(object)val != (Object)null)
			{
				val.OnPlayerDrop();
			}
			if ((Object)(object)ZNetScene.instance != (Object)null)
			{
				ZNetScene.instance.Destroy(((Component)companion).gameObject);
			}
			else
			{
				Object.Destroy((Object)(object)((Component)companion).gameObject);
			}
		}
	}
}
[HarmonyPatch(typeof(Character), "Damage", new Type[] { typeof(HitData) })]
internal static class PocketDvergerFriendlyFirePatch
{
	private static bool Prefix(Character __instance, HitData hit)
	{
		if (!Plugin.EmergencyRecallOnHostility.Value || (Object)(object)__instance == (Object)null || hit == null)
		{
			return true;
		}
		PocketDvergerCompanion component = ((Component)__instance).GetComponent<PocketDvergerCompanion>();
		if ((Object)(object)component == (Object)null)
		{
			return true;
		}
		Character attacker = hit.GetAttacker();
		Player val = (Player)(object)((attacker is Player) ? attacker : null);
		if ((Object)(object)val == (Object)null || component.GetOwnerID() != val.GetPlayerID())
		{
			return true;
		}
		PocketDvergerEmergencyRecall.Trigger(val, "friendly fire");
		return false;
	}
}
[HarmonyPatch(typeof(Character), "OnDeath")]
internal static class PocketDvergerDeathDropPatch
{
	private static void Prefix(Character __instance)
	{
		PocketDvergerCompanion pocketDvergerCompanion = (((Object)(object)__instance != (Object)null) ? ((Component)__instance).GetComponent<PocketDvergerCompanion>() : null);
		if (!((Object)(object)pocketDvergerCompanion == (Object)null) && !pocketDvergerCompanion.IsEmergencyHandled)
		{
			PocketDvergerEmergencyRecall.DropNaturalDeathDoll(pocketDvergerCompanion);
		}
	}
}
public enum PocketDvergerCommandMode
{
	FollowStay,
	Retrieve
}
internal static class PocketDvergerCommandMenu
{
	private static PocketDvergerCommandMode selectedMode;

	public static void Cycle(PocketDvergerCompanion companion)
	{
		if (!((Object)(object)companion == (Object)null))
		{
			selectedMode = ((selectedMode == PocketDvergerCommandMode.FollowStay) ? PocketDvergerCommandMode.Retrieve : PocketDvergerCommandMode.FollowStay);
			ShowSelectedMessage(companion);
		}
	}

	public static bool Execute(PocketDvergerCompanion companion, Player player)
	{
		if ((Object)(object)companion == (Object)null || (Object)(object)player == (Object)null)
		{
			return false;
		}
		if (selectedMode == PocketDvergerCommandMode.Retrieve)
		{
			companion.Retrieve(player);
		}
		else
		{
			companion.ToggleFollowStay(player);
		}
		return true;
	}

	public static string GetModeDisplayKey()
	{
		if (selectedMode != PocketDvergerCommandMode.Retrieve)
		{
			return "$SakeysPocketDverger_ModeFollow";
		}
		return "$SakeysPocketDverger_ModeRetrieve";
	}

	public static void ShowSelectedMessage(PocketDvergerCompanion companion)
	{
		Player localPlayer = Player.m_localPlayer;
		if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)companion == (Object)null))
		{
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			string text = localization.TryTranslate(Plugin.GetCompanionName(companion.CompanionType));
			string text2 = localization.TryTranslate(GetModeDisplayKey());
			((Character)localPlayer).Message((MessageType)2, text + ":" + text2, 0, (Sprite)null, false);
		}
	}
}
internal class PocketDvergerInputController : MonoBehaviour
{
	private static int suppressInteractFrame = -1;

	public static bool SuppressInteractThisFrame()
	{
		if (suppressInteractFrame == Time.frameCount)
		{
			suppressInteractFrame = -1;
			return true;
		}
		return false;
	}

	private void Update()
	{
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null || Console.IsVisible() || Menu.IsVisible())
		{
			return;
		}
		if (ZInput.GetButton("JoyLBumper") && ZInput.GetButtonDown("JoyUse"))
		{
			Character hoverCreature = localPlayer.GetHoverCreature();
			PocketDvergerCompanion pocketDvergerCompanion = (((Object)(object)hoverCreature != (Object)null) ? ((Component)hoverCreature).GetComponent<PocketDvergerCompanion>() : null);
			if ((Object)(object)pocketDvergerCompanion != (Object)null && pocketDvergerCompanion.GetOwnerID() == localPlayer.GetPlayerID())
			{
				PocketDvergerCommandMenu.Cycle(pocketDvergerCompanion);
				suppressInteractFrame = Time.frameCount;
			}
		}
		if (CommandKeyPressed())
		{
			Character hoverCreature2 = localPlayer.GetHoverCreature();
			PocketDvergerCompanion pocketDvergerCompanion2 = (((Object)(object)hoverCreature2 != (Object)null) ? ((Component)hoverCreature2).GetComponent<PocketDvergerCompanion>() : null);
			if ((Object)(object)pocketDvergerCompanion2 != (Object)null && pocketDvergerCompanion2.GetOwnerID() == localPlayer.GetPlayerID())
			{
				PocketDvergerCommandMenu.Cycle(pocketDvergerCompanion2);
			}
		}
	}

	private static bool CommandKeyPressed()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		KeyboardShortcut value = Plugin.CommandKey.Value;
		if ((int)((KeyboardShortcut)(ref value)).MainKey == 0 || !Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey))
		{
			return false;
		}
		foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers)
		{
			if (!Input.GetKey(modifier))
			{
				return false;
			}
		}
		return true;
	}
}
[HarmonyPatch(typeof(PocketDvergerCompanion), "Interact")]
internal static class PocketDvergerControllerCyclePatch
{
	private static bool Prefix(Humanoid character)
	{
		if ((Object)(object)character == (Object)null || (Object)(object)character != (Object)(object)Player.m_localPlayer)
		{
			return true;
		}
		return !PocketDvergerInputController.SuppressInteractThisFrame();
	}
}
[HarmonyPatch(typeof(Player), "OnSpawned")]
internal static class PocketDvergerPlayerSpawnPatch
{
	private static void Postfix(Player __instance)
	{
		if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && (Object)(object)((Component)__instance).GetComponent<PocketDvergerInputController>() == (Object)null)
		{
			((Component)__instance).gameObject.AddComponent<PocketDvergerInputController>();
		}
	}
}
public class PocketDvergerCompanion : MonoBehaviour, Interactable
{
	private static readonly FieldInfo TargetCreatureField = AccessTools.Field(typeof(MonsterAI), "m_targetCreature");

	private static readonly FieldInfo TargetStaticField = AccessTools.Field(typeof(MonsterAI), "m_targetStatic");

	private static readonly MethodInfo SetAlertedMethod = AccessTools.Method(typeof(BaseAI), "SetAlerted", new Type[1] { typeof(bool) }, (Type[])null);

	private static readonly MethodInfo SetTargetInfoMethod = AccessTools.Method(typeof(BaseAI), "SetTargetInfo", new Type[1] { typeof(ZDOID) }, (Type[])null);

	private ZNetView nview;

	private MonsterAI monsterAI;

	private Humanoid humanoid;

	private bool initialized;

	private bool following;

	private float originalViewRange = -1f;

	private float originalHearRange = -1f;

	private int followAiCheckFrame;

	private bool emergencyHandled;

	public PocketDvergerType CompanionType;

	internal bool IsEmergencyHandled => emergencyHandled;

	private static void ClearCombatTarget(MonsterAI ai)
	{
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ai == (Object)null)
		{
			return;
		}
		try
		{
			TargetCreatureField?.SetValue(ai, null);
			TargetStaticField?.SetValue(ai, null);
			if (SetAlertedMethod != null)
			{
				SetAlertedMethod.Invoke(ai, new object[1] { false });
			}
			if (SetTargetInfoMethod != null)
			{
				SetTargetInfoMethod.Invoke(ai, new object[1] { ZDOID.None });
			}
		}
		catch (Exception ex)
		{
			Debug.LogWarning((object)("[Sakey's Pocket Dvergr] Failed to clear combat target: " + ex.Message));
		}
	}

	private void Awake()
	{
		nview = ((Component)this).GetComponent<ZNetView>();
		monsterAI = ((Component)this).GetComponent<MonsterAI>();
		humanoid = ((Component)this).GetComponent<Humanoid>();
		LoadType();
		ApplyDisplayName();
		Character component = ((Component)this).GetComponent<Character>();
		if ((Object)(object)component != (Object)null)
		{
			try
			{
				component.SetLevel(3);
			}
			catch (Exception arg)
			{
				Logger.LogError((object)$"Pocket Dverger: SetLevel failed: {arg}");
			}
		}
		initialized = true;
	}

	public void Initialize(long ownerId)
	{
		nview = ((Component)this).GetComponent<ZNetView>();
		monsterAI = ((Component)this).GetComponent<MonsterAI>();
		humanoid = ((Component)this).GetComponent<Humanoid>();
		initialized = true;
		if ((Object)(object)nview != (Object)null && nview.IsValid() && nview.IsOwner())
		{
			ZDO zDO = nview.GetZDO();
			zDO.Set("SakeysPocketDverger_Owner", ownerId);
			zDO.Set("SakeysPocketDverger_Type", (int)CompanionType);
			zDO.Set("SakeysPocketDverger_Contract", Plugin.GetActivePrefab(CompanionType));
		}
		ApplyDisplayName();
		Character component = ((Component)this).GetComponent<Character>();
		if ((Object)(object)component != (Object)null)
		{
			try
			{
				component.SetLevel(3);
			}
			catch (Exception arg)
			{
				Logger.LogError((object)$"Pocket Dverger: Initialize SetLevel failed: {arg}");
			}
		}
	}

	private void LateUpdate()
	{
		ApplyDisplayName();
	}

	private void ApplyDisplayName()
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)humanoid == (Object)null)
		{
			humanoid = ((Component)this).GetComponent<Humanoid>();
		}
		if ((Object)(object)humanoid != (Object)null)
		{
			((Character)humanoid).m_faction = (Faction)0;
			((Character)humanoid).m_name = Plugin.GetCompanionName(CompanionType);
		}
	}

	private void LoadType()
	{
		if (!((Object)(object)nview == (Object)null) && nview.IsValid())
		{
			ZDO zDO = nview.GetZDO();
			if (zDO != null)
			{
				CompanionType = (PocketDvergerType)zDO.GetInt("SakeysPocketDverger_Type", (int)CompanionType);
			}
		}
	}

	private void FixedUpdate()
	{
		if (!initialized || (Object)(object)nview == (Object)null || !nview.IsValid() || !nview.IsOwner())
		{
			return;
		}
		Player val = FindOwner();
		if (!((Object)(object)val == (Object)null) && !((Object)(object)monsterAI == (Object)null))
		{
			if (following)
			{
				monsterAI.SetFollowTarget(((Component)val).gameObject);
			}
			ApplyFollowBehavior();
		}
	}

	private void CacheOriginalAiRanges()
	{
		if (!((Object)(object)monsterAI == (Object)null))
		{
			BaseAI val = (BaseAI)(object)monsterAI;
			if (originalViewRange < 0f)
			{
				originalViewRange = val.m_viewRange;
			}
			if (originalHearRange < 0f)
			{
				originalHearRange = val.m_hearRange;
			}
		}
	}

	private void ApplyFollowBehavior()
	{
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)monsterAI == (Object)null)
		{
			return;
		}
		CacheOriginalAiRanges();
		BaseAI val = (BaseAI)(object)monsterAI;
		if (!following)
		{
			if (originalViewRange >= 0f)
			{
				val.m_viewRange = originalViewRange;
			}
			if (originalHearRange >= 0f)
			{
				val.m_hearRange = originalHearRange;
			}
			return;
		}
		val.m_viewRange = originalViewRange * Mathf.Clamp(Plugin.FollowViewRangeMultiplier.Value, 0.05f, 1f);
		val.m_hearRange = originalHearRange * Mathf.Clamp(Plugin.FollowHearRangeMultiplier.Value, 0.05f, 1f);
		followAiCheckFrame++;
		if (followAiCheckFrame < 10)
		{
			return;
		}
		followAiCheckFrame = 0;
		Player val2 = FindOwner();
		if ((Object)(object)val2 == (Object)null)
		{
			return;
		}
		Character targetCreature = val.GetTargetCreature();
		if ((Object)(object)targetCreature == (Object)(object)val2)
		{
			PocketDvergerEmergencyRecall.Trigger(val2, "hostility");
		}
		else if (!((Object)(object)targetCreature == (Object)null) && !targetCreature.IsDead())
		{
			float num = Vector3.Distance(((Component)this).transform.position, ((Component)val2).transform.position);
			float num2 = Vector3.Distance(((Component)targetCreature).transform.position, ((Component)val2).transform.position);
			if (num > Mathf.Max(1f, Plugin.FollowLeashDistance.Value))
			{
				ClearCombatTarget(monsterAI);
			}
			else if (num2 > Mathf.Max(1f, Plugin.FollowTargetDistance.Value))
			{
				ClearCombatTarget(monsterAI);
			}
		}
	}

	private Player FindOwner()
	{
		long id = GetOwnerID();
		if (id == 0L)
		{
			return null;
		}
		return ((IEnumerable<Player>)Player.GetAllPlayers()).FirstOrDefault((Func<Player, bool>)((Player p) => (Object)(object)p != (Object)null && p.GetPlayerID() == id));
	}

	public long GetOwnerID()
	{
		if ((Object)(object)nview == (Object)null || !nview.IsValid())
		{
			return 0L;
		}
		ZDO zDO = nview.GetZDO();
		if (zDO != null)
		{
			return zDO.GetLong("SakeysPocketDverger_Owner", 0L);
		}
		return 0L;
	}

	public bool Interact(Humanoid character, bool hold, bool alt)
	{
		if (hold)
		{
			return false;
		}
		Player val = (Player)(object)((character is Player) ? character : null);
		if ((Object)(object)val == (Object)null || GetOwnerID() != val.GetPlayerID())
		{
			return false;
		}
		if (StoreGui.IsVisible() || InventoryGui.IsVisible() || Menu.IsVisible())
		{
			return false;
		}
		return PocketDvergerCommandMenu.Execute(this, val);
	}

	public bool IsFollowing()
	{
		return following;
	}

	public void ToggleFollowStay(Player player)
	{
		following = !following;
		if ((Object)(object)monsterAI != (Object)null)
		{
			BaseAI val = (BaseAI)(object)monsterAI;
			if (following)
			{
				val.ResetPatrolPoint();
				monsterAI.SetFollowTarget(((Component)player).gameObject);
			}
			else
			{
				monsterAI.SetFollowTarget((GameObject)null);
				val.SetPatrolPoint();
			}
			ApplyFollowBehavior();
		}
		((Character)player).Message((MessageType)2, following ? Plugin.GetFollowMessage(CompanionType) : Plugin.GetStayMessage(CompanionType), 0, (Sprite)null, false);
	}

	public bool Retrieve(Player player)
	{
		if ((Object)(object)player == (Object)null || ((Humanoid)player).GetInventory() == null)
		{
			return false;
		}
		if ((Object)(object)monsterAI != (Object)null)
		{
			monsterAI.SetFollowTarget((GameObject)null);
			ClearCombatTarget(monsterAI);
			((BaseAI)monsterAI).ResetPatrolPoint();
		}
		GameObject prefab = PrefabManager.Instance.GetPrefab(Plugin.GetActivePrefab(CompanionType));
		if ((Object)(object)prefab == (Object)null || !((Humanoid)player).GetInventory().AddItem(prefab, 1))
		{
			return false;
		}
		((Character)player).Message((MessageType)2, Plugin.GetRetrievedMessage(CompanionType), 0, (Sprite)null, false);
		if ((Object)(object)ZNetScene.instance != (Object)null)
		{
			ZNetScene.instance.Destroy(((Component)this).gameObject);
		}
		else
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}
		return true;
	}

	internal void MarkEmergencyHandled()
	{
		emergencyHandled = true;
	}

	public bool UseItem(Humanoid user, ItemData item)
	{
		return false;
	}

	public string GetHoverText()
	{
		CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
		string text = localization.TryTranslate(Plugin.GetCompanionName(CompanionType));
		string text2 = localization.TryTranslate(PocketDvergerCommandMenu.GetModeDisplayKey());
		return text + "\n[F3 / L1+決定] " + text2;
	}

	public string GetHoverName()
	{
		return Plugin.GetCompanionName(CompanionType);
	}
}