Decompiled source of EpicLootAdventureTools v0.8.4

plugins/EpicLootAdventureTools/EpicLootAdventureTools.dll

Decompiled 2 days 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.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Common;
using EpicLoot;
using EpicLoot.Adventure;
using EpicLoot.Biomes;
using EpicLoot.Data;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EpicLootAdventureTools
{
	[BepInPlugin("pumpli.epicloot.adventuretools", "EpicLoot Adventure Tools", "0.8.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class EpicLootAdventureToolsPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "pumpli.epicloot.adventuretools";

		public const string PluginName = "EpicLoot Adventure Tools";

		public const string PluginVersion = "0.8.4";

		private ConfigEntry<bool> _enableDiagnostics;

		private ConfigEntry<KeyboardShortcut> _trackerKey;

		private float _nextDiagnosticRefresh;

		private readonly Vector3[] _mapCorners = (Vector3[])(object)new Vector3[4];

		private static EpicLootAdventureToolsPlugin _instance;

		private Harmony _harmony;

		private bool _trackerOpen;

		private Vector2 _trackerScroll;

		private bool _diagnosticOpen;

		private string _diagnosticText = "";

		private Vector2 _diagnosticScroll;

		private Rect _diagnosticRect = new Rect(-1f, -1f, 620f, 480f);

		private int _closedFrame = -1;

		private bool _clearGuiFocus;

		private bool _mouseEnabled;

		private bool _uiMouseCaptured;

		private bool _searchFocused;

		private string _search = "";

		private bool _nearest;

		private int _bountyFilter;

		private Rect _trackerRect;

		private List<BountyInfo> _visibleBounties = new List<BountyInfo>();

		private List<TreasureMapChestInfo> _visibleTreasures = new List<TreasureMapChestInfo>();

		private readonly Dictionary<object, string> _searchLabels = new Dictionary<object, string>();

		private GUIStyle _completedStyle;

		private Texture2D _completedTex;

		private string _trackerSnapshotAt = "";

		private float _nextProgressCheck;

		private string _progressSignature = "";

		private HashSet<string> _claimableBounties = new HashSet<string>();

		private List<BountyInfo> _bounties = new List<BountyInfo>();

		private List<TreasureMapChestInfo> _treasures = new List<TreasureMapChestInfo>();

		private readonly Dictionary<object, KeyValuePair<bool, string>> _repairStates = new Dictionary<object, KeyValuePair<bool, string>>();

		private string _trackerError;

		private string _repairFeedback = "";

		private float _lastWorldScanAt = -999f;

		private TreasureMapChest[] _cachedLoadedChests = (TreasureMapChest[])(object)new TreasureMapChest[0];

		private BountyTarget[] _cachedLoadedTargets = (BountyTarget[])(object)new BountyTarget[0];

		private Object[] _cachedLoadedSpawners = (Object[])(object)new Object[0];

		private Sprite _treasureMapIcon;

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

		private GUIStyle _buttonStyle;

		private readonly Queue<string> _checkMessages = new Queue<string>();

		private float _nextCheckMessage;

		private GUIStyle _panelStyle;

		private GUIStyle _headerStyle;

		private GUIStyle _sectionStyle;

		private GUIStyle _rowStyle;

		private GUIStyle _rowHoverStyle;

		private GUIStyle _nameStyle;

		private GUIStyle _smallStyle;

		private GUIStyle _goldStyle;

		private GUIStyle _rewardLabelStyle;

		private GUIStyle _rewardAmountStyle;

		private GUIStyle _diagStyle;

		private GUIStyle _frameStyle;

		private GUIStyle _treasureIconStyle;

		private Texture2D _panelTex;

		private Texture2D _rowTex;

		private Texture2D _rowHoverTex;

		private Texture2D _buttonTex;

		private Texture2D _buttonHoverTex;

		private Texture2D _frameTex;

		private bool _traderFontApplied;

		private Type _spawnerType;

		private PropertyInfo _spawnerTreasureProperty;

		private PropertyInfo _spawnerBountyProperty;

		private PropertyInfo _spawnerPlacedProperty;

		private PropertyInfo _spawnerSearchingProperty;

		private PropertyInfo _spawnerSpawnPointProperty;

		private FieldInfo _spawnerStartedPlacementField;

		private FieldInfo _spawnerCurrentUpdatesField;

		private FieldInfo _spawnerUpdatesRequiredField;

		private MethodInfo _spawnerSetTreasureMethod;

		private MethodInfo _spawnerSetBountyMethod;

		private MethodInfo _spawnerSetIsBountyMethod;

		private readonly Dictionary<string, string> _difficultyCache = new Dictionary<string, string>();

		private bool WindowOpen
		{
			get
			{
				if (!_trackerOpen)
				{
					return _diagnosticOpen;
				}
				return true;
			}
		}

		private static bool BlockWindowInput
		{
			get
			{
				if ((Object)(object)_instance != (Object)null && _instance.CanShowTools)
				{
					if (!_instance.ToolCursorRequested)
					{
						return Time.frameCount == _instance._closedFrame;
					}
					return true;
				}
				return false;
			}
		}

		private bool CanShowTools
		{
			get
			{
				if ((Object)(object)Player.m_localPlayer != (Object)null && !((Character)Player.m_localPlayer).IsDead() && !((Character)Player.m_localPlayer).IsTeleporting())
				{
					return !OtherUiOwnsInput();
				}
				return false;
			}
		}

		private bool OwnsInput
		{
			get
			{
				if (WindowOpen)
				{
					return CanShowTools;
				}
				return false;
			}
		}

		private bool ToolCursorRequested
		{
			get
			{
				if (WindowOpen && CanShowTools)
				{
					return _mouseEnabled;
				}
				return false;
			}
		}

		private bool PointerOnTracker
		{
			get
			{
				//IL_000e: 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_0029: Unknown result type (might be due to invalid IL or missing references)
				if (_trackerOpen)
				{
					return ((Rect)(ref _trackerRect)).Contains(new Vector2(Input.mousePosition.x, (float)Screen.height - Input.mousePosition.y));
				}
				return false;
			}
		}

		private static bool OtherUiOwnsInput()
		{
			if (InventoryGui.IsVisible() || StoreGui.IsVisible() || Menu.IsVisible() || Console.IsVisible() || TextInput.IsVisible() || ((Object)(object)TextViewer.instance != (Object)null && TextViewer.instance.IsVisible()) || UnifiedPopup.IsVisible() || Minimap.IsOpen() || Minimap.InTextInput() || ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()))
			{
				return true;
			}
			GameObject val = (((Object)(object)EventSystem.current != (Object)null) ? EventSystem.current.currentSelectedGameObject : null);
			if ((Object)(object)val == (Object)null || !val.activeInHierarchy)
			{
				return false;
			}
			InputField componentInParent = val.GetComponentInParent<InputField>();
			TMP_InputField componentInParent2 = val.GetComponentInParent<TMP_InputField>();
			if (!((Object)(object)componentInParent != (Object)null) || !((Behaviour)componentInParent).isActiveAndEnabled)
			{
				if ((Object)(object)componentInParent2 != (Object)null)
				{
					return ((Behaviour)componentInParent2).isActiveAndEnabled;
				}
				return false;
			}
			return true;
		}

		private bool ReadyToCollect(BountyInfo bounty)
		{
			return _claimableBounties.Contains(bounty.ID);
		}

		private void Awake()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			_instance = this;
			MigrateConfig();
			_trackerKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "Tracker toggle key", new KeyboardShortcut((KeyCode)110, Array.Empty<KeyCode>()), "Open or close the adventure tracker. Press Left Alt while open to toggle the cursor. Walking remains available unless typing in search.");
			_enableDiagnostics = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable diagnostics", false, "Enable the optional F10 live diagnostic tool on this client. Disabled by default.");
			CacheSpawnerReflection();
			InstallInputPatches();
			EpicLootStackCompatibility.Install(_harmony, ((BaseUnityPlugin)this).Logger);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"EpicLoot Adventure Tools 0.8.4 loaded. F10 toggles diagnostics; N tracker toggle; guarded bounty/treasure repair enabled.");
		}

		private bool IsBossBounty(BountyInfo bounty)
		{
			ZNetScene instance = ZNetScene.instance;
			GameObject val = ((instance != null) ? instance.GetPrefab(bounty.Target.MonsterID) : null);
			Character val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Character>() : null);
			if ((Object)(object)val2 != (Object)null)
			{
				return val2.IsBoss();
			}
			return false;
		}

		private string BountyDifficulty(BountyInfo bounty)
		{
			string key = bounty.ID + ":" + bounty.Target.Level + ":" + bounty.RewardGold;
			if (_difficultyCache.TryGetValue(key, out var value))
			{
				return value;
			}
			BountiesConfig val = AdventureDataManager.Config?.Bounties;
			float num = ((val == null) ? 1f : ((bounty.RewardGold > 0) ? val.GoldHealthMultiplier : val.IronHealthMultiplier));
			int num2 = ((bounty.Adds != null) ? bounty.Adds.Sum((BountyTargetInfo a) => Math.Max(0, a.Count)) : 0);
			value = (IsBossBounty(bounty) ? "BOSS" : ((bounty.RewardGold > 0) ? "GOLD" : "IRON")) + $" · {Math.Max(0, bounty.Target.Level - 1)}★ · HP ×{num:0.#}" + ((num2 > 0) ? $" · +{num2} escorts" : "");
			_difficultyCache[key] = value;
			return value;
		}

		private void Update()
		{
			//IL_01c1: 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_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			if (!Input.GetMouseButton(0) && !Input.GetMouseButton(1))
			{
				_uiMouseCaptured = false;
			}
			if (ToolCursorRequested && PointerOnTracker && (Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1)))
			{
				_uiMouseCaptured = true;
			}
			if ((Object)(object)Player.m_localPlayer == (Object)null || ((Character)Player.m_localPlayer).IsDead() || ((Character)Player.m_localPlayer).IsTeleporting())
			{
				if (WindowOpen)
				{
					CloseWindows();
				}
				_checkMessages.Clear();
				return;
			}
			if (_diagnosticOpen && !_enableDiagnostics.Value)
			{
				CloseWindows();
			}
			if (OtherUiOwnsInput())
			{
				if (WindowOpen)
				{
					CloseWindows(consumeClosingInput: false);
				}
				_checkMessages.Clear();
				return;
			}
			if (WindowOpen && Input.GetKeyDown((KeyCode)27))
			{
				CloseWindows();
				return;
			}
			if (WindowOpen && Input.GetKeyDown((KeyCode)308))
			{
				_mouseEnabled = !_mouseEnabled;
				if (!_mouseEnabled)
				{
					_searchFocused = false;
				}
			}
			if (_trackerOpen && Time.unscaledTime >= _nextProgressCheck)
			{
				RefreshTracker();
			}
			if (_checkMessages.Count > 0 && Time.unscaledTime >= _nextCheckMessage)
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, "<color=#FFD45A>" + _checkMessages.Dequeue() + "</color>", 0, (Sprite)null, false);
				_nextCheckMessage = Time.unscaledTime + 5f;
			}
			if (_searchFocused)
			{
				return;
			}
			if (_enableDiagnostics.Value && Input.GetKeyDown((KeyCode)291))
			{
				if (_diagnosticOpen)
				{
					CloseWindows();
				}
				else
				{
					PrepareWindow();
					RunDiagnostics();
				}
			}
			else
			{
				KeyboardShortcut value = _trackerKey.Value;
				bool keyDown = Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey);
				value = _trackerKey.Value;
				if (SharedAdventureRules.ShortcutPressed(keyDown, ((KeyboardShortcut)(ref value)).Modifiers, (Func<KeyCode, bool>)Input.GetKey))
				{
					if (_trackerOpen)
					{
						CloseWindows();
					}
					else
					{
						PrepareWindow();
						_trackerOpen = true;
						RefreshTracker();
					}
				}
			}
			if (_diagnosticOpen && Time.unscaledTime >= _nextDiagnosticRefresh)
			{
				RefreshLiveDiagnostics();
			}
		}

		private void PrepareWindow()
		{
			_mouseEnabled = false;
			_searchFocused = false;
			_trackerOpen = false;
			_diagnosticOpen = false;
			_clearGuiFocus = true;
			_uiMouseCaptured = false;
		}

		private void MigrateConfig()
		{
			string text = Path.Combine(Paths.ConfigPath, "alexander.epicloot.adventuretools.cfg");
			if (!File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath) && File.Exists(text))
			{
				File.Copy(text, ((BaseUnityPlugin)this).Config.ConfigFilePath);
				((BaseUnityPlugin)this).Config.Reload();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Migrated existing Adventure Tools settings to pumpli config.");
			}
		}

		private void RefilterTracker(bool resetScroll = true)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 player = (((Object)(object)Player.m_localPlayer != (Object)null) ? ((Component)Player.m_localPlayer).transform.position : Vector3.zero);
			IEnumerable<BountyInfo> source = _bounties.Where((BountyInfo b) => Matches(b) && (_bountyFilter == 0 || ((_bountyFilter != 1) ? ((_bountyFilter != 2) ? IsMissing(b) : ReadyToCollect(b)) : (!ReadyToCollect(b)))));
			_visibleBounties = (_nearest ? source.OrderBy((BountyInfo b) => HorizontalDistance(player, SerializableVector3.op_Implicit(b.Position) + SerializableVector3.op_Implicit(b.MinimapCircleOffset))) : (from b in source
				orderby b.State, SafeBiomeOrder(b.Biome)
				select b)).ToList();
			IEnumerable<TreasureMapChestInfo> source2 = _treasures.Where((TreasureMapChestInfo t) => _bountyFilter != 2 && Matches(t) && (_bountyFilter != 3 || IsMissing(t)));
			_visibleTreasures = (_nearest ? source2.OrderBy((TreasureMapChestInfo t) => HorizontalDistance(player, SerializableVector3.op_Implicit(t.Position) + SerializableVector3.op_Implicit(t.MinimapCircleOffset))) : (from t in source2
				orderby SafeBiomeOrder(t.Biome), t.Interval
				select t)).ToList();
			if (resetScroll)
			{
				_trackerScroll = Vector2.zero;
			}
			bool Matches(object item)
			{
				if (!string.IsNullOrWhiteSpace(_search))
				{
					if (_searchLabels.TryGetValue(item, out var value))
					{
						return value.IndexOf(_search.Trim(), StringComparison.OrdinalIgnoreCase) >= 0;
					}
					return false;
				}
				return true;
			}
		}

		private void DrawTrackerFilters(Rect panel)
		{
			//IL_0038: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Invalid comparison between Unknown and I4
			//IL_014b: 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_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(((Rect)(ref panel)).x + 18f, ((Rect)(ref panel)).y + 76f, ((Rect)(ref panel)).width - 96f, 26f);
			if ((int)Event.current.type == 0 && !((Rect)(ref val)).Contains(Event.current.mousePosition))
			{
				GUI.FocusControl((string)null);
			}
			GUI.SetNextControlName("AdventureSearch");
			string text = GUI.TextField(val, _search, 100);
			if (!ToolCursorRequested || ((int)Event.current.type == 4 && (int)Event.current.keyCode == 13))
			{
				GUI.FocusControl((string)null);
			}
			_searchFocused = ToolCursorRequested && GUI.GetNameOfFocusedControl() == "AdventureSearch";
			if (string.IsNullOrEmpty(text) && !_searchFocused)
			{
				GUI.Label(new Rect(((Rect)(ref val)).x + 5f, ((Rect)(ref val)).y + 3f, ((Rect)(ref val)).width - 10f, 22f), "Search name, biome or target...", _smallStyle);
			}
			if (text != _search)
			{
				_search = text;
				RefilterTracker();
			}
			if (GUI.Button(new Rect(((Rect)(ref panel)).xMax - 70f, ((Rect)(ref panel)).y + 76f, 52f, 26f), "Clear", _buttonStyle))
			{
				_search = "";
				GUI.FocusControl((string)null);
				_searchFocused = false;
				RefilterTracker();
			}
			string[] array = new string[4] { "All", "Active", "Done", "Missing" };
			if (GUI.Button(new Rect(((Rect)(ref panel)).x + 18f, ((Rect)(ref panel)).y + 109f, 96f, 26f), array[_bountyFilter], _buttonStyle))
			{
				_bountyFilter = (_bountyFilter + 1) % 4;
				RefilterTracker();
			}
			if (GUI.Button(new Rect(((Rect)(ref panel)).x + 121f, ((Rect)(ref panel)).y + 109f, 125f, 26f), _nearest ? "Nearest first" : "Biome order", _buttonStyle))
			{
				_nearest = !_nearest;
				RefilterTracker();
			}
			if (GUI.Button(new Rect(((Rect)(ref panel)).x + 253f, ((Rect)(ref panel)).y + 109f, ((Rect)(ref panel)).width - 271f, 26f), "Re-sort", _buttonStyle))
			{
				RefilterTracker();
			}
		}

		private static bool PlayerInputPrefix(Player __instance, ref bool __result)
		{
			if ((Object)(object)_instance == (Object)null || !_instance.OwnsInput || !_instance._searchFocused || (Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			__result = false;
			return false;
		}

		private static bool GameButtonPrefix(string __0, ref bool __result)
		{
			if ((Object)(object)_instance == (Object)null || !_instance.OwnsInput)
			{
				return true;
			}
			bool flag = _instance.ToolCursorRequested && (_instance.PointerOnTracker || _instance._uiMouseCaptured) && (__0 == "Attack" || __0 == "SecondaryAttack" || __0 == "Block");
			if (!_instance._searchFocused && !flag)
			{
				return true;
			}
			__result = false;
			return false;
		}

		private static void PlayerControlsPrefix(Player __instance, ref bool attack, ref bool attackHold, ref bool secondaryAttack, ref bool secondaryAttackHold, ref bool block, ref bool blockHold)
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || (Object)(object)_instance == (Object)null || !_instance.CanShowTools)
			{
				return;
			}
			bool flag = _instance.ToolCursorRequested && (_instance.PointerOnTracker || _instance._diagnosticOpen);
			if (flag || _instance._uiMouseCaptured || Time.frameCount == _instance._closedFrame)
			{
				if (flag && (Input.GetMouseButton(0) || Input.GetMouseButton(1)))
				{
					_instance._uiMouseCaptured = true;
				}
				attack = (attackHold = (secondaryAttack = (secondaryAttackHold = (block = (blockHold = false)))));
			}
		}

		private void CloseWindows(bool consumeClosingInput = true)
		{
			_mouseEnabled = false;
			_searchFocused = false;
			_trackerOpen = false;
			_diagnosticOpen = false;
			_uiMouseCaptured = false;
			_clearGuiFocus = true;
			_closedFrame = (consumeClosingInput ? Time.frameCount : (-1));
			if (consumeClosingInput)
			{
				PlayerController.SetTakeInputDelay(0.15f);
			}
		}

		private void OnGUI()
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Invalid comparison between Unknown and I4
			//IL_00ce: 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_006d: Invalid comparison between Unknown and I4
			//IL_007c: 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_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Expected O, but got Unknown
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Invalid comparison between Unknown and I4
			if (_clearGuiFocus)
			{
				if (GUI.GetNameOfFocusedControl() == "AdventureSearch")
				{
					GUI.FocusControl((string)null);
				}
				_clearGuiFocus = false;
			}
			if (!CanShowTools)
			{
				return;
			}
			EnsureStyles();
			TryApplyTraderFont();
			if (!IsLargeMapOpen())
			{
				DrawTrackerButton();
			}
			if (_trackerOpen)
			{
				bool enabled = GUI.enabled;
				GUI.enabled = ToolCursorRequested || (int)Event.current.type == 7;
				EventType type = Event.current.type;
				if (!ToolCursorRequested && (Event.current.isMouse || Event.current.isKey || (int)type == 6))
				{
					Event.current.type = (EventType)11;
				}
				try
				{
					DrawTracker();
				}
				finally
				{
					if ((int)Event.current.type == 11)
					{
						Event.current.type = type;
					}
					GUI.enabled = enabled;
				}
			}
			if (_diagnosticOpen)
			{
				((Rect)(ref _diagnosticRect)).width = Mathf.Min(600f, (float)Screen.width - 20f);
				((Rect)(ref _diagnosticRect)).height = Mathf.Min(520f, (float)Screen.height - 20f);
				if (((Rect)(ref _diagnosticRect)).x < 0f || ((Rect)(ref _diagnosticRect)).y < 0f)
				{
					((Rect)(ref _diagnosticRect)).x = 16f;
					((Rect)(ref _diagnosticRect)).y = Mathf.Min(160f, (float)Screen.height - ((Rect)(ref _diagnosticRect)).height);
				}
				bool enabled2 = GUI.enabled;
				GUI.enabled = ToolCursorRequested;
				_diagnosticRect = GUI.Window(918273, _diagnosticRect, new WindowFunction(DrawDiagnosticWindowContents), GUIContent.none, _panelStyle);
				GUI.enabled = enabled2;
				((Rect)(ref _diagnosticRect)).x = Mathf.Clamp(((Rect)(ref _diagnosticRect)).x, 0f, Mathf.Max(0f, (float)Screen.width - ((Rect)(ref _diagnosticRect)).width));
				((Rect)(ref _diagnosticRect)).y = Mathf.Clamp(((Rect)(ref _diagnosticRect)).y, 0f, Mathf.Max(0f, (float)Screen.height - ((Rect)(ref _diagnosticRect)).height));
			}
		}

		private void InstallInputPatches()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			_harmony = new Harmony("pumpli.epicloot.adventuretools");
			PatchInput(typeof(PlayerController), "TakeInput", "PlayerControllerTakeInputPrefix");
			PatchInput(typeof(GameCamera), "UpdateMouseCapture", "MouseCapturePrefix");
			PatchInput(typeof(Menu), "Update", "MenuUpdatePrefix");
			PatchInput(typeof(InventoryGui), "Show", "OtherWindowOpeningPrefix");
			PatchInput(typeof(StoreGui), "Show", "OtherWindowOpeningPrefix");
			PatchInput(typeof(TextInput), "Show", "OtherWindowOpeningPrefix");
			PatchInput(typeof(Minimap), "SetMapMode", "MapModePrefix");
			PatchInput(typeof(ZInput), "GetMouseScrollWheel", "MouseWheelPrefix");
			PatchInput(typeof(ZInput), "GetButton", "GameButtonPrefix");
			PatchInput(typeof(ZInput), "GetButtonDown", "GameButtonPrefix");
			PatchInput(typeof(Player), "TakeInput", "PlayerInputPrefix");
			PatchInput(typeof(Player), "SetControls", "PlayerControlsPrefix");
		}

		private void PatchInput(Type type, string methodName, string prefix)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			try
			{
				MethodInfo methodInfo = AccessTools.Method(type, methodName, (Type[])null, (Type[])null);
				if (methodInfo == null)
				{
					throw new MissingMethodException(type.Name, methodName);
				}
				_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(EpicLootAdventureToolsPlugin), prefix, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"Could not install {type.Name}.{methodName} window input patch: {arg}");
			}
		}

		private static bool PlayerControllerTakeInputPrefix(bool __0, ref bool __result)
		{
			if ((Object)(object)_instance == (Object)null || !_instance.CanShowTools || (!_instance._searchFocused && Time.frameCount != _instance._closedFrame && (!__0 || !_instance.ToolCursorRequested)))
			{
				return true;
			}
			__result = false;
			return false;
		}

		private static bool MouseCapturePrefix()
		{
			if ((Object)(object)_instance == (Object)null || !_instance.ToolCursorRequested)
			{
				return true;
			}
			ZCursor.LockState = (CursorLockMode)0;
			ZCursor.Show();
			return false;
		}

		private static bool MenuUpdatePrefix()
		{
			if ((Object)(object)_instance == (Object)null || !_instance.CanShowTools)
			{
				return true;
			}
			if ((Object)(object)_instance != (Object)null && _instance.WindowOpen && Input.GetKeyDown((KeyCode)27))
			{
				_instance.CloseWindows();
			}
			if (!((Object)(object)_instance == (Object)null))
			{
				if (!_instance._searchFocused)
				{
					return Time.frameCount != _instance._closedFrame;
				}
				return false;
			}
			return true;
		}

		private static void OtherWindowOpeningPrefix()
		{
			if ((Object)(object)_instance != (Object)null && _instance.WindowOpen)
			{
				_instance.CloseWindows(consumeClosingInput: false);
			}
		}

		private static void MapModePrefix(MapMode __0)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			if ((int)__0 == 2)
			{
				OtherWindowOpeningPrefix();
			}
		}

		private static bool MouseWheelPrefix(ref float __result)
		{
			if (!BlockWindowInput)
			{
				return true;
			}
			__result = 0f;
			return false;
		}

		private bool IsLargeMapOpen()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			if ((Object)(object)Minimap.instance != (Object)null)
			{
				return (int)Minimap.instance.m_mode == 2;
			}
			return false;
		}

		private bool IsMissing(object adventure)
		{
			if (_repairStates.TryGetValue(adventure, out var value))
			{
				return value.Key;
			}
			return false;
		}

		private bool DrawResetButton(Rect rect)
		{
			//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_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: 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)
			Color backgroundColor = GUI.backgroundColor;
			GUI.backgroundColor = new Color(1f, 0.65f, 0.18f);
			Color color = GUI.color;
			GUI.color = new Color(0.85f, 0.32f, 0.04f);
			GUI.DrawTexture(new Rect(((Rect)(ref rect)).x - 2f, ((Rect)(ref rect)).y - 2f, ((Rect)(ref rect)).width + 4f, ((Rect)(ref rect)).height + 4f), (Texture)(object)Texture2D.whiteTexture);
			GUI.color = color;
			bool result = GUI.Button(rect, "RESET", _buttonStyle);
			GUI.backgroundColor = backgroundColor;
			return result;
		}

		private void CheckNearbyAdventures()
		{
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			RefreshTracker(scanWorld: true);
			_checkMessages.Clear();
			_nextCheckMessage = 0f;
			if (_trackerError != null)
			{
				_checkMessages.Enqueue(_trackerError);
				return;
			}
			foreach (BountyInfo bounty in _bounties.Where((BountyInfo b) => !ReadyToCollect(b) && IsNearAndLoaded(SerializableVector3.op_Implicit(b.Position), 220f)))
			{
				AddCheckResult(bounty, SafeBountyName(bounty), _cachedLoadedTargets.Any((BountyTarget t) => BountyTargetMatches(bounty, t)));
			}
			foreach (TreasureMapChestInfo treasure in _treasures.Where((TreasureMapChestInfo t) => IsNearAndLoaded(SerializableVector3.op_Implicit(t.Position), 180f)))
			{
				AddCheckResult(treasure, SafeBiomeName(treasure.Biome) + " Treasure #" + (treasure.Interval + 1), _cachedLoadedChests.Any((TreasureMapChest c) => TreasureMatchesChest(treasure, c)));
			}
			if (_checkMessages.Count == 0)
			{
				_checkMessages.Enqueue("No bounty or treasure area to check or fix nearby. Move into the area and let it load.");
			}
		}

		private void AddCheckResult(object adventure, string name, bool found)
		{
			string item = (IsMissing(adventure) ? ("Found missing or broken " + name + ": Use the Reset button to attempt a new spawn.") : (found ? (name + ": Found. Still can't find it? Try the bounty/treasure ring.") : (name + ": " + _repairStates[adventure].Value + ". Wait nearby, then Check again.")));
			_checkMessages.Enqueue(item);
		}

		private void RefreshTracker(bool scanWorld = false)
		{
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0529: Unknown result type (might be due to invalid IL or missing references)
			_nextProgressCheck = Time.unscaledTime + 5f;
			if (scanWorld)
			{
				_trackerSnapshotAt = DateTime.Now.ToString("HH:mm:ss");
			}
			try
			{
				AdventureSaveData adventureSaveData = PlayerExtensions_Adventure.GetAdventureSaveData(Player.m_localPlayer);
				HashSet<string> claimable = new HashSet<string>(from b in adventureSaveData.GetClaimableBounties()
					select b.ID);
				string text = string.Join("|", adventureSaveData.Bounties.Select((BountyInfo b) => b.ID + ":" + ((object)Unsafe.As<BountyState, BountyState>(ref b.State)/*cast due to .constrained prefix*/).ToString() + ":" + claimable.Contains(b.ID))) + "/" + string.Join("|", adventureSaveData.TreasureMaps.Select((TreasureMapChestInfo t) => ((object)Unsafe.As<Biome, Biome>(ref t.Biome)/*cast due to .constrained prefix*/).ToString() + ":" + t.Interval + ":" + ((object)Unsafe.As<TreasureMapState, TreasureMapState>(ref t.State)/*cast due to .constrained prefix*/).ToString()));
				if (!scanWorld && text == _progressSignature)
				{
					return;
				}
				Dictionary<string, KeyValuePair<bool, string>> dictionary = (from b in _bounties
					where _repairStates.ContainsKey(b)
					group b by b.ID).ToDictionary((IGrouping<string, BountyInfo> g) => g.Key, (IGrouping<string, BountyInfo> g) => _repairStates[g.First()]);
				Dictionary<string, KeyValuePair<bool, string>> dictionary2 = (from t in _treasures
					where _repairStates.ContainsKey(t)
					group t by ((object)Unsafe.As<Biome, Biome>(ref t.Biome)/*cast due to .constrained prefix*/).ToString() + ":" + t.Interval).ToDictionary((IGrouping<string, TreasureMapChestInfo> g) => g.Key, (IGrouping<string, TreasureMapChestInfo> g) => _repairStates[g.First()]);
				_claimableBounties = claimable;
				_bounties = (from b in adventureSaveData.Bounties
					where (int)b.State == 1 || ReadyToCollect(b)
					orderby b.State, SafeBiomeOrder(b.Biome)
					select b).ToList();
				_treasures = (from t in adventureSaveData.TreasureMaps
					where (int)t.State == 0
					orderby SafeBiomeOrder(t.Biome), t.Interval
					select t).ToList();
				_repairStates.Clear();
				if (scanWorld && (_bounties.Count > 0 || _treasures.Count > 0))
				{
					RefreshWorldScanCache(force: true);
				}
				foreach (BountyInfo bounty in _bounties)
				{
					if (ReadyToCollect(bounty))
					{
						_repairStates[bounty] = new KeyValuePair<bool, string>(key: false, "Ready to collect at vendor");
						continue;
					}
					if (!scanWorld || !IsNearAndLoaded(SerializableVector3.op_Implicit(bounty.Position), 220f))
					{
						_repairStates[bounty] = (dictionary.TryGetValue(bounty.ID, out var value) ? value : new KeyValuePair<bool, string>(key: false, "Active • Check nearby to diagnose"));
						continue;
					}
					string status;
					bool bountyRepairState = GetBountyRepairState(bounty, out status);
					_repairStates[bounty] = new KeyValuePair<bool, string>(bountyRepairState, status);
				}
				foreach (TreasureMapChestInfo treasure in _treasures)
				{
					if (!scanWorld || !IsNearAndLoaded(SerializableVector3.op_Implicit(treasure.Position), 180f))
					{
						_repairStates[treasure] = (dictionary2.TryGetValue(((object)Unsafe.As<Biome, Biome>(ref treasure.Biome)/*cast due to .constrained prefix*/).ToString() + ":" + treasure.Interval, out var value2) ? value2 : new KeyValuePair<bool, string>(key: false, "Check nearby to diagnose"));
						continue;
					}
					string status2;
					bool treasureRepairState = GetTreasureRepairState(treasure, out status2);
					_repairStates[treasure] = new KeyValuePair<bool, string>(treasureRepairState, status2);
				}
				_searchLabels.Clear();
				foreach (BountyInfo bounty2 in _bounties)
				{
					_searchLabels[bounty2] = SafeBountyName(bounty2) + " " + SafeMonsterName(bounty2.Target.MonsterID) + " " + SafeBiomeName(bounty2.Biome);
				}
				foreach (TreasureMapChestInfo treasure2 in _treasures)
				{
					_searchLabels[treasure2] = SafeBiomeName(treasure2.Biome) + " Treasure " + (treasure2.Interval + 1);
				}
				_progressSignature = text;
				RefilterTracker(resetScroll: false);
				_trackerError = null;
			}
			catch (Exception ex)
			{
				_trackerError = "Could not read Epic Loot adventures: " + ex.Message;
			}
		}

		private Rect GetMinimapRect()
		{
			//IL_00e9: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			float num = (float)Screen.width - 220f;
			float num2 = (float)Screen.width - 20f;
			float num3 = 230f;
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance != (Object)null && (Object)(object)instance.m_mapImageSmall != (Object)null && instance.m_smallRoot.activeInHierarchy)
			{
				RectTransform rectTransform = ((Graphic)instance.m_mapImageSmall).rectTransform;
				Canvas componentInParent = ((Component)rectTransform).GetComponentInParent<Canvas>();
				Camera obj = (((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) ? componentInParent.worldCamera : null);
				rectTransform.GetWorldCorners(_mapCorners);
				Vector2 val = RectTransformUtility.WorldToScreenPoint(obj, _mapCorners[3]);
				num = RectTransformUtility.WorldToScreenPoint(obj, _mapCorners[0]).x;
				num2 = val.x;
				num3 = (float)Screen.height - val.y;
			}
			return new Rect(num, 0f, Mathf.Max(1f, num2 - num), num3);
		}

		private Rect GetTrackerButtonRect()
		{
			//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_0038: Unknown result type (might be due to invalid IL or missing references)
			Rect minimapRect = GetMinimapRect();
			return new Rect(((Rect)(ref minimapRect)).x, Mathf.Min(((Rect)(ref minimapRect)).yMax + 6f, (float)Screen.height - 50f), ((Rect)(ref minimapRect)).width, 38f);
		}

		private void DrawTrackerButton()
		{
			//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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			Rect trackerButtonRect = GetTrackerButtonRect();
			bool enabled = GUI.enabled;
			GUI.enabled = ToolCursorRequested || InventoryGui.IsVisible() || StoreGui.IsVisible();
			if (GUI.Button(trackerButtonRect, GUIContent.none, _buttonStyle))
			{
				if (_trackerOpen)
				{
					CloseWindows();
				}
				else
				{
					PrepareWindow();
					_trackerOpen = true;
					RefreshTracker();
				}
			}
			GUI.enabled = enabled;
			DrawSpriteTexture(new Rect(((Rect)(ref trackerButtonRect)).x + 5f, ((Rect)(ref trackerButtonRect)).y + 4f, 30f, 30f), GetRewardIcon("IronBountyToken"));
			GUI.Label(new Rect(((Rect)(ref trackerButtonRect)).x + 39f, ((Rect)(ref trackerButtonRect)).y + 8f, 90f, 24f), string.Format("{0}  {1}", _trackerKey.Value, _trackerOpen ? "Hide" : "Show"), _goldStyle);
		}

		private void DrawTracker()
		{
			//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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: 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_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: 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_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0483: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0433: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0557: Unknown result type (might be due to invalid IL or missing references)
			Rect trackerButtonRect = GetTrackerButtonRect();
			float num = Mathf.Min(Mathf.Clamp(440f, 380f, 640f), (float)Screen.width - 20f);
			float num2 = ((num < 358f) ? 252f : 166f);
			float num3 = Mathf.Min(((Rect)(ref trackerButtonRect)).yMax + 6f, Mathf.Max(10f, (float)Screen.height - 280f));
			float num4 = Mathf.Min(570f, (float)Screen.height - num3 - 10f);
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(Mathf.Clamp(((Rect)(ref trackerButtonRect)).xMax - num, 10f, (float)Screen.width - num - 10f), num3, num, num4);
			_trackerRect = val;
			Color color = GUI.color;
			GUI.color = new Color(0.1f, 0.075f, 0.045f, 1f);
			GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture);
			GUI.color = color;
			DrawValheimFrame(val);
			GUI.Label(new Rect(((Rect)(ref val)).x + 18f, ((Rect)(ref val)).y + 12f, ((Rect)(ref val)).width - 170f, 32f), "Adventures", _sectionStyle);
			if (GUI.Button(new Rect(((Rect)(ref val)).xMax - 46f, ((Rect)(ref val)).y + 12f, 30f, 28f), "X", _buttonStyle))
			{
				CloseWindows();
				return;
			}
			if (GUI.Button(new Rect(((Rect)(ref val)).xMax - 135f, ((Rect)(ref val)).y + 12f, 82f, 28f), "Check", _buttonStyle))
			{
				CheckNearbyAdventures();
			}
			GUI.Label(new Rect(((Rect)(ref val)).x + 18f, ((Rect)(ref val)).y + 45f, num - 36f, 24f), $"{_trackerKey.Value}: close | Alt: toggle cursor | {_trackerSnapshotAt}", _smallStyle);
			if (_trackerError != null)
			{
				GUI.Label(new Rect(((Rect)(ref val)).x + 18f, ((Rect)(ref val)).y + 80f, num - 36f, 80f), _trackerError, _diagStyle);
				return;
			}
			DrawTrackerFilters(val);
			List<BountyInfo> visibleBounties = _visibleBounties;
			List<TreasureMapChestInfo> visibleTreasures = _visibleTreasures;
			float num5 = 34f + ((visibleBounties.Count == 0) ? 42f : ((float)visibleBounties.Count * num2)) + 20f;
			if (_bountyFilter != 2)
			{
				num5 += 34f + ((visibleTreasures.Count == 0) ? 42f : ((float)visibleTreasures.Count * num2));
			}
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(((Rect)(ref val)).x + 12f, ((Rect)(ref val)).y + 145f, ((Rect)(ref val)).width - 24f, ((Rect)(ref val)).height - 209f);
			Rect val3 = default(Rect);
			((Rect)(ref val3))..ctor(0f, 0f, ((Rect)(ref val2)).width - 22f, Mathf.Max(((Rect)(ref val2)).height, num5));
			_trackerScroll = GUI.BeginScrollView(val2, _trackerScroll, val3);
			float num6 = 0f;
			GUI.Label(new Rect(8f, num6, ((Rect)(ref val3)).width - 16f, 30f), $"Bounties ({visibleBounties.Count})", _sectionStyle);
			num6 += 34f;
			if (visibleBounties.Count == 0)
			{
				GUI.Label(new Rect(12f, num6, ((Rect)(ref val3)).width - 24f, 34f), "No matching bounties.", _smallStyle);
				num6 += 42f;
			}
			else
			{
				foreach (BountyInfo item in visibleBounties)
				{
					if (num6 + num2 - 6f >= _trackerScroll.y && num6 <= _trackerScroll.y + ((Rect)(ref val2)).height)
					{
						DrawBountyRow(new Rect(6f, num6, ((Rect)(ref val3)).width - 12f, num2 - 6f), item);
					}
					num6 += num2;
				}
			}
			if (_bountyFilter != 2)
			{
				GUI.Label(new Rect(8f, num6, ((Rect)(ref val3)).width - 16f, 30f), $"Treasure Maps ({visibleTreasures.Count})", _sectionStyle);
				num6 += 34f;
				if (visibleTreasures.Count == 0)
				{
					GUI.Label(new Rect(12f, num6, ((Rect)(ref val3)).width - 24f, 34f), "No matching treasure maps.", _smallStyle);
					num6 += 42f;
				}
				else
				{
					foreach (TreasureMapChestInfo item2 in visibleTreasures)
					{
						if (num6 + num2 - 6f >= _trackerScroll.y && num6 <= _trackerScroll.y + ((Rect)(ref val2)).height)
						{
							DrawTreasureRow(new Rect(6f, num6, ((Rect)(ref val3)).width - 12f, num2 - 6f), item2);
						}
						num6 += num2;
					}
				}
			}
			GUI.EndScrollView();
			GUI.Label(new Rect(((Rect)(ref val)).x + 18f, ((Rect)(ref val)).yMax - 59f, num - 36f, 48f), string.IsNullOrEmpty(_repairFeedback) ? "Progress updates every 5s. Missing something nearby? Press Check." : _repairFeedback, _diagStyle);
			if (ToolCursorRequested)
			{
				ConsumePointerEvent(val);
			}
		}

		private void DrawNarrowAdventure(Rect rect, BountyInfo bounty, TreasureMapChestInfo treasure)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: 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_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0445: Unknown result type (might be due to invalid IL or missing references)
			//IL_045d: Unknown result type (might be due to invalid IL or missing references)
			//IL_048d: Unknown result type (might be due to invalid IL or missing references)
			object key = ((object)bounty) ?? ((object)treasure);
			KeyValuePair<bool, string> value;
			KeyValuePair<bool, string> keyValuePair = (_repairStates.TryGetValue(key, out value) ? value : default(KeyValuePair<bool, string>));
			GUI.Box(rect, GUIContent.none, _rowStyle);
			float num = ((Rect)(ref rect)).x + 6f;
			float num2 = ((Rect)(ref rect)).width - 12f;
			Sprite sprite = GetTreasureMapIcon();
			List<KeyValuePair<string, int>> list = new List<KeyValuePair<string, int>>();
			string text;
			string text2;
			Vector3 val;
			if (bounty != null)
			{
				try
				{
					sprite = AdventureDataManager.GetTrophyIconForMonster(bounty.Target.MonsterID, bounty.RewardGold > 0);
				}
				catch
				{
				}
				text = (ReadyToCollect(bounty) ? "READY · " : "") + SafeBountyName(bounty);
				text2 = $"{SafeBiomeName(bounty.Biome)} • Level {bounty.Target.Level} ({Mathf.Max(0, bounty.Target.Level - 1)} stars)";
				val = SerializableVector3.op_Implicit(bounty.Position) + SerializableVector3.op_Implicit(bounty.MinimapCircleOffset);
				list.Add(new KeyValuePair<string, int>("IronBountyToken", bounty.RewardIron));
				list.Add(new KeyValuePair<string, int>("GoldBountyToken", bounty.RewardGold));
				list.Add(new KeyValuePair<string, int>("Coins", bounty.RewardCoins));
			}
			else
			{
				text = $"{SafeBiomeName(treasure.Biome)} Treasure #{treasure.Interval + 1}";
				val = SerializableVector3.op_Implicit(treasure.Position) + SerializableVector3.op_Implicit(treasure.MinimapCircleOffset);
				text2 = $"{HorizontalDistance(((Component)Player.m_localPlayer).transform.position, val):0}m • + random loot";
				TreasureMapBiomeInfoConfig val2 = AdventureDataManager.Config?.TreasureMap?.BiomeInfo?.Find((TreasureMapBiomeInfoConfig v) => v.GetBiome() == treasure.Biome);
				if (val2 != null)
				{
					list.Add(new KeyValuePair<string, int>("ForestToken", val2.ForestTokens));
					list.Add(new KeyValuePair<string, int>("IronBountyToken", val2.IronTokens));
					list.Add(new KeyValuePair<string, int>("GoldBountyToken", val2.GoldTokens));
					list.Add(new KeyValuePair<string, int>("Coins", val2.Coins));
				}
			}
			DrawSpriteTexture(new Rect(num, ((Rect)(ref rect)).y + 8f, 28f, 28f), sprite);
			GUI.Label(new Rect(num + 32f, ((Rect)(ref rect)).y + 6f, num2 - 32f, 54f), text, _diagStyle);
			GUI.Label(new Rect(num, ((Rect)(ref rect)).y + 63f, num2, 44f), text2, _diagStyle);
			int num3 = 0;
			foreach (KeyValuePair<string, int> item in list)
			{
				if (item.Value > 0)
				{
					float num4 = num + (float)(num3 % 2) * num2 * 0.5f;
					float num5 = ((Rect)(ref rect)).y + 111f + (float)(num3 / 2) * 23f;
					DrawSpriteTexture(new Rect(num4, num5, 18f, 18f), GetRewardIcon(item.Key));
					GUI.Label(new Rect(num4 + 20f, num5, num2 * 0.5f - 20f, 21f), $"{item.Value}", _rewardAmountStyle);
					num3++;
				}
			}
			GUI.Label(new Rect(num, ((Rect)(ref rect)).y + 159f, num2, 52f), keyValuePair.Value ?? "Checking...", _diagStyle);
			float num6 = (keyValuePair.Key ? (num2 * 0.5f - 2f) : num2);
			if (GUI.Button(new Rect(num, ((Rect)(ref rect)).y + 216f, num6, 24f), "Map", _buttonStyle))
			{
				FocusMap(val);
			}
			if (keyValuePair.Key && DrawResetButton(new Rect(num + num6 + 4f, ((Rect)(ref rect)).y + 211f, num6, 30f)))
			{
				if (bounty != null)
				{
					TryReloadBounty(bounty);
				}
				else
				{
					TryReloadTreasureMap(treasure);
				}
				RefreshTracker(scanWorld: true);
			}
		}

		private void DrawBountyRow(Rect rect, BountyInfo bounty)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ea: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Invalid comparison between Unknown and I4
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			if (((Rect)(ref rect)).width < 300f)
			{
				DrawNarrowAdventure(rect, bounty, null);
				return;
			}
			KeyValuePair<bool, string> value;
			KeyValuePair<bool, string> keyValuePair = (_repairStates.TryGetValue(bounty, out value) ? value : default(KeyValuePair<bool, string>));
			bool key = keyValuePair.Key;
			string arg = keyValuePair.Value ?? "Checking...";
			float num = (key ? 108f : 0f);
			Rect val = rect;
			GUIStyle val2 = (ReadyToCollect(bounty) ? _completedStyle : _rowStyle);
			GUI.Box(val, GUIContent.none, val2);
			bool flag = GUI.Button(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y, ((Rect)(ref val)).width, 100f), GUIContent.none, val2);
			if (!ReadyToCollect(bounty) && ((Rect)(ref val)).Contains(Event.current.mousePosition) && (int)Event.current.type == 7)
			{
				_rowHoverStyle.Draw(val, false, true, false, false);
			}
			Rect rect2 = default(Rect);
			((Rect)(ref rect2))..ctor(((Rect)(ref val)).x + 10f, ((Rect)(ref val)).y + 10f, 44f, 44f);
			Sprite sprite = null;
			try
			{
				sprite = AdventureDataManager.GetTrophyIconForMonster(bounty.Target.MonsterID, bounty.RewardGold > 0);
			}
			catch
			{
			}
			DrawSprite(rect2, sprite);
			string text = (ReadyToCollect(bounty) ? "READY · " : "") + SafeBountyName(bounty);
			string arg2 = SafeBiomeName(bounty.Biome);
			string arg3 = SafeMonsterName(bounty.Target.MonsterID);
			if (bounty.Target.Level > 1)
			{
				_ = "  " + new string('★', Mathf.Clamp(bounty.Target.Level - 1, 0, 10));
			}
			float num2 = ((Rect)(ref val)).x + 62f;
			float num3 = ((Rect)(ref val)).width - 74f;
			GUI.Label(new Rect(num2, ((Rect)(ref val)).y + 7f, num3, 23f), text, _nameStyle);
			GUI.Label(new Rect(num2, ((Rect)(ref val)).y + 29f, num3, 19f), $"{arg2}  •  {arg3}  •  Level {bounty.Target.Level}", _smallStyle);
			Color color = GUI.color;
			GUI.color = (Color)(IsBossBounty(bounty) ? new Color(1f, 0.4f, 0.3f) : ((bounty.RewardGold > 0) ? new Color(1f, 0.85f, 0.3f) : Color.white));
			GUI.Label(new Rect(num2, ((Rect)(ref val)).y + 49f, num3, 20f), BountyDifficulty(bounty), _smallStyle);
			GUI.color = color;
			DrawBountyRewards(new Rect(num2, ((Rect)(ref val)).y + 71f, num3, 22f), bounty);
			float num4 = HorizontalDistance(((Component)Player.m_localPlayer).transform.position, SerializableVector3.op_Implicit(bounty.Position) + SerializableVector3.op_Implicit(bounty.MinimapCircleOffset));
			GUI.Label(new Rect(num2, ((Rect)(ref val)).y + 97f, num3, 34f), $"{num4:0}m from marker • {arg}", _diagStyle);
			if (key)
			{
				Rect rect3 = default(Rect);
				((Rect)(ref rect3))..ctor(((Rect)(ref rect)).xMax - num, ((Rect)(ref rect)).y + 128f, num - 4f, 30f);
				if (DrawResetButton(rect3))
				{
					TryReloadBounty(bounty);
					RefreshTracker(scanWorld: true);
				}
			}
			if (flag | GUI.Button(new Rect(num2, ((Rect)(ref val)).y + 134f, num3 - num, 22f), "Show on map  >", _goldStyle))
			{
				FocusMap(SerializableVector3.op_Implicit(bounty.Position) + SerializableVector3.op_Implicit(bounty.MinimapCircleOffset));
			}
		}

		private void DrawTreasureRow(Rect rect, TreasureMapChestInfo treasure)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Invalid comparison between Unknown and I4
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			if (((Rect)(ref rect)).width < 300f)
			{
				DrawNarrowAdventure(rect, null, treasure);
				return;
			}
			KeyValuePair<bool, string> value;
			KeyValuePair<bool, string> keyValuePair = (_repairStates.TryGetValue(treasure, out value) ? value : default(KeyValuePair<bool, string>));
			bool key = keyValuePair.Key;
			string arg = keyValuePair.Value ?? "Checking...";
			float num = (key ? 108f : 0f);
			Rect val = rect;
			GUI.Box(val, GUIContent.none, _rowStyle);
			bool flag = GUI.Button(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y, ((Rect)(ref val)).width, 100f), GUIContent.none, _rowStyle);
			if (((Rect)(ref val)).Contains(Event.current.mousePosition) && (int)Event.current.type == 7)
			{
				_rowHoverStyle.Draw(val, false, true, false, false);
			}
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(((Rect)(ref val)).x + 10f, ((Rect)(ref val)).y + 13f, 44f, 44f);
			Sprite treasureMapIcon = GetTreasureMapIcon();
			if ((Object)(object)treasureMapIcon != (Object)null)
			{
				DrawSprite(val2, treasureMapIcon);
			}
			else
			{
				GUI.Box(val2, GUIContent.none, _rowStyle);
				GUI.Label(val2, "✦", _treasureIconStyle);
			}
			string arg2 = SafeBiomeName(treasure.Biome);
			Vector3 val3 = SerializableVector3.op_Implicit(treasure.Position) + SerializableVector3.op_Implicit(treasure.MinimapCircleOffset);
			float num2 = (((Object)(object)Player.m_localPlayer != (Object)null) ? HorizontalDistance(((Component)Player.m_localPlayer).transform.position, val3) : 0f);
			float num3 = ((Rect)(ref val)).x + 62f;
			float num4 = ((Rect)(ref val)).width - 74f;
			GUI.Label(new Rect(num3, ((Rect)(ref val)).y + 8f, num4, 23f), $"{arg2} Treasure #{treasure.Interval + 1}", _nameStyle);
			GUI.Label(new Rect(num3, ((Rect)(ref val)).y + 32f, num4, 34f), $"{arg}  •  {num2:0}m from marker", _diagStyle);
			DrawTreasureRewards(new Rect(num3, ((Rect)(ref val)).y + 70f, num4, 22f), treasure.Biome);
			GUI.Label(new Rect(num3, ((Rect)(ref val)).y + 94f, num4, 17f), "Treasure chest also contains random loot.", _smallStyle);
			if (key)
			{
				Rect rect2 = default(Rect);
				((Rect)(ref rect2))..ctor(((Rect)(ref rect)).xMax - num, ((Rect)(ref rect)).y + 106f, num - 4f, 30f);
				if (DrawResetButton(rect2))
				{
					TryReloadTreasureMap(treasure);
					RefreshTracker(scanWorld: true);
				}
			}
			if (flag | GUI.Button(new Rect(num3, ((Rect)(ref val)).y + 112f, num4 - num, 22f), "Show on map  >", _goldStyle))
			{
				FocusMap(val3);
			}
		}

		private bool GetTreasureRepairState(TreasureMapChestInfo treasure, out string status)
		{
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			RefreshWorldScanCache();
			if (_cachedLoadedChests.Any((TreasureMapChest chest) => TreasureMatchesChest(treasure, chest)))
			{
				status = "✓ Chest loaded";
				return false;
			}
			object obj = FindTreasureSpawner(treasure, _cachedLoadedSpawners);
			if (obj != null)
			{
				bool flag = ReadSpawnerProperty(obj, _spawnerSearchingProperty, fallback: false);
				bool flag2 = ReadPrivateField(obj, _spawnerStartedPlacementField, fallback: false);
				int num = ReadPrivateField(obj, _spawnerUpdatesRequiredField, 0);
				if (flag2 && flag)
				{
					status = "⟳ Spawner searching";
					return false;
				}
				if (!flag2 && num >= 1000)
				{
					status = "⚠ Spawner parked/retrying";
					return IsNearAndLoaded(SerializableVector3.op_Implicit(treasure.Position), Mathf.Max(80f, 180f));
				}
				status = "⟳ Spawner loaded";
				return false;
			}
			Vector3 origin = SerializableVector3.op_Implicit(treasure.Position);
			if (IsNearAndLoaded(origin, Mathf.Max(80f, 180f)))
			{
				status = "⚠ Likely orphaned";
				return true;
			}
			status = "Active • visit area to diagnose";
			return false;
		}

		private bool GetBountyRepairState(BountyInfo bounty, out string status)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: 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_00e5: Unknown result type (might be due to invalid IL or missing references)
			if ((int)bounty.State == 2)
			{
				status = "✓ Complete - return for reward";
				return false;
			}
			RefreshWorldScanCache();
			int num = _cachedLoadedTargets.Count((BountyTarget target) => BountyTargetMatches(bounty, target));
			if (num > 0)
			{
				status = $"✓ Targets loaded ({num})";
				return false;
			}
			object obj = FindBountySpawner(bounty, _cachedLoadedSpawners);
			if (obj != null)
			{
				bool flag = ReadSpawnerProperty(obj, _spawnerSearchingProperty, fallback: false);
				bool flag2 = ReadPrivateField(obj, _spawnerStartedPlacementField, fallback: false);
				int num2 = ReadPrivateField(obj, _spawnerUpdatesRequiredField, 0);
				if (flag2 && flag)
				{
					status = "⟳ Spawner searching";
					return false;
				}
				if (!flag2 && num2 >= 1000)
				{
					status = "⚠ Spawner parked/retrying";
					if (!bounty.Slain)
					{
						return IsNearAndLoaded(SerializableVector3.op_Implicit(bounty.Position), Mathf.Max(100f, 220f));
					}
					return false;
				}
				status = "⟳ Spawner loaded";
				return false;
			}
			if (bounty.Slain)
			{
				status = "⚠ Partial bounty - auto repair disabled";
				return false;
			}
			Vector3 origin = SerializableVector3.op_Implicit(bounty.Position);
			if (IsNearAndLoaded(origin, Mathf.Max(100f, 220f)))
			{
				status = "⚠ Likely orphaned";
				return true;
			}
			status = "In progress • visit area to diagnose";
			return false;
		}

		private bool IsNearAndLoaded(Vector3 origin, float limit)
		{
			//IL_0019: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				return false;
			}
			if (HorizontalDistance(((Component)Player.m_localPlayer).transform.position, origin) <= limit)
			{
				return IsAreaReady(origin);
			}
			return false;
		}

		private void RefreshWorldScanCache(bool force = false)
		{
			if (force || !(Time.unscaledTime - _lastWorldScanAt < 1f))
			{
				_lastWorldScanAt = Time.unscaledTime;
				_cachedLoadedChests = Object.FindObjectsOfType<TreasureMapChest>();
				_cachedLoadedTargets = Object.FindObjectsOfType<BountyTarget>();
				_cachedLoadedSpawners = GetLoadedSpawnerObjects();
			}
		}

		private bool IsAreaReady(Vector3 position)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				return (Object)(object)ZNetScene.instance != (Object)null && ZNetScene.instance.IsAreaReady(position);
			}
			catch
			{
				return false;
			}
		}

		private void TryReloadTreasureMap(TreasureMapChestInfo treasure)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: 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_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: 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_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || treasure == null)
			{
				return;
			}
			if ((int)treasure.State != 0)
			{
				RepairMessage("This treasure map is no longer active.", warning: true);
				return;
			}
			long playerID = localPlayer.GetPlayerID();
			if (treasure.PlayerID != 0L && treasure.PlayerID != playerID)
			{
				RepairMessage("Reload refused: this treasure belongs to a different player.", warning: true);
				return;
			}
			Vector3 val = SerializableVector3.op_Implicit(treasure.Position);
			float num = HorizontalDistance(((Component)localPlayer).transform.position, val);
			float num2 = Mathf.Max(80f, 180f);
			if (num > num2)
			{
				RepairMessage($"Move closer to the treasure circle first ({num:0}m away; reload limit {num2:0}m).", warning: true);
				return;
			}
			if (!IsAreaReady(val))
			{
				RepairMessage("Reload refused: the treasure area is not fully loaded yet. Wait a few seconds and try again.", warning: true);
				return;
			}
			RefreshWorldScanCache(force: true);
			TreasureMapChest val2 = ((IEnumerable<TreasureMapChest>)_cachedLoadedChests).FirstOrDefault((Func<TreasureMapChest, bool>)((TreasureMapChest chest) => TreasureMatchesChest(treasure, chest)));
			if ((Object)(object)val2 != (Object)null)
			{
				Vector3 position = ((Component)val2).transform.position;
				RepairMessage($"Reload cancelled: the EpicLoot chest already exists at X {position.x:0}, Z {position.z:0}.", warning: true);
				FocusMap(position);
				return;
			}
			object obj = FindTreasureSpawner(treasure, _cachedLoadedSpawners);
			if (obj != null)
			{
				bool num3 = ReadSpawnerProperty(obj, _spawnerPlacedProperty, fallback: false);
				Vector3 val3 = ReadSpawnerProperty<Vector3>(obj, _spawnerSpawnPointProperty, new Vector3(1f, 1f, 1f));
				bool flag = ReadPrivateField(obj, _spawnerStartedPlacementField, fallback: false);
				bool flag2 = ReadSpawnerProperty(obj, _spawnerSearchingProperty, fallback: false);
				if (num3 || val3 != new Vector3(1f, 1f, 1f))
				{
					RepairMessage("Reload cancelled: EpicLoot already selected/placed this treasure. Wait a moment and run F10 again.", warning: true);
					return;
				}
				if (flag && flag2)
				{
					RepairMessage("Reload cancelled: the EpicLoot spawner is actively searching right now.", warning: true);
					return;
				}
				if (_spawnerCurrentUpdatesField != null)
				{
					_spawnerCurrentUpdatesField.SetValue(obj, 0);
				}
				if (_spawnerUpdatesRequiredField != null)
				{
					_spawnerUpdatesRequiredField.SetValue(obj, 0);
				}
				if (_spawnerStartedPlacementField != null)
				{
					_spawnerStartedPlacementField.SetValue(obj, false);
				}
				_lastWorldScanAt = -999f;
				RepairMessage("EpicLoot treasure spawner found. Retry delay cleared; it will search again now.", warning: false);
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"Forced treasure spawner retry for {SafeBiomeName(treasure.Biome)} #{treasure.Interval + 1}.");
				return;
			}
			try
			{
				if (_spawnerType == null || _spawnerSetTreasureMethod == null)
				{
					throw new InvalidOperationException("AdventureSpawnController reflection is unavailable.");
				}
				ZNetScene instance = ZNetScene.instance;
				GameObject obj2 = ((instance != null) ? instance.GetPrefab("EL_SpawnController") : null);
				if ((Object)(object)obj2 == (Object)null)
				{
					throw new InvalidOperationException("EpicLoot prefab EL_SpawnController is not registered.");
				}
				Quaternion val4 = Quaternion.Euler(0f, Random.Range(0f, 360f), 0f);
				GameObject val5 = Object.Instantiate<GameObject>(obj2, val, val4);
				Component component = val5.GetComponent(_spawnerType);
				if ((Object)(object)component == (Object)null)
				{
					Object.Destroy((Object)(object)val5);
					throw new InvalidOperationException("The recreated prefab had no AdventureSpawnController component.");
				}
				_spawnerSetTreasureMethod.Invoke(component, new object[1] { treasure });
				_lastWorldScanAt = -999f;
				RepairMessage("Missing EpicLoot treasure spawner recreated. Stay nearby while it searches for a valid chest position.", warning: false);
				((BaseUnityPlugin)this).Logger.LogWarning((object)$"Recreated missing treasure spawner for {SafeBiomeName(treasure.Biome)} #{treasure.Interval + 1} at {val}.");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Treasure reload failed: " + ex));
				RepairMessage("Treasure reload failed. Check the BepInEx log for details.", warning: true);
			}
		}

		private void TryReloadBounty(BountyInfo bounty)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Invalid comparison between Unknown and I4
			//IL_0096: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: 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_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || bounty == null)
			{
				return;
			}
			if ((int)bounty.State != 1)
			{
				RepairMessage("This bounty is no longer in progress.", warning: true);
				return;
			}
			if (bounty.Slain)
			{
				RepairMessage("Reload refused: the main target was already slain. Automatic repair is disabled for partially completed bounties to avoid respawning defeated targets.", warning: true);
				return;
			}
			long playerID = localPlayer.GetPlayerID();
			if (bounty.PlayerID != 0L && bounty.PlayerID != playerID)
			{
				RepairMessage("Reload refused: this bounty belongs to a different player.", warning: true);
				return;
			}
			Vector3 val = SerializableVector3.op_Implicit(bounty.Position);
			float num = HorizontalDistance(((Component)localPlayer).transform.position, val);
			float num2 = Mathf.Max(100f, 220f);
			if (num > num2)
			{
				RepairMessage($"Move closer to the bounty circle first ({num:0}m away; reload limit {num2:0}m).", warning: true);
				return;
			}
			if (!IsAreaReady(val))
			{
				RepairMessage("Reload refused: the bounty area is not fully loaded yet. Wait a few seconds and try again.", warning: true);
				return;
			}
			RefreshWorldScanCache(force: true);
			BountyTarget val2 = ((IEnumerable<BountyTarget>)_cachedLoadedTargets).FirstOrDefault((Func<BountyTarget, bool>)((BountyTarget target) => BountyTargetMatches(bounty, target)));
			if ((Object)(object)val2 != (Object)null)
			{
				Vector3 position = ((Component)val2).transform.position;
				RepairMessage($"Reload cancelled: this bounty already has a live target at X {position.x:0}, Z {position.z:0}.", warning: true);
				FocusMap(position);
				return;
			}
			object obj = FindBountySpawner(bounty, _cachedLoadedSpawners);
			if (obj != null)
			{
				bool num3 = ReadSpawnerProperty(obj, _spawnerPlacedProperty, fallback: false);
				Vector3 val3 = ReadSpawnerProperty<Vector3>(obj, _spawnerSpawnPointProperty, new Vector3(1f, 1f, 1f));
				bool flag = ReadPrivateField(obj, _spawnerStartedPlacementField, fallback: false);
				bool flag2 = ReadSpawnerProperty(obj, _spawnerSearchingProperty, fallback: false);
				if (num3 || val3 != new Vector3(1f, 1f, 1f))
				{
					RepairMessage("Reload cancelled: EpicLoot already selected/placed this bounty. Wait a moment and run F10 again.", warning: true);
					return;
				}
				if (flag && flag2)
				{
					RepairMessage("Reload cancelled: the EpicLoot bounty spawner is actively searching right now.", warning: true);
					return;
				}
				if (_spawnerCurrentUpdatesField != null)
				{
					_spawnerCurrentUpdatesField.SetValue(obj, 0);
				}
				if (_spawnerUpdatesRequiredField != null)
				{
					_spawnerUpdatesRequiredField.SetValue(obj, 0);
				}
				if (_spawnerStartedPlacementField != null)
				{
					_spawnerStartedPlacementField.SetValue(obj, false);
				}
				_lastWorldScanAt = -999f;
				RepairMessage("EpicLoot bounty spawner found. Retry delay cleared; it will search again now.", warning: false);
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Forced bounty spawner retry for " + SafeBountyName(bounty) + " (" + bounty.ID + ")."));
				return;
			}
			try
			{
				if (_spawnerType == null || _spawnerSetBountyMethod == null || _spawnerSetIsBountyMethod == null)
				{
					throw new InvalidOperationException("AdventureSpawnController bounty reflection is unavailable.");
				}
				ZNetScene instance = ZNetScene.instance;
				GameObject obj2 = ((instance != null) ? instance.GetPrefab("EL_SpawnController") : null);
				if ((Object)(object)obj2 == (Object)null)
				{
					throw new InvalidOperationException("EpicLoot prefab EL_SpawnController is not registered.");
				}
				Quaternion val4 = Quaternion.Euler(0f, Random.Range(0f, 360f), 0f);
				GameObject val5 = Object.Instantiate<GameObject>(obj2, val, val4);
				Component component = val5.GetComponent(_spawnerType);
				if ((Object)(object)component == (Object)null)
				{
					Object.Destroy((Object)(object)val5);
					throw new InvalidOperationException("The recreated prefab had no AdventureSpawnController component.");
				}
				_spawnerSetBountyMethod.Invoke(component, new object[1] { bounty });
				_spawnerSetIsBountyMethod.Invoke(component, null);
				_lastWorldScanAt = -999f;
				RepairMessage("Missing EpicLoot bounty spawner recreated. Stay nearby while it searches for a valid target position.", warning: false);
				((BaseUnityPlugin)this).Logger.LogWarning((object)$"Recreated missing bounty spawner for {SafeBountyName(bounty)} ({bounty.ID}) at {val}.");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Bounty reload failed: " + ex));
				RepairMessage("Bounty reload failed. Check the BepInEx log for details.", warning: true);
			}
		}

		private void RepairMessage(string message, bool warning)
		{
			_repairFeedback = message;
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, message, 0, (Sprite)null, false);
			}
			if (warning)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)message);
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)message);
			}
		}

		private void FocusMap(Vector3 position)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!((Object)(object)Minimap.instance == (Object)null))
				{
					CloseWindows();
					_closedFrame = -1;
					Minimap.instance.ShowPointOnMap(position);
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not focus map: " + ex.Message));
			}
		}

		private void RunDiagnostics()
		{
			//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)
			RefreshLiveDiagnostics();
			_diagnosticScroll = Vector2.zero;
			OpenDiagnosticWindow();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("\n" + _diagnosticText));
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, "EpicLoot diagnostic complete. Press F10 again or X to close it.", 0, (Sprite)null, false);
			}
		}

		private void RefreshLiveDiagnostics()
		{
			_nextDiagnosticRefresh = Time.unscaledTime + Mathf.Max(0.5f, 2f);
			try
			{
				_diagnosticText = BuildDiagnosticReport();
			}
			catch (Exception ex)
			{
				_diagnosticText = "Diagnostic refresh failed: " + ex.Message;
			}
		}

		private void OpenDiagnosticWindow()
		{
			_diagnosticOpen = true;
		}

		private void CloseDiagnosticWindow()
		{
			CloseWindows();
		}

		private string BuildDiagnosticReport()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("EPIC LOOT ADVENTURE DIAGNOSTIC");
			stringBuilder.AppendLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
			stringBuilder.AppendLine();
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				stringBuilder.AppendLine("No local player. Join a world/server first.");
				return stringBuilder.ToString();
			}
			AdventureSaveData adventureSaveData;
			try
			{
				adventureSaveData = PlayerExtensions_Adventure.GetAdventureSaveData(Player.m_localPlayer);
			}
			catch (Exception ex)
			{
				stringBuilder.AppendLine("FAILED to read EpicLoot adventure save data: " + ex);
				return stringBuilder.ToString();
			}
			List<TreasureMapChestInfo> list = adventureSaveData.TreasureMaps.Where((TreasureMapChestInfo x) => (int)x.State == 0).ToList();
			List<BountyInfo> list2 = adventureSaveData.Bounties.Where((BountyInfo x) => (int)x.State == 1 || (int)x.State == 2).ToList();
			TreasureMapChest[] array = Object.FindObjectsOfType<TreasureMapChest>();
			BountyTarget[] array2 = Object.FindObjectsOfType<BountyTarget>();
			Object[] loadedSpawnerObjects = GetLoadedSpawnerObjects();
			stringBuilder.AppendLine($"Active treasure maps: {list.Count}");
			stringBuilder.AppendLine($"Active bounties: {list2.Count}");
			stringBuilder.AppendLine($"Loaded EpicLoot treasure chests visible to this client: {array.Length}");
			stringBuilder.AppendLine($"Loaded EpicLoot bounty targets visible to this client: {array2.Length}");
			stringBuilder.AppendLine($"Loaded AdventureSpawnControllers visible to this client: {loadedSpawnerObjects.Length}");
			stringBuilder.AppendLine();
			if (list.Count == 0)
			{
				stringBuilder.AppendLine("TREASURES: none active");
			}
			else
			{
				stringBuilder.AppendLine("TREASURES");
				foreach (TreasureMapChestInfo item in list)
				{
					AppendTreasureDiagnostic(stringBuilder, item, array, loadedSpawnerObjects);
				}
			}
			stringBuilder.AppendLine();
			if (list2.Count == 0)
			{
				stringBuilder.AppendLine("BOUNTIES: none active");
			}
			else
			{
				stringBuilder.AppendLine("BOUNTIES");
				foreach (BountyInfo item2 in list2)
				{
					AppendBountyDiagnostic(stringBuilder, item2, array2, loadedSpawnerObjects);
				}
			}
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("IMPORTANT: 'UNKNOWN / NOT LOADED' does not prove the chest is missing.");
			stringBuilder.AppendLine("Valheim clients only know nearby world objects. Stand inside/near the EpicLoot map circle and watch the next live refresh.");
			return stringBuilder.ToString();
		}

		private void AppendTreasureDiagnostic(StringBuilder sb, TreasureMapChestInfo map, TreasureMapChest[] loadedChests, Object[] loadedSpawners)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: 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_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = SerializableVector3.op_Implicit(map.Position);
			Vector3 val2 = val + SerializableVector3.op_Implicit(map.MinimapCircleOffset);
			float num = HorizontalDistance(((Component)Player.m_localPlayer).transform.position, val2);
			float num2 = HorizontalDistance(((Component)Player.m_localPlayer).transform.position, val);
			bool flag = IsAreaReady(val);
			sb.AppendLine($"- {SafeBiomeName(map.Biome)} Treasure #{map.Interval + 1}");
			sb.AppendLine($"  Marker: X {val2.x:0.0}, Z {val2.z:0.0} | player distance {num:0}m");
			sb.AppendLine(string.Format("  Search origin: X {0:0.0}, Z {1:0.0} | origin distance {2:0}m | area loaded: {3}", val.x, val.z, num2, flag ? "YES" : "NO"));
			TreasureMapChest val3 = ((IEnumerable<TreasureMapChest>)loadedChests).FirstOrDefault((Func<TreasureMapChest, bool>)((TreasureMapChest chest) => TreasureMatchesChest(map, chest)));
			if ((Object)(object)val3 != (Object)null)
			{
				Vector3 position = ((Component)val3).transform.position;
				float num3 = HorizontalDistance(val2, position);
				sb.AppendLine("  STATUS: SPAWNED + LOADED");
				sb.AppendLine($"  Actual chest: X {position.x:0.0}, Y {position.y:0.0}, Z {position.z:0.0} | {num3:0.0}m from map marker");
				return;
			}
			object obj = FindTreasureSpawner(map, loadedSpawners);
			if (obj != null)
			{
				bool num4 = ReadSpawnerProperty(obj, _spawnerPlacedProperty, fallback: false);
				bool flag2 = ReadSpawnerProperty(obj, _spawnerSearchingProperty, fallback: false);
				Vector3 val4 = ReadSpawnerProperty<Vector3>(obj, _spawnerSpawnPointProperty, new Vector3(1f, 1f, 1f));
				bool flag3 = ReadPrivateField(obj, _spawnerStartedPlacementField, fallback: false);
				int num5 = ReadPrivateField(obj, _spawnerCurrentUpdatesField, 0);
				int num6 = ReadPrivateField(obj, _spawnerUpdatesRequiredField, 0);
				if (num4)
				{
					sb.AppendLine("  STATUS: spawner says PLACED, but the chest is not currently loaded on this client.");
				}
				else if (val4 != new Vector3(1f, 1f, 1f))
				{
					sb.AppendLine("  STATUS: valid spawn point selected; chest should be spawning now.");
					sb.AppendLine($"  Selected point: X {val4.x:0.0}, Y {val4.y:0.0}, Z {val4.z:0.0}");
				}
				else if (flag3 && flag2)
				{
					sb.AppendLine("  STATUS: SPAWNER LOADED + SEARCHING for a valid chest position.");
				}
				else if (!flag3 && num6 >= 1000)
				{
					sb.AppendLine($"  STATUS: SPAWNER PARKED / RETRY DELAY ({num5}/{num6} update ticks). A previous placement search likely failed.");
				}
				else
				{
					sb.AppendLine($"  STATUS: SPAWNER LOADED, waiting to search ({num5}/{num6} update ticks). searching={flag2}");
				}
			}
			else
			{
				float num7 = Mathf.Max(80f, 180f);
				if (flag && num2 <= num7)
				{
					sb.AppendLine("  STATUS: LIKELY ORPHANED / BROKEN.");
					sb.AppendLine("  The treasure area is loaded, but no matching EpicLoot chest or AdventureSpawnController is present.");
					sb.AppendLine("  The tracker Reload button can recreate the missing spawner.");
				}
				else
				{
					sb.AppendLine("  STATUS: UNKNOWN / NOT LOADED on this client.");
					sb.AppendLine("  Go to this treasure circle, wait ~10 seconds, then press F10 again.");
				}
			}
		}

		private void AppendBountyDiagnostic(StringBuilder sb, BountyInfo bounty, BountyTarget[] loadedTargets, Object[] loadedSpawners)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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_0089: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Invalid comparison between Unknown and I4
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: 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_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: 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_022f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = SerializableVector3.op_Implicit(bounty.Position);
			Vector3 val2 = val + SerializableVector3.op_Implicit(bounty.MinimapCircleOffset);
			float num = HorizontalDistance(((Component)Player.m_localPlayer).transform.position, val2);
			float num2 = HorizontalDistance(((Component)Player.m_localPlayer).transform.position, val);
			bool flag = IsAreaReady(val);
			sb.AppendLine($"- {SafeBountyName(bounty)} ({SafeBiomeName(bounty.Biome)}) - {bounty.State}");
			sb.AppendLine($"  Marker: X {val2.x:0.0}, Z {val2.z:0.0} | player distance {num:0}m");
			sb.AppendLine(string.Format("  Spawn origin: X {0:0.0}, Z {1:0.0} | origin distance {2:0}m | area loaded: {3}", val.x, val.z, num2, flag ? "YES" : "NO"));
			int num3 = loadedTargets.Count((BountyTarget target) => BountyTargetMatches(bounty, target));
			if (num3 > 0)
			{
				sb.AppendLine($"  STATUS: SPAWNED + LOADED ({num3} bounty target component(s) visible)");
				return;
			}
			object obj = FindBountySpawner(bounty, loadedSpawners);
			if (obj != null)
			{
				bool num4 = ReadSpawnerProperty(obj, _spawnerPlacedProperty, fallback: false);
				bool flag2 = ReadSpawnerProperty(obj, _spawnerSearchingProperty, fallback: false);
				Vector3 val3 = ReadSpawnerProperty<Vector3>(obj, _spawnerSpawnPointProperty, new Vector3(1f, 1f, 1f));
				bool flag3 = ReadPrivateField(obj, _spawnerStartedPlacementField, fallback: false);
				int num5 = ReadPrivateField(obj, _spawnerCurrentUpdatesField, 0);
				int num6 = ReadPrivateField(obj, _spawnerUpdatesRequiredField, 0);
				if (num4)
				{
					sb.AppendLine("  STATUS: spawner says PLACED, but no bounty target is currently loaded on this client.");
				}
				else if (val3 != new Vector3(1f, 1f, 1f))
				{
					sb.AppendLine($"  STATUS: valid spawn point selected at X {val3.x:0.0}, Y {val3.y:0.0}, Z {val3.z:0.0}; targets should be spawning.");
				}
				else if (flag3 && flag2)
				{
					sb.AppendLine("  STATUS: SPAWNER LOADED + SEARCHING for a valid bounty position.");
				}
				else if (!flag3 && num6 >= 1000)
				{
					sb.AppendLine($"  STATUS: SPAWNER PARKED / RETRY DELAY ({num5}/{num6} update ticks). Reload becomes available in the tracker when safe.");
				}
				else
				{
					sb.AppendLine($"  STATUS: SPAWNER LOADED, waiting ({num5}/{num6} update ticks).");
				}
			}
			else if ((int)bounty.State == 2)
			{
				sb.AppendLine("  STATUS: COMPLETE. No living targets are expected.");
			}
			else if (bounty.Slain)
			{
				sb.AppendLine("  STATUS: PARTIALLY COMPLETED / TARGET MISSING.");
				sb.AppendLine("  The main target was already slain, so automatic recreation is disabled to avoid respawning defeated targets.");
			}
			else
			{
				float num7 = Mathf.Max(100f, 220f);
				if (flag && num2 <= num7)
				{
					sb.AppendLine("  STATUS: LIKELY ORPHANED / BROKEN.");
					sb.AppendLine("  The bounty area is loaded, but no matching bounty target or AdventureSpawnController is present.");
					sb.AppendLine("  The tracker Reload button can recreate the missing bounty spawner.");
				}
				else
				{
					sb.AppendLine("  STATUS: UNKNOWN / NOT LOADED. Go near the bounty circle and press F10 again.");
				}
			}
		}

		private bool TreasureMatchesChest(TreasureMapChestInfo map, TreasureMapChest chest)
		{
			//IL_0018: 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)
			if ((Object)(object)chest == (Object)null || chest.Interval != map.Interval || chest.Biome != map.Biome)
			{
				return false;
			}
			try
			{
				ZNetView component = ((Component)chest).GetComponent<ZNetView>();
				ZDO val = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null);
				if (val != null)
				{
					long num = val.GetLong("creator", 0L);
					return num == 0L || map.PlayerID == 0L || num == map.PlayerID;
				}
			}
			catch
			{
			}
			return true;
		}

		private bool BountyTargetMatches(BountyInfo bounty, BountyTarget target)
		{
			if ((Object)(object)target == (Object)null)
			{
				return false;
			}
			try
			{
				object? obj = typeof(BountyTarget).GetField("_bountyInfo", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(target);
				BountyInfo val = (BountyInfo)((obj is BountyInfo) ? obj : null);
				return val != null && val.ID == bounty.ID;
			}
			catch
			{
				return false;
			}
		}

		private void CacheSpawnerReflection()
		{
			try
			{
				_spawnerType = typeof(TreasureMapChest).Assembly.GetType("EpicLoot.Adventure.AdventureSpawnController", throwOnError: false);
				if (!(_spawnerType == null))
				{
					_spawnerTreasureProperty = _spawnerType.GetProperty("treasure", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					_spawnerBountyProperty = _spawnerType.GetProperty("bounty", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					_spawnerPlacedProperty = _spawnerType.GetProperty("placed", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					_spawnerSearchingProperty = _spawnerType.GetProperty("searchingForSpawn", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					_spawnerSpawnPointProperty = _spawnerType.GetProperty("spawnPoint", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					_spawnerStartedPlacementField = _spawnerType.GetField("startedPlacement", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					_spawnerCurrentUpdatesField = _spawnerType.GetField("currentUpdates", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					_spawnerUpdatesRequiredField = _spawnerType.GetField("updatesRequired", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					_spawnerSetTreasureMethod = _spawnerType.GetMethod("SetTreasure", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					_spawnerSetBountyMethod = _spawnerType.GetMethod("SetBounty", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					_spawnerSetIsBountyMethod = _spawnerType.GetMethod("SetIsBounty", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not prepare AdventureSpawnController diagnostics: " + ex.Message));
			}
		}

		private Object[] GetLoadedSpawnerObjects()
		{
			if (_spawnerType == null)
			{
				return (Object[])(object)new Object[0];
			}
			try
			{
				return Object.FindObjectsOfType(_spawnerType);
			}
			catch
			{
				return (Object[])(object)new Object[0];
			}
		}

		private object FindTreasureSpawner(TreasureMapChestInfo map, Object[] spawners)
		{
			//IL_0038: 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)
			foreach (Object val in spawners)
			{
				try
				{
					TreasureMapChestInfo val2 = ReadSpawnerProperty<TreasureMapChestInfo>(val, _spawnerTreasureProperty, null);
					if (val2 != null && val2.PlayerID == map.PlayerID && val2.Interval == map.Interval && val2.Biome == map.Biome)
					{
						return val;
					}
				}
				catch
				{
				}
			}
			return null;
		}

		private object FindBountySpawner(BountyInfo bounty, Object[] spawners)
		{
			foreach (Object val in spawners)
			{
				try
				{
					BountyInfo val2 = ReadSpawnerProperty<BountyInfo>(val, _spawnerBountyProperty, null);
					if (val2 != null && val2.ID == bounty.ID)
					{
						return val;
					}
				}
				catch
				{
				}
			}
			return null;
		}

		private static T ReadSpawnerProperty<T>(object spawner, PropertyInfo property, T fallback)
		{
			if (spawner == null || property == null)
			{
				return fallback;
			}
			object value = property.GetValue(spawner, null);
			if (value == null)
			{
				return fallback;
			}
			MethodInfo method = value.GetType().GetMethod("Get", BindingFlags.Instance | BindingFlags.Public);
			if (method == null)
			{
				return fallback;
			}
			object obj = method.Invoke(value, null);
			if (obj is T)
			{
				return (T)obj;
			}
			return fallback;
		}

		private static T ReadPrivateField<T>(object instance, FieldInfo field, T fallback)
		{
			try
			{
				if (instance == null || field == null)
				{
					return fallback;
				}
				return (field.GetValu