Decompiled source of Waystones v1.1.0

Waystones.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using JetBrains.Annotations;
using LocalizationManager;
using Microsoft.CodeAnalysis;
using ServerSync;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using Waystones;
using YamlDotNet.Serialization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Waystones")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Waystones")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("1af3a9e7-99be-490a-a211-741aaff1aef2")]
[assembly: AssemblyFileVersion("1.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
public class WaystoneSmall : MonoBehaviour, TextReceiver, Hoverable, Interactable
{
	private class SacrificeHoverItem
	{
		public string itemName;

		public int amount;

		public int value;

		public int inventoryCount;

		public int totalCount;
	}

	[HarmonyPatch(typeof(TextsDialog), "UpdateTextsList")]
	public static class TextsDialog_UpdateTextsList_WaystoneSacrificeItems
	{
		private static void Postfix(TextsDialog __instance)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			string text = BuildConfiguredSacrificeItemsText();
			if (text.Length != 0)
			{
				string waystoneTopic = Localization.instance.Localize("$ws_tutorial_waystone_label");
				int num = __instance.m_texts.FindIndex((TextInfo info) => info != null && (info.m_topic == "$ws_tutorial_waystone_label" || info.m_topic == waystoneTopic || Localization.instance.Localize(info.m_topic) == waystoneTopic));
				if (num >= 0)
				{
					__instance.m_texts.Insert(num + 1, new TextInfo("$ws_compendium_sacrifice_items_topic", text));
				}
			}
		}
	}

	[HarmonyPatch(typeof(TextInput), "Update")]
	public static class TextInput_Update_HoldUseButton
	{
		private static void Postfix(TextInput __instance)
		{
			((TMP_InputField)__instance.m_inputField).readOnly = false;
			if (__instance.m_queuedSign is WaystoneSmall && TextInput.IsVisible() && blockInputUntil > Time.time)
			{
				((TMP_InputField)__instance.m_inputField).readOnly = true;
			}
		}
	}

	[CompilerGenerated]
	private sealed class <ActivationToggleRequested>d__24 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public Player player;

		public WaystoneSmall <>4__this;

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

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

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

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

		private bool MoveNext()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = (object)new WaitWhile((Func<bool>)(() => ZInput.GetButton("Use") || ZInput.GetButton("JoyUse")));
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				if (TextInput.IsVisible())
				{
					return false;
				}
				if (IsSearchAllowed(player, validateCharge: false) && global::Waystones.Waystones.CanCast())
				{
					((Character)player).Message((MessageType)2, "$ws_piece_waystone_activation", 0, (Sprite)null);
					WaystoneList.EnterSearchMode(<>4__this.m_nview.GetZDO());
				}
				return false;
			}
		}

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

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

	public GameObject m_activeObject;

	public EffectList m_activateEffect = new EffectList();

	public EffectList m_deactivateEffect = new EffectList();

	public static bool initial = false;

	public static StringBuilder sb = new StringBuilder();

	public ZNetView m_nview;

	public static float blockInputUntil;

	public const float waystoneHoldSetTagDelay = 0.35f;

	private const float sacrificeHoverItemsUpdateInterval = 1f;

	private static float nextSacrificeHoverItemsUpdate;

	private static readonly List<SacrificeHoverItem> sacrificeHoverItems = new List<SacrificeHoverItem>();

	public void Awake()
	{
		if (!initial)
		{
			m_activeObject = ((Component)((Component)this).transform.Find("WayEffect")).gameObject;
			m_activeObject.SetActive(false);
			m_nview = ((Component)this).GetComponent<ZNetView>();
			if ((Object)(object)m_nview != (Object)null && m_nview.IsValid())
			{
				((MonoBehaviour)this).InvokeRepeating("UpdateStatus", 0f, 1f);
				m_nview.Register<string, string>("RPC_SetTag", (Action<long, string, string>)RPC_SetTag);
				m_nview.Register<long, string>("ToggleActivated", (Action<long, long, string>)RPC_ToggleActivated);
				m_nview.Register<int>("RPC_AddCharge", (Action<long, int>)RPC_AddCharge);
			}
		}
	}

	public void RPC_ToggleActivated(long uid, long playerID, string name)
	{
		if (m_nview.IsOwner())
		{
			if (IsActivated(playerID))
			{
				RemoveActivated(playerID);
			}
			else
			{
				AddActivated(playerID, name);
			}
			UpdateStatus();
		}
	}

	public void RemoveActivated(long playerID)
	{
		//IL_0043: 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)
		List<KeyValuePair<long, string>> activatedPlayers = GetActivatedPlayers();
		if (activatedPlayers.RemoveAll((KeyValuePair<long, string> x) => x.Key == playerID) > 0)
		{
			SetActivatedPlayers(activatedPlayers);
			m_deactivateEffect.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1);
		}
	}

	public bool IsActivated(long playerID)
	{
		return IsWaystoneActivated(m_nview.GetZDO(), playerID);
	}

	public void AddActivated(long playerID, string playerName)
	{
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		List<KeyValuePair<long, string>> activatedPlayers = GetActivatedPlayers();
		foreach (KeyValuePair<long, string> item in activatedPlayers)
		{
			if (item.Key == playerID)
			{
				return;
			}
		}
		activatedPlayers.Add(new KeyValuePair<long, string>(playerID, playerName));
		SetActivatedPlayers(activatedPlayers);
		m_activateEffect.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1);
	}

	public void SetActivatedPlayers(List<KeyValuePair<long, string>> users)
	{
		m_nview.GetZDO().Set(ZDOVars.s_permitted, users.Count, false);
		for (int i = 0; i < users.Count; i++)
		{
			KeyValuePair<long, string> keyValuePair = users[i];
			m_nview.GetZDO().Set("pu_id" + i, keyValuePair.Key);
			m_nview.GetZDO().Set("pu_name" + i, keyValuePair.Value);
		}
	}

	public List<KeyValuePair<long, string>> GetActivatedPlayers()
	{
		return GetWaystoneActivatedPlayers(m_nview.GetZDO());
	}

	public bool IsEnabled()
	{
		if ((Object)(object)Player.m_localPlayer == (Object)null)
		{
			return false;
		}
		return IsActivated(Player.m_localPlayer.GetPlayerID());
	}

	public void UpdateStatus()
	{
		bool active = IsEnabled();
		m_activeObject.SetActive(active);
	}

	public string GetHoverText()
	{
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		if (!m_nview.IsValid())
		{
			return "";
		}
		if ((Object)(object)Player.m_localPlayer == (Object)null)
		{
			return "";
		}
		if (((Character)Player.m_localPlayer).InInterior())
		{
			return GetHoverName();
		}
		if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, false, false))
		{
			return Localization.instance.Localize(GetHoverName() + "\n$piece_noaccess");
		}
		sb.Clear();
		sb.Append(GetHoverName());
		string text = StringExtensionMethods.RemoveRichTextTags(GetText());
		if (text.Length > 0)
		{
			sb.AppendFormat(" \"{0}\"", text);
		}
		sb.Append("\n[<color=yellow><b>$KEY_Use</b></color>] $ws_tooltip_start_search $ws_piece_waystone_settag");
		string text2 = ((!ZInput.IsNonClassicFunctionality() || !ZInput.IsGamepadActive()) ? "$KEY_AltPlace" : "$KEY_JoyAltKeys");
		sb.Append("\n[<color=yellow><b>" + text2 + " + $KEY_Use</b></color>] " + (IsActive() ? "$ws_piece_waystone_deactivate" : "$ws_piece_waystone_activate"));
		if (global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Cooldown)
		{
			if (WorldData.IsOnCooldown())
			{
				sb.Append("\n$hud_powernotready: <color=#add8e6>" + WorldData.GetCooldownString() + "</color>");
			}
		}
		else if (global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Charge)
		{
			if (WaystoneList.IsPlayerChargeStorage())
			{
				sb.Append($"\n$ws_tooltip_player_charge <color=#add8e6>{WorldData.GetPlayerCharge()}</color>");
			}
			else
			{
				sb.Append($"\n$ws_tooltip_waystone_charge <color=#add8e6>{WaystoneList.GetWaystoneCharge(m_nview.GetZDO())}</color>");
			}
		}
		AppendSacrificeItemsHoverText(Player.m_localPlayer);
		return Localization.instance.Localize(sb.ToString());
	}

	public string GetHoverName()
	{
		return IsActive() ? "$ws_piece_waystone_activated" : "$ws_piece_waystone_name";
	}

	public bool Interact(Humanoid human, bool hold, bool alt)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Player.m_localPlayer == (Object)null || ((Character)Player.m_localPlayer).InInterior() || !PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false))
		{
			return true;
		}
		if (hold)
		{
			if (ZInput.GetButtonPressedTimer("Use") + ZInput.GetButtonPressedTimer("JoyUse") > 0.35f && !TextInput.IsVisible())
			{
				blockInputUntil = Time.time + 1f;
				ZInput.ResetButtonStatus("Use");
				ZInput.ResetButtonStatus("JoyUse");
				TextInput.instance.RequestText((TextReceiver)(object)this, "$ws_piece_waystone_tag", Math.Max(global::Waystones.Waystones.tagCharactersLimit.Value, 10));
			}
			return false;
		}
		Player val = (Player)(object)((human is Player) ? human : null);
		if (alt)
		{
			m_nview.InvokeRPC("ToggleActivated", new object[2]
			{
				val.GetPlayerID(),
				val.GetPlayerName()
			});
			return true;
		}
		((MonoBehaviour)this).StartCoroutine(ActivationToggleRequested(val));
		return true;
	}

	[IteratorStateMachine(typeof(<ActivationToggleRequested>d__24))]
	public IEnumerator ActivationToggleRequested(Player player)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <ActivationToggleRequested>d__24(0)
		{
			<>4__this = this,
			player = player
		};
	}

	public bool UseItem(Humanoid user, ItemData item)
	{
		if (global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Cooldown && global::Waystones.Waystones.itemSacrifitionReduceCooldown.Value)
		{
			int cooldown = 0;
			if (TryReduceCooldownOnItemSacrifice(user, item, item.m_shared.m_name, ref cooldown))
			{
				((Character)user).Message((MessageType)2, Localization.instance.Localize("$ws_piece_waystone_cooldown_reduced", new string[1] { cooldown.ToString() }), 0, (Sprite)null);
				if (WorldData.IsOnCooldown())
				{
					((Character)user).Message((MessageType)1, "$hud_powernotready: " + WorldData.GetCooldownString(), 0, (Sprite)null);
				}
				return true;
			}
		}
		if (global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Charge)
		{
			int charge = 0;
			if (TryChargeWaystoneOnItemSacrifice(user, item, item.m_shared.m_name, ref charge))
			{
				((Character)user).Message((MessageType)2, Localization.instance.Localize("$ws_piece_waystone_charge_added", new string[1] { charge.ToString() }), 0, (Sprite)null);
				return true;
			}
		}
		return false;
	}

	private bool TryReduceCooldownOnItemSacrifice(Humanoid user, ItemData item, string itemName, ref int cooldown)
	{
		if (itemName == null)
		{
			return false;
		}
		itemName = itemName.GetItemName();
		if (global::Waystones.Waystones.itemsToReduceCooldown.Value.TryGetValue(itemName, out var value) && (cooldown = value) > 0)
		{
			return user.GetInventory().RemoveOneItem(item) && WorldData.TryReduceCooldown(value);
		}
		string text = global::Waystones.Waystones.itemsToReduceCooldown.Value.Keys.FirstOrDefault((string key) => key.StartsWith(itemName));
		if (text != null && global::Waystones.Waystones.itemsToReduceCooldown.Value.TryGetValue(text, out var value2) && (cooldown = value2) > 0)
		{
			string[] array = text.Split(':');
			int result;
			return array.Length > 1 && array[0] == itemName && int.TryParse(array[1], out result) && CountItems(user.GetInventory(), itemName) >= result && user.GetInventory().RemoveItem(item, result) && WorldData.TryReduceCooldown(value2);
		}
		return false;
	}

	private bool TryChargeWaystoneOnItemSacrifice(Humanoid user, ItemData item, string itemName, ref int charge)
	{
		if (itemName == null || !m_nview.IsValid())
		{
			return false;
		}
		itemName = itemName.GetItemName();
		if (global::Waystones.Waystones.itemsToReduceCooldown.Value.TryGetValue(itemName, out var value) && value > 0)
		{
			return TryConsumeChargeItem(user, item, itemName, value, 1, ref charge);
		}
		string text = global::Waystones.Waystones.itemsToReduceCooldown.Value.Keys.FirstOrDefault((string key) => key == itemName || key.StartsWith(itemName + ":"));
		if (text != null && global::Waystones.Waystones.itemsToReduceCooldown.Value.TryGetValue(text, out var value2) && value2 > 0)
		{
			string[] array = text.Split(':');
			if (array.Length > 1 && array[0] == itemName && int.TryParse(array[1], out var result))
			{
				return TryConsumeChargeItem(user, item, itemName, value2, result, ref charge);
			}
		}
		return false;
	}

	private bool TryConsumeChargeItem(Humanoid user, ItemData item, string itemName, int addCharge, int amount, ref int charge)
	{
		if (amount <= 0 || CountItems(user.GetInventory(), itemName) < amount)
		{
			return false;
		}
		charge = WaystoneList.GetPotentialChargeAdded(m_nview.GetZDO(), addCharge);
		if (charge <= 0)
		{
			return false;
		}
		if (!((amount == 1) ? user.GetInventory().RemoveOneItem(item) : user.GetInventory().RemoveItem(item, amount)))
		{
			return false;
		}
		AddCharge(addCharge);
		return true;
	}

	private void AddCharge(int amount)
	{
		if (m_nview.IsValid() && amount > 0)
		{
			if (WaystoneList.IsPlayerChargeStorage())
			{
				WaystoneList.AddCharge(m_nview.GetZDO(), amount);
				return;
			}
			if (m_nview.IsOwner())
			{
				WaystoneList.AddWaystoneCharge(m_nview.GetZDO(), amount);
				return;
			}
			m_nview.InvokeRPC("RPC_AddCharge", new object[1] { amount });
		}
	}

	public void RPC_AddCharge(long sender, int amount)
	{
		if (m_nview.IsValid() && m_nview.IsOwner())
		{
			WaystoneList.AddWaystoneCharge(m_nview.GetZDO(), amount);
		}
	}

	private int CountItems(Inventory inventory, string itemName)
	{
		return CountOwnInventoryItems(inventory, itemName);
	}

	private static int CountOwnInventoryItems(Inventory inventory, string itemName)
	{
		if (inventory == null)
		{
			return 0;
		}
		int num = 0;
		foreach (ItemData item in inventory.m_inventory)
		{
			if (item.m_shared.m_name.GetItemName() == itemName && item.m_worldLevel >= Game.m_worldLevel)
			{
				num += item.m_stack;
			}
		}
		return num;
	}

	private static int CountAvailableItems(Inventory inventory, string itemName)
	{
		if (inventory == null)
		{
			return 0;
		}
		return inventory.CountItems(itemName, -1, true);
	}

	private static void AppendSacrificeItemsHoverText(Player player)
	{
		if (!global::Waystones.Waystones.showSacrificeItemsInHover.Value || !ShouldShowSacrificeItems())
		{
			return;
		}
		RefreshSacrificeHoverItems(player);
		if (sacrificeHoverItems.Count == 0)
		{
			return;
		}
		sb.Append("\n\n");
		sb.Append((global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Charge) ? "$ws_tooltip_sacrifice_add_charge" : "$ws_tooltip_sacrifice_reduce_cooldown");
		string text = ((global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Charge) ? "$ws_tooltip_charges" : "$ws_tooltip_seconds");
		foreach (SacrificeHoverItem sacrificeHoverItem in sacrificeHoverItems)
		{
			sb.Append("\n - ");
			sb.Append("<color=#add8e6>" + sacrificeHoverItem.itemName + "</color>");
			if (sacrificeHoverItem.amount > 1)
			{
				sb.Append($" x{sacrificeHoverItem.amount}");
			}
			sb.Append(string.Format(" - {0}: <color=orange>{1}{2}</color>. $settings_inventory: <color=yellow>{3}</color>", text, (global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Charge) ? "+" : "-", sacrificeHoverItem.value, sacrificeHoverItem.inventoryCount));
			if (sacrificeHoverItem.totalCount != sacrificeHoverItem.inventoryCount)
			{
				sb.Append($", $item_total: <color=yellow>{sacrificeHoverItem.totalCount}</color>");
			}
		}
	}

	private static bool ShouldShowSacrificeItems()
	{
		return global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Charge || (global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Cooldown && global::Waystones.Waystones.itemSacrifitionReduceCooldown.Value);
	}

	private static void RefreshSacrificeHoverItems(Player player)
	{
		if (Time.time < nextSacrificeHoverItemsUpdate)
		{
			return;
		}
		nextSacrificeHoverItemsUpdate = Time.time + 1f;
		sacrificeHoverItems.Clear();
		if ((Object)(object)player == (Object)null)
		{
			return;
		}
		Inventory inventory = ((Humanoid)player).GetInventory();
		if (inventory == null)
		{
			return;
		}
		foreach (KeyValuePair<string, int> item in global::Waystones.Waystones.itemsToReduceCooldown.Value)
		{
			if (item.Value > 0 && TryParseSacrificeEntry(item.Key, out var itemName, out var amount))
			{
				int num = CountOwnInventoryItems(inventory, itemName);
				int num2 = CountAvailableItems(inventory, itemName);
				if (num > 0 || num2 > 0)
				{
					sacrificeHoverItems.Add(new SacrificeHoverItem
					{
						itemName = itemName,
						amount = amount,
						value = item.Value,
						inventoryCount = num,
						totalCount = num2
					});
				}
			}
		}
	}

	private static bool TryParseSacrificeEntry(string key, out string itemName, out int amount)
	{
		itemName = key;
		amount = 1;
		if (string.IsNullOrWhiteSpace(key))
		{
			return false;
		}
		string[] array = key.Split(':');
		if (array.Length == 1)
		{
			return true;
		}
		if (array.Length != 2 || string.IsNullOrWhiteSpace(array[0]) || !int.TryParse(array[1], out amount) || amount <= 0)
		{
			return false;
		}
		itemName = array[0];
		return true;
	}

	private static string BuildConfiguredSacrificeItemsText()
	{
		if (!ShouldShowSacrificeItems())
		{
			return "";
		}
		if (global::Waystones.Waystones.itemsToReduceCooldown.Value.Count == 0)
		{
			return "";
		}
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.Append((global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Charge) ? "$ws_tooltip_sacrifice_add_charge" : "$ws_tooltip_sacrifice_reduce_cooldown");
		string arg = ((global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Charge) ? "$ws_tooltip_charges" : "$ws_tooltip_seconds");
		foreach (KeyValuePair<string, int> item in global::Waystones.Waystones.itemsToReduceCooldown.Value)
		{
			if (item.Value > 0 && TryParseSacrificeEntry(item.Key, out var itemName, out var amount))
			{
				stringBuilder.Append("\n - ");
				stringBuilder.Append(itemName);
				if (amount > 1)
				{
					stringBuilder.Append($" x{amount}");
				}
				stringBuilder.Append(string.Format(" - {0}: <color=#add8e6>{1}{2}</color>", arg, (global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Charge) ? "+" : "-", item.Value));
			}
		}
		return stringBuilder.ToString();
	}

	public bool IsActive()
	{
		return m_activeObject.activeSelf;
	}

	public string GetText()
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		ZDO zDO = m_nview.GetZDO();
		if (zDO == null)
		{
			return "";
		}
		string @string = zDO.GetString(ZDOVars.s_tagauthor, "");
		PlatformUserID val = (PlatformUserID)(string.IsNullOrEmpty(@string) ? PlatformUserID.None : new PlatformUserID(@string));
		return CensorShittyWords.FilterUGC(zDO.GetString(ZDOVars.s_tag, ""), (UGCType)4, val, 0L);
	}

	public void GetTagSignature(out string tagRaw, out string authorId)
	{
		ZDO zDO = m_nview.GetZDO();
		tagRaw = zDO.GetString(ZDOVars.s_tag, "");
		authorId = zDO.GetString(ZDOVars.s_tagauthor, "");
	}

	public void SetText(string text)
	{
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		if (m_nview.IsValid())
		{
			ZNetView nview = m_nview;
			object[] obj = new object[2] { text, null };
			PlatformUserID platformUserID = ((IUser)PlatformManager.DistributionPlatform.LocalUser).PlatformUserID;
			obj[1] = ((object)(PlatformUserID)(ref platformUserID)).ToString();
			nview.InvokeRPC("RPC_SetTag", obj);
		}
	}

	public void RPC_SetTag(long sender, string tag, string authorId)
	{
		if (m_nview.IsValid() && m_nview.IsOwner())
		{
			GetTagSignature(out var tagRaw, out var authorId2);
			if (!(tagRaw == tag) || !(authorId2 == authorId))
			{
				ZDO zDO = m_nview.GetZDO();
				zDO.Set(ZDOVars.s_tag, tag);
				zDO.Set(ZDOVars.s_tagauthor, authorId);
			}
		}
	}

	public static List<KeyValuePair<long, string>> GetWaystoneActivatedPlayers(ZDO zdo)
	{
		List<KeyValuePair<long, string>> list = new List<KeyValuePair<long, string>>();
		int @int = zdo.GetInt(ZDOVars.s_permitted, 0);
		for (int i = 0; i < @int; i++)
		{
			long @long = zdo.GetLong("pu_id" + i, 0L);
			string @string = zdo.GetString("pu_name" + i, "");
			if (@long != 0)
			{
				list.Add(new KeyValuePair<long, string>(@long, @string));
			}
		}
		return list;
	}

	public static bool IsWaystoneActivated(ZDO zdo, long playerID)
	{
		if (zdo == null)
		{
			return false;
		}
		foreach (KeyValuePair<long, string> waystoneActivatedPlayer in GetWaystoneActivatedPlayers(zdo))
		{
			if (global::Waystones.Waystones.allowForEveryone.Value || waystoneActivatedPlayer.Key == playerID)
			{
				return true;
			}
		}
		return false;
	}

	internal static bool IsSearchAllowed(Player player, bool validateCharge = true)
	{
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)player == (Object)null)
		{
			return false;
		}
		if ((Object)(object)player != (Object)(object)Player.m_localPlayer)
		{
			return false;
		}
		if (global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Cooldown && WorldData.IsOnCooldown())
		{
			((Character)player).Message((MessageType)2, "$hud_powernotready: " + WorldData.GetCooldownString(), 0, (Sprite)null);
			return false;
		}
		if (validateCharge && global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Charge && !WaystoneList.CanStartSearchWithCharge(WaystoneList.GetCurrentTravelCharge(player.GetPlayerID(), ((Component)player).transform.position)))
		{
			((Character)player).Message((MessageType)2, "$ws_message_not_enough_charge", 0, (Sprite)null);
			return false;
		}
		if (IsNotInPosition(player))
		{
			((Character)player).Message((MessageType)2, "$msg_cart_incorrectposition", 0, (Sprite)null);
			return false;
		}
		if (!global::Waystones.Waystones.allowEncumbered.Value && ((Character)player).IsEncumbered())
		{
			((Character)player).Message((MessageType)2, "$se_encumbered_start", 0, (Sprite)null);
			return false;
		}
		if (!global::Waystones.Waystones.allowNonTeleportableItems.Value && !((Humanoid)player).IsTeleportable())
		{
			((Character)player).Message((MessageType)2, "$msg_noteleport", 0, (Sprite)null);
			return false;
		}
		if (!global::Waystones.Waystones.allowWet.Value && ((Character)player).GetSEMan().HaveStatusEffect(SEMan.s_statusEffectWet))
		{
			((Character)player).Message((MessageType)2, "$msg_bedwet", 0, (Sprite)null);
			return false;
		}
		if (!global::Waystones.Waystones.allowSensed.Value && player.IsSensed())
		{
			((Character)player).Message((MessageType)2, "$msg_bedenemiesnearby", 0, (Sprite)null);
			return false;
		}
		if (!global::Waystones.Waystones.allowNonSitting.Value && !((Character)player).IsSitting())
		{
			((Character)player).Message((MessageType)2, "$ws_piece_waystone_sit", 0, (Sprite)null);
			return false;
		}
		return true;
	}

	internal static bool IsNotInPosition(Player player)
	{
		return ((Character)player).IsAttachedToShip() || ((Character)player).IsAttached() || ((Character)player).IsDead() || ((Character)player).IsRiding() || player.IsSleeping() || ((Character)player).IsTeleporting() || ((Character)player).InPlaceMode() || ((Character)player).InBed() || ((Character)player).InCutscene() || ((Character)player).InInterior();
	}
}
internal class CustomPrefabs
{
	[HarmonyPatch(typeof(ZNetView), "Awake")]
	public static class ZNetView_Awake_AddPrefab
	{
		[HarmonyPriority(800)]
		private static bool Prefix()
		{
			return !prefabInit;
		}
	}

