Decompiled source of ValheimNamekeeper v0.4.8

BepInEx/plugins/SuperNova.ValheimNamekeeper/SuperNova.ValheimNamekeeper.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Extensions;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using SoftReferenceableAssets;
using Splatform;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
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("SuperNova.ValheimNamekeeper")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.4.8.0")]
[assembly: AssemblyInformationalVersion("0.4.8+d764a09b0cc3dce187c7cfdbc559863a70def03e")]
[assembly: AssemblyProduct("SuperNova.ValheimNamekeeper")]
[assembly: AssemblyTitle("SuperNova.ValheimNamekeeper")]
[assembly: AssemblyVersion("0.4.8.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 SuperNova.ValheimNamekeeper
{
	internal sealed class CampBoar : MonoBehaviour, Hoverable, Interactable
	{
		private WorldCamp _camp;

		private int _index;

		private Animator _animator;

		private AudioSource _voice;

		private readonly List<AudioClip> _petClips = new List<AudioClip>();

		private long _lastMeal;

		private float _reactUntil;

		private float _nextPet;

		internal static CampBoar Create(WorldCamp camp, int index, Vector3 position)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = NativeWorkshopAssets.Source("Boar");
			GameObject val2 = new GameObject("NamekeeperCampBoar_" + index);
			try
			{
				val2.SetActive(false);
				val2.transform.SetParent(((Component)camp).transform, false);
				val2.transform.position = position;
				val2.transform.localRotation = Quaternion.Euler(0f, 180f, 0f);
				val2.layer = LayerMask.NameToLayer("piece");
				Transform obj = val.transform.Find("Visual");
				if ((Object)(object)obj == (Object)null)
				{
					throw new InvalidOperationException("Native Boar Visual is unavailable");
				}
				GameObject val3 = Object.Instantiate<GameObject>(((Component)obj).gameObject, val2.transform, false);
				MonoBehaviour[] componentsInChildren = val3.GetComponentsInChildren<MonoBehaviour>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
				}
				CampBoar campBoar = val2.AddComponent<CampBoar>();
				campBoar._camp = camp;
				campBoar._index = index;
				campBoar._animator = val3.GetComponentInChildren<Animator>(true);
				campBoar._animator.applyRootMotion = false;
				campBoar._animator.fireEvents = false;
				((Behaviour)campBoar._animator).enabled = true;
				campBoar._animator.cullingMode = (AnimatorCullingMode)0;
				campBoar.PrepareVoice(val.GetComponent<Tameable>()?.m_petEffect);
				CapsuleCollider component = val.GetComponent<CapsuleCollider>();
				CapsuleCollider obj2 = val2.AddComponent<CapsuleCollider>();
				obj2.center = component.center;
				obj2.radius = component.radius;
				obj2.height = component.height;
				obj2.direction = component.direction;
				val3.SetActive(true);
				val2.SetActive(true);
				campBoar._animator.SetFloat("forward_speed", 0f);
				campBoar._animator.SetFloat("sideway_speed", 0f);
				campBoar._animator.SetFloat("turn_speed", 0f);
				campBoar._animator.SetFloat("idle", 0f);
				return campBoar;
			}
			catch
			{
				Object.DestroyImmediate((Object)(object)val2);
				throw;
			}
		}

		private void Update()
		{
			if (!((Object)(object)_animator == (Object)null) && !((Object)(object)ZNet.instance == (Object)null))
			{
				long num = (long)Math.Floor((ZNet.instance.GetTimeSeconds() + (double)_index * 4.5) / 13.0);
				if (num != _lastMeal && Time.time >= _reactUntil)
				{
					_lastMeal = num;
					_animator.SetTrigger("consume");
				}
				_animator.SetFloat("idle", (Time.time < _reactUntil) ? 2f : 0f, 0.35f, Time.deltaTime);
			}
		}

		internal void React()
		{
			if (!(Time.time < _nextPet))
			{
				_nextPet = Time.time + 2.5f;
				_reactUntil = Time.time + 2.2f;
				if (_petClips.Count > 0)
				{
					_voice.PlayOneShot(_petClips[_index % _petClips.Count]);
				}
			}
		}

		private void PrepareVoice(EffectList effects)
		{
			_voice = ((Component)this).gameObject.AddComponent<AudioSource>();
			_voice.playOnAwake = false;
			_voice.spatialBlend = 1f;
			_voice.minDistance = 1f;
			_voice.maxDistance = 18f;
			_voice.volume = 0.65f;
			if (effects?.m_effectPrefabs == null)
			{
				return;
			}
			EffectData[] effectPrefabs = effects.m_effectPrefabs;
			foreach (EffectData val in effectPrefabs)
			{
				if ((Object)(object)val?.m_prefab == (Object)null || !val.m_enabled)
				{
					continue;
				}
				ZSFX[] componentsInChildren = val.m_prefab.GetComponentsInChildren<ZSFX>(true);
				foreach (ZSFX val2 in componentsInChildren)
				{
					if (val2.m_audioClips == null)
					{
						continue;
					}
					AudioClip[] audioClips = val2.m_audioClips;
					foreach (AudioClip val3 in audioClips)
					{
						if ((Object)(object)val3 != (Object)null && !_petClips.Contains(val3))
						{
							_petClips.Add(val3);
						}
					}
				}
				AudioSource componentInChildren = val.m_prefab.GetComponentInChildren<AudioSource>(true);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					_voice.outputAudioMixerGroup = componentInChildren.outputAudioMixerGroup;
				}
			}
		}

		public string GetHoverName()
		{
			if (_index != 0)
			{
				return L.T("Snout", "Пятачок");
			}
			return L.T("Inkblot", "Клякса");
		}

		public float GetHoverOffset()
		{
			return 0.7f;
		}

		public string GetHoverText()
		{
			string text = L.Vanilla("$KEY_Use");
			if (string.IsNullOrEmpty(text) || text.StartsWith("$", StringComparison.Ordinal))
			{
				text = "E";
			}
			return GetHoverName() + "\n[<color=yellow><b>" + text + "</b></color>] " + L.T("Pet", "Погладить");
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if (hold || (Object)(object)user == (Object)null || (Object)(object)user != (Object)(object)Player.m_localPlayer || Time.time < _nextPet || Vector3.Distance(((Component)user).transform.position, ((Component)this).transform.position) > 3f)
			{
				return false;
			}
			_camp.Pet(_index);
			((Character)user).Message((MessageType)2, GetHoverName() + L.T(" grunts happily.", " довольно похрюкивает."), 0, (Sprite)null, false);
			return true;
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return false;
		}
	}
	internal static class CampDiscoveryMemory
	{
		internal static bool Remember(IDictionary<string, string> data, long world, int x, int z)
		{
			string key = "sn_namekeeper_discovery:" + world.ToString(CultureInfo.InvariantCulture) + ":" + x.ToString(CultureInfo.InvariantCulture) + ":" + z.ToString(CultureInfo.InvariantCulture);
			if (data.ContainsKey(key))
			{
				return false;
			}
			data[key] = "1";
			return true;
		}
	}
	internal static class CampFootprint
	{
		internal static bool Contains(float x, float z, float centerX, float centerZ, float radius)
		{
			float num = x - centerX;
			float num2 = z - centerZ;
			return num * num + num2 * num2 <= radius * radius;
		}
	}
	internal static class CampMeal
	{
		private const string BowlKey = "SN_HildirMealBowl";

		private const string FoodKey = "SN_HildirMealTurnips";

		internal static void Capture(GameObject nativeCamp)
		{
			Transform val = nativeCamp.transform.Find("fi_vil_container_bucket01");
			Transform val2 = nativeCamp.transform.Find("turnips");
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val.parent != (Object)(object)val2.parent)
			{
				throw new InvalidOperationException("Hildir's authored bowl/turnips group is unavailable");
			}
			NativeWorkshopAssets.Remember("SN_HildirMealBowl", ((Component)val).gameObject);
			NativeWorkshopAssets.Remember("SN_HildirMealTurnips", ((Component)val2).gameObject);
		}

		internal static Transform Create(Transform camp, Vector3 ground)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = NativeWorkshopAssets.Source("SN_HildirMealBowl").transform;
			Transform transform2 = NativeWorkshopAssets.Source("SN_HildirMealTurnips").transform;
			GameObject val = new GameObject("HildirCampMeal");
			val.SetActive(false);
			val.transform.SetParent(camp, false);
			try
			{
				val.transform.localRotation = Quaternion.Euler(0f, 90f, 0f) * Quaternion.Inverse(transform.localRotation);
				Transform transform3 = new GameObject("NativeMealFrame").transform;
				transform3.SetParent(val.transform, false);
				transform3.localPosition = -transform.localPosition;
				Transform root = Copy(transform3, "SN_HildirMealBowl", transform, solid: true);
				Copy(transform3, "SN_HildirMealTurnips", transform2, solid: false);
				Bounds val2 = WorldCamp.MeshBoundsIn(root, camp);
				Vector3 val3 = camp.InverseTransformPoint(ground);
				Transform transform4 = val.transform;
				transform4.localPosition += val3 - new Vector3(((Bounds)(ref val2)).center.x, ((Bounds)(ref val2)).min.y, ((Bounds)(ref val2)).center.z);
				val.SetActive(true);
				return val.transform;
			}
			catch
			{
				Object.DestroyImmediate((Object)(object)val);
				throw;
			}
		}

		private static Transform Copy(Transform frame, string key, Transform source, bool solid)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			Transform obj = NativeWorkshopAssets.Add(frame, key, source.localPosition, source.localScale, 0f, solid);
			obj.localRotation = source.localRotation;
			return obj;
		}
	}
	internal static class CampSeating
	{
		internal static void Install(Transform bench)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			Chair[] componentsInChildren = NativeWorkshopAssets.Source("piece_bench01").GetComponentsInChildren<Chair>(true);
			foreach (Chair val in componentsInChildren)
			{
				Transform val2 = bench.Find(((Object)((Component)val).transform).name);
				if ((Object)(object)val2 == (Object)null || (Object)(object)val.m_attachPoint == (Object)null)
				{
					throw new InvalidOperationException("Native bench seat is incomplete: " + ((Object)val).name);
				}
				Transform transform = new GameObject("attachpoint").transform;
				transform.SetParent(val2, false);
				transform.localPosition = ((Component)val).transform.InverseTransformPoint(val.m_attachPoint.position);
				transform.localRotation = Quaternion.Inverse(((Component)val).transform.rotation) * val.m_attachPoint.rotation;
				Chair obj = ((Component)val2).gameObject.AddComponent<Chair>();
				obj.m_name = val.m_name;
				obj.m_useDistance = val.m_useDistance;
				obj.m_attachPoint = transform;
				obj.m_detachOffset = val.m_detachOffset;
				obj.m_attachAnimation = val.m_attachAnimation;
				obj.m_hoverOffset = val.m_hoverOffset;
				obj.m_inShip = false;
			}
		}
	}
	internal enum DialogueCue
	{
		None,
		Arrival,
		Greeting,
		Open,
		SelectItem,
		NameEdited,
		DescriptionEdited,
		ResetName,
		ResetDescription,
		CancelReset,
		SuccessName,
		SuccessDescription,
		SuccessBoth,
		SuccessReset,
		NoChanges,
		NotEnoughCoins,
		InvalidText,
		ItemUnavailable,
		NoEligibleItems,
		NoRoof,
		TooFar,
		Failure,
		Goodbye,
		Idle
	}
	internal static class DialogueLines
	{
		private sealed class Line
		{
			internal readonly string English;

			internal readonly string Russian;

			internal Line(string english, string russian)
			{
				English = english;
				Russian = russian;
			}
		}

		private static readonly Dictionary<DialogueCue, Line[]> Lines = new Dictionary<DialogueCue, Line[]>
		{
			[DialogueCue.Arrival] = new Line[2]
			{
				new Line("The shop is open. Every treasure has a story.", "Лавка открыта. У каждой вещи есть своя история."),
				new Line("My counter is ready, and so are my quills.", "Прилавок готов, перья заточены. Заходи!")
			},
			[DialogueCue.Greeting] = new Line[2]
			{
				new Line("Welcome, traveller. What tale have you brought me?", "Здравствуй, путник. Какую историю ты мне принёс?"),
				new Line("Come closer. Even an old axe deserves a fine name.", "Подходи. Даже старый топор достоин славного имени.")
			},
			[DialogueCue.Open] = new Line[2]
			{
				new Line("Choose a piece of gear. We shall give it a story.", "Выбирай вещь. Найдём для неё достойную историю."),
				new Line("A name, a tale, or both? The choice is yours.", "Имя, история или всё сразу? Решать тебе.")
			},
			[DialogueCue.SelectItem] = new Line[2]
			{
				new Line("A worthy choice. What shall we call it?", "Достойный выбор. Как мы её назовём?"),
				new Line("This one has seen a few adventures, I think.", "Кажется, эта вещь повидала немало приключений.")
			},
			[DialogueCue.NameEdited] = new Line[2]
			{
				new Line("A good name should be remembered.", "Хорошее имя должно запоминаться."),
				new Line("Try the name aloud. Does it suit your treasure?", "Произнеси это имя. Подходит твоему сокровищу?")
			},
			[DialogueCue.DescriptionEdited] = new Line[2]
			{
				new Line("A tale worth keeping. Check the words before we begin.", "Такую историю стоит сохранить. Проверь слова перед работой."),
				new Line("A few words can hold a whole adventure.", "В нескольких словах может уместиться целое приключение.")
			},
			[DialogueCue.ResetName] = new Line[2]
			{
				new Line("Its first name, then. Restoration costs the usual fee.", "Значит, вернём прежнее имя. Цена — как за новое."),
				new Line("Some names are best left as they were.", "Иные имена хороши такими, какими были.")
			},
			[DialogueCue.ResetDescription] = new Line[2]
			{
				new Line("We can restore the old tale. Check the price below.", "Можно вернуть прежнюю историю. Цена указана внизу."),
				new Line("Back to the beginning of its story, then.", "Что ж, вернёмся к началу её истории.")
			},
			[DialogueCue.CancelReset] = new Line[1]
			{
				new Line("As you wish. Nothing has been changed or charged.", "Как пожелаешь. Ничего не изменено и не оплачено.")
			},
			[DialogueCue.SuccessName] = new Line[2]
			{
				new Line("There. May its new name bring you glory!", "Готово. Пусть новое имя принесёт тебе славу!"),
				new Line("A fine name for a fine piece of gear.", "Славное имя для славной вещи.")
			},
			[DialogueCue.SuccessDescription] = new Line[2]
			{
				new Line("Its story is written. May the next chapter be yours.", "История записана. Пусть следующая глава будет твоей."),
				new Line("Done. Those words belong to this treasure now.", "Готово. Теперь эти слова принадлежат твоему сокровищу.")
			},
			[DialogueCue.SuccessBoth] = new Line[2]
			{
				new Line("A new name and a new tale. Carry them with pride!", "Новое имя и новая история. Носи их с гордостью!"),
				new Line("All finished. Now go and make that story longer.", "Всё готово. А теперь отправляйся за продолжением истории.")
			},
			[DialogueCue.SuccessReset] = new Line[2]
			{
				new Line("The original words are restored. Just as you asked.", "Прежние слова возвращены. Всё, как ты просил."),
				new Line("Restored. Sometimes the first story is the best.", "Восстановлено. Иногда первая история — самая лучшая.")
			},
			[DialogueCue.NoChanges] = new Line[1]
			{
				new Line("The words are the same. Keep your coins.", "Слова остались прежними. Побереги монеты.")
			},
			[DialogueCue.NotEnoughCoins] = new Line[2]
			{
				new Line("A few more coins, traveller. Good work takes time.", "Нужно чуть больше монет, путник. Добрая работа требует времени."),
				new Line("Your purse is a little light. I can wait.", "Кошель немного легковат. Ничего, я подожду.")
			},
			[DialogueCue.InvalidText] = new Line[2]
			{
				new Line("Check those words: keep them within the limit, without special markings.", "Проверь текст: уложись в меру и убери особые знаки."),
				new Line("A little shorter and clearer, if you please.", "Чуть короче и яснее, будь добр.")
			},
			[DialogueCue.ItemUnavailable] = new Line[1]
			{
				new Line("Keep that item in your pack while I work.", "Держи выбранную вещь в своём инвентаре, пока я работаю.")
			},
			[DialogueCue.NoEligibleItems] = new Line[1]
			{
				new Line("Bring a single piece of gear, not a stack of supplies.", "Принеси отдельную вещь, а не стопку припасов.")
			},
			[DialogueCue.NoRoof] = new Line[2]
			{
				new Line("I need a roof over my work before I can help.", "Над моей работой нужна крыша. Тогда и помогу."),
				new Line("Let us keep the rain off the ink first.", "Сперва укроем чернила от дождя.")
			},
			[DialogueCue.TooFar] = new Line[1]
			{
				new Line("Come back to the counter when you are ready.", "Возвращайся к прилавку, когда будешь готов.")
			},
			[DialogueCue.Failure] = new Line[1]
			{
				new Line("That did not go as planned. Let us check it before trying again.", "Что-то пошло не так. Проверим всё перед новой попыткой.")
			},
			[DialogueCue.Goodbye] = new Line[2]
			{
				new Line("Safe travels. Bring me another story sometime.", "Счастливого пути. Заглядывай с новыми историями."),
				new Line("May your gear serve you well. Until next time!", "Пусть вещи служат тебе верно. До новой встречи!")
			},
			[DialogueCue.Idle] = new Line[3]
			{
				new Line("A sharp blade is useful. A famous blade is remembered.", "Острый клинок полезен. Прославленный — помнят."),
				new Line("Names fade. Stories keep them alive.", "Имена забываются. Истории помогают им жить."),
				new Line("Some treasures are worth more than their weight in silver.", "Иные сокровища стоят дороже своего веса в серебре.")
			}
		};

		internal static bool UseRussian(string gameLanguage)
		{
			return string.Equals(gameLanguage, "Russian", StringComparison.OrdinalIgnoreCase);
		}

		internal static string Get(DialogueCue cue, string gameLanguage, int variant)
		{
			if (!Lines.TryGetValue(cue, out var value))
			{
				return "";
			}
			Line line = value[(uint)variant % (uint)value.Length];
			if (!UseRussian(gameLanguage))
			{
				return line.English;
			}
			return line.Russian;
		}

		internal static int Priority(DialogueCue cue)
		{
			switch (cue)
			{
			case DialogueCue.None:
				return 0;
			case DialogueCue.Arrival:
			case DialogueCue.Greeting:
			case DialogueCue.Goodbye:
			case DialogueCue.Idle:
				return 1;
			default:
				return 2;
			case DialogueCue.SuccessName:
			case DialogueCue.SuccessDescription:
			case DialogueCue.SuccessBoth:
			case DialogueCue.SuccessReset:
			case DialogueCue.NoChanges:
			case DialogueCue.NotEnoughCoins:
			case DialogueCue.InvalidText:
			case DialogueCue.ItemUnavailable:
			case DialogueCue.NoEligibleItems:
			case DialogueCue.NoRoof:
			case DialogueCue.TooFar:
			case DialogueCue.Failure:
				return 3;
			}
		}
	}
	internal sealed class DialogueScheduler
	{
		private readonly Dictionary<DialogueCue, double> _lastByCue = new Dictionary<DialogueCue, double>();

		private DialogueCue _pending;

		private double _requestedAt;

		private double _startedAt = -100.0;

		private double _nextAt;

		private int _lastPriority;

		internal int PendingPriority => DialogueLines.Priority(_pending);

		internal void Request(DialogueCue cue, double now)
		{
			switch (cue)
			{
			case DialogueCue.None:
				return;
			case DialogueCue.Goodbye:
				if (PendingPriority < 3)
				{
					_pending = DialogueCue.None;
				}
				break;
			}
			double num = ((DialogueLines.Priority(cue) == 1) ? 30 : 8);
			if ((!_lastByCue.TryGetValue(cue, out var value) || !(now - value < num)) && (!(now < _nextAt) || _lastPriority != 3 || DialogueLines.Priority(cue) >= 3) && (_pending == DialogueCue.None || !(now - _requestedAt < 8.0) || DialogueLines.Priority(cue) >= DialogueLines.Priority(_pending)))
			{
				_pending = cue;
				_requestedAt = now;
			}
		}

		internal bool TryTake(double now, out DialogueCue cue)
		{
			cue = DialogueCue.None;
			if (_pending == DialogueCue.None)
			{
				return false;
			}
			if (now - _requestedAt > 8.0)
			{
				_pending = DialogueCue.None;
				return false;
			}
			int num = DialogueLines.Priority(_pending);
			if (now < _nextAt && (num != 3 || !(now - _startedAt >= 1.5)))
			{
				return false;
			}
			cue = _pending;
			_pending = DialogueCue.None;
			_startedAt = now;
			_nextAt = now + 5.0;
			_lastPriority = num;
			_lastByCue[cue] = now;
			return true;
		}

		internal void Clear()
		{
			_pending = DialogueCue.None;
		}
	}
	internal readonly struct HudLayout
	{
		internal readonly float Width;

		internal readonly float Height;

		internal readonly float Scale;

		internal readonly float LeftInset;

		internal HudLayout(float availableWidth, float availableHeight)
		{
			Width = 940f;
			Height = 760f;
			Scale = Math.Min(1f, Math.Min(Math.Max(1f, availableWidth) / 1920f, Math.Max(1f, availableHeight) / 1080f));
			LeftInset = 24f * Scale;
		}
	}
	internal static class NamekeeperInputState
	{
		internal static bool ShopOpen
		{
			get
			{
				if ((Object)(object)NamekeeperPlugin.Instance != (Object)null && NamekeeperPlugin.Instance.Ui != null)
				{
					return NamekeeperPlugin.Instance.Ui.InputSuppressed;
				}
				return false;
			}
		}
	}
	[HarmonyPatch]
	internal static class NamekeeperZInputBooleanGuard
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			Type type = AccessTools.TypeByName("ZInput");
			if (type == null)
			{
				yield break;
			}
			foreach (MethodInfo declaredMethod in AccessTools.GetDeclaredMethods(type))
			{
				if (!(declaredMethod.ReturnType != typeof(bool)))
				{
					ParameterInfo[] parameters = declaredMethod.GetParameters();
					bool num = (declaredMethod.Name == "GetButton" || declaredMethod.Name == "GetButtonDown" || declaredMethod.Name == "GetButtonUp") && parameters.Length == 1 && parameters[0].ParameterType == typeof(string);
					bool flag = (declaredMethod.Name == "GetMouseButton" || declaredMethod.Name == "GetMouseButtonDown" || declaredMethod.Name == "GetMouseButtonUp") && parameters.Length == 1 && parameters[0].ParameterType == typeof(int);
					bool flag2 = (declaredMethod.Name == "GetKey" || declaredMethod.Name == "GetKeyDown" || declaredMethod.Name == "GetKeyUp") && parameters.Length >= 1 && parameters.Length <= 2 && parameters[0].ParameterType == typeof(KeyCode) && (parameters.Length == 1 || parameters[1].ParameterType == typeof(bool));
					if (num || flag || flag2)
					{
						yield return declaredMethod;
					}
				}
			}
		}

		private static bool Prefix(ref bool __result)
		{
			if (!NamekeeperInputState.ShopOpen)
			{
				return true;
			}
			__result = false;
			return false;
		}
	}
	[HarmonyPatch]
	internal static class NamekeeperPlayerControllerGuard
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			Type type = AccessTools.TypeByName("PlayerController");
			if (type == null)
			{
				yield break;
			}
			foreach (MethodInfo declaredMethod in AccessTools.GetDeclaredMethods(type))
			{
				if (declaredMethod.Name == "TakeInput" && declaredMethod.ReturnType == typeof(bool))
				{
					yield return declaredMethod;
				}
			}
		}

		private static bool Prefix(ref bool __result)
		{
			if (!NamekeeperInputState.ShopOpen)
			{
				return true;
			}
			__result = false;
			return false;
		}
	}
	[HarmonyPatch]
	internal static class NamekeeperCameraCaptureGuard
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			Type type = AccessTools.TypeByName("GameCamera");
			if (type == null)
			{
				yield break;
			}
			foreach (MethodInfo declaredMethod in AccessTools.GetDeclaredMethods(type))
			{
				if (declaredMethod.Name == "UpdateMouseCapture" && declaredMethod.GetParameters().Length == 0)
				{
					yield return declaredMethod;
				}
			}
		}

		private static bool Prefix()
		{
			return !NamekeeperInputState.ShopOpen;
		}
	}
	[HarmonyPatch]
	internal static class NamekeeperScrollWheelGuard
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			Type type = AccessTools.TypeByName("ZInput");
			if (type == null)
			{
				yield break;
			}
			foreach (MethodInfo declaredMethod in AccessTools.GetDeclaredMethods(type))
			{
				if (declaredMethod.Name == "GetMouseScrollWheel" && declaredMethod.ReturnType == typeof(float) && declaredMethod.GetParameters().Length == 0)
				{
					yield return declaredMethod;
				}
			}
		}

		private static bool Prefix(ref float __result)
		{
			if (!NamekeeperInputState.ShopOpen)
			{
				return true;
			}
			__result = 0f;
			return false;
		}
	}
	internal static class InventoryChangeDispatcher
	{
		private const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly Dictionary<Type, MethodInfo> Methods = new Dictionary<Type, MethodInfo>();

		internal static void Notify(object inventory)
		{
			if (inventory == null)
			{
				return;
			}
			Type type = inventory.GetType();
			if (!Methods.TryGetValue(type, out var value))
			{
				value = type.GetMethod("Changed", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2]
				{
					typeof(bool),
					typeof(bool)
				}, null) ?? type.GetMethod("Changed", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null) ?? type.GetMethod("OnChanged", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
				Methods.Add(type, value);
			}
			if (value != null)
			{
				value.Invoke(inventory, (value.GetParameters().Length == 0) ? null : new object[2] { false, false });
				return;
			}
			if (type.GetField("m_onChanged", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(inventory) is Delegate obj)
			{
				obj.DynamicInvoke();
				return;
			}
			throw new MissingMethodException(type.FullName, "Changed(bool,bool)");
		}
	}
	internal static class InventoryTransaction
	{
		private sealed class CoinState
		{
			internal ItemData Item;

			internal int Stack;

			internal int Index;
		}

		internal static void Execute(Inventory inventory, ItemData item, int cost, Action applyText)
		{
			if (cost < 0)
			{
				throw new ArgumentOutOfRangeException("cost");
			}
			if (inventory == null || item == null || applyText == null)
			{
				throw new ArgumentNullException();
			}
			List<ItemData> allItems = inventory.GetAllItems();
			if (!allItems.Contains(item))
			{
				throw new InvalidOperationException("Selected item left inventory");
			}
			List<CoinState> list = new List<CoinState>();
			long num = 0L;
			for (int i = 0; i < allItems.Count; i++)
			{
				ItemData val = allItems[i];
				if (!(val?.m_shared?.m_name != "$item_coins") && val.m_worldLevel >= Game.m_worldLevel && val.m_stack > 0)
				{
					list.Add(new CoinState
					{
						Item = val,
						Stack = val.m_stack,
						Index = i
					});
					num += val.m_stack;
				}
			}
			if (num < cost)
			{
				throw new InvalidOperationException("Insufficient coins");
			}
			Dictionary<string, string> customData = item.m_customData;
			Dictionary<string, string> dictionary = ((customData == null) ? null : new Dictionary<string, string>(customData));
			try
			{
				int num2 = cost;
				foreach (CoinState item3 in list)
				{
					int num3 = Math.Min(num2, item3.Stack);
					ItemData item2 = item3.Item;
					item2.m_stack -= num3;
					num2 -= num3;
					if (item3.Item.m_stack == 0)
					{
						allItems.Remove(item3.Item);
					}
					if (num2 == 0)
					{
						break;
					}
				}
				applyText();
			}
			catch
			{
				foreach (CoinState item4 in list)
				{
					item4.Item.m_stack = item4.Stack;
					if (!allItems.Contains(item4.Item))
					{
						allItems.Insert(Math.Min(item4.Index, allItems.Count), item4.Item);
					}
				}
				if (customData != null)
				{
					customData.Clear();
					foreach (KeyValuePair<string, string> item5 in dictionary)
					{
						customData.Add(item5.Key, item5.Value);
					}
				}
				item.m_customData = customData;
				throw;
			}
		}
	}
	internal static class ItemText
	{
		internal const string NexusPatchOwner = "com.supernova.valheimspawner.InputGuard";

		internal static bool OwnsName(ItemData item)
		{
			return PersonalizedText.Owns(item?.m_customData, description: false);
		}

		internal static bool OwnsDescription(ItemData item)
		{
			return PersonalizedText.Owns(item?.m_customData, description: true);
		}

		internal static string GetName(ItemData item)
		{
			return PersonalizedText.Resolve(item?.m_customData, L.OriginalName(item), description: false);
		}

		internal static string GetDescription(ItemData item)
		{
			return PersonalizedText.Resolve(item?.m_customData, L.OriginalDescription(item), description: true);
		}

		internal static bool NameChanges(ItemData item, string text, bool reset)
		{
			return PersonalizedText.Changes(item?.m_customData, L.OriginalName(item), text, reset, description: false);
		}

		internal static bool DescriptionChanges(ItemData item, string text, bool reset)
		{
			return PersonalizedText.Changes(item?.m_customData, L.OriginalDescription(item), text, reset, description: true);
		}

		internal static bool Validate(string input, int max, bool allowNewlines, out string error)
		{
			error = null;
			if (input == null || input.Length > max)
			{
				error = L.T("Text is too long.", "Текст слишком длинный.");
				return false;
			}
			foreach (char c in input)
			{
				if (c == '<' || c == '>' || (char.IsControl(c) && (!allowNewlines || c != '\n')))
				{
					error = L.T("Control characters and rich-text tags are not allowed.", "Управляющие символы и теги форматирования запрещены.");
					return false;
				}
			}
			return true;
		}

		internal static void Apply(ItemData item, string name, string description, bool changeName, bool changeDescription, bool resetName, bool resetDescription)
		{
			if (item.m_customData == null)
			{
				item.m_customData = new Dictionary<string, string>();
			}
			if (changeName)
			{
				PersonalizedText.Apply(item.m_customData, L.OriginalName(item), name, resetName, description: false);
			}
			if (changeDescription)
			{
				PersonalizedText.Apply(item.m_customData, L.OriginalDescription(item), description, resetDescription, description: true);
			}
		}
	}
	[HarmonyPatch(typeof(ItemDrop), "GetHoverName")]
	internal static class GroundItemHoverNamePatch
	{
		[HarmonyPriority(0)]
		[HarmonyAfter(new string[] { "com.supernova.valheimspawner.InputGuard" })]
		private static void Postfix(ItemDrop __instance, ref string __result)
		{
			if ((Object)(object)__instance != (Object)null && ItemText.OwnsName(__instance.m_itemData))
			{
				__result = ItemText.GetName(__instance.m_itemData);
			}
		}
	}
	[HarmonyPatch(typeof(ItemDrop), "GetHoverText")]
	internal static class GroundItemHoverTextPatch
	{
		[HarmonyPriority(0)]
		[HarmonyAfter(new string[] { "com.supernova.valheimspawner.InputGuard" })]
		private static void Postfix(ItemDrop __instance, ref string __result)
		{
			ItemData val = __instance?.m_itemData;
			if (ItemText.OwnsName(val) && !string.IsNullOrEmpty(__result))
			{
				__result = PersonalizedText.ReplaceHoverName(__result, ItemText.GetName(val), ItemText.GetName(val), PersonalizedText.Read(val.m_customData, "com.supernova.valheimnexus.itemname.v1"), L.OriginalName(val), val.m_shared?.m_name);
			}
		}
	}
	[HarmonyPatch]
	internal static class ItemTooltipDescriptionPatch
	{
		private static bool s_warned;

		private static IEnumerable<MethodBase> TargetMethods()
		{
			return from m in AccessTools.GetDeclaredMethods(typeof(ItemData))
				where m.Name == "GetTooltip" && m.ReturnType == typeof(string) && m.IsStatic && m.GetParameters().Length != 0 && m.GetParameters()[0].ParameterType == typeof(ItemData)
				select m;
		}

		[HarmonyPriority(0)]
		[HarmonyAfter(new string[] { "com.supernova.valheimspawner.InputGuard" })]
		private static void Postfix(object[] __args, ref string __result)
		{
			if (__args == null || __args.Length == 0)
			{
				return;
			}
			object obj = __args[0];
			ItemData val = (ItemData)((obj is ItemData) ? obj : null);
			if (val == null || !ItemText.OwnsDescription(val) || string.IsNullOrEmpty(__result))
			{
				return;
			}
			string description = ItemText.GetDescription(val);
			string text = PersonalizedText.ReplaceDescription(__result, description, val.m_shared?.m_description, L.OriginalDescription(val), PersonalizedText.Read(val.m_customData, "com.supernova.valheimnexus.itemdescription.v1"));
			if (!s_warned && text == __result && !__result.StartsWith(description, StringComparison.Ordinal))
			{
				s_warned = true;
				ManualLogSource log = NamekeeperPlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"Namekeeper: unknown tooltip description layout; preserved other-mod text and stats.");
				}
			}
			__result = text;
		}
	}
	[HarmonyPatch]
	internal static class InventoryTooltipTitlePatch
	{
		private static bool s_warned;

		private static bool s_loggedUpdate;

		private static MethodBase TargetMethod()
		{
			MethodInfo? methodInfo = AccessTools.GetDeclaredMethods(typeof(InventoryGrid)).FirstOrDefault((MethodInfo m) => m.Name == "CreateItemTooltip" && !m.IsStatic && m.GetParameters().Length == 2 && m.GetParameters()[0].ParameterType == typeof(ItemData) && m.GetParameters()[1].ParameterType.Name == "UITooltip");
			if (methodInfo == null)
			{
				throw new MissingMethodException("InventoryGrid.CreateItemTooltip(ItemData, UITooltip)");
			}
			ManualLogSource log = NamekeeperPlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"Namekeeper: patch inventory tooltip titles after CreateItemTooltip (UITooltip.Set)");
				return methodInfo;
			}
			return methodInfo;
		}

		[HarmonyPriority(0)]
		[HarmonyAfter(new string[] { "com.supernova.valheimspawner.InputGuard" })]
		private static void Postfix(object[] __args)
		{
			if (__args == null || __args.Length < 2)
			{
				return;
			}
			object obj = __args[0];
			ItemData val = (ItemData)((obj is ItemData) ? obj : null);
			if (val == null || !ItemText.OwnsName(val))
			{
				return;
			}
			try
			{
				TooltipTitleUpdater.SetTitle(__args[1], ItemText.GetName(val));
				if (!s_loggedUpdate)
				{
					s_loggedUpdate = true;
					ManualLogSource log = NamekeeperPlugin.Log;
					if (log != null)
					{
						log.LogInfo((object)"Namekeeper: customized InventoryGrid tooltip refreshed through UITooltip.Set.");
					}
				}
			}
			catch (Exception ex)
			{
				if (!s_warned)
				{
					s_warned = true;
					ManualLogSource log2 = NamekeeperPlugin.Log;
					if (log2 != null)
					{
						log2.LogWarning((object)("Namekeeper inventory tooltip refresh failed: " + ex));
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(Player), "TakeInput")]
	internal static class BlockGameplayWhenShopOpen
	{
		private static bool Prefix(Player __instance, ref bool __result)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && NamekeeperInputState.ShopOpen)
			{
				__result = false;
				return false;
			}
			return true;
		}
	}
	internal static class L
	{
		internal static bool Ru
		{
			get
			{
				string gameLanguage = null;
				try
				{
					if (Localization.instance != null)
					{
						gameLanguage = Localization.instance.GetSelectedLanguage();
					}
				}
				catch (Exception)
				{
				}
				return UiLanguagePolicy.UseRussian(NamekeeperPlugin.Language?.Value, gameLanguage);
			}
		}

		internal static string T(string en, string ru)
		{
			if (!Ru)
			{
				return en;
			}
			return ru;
		}

		internal static string Vanilla(string token)
		{
			if (string.IsNullOrEmpty(token) || !token.StartsWith("$", StringComparison.Ordinal))
			{
				return token ?? "";
			}
			try
			{
				return LocalizationManager.Instance.TryTranslate(token) ?? token;
			}
			catch (Exception)
			{
				return token;
			}
		}

		internal static string Name(ItemData item)
		{
			if (item != null)
			{
				return ItemText.GetName(item);
			}
			return "";
		}

		internal static string OriginalName(ItemData item)
		{
			if (item?.m_shared != null)
			{
				return Vanilla(item.m_shared.m_name);
			}
			return "";
		}

		internal static string OriginalDescription(ItemData item)
		{
			if (item?.m_shared != null)
			{
				return Vanilla(item.m_shared.m_description);
			}
			return "";
		}
	}
	internal static class LegacyShopModel
	{
		private static Material _wood;

		private static Material _darkWood;

		private static Material _roof;

		private static Material _iron;

		private static Material _brass;

		private static Material _paper;

		private static Material _glow;

		private static Material _signWood;

		private static void PrepareMaterials()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			if ((int)SystemInfo.graphicsDeviceType != 4 && !((Object)(object)_wood != (Object)null))
			{
				Shader val = Shader.Find("Standard") ?? Shader.Find("Diffuse");
				if ((Object)(object)val == (Object)null)
				{
					GameObject prefab = PrefabManager.Instance.GetPrefab("woodwall");
					MeshRenderer val2 = (((Object)(object)prefab != (Object)null) ? prefab.GetComponentInChildren<MeshRenderer>(true) : null);
					val = (((Object)(object)val2 != (Object)null && (Object)(object)((Renderer)val2).sharedMaterial != (Object)null) ? ((Renderer)val2).sharedMaterial.shader : null);
				}
				if (!((Object)(object)val == (Object)null))
				{
					_wood = TimberMaterial(val, new Color(0.61f, 0.39f, 0.22f), 13);
					_darkWood = TimberMaterial(val, new Color(0.34f, 0.21f, 0.13f), 29);
					_roof = TimberMaterial(val, new Color(0.42f, 0.25f, 0.14f), 47);
					_iron = SolidMaterial(val, new Color(0.12f, 0.14f, 0.15f), 0.5f);
					_brass = SolidMaterial(val, new Color(0.67f, 0.43f, 0.15f), 0.65f);
					_paper = SolidMaterial(val, new Color(0.79f, 0.7f, 0.49f), 0f);
					_signWood = TimberMaterial(val, new Color(0.86f, 0.73f, 0.51f), 61);
					_glow = WorkshopLighting.GlowMaterial(val);
				}
			}
		}

		private static Material TimberMaterial(Shader shader, Color tone, int offset)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			Material val = new Material(shader);
			((Object)val).name = "NamekeeperTimber_" + offset;
			Texture2D val2 = new Texture2D(96, 96, (TextureFormat)4, false);
			((Object)val2).name = ((Object)val).name + "_Texture";
			((Texture)val2).wrapMode = (TextureWrapMode)0;
			((Texture)val2).filterMode = (FilterMode)1;
			Color[] array = (Color[])(object)new Color[9216];
			for (int i = 0; i < 96; i++)
			{
				for (int j = 0; j < 96; j++)
				{
					float num = Mathf.PerlinNoise((float)(j + offset) * 0.052f, (float)(i + offset) * 0.008f);
					float num2 = Mathf.PerlinNoise((float)(j + offset) * 0.022f, (float)(i + offset) * 0.024f);
					float num3 = Mathf.Clamp(0.72f + (num - 0.5f) * 0.45f + (num2 - 0.5f) * 0.24f, 0.4f, 1f);
					array[i * 96 + j] = new Color(tone.r * num3, tone.g * num3, tone.b * num3, 1f);
				}
			}
			val2.SetPixels(array);
			val2.Apply(false, false);
			val.enableInstancing = true;
			val.SetFloat("_Glossiness", 0.12f);
			val.mainTexture = (Texture)(object)val2;
			val.color = Color.white;
			return val;
		}

		internal static void BuildBody(Transform root)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: 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_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0404: Unknown result type (might be due to invalid IL or missing references)
			//IL_044a: Unknown result type (might be due to invalid IL or missing references)
			//IL_045e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0492: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0527: Unknown result type (might be due to invalid IL or missing references)
			//IL_053b: Unknown result type (might be due to invalid IL or missing references)
			PrepareMaterials();
			int num = LayerMask.NameToLayer("piece");
			if (num < 0)
			{
				num = 0;
			}
			for (int i = 0; i < 11; i++)
			{
				float num2 = -2.25f + (float)i * 0.45f;
				Block(root, "FloorPlank", new Vector3(num2, -0.12f, 0f), new Vector3(0.425f, 0.18f, 4.05f), _wood, num);
			}
			float[] array = new float[2] { -2.05f, 2.05f };
			foreach (float num3 in array)
			{
				float[] array2 = new float[2] { -1.64f, 1.64f };
				foreach (float num4 in array2)
				{
					Block(root, "FoundationFoot", new Vector3(num3, -0.39f, num4), new Vector3(0.36f, 0.82f, 0.36f), _darkWood, num);
					Block(root, "MainPost", new Vector3(num3, 1.46f, num4), new Vector3(0.25f, 3.15f, 0.25f), _darkWood, num);
					Block(root, "PostCollar", new Vector3(num3, 0.12f, num4), new Vector3(0.39f, 0.12f, 0.39f), _wood, num);
				}
			}
			array = new float[2] { -1.52f, 1.52f };
			foreach (float num5 in array)
			{
				Block(root, "FloorCrossBeam", new Vector3(0f, -0.29f, num5), new Vector3(4.7f, 0.24f, 0.2f), _darkWood, num);
			}
			for (int l = 0; l < 12; l++)
			{
				float num6 = -2.2f + (float)l * 0.4f;
				Block(root, "BackBoard", new Vector3(num6, 1.55f, 1.82f), new Vector3(0.385f, 2.85f, 0.13f), _wood, num);
			}
			array = new float[2] { -2.22f, 2.22f };
			foreach (float num7 in array)
			{
				for (int m = 0; m < 5; m++)
				{
					Block(root, "SideRail", new Vector3(num7, 0.32f + (float)m * 0.33f, 0.2f), new Vector3(0.16f, 0.31f, 3.18f), _wood, num);
				}
				Block(root, "SideBeam", new Vector3(num7, 1.98f, 0.1f), new Vector3(0.22f, 0.19f, 3.6f), _darkWood, num);
			}
			for (int n = 0; n < 10; n++)
			{
				Block(root, "CounterBoard", new Vector3(-1.96f + (float)n * 0.435f, 1.07f, -1.46f), new Vector3(0.415f, 0.15f, 0.95f), _wood, num);
			}
			for (int num8 = 0; num8 < 5; num8++)
			{
				Block(root, "CounterFrontBoard", new Vector3(0f, 0.13f + (float)num8 * 0.17f, -1.91f), new Vector3(4.1f, 0.16f, 0.12f), _darkWood, num);
			}
			Block(root, "CounterUpperRim", new Vector3(0f, 1.12f, -1.92f), new Vector3(4.5f, 0.17f, 0.19f), _darkWood, num);
			Block(root, "CounterBottomShelf", new Vector3(0f, 0.33f, -1.1f), new Vector3(3.8f, 0.14f, 0.8f), _wood, num);
			array = new float[2] { -1.9f, 1.9f };
			foreach (float num9 in array)
			{
				Block(root, "RoofCrossBeam", new Vector3(0f, 2.9f, num9), new Vector3(4.6f, 0.16f, 0.21f), _darkWood, num);
			}
			Block(root, "SignFace", new Vector3(0f, 2.64f, -1.98f), new Vector3(1.85f, 0.44f, 0.15f), _signWood, num);
			Block(root, "SignTop", new Vector3(0f, 2.9f, -1.98f), new Vector3(2.06f, 0.09f, 0.2f), _darkWood, num);
			array = new float[2] { -0.9f, 0.9f };
			foreach (float num10 in array)
			{
				Block(root, "SignHanger", new Vector3(num10, 2.9f, -1.98f), new Vector3(0.08f, 0.45f, 0.1f), _darkWood, num);
			}
			Decorate(root, num);
		}

		private static Transform Block(Transform parent, string name, Vector3 localPos, Vector3 localSize, Material material, int layer, bool roof = false)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)obj).name = name;
			obj.layer = layer;
			obj.tag = (roof ? "Untagged" : "leaky");
			MeshFilter component = obj.GetComponent<MeshFilter>();
			if ((Object)(object)component != (Object)null)
			{
				component.sharedMesh = WorkshopMesh.Box;
			}
			obj.transform.SetParent(parent, false);
			obj.transform.localPosition = localPos;
			obj.transform.localRotation = Quaternion.identity;
			obj.transform.localScale = localSize;
			MeshRenderer component2 = obj.GetComponent<MeshRenderer>();
			if ((Object)(object)component2 != (Object)null)
			{
				((Renderer)component2).sharedMaterial = material;
				if ((Object)(object)material == (Object)null)
				{
					((Renderer)component2).enabled = false;
				}
			}
			return obj.transform;
		}

		internal static void BuildRoof(Transform root)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: 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)
			PrepareMaterials();
			int num = LayerMask.NameToLayer("piece");
			if (num < 0)
			{
				num = 0;
			}
			for (int i = 0; i < 9; i++)
			{
				float num2 = -2.24f + (float)i * 0.56f;
				Block(root, "RoofLeft", new Vector3(-1.14f, 0.46f, num2), new Vector3(2.66f, 0.16f, 0.57f), _roof, num, roof: true).localRotation = Quaternion.Euler(0f, 0f, 22f);
				Block(root, "RoofRight", new Vector3(1.14f, 0.46f, num2), new Vector3(2.66f, 0.16f, 0.57f), _roof, num, roof: true).localRotation = Quaternion.Euler(0f, 0f, -22f);
			}
			Block(root, "RoofRidge", new Vector3(0f, 0.93f, 0f), new Vector3(0.28f, 0.19f, 5.15f), _darkWood, num, roof: true);
			float[] array = new float[2] { -2.48f, 2.48f };
			foreach (float num3 in array)
			{
				Block(root, "CarvedGableLeft", new Vector3(-1.14f, 0.46f, num3), new Vector3(2.72f, 0.2f, 0.16f), _darkWood, num, roof: true).localRotation = Quaternion.Euler(0f, 0f, 22f);
				Block(root, "CarvedGableRight", new Vector3(1.14f, 0.46f, num3), new Vector3(2.72f, 0.2f, 0.16f), _darkWood, num, roof: true).localRotation = Quaternion.Euler(0f, 0f, -22f);
			}
			array = new float[2] { -2.37f, 2.37f };
			foreach (float num4 in array)
			{
				Block(root, "EaveTrim", new Vector3(num4, -0.04f, 0f), new Vector3(0.18f, 0.18f, 5.12f), _darkWood, num, roof: true);
			}
		}

		private static Material SolidMaterial(Shader shader, Color color, float metallic)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			Material val = new Material(shader)
			{
				color = color,
				enableInstancing = true
			};
			val.SetFloat("_Metallic", metallic);
			val.SetFloat("_Glossiness", 0.22f);
			return val;
		}

		private static Transform Ornament(Transform root, string name, Vector3 position, Vector3 size, Material material, int layer)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			Transform obj = Block(root, name, position, size, material, layer);
			Object.DestroyImmediate((Object)(object)((Component)obj).GetComponent<Collider>());
			return obj;
		}

		private static void Decorate(Transform root, int layer)
		{
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: 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)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_037f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0413: Unknown result type (might be due to invalid IL or missing references)
			//IL_045f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0473: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_04eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0514: Unknown result type (might be due to invalid IL or missing references)
			//IL_0528: Unknown result type (might be due to invalid IL or missing references)
			//IL_055c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0570: Unknown result type (might be due to invalid IL or missing references)
			//IL_0596: Unknown result type (might be due to invalid IL or missing references)
			//IL_05aa: 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_05e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0622: Unknown result type (might be due to invalid IL or missing references)
			//IL_0636: Unknown result type (might be due to invalid IL or missing references)
			float[] array = new float[2] { -2.05f, 2.05f };
			foreach (float num in array)
			{
				float[] array2 = new float[2] { -1.64f, 1.64f };
				foreach (float num2 in array2)
				{
					float[] array3 = new float[2] { 0.28f, 2.55f };
					foreach (float num3 in array3)
					{
						Ornament(root, "IronPostBand", new Vector3(num, num3, num2), new Vector3(0.27f, 0.09f, 0.27f), _iron, layer);
					}
					Ornament(root, "DiagonalBrace", new Vector3(num - Mathf.Sign(num) * 0.3f, 2.56f, num2), new Vector3(0.15f, 0.88f, 0.18f), _darkWood, layer).localRotation = Quaternion.Euler(0f, 0f, Mathf.Sign(num) * -43f);
				}
				Lantern(root, new Vector3(num, 2.24f, -1.87f), layer);
			}
			array = new float[2] { 2.43f, 2.85f };
			foreach (float num4 in array)
			{
				Ornament(root, "SignCarving", new Vector3(0f, num4, -2.072f), new Vector3(1.86f, 0.035f, 0.028f), _brass, layer);
			}
			array = new float[2] { -0.83f, 0.83f };
			foreach (float num5 in array)
			{
				Ornament(root, "SignStud", new Vector3(num5, 2.64f, -2.075f), new Vector3(0.07f, 0.07f, 0.04f), _brass, layer);
			}
			GameObject val = new GameObject("LocalizedWorkshopSign");
			val.transform.SetParent(root, false);
			val.transform.localPosition = new Vector3(0f, 2.64f, -2.059f);
			val.AddComponent<WorkshopSign>().Initialize();
			Ornament(root, "WritingMat", new Vector3(0.97f, 1.158f, -1.43f), new Vector3(1.02f, 0.025f, 0.6f), _darkWood, layer);
			Ornament(root, "Parchment", new Vector3(0.93f, 1.18f, -1.45f), new Vector3(0.42f, 0.022f, 0.4f), _paper, layer).localRotation = Quaternion.Euler(0f, 12f, 0f);
			Ornament(root, "InkPot", new Vector3(1.38f, 1.23f, -1.24f), new Vector3(0.13f, 0.15f, 0.13f), _iron, layer);
			Ornament(root, "WritingQuill", new Vector3(1.38f, 1.39f, -1.24f), new Vector3(0.035f, 0.32f, 0.035f), _paper, layer).localRotation = Quaternion.Euler(0f, 0f, -24f);
			Ornament(root, "ToolBoard", new Vector3(-1.02f, 1.9f, 1.69f), new Vector3(1.5f, 0.65f, 0.1f), _darkWood, layer);
			for (int l = 0; l < 4; l++)
			{
				float num6 = -1.54f + (float)l * 0.34f;
				Ornament(root, "ToolHandle", new Vector3(num6, 1.87f, 1.6f), new Vector3(0.065f, 0.38f, 0.06f), _wood, layer);
				Ornament(root, "ToolHead", new Vector3(num6, 2.08f, 1.59f), new Vector3((l % 2 == 0) ? 0.22f : 0.09f, 0.1f, 0.09f), _iron, layer);
			}
			array = new float[3] { 0.72f, 1.42f, 2.13f };
			foreach (float num7 in array)
			{
				Block(root, "DisplayShelf", new Vector3(1.16f, num7, 1.54f), new Vector3(1.48f, 0.1f, 0.43f), _darkWood, layer);
			}
			for (int m = 0; m < 3; m++)
			{
				Ornament(root, "Ledger", new Vector3(0.74f + (float)m * 0.32f, 1.56f, 1.48f), new Vector3(0.2f, 0.23f, 0.28f), _wood, layer).localRotation = Quaternion.Euler(0f, 0f, (float)((m - 1) * 8));
				Ornament(root, "LedgerSpine", new Vector3(0.74f + (float)m * 0.32f, 1.56f, 1.32f), new Vector3(0.14f, 0.03f, 0.025f), _brass, layer);
			}
			Ornament(root, "DisplayBase", new Vector3(-1.18f, 1.22f, -1.4f), new Vector3(0.63f, 0.15f, 0.45f), _darkWood, layer);
			Ornament(root, "EngravedBlade", new Vector3(-1.18f, 1.37f, -1.4f), new Vector3(0.56f, 0.055f, 0.1f), _iron, layer).localRotation = Quaternion.Euler(0f, 20f, 0f);
			Ornament(root, "BladeGrip", new Vector3(-1.52f, 1.37f, -1.4f), new Vector3(0.22f, 0.07f, 0.08f), _wood, layer);
			Ornament(root, "BladeGuard", new Vector3(-1.4f, 1.37f, -1.4f), new Vector3(0.06f, 0.08f, 0.25f), _brass, layer);
		}

		private static void Lantern(Transform root, Vector3 position, int layer)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_0099: 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)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			Ornament(root, "LanternHook", position + Vector3.up * 0.4f, new Vector3(0.07f, 0.4f, 0.07f), _iron, layer);
			MeshRenderer component = ((Component)Ornament(root, "LanternGlow", position, new Vector3(0.18f, 0.28f, 0.18f), _glow, layer)).GetComponent<MeshRenderer>();
			((Renderer)component).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)component).receiveShadows = false;
			float[] array = new float[2] { -0.18f, 0.18f };
			foreach (float num in array)
			{
				Ornament(root, "LanternCap", position + Vector3.up * num, new Vector3(0.3f, 0.07f, 0.3f), _iron, layer);
			}
			array = new float[2] { -0.12f, 0.12f };
			foreach (float num2 in array)
			{
				float[] array2 = new float[2] { -0.12f, 0.12f };
				foreach (float num3 in array2)
				{
					Ornament(root, "LanternBar", position + new Vector3(num2, 0f, num3), new Vector3(0.025f, 0.32f, 0.025f), _iron, layer);
				}
			}
			if ((Object)(object)_glow != (Object)null)
			{
				GameObject val = new GameObject("WorkshopWarmLight");
				val.transform.SetParent(root, false);
				val.transform.localPosition = position;
				WorkshopLighting.Configure(val.AddComponent<Light>());
			}
		}
	}
	internal static class LightingRules
	{
		internal static float Range(float native)
		{
			return Math.Max(6f, Math.Min(8f, native));
		}

		internal static float Intensity(float native)
		{
			if (!(native > 0f))
			{
				return 2.5f;
			}
			return Math.Max(2.5f, Math.Min(4f, native));
		}
	}
	internal static class MapAdminAccess
	{
		internal static bool Authorize(bool server, bool ready, bool connected, string authenticatedTransportId, Func<string, bool> nativeAdminCheck)
		{
			if (server && ready && connected && !string.IsNullOrEmpty(authenticatedTransportId) && nativeAdminCheck != null)
			{
				return nativeAdminCheck(authenticatedTransportId);
			}
			return false;
		}
	}
	internal sealed class MerchantDialogue : MonoBehaviour
	{
		private const float GestureBlendSeconds = 0.18f;

		private static readonly List<MerchantDialogue> Speakers = new List<MerchantDialogue>();

		private static float s_nextAmbientAt;

		private static MerchantDialogue s_currentVoice;

		private readonly DialogueScheduler _scheduler = new DialogueScheduler();

		private readonly Dictionary<int, List<AudioClip>> _voices = new Dictionary<int, List<AudioClip>>();

		private readonly List<AudioClip> _allVoices = new List<AudioClip>();

		private AudioSource _voice;

		private Animator _animator;

		private ShopState _shop;

		private float _nextProximity;

		private float _nextIdle;

		private bool _near;

		private bool _warned;

		private bool _warnedAnimation;

		private float _dialogHeight = 2f;

		internal void Initialize(ShopState shop)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			_shop = shop;
			_animator = ((Component)this).GetComponentInChildren<Animator>(true);
			_nextIdle = Time.unscaledTime + 40f;
			GameObject val = new GameObject("NamekeeperVoice");
			val.transform.SetParent(((Component)this).transform, false);
			val.transform.localPosition = Vector3.up * 1.35f;
			_voice = val.AddComponent<AudioSource>();
			_voice.playOnAwake = false;
			_voice.loop = false;
			_voice.spatialBlend = 1f;
			_voice.minDistance = 2f;
			_voice.maxDistance = 14f;
			_voice.rolloffMode = (AudioRolloffMode)0;
			try
			{
				GameObject val2 = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab("Hildir") : null);
				Trader val3 = (((Object)(object)val2 != (Object)null) ? val2.GetComponentInChildren<Trader>(true) : null);
				if ((Object)(object)val3 != (Object)null)
				{
					_dialogHeight = Mathf.Clamp(val3.m_dialogHeight, 1.5f, 3f);
					ReadVoices(0, val3.m_randomTalkFX);
					ReadVoices(1, val3.m_randomGreetFX);
					ReadVoices(2, val3.m_randomStartTradeFX);
					ReadVoices(3, val3.m_randomBuyFX);
					ReadVoices(4, val3.m_randomGoodbyeFX);
					ReadVoices(5, val3.m_randomSellFX);
				}
				ManualLogSource log = NamekeeperPlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)("Namekeeper merchant dialogue: " + _allVoices.Count + " Hildir voice clips discovered; language follows the game."));
				}
				if (_allVoices.Count == 0)
				{
					ManualLogSource log2 = NamekeeperPlugin.Log;
					if (log2 != null)
					{
						log2.LogWarning((object)"Hildir voice clips unavailable; merchant text remains enabled.");
					}
				}
			}
			catch (Exception ex)
			{
				Warn(ex);
			}
			Request(DialogueCue.Arrival);
		}

		private void ReadVoices(int group, EffectList effects)
		{
			List<AudioClip> list = new List<AudioClip>();
			if (effects?.m_effectPrefabs != null)
			{
				EffectData[] effectPrefabs = effects.m_effectPrefabs;
				foreach (EffectData val in effectPrefabs)
				{
					if (val == null || !val.m_enabled || (Object)(object)val.m_prefab == (Object)null)
					{
						continue;
					}
					ZSFX[] componentsInChildren = val.m_prefab.GetComponentsInChildren<ZSFX>(true);
					foreach (ZSFX val2 in componentsInChildren)
					{
						if (val2.m_audioClips == null)
						{
							continue;
						}
						AudioClip[] audioClips = val2.m_audioClips;
						foreach (AudioClip val3 in audioClips)
						{
							if ((Object)(object)val3 != (Object)null)
							{
								if (!list.Contains(val3))
								{
									list.Add(val3);
								}
								if (!_allVoices.Contains(val3))
								{
									_allVoices.Add(val3);
								}
							}
						}
					}
					AudioSource componentInChildren = val.m_prefab.GetComponentInChildren<AudioSource>(true);
					if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.outputAudioMixerGroup != (Object)null)
					{
						_voice.outputAudioMixerGroup = componentInChildren.outputAudioMixerGroup;
					}
				}
			}
			_voices[group] = list;
		}

		internal void Request(DialogueCue cue)
		{
			if (NamekeeperPlugin.DialogueEnabled.Value)
			{
				_scheduler.Request(cue, Time.unscaledTime);
			}
		}

		private void OnEnable()
		{
			if (!Speakers.Contains(this))
			{
				Speakers.Add(this);
			}
		}

		private void OnDisable()
		{
			Speakers.Remove(this);
			_scheduler.Clear();
			if ((Object)(object)_voice != (Object)null)
			{
				_voice.Stop();
			}
			if ((Object)(object)s_currentVoice == (Object)(object)this)
			{
				s_currentVoice = null;
			}
			if ((Object)(object)Chat.instance != (Object)null)
			{
				Chat.instance.ClearNpcText(((Component)this).gameObject);
			}
		}

		private void Update()
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: 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)
			if ((Object)(object)_shop == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			if (!NamekeeperPlugin.DialogueEnabled.Value)
			{
				_scheduler.Clear();
				if ((Object)(object)_voice != (Object)null && _voice.isPlaying)
				{
					_voice.Stop();
				}
				return;
			}
			if (!NamekeeperPlugin.VoiceEnabled.Value && (Object)(object)_voice != (Object)null && _voice.isPlaying)
			{
				_voice.Stop();
			}
			float unscaledTime = Time.unscaledTime;
			float num = Vector3.Distance(((Component)Player.m_localPlayer).transform.position, ((Component)this).transform.position);
			if (unscaledTime >= _nextProximity)
			{
				_nextProximity = unscaledTime + 0.5f;
				bool flag = num <= (_near ? 9f : 6f);
				bool flag2 = IsNearest(((Component)Player.m_localPlayer).transform.position, num);
				if (flag && !_near && flag2)
				{
					Request(DialogueCue.Greeting);
				}
				else if (!flag && _near && num < 15f)
				{
					Request(DialogueCue.Goodbye);
				}
				_near = flag;
				NamekeeperPlugin instance = NamekeeperPlugin.Instance;
				bool flag3 = instance != null && instance.Ui?.IsOpen == true;
				if (flag && flag2 && !flag3 && unscaledTime >= _nextIdle)
				{
					_nextIdle = unscaledTime + Random.Range(40f, 65f);
					Request(DialogueCue.Idle);
				}
			}
			if (!(num > 16f) && !((Object)(object)Chat.instance == (Object)null) && (_scheduler.PendingPriority != 1 || (!(unscaledTime < s_nextAmbientAt) && IsNearest(((Component)Player.m_localPlayer).transform.position, num))) && _scheduler.TryTake(unscaledTime, out var cue))
			{
				if (DialogueLines.Priority(cue) == 1)
				{
					s_nextAmbientAt = unscaledTime + 6f;
				}
				Speak(cue);
			}
		}

		private bool IsNearest(Vector3 playerPosition, float distance)
		{
			//IL_0027: 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)
			foreach (MerchantDialogue speaker in Speakers)
			{
				if ((Object)(object)speaker != (Object)null && (Object)(object)speaker != (Object)(object)this && Vector3.Distance(playerPosition, ((Component)speaker).transform.position) < distance)
				{
					return false;
				}
			}
			return true;
		}

		private void Speak(DialogueCue cue)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Animate(cue);
				string selectedLanguage = Localization.instance.GetSelectedLanguage();
				string text = DialogueLines.Get(cue, selectedLanguage, Random.Range(0, 1000));
				if (string.IsNullOrEmpty(text))
				{
					return;
				}
				Chat.instance.SetNpcText(((Component)this).gameObject, Vector3.up * _dialogHeight, 20f, 5f, "", text, false);
				if (NamekeeperPlugin.VoiceEnabled.Value && !((Object)(object)_voice == (Object)null) && _allVoices.Count != 0)
				{
					int num;
					switch (cue)
					{
					default:
						num = 0;
						break;
					case DialogueCue.SuccessName:
					case DialogueCue.SuccessDescription:
					case DialogueCue.SuccessBoth:
					case DialogueCue.SuccessReset:
						num = 3;
						break;
					case DialogueCue.Goodbye:
						num = 4;
						break;
					case DialogueCue.Open:
						num = 2;
						break;
					case DialogueCue.Arrival:
					case DialogueCue.Greeting:
						num = 1;
						break;
					}
					int key = num;
					List<AudioClip> value;
					List<AudioClip> list = ((_voices.TryGetValue(key, out value) && value.Count > 0) ? value : _allVoices);
					if ((Object)(object)s_currentVoice != (Object)null && (Object)(object)s_currentVoice != (Object)(object)this && (Object)(object)s_currentVoice._voice != (Object)null)
					{
						s_currentVoice._voice.Stop();
					}
					s_currentVoice = this;
					_voice.Stop();
					_voice.volume = NamekeeperPlugin.VoiceVolume.Value;
					_voice.pitch = 1f;
					_voice.clip = list[Random.Range(0, list.Count)];
					_voice.Play();
				}
			}
			catch (Exception ex)
			{
				Warn(ex);
			}
		}

		private void Animate(DialogueCue cue)
		{
			if ((Object)(object)_animator == (Object)null || !((Behaviour)_animator).isActiveAndEnabled)
			{
				return;
			}
			string text;
			switch (cue)
			{
			case DialogueCue.Arrival:
			case DialogueCue.Greeting:
			case DialogueCue.Open:
				text = "Emote_wave";
				break;
			case DialogueCue.SelectItem:
			case DialogueCue.NameEdited:
			case DialogueCue.DescriptionEdited:
				text = "Emote_point";
				break;
			case DialogueCue.ResetName:
			case DialogueCue.ResetDescription:
			case DialogueCue.CancelReset:
				text = "Emote_shrug";
				break;
			case DialogueCue.SuccessName:
			case DialogueCue.SuccessDescription:
			case DialogueCue.SuccessBoth:
			case DialogueCue.SuccessReset:
				text = "Emote_cheer";
				break;
			case DialogueCue.Goodbye:
				text = "Emote_bow";
				break;
			case DialogueCue.NoChanges:
			case DialogueCue.NotEnoughCoins:
			case DialogueCue.InvalidText:
			case DialogueCue.ItemUnavailable:
			case DialogueCue.NoEligibleItems:
			case DialogueCue.NoRoof:
			case DialogueCue.TooFar:
			case DialogueCue.Failure:
				text = "Emote_nonono";
				break;
			default:
				text = null;
				break;
			}
			string text2 = text;
			if (text2 == null)
			{
				return;
			}
			int num = Animator.StringToHash("Base Layer.Emotes." + text2);
			if (!_animator.HasState(0, num))
			{
				if (!_warnedAnimation)
				{
					_warnedAnimation = true;
					ManualLogSource log = NamekeeperPlugin.Log;
					if (log != null)
					{
						log.LogWarning((object)("Player animation state unavailable: " + text2));
					}
				}
			}
			else
			{
				_animator.CrossFadeInFixedTime(num, 0.18f, 0, 0f);
			}
		}

		private void Warn(Exception ex)
		{
			if (!_warned)
			{
				_warned = true;
				ManualLogSource log = NamekeeperPlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("Merchant dialogue presentation unavailable: " + ex));
				}
			}
		}
	}
	internal static class MerchantVisual
	{
		private const int FemalePlayerModel = 1;

		private const string MerchantHair = "Hair6";

		private const string MerchantDress = "ArmorDress10";

		private const BindingFlags InstanceFields = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		private const BindingFlags PrivateInstanceMethod = BindingFlags.Instance | BindingFlags.NonPublic;

		internal static GameObject Create(ShopState shop)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: 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_015c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("NamekeeperMerchant");
			val.transform.SetParent(((Component)shop).transform, false);
			val.transform.localPosition = ShopState.MerchantLocalOffset;
			val.transform.localRotation = Quaternion.Euler(0f, 180f, 0f);
			int num = LayerMask.NameToLayer("piece");
			if (num >= 0)
			{
				val.layer = num;
			}
			val.SetActive(false);
			val.AddComponent<MerchantInteraction>().Shop = shop;
			CapsuleCollider obj = val.AddComponent<CapsuleCollider>();
			obj.center = new Vector3(0f, 0.8f, 0f);
			obj.height = 1.6f;
			obj.radius = 0.46f;
			((Collider)obj).isTrigger = false;
			if (!TryAttachPlayer(val.transform))
			{
				GameObject obj2 = GameObject.CreatePrimitive((PrimitiveType)1);
				((Object)obj2).name = "FallbackMerchantVisual";
				obj2.transform.SetParent(val.transform, false);
				obj2.transform.localPosition = new Vector3(0f, 0.8f, 0f);
				obj2.transform.localScale = new Vector3(0.6f, 0.8f, 0.6f);
				Collider component = obj2.GetComponent<Collider>();
				if ((Object)(object)component != (Object)null)
				{
					Object.Destroy((Object)(object)component);
				}
				Renderer component2 = obj2.GetComponent<Renderer>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.material.color = new Color(0.46f, 0.29f, 0.18f);
				}
				NamekeeperPlugin.Log.LogWarning((object)"Female player visual unavailable: using fallback NPC shape");
			}
			val.SetActive(true);
			val.AddComponent<MerchantDialogue>().Initialize(shop);
			return val;
		}

		private static bool TryAttachPlayer(Transform holder)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ZNetScene.instance == (Object)null)
			{
				return false;
			}
			GameObject prefab = ZNetScene.instance.GetPrefab("Player");
			if ((Object)(object)prefab == (Object)null)
			{
				return false;
			}
			bool forceDisableInit = ZNetView.m_forceDisableInit;
			GameObject val = null;
			try
			{
				ZNetView.m_forceDisableInit = true;
				val = Object.Instantiate<GameObject>(prefab, holder);
				((Object)val).name = "NamekeeperPlayerVisual";
				val.transform.localPosition = Vector3.zero;
				val.transform.localRotation = Quaternion.identity;
				val.transform.localScale = Vector3.one;
				PreparePlayerAppearance(val);
				StripGameplayComponents(val);
				Animator componentInChildren = val.GetComponentInChildren<Animator>(true);
				if ((Object)(object)componentInChildren == (Object)null)
				{
					throw new InvalidOperationException("Player prefab has no Animator");
				}
				componentInChildren.applyRootMotion = false;
				((Behaviour)componentInChildren).enabled = true;
				return true;
			}
			catch (Exception ex)
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val);
				}
				NamekeeperPlugin.Log.LogWarning((object)("Female player appearance setup failed: " + ex));
				return false;
			}
			finally
			{
				ZNetView.m_forceDisableInit = forceDisableInit;
			}
		}

		private static void PreparePlayerAppearance(GameObject clone)
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			VisEquipment component = clone.GetComponent<VisEquipment>();
			if ((Object)(object)component == (Object)null)
			{
				throw new InvalidOperationException("Player prefab has no VisEquipment");
			}
			int stableHashCode = StringExtensionMethods.GetStableHashCode("Hair6");
			int stableHashCode2 = StringExtensionMethods.GetStableHashCode("ArmorDress10");
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(0.78f, 0.61f, 0.49f);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(0.18f, 0.08f, 0.035f);
			SetField(component, "m_randomModelIndex", false);
			SetField(component, "m_npcHairChance", 0f);
			SetField(component, "m_npcBeardChance", 0f);
			SetField(component, "m_modelIndex", 1);
			SetField(component, "m_currentModelIndex", -1);
			SetField(component, "m_skinColor", val);
			SetField(component, "m_hairColor", val2);
			InvokePrivate(component, "Awake");
			component.SetModel(1);
			component.SetSkinColor(val);
			component.SetHairColor(val2);
			component.SetHairItem(stableHashCode);
			component.SetBeardItem(0);
			component.SetChestItem(stableHashCode2);
			component.SetLegItem(0);
			component.CustomUpdate(0f, 0f);
			component.CustomUpdate(0f, 0f);
			((Behaviour)component).enabled = false;
			InvokePrivate(component, "OnDisable");
			Object.DestroyImmediate((Object)(object)component);
		}

		private static void SetField(VisEquipment target, string name, object value)
		{
			FieldInfo? field = typeof(VisEquipment).GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field == null)
			{
				throw new MissingFieldException(typeof(VisEquipment).FullName, name);
			}
			field.SetValue(target, value);
		}

		private static void InvokePrivate(VisEquipment target, string name)
		{
			MethodInfo? method = typeof(VisEquipment).GetMethod(name, BindingFlags.Instance | BindingFlags.NonPublic);
			if (method == null)
			{
				throw new MissingMethodException(typeof(VisEquipment).FullName, name);
			}
			method.Invoke(target, null);
		}

		private static void StripGameplayComponents(GameObject clone)
		{
			MonoBehaviour[] componentsInChildren = clone.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val);
				}
			}
			Collider[] componentsInChildren2 = clone.GetComponentsInChildren<Collider>(true);
			foreach (Collider val2 in componentsInChildren2)
			{
				if ((Object)(object)val2 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val2);
				}
			}
			Rigidbody[] componentsInChildren3 = clone.GetComponentsInChildren<Rigidbody>(true);
			foreach (Rigidbody val3 in componentsInChildren3)
			{
				if ((Object)(object)val3 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val3);
				}
			}
			AudioSource[] componentsInChildren4 = clone.GetComponentsInChildren<AudioSource>(true);
			foreach (AudioSource obj in componentsInChildren4)
			{
				obj.Stop();
				Object.DestroyImmediate((Object)(object)obj);
			}
			ParticleSystem[] componentsInChildren5 = clone.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem obj2 in componentsInChildren5)
			{
				obj2.Stop(true, (ParticleSystemStopBehavior)0);
				Object.DestroyImmediate((Object)(object)obj2);
			}
			ParticleSystemRenderer[] componentsInChildren6 = clone.GetComponentsInChildren<ParticleSystemRenderer>(true);
			foreach (ParticleSystemRenderer val4 in componentsInChildren6)
			{
				if ((Object)(object)val4 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val4);
				}
			}
			Light[] componentsInChildren7 = clone.GetComponentsInChildren<Light>(true);
			foreach (Light val5 in componentsInChildren7)
			{
				if ((Object)(object)val5 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val5);
				}
			}
		}
	}
	internal sealed class MerchantInteraction : MonoBehaviour, Hoverable, Interactable
	{
		internal ShopState Shop;

		public string GetHoverName()
		{
			return L.T("Namekeeper", "Хранительница имён");
		}

		public string GetHoverText()
		{
			if ((Object)(object)Shop == (Object)null || ((Object)(object)NamekeeperPlugin.Instance != (Object)null && NamekeeperPlugin.Instance.Ui != null && NamekeeperPlugin.Instance.Ui.IsOpen))
			{
				return "";
			}
			string text = "<color=#F1D7A0><b>" + GetHoverName() + "</b></color>";
			if (!Shop.CanServe(out var reason))
			{
				return text + "\n<color=#D6A97A>" + reason + "</color>";
			}
			string text2 = L.Vanilla("$KEY_Use");
			if (string.IsNullOrEmpty(text2) || text2.StartsWith("$", StringComparison.Ordinal))
			{
				text2 = "E";
			}
			return text + "\n[<color=#EFC36B><b>" + text2 + "</b></color>] " + L.T("Personalize item", "Изменить предмет");
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (hold || (Object)(object)Shop == (Object)null || (Object)(object)user != (Object)(object)Player.m_localPlayer)
			{
				return false;
			}
			if (Vector3.Distance(((Component)user).transform.position, ((Component)this).transform.position) > 3.5f)
			{
				return false;
			}
			if (!Shop.CanServe(out var reason))
			{
				Shop.Speak(DialogueCue.NoRoof);
				if ((Object)(object)MessageHud.instance != (Object)null)
				{
					MessageHud.instance.ShowMessage((MessageType)2, reason, 0, (Sprite)null, false, true);
				}
				return false;
			}
			NamekeeperPlugin.Instance?.Ui?.Open(Shop);
			return true;
		}

		public float GetHoverOffset()
		{
			return 0f;
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			if ((Object)(object)user == (Object)(object)Player.m_localPlayer)
			{
				Shop?.Speak(DialogueCue.ItemUnavailable);
			}
			return false;
		}
	}
	internal static class NamekeeperEffects
	{
		internal static void Play(Vector3 position)
		{
			//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_0010: 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_001d: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			GameObject val = new GameObject("NamekeeperGoldSparkles");
			val.transform.position = position;
			ParticleSystem obj = val.AddComponent<ParticleSystem>();
			MainModule main = obj.main;
			((MainModule)(ref main)).loop = false;
			((MainModule)(ref main)).duration = 1.15f;
			((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(1.05f);
			((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(1.7f);
			((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.09f);
			((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(1f, 0.77f, 0.25f, 1f));
			((MainModule)(ref main)).maxParticles = 42;
			((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1;
			EmissionModule emission = obj.emission;
			((EmissionModule)(ref emission)).enabled = false;
			ShapeModule shape = obj.shape;
			((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0;
			((ShapeModule)(ref shape)).radius = 0.4f;
			obj.Emit(35);
			obj.Stop(true, (ParticleSystemStopBehavior)1);
			Object.Destroy((Object)val, 3f);
		}
	}
	internal sealed class NamekeeperGui : IDisposable
	{
		private ShopState _shop;

		private NativeHud _hud;

		private bool _open;

		private bool _submitting;

		private bool _inputBlocked;

		private bool _cursorSaved;

		private CursorLockMode _oldLock;

		private bool _oldVisible;

		private float _suppressInputUntil;

		private float _lastSubmit;

		private float _nextRefresh;

		private static readonly FieldInfo OtherInputRequests = typeof(GUIManager).GetField("InputBlockRequests", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

		internal ItemData SelectedItem { get; private set; }

		internal string NameDraft { get; private set; } = "";

		internal string DescriptionDraft { get; private set; } = "";

		internal bool ResetName { get; private set; }

		internal bool ResetDescription { get; private set; }

		internal string Filter { get; private set; } = "";

		internal string Notice { get; private set; } = "";

		internal bool IsOpen => _open;

		internal bool InputSuppressed
		{
			get
			{
				if (!_open)
				{
					return Time.unscaledTime < _suppressInputUntil;
				}
				return true;
			}
		}

		internal bool NameChanged
		{
			get
			{
				if (SelectedItem != null)
				{
					return ItemText.NameChanges(SelectedItem, NameDraft.Trim(), ResetName);
				}
				return false;
			}
		}

		internal bool DescriptionChanged
		{
			get
			{
				if (SelectedItem != null)
				{
					return ItemText.DescriptionChanges(SelectedItem, DescriptionDraft, ResetDescription);
				}
				return false;
			}
		}

		internal int TotalCost => (NameChanged ? NamekeeperPlugin.NameFee.Value : 0) + (DescriptionChanged ? NamekeeperPlugin.DescriptionFee.Value : 0);

		internal int Coins
		{
			get
			{
				Player localPlayer = Player.m_localPlayer;
				int? obj;
				if (localPlayer == null)
				{
					obj = null;
				}
				else
				{
					Inventory inventory = ((Humanoid)localPlayer).GetInventory();
					obj = ((inventory != null) ? new int?(inventory.CountItems("$item_coins", -1, true)) : ((int?)null));
				}
				int? num = obj;
				return num.GetValueOrDefault();
			}
		}

		internal bool CanSubmit
		{
			get
			{
				if (SelectedItem != null && !_submitting)
				{
					if (!NameChanged)
					{
						return DescriptionChanged;
					}
					return true;
				}
				return false;
			}
		}

		internal void Open(ShopState shop)
		{
			//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)
			if ((Object)(object)shop == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			if (!shop.CanServe(out var reason))
			{
				Say(reason);
				Speak(shop, DialogueCue.NoRoof);
				return;
			}
			if (_open)
			{
				Close(farewell: false);
			}
			try
			{
				_hud = ((_hud != null && _hud.IsAlive) ? _hud : new NativeHud(this));
				_oldLock = Cursor.lockState;
				_oldVisible = Cursor.visible;
				_cursorSaved = true;
				_shop = shop;
				_open = true;
				_suppressInputUntil = 0f;
				SelectedItem = null;
				string text = (Notice = "");
				string text3 = (Filter = text);
				string nameDraft = (DescriptionDraft = text3);
				NameDraft = nameDraft;
				bool resetName = (ResetDescription = false);
				ResetName = resetName;
				SetGameplayInputBlocked(blocked: true);
				_hud.Show();
				KeepCursor();
				Speak(shop, (EligibleItems().Count == 0) ? DialogueCue.NoEligibleItems : DialogueCue.Open);
			}
			catch (Exception ex)
			{
				ManualLogSource log = NamekeeperPlugin.Log;
				if (log != null)
				{
					log.LogError((object)("Could not open native shop UI: " + ex));
				}
				Close(farewell: false);
				Say(L.T("Could not open the shop. Check the log.", "Не удалось открыть лавку. Проверьте журнал."));
				Speak(shop, DialogueCue.Failure);
			}
		}

		internal void CloseIfShop(ShopState shop)
		{
			if ((Object)(object)_shop == (Object)(object)shop)
			{
				Close(farewell: false);
			}
		}

		internal void Close()
		{
			Close(farewell: true);
		}

		private void Close(bool farewell)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			ShopState shop = _shop;
			bool open = _open;
			_open = false;
			_shop = null;
			_suppressInputUntil = Time.unscaledTime + 0.16f;
			SelectedItem = null;
			try
			{
				_hud?.Hide();
			}
			finally
			{
				SetGameplayInputBlocked(blocked: false);
				if (_cursorSaved)
				{
					if (HasOtherInputRequests())
					{
						KeepCursor();
					}
					else
					{
						Cursor.visible = _oldVisible;
						Cursor.lockState = _oldLock;
					}
					_cursorSaved = false;
				}
			}
			if (open && farewell)
			{
				Speak(shop, DialogueCue.Goodbye);
			}
		}

		internal void Tick()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			if (!_open)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || (Object)(object)_shop == (Object)null || _hud == null || !_hud.IsAlive)
			{
				Close(farewell: false);
				return;
			}
			if (Vector3.Distance(((Component)localPlayer).transform.position, ((Component)_shop).transform.position) > 5.5f)
			{
				Speak(_shop, DialogueCue.TooFar);
				Close(farewell: false);
				return;
			}
			if (!_shop.CanServe(out var _))
			{
				Speak(_shop, DialogueCue.NoRoof);
				Close(farewell: false);
				return;
			}
			KeepCursor();
			if (Input.GetKeyDown((KeyCode)27))
			{
				Close();
			}
			else
			{
				if (Time.unscaledTime < _nextRefresh)
				{
					return;
				}
				_nextRefresh = Time.unscaledTime + 0.25f;
				try
				{
					if (SelectedItem != null && !HasItem(((Humanoid)localPlayer).GetInventory(), SelectedItem))
					{
						SelectedItem = null;
						Say(L.T("Selected item is no longer in your inventory.", "Выбранного предмета больше нет в инвентаре."));
						Speak(_shop, DialogueCue.ItemUnavailable);
					}
					_hud.Refresh();
				}
				catch (Exception ex)
				{
					ManualLogSource log = NamekeeperPlugin.Log;
					if (log != null)
					{
						log.LogWarning((object)("Shop UI refresh failed; closing safely: " + ex));
					}
					Close(farewell: false);
				}
			}
		}

		internal void LateTick()
		{
			if (_open)
			{
				KeepCursor();
			}
		}

		private static bool HasOtherInputRequests()
		{
			try
			{
				return OtherInputRequests?.GetValue(null) is int num && num > 0;
			}
			catch
			{
				return false;
			}
		}

		private static void KeepCursor()
		{
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
		}

		private void SetGameplayInputBlocked(bool blocked)
		{
			if (_inputBlocked == blocked)
			{
				return;
			}
			try
			{
				GUIManager.BlockInput(blocked);
				_inputBlocked = blocked;
			}
			catch (Exception ex)
			{
				ManualLogSource log = NamekeeperPlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("GUIManager.BlockInput failed: " + ex));
				}
			}
		}

		internal List<ItemData> EligibleItems()
		{
			List<ItemData> list = new List<ItemData>();
			Player localPlayer = Player.m_localPlayer;
			Inventory val = ((localPlayer != null) ? ((Humanoid)localPlayer).GetInventory() : null);
			if (val == null)
			{
				return list;
			}
			foreach (ItemData allItem in val.GetAllItems())
			{
				if (IsEligible(allItem) && (string.IsNullOrEmpty(Filter) || ItemText.GetName(allItem).IndexOf(Filter, StringComparison.OrdinalIgnoreCase) >= 0 || L.OriginalName(allItem).IndexOf(Filter, StringComparison.OrdinalIgnoreCase) >= 0))
				{
					list.Add(allItem);
				}
			}
			return list;
		}

		internal void SetFilter(string value)
		{
			Filter = value ?? "";
			_hud.Refresh();
		}

		internal void SetName(string value)
		{
			NameDraft = value ?? "";
			_hud.RefreshEditor();
		}

		internal void SetDescription(string value)
		{
			DescriptionDraft = value ?? "";
			_hud.RefreshEditor();
		}

		internal void FinishNameEdit()
		{
			if (NameChanged && !ResetName)
			{
				Speak(_shop, DialogueCue.NameEdited);
			}
		}

		internal void FinishDescriptionEdit()
		{
			if (DescriptionChanged && !ResetDescription)
			{
				Speak(_shop, DialogueCue.DescriptionEdited);
			}
		}

		internal void ToggleNameReset()
		{
			ResetName = !ResetName;
			Speak(_shop, (!ResetName) ? DialogueCue.CancelReset : (NameChanged ? DialogueCue.ResetName : DialogueCue.NoChanges));
			_hud.RefreshEditor();
		}

		internal void ToggleDescriptionReset()
		{
			ResetDescription = !ResetDescription;
			Speak(_shop, (!ResetDescription) ? DialogueCue.CancelReset : (DescriptionChanged ? DialogueCue.ResetDescription : DialogueCue.NoChanges));
			_hud.RefreshEditor();
		}

		internal void SwitchLanguage()
		{
			NamekeeperPlugin.Language.Value = (L.Ru ? "English" : "Russian");
			((BaseUnityPlugin)NamekeeperPlugin.Instance).Config.Save();
			_hud.RefreshLanguage();
		}

		internal void Select(ItemData item)
		{
			if (IsEligible(item))
			{
				Player localPlayer = Player.m_localPlayer;
				if (HasItem((localPlayer != null) ? ((Humanoid)localPlayer).GetInventory() : null, item))
				{
					SelectedItem = item;
					NameDraft = ItemText.GetName(item);
					DescriptionDraft = ItemText.GetDescription(item);
					bool resetName = (ResetDescription = false);
					ResetName = resetName;
					Notice = "";
					_hud.Refresh();
					_hud.FocusName();
					Speak(_shop, DialogueCue.SelectItem);
				}
			}
		}

		internal void Commit()
		{
			//IL_0076: 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_035e: Unknown result type (might be due to invalid IL or missing references)
			if (!_open || _submitting || Time.realtimeSinceStartup - _lastSubmit < 0.5f)
			{
				return;
			}
			_submitting = true;
			_lastSubmit = Time.realtimeSinceS