Decompiled source of ParchmentMap v0.6.8

ParchmentMap.dll

Decompiled a month 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.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.UI;
using Valheim.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("ParchmentMap")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.6.8.0")]
[assembly: AssemblyInformationalVersion("0.6.8+f8984bbdaac924feed2c5dd7f7cc88d47814059d")]
[assembly: AssemblyProduct("ParchmentMap")]
[assembly: AssemblyTitle("ParchmentMap")]
[assembly: AssemblyVersion("0.6.8.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ParchmentMap
{
	internal static class CompassItem
	{
		private sealed class Part
		{
			public string Prefab;

			public string Token;

			public string Picture;

			public float Size;

			public float Weight;

			public int Stack;

			public string Station;

			public Func<string> Recipe;
		}

		public const string PrefabName = "Q8_Compass";

		public const string CasePrefabName = "Q8_CompassCase";

		public const string NeedlePrefabName = "Q8_CompassNeedle";

		public const string MagnetisedPrefabName = "Q8_CompassNeedleMagnetised";

		public const string LidPrefabName = "Q8_CompassLid";

		public const string NameToken = "$item_q8pm_compass";

		private const string BasePrefabName = "DeerHide";

		private static readonly Part[] Parts = new Part[5]
		{
			new Part
			{
				Prefab = "Q8_CompassCase",
				Token = "item_q8pm_compass_case",
				Picture = "compass_case",
				Size = 0.14f,
				Weight = 0.5f,
				Stack = 10,
				Station = CraftingStations.Forge,
				Recipe = () => ParchmentMapPlugin.CompassCaseRecipe.Value
			},
			new Part
			{
				Prefab = "Q8_CompassNeedle",
				Token = "item_q8pm_compass_needle",
				Picture = "needle_iron",
				Size = 0.12f,
				Weight = 0.1f,
				Stack = 20,
				Station = CraftingStations.Forge,
				Recipe = () => ParchmentMapPlugin.CompassNeedleRecipe.Value
			},
			new Part
			{
				Prefab = "Q8_CompassNeedleMagnetised",
				Token = "item_q8pm_compass_needle_magnetised",
				Picture = "needle_magnet",
				Size = 0.12f,
				Weight = 0.1f,
				Stack = 20
			},
			new Part
			{
				Prefab = "Q8_CompassLid",
				Token = "item_q8pm_compass_lid",
				Picture = "compass_lid",
				Size = 0.14f,
				Weight = 0.3f,
				Stack = 10,
				Station = CraftingStations.Workbench,
				Recipe = () => ParchmentMapPlugin.CompassLidRecipe.Value
			},
			new Part
			{
				Prefab = "Q8_Compass",
				Token = "item_q8pm_compass",
				Picture = "compass",
				Size = 0.16f,
				Weight = 0.5f,
				Stack = 1,
				Station = CraftingStations.Workbench,
				Recipe = () => ParchmentMapPlugin.CompassRecipe.Value
			}
		};

		internal static bool IsCompass(ItemData item)
		{
			if (item != null && item.m_shared != null)
			{
				return item.m_shared.m_name == "$item_q8pm_compass";
			}
			return false;
		}

		internal static bool InInventory(Player player)
		{
			Inventory val = (((Object)(object)player != (Object)null) ? ((Humanoid)player).GetInventory() : null);
			if (val == null)
			{
				return false;
			}
			List<ItemData> allItems = val.GetAllItems();
			for (int i = 0; i < allItems.Count; i++)
			{
				if (IsCompass(allItems[i]))
				{
					return true;
				}
			}
			return false;
		}

		internal static void Register()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= Register;
			Part[] parts = Parts;
			for (int i = 0; i < parts.Length; i++)
			{
				Register(parts[i]);
			}
		}

		private static void Register(Part part)
		{
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Invalid comparison between Unknown and I4
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Expected O, but got Unknown
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Expected O, but got Unknown
			GameObject val = PrefabManager.Instance.CreateClonedPrefab(part.Prefab, "DeerHide");
			ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null);
			if ((Object)(object)val2 == (Object)null)
			{
				ParchmentMapPlugin.Log.LogError((object)("Base prefab DeerHide not found or has no ItemDrop, " + part.Prefab + " is not added."));
				return;
			}
			bool flag = (int)SystemInfo.graphicsDeviceType == 4;
			if (!flag)
			{
				try
				{
					BuildVisuals(val, part);
				}
				catch (Exception ex)
				{
					ParchmentMapPlugin.Log.LogWarning((object)("Could not build the model of " + part.Prefab + ": " + ex.Message));
				}
			}
			val2.m_autoDestroy = false;
			SharedData shared = val2.m_itemData.m_shared;
			shared.m_itemType = (ItemType)1;
			shared.m_maxStackSize = part.Stack;
			shared.m_autoStack = part.Stack > 1;
			shared.m_maxQuality = 1;
			shared.m_weight = part.Weight;
			shared.m_value = 0;
			shared.m_teleportable = true;
			shared.m_questItem = false;
			shared.m_useDurability = false;
			shared.m_canBeReparied = false;
			shared.m_buildPieces = null;
			shared.m_equipStatusEffect = null;
			shared.m_setStatusEffect = null;
			shared.m_consumeStatusEffect = null;
			shared.m_setName = "";
			shared.m_setSize = 0;
			shared.m_food = 0f;
			shared.m_foodStamina = 0f;
			shared.m_foodEitr = 0f;
			shared.m_variants = 0;
			shared.m_attack = (Attack)(((object)shared.m_attack) ?? ((object)new Attack()));
			shared.m_secondaryAttack = (Attack)(((object)shared.m_secondaryAttack) ?? ((object)new Attack()));
			ItemConfig val3 = new ItemConfig
			{
				Name = "$" + part.Token,
				Description = "$" + part.Token + "_desc"
			};
			if (!flag)
			{
				val3.Icons = (Sprite[])(object)new Sprite[1] { LoadSprite(part.Picture + "_icon.png") };
				if (part.Station != null)
				{
					val3.CraftingStation = part.Station;
					val3.MinStationLevel = 1;
					val3.Amount = 1;
					val3.Requirements = MapItem.ParseRecipe(part.Recipe()).ToArray();
				}
			}
			if (!ItemManager.Instance.AddItem(new CustomItem(val, false, val3)))
			{
				ParchmentMapPlugin.Log.LogError((object)("Jotunn rejected the item " + part.Prefab + "."));
			}
		}

		internal static void ApplyRecipesToObjectDB()
		{
			Part[] parts = Parts;
			foreach (Part part in parts)
			{
				if (part.Recipe != null)
				{
					MapItem.ApplyRecipeTo(part.Prefab, part.Recipe());
				}
			}
		}

		internal static void AddObliteratorConversion(Incinerator incinerator)
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			if ((Object)(object)incinerator == (Object)null || incinerator.m_conversions == null || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return;
			}
			ItemDrop val = ItemOf("Q8_CompassNeedle");
			ItemDrop val2 = ItemOf("Q8_CompassNeedleMagnetised");
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
			{
				return;
			}
			foreach (IncineratorConversion conversion in incinerator.m_conversions)
			{
				if (conversion != null && (Object)(object)conversion.m_result == (Object)(object)val2)
				{
					return;
				}
			}
			incinerator.m_conversions.Add(new IncineratorConversion
			{
				m_requirements = new List<Requirement>
				{
					new Requirement
					{
						m_resItem = val,
						m_amount = 1
					}
				},
				m_result = val2,
				m_resultAmount = 1,
				m_priority = 100,
				m_requireOnlyOneIngredient = false
			});
		}

		private static ItemDrop ItemOf(string prefabName)
		{
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefabName);
			if (!((Object)(object)itemPrefab != (Object)null))
			{
				return null;
			}
			return itemPrefab.GetComponent<ItemDrop>();
		}

		private static void BuildVisuals(GameObject prefab, Part part)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_006f: 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_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			MeshRenderer componentInChildren = prefab.GetComponentInChildren<MeshRenderer>(true);
			Material val = (((Object)(object)componentInChildren != (Object)null && (Object)(object)((Renderer)componentInChildren).sharedMaterial != (Object)null) ? new Material(((Renderer)componentInChildren).sharedMaterial) : new Material(Shader.Find("Standard")));
			((Object)val).name = "q8pm_" + part.Picture;
			val.mainTexture = (Texture)(object)MapItem.LoadTexture(part.Picture + ".png", repeat: false);
			val.color = Color.white;
			if (val.HasProperty("_Cull"))
			{
				val.SetFloat("_Cull", 0f);
			}
			string[] array = new string[3] { "_BumpMap", "_MetallicGlossMap", "_EmissionMap" };
			foreach (string text in array)
			{
				if (val.HasProperty(text))
				{
					val.SetTexture(text, (Texture)null);
				}
			}
			array = new string[2] { "_Metallic", "_Glossiness" };
			foreach (string text2 in array)
			{
				if (val.HasProperty(text2))
				{
					val.SetFloat(text2, 0f);
				}
			}
			for (int num = prefab.transform.childCount - 1; num >= 0; num--)
			{
				Object.DestroyImmediate((Object)(object)((Component)prefab.transform.GetChild(num)).gameObject);
			}
			LODGroup component = prefab.GetComponent<LODGroup>();
			if ((Object)(object)component != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component);
			}
			GameObject val2 = new GameObject("model")
			{
				layer = prefab.layer
			};
			val2.transform.SetParent(prefab.transform, false);
			val2.transform.localPosition = new Vector3(0f, 0.012f, 0f);
			val2.transform.localRotation = Quaternion.Euler(90f, 0f, 0f);
			val2.AddComponent<MeshFilter>().sharedMesh = BuildQuad(part.Size, part.Picture);
			((Renderer)val2.AddComponent<MeshRenderer>()).sharedMaterial = val;
			if ((Object)(object)prefab.GetComponentInChildren<Collider>(true) == (Object)null)
			{
				BoxCollider obj = prefab.AddComponent<BoxCollider>();
				obj.size = new Vector3(part.Size, 0.03f, part.Size);
				obj.center = new Vector3(0f, 0.015f, 0f);
			}
		}

		private static Mesh BuildQuad(float size, string name)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0036: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			float num = size / 2f;
			Mesh val = new Mesh
			{
				name = "q8pm_" + name + "_quad"
			};
			val.vertices = (Vector3[])(object)new Vector3[4]
			{
				new Vector3(0f - num, 0f - num, 0f),
				new Vector3(0f - num, num, 0f),
				new Vector3(num, 0f - num, 0f),
				new Vector3(num, num, 0f)
			};
			val.normals = (Vector3[])(object)new Vector3[4]
			{
				Vector3.back,
				Vector3.back,
				Vector3.back,
				Vector3.back
			};
			val.uv = (Vector2[])(object)new Vector2[4]
			{
				new Vector2(0f, 0f),
				new Vector2(0f, 1f),
				new Vector2(1f, 0f),
				new Vector2(1f, 1f)
			};
			val.triangles = new int[6] { 0, 1, 2, 2, 1, 3 };
			val.RecalculateBounds();
			return val;
		}

		private static Sprite LoadSprite(string resourceName)
		{
			//IL_0021: 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)
			Texture2D val = MapItem.LoadTexture(resourceName, repeat: false);
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
		}
	}
	internal static class CompassMap
	{
		private const float CheckEvery = 0.5f;

		private const float BaseSize = 150f;

		private const float KeyCapBorder = 20f;

		private static readonly NeedleSwing Swing = new NeedleSwing();

		private static MapCompassView.Parts parts;

		private static RectTransform root;

		private static MapKeyHint hint;

		private static string language;

		private static float checkAt;

		private static bool carried;

		private static bool wasOpen;

		private static bool compassShown;

		private static bool hintStale;

		private static bool hintFaulted;

		private static bool faulted;

		internal static void Reset()
		{
			faulted = false;
			hintFaulted = false;
			carried = false;
			wasOpen = false;
			checkAt = 0f;
			Drop();
		}

		internal static void Tick()
		{
			if (faulted)
			{
				return;
			}
			try
			{
				TickCore();
			}
			catch (Exception ex)
			{
				faulted = true;
				Hide();
				ParchmentMapPlugin.Log.LogError((object)("Compass on the map is switched off until you re-enter the world: " + ex));
			}
		}

		private static void TickCore()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Invalid comparison between Unknown and I4
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			Minimap instance = Minimap.instance;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)instance == (Object)null || (Object)(object)instance.m_largeRoot == (Object)null || (int)instance.m_mode != 2)
			{
				wasOpen = false;
				Hide();
				return;
			}
			if (!wasOpen || Time.time >= checkAt)
			{
				checkAt = Time.time + 0.5f;
				carried = CompassItem.InInventory(localPlayer);
				if ((Object)(object)root != (Object)null && Language() != language)
				{
					Drop();
				}
			}
			wasOpen = true;
			if (!carried)
			{
				Hide();
				return;
			}
			if ((Object)(object)root == (Object)null)
			{
				Build(instance);
			}
			if (Keys.Pressed(ParchmentMapPlugin.CompassMapKey.Value) && !Keys.Typing())
			{
				ParchmentMapPlugin.CompassOnMap.Value = !ParchmentMapPlugin.CompassOnMap.Value;
			}
			bool value = ParchmentMapPlugin.CompassOnMap.Value;
			float target = NeedleSwing.Heading(localPlayer);
			bool num = !((Component)root).gameObject.activeSelf;
			if (num)
			{
				((Transform)root).SetAsLastSibling();
				((Component)root).gameObject.SetActive(true);
			}
			if (num || value != compassShown)
			{
				compassShown = value;
				MapCompassView.Show(parts, value);
				if (value)
				{
					Swing.Kick(target);
				}
				hintStale = true;
			}
			if (value)
			{
				MapCompassView.Pose(parts, Swing.Step(target, Time.deltaTime));
			}
			TickHint(instance, value);
		}

		private static void TickHint(Minimap minimap, bool shown)
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Invalid comparison between Unknown and I4
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			if (hintFaulted)
			{
				return;
			}
			try
			{
				if (hint == null || !hint.Alive)
				{
					hint = MapKeyHint.Create(minimap.m_largeRoot.transform, LoadSprite("key_cap.png", 20f));
					if (hint == null)
					{
						hintFaulted = true;
						ParchmentMapPlugin.Log.LogInfo((object)"The map has no key hint row to add the compass key to; the key itself works.");
						return;
					}
					hintStale = true;
				}
				if (hintStale)
				{
					hintStale = false;
					KeyboardShortcut value = ParchmentMapPlugin.CompassMapKey.Value;
					hint.Set(Localization.instance.Localize(shown ? "$q8pm_hint_compass_hide" : "$q8pm_hint_compass_show"), KeyLabel.Of(((KeyboardShortcut)(ref value)).MainKey, ((KeyboardShortcut)(ref value)).Modifiers));
				}
				MapKeyHint mapKeyHint = hint;
				KeyboardShortcut value2 = ParchmentMapPlugin.CompassMapKey.Value;
				mapKeyHint.Show((int)((KeyboardShortcut)(ref value2)).MainKey > 0);
			}
			catch (Exception ex)
			{
				hintFaulted = true;
				ParchmentMapPlugin.Log.LogWarning((object)("No key hint for the compass on the map until you re-enter the world: " + ex));
			}
		}

		internal static void ApplyPose()
		{
			if ((Object)(object)root != (Object)null)
			{
				SetPose(root);
			}
		}

		internal static void RefreshHint()
		{
			hintStale = true;
		}

		private static void Hide()
		{
			if ((Object)(object)root != (Object)null && ((Component)root).gameObject.activeSelf)
			{
				((Component)root).gameObject.SetActive(false);
			}
			if (hint != null)
			{
				hint.Show(visible: false);
			}
		}

		private static void Drop()
		{
			if ((Object)(object)root != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)root).gameObject);
			}
			root = null;
			parts = null;
			if (hint != null)
			{
				hint.Destroy();
			}
			hint = null;
		}

		private static string Language()
		{
			if (Localization.instance == null)
			{
				return null;
			}
			return Localization.instance.GetSelectedLanguage();
		}

		private static void Build(Minimap minimap)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			language = Language();
			Texture2D val = MapItem.LoadTexture((language == "Russian") ? "compass_letters_ru.png" : "compass_letters_en.png", repeat: false);
			Sprite[] array = (Sprite[])(object)new Sprite[4];
			int height = ((Texture)val).height;
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = Sprite.Create(val, new Rect((float)(i * height), 0f, (float)height, (float)height), new Vector2(0.5f, 0.5f), 100f);
			}
			parts = MapCompassView.Build(minimap.m_largeRoot.transform, LoadSprite("compass_rose.png"), LoadSprite("compass_rose_full.png"), array, LoadSprite("compass_dial.png"), LoadSprite("compass_needle.png"));
			root = parts.Root;
			((Component)root).gameObject.SetActive(false);
			RectTransform obj = root;
			RectTransform obj2 = root;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0f, 1f);
			obj2.anchorMax = val2;
			obj.anchorMin = val2;
			root.pivot = new Vector2(0f, 1f);
			SetPose(root);
		}

		private static void SetPose(RectTransform rect)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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)
			//IL_003f: 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)
			float num = 315f * Mathf.Clamp(ParchmentMapPlugin.CompassScale.Value, 0.2f, 4f);
			rect.sizeDelta = new Vector2(num, num);
			Vector2 value = ParchmentMapPlugin.CompassPosition.Value;
			rect.anchoredPosition = new Vector2(value.x, 0f - value.y);
		}

		internal static Sprite LoadSprite(string resourceName)
		{
			//IL_0021: 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)
			Texture2D val = MapItem.LoadTexture(resourceName, repeat: false);
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
		}

		private static Sprite LoadSprite(string resourceName, float border)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = MapItem.LoadTexture(resourceName, repeat: false);
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, new Vector4(border, border, border, border));
		}
	}
	internal static class CompassSlot
	{
		private static readonly FieldRef<InventoryGrid, List<InventoryElement>> ElementsRef = AccessTools.FieldRefAccess<InventoryGrid, List<InventoryElement>>("m_elements");

		private static readonly FieldInfo BarElementsField = AccessTools.Field(typeof(HotkeyBar), "m_elements");

		private static readonly FieldInfo BarIconField = AccessTools.Field(AccessTools.Inner(typeof(HotkeyBar), "ElementData"), "m_icon");

		private static readonly FieldRef<HotkeyBar, List<ItemData>> BarItemsRef = AccessTools.FieldRefAccess<HotkeyBar, List<ItemData>>("m_items");

		private static readonly NeedleSwing BagSwing = new NeedleSwing();

		private static readonly NeedleSwing BarSwing = new NeedleSwing();

		private static readonly HashSet<int> CompassCells = new HashSet<int>();

		private static readonly Dictionary<HotkeyBar, List<Transform>> BarNeedles = new Dictionary<HotkeyBar, List<Transform>>();

		private static readonly List<HotkeyBar> GoneBars = new List<HotkeyBar>();

		private static Sprite dial;

		private static Sprite needle;

		private static Sprite shadow;

		private static int bagFrame = -10;

		private static float barAngle;

		private static bool barKick;

		private static bool faulted;

		internal static void Reset()
		{
			faulted = false;
			bagFrame = -10;
			barKick = false;
			BarNeedles.Clear();
		}

		internal static void AfterBag(InventoryGrid grid, Inventory inventory, Player player)
		{
			if (faulted || (Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || inventory == null)
			{
				return;
			}
			try
			{
				List<InventoryElement> list = ElementsRef.Invoke(grid);
				if (list == null)
				{
					return;
				}
				int width = inventory.GetWidth();
				CompassCells.Clear();
				foreach (ItemData allItem in inventory.GetAllItems())
				{
					if (CompassItem.IsCompass(allItem))
					{
						CompassCells.Add(allItem.m_gridPos.y * width + allItem.m_gridPos.x);
					}
				}
				float target = NeedleSwing.Heading(player);
				if (Time.frameCount - bagFrame > 2)
				{
					BagSwing.Kick(target);
				}
				bagFrame = Time.frameCount;
				float angle = BagSwing.Step(target, Time.deltaTime);
				for (int i = 0; i < list.Count; i++)
				{
					InventoryElement val = list[i];
					if ((Object)(object)val != (Object)null && (Object)(object)val.m_icon != (Object)null)
					{
						Apply(val.m_icon, val.m_used && CompassCells.Contains(i), angle);
					}
				}
			}
			catch (Exception e)
			{
				Fail(e);
			}
		}

		internal static void AfterHotbar(HotkeyBar bar, Player player)
		{
			if (faulted || (Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			try
			{
				IList list = BarElementsField.GetValue(bar) as IList;
				List<ItemData> list2 = BarItemsRef.Invoke(bar);
				if (list == null || list2 == null)
				{
					return;
				}
				CompassCells.Clear();
				foreach (ItemData item in list2)
				{
					if (CompassItem.IsCompass(item))
					{
						CompassCells.Add(item.m_gridPos.x);
					}
				}
				if (!BarNeedles.TryGetValue(bar, out var value))
				{
					value = new List<Transform>();
					BarNeedles[bar] = value;
				}
				value.Clear();
				for (int i = 0; i < list.Count; i++)
				{
					object? value2 = BarIconField.GetValue(list[i]);
					Image val = (Image)((value2 is Image) ? value2 : null);
					if (!((Object)(object)val == (Object)null))
					{
						bool flag = CompassCells.Contains(i);
						if (Apply(val, flag, barAngle))
						{
							barKick = true;
						}
						if (flag)
						{
							value.Add(((Component)val).transform.Find("q8pm_needle"));
						}
					}
				}
			}
			catch (Exception e)
			{
				Fail(e);
			}
		}

		internal static void TickHotbar()
		{
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (faulted || (Object)(object)localPlayer == (Object)null || BarNeedles.Count == 0)
			{
				return;
			}
			try
			{
				float target = NeedleSwing.Heading(localPlayer);
				if (barKick)
				{
					BarSwing.Kick(target);
					barKick = false;
				}
				barAngle = BarSwing.Step(target, Time.deltaTime);
				GoneBars.Clear();
				foreach (KeyValuePair<HotkeyBar, List<Transform>> barNeedle in BarNeedles)
				{
					if ((Object)(object)barNeedle.Key == (Object)null)
					{
						GoneBars.Add(barNeedle.Key);
						continue;
					}
					foreach (Transform item in barNeedle.Value)
					{
						if ((Object)(object)item != (Object)null && ((Component)item).gameObject.activeInHierarchy)
						{
							Image component = ((Component)item.parent).GetComponent<Image>();
							SlotNeedle.Turn(item, barAngle, ((Object)(object)component != (Object)null) ? ((Graphic)component).color : Color.white);
						}
					}
				}
				foreach (HotkeyBar goneBar in GoneBars)
				{
					BarNeedles.Remove(goneBar);
				}
			}
			catch (Exception e)
			{
				Fail(e);
			}
		}

		private static bool Apply(Image icon, bool compass, float angle)
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ((Component)icon).transform.Find("q8pm_needle");
			if (!compass)
			{
				if ((Object)(object)val != (Object)null && ((Component)val).gameObject.activeSelf)
				{
					((Component)val).gameObject.SetActive(false);
				}
				return false;
			}
			bool result = false;
			if ((Object)(object)val == (Object)null)
			{
				if ((Object)(object)dial == (Object)null)
				{
					dial = CompassMap.LoadSprite("compass_icon_dial.png");
					needle = CompassMap.LoadSprite("compass_needle.png");
					shadow = CompassMap.LoadSprite("compass_needle_shadow.png");
				}
				val = (Transform)(object)SlotNeedle.Build(((Graphic)icon).rectTransform, needle, shadow);
				result = true;
			}
			icon.sprite = dial;
			if (!((Component)val).gameObject.activeSelf)
			{
				((Component)val).gameObject.SetActive(true);
				result = true;
			}
			SlotNeedle.Turn(val, angle, ((Graphic)icon).color);
			return result;
		}

		private static void Fail(Exception e)
		{
			faulted = true;
			ParchmentMapPlugin.Log.LogError((object)("Compass needle in the icons is switched off until you re-enter the world: " + e));
		}
	}
	internal static class Journal
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static CoroutineHandler <0>__OnServer;

			public static CoroutineHandler <1>__OnClient;
		}

		private const string RpcName = "q8pm_journal";

		private const string Folder = "parchmentmap";

		private const byte Version = 1;

		private static CustomRPC rpc;

		private static StreamWriter writer;

		private static string writerPath;

		private static bool failed;

		private static bool sendFailed;

		private static readonly HashSet<long> joined = new HashSet<long>();

		internal static bool Enabled => ParchmentMapPlugin.ServerJournal.Value;

		internal static void Register()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//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_0040: Expected O, but got Unknown
			NetworkManager instance = NetworkManager.Instance;
			object obj = <>O.<0>__OnServer;
			if (obj == null)
			{
				CoroutineHandler val = OnServer;
				<>O.<0>__OnServer = val;
				obj = (object)val;
			}
			object obj2 = <>O.<1>__OnClient;
			if (obj2 == null)
			{
				CoroutineHandler val2 = OnClient;
				<>O.<1>__OnClient = val2;
				obj2 = (object)val2;
			}
			rpc = instance.AddRPC("q8pm_journal", (CoroutineHandler)obj, (CoroutineHandler)obj2);
		}

		internal static void Close()
		{
			joined.Clear();
			failed = false;
			if (writer != null)
			{
				try
				{
					writer.Dispose();
				}
				catch (Exception)
				{
				}
				writer = null;
				writerPath = null;
			}
		}

		internal static void Report(string kind, string text)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (!Enabled || (Object)(object)ZNet.instance == (Object)null)
			{
				return;
			}
			try
			{
				if (ZNet.instance.IsServer())
				{
					Player localPlayer = Player.m_localPlayer;
					Write(kind, Who(((Object)(object)localPlayer != (Object)null) ? localPlayer.GetPlayerName() : "?", "local", ((Object)(object)localPlayer != (Object)null) ? localPlayer.GetPlayerID() : 0, ((Object)(object)localPlayer != (Object)null) ? ((Component)localPlayer).transform.position : Vector3.zero), text);
					return;
				}
				ZNetPeer serverPeer = ZNet.instance.GetServerPeer();
				if (rpc != null && serverPeer != null)
				{
					ZPackage val = new ZPackage();
					val.Write((byte)1);
					val.Write(kind);
					val.Write(JournalText.Clean(text));
					rpc.SendPackage(serverPeer.m_uid, val);
				}
			}
			catch (Exception ex)
			{
				if (!sendFailed)
				{
					sendFailed = true;
					ParchmentMapPlugin.Log.LogWarning((object)("Could not send a journal record to the server: " + ex.Message));
				}
			}
		}

		private static IEnumerator OnClient(long sender, ZPackage package)
		{
			yield break;
		}

		private static IEnumerator OnServer(long sender, ZPackage package)
		{
			Receive(sender, package);
			yield break;
		}

		private static void Receive(long sender, ZPackage package)
		{
			try
			{
				if (Enabled && !((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && package.ReadByte() == 1)
				{
					string kind = package.ReadString();
					string text = package.ReadString();
					if (JournalText.IsKind(kind))
					{
						ZNetPeer peer = ZNet.instance.GetPeer(sender);
						Write(kind, (peer != null) ? Who(peer) : ("peer=" + sender), text);
					}
				}
			}
			catch (Exception ex)
			{
				ParchmentMapPlugin.Log.LogWarning((object)("Could not read a journal record: " + ex.Message));
			}
		}

		internal static void OnCharacter(ZNetPeer peer, ZDOID character)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!Enabled || peer == null)
				{
					return;
				}
				if (character == ZDOID.None)
				{
					if (joined.Contains(peer.m_uid))
					{
						Write("DESPAWN", Who(peer), "");
					}
				}
				else
				{
					Write(joined.Add(peer.m_uid) ? "JOIN" : "RESPAWN", Who(peer), "");
				}
			}
			catch (Exception ex)
			{
				ParchmentMapPlugin.Log.LogWarning((object)("Journal: a player's arrival is not recorded: " + ex.Message));
			}
		}

		internal static void OnDisconnect(ZNetPeer peer)
		{
			try
			{
				if (peer != null && joined.Remove(peer.m_uid) && Enabled)
				{
					Write("LEAVE", Who(peer), "");
				}
			}
			catch (Exception ex)
			{
				ParchmentMapPlugin.Log.LogWarning((object)("Journal: a player's leaving is not recorded: " + ex.Message));
			}
		}

		internal static void Server(string kind, string text)
		{
			if (Enabled)
			{
				Write(kind, "server", text);
			}
		}

		internal static string NameOf(long peerUid)
		{
			return (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetPeer(peerUid) : null)?.m_playerName;
		}

		internal static string NameOfPlayer(long playerId)
		{
			if ((Object)(object)ZNet.instance == (Object)null || playerId == 0L)
			{
				return null;
			}
			foreach (ZNetPeer peer in ZNet.instance.GetPeers())
			{
				if (peer.m_playerID == playerId)
				{
					return peer.m_playerName;
				}
			}
			return null;
		}

		private static string Who(ZNetPeer peer)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			string host = "?";
			try
			{
				host = ((peer.m_socket != null) ? peer.m_socket.GetHostName() : "?");
			}
			catch (Exception)
			{
			}
			return Who(peer.m_playerName, host, peer.m_playerID, peer.m_refPos);
		}

		private static string Who(string name, string host, long playerId, Vector3 at)
		{
			//IL_004d: 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)
			return "player=" + JournalText.Quote(name) + " host=" + JournalText.Clean(host).Replace(' ', '_') + " pid=" + playerId + " at=" + JournalText.Point(at.x, at.z);
		}

		private static void Write(string kind, string who, string text)
		{
			if (failed || (Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || ZNet.World == null)
			{
				return;
			}
			try
			{
				DateTime now = DateTime.Now;
				string text2 = Path.Combine(Utils.GetSaveDataPath((FileSource)2), "parchmentmap");
				string text3 = Path.Combine(text2, SafeName(ZNet.instance.GetWorldName()) + "." + ZNet.instance.GetWorldUID().ToString("X") + ".journal-" + now.ToString("yyyy-MM") + ".log");
				if (writer == null || text3 != writerPath)
				{
					if (writer != null)
					{
						writer.Dispose();
						writer = null;
					}
					Directory.CreateDirectory(text2);
					writer = new StreamWriter(new FileStream(text3, FileMode.Append, FileAccess.Write, FileShare.Read), new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
					writer.AutoFlush = true;
					writerPath = text3;
					ParchmentMapPlugin.Log.LogInfo((object)("Journal: " + text3));
					writer.WriteLine(JournalText.Line(now, "START", "server", "world=" + JournalText.Quote(ZNet.instance.GetWorldName()) + " mod=0.6.8 dedicated=" + (ZNet.instance.IsDedicated() ? 1 : 0) + " utc_offset=" + TimeZoneInfo.Local.GetUtcOffset(now).TotalHours.ToString("+0.#;-0.#", CultureInfo.InvariantCulture)));
				}
				writer.WriteLine(JournalText.Line(now, kind, who, text));
			}
			catch (Exception ex)
			{
				failed = true;
				ParchmentMapPlugin.Log.LogWarning((object)("The journal is off until the world is restarted: " + ex.Message));
			}
		}

		private static string SafeName(string name)
		{
			StringBuilder stringBuilder = new StringBuilder();
			string text = name ?? "";
			foreach (char c in text)
			{
				stringBuilder.Append((Array.IndexOf(Path.GetInvalidFileNameChars(), c) >= 0) ? '_' : c);
			}
			if (stringBuilder.Length <= 0)
			{
				return "world";
			}
			return stringBuilder.ToString();
		}
	}
	internal static class TableWatch
	{
		private sealed class Seen
		{
			public uint Revision;

			public int Cells;

			public int Marks;

			public Vector3 Pos;

			public bool Listed;
		}

		private const string TablePrefab = "piece_cartographytable";

		private const float ScanEvery = 30f;

		private const float FirstScanAfter = 10f;

		private static readonly Dictionary<ZDOID, Seen> tables = new Dictionary<ZDOID, Seen>();

		private static readonly List<ZDO> found = new List<ZDO>();

		private static readonly int RecordsKey = StringExtensionMethods.GetStableHashCode("q8pm_table");

		private static readonly int CreatorKey = StringExtensionMethods.GetStableHashCode("creator");

		private static int index;

		private static bool scanning;

		private static bool firstPass = true;

		private static float nextScan;

		private static bool faulted;

		internal static void Reset()
		{
			tables.Clear();
			found.Clear();
			scanning = false;
			firstPass = true;
			nextScan = 0f;
			faulted = false;
		}

		internal static void Tick()
		{
			if (faulted || !Journal.Enabled || (Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || ZDOMan.instance == null || ZNet.World == null)
			{
				return;
			}
			try
			{
				if (!scanning)
				{
					if (nextScan == 0f)
					{
						nextScan = Time.unscaledTime + 10f;
					}
					if (Time.unscaledTime < nextScan)
					{
						return;
					}
					scanning = true;
					index = 0;
					found.Clear();
				}
				if (ZDOMan.instance.GetAllZDOsWithPrefabIterative("piece_cartographytable", found, ref index))
				{
					scanning = false;
					nextScan = Time.unscaledTime + 30f;
					Compare();
					if (firstPass)
					{
						Journal.Server("TABLES", "count=" + tables.Count);
					}
					firstPass = false;
				}
			}
			catch (Exception ex)
			{
				faulted = true;
				ParchmentMapPlugin.Log.LogWarning((object)("Cartography tables are no longer watched for the journal: " + ex.Message));
			}
		}

		private unsafe static void Compare()
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_0359: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			foreach (Seen value2 in tables.Values)
			{
				value2.Listed = false;
			}
			foreach (ZDO item in found)
			{
				if (item == null || !item.IsValid())
				{
					continue;
				}
				Seen value;
				bool flag = !tables.TryGetValue(item.m_uid, out value);
				if (flag)
				{
					value = new Seen
					{
						Revision = uint.MaxValue
					};
					tables[item.m_uid] = value;
				}
				if (value.Listed)
				{
					continue;
				}
				value.Listed = true;
				value.Pos = item.GetPosition();
				if (!flag && item.DataRevision == value.Revision)
				{
					continue;
				}
				value.Revision = item.DataRevision;
				int num = 0;
				int num2 = 0;
				byte[] byteArray = item.GetByteArray(RecordsKey, (byte[])null);
				if (byteArray != null)
				{
					string error;
					TableData tableData = TableData.FromBytes(byteArray, out error);
					if (tableData != null)
					{
						num = MapBits.Count(tableData.Explored);
						num2 = tableData.Pins.Count;
					}
				}
				string text = JournalText.Point(value.Pos.x, value.Pos.z);
				ZDOID uid = item.m_uid;
				string text2 = "table=" + text + " zdo=" + ((object)(*(ZDOID*)(&uid))/*cast due to .constrained prefix*/).ToString();
				if (flag)
				{
					long playerId = item.GetLong(CreatorKey, 0L);
					string text3 = Journal.NameOfPlayer(playerId);
					Journal.Server(firstPass ? "TABLE-STATE" : "TABLE-NEW", text2 + " cells=" + num + " marks=" + num2 + " built_by=" + playerId + ((text3 != null) ? (" builder=" + JournalText.Quote(text3)) : ""));
				}
				else if (num != value.Cells || num2 != value.Marks)
				{
					string text4 = Journal.NameOf(item.GetOwner());
					Journal.Server("TABLE-CHANGED", text2 + " cells=" + value.Cells + "->" + num + " marks=" + value.Marks + "->" + num2 + " last_writer=" + ((text4 != null) ? JournalText.Quote(text4) : "?"));
				}
				value.Cells = num;
				value.Marks = num2;
			}
			List<ZDOID> list = null;
			foreach (KeyValuePair<ZDOID, Seen> table in tables)
			{
				if (!table.Value.Listed)
				{
					(list ?? (list = new List<ZDOID>())).Add(table.Key);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (ZDOID item2 in list)
			{
				Seen seen = tables[item2];
				string[] obj = new string[8]
				{
					"table=",
					JournalText.Point(seen.Pos.x, seen.Pos.z),
					" zdo=",
					null,
					null,
					null,
					null,
					null
				};
				ZDOID uid = item2;
				obj[3] = ((object)(*(ZDOID*)(&uid))/*cast due to .constrained prefix*/).ToString();
				obj[4] = " cells=";
				obj[5] = seen.Cells.ToString();
				obj[6] = " marks=";
				obj[7] = seen.Marks.ToString();
				Journal.Server("TABLE-GONE", string.Concat(obj));
				tables.Remove(item2);
			}
		}
	}
	internal static class JournalText
	{
		public const int MaxText = 4000;

		public const int MaxKind = 16;

		public static bool IsKind(string kind)
		{
			if (string.IsNullOrEmpty(kind) || kind.Length > 16)
			{
				return false;
			}
			foreach (char c in kind)
			{
				if ((c < 'A' || c > 'Z') && c != '-')
				{
					return false;
				}
			}
			return true;
		}

		public static string Clean(string text)
		{
			if (string.IsNullOrEmpty(text))
			{
				return "";
			}
			StringBuilder stringBuilder = new StringBuilder(Math.Min(text.Length, 4000));
			foreach (char c in text)
			{
				if (stringBuilder.Length >= 4000)
				{
					break;
				}
				stringBuilder.Append(char.IsControl(c) ? ' ' : c);
			}
			return stringBuilder.ToString();
		}

		public static string Quote(string value)
		{
			return "\"" + Clean(value ?? "").Replace('"', '\'') + "\"";
		}

		public static string Point(float x, float z)
		{
			return "(" + Math.Round(x).ToString(CultureInfo.InvariantCulture) + "," + Math.Round(z).ToString(CultureInfo.InvariantCulture) + ")";
		}

		public static string Line(DateTime time, string kind, string who, string text)
		{
			return time.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture) + "\t" + kind + "\t" + who + "\t" + Clean(text);
		}

		public static string Area(string prefix, BitArray cells, int size, float pixelSize)
		{
			byte[] array = MapBits.Pack(cells);
			int num = int.MaxValue;
			int num2 = int.MinValue;
			int num3 = int.MaxValue;
			int num4 = int.MinValue;
			long num5 = 0L;
			long num6 = 0L;
			int num7 = 0;
			for (int i = 0; i < array.Length; i++)
			{
				int num8 = array[i];
				if (num8 == 0)
				{
					continue;
				}
				for (int j = 0; j < 8; j++)
				{
					if ((num8 & (1 << j)) != 0)
					{
						int num9 = i * 8 + j;
						int num10 = num9 % size;
						int num11 = num9 / size;
						num = Math.Min(num, num10);
						num2 = Math.Max(num2, num10);
						num3 = Math.Min(num3, num11);
						num4 = Math.Max(num4, num11);
						num5 += num10;
						num6 += num11;
						num7++;
					}
				}
			}
			if (num7 == 0)
			{
				return prefix + "_cells=0";
			}
			float half = size / 2;
			Func<double, string> func = (double cell) => Math.Round((cell - (double)half) * (double)pixelSize).ToString(CultureInfo.InvariantCulture);
			return prefix + "_cells=" + num7.ToString(CultureInfo.InvariantCulture) + " " + prefix + "_area=(" + func(num) + ".." + func(num2) + "," + func(num3) + ".." + func(num4) + ") " + prefix + "_centre=(" + func((double)num5 / (double)num7) + "," + func((double)num6 / (double)num7) + ")";
		}
	}
	internal sealed class ExploreBatch
	{
		public const int MaxZones = 80;

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

		public int Cells { get; private set; }

		public int Zones => zones.Count;

		public void Add(int x, int y, int size, float pixelSize)
		{
			float num = size / 2;
			int zoneX = ZoneGrid.ZoneOf(((float)x - num) * pixelSize);
			int zoneY = ZoneGrid.ZoneOf(((float)y - num) * pixelSize);
			if (ZoneRevs.InRange(zoneX, zoneY))
			{
				int key = ZoneRevs.Key(zoneX, zoneY);
				zones.TryGetValue(key, out var value);
				zones[key] = value + 1;
				Cells++;
			}
		}

		public string Flush()
		{
			List<int> list = new List<int>(zones.Keys);
			list.Sort();
			StringBuilder stringBuilder = new StringBuilder();
			int num = 0;
			int num2 = 0;
			foreach (int item in list)
			{
				if (num2 >= 80)
				{
					break;
				}
				ZoneRevs.Split(item, out var zoneX, out var zoneY);
				if (num2 > 0)
				{
					stringBuilder.Append(';');
				}
				stringBuilder.Append(JournalText.Point((float)zoneX * 64f, (float)zoneY * 64f)).Append('+').Append(zones[item].ToString(CultureInfo.InvariantCulture));
				num += zones[item];
				zones.Remove(item);
				num2++;
			}
			Cells -= num;
			return "cells=+" + num.ToString(CultureInfo.InvariantCulture) + " zones=" + stringBuilder;
		}
	}
	internal static class KeyLabel
	{
		internal static string Of(KeyCode key, IEnumerable<KeyCode> modifiers)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			StringBuilder stringBuilder = new StringBuilder();
			if (modifiers != null)
			{
				foreach (KeyCode modifier in modifiers)
				{
					stringBuilder.Append(One(modifier)).Append('+');
				}
			}
			return stringBuilder.Append(One(key)).ToString();
		}

		private unsafe static string One(KeyCode key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Invalid comparison between Unknown and I4
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected I4, but got Unknown
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Invalid comparison between Unknown and I4
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Invalid comparison between Unknown and I4
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected I4, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Invalid comparison between Unknown and I4
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Invalid comparison between Unknown and I4
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected I4, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Invalid comparison between Unknown and I4
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Expected I4, but got Unknown
			//IL_00a7: 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_00c8: Expected I4, but got Unknown
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Invalid comparison between Unknown and I4
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Invalid comparison between Unknown and I4
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected I4, but got Unknown
			if ((int)key >= 48 && (int)key <= 57)
			{
				return (key - 48).ToString();
			}
			if ((int)key >= 256 && (int)key <= 265)
			{
				return "Num" + (key - 256);
			}
			if ((int)key <= 59)
			{
				if ((int)key <= 27)
				{
					if ((int)key == 13)
					{
						return "Enter";
					}
					if ((int)key == 27)
					{
						return "Esc";
					}
				}
				else
				{
					switch (key - 39)
					{
					default:
						if ((int)key != 59)
						{
							break;
						}
						return ";";
					case 6:
						return "-";
					case 0:
						return "'";
					case 5:
						return ",";
					case 7:
						return ".";
					case 8:
						return "/";
					case 1:
					case 2:
					case 3:
					case 4:
						break;
					}
				}
			}
			else if ((int)key <= 96)
			{
				if ((int)key == 61)
				{
					return "=";
				}
				switch (key - 91)
				{
				case 5:
					return "`";
				case 0:
					return "[";
				case 2:
					return "]";
				case 1:
					return "\\";
				}
			}
			else
			{
				if ((int)key == 127)
				{
					return "Del";
				}
				switch (key - 273)
				{
				default:
					switch (key - 303)
					{
					case 2:
					case 3:
						return "Ctrl";
					case 4:
					case 5:
						return "Alt";
					case 0:
					case 1:
						return "Shift";
					}
					break;
				case 4:
					return "Ins";
				case 7:
					return "PgUp";
				case 8:
					return "PgDn";
				case 0:
					return "Up";
				case 1:
					return "Down";
				case 3:
					return "Left";
				case 2:
					return "Right";
				case 5:
				case 6:
					break;
				}
			}
			return ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString();
		}
	}
	internal static class Keys
	{
		internal static bool Pressed(KeyboardShortcut key)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if ((int)((KeyboardShortcut)(ref key)).MainKey == 0 || !ZInput.GetKeyDown(((KeyboardShortcut)(ref key)).MainKey, false))
			{
				return false;
			}
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref key)).Modifiers)
			{
				if (!ZInput.GetKey(modifier, false))
				{
					return false;
				}
			}
			return true;
		}

		internal static bool Typing()
		{
			if ((!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !Console.IsVisible() && !TextInput.IsVisible() && !Menu.IsVisible() && !Minimap.InTextInput())
			{
				return ZInput.VirtualKeyboardOpen;
			}
			return true;
		}
	}
	internal static class MapCompassView
	{
		internal sealed class Parts
		{
			internal RectTransform Root;

			internal RectTransform Needle;

			internal RectTransform Case;

			internal Image Rose;

			internal Sprite RoseUnder;

			internal Sprite RoseWhole;
		}

		internal const float RoseSpan = 2.1f;

		private const float LetterRadius = 0.4364f;

		private const float LetterCell = 0.125f;

		internal static Parts Build(Transform parent, Sprite rose, Sprite roseWhole, Sprite[] letters, Sprite dial, Sprite needle)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("q8pm_compass", new Type[1] { typeof(RectTransform) });
			Parts parts = new Parts
			{
				Root = val.GetComponent<RectTransform>(),
				RoseUnder = rose,
				RoseWhole = roseWhole
			};
			((Transform)parts.Root).SetParent(parent, false);
			parts.Rose = ((Component)Layer(parts.Root, "rose", rose, 1f)).GetComponent<Image>();
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.0625f, 0.0625f);
			Vector2 val3 = default(Vector2);
			for (int i = 0; i < letters.Length; i++)
			{
				RectTransform obj = Layer(parts.Root, "letter" + i, letters[i], 0.125f);
				float num = -90f * (float)i * ((float)Math.PI / 180f);
				((Vector2)(ref val3))..ctor(0.5f - Mathf.Sin(num) * 0.4364f, 0.5f + Mathf.Cos(num) * 0.4364f);
				obj.anchorMin = val3 - val2;
				obj.anchorMax = val3 + val2;
			}
			parts.Case = Layer(parts.Root, "case", dial, 0.4761905f);
			parts.Needle = Layer(parts.Root, "needle", needle, 0.4761905f);
			return parts;
		}

		internal static void Pose(Parts parts, float heading)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			((Transform)parts.Needle).localRotation = Quaternion.Euler(0f, 0f, 0f - heading);
		}

		internal static void Show(Parts parts, bool compass)
		{
			parts.Rose.sprite = (compass ? parts.RoseUnder : parts.RoseWhole);
			((Component)parts.Case).gameObject.SetActive(compass);
			((Component)parts.Needle).gameObject.SetActive(compass);
		}

		private static RectTransform Layer(RectTransform parent, string name, Sprite sprite, float share)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			});
			RectTransform component = val.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)parent, false);
			float num = (1f - share) / 2f;
			component.anchorMin = new Vector2(num, num);
			component.anchorMax = new Vector2(1f - num, 1f - num);
			Vector2 offsetMin = (component.offsetMax = Vector2.zero);
			component.offsetMin = offsetMin;
			Image component2 = val.GetComponent<Image>();
			component2.sprite = sprite;
			((Graphic)component2).raycastTarget = false;
			return component;
		}
	}
	internal sealed class PinRecord
	{
		public string Name = "";

		public Vector3 Pos;

		public int Type;

		public bool Checked;

		public PinRecord Clone()
		{
			//IL_0013: 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)
			return new PinRecord
			{
				Name = Name,
				Pos = Pos,
				Type = Type,
				Checked = Checked
			};
		}
	}
	internal static class MapBits
	{
		public static byte[] Pack(BitArray bits)
		{
			byte[] array = new byte[(bits.Length + 7) / 8];
			bits.CopyTo(array, 0);
			return array;
		}

		public static BitArray Unpack(byte[] bytes, int bitCount)
		{
			BitArray bitArray = new BitArray(bytes);
			if (bitArray.Length != bitCount)
			{
				bitArray.Length = bitCount;
			}
			return bitArray;
		}

		public static int Count(BitArray bits)
		{
			int[] array = new int[(bits.Length + 31) / 32];
			bits.CopyTo(array, 0);
			int num = 0;
			for (int i = 0; i < array.Length; i++)
			{
				uint num2 = (uint)array[i];
				num2 -= (num2 >> 1) & 0x55555555;
				num2 = (num2 & 0x33333333) + ((num2 >> 2) & 0x33333333);
				num += (int)(((num2 + (num2 >> 4)) & 0xF0F0F0F) * 16843009 >> 24);
			}
			return num;
		}

		public static bool Any(BitArray bits)
		{
			int[] array = new int[(bits.Length + 31) / 32];
			bits.CopyTo(array, 0);
			for (int i = 0; i < array.Length; i++)
			{
				if (array[i] != 0)
				{
					return true;
				}
			}
			return false;
		}

		public static bool Centroid(BitArray bits, int size, out float x, out float y)
		{
			byte[] array = Pack(bits);
			double num = 0.0;
			double num2 = 0.0;
			long num3 = 0L;
			for (int i = 0; i < array.Length; i++)
			{
				int num4 = array[i];
				if (num4 == 0)
				{
					continue;
				}
				for (int j = 0; j < 8; j++)
				{
					if ((num4 & (1 << j)) != 0)
					{
						int num5 = i * 8 + j;
						num += (double)(num5 % size);
						num2 += (double)(num5 / size);
						num3++;
					}
				}
			}
			x = ((num3 > 0) ? ((float)(num / (double)num3)) : 0f);
			y = ((num3 > 0) ? ((float)(num2 / (double)num3)) : 0f);
			return num3 > 0;
		}

		public static BitArray Added(BitArray before, BitArray after)
		{
			return new BitArray(after).And(new BitArray(before).Not());
		}

		public static byte[] Compress(byte[] raw)
		{
			using MemoryStream memoryStream = new MemoryStream();
			using (GZipStream gZipStream = new GZipStream(memoryStream, CompressionLevel.Optimal))
			{
				gZipStream.Write(raw, 0, raw.Length);
			}
			return memoryStream.ToArray();
		}

		public static byte[] Decompress(byte[] packed, int offset)
		{
			using MemoryStream stream = new MemoryStream(packed, offset, packed.Length - offset);
			using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress);
			using MemoryStream memoryStream = new MemoryStream();
			gZipStream.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}
	}
	internal static class PinMerge
	{
		public const float SameRadius = 1f;

		public const int MaxTombstones = 256;

		public static bool Near(Vector3 a, Vector3 b, float radius)
		{
			//IL_0000: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			float num = a.x - b.x;
			float num2 = a.z - b.z;
			return num * num + num2 * num2 < radius * radius;
		}

		public static int IndexNear(List<PinRecord> pins, Vector3 pos)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < pins.Count; i++)
			{
				if (Near(pins[i].Pos, pos, 1f))
				{
					return i;
				}
			}
			return -1;
		}

		public static bool IsBuried(List<Vector3> tombstones, Vector3 pos)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < tombstones.Count; i++)
			{
				if (Near(tombstones[i], pos, 1f))
				{
					return true;
				}
			}
			return false;
		}

		public static void Bury(List<Vector3> tombstones, Vector3 pos)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if (!IsBuried(tombstones, pos))
			{
				tombstones.Add(pos);
				if (tombstones.Count > 256)
				{
					tombstones.RemoveRange(0, tombstones.Count - 256);
				}
			}
		}

		public static void Unbury(List<Vector3> tombstones, Vector3 pos)
		{
			//IL_0007: 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)
			tombstones.RemoveAll((Vector3 t) => Near(t, pos, 1f));
		}

		public static List<PinRecord> FromTable(List<PinRecord> mapPins, List<Vector3> tombstones, List<PinRecord> tablePins)
		{
			//IL_0019: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			List<PinRecord> list = new List<PinRecord>();
			foreach (PinRecord tablePin in tablePins)
			{
				if (!IsBuried(tombstones, tablePin.Pos) && IndexNear(mapPins, tablePin.Pos) < 0 && IndexNear(list, tablePin.Pos) < 0)
				{
					list.Add(tablePin.Clone());
				}
			}
			return list;
		}

		public static void IntoTable(List<PinRecord> tablePins, List<PinRecord> mapPins, List<Vector3> tombstones)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			tablePins.RemoveAll((PinRecord p) => IsBuried(tombstones, p.Pos));
			foreach (PinRecord mapPin in mapPins)
			{
				int num = IndexNear(tablePins, mapPin.Pos);
				if (num >= 0)
				{
					tablePins[num] = mapPin.Clone();
				}
				else
				{
					tablePins.Add(mapPin.Clone());
				}
			}
		}
	}
	internal sealed class ZoneRevs
	{
		private const int Offset = 512;

		private const int Bits = 10;

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

		public int Count => revs.Count;

		public static bool InRange(int zoneX, int zoneY)
		{
			if (zoneX > -512 && zoneX < 512 && zoneY > -512)
			{
				return zoneY < 512;
			}
			return false;
		}

		public static int Key(int zoneX, int zoneY)
		{
			return (zoneY + 512 << 10) | (zoneX + 512);
		}

		public static void Split(int key, out int zoneX, out int zoneY)
		{
			zoneX = (key & 0x3FF) - 512;
			zoneY = (key >> 10) - 512;
		}

		public int Get(int zoneX, int zoneY)
		{
			if (!InRange(zoneX, zoneY) || !revs.TryGetValue(Key(zoneX, zoneY), out var value))
			{
				return 0;
			}
			return value;
		}

		public bool Raise(int zoneX, int zoneY, int rev)
		{
			if (InRange(zoneX, zoneY))
			{
				return RaiseKey(Key(zoneX, zoneY), rev);
			}
			return false;
		}

		public bool RaiseAll(ZoneRevs other)
		{
			bool flag = false;
			foreach (KeyValuePair<int, int> rev in other.revs)
			{
				flag |= RaiseKey(rev.Key, rev.Value);
			}
			return flag;
		}

		public int GetKey(int key)
		{
			if (!revs.TryGetValue(key, out var value))
			{
				return 0;
			}
			return value;
		}

		public bool RaiseKey(int key, int rev)
		{
			if (rev <= 0 || (revs.TryGetValue(key, out var value) && value >= rev))
			{
				return false;
			}
			revs[key] = rev;
			return true;
		}

		public void Clear()
		{
			revs.Clear();
		}

		public int CountAlsoIn(ZoneRevs other)
		{
			int num = 0;
			foreach (int key in revs.Keys)
			{
				num += (other.revs.ContainsKey(key) ? 1 : 0);
			}
			return num;
		}

		public ZoneRevs Clone()
		{
			ZoneRevs zoneRevs = new ZoneRevs();
			foreach (KeyValuePair<int, int> rev in revs)
			{
				zoneRevs.revs[rev.Key] = rev.Value;
			}
			return zoneRevs;
		}

		public void Write(BinaryWriter w)
		{
			List<int> list = new List<int>(revs.Keys);
			list.Sort();
			MapIO.WriteVar(w, list.Count);
			int num = 0;
			foreach (int item in list)
			{
				MapIO.WriteVar(w, item - num);
				MapIO.WriteVar(w, revs[item]);
				num = item;
			}
		}

		public static ZoneRevs Read(BinaryReader r)
		{
			ZoneRevs zoneRevs = new ZoneRevs();
			int num = MapIO.ReadVar(r);
			if (num > 1048576)
			{
				throw new InvalidDataException("zone snapshot list of " + num);
			}
			int num2 = 0;
			for (int i = 0; i < num; i++)
			{
				num2 += MapIO.ReadVar(r);
				int num3 = MapIO.ReadVar(r);
				if (num2 >= 1048576)
				{
					throw new InvalidDataException("zone snapshot list runs out of the world");
				}
				if (num3 > 0)
				{
					zoneRevs.revs[num2] = num3;
				}
			}
			return zoneRevs;
		}
	}
	internal static class ZoneGrid
	{
		public const float ZoneSize = 64f;

		public const float Overhang = 64f;

		public static int ZoneOf(float w)
		{
			return (int)Math.Floor(((double)w + 32.0) / 64.0);
		}

		public static List<int> Touching(float x, float z, float radius)
		{
			List<int> list = new List<int>();
			for (int i = ZoneOf(z - radius); i <= ZoneOf(z + radius); i++)
			{
				for (int j = ZoneOf(x - radius); j <= ZoneOf(x + radius); j++)
				{
					float num = Math.Max((float)j * 64f - 32f, Math.Min(x, (float)j * 64f + 32f));
					float num2 = Math.Max((float)i * 64f - 32f, Math.Min(z, (float)i * 64f + 32f));
					if ((num - x) * (num - x) + (num2 - z) * (num2 - z) <= radius * radius && ZoneRevs.InRange(j, i))
					{
						list.Add(ZoneRevs.Key(j, i));
					}
				}
			}
			return list;
		}

		public static List<int> WithoutRev(BitArray cells, int textureSize, float pixelSize, ZoneRevs revs)
		{
			HashSet<int> hashSet = new HashSet<int>();
			byte[] array = MapBits.Pack(cells);
			float num = textureSize / 2;
			int num2 = -1;
			for (int i = 0; i < array.Length; i++)
			{
				int num3 = array[i];
				if (num3 == 0)
				{
					continue;
				}
				for (int j = 0; j < 8; j++)
				{
					if ((num3 & (1 << j)) != 0)
					{
						int num4 = i * 8 + j;
						int zoneX = ZoneOf(((float)(num4 % textureSize) - num) * pixelSize);
						int zoneY = ZoneOf(((float)(num4 / textureSize) - num) * pixelSize);
						int num5 = ZoneRevs.Key(zoneX, zoneY);
						if (num5 != num2 && ZoneRevs.InRange(zoneX, zoneY))
						{
							num2 = num5;
							hashSet.Add(num5);
						}
					}
				}
			}
			HashSet<int> hashSet2 = new HashSet<int>();
			foreach (int item in hashSet)
			{
				ZoneRevs.Split(item, out var zoneX2, out var zoneY2);
				for (int k = -1; k <= 1; k++)
				{
					for (int l = -1; l <= 1; l++)
					{
						if (ZoneRevs.InRange(zoneX2 + l, zoneY2 + k) && revs.Get(zoneX2 + l, zoneY2 + k) == 0)
						{
							hashSet2.Add(ZoneRevs.Key(zoneX2 + l, zoneY2 + k));
						}
					}
				}
			}
			List<int> list = new List<int>(hashSet2);
			list.Sort();
			return list;
		}
	}
	internal sealed class MapData
	{
		public const string CustomDataKey = "q8pm_map";

		public const string StatsKey = "q8pm_stats";

		private const byte FormatVersion = 2;

		public long WorldUid;

		public int TextureSize;

		public BitArray Explored;

		public BitArray Pending;

		public List<PinRecord> Pins = new List<PinRecord>();

		public List<Vector3> Tombstones = new List<Vector3>();

		public bool HasView;

		public float ViewX;

		public float ViewZ;

		public ZoneRevs DrawnRevs = new ZoneRevs();

		public ZoneRevs PendingRevs = new ZoneRevs();

		public bool SurveyChecked;

		public static MapData CreateNew(long worldUid, int textureSize)
		{
			return new MapData
			{
				WorldUid = worldUid,
				TextureSize = textureSize,
				Explored = new BitArray(textureSize * textureSize),
				Pending = new BitArray(textureSize * textureSize)
			};
		}

		public string ToBlob()
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			using MemoryStream memoryStream = new MemoryStream();
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
			binaryWriter.Write(WorldUid);
			binaryWriter.Write(TextureSize);
			MapIO.WriteBits(binaryWriter, Explored);
			bool flag = MapBits.Any(Pending);
			binaryWriter.Write(flag);
			if (flag)
			{
				MapIO.WriteBits(binaryWriter, Pending);
			}
			MapIO.WritePins(binaryWriter, Pins);
			binaryWriter.Write(Tombstones.Count);
			foreach (Vector3 tombstone in Tombstones)
			{
				binaryWriter.Write(tombstone.x);
				binaryWriter.Write(tombstone.z);
			}
			binaryWriter.Write(HasView);
			binaryWriter.Write(ViewX);
			binaryWriter.Write(ViewZ);
			DrawnRevs.Write(binaryWriter);
			PendingRevs.Write(binaryWriter);
			binaryWriter.Flush();
			return Convert.ToBase64String(MapIO.Wrap(2, memoryStream.ToArray()));
		}

		public static MapData FromBlob(string blob, out string error)
		{
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			error = null;
			try
			{
				byte version;
				using BinaryReader binaryReader = new BinaryReader(new MemoryStream(MapIO.Unwrap(Convert.FromBase64String(blob), 2, out version)));
				MapData mapData = new MapData();
				mapData.WorldUid = binaryReader.ReadInt64();
				mapData.TextureSize = binaryReader.ReadInt32();
				int num = mapData.TextureSize * mapData.TextureSize;
				mapData.Explored = MapIO.ReadBits(binaryReader, num);
				mapData.Pending = (binaryReader.ReadBoolean() ? MapIO.ReadBits(binaryReader, num) : new BitArray(num));
				mapData.Pins = MapIO.ReadPins(binaryReader);
				int num2 = binaryReader.ReadInt32();
				for (int i = 0; i < num2; i++)
				{
					float num3 = binaryReader.ReadSingle();
					float num4 = binaryReader.ReadSingle();
					mapData.Tombstones.Add(new Vector3(num3, 0f, num4));
				}
				mapData.HasView = binaryReader.ReadBoolean();
				mapData.ViewX = binaryReader.ReadSingle();
				mapData.ViewZ = binaryReader.ReadSingle();
				if (version >= 2)
				{
					mapData.DrawnRevs = ZoneRevs.Read(binaryReader);
					mapData.PendingRevs = ZoneRevs.Read(binaryReader);
				}
				return mapData;
			}
			catch (Exception ex)
			{
				error = ex.GetType().Name + ": " + ex.Message;
				return null;
			}
		}
	}
	internal sealed class TableData
	{
		public const string ZdoKey = "q8pm_table";

		private const byte FormatVersion = 2;

		public int TextureSize;

		public BitArray Explored;

		public List<PinRecord> Pins = new List<PinRecord>();

		public ZoneRevs Revs = new ZoneRevs();

		public static TableData CreateNew(int textureSize)
		{
			return new TableData
			{
				TextureSize = textureSize,
				Explored = new BitArray(textureSize * textureSize)
			};
		}

		public byte[] ToBytes()
		{
			using MemoryStream memoryStream = new MemoryStream();
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
			binaryWriter.Write(TextureSize);
			MapIO.WriteBits(binaryWriter, Explored);
			MapIO.WritePins(binaryWriter, Pins);
			Revs.Write(binaryWriter);
			binaryWriter.Flush();
			return MapIO.Wrap(2, memoryStream.ToArray());
		}

		public static TableData FromBytes(byte[] bytes, out string error)
		{
			error = null;
			try
			{
				byte version;
				using BinaryReader binaryReader = new BinaryReader(new MemoryStream(MapIO.Unwrap(bytes, 2, out version)));
				TableData tableData = new TableData();
				tableData.TextureSize = binaryReader.ReadInt32();
				tableData.Explored = MapIO.ReadBits(binaryReader, tableData.TextureSize * tableData.TextureSize);
				tableData.Pins = MapIO.ReadPins(binaryReader);
				if (version >= 2)
				{
					tableData.Revs = ZoneRevs.Read(binaryReader);
				}
				return tableData;
			}
			catch (Exception ex)
			{
				error = ex.GetType().Name + ": " + ex.Message;
				return null;
			}
		}
	}
	internal static class MapIO
	{
		public static byte[] Wrap(byte version, byte[] raw)
		{
			byte[] array = MapBits.Compress(raw);
			byte[] array2 = new byte[array.Length + 1];
			array2[0] = version;
			Buffer.BlockCopy(array, 0, array2, 1, array.Length);
			return array2;
		}

		public static byte[] Unwrap(byte[] bytes, byte newestVersion, out byte version)
		{
			if (bytes == null || bytes.Length < 2)
			{
				throw new InvalidDataException("empty data");
			}
			version = bytes[0];
			if (version < 1 || version > newestVersion)
			{
				throw new InvalidDataException("unknown format version " + version);
			}
			return MapBits.Decompress(bytes, 1);
		}

		public static void WriteVar(BinaryWriter w, int value)
		{
			uint num;
			for (num = (uint)value; num >= 128; num >>= 7)
			{
				w.Write((byte)(num | 0x80));
			}
			w.Write((byte)num);
		}

		public static int ReadVar(BinaryReader r)
		{
			int num = 0;
			for (int i = 0; i <= 28; i += 7)
			{
				byte b = r.ReadByte();
				num |= (b & 0x7F) << i;
				if ((b & 0x80) == 0)
				{
					if (num < 0)
					{
						throw new InvalidDataException("negative number");
					}
					return num;
				}
			}
			throw new InvalidDataException("number too long");
		}

		public static void WriteBits(BinaryWriter w, BitArray bits)
		{
			byte[] array = MapBits.Pack(bits);
			w.Write(array.Length);
			w.Write(array);
		}

		public static BitArray ReadBits(BinaryReader r, int bitCount)
		{
			int num = r.ReadInt32();
			if (num != (bitCount + 7) / 8)
			{
				throw new InvalidDataException("bitmap size " + num + " does not match map size");
			}
			return MapBits.Unpack(r.ReadBytes(num), bitCount);
		}

		public static void WritePins(BinaryWriter w, List<PinRecord> pins)
		{
			w.Write(pins.Count);
			foreach (PinRecord pin in pins)
			{
				w.Write(pin.Name ?? "");
				w.Write(pin.Pos.x);
				w.Write(pin.Pos.y);
				w.Write(pin.Pos.z);
				w.Write(pin.Type);
				w.Write(pin.Checked);
			}
		}

		public static List<PinRecord> ReadPins(BinaryReader r)
		{
			//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)
			int num = r.ReadInt32();
			List<PinRecord> list = new List<PinRecord>(num);
			for (int i = 0; i < num; i++)
			{
				PinRecord pinRecord = new PinRecord();
				pinRecord.Name = r.ReadString();
				float num2 = r.ReadSingle();
				float num3 = r.ReadSingle();
				float num4 = r.ReadSingle();
				pinRecord.Pos = new Vector3(num2, num3, num4);
				pinRecord.Type = r.ReadInt32();
				pinRecord.Checked = r.ReadBoolean();
				list.Add(pinRecord);
			}
			return list;
		}
	}
	internal static class MapItem
	{
		public const string PrefabName = "Q8_ParchmentMap";

		public const string NameToken = "$item_q8pm_parchment";

		public const string DescriptionToken = "$item_q8pm_parchment_desc";

		private const string BasePrefabName = "DeerHide";

		private const string HandModelName = "model";

		private const float SheetWidth = 0.44f;

		private const float SheetHeight = 0.33f;

		private static readonly FieldRef<VisEquipment, GameObject> RightItemInstanceRef = AccessTools.FieldRefAccess<VisEquipment, GameObject>("m_rightItemInstance");

		private static Transform handModel;

		internal static bool IsParchment(ItemData item)
		{
			if (item != null && item.m_shared != null)
			{
				return item.m_shared.m_name == "$item_q8pm_parchment";
			}
			return false;
		}

		internal static void Register()
		{
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Invalid comparison between Unknown and I4
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Expected O, but got Unknown
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Expected O, but got Unknown
			PrefabManager.OnVanillaPrefabsAvailable -= Register;
			GameObject val = PrefabManager.Instance.CreateClonedPrefab("Q8_ParchmentMap", "DeerHide");
			if ((Object)(object)val == (Object)null)
			{
				ParchmentMapPlugin.Log.LogError((object)"Base prefab DeerHide not found, the parchment map is not added.");
				return;
			}
			ItemDrop component = val.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null)
			{
				ParchmentMapPlugin.Log.LogError((object)"Base prefab DeerHide has no ItemDrop, the parchment map is not added.");
				return;
			}
			bool flag = (int)SystemInfo.graphicsDeviceType == 4;
			if (!flag)
			{
				try
				{
					BuildVisuals(val);
				}
				catch (Exception ex)
				{
					ParchmentMapPlugin.Log.LogWarning((object)("Could not build the parchment model: " + ex.Message));
				}
			}
			component.m_autoDestroy = false;
			SharedData shared = component.m_itemData.m_shared;
			shared.m_itemType = (ItemType)19;
			shared.m_animationState = (AnimationState)5;
			shared.m_attachOverride = (ItemType)0;
			shared.m_maxStackSize = 1;
			shared.m_autoStack = false;
			shared.m_maxQuality = 1;
			shared.m_weight = 0.3f;
			shared.m_value = 0;
			shared.m_teleportable = true;
			shared.m_questItem = false;
			shared.m_equipDuration = 0.5f;
			shared.m_useDurability = false;
			shared.m_canBeReparied = false;
			shared.m_buildPieces = null;
			shared.m_equipStatusEffect = null;
			shared.m_attackStatusEffect = null;
			shared.m_consumeStatusEffect = null;
			shared.m_setStatusEffect = null;
			shared.m_setName = "";
			shared.m_setSize = 0;
			shared.m_food = 0f;
			shared.m_foodStamina = 0f;
			shared.m_foodEitr = 0f;
			shared.m_variants = 0;
			shared.m_attack = (Attack)(((object)shared.m_attack) ?? ((object)new Attack()));
			shared.m_secondaryAttack = (Attack)(((object)shared.m_secondaryAttack) ?? ((object)new Attack()));
			shared.m_attack.m_attackAnimation = "";
			shared.m_secondaryAttack.m_attackAnimation = "";
			ItemConfig val2 = new ItemConfig
			{
				Name = "$item_q8pm_parchment",
				Description = "$item_q8pm_parchment_desc"
			};
			if (!flag)
			{
				val2.CraftingStation = CraftingStations.Workbench;
				val2.MinStationLevel = 1;
				val2.Amount = 1;
				val2.Icons = (Sprite[])(object)new Sprite[1] { LoadIcon() };
				val2.Requirements = ParseRecipe(ParchmentMapPlugin.Recipe.Value).ToArray();
			}
			if (!ItemManager.Instance.AddItem(new CustomItem(val, false, val2)))
			{
				ParchmentMapPlugin.Log.LogError((object)"Jotunn rejected the parchment map item.");
			}
		}

		internal static List<RequirementConfig> ParseRecipe(string text)
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			List<RequirementConfig> list = new List<RequirementConfig>();
			string[] array = (text ?? "").Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text2 in array)
			{
				string[] array2 = text2.Split(new char[1] { ':' });
				if (array2.Length != 2 || array2[0].Trim().Length == 0 || !int.TryParse(array2[1].Trim(), out var result) || result < 1)
				{
					ParchmentMapPlugin.Log.LogWarning((object)("Recipe entry '" + text2 + "' is ignored, expected Item:amount."));
				}
				else
				{
					list.Add(new RequirementConfig(array2[0].Trim(), result, 0, true));
				}
			}
			if (list.Count == 0)
			{
				list.Add(new RequirementConfig("DeerHide", 2, 0, true));
			}
			return list;
		}

		internal static void ApplyRecipeToObjectDB()
		{
			ApplyRecipeTo("Q8_ParchmentMap", ParchmentMapPlugin.Recipe.Value);
		}

		internal static void ApplyRecipeTo(string prefabName, string recipeText)
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			if ((Object)(object)ObjectDB.instance == (Object)null)
			{
				return;
			}
			Recipe val = ObjectDB.instance.m_recipes.Find((Recipe r) => (Object)(object)r != (Object)null && (Object)(object)r.m_item != (Object)null && ((Object)((Component)r.m_item).gameObject).name == prefabName);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			List<Requirement> list = new List<Requirement>();
			foreach (RequirementConfig item in ParseRecipe(recipeText))
			{
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item.Item);
				ItemDrop val2 = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null);
				if ((Object)(object)val2 == (Object)null)
				{
					ParchmentMapPlugin.Log.LogWarning((object)("Recipe item '" + item.Item + "' does not exist and is ignored."));
					continue;
				}
				list.Add(new Requirement
				{
					m_resItem = val2,
					m_amount = item.Amount,
					m_amountPerLevel = 0,
					m_recover = true
				});
			}
			if (list.Count > 0)
			{
				val.m_resources = list.ToArray();
			}
		}

		private static void BuildVisuals(GameObject prefab)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0059: 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_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Expected O, but got Unknown
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			MeshRenderer componentInChildren = prefab.GetComponentInChildren<MeshRenderer>(true);
			Material val = (((Object)(object)componentInChildren != (Object)null && (Object)(object)((Renderer)componentInChildren).sharedMaterial != (Object)null) ? new Material(((Renderer)componentInChildren).sharedMaterial) : new Material(Shader.Find("Standard")));
			((Object)val).name = "q8pm_parchment";
			val.mainTexture = (Texture)(object)LoadTexture("parchment.png", repeat: false);
			val.color = Color.white;
			if (val.HasProperty("_Cull"))
			{
				val.SetFloat("_Cull", 0f);
			}
			string[] array = new string[3] { "_BumpMap", "_MetallicGlossMap", "_EmissionMap" };
			foreach (string text in array)
			{
				if (val.HasProperty(text))
				{
					val.SetTexture(text, (Texture)null);
				}
			}
			array = new string[2] { "_Metallic", "_Glossiness" };
			foreach (string text2 in array)
			{
				if (val.HasProperty(text2))
				{
					val.SetFloat(text2, 0f);
				}
			}
			for (int num = prefab.transform.childCount - 1; num >= 0; num--)
			{
				Object.DestroyImmediate((Object)(object)((Component)prefab.transform.GetChild(num)).gameObject);
			}
			LODGroup component = prefab.GetComponent<LODGroup>();
			if ((Object)(object)component != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component);
			}
			Mesh mesh = BuildSheetMesh();
			GameObject obj = CreateSheet("ground", prefab.transform, mesh, val);
			obj.transform.localPosition = new Vector3(0f, 0.02f, 0f);
			obj.transform.localRotation = Quaternion.Euler(90f, 0f, 0f);
			GameObject val2 = new GameObject("attach");
			val2.layer = prefab.layer;
			val2.transform.SetParent(prefab.transform, false);
			handModel = CreateSheet("model", val2.transform, mesh, val).transform;
			val2.SetActive(false);
			ApplyHandPose();
			if ((Object)(object)prefab.GetComponentInChildren<Collider>(true) == (Object)null)
			{
				BoxCollider obj2 = prefab.AddComponent<BoxCollider>();
				obj2.size = new Vector3(0.44f, 0.04f, 0.33f);
				obj2.center = new Vector3(0f, 0.02f, 0f);
			}
		}

		private static GameObject CreateSheet(string name, Transform parent, Mesh mesh, Material material)
		{
			//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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			GameObject val = new GameObject(name)
			{
				layer = ((Component)parent).gameObject.layer
			};
			val.transform.SetParent(parent, false);
			val.AddComponent<MeshFilter>().sharedMesh = mesh;
			((Renderer)val.AddComponent<MeshRenderer>()).sharedMaterial = material;
			return val;
		}

		private static Mesh BuildSheetMesh()
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: 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_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Expected O, but got Unknown
			int num = 9;
			Vector3[] array = (Vector3[])(object)new Vector3[num * 2];
			Vector3[] array2 = (Vector3[])(object)new Vector3[num * 2];
			Vector2[] array3 = (Vector2[])(object)new Vector2[num * 2];
			for (int i = 0; i < num; i++)
			{
				float num2 = (float)i / 8f;
				float num3 = (num2 - 0.5f) * 0.44f;
				float num4 = -0.018f * Mathf.Sin(num2 * (float)Math.PI);
				for (int j = 0; j < 2; j++)
				{
					int num5 = i * 2 + j;
					array[num5] = new Vector3(num3, ((float)j - 0.5f) * 0.33f, num4);
					array2[num5] = Vector3.back;
					array3[num5] = new Vector2(num2, (float)j);
				}
			}
			int[] array4 = new int[48];
			int num6 = 0;
			for (int k = 0; k < 8; k++)
			{
				int num7 = k * 2;
				int num8 = num7 + 1;
				int num9 = num7 + 2;
				int num10 = num7 + 3;
				array4[num6++] = num7;
				array4[num6++] = num8;
				array4[num6++] = num9;
				array4[num6++] = num9;
				array4[num6++] = num8;
				array4[num6++] = num10;
			}
			Mesh val = new Mesh
			{
				name = "q8pm_sheet",
				vertices = array,
				normals = array2,
				uv = array3,
				triangles = array4
			};
			val.RecalculateBounds();
			return val;
		}

		internal static void ApplyHandPose()
		{
			if ((Object)(object)handModel != (Object)null)
			{
				SetPose(handModel);
			}
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && IsParchment(((Humanoid)localPlayer).RightItem))
			{
				VisEquipment component = ((Component)localPlayer).GetComponent<VisEquipment>();
				GameObject val = (((Object)(object)component != (Object)null) ? RightItemInstanceRef.Invoke(component) : null);
				Transform val2 = (((Object)(object)val != (Object)null) ? val.transform.Find("model") : null);
				if ((Object)(object)val2 != (Object)null)
				{
					SetPose(val2);
				}
			}
		}

		private static void SetPose(Transform model)
		{
			//IL_0006: 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_0026: 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)
			model.localPosition = ParchmentMapPlugin.HandPosition.Value;
			model.localRotation = Quaternion.Euler(ParchmentMapPlugin.HandRotation.Value);
			model.localScale = Vector3.one * Mathf.Clamp(ParchmentMapPlugin.HandScale.Value, 0.1f, 5f);
		}

		private static Sprite LoadIcon()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = LoadTexture("icon.png", repeat: false);
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
		}

		internal static Texture2D LoadTexture(string resourceName, bool repeat)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true);
			try
			{
				using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
				if (stream == null)
				{
					throw new FileNotFoundException("embedded resource is missing");
				}
				byte[] array = new byte[stream.Length];
				int num;
				for (int i = 0; i < array.Length; i += num)
				{
					num = stream.Read(array, i, array.Length - i);
					if (num <= 0)
					{
						break;
					}
				}
				Type type = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule");
				MethodInfo methodInfo = ((type != null) ? type.GetMethod("LoadImage", new Type[2]
				{
					typeof(Texture2D),
					typeof(byte[])
				}) : null);
				if (methodInfo == null || !(bool)methodInfo.Invoke(null, new object[2] { val, array }))
				{
					throw new InvalidDataException("the image could not be decoded");
				}
			}
			catch (Exception ex)
			{
				ParchmentMapPlugin.Log.LogWarning((object)("Could not load " + resourceName + ": " + ex.Message));
				Color val2 = default(Color);
				((Color)(ref val2))..ctor(0.85f, 0.75f, 0.55f, 1f);
				val.SetPixels((Color[])(object)new Color[4] { val2, val2, val2, val2 });
				val.Apply();
			}
			((Object)val).name = "q8pm_" + resourceName;
			((Texture)val).wrapMode = (TextureWrapMode)(!repeat);
			return val;
		}
	}
	internal sealed class MapKeyHint
	{
		private const float CapSide = 32f;

		private const float CapPadding = 14f;

		private const float CharWidth = 11f;

		private const float KeyFontSize = 18f;

		private readonly GameObject root;

		private readonly TMP_Text label;

		private readonly TMP_Text key;

		private readonly LayoutElement capSize;

		internal bool Alive => (Object)(object)root != (Object)null;

		internal static MapKeyHint Create(Transform largeRoot, Sprite cap)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			Transform val = largeRoot.Find("KeyHints/keyboard_hints");
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			foreach (Transform item in val)
			{
				Transform val2 = item;
				Transform val3 = val2.Find("Label");
				Transform val4 = val2.Find("keyboard_hint");
				if ((Object)(object)val3 != (Object)null && (Object)(object)val4 != (Object)null && (Object)(object)((Component)val3).GetComponent<TMP_Text>() != (Object)null && (Object)(object)((Component)val4).GetComponent<Image>() != (Object)null)
				{
					return new MapKeyHint(((Component)val2).gameObject, val, cap);
				}
			}
			return null;
		}

		private MapKeyHint(GameObject sample, Transform row, Sprite cap)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			root = Object.Instantiate<GameObject>(sample, row);
			((Object)root).name = "q8pm_compass_hint";
			root.transform.SetAsFirstSibling();
			label = ((Component)root.transform.Find("Label")).GetComponent<TMP_Text>();
			Image component = ((Component)root.transform.Find("keyboard_hint")).GetComponent<Image>();
			component.sprite = cap;
			component.type = (Type)1;
			((Graphic)component).color = Color.white;
			((Graphic)component).raycastTarget = false;
			Canvas componentInParent = ((Component)row).GetComponentInParent<Canvas>(true);
			float num = (((Object)(object)componentInParent != (Object)null) ? componentInParent.referencePixelsPerUnit : 50f);
			Rect rect = cap.rect;
			component.pixelsPerUnitMultiplier = ((Rect)(ref rect)).height / 32f / (cap.pixelsPerUnit / num);
			capSize = ((Component)component).GetComponent<LayoutElement>();
			if ((Object)(object)capSize == (Object)null)
			{
				capSize = ((Component)component).gameObject.AddComponent<LayoutElement>();
			}
			capSize.minHeight = (capSize.preferredHeight = 32f);
			GameObject val = Object.Instantiate<GameObject>(((Component)label).gameObject, ((Component)component).transform);
			((Object)val).name = "key";
			ContentSizeFitter component2 = val.GetComponent<ContentSizeFitter>();
			if ((Object)(object)component2 != (Object)null)
			{
				((Behaviour)component2).enabled = false;
				Object.Destroy((Object)(object)component2);
			}
			RectTransform val2 = (RectTransform)val.transform;
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.pivot = new Vector2(0.5f, 0.5f);
			val2.offsetMin = new Vector2(0f, 2f);
			val2.offsetMax = Vector2.zero;
			((Transform)val2).localRotation = Quaternion.identity;
			((Transform)val2).localScale = Vector3.one;
			key = val.GetComponent<TMP_Text>();
			key.enableAutoSizing = true;
			key.fontSizeMin = 10f;
			key.fontSizeMax = 18f;
			key.alignment = (TextAlignmentOptions)514;
			key.textWrappingMode = (TextWrappingModes)0;
			key.overflowMode = (TextOverflowModes)0;
			((Graphic)key).raycastTarget = false;
		}

		internal void Show(bool visible)
		{
			if ((Object)(object)root != (Object)null && root.activeSelf != visible)
			{
				root.SetActive(visible);
			}
		}

		internal void Set(string text, string keyName)
		{
			if (!((Object)(object)root == (Object)null))
			{
				label.text = text;
				key.text = keyName;
				float num = ((keyName.Length <= 1) ? 32f : Mathf.Max(32f, 14f + 11f * (float)keyName.Length));
				LayoutElement obj = capSize;
				float minWidth = (capSize.preferredWidth = num);
				obj.minWidth = minWidth;
			}
		}

		internal void Destroy()
		{
			if ((Object)(object)root != (Object)null)
			{
				Object.Destroy((Object)(object)root);
			}
		}
	}
	internal static class MapReports
	{
		internal sealed class TableUse
		{
			public bool Write;

			public Vector3 TablePos;

			public ZDOID TableId;

			public int Notes;

			public BitArray Got;

			public BitArray Gave;

			public int GotMarks;

			public int GaveMarks;

			public int LostMarks;

			public int MapCells;

			public int MapMarks;

			public int MapZones;

			public int TableCells;

			public int TableMarks;

			public bool TableEmpty;
		}

		internal const string IdKey = "q8pm_id";

		private const float ExploreEvery = 30f;

		private static readonly ExploreBatch batch = new ExploreBatch();

		private static readonly Dictionar