	[HarmonyPatch(typeof(ZSyncTransform), "Awake")]
	public static class ZSyncTransform_Awake_AddPrefab
	{
		[HarmonyPriority(800)]
		private static bool Prefix()
		{
			return !prefabInit;
		}
	}

	[HarmonyPatch(typeof(ZSyncTransform), "OnEnable")]
	public static class ZSyncTransform_OnEnable_AddPrefab
	{
		[HarmonyPriority(800)]
		private static bool Prefix()
		{
			return !prefabInit;
		}
	}

	[HarmonyPatch(typeof(ItemDrop), "Awake")]
	public static class ItemDrop_Awake_AddPrefab
	{
		[HarmonyPriority(800)]
		private static bool Prefix()
		{
			return !prefabInit;
		}
	}

	[HarmonyPatch(typeof(ItemDrop), "Start")]
	public static class ItemDrop_Start_AddPrefab
	{
		[HarmonyPriority(800)]
		private static bool Prefix()
		{
			return !prefabInit;
		}
	}

	[HarmonyPatch(typeof(Piece), "Awake")]
	public static class Piece_Awake_AddPrefab
	{
		[HarmonyPriority(800)]
		private static bool Prefix()
		{
			return !prefabInit;
		}
	}

	[HarmonyPatch(typeof(WearNTear), "Awake")]
	public static class WearNTear_Awake_AddPrefab
	{
		[HarmonyPriority(800)]
		private static bool Prefix()
		{
			return !prefabInit;
		}
	}

