Decompiled source of ExpertExplorer v1.4.2

ExpertExplorer.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ExpertExplorer")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ExpertExplorer")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("1.4.2.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.4.2.0")]
namespace ExpertExplorer
{
	public class PlayerExplorationData : MonoBehaviour
	{
		public Dictionary<Vector2i, int> DiscoveredLocations = new Dictionary<Vector2i, int>();

		public List<int> DiscoveredBiomes = new List<int>();

		public Dictionary<Vector2i, string> PinnedLocations = new Dictionary<Vector2i, string>();

		public bool IsZoneLocationAlreadyDiscovered(Vector2i zone)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return DiscoveredLocations.ContainsKey(zone);
		}

		public void FlagAsDiscovered(ZoneData zoneData)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (zoneData != null && !string.IsNullOrEmpty(zoneData.LocationPrefab))
			{
				DiscoveredLocations[zoneData.ZoneId] = zoneData.LocationHash;
				Logger.LogInfo((object)("Discovered location " + zoneData.LocalizedLocationName));
			}
		}

		public void FlagAsDiscovered(Biome biome)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			int item = Heightmap.s_biomeToIndex[biome];
			if (!DiscoveredBiomes.Contains(item))
			{
				DiscoveredBiomes.Add(item);
				Logger.LogInfo((object)$"Discovered biome {biome}");
			}
		}

		public void FlagAsPinned(Vector2i zone, PinData pinData)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			PinnedLocations[zone] = pinData.m_name;
		}

		public void RemovePin(Vector2i zone)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			PinnedLocations.Remove(zone);
		}

		public void Save(Player player)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_0054: 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_009b: Expected O, but got Unknown
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Expected O, but got Unknown
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null)
			{
				Logger.LogError((object)"Tried to save an PlayerExplorationData without a player!");
				return;
			}
			SaveValue(player, "PlayerExplorationData", "This player is using PlayerExplorationData!");
			ZPackage val = new ZPackage();
			val.Write(DiscoveredLocations.Count);
			foreach (KeyValuePair<Vector2i, int> discoveredLocation in DiscoveredLocations)
			{
				val.Write(discoveredLocation.Key);
				val.Write(discoveredLocation.Value);
			}
			SaveValue(player, "DiscoveredLocations", val.GetBase64());
			val = new ZPackage();
			val.Write(DiscoveredBiomes.Count);
			foreach (int discoveredBiome in DiscoveredBiomes)
			{
				val.Write(discoveredBiome);
			}
			SaveValue(player, "ExpertExplorerDiscoveredBiomes", val.GetBase64());
			val = new ZPackage();
			val.Write(PinnedLocations.Count);
			foreach (KeyValuePair<Vector2i, string> pinnedLocation in PinnedLocations)
			{
				val.Write(pinnedLocation.Key);
				val.Write(pinnedLocation.Value);
			}
			SaveValue(player, "PinnedLocations", val.GetBase64());
		}

		public void Load(Player fromPlayer)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_00f8: 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_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Expected O, but got Unknown
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)fromPlayer == (Object)null)
			{
				Logger.LogError((object)"Tried to load an PlayerExplorationData with a null player!");
				return;
			}
			LoadValue(fromPlayer, "PlayerExplorationData", out var _);
			if (LoadValue(fromPlayer, "DiscoveredLocations", out var value2))
			{
				ZPackage val = new ZPackage(value2);
				int num = val.ReadInt();
				for (int i = 0; i < num; i++)
				{
					Vector2i key = val.ReadVector2i();
					DiscoveredLocations[key] = val.ReadInt();
				}
			}
			fromPlayer.m_customData.Remove("DiscoveredBiomes");
			DiscoveredBiomes.Clear();
			if (LoadValue(fromPlayer, "ExpertExplorerDiscoveredBiomes", out var value3))
			{
				ZPackage val2 = new ZPackage(value3);
				int num2 = val2.ReadInt();
				for (int j = 0; j < num2; j++)
				{
					int item = val2.ReadInt();
					if (!DiscoveredBiomes.Contains(item))
					{
						DiscoveredBiomes.Add(item);
					}
				}
			}
			foreach (Biome item2 in fromPlayer.m_knownBiome)
			{
				FlagAsDiscovered(item2);
			}
			PinnedLocations.Clear();
			if (LoadValue(fromPlayer, "PinnedLocations", out var value4))
			{
				ZPackage val3 = new ZPackage(value4);
				int num3 = val3.ReadInt();
				for (int k = 0; k < num3; k++)
				{
					Vector2i key2 = val3.ReadVector2i();
					PinnedLocations[key2] = val3.ReadString();
				}
			}
		}

		private static void SaveValue(Player player, string key, string value)
		{
			if (player.m_customData.ContainsKey(key))
			{
				player.m_customData[key] = value;
			}
			else
			{
				player.m_customData.Add(key, value);
			}
		}

		private static bool LoadValue(Player player, string key, out string value)
		{
			if (player.m_customData.TryGetValue(key, out value))
			{
				return true;
			}
			return false;
		}
	}
	public static class PlayerExtensions
	{
		public static void InitializeExplorationData(this Player player)
		{
			if (!((Object)(object)player == (Object)null) && !player.HasExplorationData())
			{
				((Component)player).gameObject.AddComponent<PlayerExplorationData>().Load(player);
			}
		}

		public static bool HasExplorationData(this Player player)
		{
			return (Object)(object)((player != null) ? ((Component)player).gameObject.GetComponent<PlayerExplorationData>() : null) != (Object)null;
		}

		public static PlayerExplorationData ExplorationData(this Player player)
		{
			if (player == null)
			{
				return null;
			}
			return ((Component)player).gameObject.GetComponent<PlayerExplorationData>();
		}
	}
	[BepInPlugin("com.milkwyzard.ExpertExplorer", "ExpertExplorer", "1.4.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class ExpertExplorer : BaseUnityPlugin
	{
		public const string PluginGUID = "com.milkwyzard.ExpertExplorer";

		public const string PluginName = "ExpertExplorer";

		public const string PluginVersion = "1.4.2";

		public const string SkillId = "com.milkwyzard.ExpertExplorer.Exploration";

		public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization();

		private Harmony harmony;

		private const float POST_INTRO_DELAY = 1f;

		private const float ZONE_CHECK_FREQUENCY = 1.5f;

		private const float ZONE_RPC_REQUEST_FREQUENCY = 2f;

		private static ZoneData currentZoneData = null;

		private static Vector2i currentZone;

		private static string lastEvaluatedLocation = string.Empty;

		private static float zoneCheckTimer = 0f;

		private static float zoneRpcRequestTimer = 0f;

		private static bool introLastFrame = false;

		private static bool locationsAvailable = false;

		private static Dictionary<Vector2i, ZoneData> zoneDataCache = new Dictionary<Vector2i, ZoneData>();

		private static Dictionary<Vector2i, Sprite> locationSpriteMap = new Dictionary<Vector2i, Sprite>();

		private static Dictionary<Vector2i, PinData> locationPins = new Dictionary<Vector2i, PinData>();

		private static List<string> specialLocations = new List<string> { "StartTemple", "Eikthyrnir", "Dragonqueen", "GoblinKing", "GDKing", "Bonemass", "Vendor_BlackForest", "Hildir_camp", "Mistlands_DvergrBossEntrance1" };

		private static List<string> dungeonLocations = new List<string> { "Mistlands_DvergrBossEntrance1", "Hildir_cave", "Hildir_crypt", "Crypt2", "Crypt3", "Crypt4", "Mistlands_DvergrTownEntrance1", "Mistlands_DvergrTownEntrance2", "MountainCave02", "SunkenCrypt4" };

		public static ConfigEntry<float> SkillXpFactor;

		public static ConfigEntry<float> MaxExploreRadius;

		public static ConfigEntry<float> DiscoverDistance;

		public static ConfigEntry<KeyboardShortcut> PinKey;

		public static ConfigEntry<KeyboardShortcut> PinPointOfInterest;

		public static ConfigEntry<KeyboardShortcut> PinOre;

		public static ConfigEntry<KeyboardShortcut> PinHome;

		public static ConfigEntry<KeyboardShortcut> PinCamp;

		public static ConfigEntry<KeyboardShortcut> PinDungeon;

		public static ConfigEntry<KeyboardShortcut> PinPortal;

		public static ConfigEntry<string> PinTextPointOfInterest;

		public static ConfigEntry<string> PinTextOre;

		public static ConfigEntry<string> PinTextHome;

		public static ConfigEntry<string> PinTextCamp;

		public static ConfigEntry<string> PinTextDungeon;

		public static ConfigEntry<string> PinTextPortal;

		public static ConfigEntry<bool> AutoPinDungeonLocations;

		public static ConfigEntry<bool> ShowLocationDiscoveryNotification;

		public static SkillType ExplorationSkillType;

		public ExpertExplorer()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			harmony = new Harmony("com.milkwyzard.ExpertExplorer");
		}

		public void Start()
		{
			harmony.PatchAll(Assembly.GetExecutingAssembly());
		}

		private void Awake()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			//IL_00ea: 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)
			//IL_0149: Expected O, but got Unknown
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Expected O, but got Unknown
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
			ConfigurationManagerAttributes val = new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			};
			SkillXpFactor = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SkillXpFactor", 1.5f, new ConfigDescription("Factor applied to skill gain. Higher number means faster skill gain. Range 0-100.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[1] { val }));
			MaxExploreRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Exploration", "MaxExploreRadius", 200f, new ConfigDescription("Max explore radius used when the Exploration Skill is at 100. Range 100-300.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(100f, 300f), new object[1] { val }));
			DiscoverDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Exploration", "DiscoverDistance", 10f, new ConfigDescription("Distance between the player and the bounds of a location required to mark the location as discovered. Range 0-50.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f), new object[1] { val }));
			PinKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Pin to Mini-Map Key", new KeyboardShortcut((KeyCode)112, Array.Empty<KeyCode>()), "Hotkey used to add a pin to the mini-map when a new location is discovered.");
			AutoPinDungeonLocations = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Auto-Pin Dungeon Locations", true, "Flag that can be set to have dungeons auto-pin to the map when discovered.");
			ShowLocationDiscoveryNotification = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Show Location Discovery Notification", true, new ConfigDescription("Flag that can be set toggle whether a ui notification occurs when a location is discovered.", (AcceptableValueBase)null, new object[1] { val }));
			PinHome = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Pin Home Key", new KeyboardShortcut((KeyCode)256, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 }), "Hotkey used to add a home/town pin to the mini-map.");
			PinPointOfInterest = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Pin Point of Interest Key", new KeyboardShortcut((KeyCode)257, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 }), "Hotkey used to add a point of interest pin to the mini-map.");
			PinOre = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Pin Ore Key", new KeyboardShortcut((KeyCode)258, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 }), "Hotkey used to add an ore deposit pin to the mini-map.");
			PinCamp = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Pin Camp Key", new KeyboardShortcut((KeyCode)259, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 }), "Hotkey used to add a camp pin to the mini-map.");
			PinDungeon = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Pin Dungeon Key", new KeyboardShortcut((KeyCode)260, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 }), "Hotkey used to add a dungeon pin to the mini-map.");
			PinPortal = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Pin Portal Key", new KeyboardShortcut((KeyCode)261, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 }), "Hotkey used to add a portal pin to the mini-map.");
			PinTextHome = ((BaseUnityPlugin)this).Config.Bind<string>("Map Pin Text", "Pin Text Home", "Home or Town", "Text displayed when pinning a home location to the minimap with the keyboard shortcut.");
			PinTextPointOfInterest = ((BaseUnityPlugin)this).Config.Bind<string>("Map Pin Text", "Pin Text Point of Interest", "Point of Interest", "Text displayed when pinning a point of interest to the minimap with the keyboard shortcut.");
			PinTextOre = ((BaseUnityPlugin)this).Config.Bind<string>("Map Pin Text", "Pin Text Ore", "Ore Deposit", "Text displayed when pinning an ore deposit location to the minimap with the keyboard shortcut.");
			PinTextCamp = ((BaseUnityPlugin)this).Config.Bind<string>("Map Pin Text", "Pin Text Camp", "Camp", "Text displayed when pinning a camp location to the minimap with the keyboard shortcut.");
			PinTextDungeon = ((BaseUnityPlugin)this).Config.Bind<string>("Map Pin Text", "Pin Text Dungeon", "Crypt or Dungeon", "Text displayed when pinning a dungeon location to the minimap with the keyboard shortcut.");
			PinTextPortal = ((BaseUnityPlugin)this).Config.Bind<string>("Map Pin Text", "Pin Text Portal", "Portal", "Text displayed when pinning a portal to the minimap with the keyboard shortcut.");
			ZoneManager.OnVanillaLocationsAvailable += OnVanillaLocationAvailable;
			SkillConfig val2 = new SkillConfig();
			val2.Identifier = "com.milkwyzard.ExpertExplorer.Exploration";
			val2.Name = "$skill_exploration";
			val2.Description = "$skill_exploration_desc";
			val2.IncreaseStep = SkillXpFactor.Value;
			ExplorationSkillType = SkillManager.Instance.AddSkill(val2);
			ZoneHelper.Instance.SetZoneDataAction = delegate(ZoneData zoneData)
			{
				SetZoneData(zoneData);
			};
			Logger.LogInfo((object)"ExpertExplorer v1.4.2 loaded and patched.");
		}

		private void OnVanillaLocationAvailable()
		{
			locationsAvailable = true;
		}

		private void Update()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: 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_00e4: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0332: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_034d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: 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_0455: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0470: Unknown result type (might be due to invalid IL or missing references)
			//IL_0517: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0532: Unknown result type (might be due to invalid IL or missing references)
			if (ZInput.instance == null || !locationsAvailable || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			if (((Character)Player.m_localPlayer).InIntro())
			{
				introLastFrame = true;
			}
			else
			{
				if (((Character)Player.m_localPlayer).InCutscene())
				{
					return;
				}
				Vector3 position = ((Component)Player.m_localPlayer).transform.position;
				PlayerExplorationData playerExplorationData = Player.m_localPlayer.ExplorationData();
				if ((Object)(object)playerExplorationData == (Object)null)
				{
					Logger.LogWarning((object)"Update skipped because there is no exploration data.");
					return;
				}
				if (introLastFrame)
				{
					zoneCheckTimer = 1f;
					introLastFrame = false;
				}
				zoneCheckTimer = Mathf.Max(0f, zoneCheckTimer - Time.deltaTime);
				zoneRpcRequestTimer = Mathf.Max(0f, zoneRpcRequestTimer - Time.deltaTime);
				if (!((Character)Player.m_localPlayer).InInterior() && zoneCheckTimer == 0f)
				{
					Vector2i zone = ZoneSystem.GetZone(position);
					if (zone != currentZone)
					{
						currentZone = zone;
						zoneDataCache.TryGetValue(currentZone, out currentZoneData);
					}
					if (currentZoneData == null && zoneRpcRequestTimer == 0f)
					{
						zoneRpcRequestTimer = 2f;
						ZoneHelper.Instance.Client_RequestZoneData(currentZone);
					}
					zoneCheckTimer = 1.5f;
				}
				if (currentZoneData != null && currentZoneData.IsValid() && !playerExplorationData.IsZoneLocationAlreadyDiscovered(currentZone) && (IsLookingAtLocation(Player.m_localPlayer, currentZoneData) || IsInsideLocation(Player.m_localPlayer, currentZoneData)) && currentZoneData.LocationPrefab != lastEvaluatedLocation)
				{
					lastEvaluatedLocation = currentZoneData.LocationPrefab;
					playerExplorationData.FlagAsDiscovered(currentZoneData);
					playerExplorationData.Save(Player.m_localPlayer);
					((Character)Player.m_localPlayer).RaiseSkill(ExplorationSkillType, 1f);
					_ = "Discovered " + currentZoneData.LocalizedLocationName;
					Vector3 locationPosition = currentZoneData.LocationPosition;
					locationPosition.y = ZoneSystem.instance.GetGroundHeight(currentZoneData.LocationPosition) + ((Character)Player.m_localPlayer).GetHeight();
					Sprite value = null;
					locationSpriteMap.TryGetValue(currentZone, out value);
					if ((Object)(object)value == (Object)null)
					{
						Logger.LogInfo((object)("No sprite icon for location " + currentZoneData.LocationPrefab));
					}
					if (ShowLocationDiscoveryNotification.Value)
					{
						QueueFoundLocationMsg(value, "Location Discovered", currentZoneData.LocalizedLocationName, IsSpecialLocation(currentZoneData.LocationPrefab));
					}
					if (AutoPinDungeonLocations.Value && IsDungeonLocation(currentZoneData.LocationPrefab))
					{
						((MonoBehaviour)this).StartCoroutine(AutoPinLocation(currentZoneData, playerExplorationData));
					}
				}
				if (((Character)Player.m_localPlayer).TakeInput())
				{
					KeyboardShortcut value2 = PinKey.Value;
					if (ZInput.GetKeyDown(((KeyboardShortcut)(ref value2)).MainKey, true) && (IsLookingAtLocation(Player.m_localPlayer, currentZoneData) || IsInsideLocation(Player.m_localPlayer, currentZoneData)) && !locationPins.ContainsKey(currentZone) && !IsSpecialLocation(currentZoneData.LocationPrefab))
					{
						PinLocation(currentZoneData, playerExplorationData);
					}
					if (IsPinKeyPressed(PinHome.Value))
					{
						Minimap.instance.AddPin(((Component)Player.m_localPlayer).transform.position, (PinType)1, PinTextHome.Value, true, false, 0L, "");
						((Character)Player.m_localPlayer).Message((MessageType)1, PinTextHome.Value + " pinned to minimap.", 0, (Sprite)null);
					}
					if (IsPinKeyPressed(PinPointOfInterest.Value))
					{
						Minimap.instance.AddPin(((Component)Player.m_localPlayer).transform.position, (PinType)3, PinTextPointOfInterest.Value, true, false, 0L, "");
						((Character)Player.m_localPlayer).Message((MessageType)1, PinTextPointOfInterest.Value + " pinned to minimap.", 0, (Sprite)null);
					}
					if (IsPinKeyPressed(PinOre.Value))
					{
						Minimap.instance.AddPin(((Component)Player.m_localPlayer).transform.position, (PinType)2, PinTextOre.Value, true, false, 0L, "");
						((Character)Player.m_localPlayer).Message((MessageType)1, PinTextOre.Value + " pinned to minimap.", 0, (Sprite)null);
					}
					if (IsPinKeyPressed(PinCamp.Value))
					{
						Minimap.instance.AddPin(((Component)Player.m_localPlayer).transform.position, (PinType)0, PinTextCamp.Value, true, false, 0L, "");
						((Character)Player.m_localPlayer).Message((MessageType)1, PinTextCamp.Value + " pinned to minimap.", 0, (Sprite)null);
					}
					if (IsPinKeyPressed(PinDungeon.Value))
					{
						Minimap.instance.AddPin(((Component)Player.m_localPlayer).transform.position, (PinType)3, PinTextDungeon.Value, true, false, 0L, "");
						((Character)Player.m_localPlayer).Message((MessageType)1, PinTextDungeon.Value + " pinned to minimap.", 0, (Sprite)null);
					}
					if (IsPinKeyPressed(PinPortal.Value))
					{
						Minimap.instance.AddPin(((Component)Player.m_localPlayer).transform.position, (PinType)6, PinTextPortal.Value, true, false, 0L, "");
						((Character)Player.m_localPlayer).Message((MessageType)1, PinTextPortal.Value + " pinned to minimap.", 0, (Sprite)null);
					}
				}
			}
		}

		private bool IsPinKeyPressed(KeyboardShortcut pinKey)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (!ZInput.GetKeyDown(((KeyboardShortcut)(ref pinKey)).MainKey, true))
			{
				return false;
			}
			bool result = true;
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref pinKey)).Modifiers)
			{
				if (!ZInput.GetKey(modifier, true))
				{
					result = false;
					Logger.LogInfo((object)$"Missing key modifier {modifier}");
					break;
				}
			}
			return result;
		}

		public static ZoneData GetCurrentLocation(Player player)
		{
			if (currentZoneData != null && currentZoneData.IsValid() && (((Character)player).InInterior() || IsLookingAtLocation(player, currentZoneData) || IsInsideLocation(player, currentZoneData)))
			{
				return currentZoneData;
			}
			return null;
		}

		public static bool IsSpecialLocation(string locationPrefabName)
		{
			return specialLocations.Contains(locationPrefabName);
		}

		public static bool IsDungeonLocation(string locationPrefabName)
		{
			return dungeonLocations.Contains(locationPrefabName);
		}

		public static void OnPinRemoved(PinData pinData)
		{
			//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_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			Vector2i zone = ZoneSystem.GetZone(pinData.m_pos);
			if (locationPins.ContainsKey(zone) && locationPins[zone].m_name == pinData.m_name)
			{
				locationPins.Remove(zone);
				Player.m_localPlayer.ExplorationData()?.RemovePin(zone);
			}
		}

		private static IEnumerator AutoPinLocation(ZoneData zoneData, PlayerExplorationData explorationData)
		{
			yield return (object)new WaitForSeconds(1f);
			PinLocation(zoneData, explorationData);
		}

		private static void PinLocation(ZoneData zoneData, PlayerExplorationData explorationData)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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)
			//IL_0031: 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)
			Vector3 locationPosition = zoneData.LocationPosition;
			Vector2i zoneId = zoneData.ZoneId;
			string localizedLocationName = zoneData.LocalizedLocationName;
			PinData val = Minimap.instance.AddPin(locationPosition, (PinType)3, localizedLocationName, true, false, 0L, "");
			locationPins[zoneId] = val;
			explorationData.FlagAsPinned(zoneId, val);
			((Character)Player.m_localPlayer).Message((MessageType)1, "Location pinned to minimap.", 0, (Sprite)null);
		}

		private static void SetZoneData(ZoneData zoneData)
		{
			//IL_000d: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: 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)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Expected O, but got Unknown
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			if (!(currentZone == zoneData.ZoneId))
			{
				return;
			}
			zoneDataCache[currentZone] = zoneData;
			currentZoneData = zoneData;
			if (locationSpriteMap.ContainsKey(currentZone))
			{
				return;
			}
			ZoneLocation val = ((IEnumerable<ZoneLocation>)ZoneSystem.instance.m_locations).FirstOrDefault((Func<ZoneLocation, bool>)((ZoneLocation l) => l.m_prefabName == zoneData.LocationPrefab));
			if (val == null)
			{
				return;
			}
			GameObject val2 = val.m_prefab.Asset;
			Location component = val2.GetComponent<Location>();
			if (Object.op_Implicit((Object)(object)component) && component.m_hasInterior)
			{
				Transform transform = ((Component)component).transform;
				for (int i = 0; i < transform.childCount; i++)
				{
					Transform child = transform.GetChild(i);
					if (((Object)child).name.ToLowerInvariant().Equals("exterior"))
					{
						val2 = ((Component)child).gameObject;
						break;
					}
				}
			}
			Sprite val3 = RenderManager.Instance.Render(new RenderRequest(val2)
			{
				Rotation = RenderManager.IsometricRotation,
				FieldOfView = 20f,
				DistanceMultiplier = 1.1f,
				Width = 256,
				Height = 256
			});
			if ((Object)(object)val3 != (Object)null)
			{
				locationSpriteMap[currentZone] = val3;
			}
		}

		private static bool IsLookingAtLocation(Player player, ZoneData zoneData)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			float locationRadiusMax = zoneData.LocationRadiusMax;
			Vector3 position = ((Component)player).transform.position;
			float num = locationRadiusMax + DiscoverDistance.Value;
			bool result = false;
			if (Vector3.Distance(position, currentZoneData.LocationPosition) < num && Vector3.Angle(currentZoneData.LocationPosition - position, ((Component)Player.m_localPlayer).transform.forward) < 20f)
			{
				result = true;
			}
			return result;
		}

		private static bool IsInsideLocation(Player player, ZoneData zoneData)
		{
			//IL_0006: 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)
			return Utils.DistanceXZ(((Component)player).transform.position, currentZoneData.LocationPosition) < zoneData.LocationRadiusMax;
		}

		public static void QueueFoundLocationMsg(Sprite icon, string topic, string description, bool isSpecialLocation)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			string text = description;
			KeyboardShortcut value = PinKey.Value;
			string text2 = ((object)(KeyboardShortcut)(ref value)).ToString();
			if (!isSpecialLocation)
			{
				text = text + "\nPress [<color=yellow><b>" + text2 + "</b></color>] to add a pin";
			}
			UnlockMsg val = new UnlockMsg();
			val.m_icon = icon;
			val.m_topic = topic;
			val.m_description = text;
			MessageHud.instance.m_unlockMsgQueue.Enqueue(val);
			MessageHud.instance.AddLog(topic + ": " + description);
		}
	}
	public class ZoneData
	{
		public Vector2i ZoneId { get; set; }

		public string LocationPrefab { get; set; }

		public Vector3 LocationPosition { get; set; }

		public int LocationHash { get; set; }

		public float LocationRadiusMax { get; set; }

		public bool IsPlaced { get; set; }

		public string LocalizedLocationName { get; set; }

		public bool HasLocation { get; set; }

		public ZoneData()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			ZoneId = default(Vector2i);
			LocationPrefab = string.Empty;
			LocationPosition = default(Vector3);
			LocationHash = 0;
			LocationRadiusMax = 0f;
			IsPlaced = false;
			LocalizedLocationName = string.Empty;
			HasLocation = false;
		}

		public bool IsValid()
		{
			if (HasLocation && !string.IsNullOrEmpty(LocationPrefab))
			{
				return IsPlaced;
			}
			return false;
		}
	}
	public sealed class ZoneHelper
	{
		private static readonly ZoneHelper instance;

		public Action<ZoneData> SetZoneDataAction;

		public static ZoneHelper Instance => instance;

		static ZoneHelper()
		{
			instance = new ZoneHelper();
		}

		private ZoneHelper()
		{
		}

		public void RegisterRPC(ZRoutedRpc routedRpc)
		{
			routedRpc.Register<int, int>("RequestZoneData", (Action<long, int, int>)RPC_RequestZoneData);
			routedRpc.Register<ZPackage>("SetZoneData", (Action<long, ZPackage>)RPC_SetZoneData);
		}

		public ZoneData GetZoneData(Vector2i zone)
		{
			//IL_0007: 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_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)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			ZoneData zoneData = new ZoneData();
			zoneData.ZoneId = zone;
			if (ZoneSystem.instance.m_locationInstances.TryGetValue(zone, out var value))
			{
				zoneData.LocationPrefab = ((value.m_location != null) ? value.m_location.m_prefabName : string.Empty);
				zoneData.LocationRadiusMax = ((value.m_location != null) ? Mathf.Max(value.m_location.m_exteriorRadius, value.m_location.m_interiorRadius) : 0f);
				zoneData.LocationPosition = value.m_position;
				zoneData.IsPlaced = value.m_placed;
				zoneData.LocalizedLocationName = ((value.m_location != null) ? GetLocationName(value.m_location.m_prefabName) : string.Empty);
				zoneData.HasLocation = value.m_location != null;
			}
			return zoneData;
		}

		private string GetLocationName(string prefabName)
		{
			return ExpertExplorer.Localization.TryTranslate("location_" + prefabName);
		}

		public void Client_RequestZoneData(Vector2i zone)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			ZRoutedRpc.instance.InvokeRoutedRPC("RequestZoneData", new object[2] { zone.x, zone.y });
		}

		private void RPC_RequestZoneData(long sender, int zoneX, int zoneY)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			ZoneData zoneData = GetZoneData(new Vector2i(zoneX, zoneY));
			ZPackage val = new ZPackage();
			val.Write(zoneData.ZoneId);
			val.Write(zoneData.LocationPrefab);
			val.Write(zoneData.LocationPosition);
			val.Write(zoneData.LocationHash);
			val.Write(zoneData.LocationRadiusMax);
			val.Write(zoneData.IsPlaced);
			val.Write(zoneData.HasLocation);
			ZRoutedRpc.instance.InvokeRoutedRPC(sender, "SetZoneData", new object[1] { val });
		}

		private void RPC_SetZoneData(long sender, ZPackage zoneDataPkg)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (zoneDataPkg == null)
			{
				Logger.LogWarning((object)"Zone Data package was null.");
				return;
			}
			ZoneData zoneData = new ZoneData();
			zoneData.ZoneId = zoneDataPkg.ReadVector2i();
			zoneData.LocationPrefab = zoneDataPkg.ReadString();
			zoneData.LocationPosition = zoneDataPkg.ReadVector3();
			zoneData.LocationHash = zoneDataPkg.ReadInt();
			zoneData.LocationRadiusMax = zoneDataPkg.ReadSingle();
			zoneData.IsPlaced = zoneDataPkg.ReadBool();
			zoneData.HasLocation = zoneDataPkg.ReadBool();
			zoneData.LocalizedLocationName = ((!string.IsNullOrEmpty(zoneData.LocationPrefab)) ? ExpertExplorer.Localization.TryTranslate("location_" + zoneData.LocationPrefab) : string.Empty);
			SetZoneDataAction?.Invoke(zoneData);
		}
	}
}
namespace ExpertExplorer.Patches
{
	[HarmonyPatch(typeof(ZNet), "Awake")]
	public static class ZNetPatch_Awake
	{
		public static void Postfix(ZNet __instance)
		{
			ZoneHelper.Instance.RegisterRPC(__instance.m_routedRpc);
		}
	}
	[HarmonyPatch]
	public static class MinimapPatch
	{
		private static TMP_Text m_LocationNameSmall;

