Decompiled source of CryptOrePins v0.2.0

plugins/CryptOrePins/CryptOrePins.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Blackforge.Hot;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[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 Blackforge
{
	public static class Crypts
	{
		private enum Kind
		{
			Pickable,
			RandomPick,
			Chest,
			Breakable,
			Item,
			Spawner
		}

		private class Tally
		{
			public LocationInstance place;

			public ZDO proxy;

			public int left;

			public int maybe;

			public int taken;

			public bool visited;
		}

		private class Place
		{
			public string item;

			public Vector3 position;

			public byte state;

			public bool ore;
		}

		private const string Ask = "bf_crypts_ask";

		private const string Answer = "bf_crypts";

		private const string Found = "bf_crypts_found";

		private const string Measured = "bf_chests_measured";

		private static readonly string[] RpcNames = new string[4] { "bf_crypts_ask", "bf_crypts", "bf_crypts_found", "bf_chests_measured" };

		private static readonly string[] Loot = new string[10] { "SurtlingCore", "IronScrap", "WitheredBone", "Chain", "WolfHairBundle", "WolfClaw", "JuteRed", "BlackCore", "DvergrKeyFragment", "RoyalJelly" };

		private static readonly string[] Ores = new string[3] { "CopperOre", "TinOre", "SilverOre" };

		private const string Copper = "CopperOre";

		private const float FewCopper = 25f;

		private const string Hidden = "SilverOre";

		private static readonly int FoundMark = StringExtensionMethods.GetStableHashCode("bf_found");

		private const string IronPlace = "SunkenCrypt";

		private const string Iron = "IronScrap";

		private const float FewIron = 70f;

		private static readonly (string start, string item)[] Icons = new(string, string)[6]
		{
			("SunkenCrypt", "IronScrap"),
			("Crypt", "SurtlingCore"),
			("TrollCave", "TrophyFrostTroll"),
			("MountainCave", "WolfClaw"),
			("Mistlands_DvergrTownEntrance", "BlackCore"),
			("MorgenHole", "TrophyMorgen")
		};

		private const byte Untouched = 0;

		private const byte Partly = 1;

		private const byte Empty = 2;

		private static HotHost host;

		private static ManualLogSource log;

		private static readonly int Mark = StringExtensionMethods.GetStableHashCode("bf_loot_mark");

		private const float InsideFrom = 3000f;

		private const float AnswerAge = 20f;

		private static Dictionary<int, Kind> watched;

		private static Dictionary<int, (byte ore, byte state)> ores;

		private static HashSet<int> lootHashes;

		private static readonly Dictionary<int, bool> inside = new Dictionary<int, bool>();

		private static Queue<ZoneLocation> unknown;

		private static ZPackage answer;

		private static float answerAt;

		private static bool detailed;

		private const float AskEvery = 30f;

		private const float AskSoon = 5f;

		private const int IconSize = 64;

		private static readonly List<Place> places = new List<Place>();

		private static readonly List<PinData> pins = new List<PinData>();

		private static readonly Dictionary<string, Sprite> sprites = new Dictionary<string, Sprite>();

		private static float askedAt = -1000f;

		private static bool redraw;

		private const string PlacesKey = "bf_map_places";

		private const string OresKey = "bf_map_ores";

		private static bool showPlaces = true;

		private static bool showOres = true;

		private static ConfigEntry<bool> placesEntry;

		private static ConfigEntry<bool> oresEntry;

		private static ConfigEntry<bool> placesRow;

		private static ConfigEntry<bool> oresRow;

		private static ConfigEntry<float> rowsRight;

		private static ConfigEntry<float> rowsUp;

		private static readonly HashSet<ZDOID> told = new HashSet<ZDOID>();

		private const float Close = 0.2f;

		public static void Load(HotHost from)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Expected O, but got Unknown
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Expected O, but got Unknown
			host = from;
			log = from.Log;
			host.Harmony.Patch((MethodBase)AccessTools.Method(typeof(Game), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Crypts), "Register", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			host.Harmony.Patch((MethodBase)AccessTools.Method(typeof(ZoneSystem), "Update", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Crypts), "ServerTick", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			if (!host.IsDedicatedServer)
			{
				host.Harmony.Patch((MethodBase)AccessTools.Method(typeof(Minimap), "Update", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Crypts), "MapTick", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				host.Harmony.Patch((MethodBase)AccessTools.Method(typeof(SE_Finder), "UpdateStatusEffect", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Crypts), "Wishbone", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				showPlaces = placesEntry.Value;
				showOres = oresEntry.Value;
				Func<Vector2> offset = () => new Vector2(rowsRight.Value, rowsUp.Value);
				MapSwitches.Add(1, "Crypts", "SurtlingCore", () => showPlaces, SetPlaces, () => placesRow.Value, offset);
				MapSwitches.Add(2, "Metals", "CopperOre", () => showOres, SetOres, () => oresRow.Value, offset);
			}
			if (ZRoutedRpc.instance != null)
			{
				Register();
			}
		}

		public static void Unload()
		{
			RemovePins();
			MapSwitches.Clear();
			foreach (Sprite value in sprites.Values)
			{
				if ((Object)(object)value != (Object)null)
				{
					Object.Destroy((Object)(object)value.texture);
					Object.Destroy((Object)(object)value);
				}
			}
			sprites.Clear();
			places.Clear();
			host?.UnregisterRpc(RpcNames);
			watched = null;
			ores = null;
			inside.Clear();
			unknown = null;
			answer = null;
			detailed = false;
			host = null;
		}

		private static void Register()
		{
			if (host != null && ZRoutedRpc.instance != null && !((Object)(object)ZNet.instance == (Object)null))
			{
				host.UnregisterRpc(RpcNames);
				if (ZNet.instance.IsServer())
				{
					ZRoutedRpc.instance.Register("bf_crypts_ask", (Action<long>)OnAsk);
					ZRoutedRpc.instance.Register<ZDOID>("bf_crypts_found", (Action<long, ZDOID>)OnFound);
					ZRoutedRpc.instance.Register<string>("bf_chests_measured", (Action<long, string>)OnMeasured);
				}
				if (!host.IsDedicatedServer)
				{
					ZRoutedRpc.instance.Register<ZPackage>("bf_crypts", (Action<long, ZPackage>)OnAnswer);
				}
				places.Clear();
				watched = null;
				ores = null;
				inside.Clear();
				unknown = null;
				answer = null;
				askedAt = -1000f;
				told.Clear();
			}
		}

		private static void ServerTick(ZoneSystem __instance)
		{
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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)
			if (host == null || (Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer())
			{
				return;
			}
			if (unknown == null)
			{
				unknown = new Queue<ZoneLocation>();
				HashSet<int> hashSet = new HashSet<int>();
				foreach (LocationInstance value in __instance.m_locationInstances.Values)
				{
					if (value.m_location != null && value.m_location.m_prefab.IsValid && hashSet.Add(value.m_location.Hash))
					{
						unknown.Enqueue(value.m_location);
					}
				}
				if (unknown.Count == 0)
				{
					unknown = null;
				}
			}
			else
			{
				if (unknown.Count == 0)
				{
					return;
				}
				ZoneLocation val = unknown.Dequeue();
				try
				{
					val.m_prefab.Load();
					Location component = val.m_prefab.Asset.GetComponent<Location>();
					inside[val.Hash] = (Object)(object)component != (Object)null && component.m_hasInterior;
					val.m_prefab.Release();
				}
				catch (Exception ex)
				{
					inside[val.Hash] = false;
					log.LogWarning((object)("crypts: the location " + val.m_prefabName + " could not be read: " + ex.Message));
				}
				if (unknown.Count == 0)
				{
					string arg = string.Join(", ", from kind in inside
						where kind.Value
						select NameOf(__instance, kind.Key) into name
						orderby name
						select name);
					log.LogInfo((object)$"crypts: {inside.Count((KeyValuePair<int, bool> kind) => kind.Value)} of {inside.Count} kinds of places have an inside: {arg}");
					answer = null;
				}
			}
		}

		private static string NameOf(ZoneSystem zones, int hash)
		{
			if (!zones.m_locationsByHash.TryGetValue(hash, out var value))
			{
				return hash.ToString();
			}
			return value.m_prefabName;
		}

		private static void OnAsk(long sender)
		{
			if (host == null || (Object)(object)ZoneSystem.instance == (Object)null || (Object)(object)ZNetScene.instance == (Object)null || (Object)(object)ObjectDB.instance == (Object)null || unknown == null || unknown.Count > 0)
			{
				return;
			}
			try
			{
				if (answer == null || Time.realtimeSinceStartup - answerAt > 20f)
				{
					answer = Count();
					answerAt = Time.realtimeSinceStartup;
				}
				ZRoutedRpc.instance.InvokeRoutedRPC(sender, "bf_crypts", new object[1] { answer });
			}
			catch (Exception arg)
			{
				log.LogError((object)$"crypts: the count failed: {arg}");
			}
		}

		private static void OnMeasured(long sender, string text)
		{
			string text2 = ((!((Object)(object)ZNet.instance != (Object)null)) ? null : ZNet.instance.GetPeer(sender)?.m_playerName);
			ManualLogSource obj = log;
			if (obj != null)
			{
				obj.LogInfo((object)("chests: " + (text2 ?? sender.ToString()) + " measured " + text));
			}
		}

		private static void OnFound(long sender, ZDOID id)
		{
			//IL_003a: 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)
			if (host != null && ZDOMan.instance != null && !((Object)(object)ZNetScene.instance == (Object)null) && !((Object)(object)ObjectDB.instance == (Object)null))
			{
				if (watched == null)
				{
					Watch();
				}
				ZDO zDO = ZDOMan.instance.GetZDO(id);
				int num = Array.IndexOf(Ores, "SilverOre");
				if (zDO != null && ores.TryGetValue(zDO.GetPrefab(), out (byte, byte) value) && value.Item1 == num && !zDO.GetBool(FoundMark, false))
				{
					zDO.Set(FoundMark, true);
					answer = null;
					log.LogInfo((object)$"crypts: a wishbone found the vein at {zDO.GetPosition()}");
				}
			}
		}

		internal static List<(string ore, ZDO deposit, bool hit, float far)> Around(Vector3 from, float within)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			if (ZDOMan.instance == null || (Object)(object)ZNetScene.instance == (Object)null || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return null;
			}
			if (watched == null)
			{
				Watch();
			}
			List<(string, ZDO, bool, float)> list = new List<(string, ZDO, bool, float)>();
			List<ZDO>[] objectsBySector = ZDOMan.instance.m_objectsBySector;
			foreach (List<ZDO> list2 in objectsBySector)
			{
				if (list2 == null)
				{
					continue;
				}
				foreach (ZDO item in list2)
				{
					if (ores.TryGetValue(item.GetPrefab(), out (byte, byte) value))
					{
						float num = Utils.DistanceXZ(from, item.GetPosition());
						if (num <= within)
						{
							list.Add((Ores[value.Item1], item, value.Item2 != 0, num));
						}
					}
				}
			}
			list.Sort(((string ore, ZDO deposit, bool hit, float far) a, (string ore, ZDO deposit, bool hit, float far) b) => a.far.CompareTo(b.far));
			return list;
		}

		internal static bool Pinned(ZDO zdo)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (!ores.TryGetValue(zdo.GetPrefab(), out (byte, byte) value) || zdo.GetPosition().y >= 3000f)
			{
				return false;
			}
			if (Ores[value.Item1] == "SilverOre" && value.Item2 == 0 && !zdo.GetBool(FoundMark, false))
			{
				return false;
			}
			if (Ores[value.Item1] == "CopperOre" && value.Item2 != 0)
			{
				(int, int, float)? tuple = Pieces(zdo, "CopperOre");
				if (tuple.HasValue)
				{
					float item = tuple.GetValueOrDefault().Item3;
					return !(item < 25f);
				}
			}
			return true;
		}

		internal static (int left, int pieces, float ore)? Pieces(ZDO deposit, string ore)
		{
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			try
			{
				GameObject prefab = ZNetScene.instance.GetPrefab(deposit.GetPrefab());
				MineRock5 val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<MineRock5>() : null);
				string text = deposit.GetString(ZDOVars.s_health, "");
				if ((Object)(object)val == (Object)null || text.Length == 0)
				{
					return null;
				}
				ZPackage val2 = new ZPackage(Convert.FromBase64String(text));
				int num = val2.ReadInt();
				if (num <= 0 || num > 2000)
				{
					return null;
				}
				int num2 = 0;
				for (int i = 0; i < num; i++)
				{
					if (val2.ReadSingle() > 0f)
					{
						num2++;
					}
				}
				return (num2, num, (float)num2 * PerRoll(val.m_dropItems, ore) * Game.m_resourceRate);
			}
			catch (Exception ex)
			{
				log.LogWarning((object)$"crypts: the pieces of the deposit at {deposit.GetPosition()} could not be read: {ex.Message}");
				return null;
			}
		}

		private static float PerRoll(DropTable drops, string item)
		{
			if (drops == null)
			{
				return 0f;
			}
			float weights = drops.m_drops.Sum((DropData drop) => drop.m_weight);
			if (!(weights <= 0f))
			{
				return drops.m_dropChance * (float)(drops.m_dropMin + drops.m_dropMax) / 2f * drops.m_drops.Where((DropData drop) => (Object)(object)drop.m_item != (Object)null && ((Object)drop.m_item).name == item).Sum((DropData drop) => drop.m_weight / weights * (float)(drop.m_stackMin + drop.m_stackMax) / 2f);
			}
			return 0f;
		}

		private static bool Drops(DropTable table)
		{
			return table?.m_drops.Any((DropData drop) => (Object)(object)drop.m_item != (Object)null && lootHashes.Contains(StringExtensionMethods.GetStableHashCode(((Object)drop.m_item).name))) ?? false;
		}

		private static int Ore(DropTable table)
		{
			if (table != null)
			{
				return Array.FindIndex(Ores, (string ore) => table.m_drops.Any((DropData drop) => (Object)(object)drop.m_item != (Object)null && ((Object)drop.m_item).name == ore));
			}
			return -1;
		}

		private static void Watch()
		{
			watched = new Dictionary<int, Kind>();
			ores = new Dictionary<int, (byte, byte)>();
			lootHashes = new HashSet<int>();
			string[] loot = Loot;
			foreach (string text in loot)
			{
				if ((Object)(object)ObjectDB.instance.GetItemPrefab(text) == (Object)null)
				{
					log.LogWarning((object)("crypts: the game has no item " + text));
				}
				else
				{
					lootHashes.Add(StringExtensionMethods.GetStableHashCode(text));
				}
			}
			List<(int, GameObject)> list = new List<(int, GameObject)>();
			foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
			{
				if ((Object)(object)prefab == (Object)null)
				{
					continue;
				}
				int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)prefab).name);
				Pickable componentInChildren = prefab.GetComponentInChildren<Pickable>(true);
				PickableItem componentInChildren2 = prefab.GetComponentInChildren<PickableItem>(true);
				Container componentInChildren3 = prefab.GetComponentInChildren<Container>(true);
				DropOnDestroyed componentInChildren4 = prefab.GetComponentInChildren<DropOnDestroyed>(true);
				MineRock componentInChildren5 = prefab.GetComponentInChildren<MineRock>(true);
				MineRock5 componentInChildren6 = prefab.GetComponentInChildren<MineRock5>(true);
				Destructible componentInChildren7 = prefab.GetComponentInChildren<Destructible>(true);
				int num = Math.Max(((Object)(object)componentInChildren5 != (Object)null) ? Ore(componentInChildren5.m_dropItems) : (-1), ((Object)(object)componentInChildren6 != (Object)null) ? Ore(componentInChildren6.m_dropItems) : (-1));
				if (num < 0 && (Object)(object)componentInChildren4 != (Object)null && componentInChildren4.m_dropWhenDestroyed.m_drops.Count > 0 && componentInChildren4.m_dropWhenDestroyed.m_drops.All((DropData only) => (Object)(object)only.m_item != (Object)null && Ores.Contains(((Object)only.m_item).name)))
				{
					num = Ore(componentInChildren4.m_dropWhenDestroyed);
				}
				if (num >= 0)
				{
					ores[stableHashCode] = ((byte)num, ((Object)(object)componentInChildren6 != (Object)null) ? ((byte)1) : ((byte)0));
				}
				if ((Object)(object)componentInChildren7 != (Object)null && (Object)(object)componentInChildren7.m_spawnWhenDestroyed != (Object)null)
				{
					list.Add((stableHashCode, componentInChildren7.m_spawnWhenDestroyed));
				}
				if (lootHashes.Contains(stableHashCode) && (Object)(object)prefab.GetComponent<ItemDrop>() != (Object)null)
				{
					watched[stableHashCode] = Kind.Item;
				}
				else if ((Object)(object)componentInChildren != (Object)null && (((Object)(object)componentInChildren.m_itemPrefab != (Object)null && lootHashes.Contains(StringExtensionMethods.GetStableHashCode(((Object)componentInChildren.m_itemPrefab).name))) || Drops(componentInChildren.m_extraDrops)))
				{
					watched[stableHashCode] = Kind.Pickable;
				}
				else if ((Object)(object)componentInChildren2 != (Object)null && (Object)(object)componentInChildren2.m_itemPrefab != (Object)null && lootHashes.Contains(StringExtensionMethods.GetStableHashCode(((Object)componentInChildren2.m_itemPrefab).name)))
				{
					watched[stableHashCode] = Kind.Breakable;
				}
				else if ((Object)(object)componentInChildren2 != (Object)null && componentInChildren2.m_randomItemPrefabs.Any((RandomItem item) => (Object)(object)item.m_itemPrefab != (Object)null && lootHashes.Contains(StringExtensionMethods.GetStableHashCode(((Object)item.m_itemPrefab).name))))
				{
					watched[stableHashCode] = Kind.RandomPick;
				}
				else if ((Object)(object)componentInChildren3 != (Object)null && Drops(componentInChildren3.m_defaultItems))
				{
					watched[stableHashCode] = Kind.Chest;
				}
				else if (!((Object)(object)prefab.GetComponentInChildren<Door>(true) != (Object)null))
				{
					if (((Object)(object)componentInChildren4 != (Object)null && Drops(componentInChildren4.m_dropWhenDestroyed)) || ((Object)(object)componentInChildren5 != (Object)null && Drops(componentInChildren5.m_dropItems)) || ((Object)(object)componentInChildren6 != (Object)null && Drops(componentInChildren6.m_dropItems)))
					{
						watched[stableHashCode] = Kind.Breakable;
					}
					else if ((Object)(object)prefab.GetComponentInChildren<CreatureSpawner>(true) != (Object)null)
					{
						watched[stableHashCode] = Kind.Spawner;
					}
				}
			}
			foreach (var (key, val) in list)
			{
				if (!watched.ContainsKey(key) && watched.TryGetValue(StringExtensionMethods.GetStableHashCode(((Object)val).name), out var value) && value == Kind.Breakable)
				{
					watched[key] = Kind.Breakable;
				}
				if (!ores.ContainsKey(key) && ores.TryGetValue(StringExtensionMethods.GetStableHashCode(((Object)val).name), out (byte, byte) value2))
				{
					ores[key] = (value2.Item1, 0);
				}
			}
			Kind[] array = new Kind[4]
			{
				Kind.Pickable,
				Kind.RandomPick,
				Kind.Chest,
				Kind.Breakable
			};
			foreach (Kind kind in array)
			{
				IEnumerable<string> values = from entry in watched
					where entry.Value == kind
					select ((Object)ZNetScene.instance.GetPrefab(entry.Key)).name into name
					orderby name
					select name;
				log.LogInfo((object)string.Format("crypts: loot of the kind {0}: {1}", kind, string.Join(", ", values)));
			}
			log.LogInfo((object)("crypts: deposits: " + string.Join(", ", from entry in ores
				select ((Object)ZNetScene.instance.GetPrefab(entry.Key)).name + " " + Ores[entry.Value.ore] into name
				orderby name
				select name)));
		}

		private static ZPackage Count()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			if (watched == null)
			{
				Watch();
			}
			ZoneSystem instance = ZoneSystem.instance;
			Dictionary<Vector2s, Tally> dictionary = Tallies(instance);
			ZPackage val = new ZPackage();
			List<string> list = (from name in dictionary.Values.Select((Tally tally) => tally.place.m_location.m_prefabName).Distinct()
				orderby name
				select name).ToList();
			val.Write(list.Count);
			foreach (string item in list)
			{
				val.Write(item);
			}
			val.Write(dictionary.Count);
			int[] array = new int[3];
			foreach (KeyValuePair<Vector2s, Tally> item2 in dictionary)
			{
				Tally value = item2.Value;
				byte b = Shown(instance, item2.Key, value);
				array[b]++;
				val.Write(list.IndexOf(value.place.m_location.m_prefabName));
				val.Write(value.place.m_position);
				val.Write(b);
			}
			List<(byte, Vector3, byte)> list2 = new List<(byte, Vector3, byte)>();
			List<ZDO>[] objectsBySector = ZDOMan.instance.m_objectsBySector;
			foreach (List<ZDO> list3 in objectsBySector)
			{
				if (list3 == null)
				{
					continue;
				}
				foreach (ZDO item3 in list3)
				{
					if (ores.TryGetValue(item3.GetPrefab(), out (byte, byte) value2) && Pinned(item3))
					{
						list2.Add((value2.Item1, item3.GetPosition(), value2.Item2));
					}
				}
			}
			val.Write(list2.Count);
			foreach (var (b2, val2, b3) in list2)
			{
				val.Write(b2);
				val.Write(val2.x);
				val.Write(val2.z);
				val.Write(b3);
			}
			if (!detailed)
			{
				detailed = true;
				foreach (IGrouping<string, Tally> item4 in from tally in dictionary.Values
					group tally by tally.place.m_location.m_prefabName into kind
					orderby kind.Key
					select kind)
				{
					log.LogInfo((object)$"crypts: {item4.Key}: {item4.Count()} places, {item4.Count((Tally tally) => tally.place.m_placed)} placed, {item4.Count((Tally tally) => tally.proxy != null)} with a proxy, left {item4.Sum((Tally tally) => tally.left)}, maybe {item4.Sum((Tally tally) => tally.maybe)}, taken {item4.Sum((Tally tally) => tally.taken)}, {item4.Count((Tally tally) => tally.visited)} visited");
				}
			}
			log.LogInfo((object)$"crypts: {dictionary.Count} places, {array[0]} untouched, {array[1]} partly looted, {array[2]} empty, {list2.Count} deposits");
			return val;
		}

		private static Dictionary<Vector2s, Tally> Tallies(ZoneSystem zones)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<Vector2s, Tally> dictionary = new Dictionary<Vector2s, Tally>();
			bool value = default(bool);
			foreach (KeyValuePair<Vector2s, LocationInstance> locationInstance in zones.m_locationInstances)
			{
				if (locationInstance.Value.m_location != null && inside.TryGetValue(locationInstance.Value.m_location.Hash, out value) && value)
				{
					dictionary[locationInstance.Key] = new Tally
					{
						place = locationInstance.Value
					};
				}
			}
			int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)zones.m_locationProxyPrefab).name);
			HashSet<SectorIndex> hashSet = new HashSet<SectorIndex>();
			List<ZDO> list = new List<ZDO>();
			foreach (KeyValuePair<Vector2s, Tally> item in dictionary)
			{
				if (!item.Value.place.m_placed)
				{
					continue;
				}
				for (int i = -1; i <= 1; i++)
				{
					for (int j = -1; j <= 1; j++)
					{
						list.Clear();
						ZDOMan.instance.FindObjects(new Vector2s(item.Key.x + i, item.Key.y + j), list, hashSet);
						foreach (ZDO item2 in list)
						{
							Add(item2, dictionary, stableHashCode);
						}
					}
				}
			}
			return dictionary;
		}

		internal static string Places(string part, string item)
		{
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: 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)
			if ((Object)(object)ZoneSystem.instance == (Object)null || ZDOMan.instance == null || (Object)(object)ZNetScene.instance == (Object)null || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return "the world is not loaded yet";
			}
			if (unknown == null || unknown.Count > 0)
			{
				return "the kinds of places are not read yet, ask again in a minute";
			}
			if (watched == null)
			{
				Watch();
			}
			ZoneSystem instance = ZoneSystem.instance;
			List<(float, string)> list = new List<(float, string)>();
			int num = 0;
			int num2 = 0;
			float num3 = 0f;
			foreach (KeyValuePair<Vector2s, Tally> item2 in Tallies(instance))
			{
				Tally value = item2.Value;
				string name = value.place.m_location.m_prefabName;
				if (part != null && name.IndexOf(part, StringComparison.OrdinalIgnoreCase) < 0)
				{
					continue;
				}
				num++;
				if (!value.place.m_placed)
				{
					num2++;
					continue;
				}
				byte b = State(value);
				if (b != 2)
				{
					string text = item ?? Icons.FirstOrDefault(((string start, string item) icon) => name.StartsWith(icon.start)).item;
					byte b2 = Shown(instance, item2.Key, value);
					string text2 = string.Format("x {0:0} z {1:0}, {2}", value.place.m_position.x, value.place.m_position.z, (b2 == 2) ? string.Format("grey on the map, under {0:0} {1}", 70f, "IronScrap") : ((b == 0) ? "untouched" : "partly looted"));
					if (text == null || !lootHashes.Contains(StringExtensionMethods.GetStableHashCode(text)))
					{
						list.Add((0f, text2 + ", " + LootOf(instance, item2.Key, name)));
						continue;
					}
					float num4 = Left(instance, item2.Key, text);
					num3 += num4;
					list.Add((num4, $"{text2}, about {num4:0} {text}"));
				}
			}
			string text3 = string.Format("{0} of {1} places{2} still have loot, about {3:0} of the item in all, {4} more are not made yet as nobody came near. Resource rate {5:0.##}{6}", list.Count, num, (part != null) ? (" with " + part + " in the name") : "", num3, num2, Game.m_resourceRate, (item != null) ? $", {item} drops {Blackforge.Drops.Rate(item)} times" : "");
			return string.Join("\n", new string[1] { text3 }.Concat(from line in list
				orderby line.sum descending
				select line.line));
		}

		private static float Left(ZoneSystem zones, Vector2s home, string item)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			int stableHashCode = StringExtensionMethods.GetStableHashCode(item);
			int num = Blackforge.Drops.Rate(item);
			int num2 = 0;
			float num3 = 0f;
			foreach (var (val, kind, val2) in Objects(zones, home))
			{
				switch (kind)
				{
				case Kind.Pickable:
				{
					Pickable componentInChildren = val2.GetComponentInChildren<Pickable>(true);
					if (!val.GetBool(ZDOVars.s_picked, false) && (Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.m_itemPrefab != (Object)null && ((Object)componentInChildren.m_itemPrefab).name == item)
					{
						num2 += Math.Max(1, componentInChildren.m_amount);
					}
					break;
				}
				case Kind.RandomPick:
					if (val.GetInt(ZDOVars.s_itemPrefab, 0) == stableHashCode)
					{
						num2++;
					}
					break;
				case Kind.Chest:
				{
					if (val.GetBool(ZDOVars.s_addedDefaultItems, false))
					{
						num2 += Held(val, item);
						break;
					}
					Container componentInChildren3 = val2.GetComponentInChildren<Container>(true);
					num3 += (((Object)(object)componentInChildren3 != (Object)null) ? PerRoll(componentInChildren3.m_defaultItems, item) : 0f) * (float)num;
					break;
				}
				case Kind.Breakable:
				{
					PickableItem componentInChildren2 = val2.GetComponentInChildren<PickableItem>(true);
					if ((Object)(object)componentInChildren2 != (Object)null && (Object)(object)componentInChildren2.m_itemPrefab != (Object)null)
					{
						if (((Object)componentInChildren2.m_itemPrefab).name == item)
						{
							num2 += Math.Max(1, componentInChildren2.m_stack);
						}
					}
					else
					{
						num3 += Breaks(val, val2, item) * (float)num;
					}
					break;
				}
				case Kind.Item:
					if (((Object)val2).name == item)
					{
						num2 += val.GetInt(ZDOVars.s_stack, 1);
					}
					break;
				}
			}
			return (float)num2 + num3;
		}

		private static IEnumerable<(ZDO zdo, Kind kind, GameObject prefab)> Objects(ZoneSystem zones, Vector2s home)
		{
			//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)
			HashSet<SectorIndex> seen = new HashSet<SectorIndex>();
			List<ZDO> objects = new List<ZDO>();
			for (int x = -1; x <= 1; x++)
			{
				for (int y = -1; y <= 1; y++)
				{
					objects.Clear();
					ZDOMan.instance.FindObjects(new Vector2s(home.x + x, home.y + y), objects, seen);
					foreach (ZDO item in objects.ToList())
					{
						Vector3 position = item.GetPosition();
						if (!(position.y < 3000f) && watched.TryGetValue(item.GetPrefab(), out var value) && PlaceAt(zones, position, out var place, out var _) && ((Vector2s)(ref place)).Equals(home))
						{
							GameObject prefab = ZNetScene.instance.GetPrefab(item.GetPrefab());
							if ((Object)(object)prefab != (Object)null)
							{
								yield return (zdo: item, kind: value, prefab: prefab);
							}
						}
					}
				}
			}
		}

		private static int Held(ZDO zdo, string item)
		{
			//IL_002c: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			byte[] byteArray = zdo.GetByteArray(ZDOVars.s_items, (byte[])null);
			if (byteArray == null || byteArray.Length == 0)
			{
				return 0;
			}
			try
			{
				Inventory val = new Inventory("crypts", (Sprite)null, 8, 8);
				val.Load(new ZPackage(byteArray));
				return (from held in val.GetAllItems()
					where (Object)(object)held.m_dropPrefab != (Object)null && ((Object)held.m_dropPrefab).name == item
					select held).Sum((ItemData held) => held.m_stack);
			}
			catch (Exception)
			{
				return 0;
			}
		}

		private static float Breaks(ZDO zdo, GameObject prefab, string item)
		{
			MineRock5 componentInChildren = prefab.GetComponentInChildren<MineRock5>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				return ((zdo == null) ? ((float?)null) : Pieces(zdo, item)?.ore) ?? ((float)((Component)componentInChildren).GetComponentsInChildren<Collider>(true).Length * PerRoll(componentInChildren.m_dropItems, item) * Game.m_resourceRate);
			}
			Destructible componentInChildren2 = prefab.GetComponentInChildren<Destructible>(true);
			if ((Object)(object)componentInChildren2 != (Object)null && (Object)(object)componentInChildren2.m_spawnWhenDestroyed != (Object)null && (Object)(object)componentInChildren2.m_spawnWhenDestroyed != (Object)(object)prefab)
			{
				return Breaks(null, componentInChildren2.m_spawnWhenDestroyed, item);
			}
			MineRock rock = prefab.GetComponentInChildren<MineRock>(true);
			if ((Object)(object)rock != (Object)null)
			{
				int num = (((Object)(object)rock.m_areaRoot != (Object)null) ? rock.m_areaRoot : ((Component)rock).gameObject).GetComponentsInChildren<Collider>(true).Length;
				return (float)((zdo == null) ? num : Enumerable.Range(0, num).Count((int index) => zdo.GetFloat("Health" + index, rock.m_health) > 0f)) * PerRoll(rock.m_dropItems, item) * Game.m_resourceRate;
			}
			DropOnDestroyed componentInChildren3 = prefab.GetComponentInChildren<DropOnDestroyed>(true);
			if (!((Object)(object)componentInChildren3 != (Object)null))
			{
				return 0f;
			}
			return PerRoll(componentInChildren3.m_dropWhenDestroyed, item) * Game.m_resourceRate;
		}

		private static void Add(ZDO zdo, Dictionary<Vector2s, Tally> tallies, int proxyHash)
		{
			//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_0044: 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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: 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_00b0: 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)
			Vector3 position = zdo.GetPosition();
			int prefab = zdo.GetPrefab();
			if (prefab == proxyHash)
			{
				if (tallies.TryGetValue(ZoneSystem.GetZone(position), out var value) && Utils.DistanceXZ(position, value.place.m_position) < 1f)
				{
					value.proxy = zdo;
				}
			}
			else
			{
				if (position.y < 3000f || !watched.TryGetValue(prefab, out var value2))
				{
					return;
				}
				Vector2s zone = ZoneSystem.GetZone(position);
				Tally tally = null;
				float num = float.MaxValue;
				Vector2s val = default(Vector2s);
				for (int i = -1; i <= 1; i++)
				{
					for (int j = -1; j <= 1; j++)
					{
						((Vector2s)(ref val))..ctor(zone.x + i, zone.y + j);
						if (tallies.TryGetValue(val, out var value3) && value3.place.m_placed)
						{
							float num2 = Utils.DistanceXZ(position, ZoneSystem.GetZonePos(val));
							if (num2 < num)
							{
								num = num2;
								tally = value3;
							}
						}
					}
				}
				if (tally == null)
				{
					return;
				}
				switch (value2)
				{
				case Kind.Pickable:
					if (zdo.GetBool(ZDOVars.s_picked, false))
					{
						tally.taken++;
					}
					else
					{
						tally.left++;
					}
					break;
				case Kind.RandomPick:
				{
					int num3 = zdo.GetInt(ZDOVars.s_itemPrefab, 0);
					if (num3 == 0)
					{
						tally.maybe++;
					}
					else if (lootHashes.Contains(num3))
					{
						tally.left++;
					}
					break;
				}
				case Kind.Chest:
					if (!zdo.GetBool(ZDOVars.s_addedDefaultItems, false))
					{
						tally.maybe++;
					}
					else if (HoldsLoot(zdo))
					{
						tally.left++;
					}
					break;
				case Kind.Breakable:
				case Kind.Item:
					tally.left++;
					break;
				case Kind.Spawner:
					if (zdo.GetLong(ZDOVars.s_aliveTime, 0L) != 0L || zdo.GetConnectionZDOID((ConnectionType)3) != ZDOID.None)
					{
						tally.visited = true;
					}
					break;
				}
			}
		}

		private static bool PlaceAt(ZoneSystem zones, Vector3 position, out Vector2s place, out string name)
		{
			//IL_0001: 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_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_0082: 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)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: 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)
			place = default(Vector2s);
			name = "";
			Vector2s zone = ZoneSystem.GetZone(position);
			float num = float.MaxValue;
			Vector2s val = default(Vector2s);
			for (int i = -1; i <= 1; i++)
			{
				for (int j = -1; j <= 1; j++)
				{
					((Vector2s)(ref val))..ctor(zone.x + i, zone.y + j);
					if (zones.m_locationInstances.TryGetValue(val, out var value) && value.m_placed && value.m_location != null && inside.TryGetValue(value.m_location.Hash, out var value2) && value2)
					{
						float num2 = Utils.DistanceXZ(position, ZoneSystem.GetZonePos(val));
						if (num2 < num)
						{
							num = num2;
							place = val;
							name = value.m_location.m_prefabName;
						}
					}
				}
			}
			return num < float.MaxValue;
		}

		internal static string Inside(Vector3 at)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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)
			if (at.y < 3000f || (Object)(object)ZoneSystem.instance == (Object)null || ZDOMan.instance == null || (Object)(object)ZNetScene.instance == (Object)null || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return null;
			}
			if (watched == null)
			{
				Watch();
			}
			ZoneSystem instance = ZoneSystem.instance;
			if (!PlaceAt(instance, at, out var place, out var name))
			{
				return "in an inside of no known place";
			}
			return LootOf(instance, place, name);
		}

		internal static string LootNear(Vector3 at, float within)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ZoneSystem.instance == (Object)null || ZDOMan.instance == null || (Object)(object)ZNetScene.instance == (Object)null || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return null;
			}
			if (watched == null)
			{
				Watch();
			}
			ZoneSystem instance = ZoneSystem.instance;
			if (!PlaceNear(instance, at, within, out var home, out var best, out var nearest))
			{
				return null;
			}
			return $"{nearest:0} m away at x {best.m_position.x:0} z {best.m_position.z:0}, {LootOf(instance, home, best.m_location.m_prefabName)}";
		}

		private static bool PlaceNear(ZoneSystem zones, Vector3 at, float within, out Vector2s home, out LocationInstance best, out float nearest)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//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_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)
			home = default(Vector2s);
			best = default(LocationInstance);
			nearest = within;
			foreach (KeyValuePair<Vector2s, LocationInstance> locationInstance in zones.m_locationInstances)
			{
				if (locationInstance.Value.m_placed && locationInstance.Value.m_location != null && inside.TryGetValue(locationInstance.Value.m_location.Hash, out var value) && value)
				{
					float num = Utils.DistanceXZ(at, locationInstance.Value.m_position);
					if (num < nearest)
					{
						nearest = num;
						home = locationInstance.Key;
						best = locationInstance.Value;
					}
				}
			}
			return best.m_location != null;
		}

		internal static string Things(Vector3 at, float within, string item)
		{
			//IL_004c: 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)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//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_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0584: Unknown result type (might be due to invalid IL or missing references)
			//IL_0586: Unknown result type (might be due to invalid IL or missing references)
			//IL_0598: Unknown result type (might be due to invalid IL or missing references)
			//IL_059a: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04da: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_050b: Unknown result type (might be due to invalid IL or missing references)
			//IL_051a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ZoneSystem.instance == (Object)null || ZDOMan.instance == null || (Object)(object)ZNetScene.instance == (Object)null || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return "the world is not loaded yet";
			}
			if (watched == null)
			{
				Watch();
			}
			ZoneSystem instance = ZoneSystem.instance;
			bool flag = at.y >= 3000f;
			Vector2s home;
			LocationInstance best;
			float nearest;
			if (flag)
			{
				if (!PlaceAt(instance, at, out home, out var _))
				{
					return "in an inside of no known place";
				}
				best = instance.m_locationInstances[home];
			}
			else if (!PlaceNear(instance, at, within, out home, out best, out nearest))
			{
				return $"no crypt or cave within {within:0} m";
			}
			string name2 = best.m_location.m_prefabName;
			string text = item ?? Icons.FirstOrDefault(((string start, string item) icon) => name2.StartsWith(icon.start)).item;
			if (text != null && !lootHashes.Contains(StringExtensionMethods.GetStableHashCode(text)))
			{
				text = null;
			}
			int num = ((text == null) ? 1 : Blackforge.Drops.Rate(text));
			List<(float, float, string)> list = new List<(float, float, string)>();
			foreach (var item7 in Objects(instance, home))
			{
				ZDO item2 = item7.zdo;
				Kind item3 = item7.kind;
				GameObject item4 = item7.prefab;
				string text2 = null;
				float num2 = 0f;
				switch (item3)
				{
				case Kind.Pickable:
				{
					Pickable componentInChildren = item4.GetComponentInChildren<Pickable>(true);
					if (!item2.GetBool(ZDOVars.s_picked, false))
					{
						string text3 = (((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.m_itemPrefab != (Object)null) ? ((Object)componentInChildren.m_itemPrefab).name : ((Object)item4).name);
						int num4 = ((!((Object)(object)componentInChildren != (Object)null)) ? 1 : Math.Max(1, componentInChildren.m_amount));
						text2 = $"{num4} {text3} to pick";
						num2 = ((text3 == text) ? ((float)num4) : 0f);
					}
					break;
				}
				case Kind.RandomPick:
				{
					int num5 = item2.GetInt(ZDOVars.s_itemPrefab, 0);
					if (num5 == 0)
					{
						text2 = ((Object)item4).name + ", a random item nobody came near yet";
					}
					else if (lootHashes.Contains(num5))
					{
						GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(num5);
						string text4 = ((itemPrefab != null) ? ((Object)itemPrefab).name : null) ?? num5.ToString();
						text2 = "1 " + text4 + " to pick";
						num2 = ((text4 == text) ? 1f : 0f);
					}
					break;
				}
				case Kind.Chest:
					if (!item2.GetBool(ZDOVars.s_addedDefaultItems, false))
					{
						Container componentInChildren2 = item4.GetComponentInChildren<Container>(true);
						num2 = ((text != null && (Object)(object)componentInChildren2 != (Object)null) ? (PerRoll(componentInChildren2.m_defaultItems, text) * (float)num) : 0f);
						text2 = ((Object)item4).name + " nobody opened yet" + ((text != null) ? $", about {num2:0.#} {text}" : "");
					}
					else if (HoldsLoot(item2))
					{
						num2 = ((text != null) ? ((float)Held(item2, text)) : 0f);
						text2 = ((Object)item4).name + ", opened, with loot in it" + ((text != null) ? $", {num2:0} {text}" : "");
					}
					break;
				case Kind.Breakable:
				{
					PickableItem componentInChildren3 = item4.GetComponentInChildren<PickableItem>(true);
					if ((Object)(object)componentInChildren3 != (Object)null && (Object)(object)componentInChildren3.m_itemPrefab != (Object)null)
					{
						text2 = $"{Math.Max(1, componentInChildren3.m_stack)} {((Object)componentInChildren3.m_itemPrefab).name} to pick";
						num2 = ((((Object)componentInChildren3.m_itemPrefab).name == text) ? ((float)Math.Max(1, componentInChildren3.m_stack)) : 0f);
						break;
					}
					num2 = ((text != null) ? (Breaks(item2, item4, text) * (float)num) : 0f);
					(int, int, float)? tuple = Pieces(item2, text ?? "");
					object obj;
					if (tuple.HasValue)
					{
						(int, int, float) valueOrDefault = tuple.GetValueOrDefault();
						int item5 = valueOrDefault.Item1;
						int item6 = valueOrDefault.Item2;
						obj = $"{item5} of {item6} pieces left";
					}
					else
					{
						obj = "never hit";
					}
					string text5 = (string)obj;
					text2 = ((Object)item4).name + ", " + text5 + ((text != null) ? $", about {num2:0.#} {text}" : "");
					break;
				}
				case Kind.Item:
				{
					int num3 = item2.GetInt(ZDOVars.s_stack, 1);
					text2 = $"{num3} {((Object)item4).name} on the floor";
					num2 = ((((Object)item4).name == text) ? ((float)num3) : 0f);
					break;
				}
				}
				if (text2 != null)
				{
					Vector3 position = item2.GetPosition();
					float num6 = Vector3.Distance(at, position);
					list.Add((num6, num2, string.Format("{0}, at x {1:0.#} z {2:0.#} height {3:0.#}{4}", text2, position.x, position.z, position.y, flag ? $", {num6:0} m from the point" : "")));
				}
			}
			string text6 = string.Format("inside {0} at x {1:0} z {2:0}: {3} things with loot{4}", name2, best.m_position.x, best.m_position.z, list.Count, (text != null) ? $", about {list.Sum<(float, float, string)>(((float far, float gives, string line) line) => line.gives):0} {text}, {text} drops {num} times" : "");
			IEnumerable<(float, float, string)> source = (flag ? list.OrderBy<(float, float, string), float>(((float far, float gives, string line) line) => line.far) : list.OrderByDescending<(float, float, string), float>(((float far, float gives, string line) line) => line.gives));
			return string.Join("\n", new string[1] { text6 }.Concat(source.Select<(float, float, string), string>(((float far, float gives, string line) line) => line.line)));
		}

		private static string LootOf(ZoneSystem zones, Vector2s home, string name)
		{
			//IL_003c: 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_004e: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Expected O, but got Unknown
			SortedDictionary<string, int> left = new SortedDictionary<string, int>();
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			HashSet<SectorIndex> hashSet = new HashSet<SectorIndex>();
			List<ZDO> list = new List<ZDO>();
			for (int i = -1; i <= 1; i++)
			{
				for (int j = -1; j <= 1; j++)
				{
					list.Clear();
					ZDOMan.instance.FindObjects(new Vector2s(home.x + i, home.y + j), list, hashSet);
					foreach (ZDO item in list)
					{
						Vector3 position = item.GetPosition();
						if (position.y < 3000f || !watched.TryGetValue(item.GetPrefab(), out var value) || !PlaceAt(zones, position, out var place, out var _) || !((Vector2s)(ref place)).Equals(home))
						{
							continue;
						}
						GameObject prefab = ZNetScene.instance.GetPrefab(item.GetPrefab());
						if ((Object)(object)prefab == (Object)null)
						{
							continue;
						}
						switch (value)
						{
						case Kind.Pickable:
						{
							Pickable componentInChildren2 = prefab.GetComponentInChildren<Pickable>(true);
							if (!item.GetBool(ZDOVars.s_picked, false))
							{
								Count(((Object)(object)componentInChildren2 != (Object)null && (Object)(object)componentInChildren2.m_itemPrefab != (Object)null) ? ((Object)componentInChildren2.m_itemPrefab).name : ((Object)prefab).name, (!((Object)(object)componentInChildren2 != (Object)null)) ? 1 : componentInChildren2.m_amount);
							}
							break;
						}
						case Kind.RandomPick:
						{
							int num4 = item.GetInt(ZDOVars.s_itemPrefab, 0);
							if (num4 == 0)
							{
								num2++;
							}
							else if (lootHashes.Contains(num4))
							{
								GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(num4);
								Count(((itemPrefab != null) ? ((Object)itemPrefab).name : null) ?? num4.ToString(), 1);
							}
							break;
						}
						case Kind.Chest:
						{
							if (!item.GetBool(ZDOVars.s_addedDefaultItems, false))
							{
								num++;
								break;
							}
							byte[] byteArray = item.GetByteArray(ZDOVars.s_items, (byte[])null);
							if (byteArray == null || byteArray.Length == 0)
							{
								break;
							}
							Inventory val = new Inventory("crypts", (Sprite)null, 8, 8);
							val.Load(new ZPackage(byteArray));
							foreach (ItemData allItem in val.GetAllItems())
							{
								if ((Object)(object)allItem.m_dropPrefab != (Object)null && lootHashes.Contains(StringExtensionMethods.GetStableHashCode(((Object)allItem.m_dropPrefab).name)))
								{
									Count(((Object)allItem.m_dropPrefab).name, allItem.m_stack);
								}
							}
							break;
						}
						case Kind.Breakable:
						{
							PickableItem componentInChildren = prefab.GetComponentInChildren<PickableItem>(true);
							if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.m_itemPrefab != (Object)null)
							{
								Count(((Object)componentInChildren.m_itemPrefab).name, componentInChildren.m_stack);
							}
							else
							{
								num3++;
							}
							break;
						}
						case Kind.Item:
							Count(((Object)prefab).name, item.GetInt(ZDOVars.s_stack, 1));
							break;
						}
					}
				}
			}
			List<string> list2 = left.Select((KeyValuePair<string, int> entry) => $"{entry.Value} {entry.Key}").ToList();
			if (num > 0)
			{
				list2.Add($"{num} chests nobody opened yet");
			}
			if (num2 > 0)
			{
				list2.Add($"{num2} random items nobody came near yet");
			}
			if (num3 > 0)
			{
				list2.Add($"{num3} things that drop loot when broken");
			}
			return "inside " + name + ", left there: " + ((list2.Count > 0) ? string.Join(", ", list2) : "no loot");
			void Count(string item, int amount)
			{
				left.TryGetValue(item, out var value2);
				left[item] = value2 + Math.Max(1, amount);
			}
		}

		private static bool HoldsLoot(ZDO zdo)
		{
			//IL_001f: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			byte[] byteArray = zdo.GetByteArray(ZDOVars.s_items, (byte[])null);
			if (byteArray == null || byteArray.Length == 0)
			{
				return false;
			}
			try
			{
				Inventory val = new Inventory("crypts", (Sprite)null, 8, 8);
				val.Load(new ZPackage(byteArray));
				return val.GetAllItems().Any((ItemData item) => (Object)(object)item.m_dropPrefab != (Object)null && lootHashes.Contains(StringExtensionMethods.GetStableHashCode(((Object)item.m_dropPrefab).name)));
			}
			catch (Exception)
			{
				return true;
			}
		}

		private static byte Shown(ZoneSystem zones, Vector2s home, Tally tally)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			byte b = State(tally);
			if (b == 2 || !tally.place.m_placed || !tally.place.m_location.m_prefabName.StartsWith("SunkenCrypt"))
			{
				return b;
			}
			if (!(Left(zones, home, "IronScrap") < 70f))
			{
				return b;
			}
			return 2;
		}

		private static byte State(Tally tally)
		{
			if (!tally.place.m_placed)
			{
				return 0;
			}
			if (tally.left + tally.maybe == 0)
			{
				return 2;
			}
			int num = ((tally.proxy != null) ? tally.proxy.GetInt(Mark, -1) : (-1));
			if (num < 0)
			{
				if (tally.visited || tally.taken > 0)
				{
					return 1;
				}
				ZDO proxy = tally.proxy;
				if (proxy != null)
				{
					proxy.Set(Mark, tally.left, false);
				}
				return 0;
			}
			if (tally.left > num)
			{
				tally.proxy.Set(Mark, tally.left, false);
				num = tally.left;
			}
			if (tally.left < num || tally.taken != 0)
			{
				return 1;
			}
			return 0;
		}

		public static void Bind(ConfigFile config)
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			placesEntry = config.Bind<bool>("Map", "Crypts", true, "The places with an inside, like a burial chamber or a crypt, show on the map. The switch Crypts on the big map changes it too.");
			oresEntry = config.Bind<bool>("Map", "Metals", true, "The metal deposits show on the map. The switch Metals on the big map changes it too.");
			placesRow = config.Bind<bool>("Switches", "ShowCrypts", true, "The switch Crypts shows on the big map. Hidden, the map keeps the value of Crypts.");
			oresRow = config.Bind<bool>("Switches", "ShowMetals", true, "The switch Metals shows on the big map. Hidden, the map keeps the value of Metals.");
			rowsRight = config.Bind<float>("Switches", "MoveRight", 0f, new ConfigDescription("Moves the switches of this mod on the big map to the right, under 0 to the left. 1 row of switches is 51 high.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-2000f, 2000f), Array.Empty<object>()));
			rowsUp = config.Bind<float>("Switches", "MoveUp", 0f, new ConfigDescription("Moves the switches of this mod on the big map up, under 0 down. 1 row of switches is 51 high.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-2000f, 2000f), Array.Empty<object>()));
			config.SettingChanged += delegate
			{
				if (showPlaces != placesEntry.Value)
				{
					SetPlaces(placesEntry.Value);
				}
				if (showOres != oresEntry.Value)
				{
					SetOres(oresEntry.Value);
				}
			};
		}

		private static void SetPlaces(bool on)
		{
			showPlaces = on;
			placesEntry.Value = on;
			redraw = true;
		}

		private static void SetOres(bool on)
		{
			showOres = on;
			oresEntry.Value = on;
			redraw = true;
		}

		private static void OnAnswer(long sender, ZPackage package)
		{
			//IL_0067: 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_00b0: 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_012f: 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)
			places.Clear();
			int num = package.ReadInt();
			List<string> names = new List<string>();
			for (int i = 0; i < num; i++)
			{
				names.Add(package.ReadString());
			}
			num = package.ReadInt();
			for (int j = 0; j < num; j++)
			{
				int name = package.ReadInt();
				Vector3 position = package.ReadVector3();
				byte state = package.ReadByte();
				string item = Icons.FirstOrDefault(((string start, string item) icon) => names[name].StartsWith(icon.start)).item ?? "";
				places.Add(new Place
				{
					item = item,
					position = position,
					state = state
				});
			}
			num = package.ReadInt();
			for (int num2 = 0; num2 < num; num2++)
			{
				byte b = package.ReadByte();
				float num3 = package.ReadSingle();
				float num4 = package.ReadSingle();
				byte state2 = package.ReadByte();
				places.Add(new Place
				{
					item = ((b < Ores.Length) ? Ores[b] : ""),
					position = new Vector3(num3, 0f, num4),
					state = state2,
					ore = true
				});
			}
			redraw = true;
		}

		private static void Wishbone(SE_Finder __instance)
		{
			//IL_0042: 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_0089: 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)
			Beacon beacon = __instance.m_beacon;
			Character character = ((StatusEffect)__instance).m_character;
			if (host != null && !((Object)(object)beacon == (Object)null) && !((Object)(object)character == (Object)null) && !((Object)(object)character != (Object)(object)Player.m_localPlayer) && ZRoutedRpc.instance != null && !(Utils.DistanceXZ(((Component)character).transform.position, ((Component)beacon).transform.position) >= beacon.m_range * 0.2f))
			{
				ZNetView componentInParent = ((Component)beacon).GetComponentInParent<ZNetView>();
				if (!((Object)(object)componentInParent == (Object)null) && componentInParent.IsValid() && told.Add(componentInParent.GetZDO().m_uid))
				{
					ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "bf_crypts_found", new object[1] { componentInParent.GetZDO().m_uid });
					askedAt = Time.realtimeSinceStartup - 30f + 2f;
				}
			}
		}

		private static void MapTick(Minimap __instance)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			//IL_00c3: 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_00e2: 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)
			if (host == null)
			{
				return;
			}
			if ((int)__instance.m_mode != 2)
			{
				redraw = places.Count > 0;
				RemovePins();
				return;
			}
			MapSwitches.Draw(__instance);
			if (ZRoutedRpc.instance != null && Time.realtimeSinceStartup - askedAt > ((places.Count == 0) ? 5f : 30f))
			{
				askedAt = Time.realtimeSinceStartup;
				ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "bf_crypts_ask", Array.Empty<object>());
			}
			if (!redraw)
			{
				return;
			}
			redraw = false;
			RemovePins();
			foreach (Place place in places)
			{
				if ((place.ore ? showOres : showPlaces) && __instance.IsExplored(place.position))
				{
					PinData val = __instance.AddPin(place.position, (PinType)8, "", false, false, 0L, default(PlatformUserID));
					val.m_icon = Icon(__instance, place);
					pins.Add(val);
				}
			}
		}

		private static void RemovePins()
		{
			if (pins.Count == 0)
			{
				return;
			}
			if ((Object)(object)Minimap.instance != (Object)null)
			{
				foreach (PinData pin in pins)
				{
					Minimap.instance.RemovePin(pin);
				}
			}
			pins.Clear();
		}

		private static Sprite Icon(Minimap map, Place place)
		{
			string item = place.item;
			string key = $"{item} {place.state}";
			if (sprites.TryGetValue(key, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			Sprite val = null;
			if (item.Length > 0 && (Object)(object)ObjectDB.instance != (Object)null)
			{
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item);
				ItemDrop val2 = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null);
				if ((Object)(object)val2 != (Object)null && val2.m_itemData.m_shared.m_icons.Length != 0)
				{
					val = val2.m_itemData.m_shared.m_icons[0];
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				val = map.GetSprite((PinType)3);
			}
			try
			{
				value = Ringed(val, place.state);
			}
			catch (Exception ex)
			{
				log.LogWarning((object)("crypts: no icon for " + place.item + ": " + ex.Message));
				value = val;
			}
			sprites[key] = value;
			return value;
		}

		private static Sprite Ringed(Sprite source, byte state)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: 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_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			Color val = (Color)(state switch
			{
				1 => new Color(1f, 0.8f, 0.2f), 
				0 => new Color(0.3f, 0.85f, 0.35f), 
				_ => new Color(0.55f, 0.55f, 0.55f), 
			});
			float num = ((state == 2) ? 0.45f : 1f);
			Texture2D val2 = Read(source);
			Texture2D val3 = new Texture2D(64, 64, (TextureFormat)4, false);
			Color[] array = (Color[])(object)new Color[4096];
			float num2 = 31.5f;
			float num3 = 23.04f;
			float num4 = num3 - 4f;
			float num5 = num4 * 1.5f;
			float num6 = num2 - num5 / 2f;
			Color val4 = default(Color);
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					float num7 = Mathf.Sqrt(((float)j - num2) * ((float)j - num2) + ((float)i - num2) * ((float)i - num2));
					if (num7 > num4)
					{
						val4 = val;
						val4.a = Mathf.Clamp01(num3 - num7 + 1f);
					}
					else
					{
						((Color)(ref val4))..ctor(0f, 0f, 0f, 0.6f);
						float num8 = ((float)j - num6) / num5;
						float num9 = ((float)i - num6) / num5;
						if (num8 >= 0f && num8 <= 1f && num9 >= 0f && num9 <= 1f)
						{
							Color pixelBilinear = val2.GetPixelBilinear(num8, num9);
							((Color)(ref val4))..ctor(Mathf.Lerp(val4.r, pixelBilinear.r * num, pixelBilinear.a), Mathf.Lerp(val4.g, pixelBilinear.g * num, pixelBilinear.a), Mathf.Lerp(val4.b, pixelBilinear.b * num, pixelBilinear.a), Mathf.Max(val4.a, pixelBilinear.a));
						}
					}
					array[i * 64 + j] = val4;
				}
			}
			Object.Destroy((Object)(object)val2);
			val3.SetPixels(array);
			val3.Apply();
			return Sprite.Create(val3, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
		}

		private static Texture2D Read(Sprite sprite)
		{
			//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_0047: 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_0069: 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_007d: Expected O, but got Unknown
			Texture texture = (Texture)(object)sprite.texture;
			Rect textureRect = sprite.textureRect;
			RenderTexture temporary = RenderTexture.GetTemporary(texture.width, texture.height, 0, (RenderTextureFormat)0);
			RenderTexture active = RenderTexture.active;
			try
			{
				Graphics.Blit(texture, temporary);
				RenderTexture.active = temporary;
				Texture2D val = new Texture2D((int)((Rect)(ref textureRect)).width, (int)((Rect)(ref textureRect)).height, (TextureFormat)4, false);
				val.ReadPixels(new Rect(((Rect)(ref textureRect)).x, ((Rect)(ref textureRect)).y, ((Rect)(ref textureRect)).width, ((Rect)(ref textureRect)).height), 0, 0);
				val.Apply();
				return val;
			}
			finally
			{
				RenderTexture.active = active;
				RenderTexture.ReleaseTemporary(temporary);
			}
		}
	}
	[BepInPlugin("vladasz.cryptorepins", "Crypt and Ore Pins", "0.2.0")]
	public class CryptOrePinsPlugin : BaseUnityPlugin
	{
		public const string Id = "vladasz.cryptorepins";

		public const string Number = "0.2.0";

		private void Awake()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			Crypts.Bind(((BaseUnityPlugin)this).Config);
			Crypts.Load(new HotHost(((BaseUnityPlugin)this).Logger, new Harmony("vladasz.cryptorepins"), "0.2.0"));
		}
	}
	internal static class Drops
	{
		internal static int Rate(string item)
		{
			return 1;
		}
	}
	internal static class MapSwitches
	{
		private sealed class Row
		{
			public int index;

			public string text;

			public string item;

			public Func<bool> on;

			public UnityAction<bool> changed;

			public Func<bool> shown;

			public Func<Vector2> offset;

			public GameObject made;

			public Toggle toggle;

			public Vector2 home;
		}

		private const float RowStep = 51f;

		private static readonly List<Row> rows = new List<Row>();

		internal static void Add(int index, string text, string item, Func<bool> on, UnityAction<bool> changed, Func<bool> shown = null, Func<Vector2> offset = null)
		{
			rows.Add(new Row
			{
				index = index,
				text = text,
				item = item,
				on = on,
				changed = changed,
				shown = shown,
				offset = offset
			});
		}

		internal static void Draw(Minimap map)
		{
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			Toggle publicPosition = map.m_publicPosition;
			if ((Object)(object)publicPosition == (Object)null)
			{
				return;
			}
			foreach (Row row in rows)
			{
				if ((Object)(object)row.made == (Object)null)
				{
					row.made = Make(publicPosition, row);
				}
				bool flag = Shown(row);
				if (row.made.activeSelf != flag)
				{
					row.made.SetActive(flag);
				}
				if (!flag)
				{
					continue;
				}
				int num = row.index;
				foreach (Row row2 in rows)
				{
					if (row2.index < row.index && !Shown(row2))
					{
						num--;
					}
				}
				Vector2 val = ((row.offset != null) ? row.offset() : Vector2.zero);
				((RectTransform)row.made.transform).anchoredPosition = row.home + val + new Vector2(0f, (float)(num + 1) * 51f);
				bool flag2 = row.on();
				if ((Object)(object)row.toggle != (Object)null && row.toggle.isOn != flag2)
				{
					row.toggle.SetIsOnWithoutNotify(flag2);
				}
			}
		}

		private static bool Shown(Row row)
		{
			if (row.shown != null)
			{
				return row.shown();
			}
			return true;
		}

		internal static void Clear()
		{
			foreach (Row row in rows)
			{
				if ((Object)(object)row.made != (Object)null)
				{
					Object.Destroy((Object)(object)row.made);
				}
			}
			rows.Clear();
		}

		private static GameObject Make(Toggle source, Row row)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)((Component)source).transform.parent;
			GameObject obj = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Transform)val).parent);
			((Object)obj).name = $"bf_map_switch_{row.index}";
			obj.transform.SetSiblingIndex(((Transform)val).GetSiblingIndex() + 1);
			Toggle val2 = (row.toggle = obj.GetComponentInChildren<Toggle>(true));
			val2.onValueChanged = new ToggleEvent();
			val2.SetIsOnWithoutNotify(row.on());
			((UnityEvent<bool>)(object)val2.onValueChanged).AddListener(row.changed);
			TMP_Text componentInChildren = obj.GetComponentInChildren<TMP_Text>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.text = row.text;
			}
			object obj2;
			if (!((Object)(object)ObjectDB.instance != (Object)null))
			{
				obj2 = null;
			}
			else
			{
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(row.item);
				obj2 = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null);
			}
			ItemDrop val3 = (ItemDrop)obj2;
			Graphic graphic = val2.graphic;
			Image val4 = (Image)(object)((graphic is Image) ? graphic : null);
			if (val4 != null && (Object)(object)val3 != (Object)null && val3.m_itemData.m_shared.m_icons.Length != 0)
			{
				val4.sprite = val3.m_itemData.m_shared.m_icons[0];
			}
			row.home = val.anchoredPosition;
			return obj;
		}
	}
}
namespace Blackforge.Hot
{
	public sealed class HotHost
	{
		public ManualLogSource Log { get; }

		public Harmony Harmony { get; }

		public string Version { get; }

		public bool IsDedicatedServer => (int)SystemInfo.graphicsDeviceType == 4;

		internal HotHost(ManualLogSource log, Harmony harmony, string version)
		{
			Log = log;
			Harmony = harmony;
			Version = version;
		}

		public byte[] ReadAsset(string relative)
		{
			return File.ReadAllBytes(Path.Combine(Path.GetDirectoryName(typeof(HotHost).Assembly.Location), relative));
		}

		public void UnregisterRpc(IEnumerable<string> names)
		{
			if (ZRoutedRpc.instance == null)
			{
				return;
			}
			foreach (string name in names)
			{
				ZRoutedRpc.instance.m_functions.Remove(StringExtensionMethods.GetStableHashCode(name));
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}