	[HarmonyPatch(typeof(WearNTear), "Start")]
	public static class WearNTear_Start_AddPrefab
	{
		[HarmonyPriority(800)]
		private static bool Prefix()
		{
			return !prefabInit;
		}
	}

	[HarmonyPatch(typeof(GuidePoint), "Start")]
	public static class GuidePoint_Start_AddPrefab
	{
		[HarmonyPriority(800)]
		private static bool Prefix()
		{
			return !prefabInit;
		}
	}

	private const string c_rootObjectName = "_shudnalRoot";

	private const string c_rootPrefabsName = "Prefabs";

	private static GameObject rootObject;

	private static GameObject rootPrefabs;

	public static bool prefabInit;

	private static void InitRootObject()
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Expected O, but got Unknown
		if ((Object)(object)rootObject == (Object)null)
		{
			rootObject = (GameObject)(((object)GameObject.Find("_shudnalRoot")) ?? ((object)new GameObject("_shudnalRoot")));
		}
		Object.DontDestroyOnLoad((Object)(object)rootObject);
		if ((Object)(object)rootPrefabs == (Object)null)
		{
			Transform obj = rootObject.transform.Find("Prefabs");
			rootPrefabs = ((obj != null) ? ((Component)obj).gameObject : null);
			if ((Object)(object)rootPrefabs == (Object)null)
			{
				rootPrefabs = new GameObject("Prefabs");
				rootPrefabs.transform.SetParent(rootObject.transform, false);
				rootPrefabs.SetActive(false);
			}
		}
	}

	internal static GameObject InitPrefabClone(GameObject prefabToClone, string prefabName)
	{
		InitRootObject();
		if ((Object)(object)rootPrefabs.transform.Find(prefabName) != (Object)null)
		{
			return ((Component)rootPrefabs.transform.Find(prefabName)).gameObject;
		}
		prefabInit = true;
		GameObject val = Object.Instantiate<GameObject>(prefabToClone, rootPrefabs.transform, false);
		prefabInit = false;
		((Object)val).name = prefabName;
		return val;
	}

	internal static Component AddComponent(GameObject gameObject, Type type)
	{
		prefabInit = true;
		Component result = gameObject.AddComponent(type);
		prefabInit = false;
		return result;
	}
}
namespace LocalizationManager
{
	[PublicAPI]
	public class Localizer
	{
		[CompilerGenerated]
		private sealed class <Load>d__12 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitUntil((Func<bool>)(() => PlatformManager.DistributionPlatform != null && PlatformInitializer.PreferencesInitialized));
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (string.IsNullOrEmpty(PlatformPrefs.GetString("language", "")))
					{
						PlatformPrefs.SetString("language", "English");
					}
					LoadLocalization(Localization.instance, Localization.instance.GetSelectedLanguage());
					return false;
				}
			}

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

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

		private const string defaultLanguage = "English";

		private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors;

		private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts;

		private static readonly ConditionalWeakTable<Localization, string> localizationLanguage;

		private static readonly List<WeakReference<Localization>> localizationObjects;

		private static BaseUnityPlugin? _plugin;

		private static readonly List<string> fileExtensions;

		private static BaseUnityPlugin Plugin
		{
			get
			{
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: Expected O, but got Unknown
				if (_plugin == null)
				{
					IEnumerable<TypeInfo> source;
					try
					{
						source = Assembly.GetExecutingAssembly().DefinedTypes.ToList();
					}
					catch (ReflectionTypeLoadException ex)
					{
						source = from t in ex.Types
							where t != null
							select t.GetTypeInfo();
					}
					_plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
				}
				return _plugin;
			}
		}

		private static void UpdatePlaceholderText(Localization localization, string key)
		{
			localizationLanguage.TryGetValue(localization, out string value);
			string text = loadedTexts[value][key];
			if (PlaceholderProcessors.TryGetValue(key, out Dictionary<string, Func<string>> value2))
			{
				text = value2.Aggregate(text, (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value()));
			}
			localization.AddWord(key, text);
		}

		public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, Func<T, string>? convertConfigValue = null) where T : notnull
		{
			string key2 = key;
			string placeholder2 = placeholder;
			Func<T, string> convertConfigValue2 = convertConfigValue;
			ConfigEntry<T> config2 = config;
			if (convertConfigValue2 == null)
			{
				convertConfigValue2 = (T val) => val.ToString();
			}
			if (!PlaceholderProcessors.ContainsKey(key2))
			{
				PlaceholderProcessors[key2] = new Dictionary<string, Func<string>>();
			}
			config2.SettingChanged += delegate
			{
				UpdatePlaceholder();
			};
			if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage()))
			{
				UpdatePlaceholder();
			}
			void UpdatePlaceholder()
			{
				PlaceholderProcessors[key2][placeholder2] = () => convertConfigValue2(config2.Value);
				UpdatePlaceholderText(Localization.instance, key2);
			}
		}

		public static void AddText(string key, string text)
		{
			List<WeakReference<Localization>> list = new List<WeakReference<Localization>>();
			foreach (WeakReference<Localization> localizationObject in localizationObjects)
			{
				if (localizationObject.TryGetTarget(out var target))
				{
					Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)];
					if (!target.m_translations.ContainsKey(key))
					{
						dictionary[key] = text;
						target.AddWord(key, text);
					}
				}
				else
				{
					list.Add(localizationObject);
				}
			}
			foreach (WeakReference<Localization> item in list)
			{
				localizationObjects.Remove(item);
			}
		}

		[IteratorStateMachine(typeof(<Load>d__12))]
		public static IEnumerator Load()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Load>d__12(0);
		}

		private static void LoadLocalization(Localization __instance, string language)
		{
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Expected O, but got Unknown
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Expected O, but got Unknown
			if (!localizationLanguage.Remove(__instance))
			{
				localizationObjects.Add(new WeakReference<Localization>(__instance));
			}
			localizationLanguage.Add(__instance, language);
			Dictionary<string, string> localizationFiles = new Dictionary<string, string>();
			string[] prefixes = new string[2]
			{
				Plugin.Info.Metadata.Name + ".",
				Plugin.Info.Metadata.Name.Replace(" ", "") + "."
			};
			Scan(Paths.ConfigPath, warn: true);
			Scan(Paths.PluginPath, warn: false);
			byte[] array = LoadTranslationFromAssembly("English");
			if (array == null)
			{
				throw new Exception("Found no English localizations in mod " + Plugin.Info.Metadata.Name + ". Expected an embedded resource Translations/English.json or Translations/English.yml.");
			}
			Dictionary<string, string> dictionary = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).IgnoreFields().Build().Deserialize<Dictionary<string, string>>(Encoding.UTF8.GetString(array));
			if (dictionary == null)
			{
				throw new Exception("Localization for mod " + Plugin.Info.Metadata.Name + " failed: Localization file was empty.");
			}
			string text = null;
			if (language != "English")
			{
				if (localizationFiles.ContainsKey(language))
				{
					text = File.ReadAllText(localizationFiles[language]);
				}
				else
				{
					byte[] array2 = LoadTranslationFromAssembly(language);
					if (array2 != null)
					{
						text = Encoding.UTF8.GetString(array2);
					}
				}
			}
			if (text == null && localizationFiles.ContainsKey("English"))
			{
				text = File.ReadAllText(localizationFiles["English"]);
			}
			if (text != null)
			{
				Dictionary<string, string> dictionary2;
				try
				{
					dictionary2 = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text) ?? new Dictionary<string, string>();
				}
				catch (Exception arg)
				{
					global::Waystones.Waystones.LogInfo($"Failed to deserialize localization for language '{language}'. Using base localization only.\n{arg}");
					dictionary2 = new Dictionary<string, string>();
				}
				foreach (KeyValuePair<string, string> item in dictionary2)
				{
					dictionary[item.Key] = item.Value;
				}
			}
			loadedTexts[language] = dictionary;
			foreach (KeyValuePair<string, string> item2 in dictionary)
			{
				UpdatePlaceholderText(__instance, item2.Key);
			}
			void Scan(string root, bool warn)
			{
				foreach (string item3 in from f in Directory.GetFiles(root, "*.*", SearchOption.AllDirectories)
					where fileExtensions.Contains(Path.GetExtension(f))
					select f)
				{
					string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(item3);
					string[] array3 = prefixes;
					foreach (string text2 in array3)
					{
						if (fileNameWithoutExtension.StartsWith(text2))
						{
							string text3 = fileNameWithoutExtension.Substring(text2.Length);
							if (!string.IsNullOrWhiteSpace(text3))
							{
								if (localizationFiles.ContainsKey(text3))
								{
									if (warn)
									{
										global::Waystones.Waystones.LogInfo("Duplicate localization '" + text3 + "' for " + Plugin.Info.Metadata.Name + ". Skipping " + item3);
									}
								}
								else
								{
									localizationFiles[text3] = item3;
								}
							}
							break;
						}
					}
				}
			}
		}

		static Localizer()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>();
			loadedTexts = new Dictionary<string, Dictionary<string, string>>();
			localizationLanguage = new ConditionalWeakTable<Localization, string>();
			localizationObjects = new List<WeakReference<Localization>>();
			fileExtensions = new List<string> { ".json", ".yml" };
			Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager");
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static byte[]? LoadTranslationFromAssembly(string language)
		{
			foreach (string fileExtension in fileExtensions)
			{
				byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension);
				if (array != null)
				{
					return array;
				}
			}
			return null;
		}

		public static byte[]? ReadEmbeddedFileBytes(string resourceFileName, Assembly? containingAssembly = null)
		{
			string resourceFileName2 = resourceFileName;
			using MemoryStream memoryStream = new MemoryStream();
			if ((object)containingAssembly == null)
			{
				containingAssembly = Assembly.GetCallingAssembly();
			}
			string text = containingAssembly.GetManifestResourceNames().FirstOrDefault((string str) => str.EndsWith(resourceFileName2, StringComparison.Ordinal));
			if (text != null)
			{
				containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream);
			}
			return (memoryStream.Length == 0L) ? null : memoryStream.ToArray();
		}
	}
}
namespace Waystones
{
	internal static class CustomSyncedValuesSynchronizer
	{
		[CompilerGenerated]
		private sealed class <AssignAfterServerUpdate>d__6<T> : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public CustomSyncedValue<T> syncedValue;