		private static float miniMapHeight;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Minimap), "Explore", new Type[]
		{
			typeof(Vector3),
			typeof(float)
		})]
		private static void Explore(ref Minimap __instance, ref Vector3 p, ref float radius)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			float num = ((Character)Player.m_localPlayer).GetSkillLevel(ExpertExplorer.ExplorationSkillType) / 100f;
			radius = Mathf.Lerp(__instance.m_exploreRadius, ExpertExplorer.MaxExploreRadius.Value, num);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Minimap), "Awake")]
		private static void Awake(ref Minimap __instance)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: 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_00c7: 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)
			Rect rect = ((Graphic)__instance.m_mapImageSmall).rectTransform.rect;
			miniMapHeight = ((Rect)(ref rect)).height;
			m_LocationNameSmall = Object.Instantiate<GameObject>(((Component)__instance.m_biomeNameSmall).gameObject, ((Component)__instance.m_biomeNameSmall).gameObject.transform.parent).GetComponent<TMP_Text>();
			if ((Object)(object)m_LocationNameSmall == (Object)null)
			{
				Logger.LogWarning((object)"Could not duplicate biome name text");
				return;
			}
			m_LocationNameSmall.text = "Location Text Test";
			m_LocationNameSmall.fontSize = 12f;
			((Transform)m_LocationNameSmall.rectTransform).position = new Vector3(((Transform)m_LocationNameSmall.rectTransform).position.x, ((Transform)m_LocationNameSmall.rectTransform).position.y + 25f, ((Transform)m_LocationNameSmall.rectTransform).position.z);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Minimap), "RemovePin", new Type[] { typeof(PinData) })]
		private static void RemovePin(ref Minimap __instance, ref PinData pin)
		{
			ExpertExplorer.OnPinRemoved(pin);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Minimap), "UpdateBiome")]
		private static void UpdateBiome(ref Minimap __instance, ref Player player)
		{
			UpdateLocation(player);
		}

		private static void UpdateLocation(Player localPlayer)
		{
			ZoneData currentLocation = ExpertExplorer.GetCurrentLocation(localPlayer);
			string text = ((currentLocation != null) ? currentLocation.LocalizedLocationName : string.Empty);
			m_LocationNameSmall.text = text;
		}
	}
	[HarmonyPatch]
	public static class PlayerPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "Load")]
		private static void Load(ref Player __instance, ref ZPackage pkg)
		{
			__instance.InitializeExplorationData();
			__instance.ExplorationData().Load(__instance);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Player), "Save")]
		private static void Save(ref Player __instance, ref ZPackage pkg)
		{
			__instance.InitializeExplorationData();
			__instance.ExplorationData().Save(__instance);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Player), "AddKnownBiome")]
		private static void AddKnownBiome(ref Player __instance, ref Biome biome)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.IsBiomeKnown(biome))
			{
				PlayerExplorationData playerExplorationData = Player.m_localPlayer.ExplorationData();
				if ((Object)(object)playerExplorationData != (Object)null)
				{
					playerExplorationData.FlagAsDiscovered(biome);
					((Character)__instance).RaiseSkill(ExpertExplorer.ExplorationSkillType, 1f);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "OnSpawned")]
		private static void OnSpawned(ref Player __instance)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Character)__instance).InIntro() && !Game.instance.m_firstSpawn)
			{
				Vector2i zone = ZoneSystem.GetZone(((Component)__instance).transform.position);
				ZoneHelper.Instance.Client_RequestZoneData(zone);
			}
		}
	}
}