			public Func<T> function;

			public bool assignIfChanged;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = AssignAfterServerUpdate(syncedValue, function(), assignIfChanged);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					return false;
				}
			}

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

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

		[CompilerGenerated]
		private sealed class <AssignAfterServerUpdate>d__7<T> : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public CustomSyncedValue<T> syncedValue;

			public T value;

			public bool assignIfChanged;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (assignIfChanged && syncedValue.Value.Equals(value))
					{
						return false;
					}
					<>2__current = waitForServerUpdate;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					syncedValue.AssignLocalValue(value);
					return false;
				}
			}

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

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

		[CompilerGenerated]
		private sealed class <CoroutineCoordinator>d__9 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

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

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

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

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

			private bool MoveNext()
			{
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					coroutines.Dequeue();
					goto IL_005c;
				}
				<>1__state = -1;
				goto IL_0081;
				IL_005c:
				if (coroutines.Count > 0)
				{
					<>2__current = ((MonoBehaviour)Waystones.instance).StartCoroutine(coroutines.Peek());
					<>1__state = 1;
					return true;
				}
				if (coroutines.Count == 0)
				{
					return false;
				}
				goto IL_0081;
				IL_0081:
				bool flag = true;
				goto IL_005c;
			}

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

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

		private static readonly Queue<IEnumerator> coroutines = new Queue<IEnumerator>();

		private static readonly WaitWhile waitForServerUpdate = new WaitWhile((Func<bool>)(() => ConfigSync.ProcessingServerUpdate));

		public static void AssignValueSafe<T>(this CustomSyncedValue<T> syncedValue, T value)
		{
			AddToQueue(AssignAfterServerUpdate(syncedValue, value, assignIfChanged: false));
		}

		public static void AssignValueSafe<T>(this CustomSyncedValue<T> syncedValue, Func<T> function)
		{
			AddToQueue(AssignAfterServerUpdate(syncedValue, function, assignIfChanged: false));
		}

		public static void AssignValueIfChanged<T>(this CustomSyncedValue<T> syncedValue, T value)
		{
			AddToQueue(AssignAfterServerUpdate(syncedValue, value, assignIfChanged: true));
		}

		public static void AssignValueIfChanged<T>(this CustomSyncedValue<T> syncedValue, Func<T> function)
		{
			AddToQueue(AssignAfterServerUpdate(syncedValue, function, assignIfChanged: true));
		}

		[IteratorStateMachine(typeof(<AssignAfterServerUpdate>d__6<>))]
		private static IEnumerator AssignAfterServerUpdate<T>(CustomSyncedValue<T> syncedValue, Func<T> function, bool assignIfChanged)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <AssignAfterServerUpdate>d__6<T>(0)
			{
				syncedValue = syncedValue,
				function = function,
				assignIfChanged = assignIfChanged
			};
		}

		[IteratorStateMachine(typeof(<AssignAfterServerUpdate>d__7<>))]
		private static IEnumerator AssignAfterServerUpdate<T>(CustomSyncedValue<T> syncedValue, T value, bool assignIfChanged)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <AssignAfterServerUpdate>d__7<T>(0)
			{
				syncedValue = syncedValue,
				value = value,
				assignIfChanged = assignIfChanged
			};
		}

		private static void AddToQueue(IEnumerator coroutine)
		{
			coroutines.Enqueue(coroutine);
			if (coroutines.Count == 1)
			{
				((MonoBehaviour)Waystones.instance).StartCoroutine(CoroutineCoordinator());
			}
		}

		[IteratorStateMachine(typeof(<CoroutineCoordinator>d__9))]
		private static IEnumerator CoroutineCoordinator()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <CoroutineCoordinator>d__9(0);
		}
	}
	public static class DirectionSearch
	{
		public class Direction
		{
			public string name;

			public Vector3 position;

			public Quaternion rotation;

			public double cooldown;

			public int travelCost;

			public int arrivalCharge;

			private const int NoArrivalCharge = int.MinValue;

			private readonly WaystoneList.WaystoneData waystone;

			public static readonly StringBuilder _sb = new StringBuilder(5);

			public Direction(string name, Vector3 position)
				: this(name, position, Quaternion.identity, null)
			{
			}//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)


			public Direction(string name, Vector3 position, Quaternion rotation)
				: this(name, position, rotation, null)
			{
			}//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)


			internal Direction(string name, WaystoneList.WaystoneData waystone)
				: this(name, waystone.searchPosition, waystone.searchRotation, waystone)
			{
			}//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)


			private Direction(string name, Vector3 position, Quaternion rotation, WaystoneList.WaystoneData waystone)
			{
				//IL_0010: 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_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: 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_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				this.name = name;
				this.position = position;
				this.rotation = rotation;
				this.waystone = waystone;
				cooldown = WorldData.GetCooldownTimeToTarget(position);
				travelCost = WorldData.GetTravelChargeCost(Object.op_Implicit((Object)(object)Player.m_localPlayer) ? ((Component)Player.m_localPlayer).transform.position : Vector3.zero, position);
				arrivalCharge = waystone?.charge ?? int.MinValue;
			}

			public string GetHoverText()
			{
				//IL_018c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0192: Unknown result type (might be due to invalid IL or missing references)
				_sb.Clear();
				_sb.Append(name);
				if (Waystones.waystoneMode.Value == Waystones.WaystoneMode.Cooldown)
				{
					_sb.Append("\n[<color=yellow><b>$KEY_Use</b></color>] $ws_tooltip_moving_to");
					_sb.Append("\n\n$ws_tooltip_cooldown_after <color=#add8e6>" + WorldData.TimerString(cooldown) + "</color>");
				}
				else if (Waystones.waystoneMode.Value == Waystones.WaystoneMode.Charge)
				{
					_sb.Append("\n[<color=yellow><b>$KEY_Use</b></color>] $ws_tooltip_moving_to");
					_sb.Append($"\n\n$ws_tooltip_travel_cost <color=#add8e6>{travelCost}</color>");
					if (WaystoneList.IsPlayerChargeStorage())
					{
						int playerCharge = WorldData.GetPlayerCharge();
						_sb.Append($"\n$ws_tooltip_player_charge <color=#add8e6>{playerCharge}</color>");
						_sb.Append($"\n$ws_tooltip_player_charge_after <color=#add8e6>{playerCharge - travelCost}</color>");
					}
					else if (arrivalCharge != int.MinValue)
					{
						_sb.Append($"\n$ws_tooltip_arrival_charge <color=#add8e6>{arrivalCharge}</color>");
						bool flag = WaystoneList.HasEnoughWaystoneCharge(arrivalCharge, travelCost, Waystones.allowWaystoneChargeOverdraft.Value);
						_sb.Append("\n$ws_tooltip_return_check <color=#add8e6>" + (flag ? "$menu_yes" : "$menu_no") + "</color>");
					}
				}
				else
				{
					float value = Utils.DistanceXZ(((Component)Player.m_localPlayer).transform.position, position);
					string text = FormatUnits(value, (Waystones.orientationDistanceUnit.Value == Waystones.DistanceUnit.Yards) ? " yd" : "m");
					_sb.Append("\n$ws_tooltip_distance <color=#add8e6>" + text + "</color>");
				}
				return Localization.instance.Localize(_sb.ToString());
			}

			private static string FormatUnits(float value, string unit)
			{
				if (value < 1000f)
				{
					return $"{Mathf.RoundToInt(value)}{unit}";
				}
				float num = value / 1000f;
				return (num >= 10f) ? $"{num:0}k{unit}" : $"{num:0.#}k{unit}";
			}
		}

		[HarmonyPatch(typeof(Hud), "UpdateCrosshair")]
		public static class Hud_UpdateCrosshair_HoverTextDirectionMode
		{
			private static void Postfix(Hud __instance)
			{
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				if (activated && current != null)
				{
					((TMP_Text)__instance.m_hoverName).SetText(current.GetHoverText());
					((Graphic)__instance.m_crosshair).color = (Color)((((TMP_Text)__instance.m_hoverName).text.Length > 0) ? Color.yellow : new Color(1f, 1f, 1f, 0.5f));
				}
			}
		}

		[HarmonyPatch(typeof(Hud), "Awake")]
		public static class Hud_Awake_BlackPanelInit
		{
			private static void Postfix(Hud __instance)
			{
				GameObject val = Object.Instantiate<GameObject>(((Component)__instance.m_loadingScreen).gameObject, ((Component)__instance.m_loadingScreen).transform.parent);
				((Object)val).name = "Waystones_DirectionSearchBlack";
				val.transform.SetSiblingIndex(0);
				val.transform.Find("Loading/TopFade").SetParent(val.transform);
				val.transform.Find("Loading/BottomFade").SetParent(val.transform);
				for (int num = val.transform.childCount - 1; num >= 0; num--)
				{
					Transform child = val.transform.GetChild(num);
					switch (((Object)child).name)
					{
					case "Loading":
					case "Sleeping":
					case "Teleporting":
					case "Image":
					case "Tip":
					case "panel_separator":
						Object.Destroy((Object)(object)((Component)child).gameObject);
						break;
					}
				}
				GameObject prefab = ZNetScene.instance.GetPrefab("guard_stone");
				if ((Object)(object)prefab != (Object)null)
				{
					GameObject val2 = Object.Instantiate<GameObject>(((Component)prefab.transform.Find("WayEffect/sfx")).gameObject, val.transform);
					((Object)val2).name = "sfx";
					val2.AddComponent<FollowPlayer>();
					val2.SetActive(true);
					screenBlackenerSfx = val2.GetComponent<AudioSource>();
				}
				screenBlackener = val.GetComponent<CanvasGroup>();
				((Component)screenBlackener).gameObject.SetActive(false);
				Waystones.LogInfo("Blackener panel initialized");
			}
		}

		[HarmonyPatch(typeof(Hud), "UpdateBlackScreen")]
		public static class Hud_UpdateBlackScreen_DirectionModeScreenEffect
		{
			private static void Postfix(float dt)
			{
				if (activated)
				{
					((Component)screenBlackener).gameObject.SetActive(true);
					screenBlackener.alpha = Mathf.MoveTowards(screenBlackener.alpha, Mathf.Lerp(Waystones.fadeMin.Value, Waystones.fadeMax.Value, currentAngle / Mathf.Max(GetCurrentScreenSensivityThreshold(), GetCurrentSensivity())), dt);
					screenBlackenerSfx.volume = Mathf.MoveTowards(screenBlackenerSfx.volume, Mathf.Lerp(Waystones.sfxMax.Value, Waystones.sfxMin.Value, currentAngle / Mathf.Max(GetCurrentSfxSensivityThreshold(), GetCurrentSensivity())), dt * 3f);
					screenBlackenerSfx.pitch = Mathf.MoveTowards(screenBlackenerSfx.pitch, Mathf.Lerp(Waystones.sfxPitchMax.Value, Waystones.sfxPitchMin.Value, currentAngle / Mathf.Max(GetCurrentSfxSensivityThreshold(), GetCurrentSensivity())), dt);
					return;
				}
				screenBlackener.alpha = Mathf.MoveTowards(screenBlackener.alpha, 0f, dt / 2f);
				screenBlackenerSfx.volume = Mathf.MoveTowards(screenBlackenerSfx.volume, 0f, dt);
				screenBlackenerSfx.pitch = Mathf.MoveTowards(screenBlackenerSfx.pitch, 1f, dt);
				if (screenBlackener.alpha <= 0f)
				{
					((Component)screenBlackener).gameObject.SetActive(false);
				}
			}
		}

		[HarmonyPatch]
		public static class JoyRightStick_SlowFactor
		{
			[CompilerGenerated]
			private sealed class <TargetMethods>d__0 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IDisposable, IEnumerator
			{
				private int <>1__state;

				private MethodBase <>2__current;

				private int <>l__initialThreadId;

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

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

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

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

				private bool MoveNext()
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>2__current = AccessTools.Method(typeof(ZInput), "GetJoyRightStickX", (Type[])null, (Type[])null);
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -1;
						<>2__current = AccessTools.Method(typeof(ZInput), "GetJoyRightStickY", (Type[])null, (Type[])null);
						<>1__state = 2;
						return true;
					case 2:
						<>1__state = -1;
						return false;
					}
				}

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

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

				[DebuggerHidden]
				IEnumerator<MethodBase> IEnumerable<MethodBase>.GetEnumerator()
				{
					if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
					{
						<>1__state = 0;
						return this;
					}
					return new <TargetMethods>d__0(0);
				}

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

			[IteratorStateMachine(typeof(<TargetMethods>d__0))]
			private static IEnumerable<MethodBase> TargetMethods()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <TargetMethods>d__0(-2);
			}

			private static void Postfix(ref float __result)
			{
				if (activated)
				{
					if (!Game.CanPause())
					{
						__result /= 2f;
					}
					else if (Game.m_timeScale != 0f)
					{
						__result *= Mathf.Clamp(1f / Game.m_timeScale, 1f, 2f);
					}
				}
			}
		}

		[HarmonyPatch(typeof(ZInput), "GetMouseDelta")]
		public static class ZInput_GetMouseDelta_SlowFactor
		{
			private static void Postfix(ref Vector2 __result)
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				if (activated)
				{
					__result *= Mathf.Clamp(((Vector2)(ref __result)).magnitude / Waystones.slowFactorLookDeceleration.Value, Waystones.slowFactorLookMinimum.Value, 1f);
				}
			}
		}

		[HarmonyPatch]
		public static class StopDirectionMode_Postfix
		{
			[CompilerGenerated]
			private sealed class <TargetMethods>d__0 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IDisposable, IEnumerator
			{
				private int <>1__state;

				private MethodBase <>2__current;

				private int <>l__initialThreadId;

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

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

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

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

				private bool MoveNext()
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>2__current = AccessTools.Method(typeof(Menu), "Show", (Type[])null, (Type[])null);
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -1;
						<>2__current = AccessTools.Method(typeof(Menu), "Hide", (Type[])null, (Type[])null);
						<>1__state = 2;
						return true;
					case 2:
						<>1__state = -1;
						<>2__current = AccessTools.Method(typeof(Game), "Unpause", (Type[])null, (Type[])null);
						<>1__state = 3;
						return true;
					case 3:
						<>1__state = -1;
						<>2__current = AccessTools.Method(typeof(Game), "Pause", (Type[])null, (Type[])null);
						<>1__state = 4;
						return true;
					case 4:
						<>1__state = -1;
						<>2__current = AccessTools.Method(typeof(ZoneSystem), "Start", (Type[])null, (Type[])null);
						<>1__state = 5;
						return true;
					case 5:
						<>1__state = -1;
						<>2__current = AccessTools.Method(typeof(ZoneSystem), "OnDestroy", (Type[])null, (Type[])null);
						<>1__state = 6;
						return true;
					case 6:
						<>1__state = -1;
						<>2__current = AccessTools.Method(typeof(FejdStartup), "Start", (Type[])null, (Type[])null);
						<>1__state = 7;
						return true;
					case 7:
						<>1__state = -1;
						<>2__current = AccessTools.Method(typeof(FejdStartup), "OnDestroy", (Type[])null, (Type[])null);
						<>1__state = 8;
						return true;
					case 8:
						<>1__state = -1;
						<>2__current = AccessTools.Method(typeof(Player), "SetSleeping", (Type[])null, (Type[])null);
						<>1__state = 9;
						return true;
					case 9:
						<>1__state = -1;
						<>2__current = AccessTools.Method(typeof(Player), "UseHotbarItem", (Type[])null, (Type[])null);
						<>1__state = 10;
						return true;
					case 10:
						<>1__state = -1;
						<>2__current = AccessTools.Method(typeof(Player), "StartGuardianPower", (Type[])null, (Type[])null);
						<>1__state = 11;
						return true;
					case 11:
						<>1__state = -1;
						<>2__current = AccessTools.Method(typeof(Player), "StopEmote", (Type[])null, (Type[])null);
						<>1__state = 12;
						return true;
					case 12:
						<>1__state = -1;
						return false;
					}
				}

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

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

				[DebuggerHidden]
				IEnumerator<MethodBase> IEnumerable<MethodBase>.GetEnumerator()
				{
					if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
					{
						<>1__state = 0;
						return this;
					}
					return new <TargetMethods>d__0(0);
				}

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

			[IteratorStateMachine(typeof(<TargetMethods>d__0))]
			private static IEnumerable<MethodBase> TargetMethods()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <TargetMethods>d__0(-2);
			}

			private static void Postfix()
			{
				Exit(force: true);
			}
		}

		[HarmonyPatch(typeof(GameCamera), "Awake")]
		public static class GameCamera_Awake_SetDefaultPov
		{
			private static void Postfix(GameCamera __instance)
			{
				defaultFoV = ((__instance.m_fov == 0f) ? 65f : __instance.m_fov);
			}
		}

		[HarmonyPatch(typeof(GameCamera), "UpdateCamera")]
		public static class GameCamera_UpdateCamera_BlockCameraDistance
		{
			private static void Prefix(GameCamera __instance, ref float __state)
			{
				if (activated)
				{
					__state = __instance.m_zoomSens;
					__instance.m_zoomSens = 0f;
				}
			}

			private static void Postfix(GameCamera __instance, float __state)
			{
				if (activated)
				{
					__instance.m_zoomSens = __state;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "SetControls")]
		public static class Player_SetControls_SearchModeExit
		{
			private static void Postfix(Player __instance, Vector3 movedir, bool attack, bool secondaryAttack, bool block, bool jump, bool crouch, bool run, bool autoRun, bool dodge)
			{
				if (activated && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && (((Vector3)(ref movedir)).magnitude > 0.05f || attack || secondaryAttack || block || jump || crouch || run || autoRun || dodge))
				{
					Exit(force: true);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "FindHoverObject")]
		public static class Player_FindHoverObject_SearchMode
		{
			private static bool Prefix(Player __instance, out GameObject hover, out Character hoverCreature)
			{
				hover = null;
				hoverCreature = null;
				if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
				{
					return true;
				}
				if (!activated)
				{
					return true;
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Player), "GetHoverObject")]
		public static class Player_GetHoverObject_SearchMode
		{
			private static bool Prefix(Player __instance, ref GameObject __result)
			{
				if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
				{
					return true;
				}
				if (!activated)
				{
					return true;
				}
				__result = null;
				return false;
			}
		}

		[HarmonyPatch(typeof(Minimap), "OnMapLeftDown")]
		public static class Minimap_ShowPinNameInput_BlockPinDialogInSearchMode
		{
			private static bool Prefix(Minimap __instance)
			{
				if (!IsActivated)
				{
					return true;
				}
				__instance.m_leftClickTime = Time.time;
				__instance.m_leftDownTime = Time.time;
				return false;
			}
		}

		private static List<Direction> directions = new List<Direction>();

		private static Direction current;

		private static bool activated;

		private static readonly Direction placeOfMystery = new Direction("$ws_location_random_point", Vector3.zero);

		private static float currentAngle;

		private static WaystoneList.WaystoneData sourceWaystone;

		private static float defaultFoV;

		private static float targetFoV;

		public static CanvasGroup screenBlackener;

		public static AudioSource screenBlackenerSfx;

		public static bool IsActivated => activated;

		internal static void Toggle()
		{
			if (activated)
			{
				Exit();
			}
			else if (Waystones.useShortcutToEnter.Value && Waystones.CanCast() && WaystoneSmall.IsSearchAllowed(Player.m_localPlayer, validateCharge: false))
			{
				WaystoneList.EnterSearchMode();
			}
		}

		internal static void Enter()
		{
			//IL_0033: 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)
			Player localPlayer = Player.m_localPlayer;
			if (!Waystones.CanCast() || !WaystoneSmall.IsSearchAllowed(localPlayer, validateCharge: false))
			{
				return;
			}
			sourceWaystone = WaystoneList.GetSearchSourceWaystone() ?? WaystoneList.GetClosestActivatedWaystoneData(((Component)localPlayer).transform.position);
			if (Waystones.waystoneMode.Value == Waystones.WaystoneMode.Charge && !WaystoneList.HasEnoughTravelCharge(sourceWaystone, WorldData.MinWaystoneChargeCost, Waystones.allowWaystoneChargeOverdraft.Value))
			{
				sourceWaystone = null;
				((Character)localPlayer).Message((MessageType)2, "$ws_message_not_enough_charge", 0, (Sprite)null);
				return;
			}
			if (!activated)
			{
				Game.FadeTimeScale(Waystones.slowFactorTime.Value, 4f);
				targetFoV = defaultFoV;
				Waystones.LogInfo($"Search mode activated at {((Component)localPlayer).transform.position}");
			}
			FillDirections();
			activated = true;
			WaystoneList.UpdatePins();
		}

		internal static void Exit(bool force = false)
		{
			if (!Waystones.CanCast() && !force)
			{
				return;
			}
			if (activated)
			{
				GameCamera.instance.m_fov = defaultFoV;
				if (Game.m_timeScale >= Waystones.slowFactorTime.Value)
				{
					Game.FadeTimeScale(1f, 1f);
				}
				if (Waystones.waystoneMode.Value == Waystones.WaystoneMode.Cooldown && !WorldData.IsOnCooldown())
				{
					WorldData.SetCooldown(Waystones.cooldownSearchMode.Value);
				}
				Waystones.LogInfo("Search mode ended");
			}
			activated = false;
			current = null;
			currentAngle = 0f;
			sourceWaystone = null;
			WaystoneList.UpdatePins();
		}

		internal static void FillDirections()
		{
			//IL_0024: 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_01db: 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_0138: 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)
			directions.Clear();
			if (Waystones.locationShowCurrentSpawn.Value)
			{
				directions.Add(new Direction("$ws_location_spawn_point", GetSpawnPoint()));
			}
			ZoneSystem.instance.tempIconList.Clear();
			ZoneSystem.instance.GetLocationIcons(ZoneSystem.instance.tempIconList);
			foreach (KeyValuePair<Vector3, string> tempIcon in ZoneSystem.instance.tempIconList)
			{
				if (tempIcon.Value == "StartTemple" && Waystones.locationShowStartTemple.Value)
				{
					directions.Add(new Direction("$ws_location_start_temple", tempIcon.Key));
				}
				else if (tempIcon.Value == "Vendor_BlackForest" && Waystones.locationShowHaldor.Value)
				{
					directions.Add(new Direction("$npc_haldor", tempIcon.Key));
				}
				else if (tempIcon.Value == "Hildir_camp" && Waystones.locationShowHildir.Value)
				{
					directions.Add(new Direction("$npc_hildir", tempIcon.Key));
				}
				else if (tempIcon.Value == "BogWitch_Camp" && Waystones.locationShowBogWitch.Value)
				{
					directions.Add(new Direction("$npc_bogwitch", tempIcon.Key));
				}
			}
			PlayerProfile playerProfile = Game.instance.GetPlayerProfile();
			if (playerProfile.HaveDeathPoint() && Waystones.locationShowLastTombstone.Value)
			{
				directions.Add(new Direction("$ws_location_last_tombstone", playerProfile.GetDeathPoint()));
			}
			directions.AddRange(WorldData.GetSavedDirections());
			CollectionExtensions.Do<Direction>((IEnumerable<Direction>)directions, (Action<Direction>)delegate(Direction d)
			{
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				Waystones.LogInfo(string.Format("{0} {1} {2} {3}", Localization.instance.Localize(d.name), d.position, WorldData.TimerString(d.cooldown), (Utils.DistanceXZ(((Component)Player.m_localPlayer).transform.position, d.position) < 10f) ? "(filtered, too close)" : ""));
			});
			directions.RemoveAll((Direction d) => Utils.DistanceXZ(((Component)Player.m_localPlayer).transform.position, d.position) < 10f);
			if (Waystones.waystoneMode.Value != Waystones.WaystoneMode.Orientation)
			{
				return;
			}
			float maxDistance = Waystones.orientationWaystoneVisibilityDistance.Value;
			directions.RemoveAll(delegate(Direction d)
			{
				//IL_000b: 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)
				float num = Utils.DistanceXZ(((Component)Player.m_localPlayer).transform.position, d.position);
				if (num <= maxDistance)
				{
					return false;
				}
				string name = d.name;
				if (1 == 0)
				{
				}
				bool result = name switch
				{
					"$ws_location_spawn_point" => !Waystones.orientationShowDistantCurrentSpawn.Value, 
					"$ws_location_last_tombstone" => !Waystones.orientationShowDistantLastTombstone.Value, 
					"$ws_location_last_ship" => !Waystones.orientationShowDistantLastShip.Value, 
					"$ws_location_last_location" => !Waystones.orientationShowDistantLastPoint.Value, 
					"$ws_location_start_temple" => !Waystones.orientationShowDistantStartTemple.Value, 
					"$npc_haldor" => !Waystones.orientationShowDistantHaldor.Value, 
					"$npc_hildir" => !Waystones.orientationShowDistantHildir.Value, 
					"$npc_bogwitch" => !Waystones.orientationShowDistantBogWitch.Value, 
					_ => d.name.Contains("$ws_piece_waystone_name") && !Waystones.orientationShowDistantWaystones.Value, 
				};
				if (1 == 0)
				{
				}
				return result;
			});
		}

		internal static Vector3 GetSpawnPoint()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			PlayerProfile playerProfile = Game.instance.GetPlayerProfile();
			if (playerProfile.HaveCustomSpawnPoint())
			{
				return playerProfile.GetCustomSpawnPoint();
			}
			return playerProfile.GetHomePoint();
		}

		internal static void Update()
		{
			//IL_000c: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: 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_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = Waystones.shortcut.Value;
			if (((KeyboardShortcut)(ref value)).IsDown())
			{
				Toggle();
			}
			else if (activated && (ZInput.GetButtonDown("Block") || ZInput.GetButtonDown("JoyButtonB")))
			{
				Exit();
			}
			if (current != null && (ZInput.GetButton("Use") || ZInput.GetButton("JoyUse")) && Waystones.CanCast())
			{
				Direction direction = ((current == placeOfMystery) ? new Direction("$ws_location_random_point", GetRandomPoint()) : current);
				if (Waystones.waystoneMode.Value == Waystones.WaystoneMode.Orientation)
				{
					Exit();
					return;
				}
				if (Waystones.waystoneMode.Value == Waystones.WaystoneMode.Charge && !WaystoneList.HasEnoughTravelCharge(sourceWaystone, direction.travelCost, Waystones.allowWaystoneChargeOverdraft.Value))
				{
					MessageHud.instance.ShowMessage((MessageType)2, "$ws_message_not_enough_charge", 0, (Sprite)null, false);
					return;
				}
				Waystones.TeleportAttempt(direction.position, direction.rotation, direction.cooldown, direction.name, sourceWaystone, direction.travelCost);
				Exit();
			}
			if (activated && !Waystones.CanCast())
			{
				Exit(force: true);
			}
			if (!activated)
			{
				return;
			}
			current = null;
			targetFoV -= Mathf.Clamp(ZInput.GetMouseScrollWheel(), -1f, 1f);
			if (ZInput.GetButton("JoyAltKeys") && !Hud.InRadial())
			{
				if (ZInput.GetButton("JoyCamZoomIn"))
				{
					targetFoV -= 1f;
				}
				else if (ZInput.GetButton("JoyCamZoomOut"))
				{
					targetFoV += 1f;
				}
			}
			targetFoV = Mathf.Clamp(targetFoV, defaultFoV - Waystones.fovDelta.Value, defaultFoV + Waystones.fovDelta.Value);
			GameCamera.instance.m_fov = Mathf.MoveTowards(GameCamera.instance.m_fov, targetFoV, Waystones.fovDelta.Value);
			Vector3 look = ((Character)Player.m_localPlayer).GetLookDir();
			currentAngle = Vector3.Angle(look, Vector3.down);
			if (currentAngle < GetCurrentSensivity() && Waystones.locationShowRandomPoint.Value)
			{
				current = placeOfMystery;
			}
			else if (directions.Count != 0)
			{
				Vector3 pos = ((Character)Player.m_localPlayer).GetEyePoint();
				directions = directions.OrderBy((Direction dir) => Vector3.Angle(look, dir.position - pos)).ToList();
				currentAngle = Vector3.Angle(look, directions[0].position - pos);
				if (currentAngle < GetCurrentSensivity())
				{
					current = directions[0];
				}
			}
		}

		private static float GetCurrentSensivity()
		{
			return Waystones.directionSensitivity.Value * targetFoV / defaultFoV;
		}

		private static float GetCurrentScreenSensivityThreshold()
		{
			return Waystones.directionSensitivityThreshold.Value * targetFoV / defaultFoV;
		}

		private static float GetCurrentSfxSensivityThreshold()
		{
			return Waystones.sfxSensitivityThreshold.Value * targetFoV / defaultFoV;
		}

		private static Vector3 GetRandomPoint()
		{
			//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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 zero = Vector3.zero;
			do
			{
				zero = GetRandomPointInRadius(Vector3.zero, 10000f);
			}
			while (!IsValidRandomPointForTeleport(ref zero));
			return zero;
		}

		private static bool IsValidRandomPointForTeleport(ref Vector3 pos)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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)
			Biome biome = WorldGenerator.instance.GetBiome(pos);
			if ((int)biome == 256 || (int)biome == 0 || !Player.m_localPlayer.m_knownBiome.Contains(biome))
			{
				return false;
			}
			pos = new Vector3(pos.x, 31f, pos.z);
			return true;
		}

		public static Vector3 GetRandomPointInRadius(Vector3 center, float radius)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			float num = Random.value * (float)Math.PI * 2f;
			float num2 = Random.Range(0f, radius);
			return center + new Vector3(Mathf.Sin(num) * num2, 0f, Mathf.Cos(num) * num2);
		}
	}
	public static class ItemNameTokens
	{
		[HarmonyPatch(typeof(Player), "Load")]
		private static class Player_Load_UpdateRegisters
		{
			private static void Prefix()
			{
				UpdateRegisters();
			}
		}

		public static readonly Dictionary<string, string> itemNames = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

		public static void UpdateRegisters()
		{
			if (!Object.op_Implicit((Object)(object)ObjectDB.instance))
			{
				return;
			}
			itemNames.Clear();
			foreach (GameObject item in ObjectDB.instance.m_items)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				ItemDrop component = item.GetComponent<ItemDrop>();
				if (component != null)
				{
					SharedData val = component.m_itemData?.m_shared;
					if (val != null && !string.IsNullOrWhiteSpace(val.m_name) && val.m_name.StartsWith("$"))
					{
						itemNames[((Object)item).name] = val.m_name;
						itemNames[val.m_name] = val.m_name;
					}
				}
			}
			Waystones.ReadInitialConfigs();
		}

		public static string GetItemName(this string input)
		{
			string value;
			return itemNames.TryGetValue((input ?? "").Trim(), out value) ? value : input;
		}
	}
	internal static class WaystoneList
	{
		public class WaystoneData
		{
			public string tag;

			public Vector3 searchPosition;

			public Quaternion searchRotation;

			public Vector3 worldPosition;

			public int charge;
		}

		[HarmonyPatch(typeof(Minimap), "Start")]
		public static class WaystoneIconType
		{
			public static int pinType;

			private static void Postfix(Minimap __instance)
			{
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				pinType = __instance.m_visibleIconTypes.Length;
				bool[] array = new bool[pinType + 1];
				Array.Copy(__instance.m_visibleIconTypes, array, pinType);
				__instance.m_visibleIconTypes = array;
				__instance.m_icons.Add(new SpriteData
				{
					m_name = (PinType)pinType,
					m_icon = iconWaystone
				});
			}
		}

		[HarmonyPatch(typeof(ZoneSystem), "Start")]
		public static class ZoneSystem_Start_WaystoneList
		{
			private static void Postfix()
			{
				RegisterRPCs();
			}
		}

		[HarmonyPatch(typeof(ZoneSystem), "OnDestroy")]
		public static class ZoneSystem_OnDestroy_WaystoneList
		{
			private static void Postfix()
			{
				waystoneObjects.Clear();
				activatedWaystones.Clear();
				searchSourceWaystone = null;
			}
		}

		[HarmonyPatch(typeof(ZDOMan), "Load")]
		public static class ZDOMan_Load_WaystoneListInit
		{
			private static void Postfix(ZDOMan __instance)
			{
				foreach (KeyValuePair<ZDOID, ZDO> item in __instance.m_objectsByID)
				{
					if (item.Value.GetPrefab() == PieceWaystone.waystoneHash)
					{
						waystoneObjects.Add(item.Value);
					}
				}
			}
		}

		[HarmonyPatch(typeof(ZDOMan), "CreateNewZDO", new Type[]
		{
			typeof(ZDOID),
			typeof(Vector3),
			typeof(int)
		})]
		public static class ZDOMan_CreateNewZDO_WaystoneListAddNew
		{
			private static void Postfix(int prefabHashIn, ZDO __result)
			{
				if (((prefabHashIn != 0) ? prefabHashIn : __result.GetPrefab()) == PieceWaystone.waystoneHash)
				{
					waystoneObjects.Add(__result);
				}
			}
		}

		[HarmonyPatch(typeof(ZDOMan), "HandleDestroyedZDO")]
		public static class ZDOMan_HandleDestroyedZDO_WaystoneListRemove
		{
			private static void Prefix(ZDOMan __instance, ZDOID uid)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				ZDO zDO = __instance.GetZDO(uid);
				if (zDO != null && zDO.GetPrefab() == PieceWaystone.waystoneHash)
				{
					waystoneObjects.Remove(zDO);
				}
			}
		}

		[HarmonyPatch(typeof(ZDO), "Deserialize")]
		public static class ZDO_Deserialize_WaystoneListAdd
		{
			private static void Postfix(ZDO __instance)
			{
				if (__instance.GetPrefab() == PieceWaystone.waystoneHash)
				{
					waystoneObjects.Add(__instance);
				}
			}
		}

		public static Sprite iconWaystone;

		public static readonly List<PinData> waystonePins = new List<PinData>();

		public static readonly List<WaystoneData> activatedWaystones = new List<WaystoneData>();

		private static WaystoneData searchSourceWaystone;

		public static readonly HashSet<ZDO> waystoneObjects = new HashSet<ZDO>();

		public const string customDataKey = "WaystoneList";

		public const string chargeZdoKey = "WaystoneCharges";

		private const float waystoneSearchPointOffset = 1f;

		private const float defaultWaystoneMatchDistance = 8f;

		private const string markedLocationRequestRpc = "MarkedLocationRequest";

		private const string markedLocationResponseRpc = "MarkedLocationResponse";

		private const string consumeWaystoneChargeRequestRpc = "ConsumeWaystoneChargeRequest";

		public static void UpdatePins()
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			foreach (PinData waystonePin in waystonePins)
			{
				Minimap.instance.RemovePin(waystonePin);
			}
			waystonePins.Clear();
			if (!Waystones.locationWaystonesShowOnMap.Value || !DirectionSearch.IsActivated)
			{
				return;
			}
			foreach (WaystoneData activatedWaystone in activatedWaystones)
			{
				waystonePins.Add(Minimap.instance.AddPin(activatedWaystone.searchPosition, (PinType)WaystoneIconType.pinType, activatedWaystone.tag, false, false, Player.m_localPlayer.GetPlayerID(), default(PlatformUserID)));
			}
		}

		internal static void RegisterRPCs()
		{
			if (ZNet.instance.IsServer())
			{
				ZRoutedRpc.instance.Register<ZPackage>("MarkedLocationRequest", (Action<long, ZPackage>)RPC_MarkedLocationRequest);
				ZRoutedRpc.instance.Register<ZPackage>("ConsumeWaystoneChargeRequest", (Action<long, ZPackage>)RPC_ConsumeWaystoneChargeRequest);
			}
			else
			{
				ZRoutedRpc.instance.Register<ZPackage>("MarkedLocationResponse", (Action<long, ZPackage>)RPC_MarkedLocationResponse);
			}
		}

		public static void EnterSearchMode(ZDO sourceZdo = null)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (Object.op_Implicit((Object)(object)localPlayer) && !((Object)(object)ZNet.instance == (Object)null))
			{
				if (!ZNet.instance.IsServer())
				{
					MarkedLocationRequest(sourceZdo);
					return;
				}
				GetActivatedWaystones(localPlayer.GetPlayerID());
				searchSourceWaystone = CreateSearchSourceWaystone(sourceZdo, ((Component)localPlayer).transform.position);
				DirectionSearch.Enter();
			}
		}

		public static void MarkedLocationRequest(ZDO sourceZdo = null)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (Object.op_Implicit((Object)(object)localPlayer))
			{
				Waystones.LogInfo("Marked location request");
				ZPackage val = new ZPackage();
				val.Write(localPlayer.GetPlayerID());
				val.Write(((Component)localPlayer).transform.position);
				bool flag = sourceZdo != null;
				val.Write(flag ? 1 : 0);
				if (flag)
				{
					val.Write(sourceZdo.GetPosition());
				}
				ZRoutedRpc.instance.InvokeRoutedRPC("MarkedLocationRequest", new object[1] { val });
			}
		}

		public static List<WaystoneData> GetActivatedWaystones(long playerID)
		{
			activatedWaystones.Clear();
			waystoneObjects.RemoveWhere((ZDO zdo) => zdo == null);
			foreach (ZDO waystoneObject in waystoneObjects)
			{
				if (WaystoneSmall.IsWaystoneActivated(waystoneObject, playerID))
				{
					string @string = waystoneObject.GetString(ZDOVars.s_tag, "");
					if (!string.IsNullOrWhiteSpace(@string))
					{
						activatedWaystones.Add(CreateWaystoneData(waystoneObject, @string));
					}
				}
			}
			return activatedWaystones;
		}

		private static WaystoneData CreateWaystoneData(ZDO zdo, string tag)
		{
			//IL_000f: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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)
			//IL_004d: 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)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			if (zdo == null)
			{
				return null;
			}
			Vector3 position = zdo.GetPosition();
			Quaternion rotation = zdo.GetRotation();
			Vector3 val = rotation * Vector3.forward;
			return new WaystoneData
			{
				tag = tag,
				worldPosition = position,
				searchPosition = position + val * 1f + Vector3.up,
				searchRotation = rotation * Quaternion.Euler(0f, 180f, 0f),
				charge = GetWaystoneCharge(zdo)
			};
		}

		private static WaystoneData CreateSearchSourceWaystone(ZDO sourceZdo, Vector3 playerPosition)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			if (sourceZdo == null)
			{
				sourceZdo = GetClosestWaystone(playerPosition);
			}
			return CreateWaystoneData(sourceZdo, (sourceZdo == null) ? "" : sourceZdo.GetString(ZDOVars.s_tag, ""));
		}

		public static WaystoneData GetSearchSourceWaystone()
		{
			return searchSourceWaystone;
		}

		public static WaystoneData GetClosestActivatedWaystoneData(Vector3 point, float maxDistance = 8f)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			WaystoneData result = null;
			float num = maxDistance;
			foreach (WaystoneData activatedWaystone in activatedWaystones)
			{
				float num2 = Utils.DistanceXZ(point, activatedWaystone.worldPosition);
				if (num2 <= num)
				{
					num = num2;
					result = activatedWaystone;
				}
			}
			return result;
		}

		public static int GetClosestActivatedWaystoneCharge(long playerID, Vector3 point, float maxDistance = 8f)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			WaystoneData closestActivatedWaystoneData = GetClosestActivatedWaystoneData(point, maxDistance);
			if (closestActivatedWaystoneData != null)
			{
				return closestActivatedWaystoneData.charge;
			}
			if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
			{
				ZDO closestWaystone = GetClosestWaystone(point, maxDistance);
				return (closestWaystone != null) ? GetWaystoneCharge(closestWaystone) : 0;
			}
			return 0;
		}

		public static bool IsPlayerChargeStorage()
		{
			return Waystones.waystoneChargeStorage.Value == Waystones.ChargeStorage.Player;
		}

		public static int GetDefaultWaystoneCharge()
		{
			return WorldData.GetDefaultCharge();
		}

		public static int GetCurrentTravelCharge(long playerID, Vector3 point, float maxDistance = 8f)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			return IsPlayerChargeStorage() ? WorldData.GetPlayerCharge() : GetClosestActivatedWaystoneCharge(playerID, point, maxDistance);
		}

		public static int GetWaystoneCharge(ZDO zdo)
		{
			if (zdo == null)
			{
				return 0;
			}
			int @int = zdo.GetInt("WaystoneCharges", GetDefaultWaystoneCharge());
			return Waystones.allowWaystoneChargeOverflow.Value ? @int : Mathf.Min(@int, WorldData.MaxWaystoneCharge);
		}

		public static int GetPotentialChargeAdded(ZDO zdo, int amount)
		{
			return IsPlayerChargeStorage() ? WorldData.GetPotentialPlayerChargeAdded(amount) : GetPotentialWaystoneChargeAdded(zdo, amount);
		}

		public static int GetPotentialWaystoneChargeAdded(ZDO zdo, int amount)
		{
			if (zdo == null || amount <= 0)
			{
				return 0;
			}
			int waystoneCharge = GetWaystoneCharge(zdo);
			int maxWaystoneCharge = WorldData.MaxWaystoneCharge;
			if (Waystones.allowWaystoneChargeOverflow.Value)
			{
				return (waystoneCharge < maxWaystoneCharge) ? amount : 0;
			}
			int num = Mathf.Min(waystoneCharge + amount, maxWaystoneCharge);
			return Mathf.Max(0, num - waystoneCharge);
		}

		public static bool CanStartSearchWithCharge(int current)
		{
			return HasEnoughCharge(current, WorldData.MinWaystoneChargeCost, Waystones.allowWaystoneChargeOverdraft.Value);
		}

		public static bool HasEnoughTravelCharge(WaystoneData sourceWaystone, int amount, bool allowOverdraftWhenPositive)
		{
			int current = (IsPlayerChargeStorage() ? WorldData.GetPlayerCharge() : (sourceWaystone?.charge ?? 0));
			return HasEnoughCharge(current, amount, allowOverdraftWhenPositive);
		}

		public static bool HasEnoughWaystoneCharge(WaystoneData waystone, int amount, bool allowOverdraftWhenPositive)
		{
			return waystone != null && HasEnoughCharge(waystone.charge, amount, allowOverdraftWhenPositive);
		}

		public static bool HasEnoughWaystoneCharge(int current, int amount, bool allowOverdraftWhenPositive)
		{
			return HasEnoughCharge(current, amount, allowOverdraftWhenPositive);
		}

		public static bool TryConsumeTravelCharge(WaystoneData sourceWaystone, long playerID, int amount, bool allowOverdraftWhenPositive = false)
		{
			return IsPlayerChargeStorage() ? WorldData.TryConsumePlayerCharge(amount, allowOverdraftWhenPositive) : TryConsumeWaystoneCharge(sourceWaystone, playerID, amount, allowOverdraftWhenPositive);
		}

		public static bool TryConsumeWaystoneCharge(WaystoneData waystone, long playerID, int amount, bool allowOverdraftWhenPositive = false)
		{
			//IL_0099: 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)
			if (waystone == null || amount <= 0)
			{
				return false;
			}
			if (!HasEnoughCharge(waystone.charge, amount, allowOverdraftWhenPositive))
			{
				return false;
			}
			if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
			{
				ZDO closestWaystone = GetClosestWaystone(waystone.worldPosition, 2f);
				if (!TryConsumeWaystoneCharge(closestWaystone, amount, allowOverdraftWhenPositive))
				{
					return false;
				}
				waystone.charge = GetWaystoneCharge(closestWaystone);
				return true;
			}
			waystone.charge -= amount;
			ConsumeWaystoneChargeRequest(playerID, waystone.worldPosition, amount, allowOverdraftWhenPositive);
			return true;
		}

		public static bool TryConsumeWaystoneCharge(ZDO zdo, int amount, bool allowOverdraftWhenPositive = false)
		{
			if (zdo == null || amount <= 0)
			{
				return false;
			}
			int waystoneCharge = GetWaystoneCharge(zdo);
			if (!HasEnoughCharge(waystoneCharge, amount, allowOverdraftWhenPositive))
			{
				return false;
			}
			zdo.Set("WaystoneCharges", waystoneCharge - amount);
			return true;
		}

		private static bool HasEnoughCharge(int current, int amount, bool allowOverdraftWhenPositive)
		{
			return current >= amount || (allowOverdraftWhenPositive && current > 0);
		}

		public static int AddCharge(ZDO zdo, int amount)
		{
			return IsPlayerChargeStorage() ? WorldData.AddPlayerCharge(amount) : AddWaystoneCharge(zdo, amount);
		}

		public static int AddWaystoneCharge(ZDO zdo, int amount)
		{
			int potentialWaystoneChargeAdded = GetPotentialWaystoneChargeAdded(zdo, amount);
			if (potentialWaystoneChargeAdded <= 0)
			{
				return 0;
			}
			zdo.Set("WaystoneCharges", GetWaystoneCharge(zdo) + potentialWaystoneChargeAdded);
			return potentialWaystoneChargeAdded;
		}

		public static ZDO GetClosestActivatedWaystone(long playerID, Vector3 point, float maxDistance = 8f)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			ZDO result = null;
			float num = maxDistance;
			foreach (ZDO waystoneObject in waystoneObjects)
			{
				if (WaystoneSmall.IsWaystoneActivated(waystoneObject, playerID))
				{
					float num2 = Utils.DistanceXZ(point, waystoneObject.GetPosition());
					if (num2 <= num)
					{
						num = num2;
						result = waystoneObject;
					}
				}
			}
			return result;
		}

		public static ZDO GetClosestWaystone(Vector3 point, float maxDistance = 8f)
		{
			//IL_0046: 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)
			ZDO result = null;
			float num = maxDistance;
			waystoneObjects.RemoveWhere((ZDO zdo) => zdo == null);
			foreach (ZDO waystoneObject in waystoneObjects)
			{
				float num2 = Utils.DistanceXZ(point, waystoneObject.GetPosition());
				if (num2 <= num)
				{
					num = num2;
					result = waystoneObject;
				}
			}
			return result;
		}

		private static void ConsumeWaystoneChargeRequest(long playerID, Vector3 worldPosition, int amount, bool allowOverdraftWhenPositive)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			ZPackage val = new ZPackage();
			val.Write(playerID);
			val.Write(worldPosition);
			val.Write(amount);
			val.Write(allowOverdraftWhenPositive ? 1 : 0);
			ZRoutedRpc.instance.InvokeRoutedRPC("ConsumeWaystoneChargeRequest", new object[1] { val });
		}

		public static void RPC_ConsumeWaystoneChargeRequest(long sender, ZPackage pkg)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			long num = pkg.ReadLong();
			Vector3 val = pkg.ReadVector3();
			int num2 = pkg.ReadInt();
			pkg.ReadInt();
			bool value = Waystones.allowWaystoneChargeOverdraft.Value;
			ZDO closestWaystone = GetClosestWaystone(val, 2f);
			if (!TryConsumeWaystoneCharge(closestWaystone, num2, value))
			{
				Waystones.LogInfo($"Rejected waystone charge consume request from {sender}. Player: {num}, amount: {num2}, position: {val}");
			}
		}

		public static void RPC_MarkedLocationRequest(long sender, ZPackage request)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			long playerID = request.ReadLong();
			Vector3 playerPosition = request.ReadVector3();
			ZDO sourceZdo = null;
			if (request.ReadInt() != 0)
			{
				sourceZdo = GetClosestWaystone(request.ReadVector3(), 2f);
			}
			GetActivatedWaystones(playerID);
			WaystoneData waystoneData = CreateSearchSourceWaystone(sourceZdo, playerPosition);
			ZPackage val = new ZPackage();
			val.Write(activatedWaystones.Count);
			foreach (WaystoneData activatedWaystone in activatedWaystones)
			{
				WriteWaystoneData(val, activatedWaystone);
			}
			val.Write((waystoneData != null) ? 1 : 0);
			if (waystoneData != null)
			{
				WriteWaystoneData(val, waystoneData);
			}
			ZRoutedRpc.instance.InvokeRoutedRPC(sender, "MarkedLocationResponse", new object[1]