Decompiled source of MMOHeimSimpleQuest v1.0.3

MMOHeimSimpleQuest.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("MMOHeim SimpleQuest")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MMOHeim SimpleQuest")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("526f6350-8ad0-4fd8-8066-5806b070f058")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SimpleQuest;

[HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })]
public static class ItemCollectionPatch
{
	private static void Postfix(Inventory __instance, ItemData item, bool __result)
	{
		if (!__result || item == null || (Object)(object)item.m_dropPrefab == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null || __instance != ((Humanoid)Player.m_localPlayer).GetInventory())
		{
			return;
		}
		if ((Object)(object)SimpleQuestPro.Instance != (Object)null)
		{
			string name = ((Object)item.m_dropPrefab).name;
			foreach (QuestConfig item2 in SimpleQuestPro.Instance.serverQuests.Quests.Where((QuestConfig q) => string.IsNullOrEmpty(q.PreReqID) || SimpleQuestPro.Instance.completedQuests.Contains(q.PreReqID)).ToList())
			{
				if (!SimpleQuestPro.Instance.completedQuests.Contains(item2.ID))
				{
					QuestRequirement questRequirement = item2.Reqs?.FirstOrDefault((QuestRequirement r) => r.Prefab.Trim().Equals(name, StringComparison.OrdinalIgnoreCase));
					if (questRequirement != null)
					{
						int itemCount = QuestUtils.GetItemCount(name);
						string itemName = QuestUtils.GetItemName(name);
						((Character)Player.m_localPlayer).Message((MessageType)1, $"<b><color=#FFD700>{itemName}: {itemCount} / {questRequirement.Amount}</color></b>", 0, (Sprite)null);
					}
				}
			}
			if (SimpleQuestPro.Instance.IsWindowActive())
			{
				QuestUI.UpdateUI();
			}
		}
		QuestUI.UpdateHUD();
	}
}
[HarmonyPatch]
public static class PlantWatcher
{
	[HarmonyPatch(typeof(Player), "ConsumeResources")]
	[HarmonyPrefix]
	private static void Prefix(Requirement[] requirements, int itemQuality)
	{
		if (requirements == null || (Object)(object)Player.m_localPlayer == (Object)null)
		{
			return;
		}
		foreach (Requirement val in requirements)
		{
			if (val == null || (Object)(object)val.m_resItem == (Object)null)
			{
				continue;
			}
			string name = ((Object)val.m_resItem).name;
			string questName = "";
			if (name.Contains("CarrotSeeds"))
			{
				questName = "Carrot";
			}
			else if (name.Contains("TurnipSeeds"))
			{
				questName = "Turnip";
			}
			else if (name.Contains("OnionSeeds"))
			{
				questName = "Onion";
			}
			else if (name.Contains("Seed"))
			{
				questName = name.Replace("Seeds", "").Replace("Seed", "");
			}
			if (string.IsNullOrEmpty(questName))
			{
				continue;
			}
			if ((Object)(object)SimpleQuestPro.Instance != (Object)null)
			{
				foreach (QuestConfig visibleQuest in QuestUtils.GetVisibleQuests())
				{
					if (SimpleQuestPro.Instance.completedQuests.Contains(visibleQuest.ID))
					{
						continue;
					}
					QuestRequirement questRequirement = visibleQuest.KillReqs?.FirstOrDefault((QuestRequirement k) => string.Equals(k.Prefab.Trim(), questName, StringComparison.OrdinalIgnoreCase));
					if (questRequirement != null)
					{
						if (!SimpleQuestPro.playerKills.ContainsKey(questName))
						{
							SimpleQuestPro.playerKills[questName] = 0;
						}
						SimpleQuestPro.playerKills[questName]++;
						int num = SimpleQuestPro.playerKills[questName];
						string itemName = QuestUtils.GetItemName(questName);
						((Character)Player.m_localPlayer).Message((MessageType)1, $"<b><color=#FFD700>{itemName}: {num} / {questRequirement.Amount}</color></b>", 0, (Sprite)null);
					}
				}
				if (SimpleQuestPro.Instance.IsWindowActive())
				{
					QuestUI.UpdateUI();
				}
			}
			QuestUI.UpdateHUD();
		}
	}
}
public class QuestConfig
{
	public string ID;

	public string Title;

	public string Goal;

	public string Rarity;

	public string RewardItem;

	public string PreReqID;

	public int RewardAmount;

	public int ExpReward;

	public List<QuestRequirement> Reqs;

	public List<QuestRequirement> KillReqs;

	public List<QuestRequirement> RewardItems;
}
public class QuestList
{
	public List<QuestConfig> Quests = new List<QuestConfig>();
}
public class QuestRequirement
{
	public string Prefab;

	public int Amount;
}
public static class QuestUI
{
	private class TrackerDragHandler : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler, IEndDragHandler
	{
		private RectTransform rectTransform;

		private Canvas canvas;

		private bool canDrag;

		public void OnBeginDrag(PointerEventData eventData)
		{
			canDrag = IsTrackerDragAllowed() && (Object)(object)hudPanel != (Object)null && hudPanel.activeSelf;
			if (canDrag)
			{
				rectTransform = hudPanel.GetComponent<RectTransform>();
				canvas = (((Object)(object)rectTransform != (Object)null) ? ((Component)rectTransform).GetComponentInParent<Canvas>() : null);
			}
		}

		public void OnDrag(PointerEventData eventData)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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)
			if (!IsTrackerDragAllowed())
			{
				canDrag = false;
			}
			else if (canDrag && !((Object)(object)rectTransform == (Object)null))
			{
				float num = (((Object)(object)canvas != (Object)null && canvas.scaleFactor > 0f) ? canvas.scaleFactor : 1f);
				RectTransform obj = rectTransform;
				obj.anchoredPosition += eventData.delta / num;
				ClampRectToScreen(rectTransform);
			}
		}

		public void OnEndDrag(PointerEventData eventData)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (canDrag && (Object)(object)rectTransform != (Object)null && (Object)(object)SimpleQuestPro.Instance != (Object)null)
			{
				ClampRectToScreen(rectTransform);
				SimpleQuestPro.Instance.SaveTrackerPosition(ToSavedTopLeft(rectTransform));
			}
			canDrag = false;
		}
	}

	[Serializable]
	[CompilerGenerated]
	private sealed class <>c
	{
		public static readonly <>c <>9 = new <>c();

		public static UnityAction <>9__10_0;

		public static UnityAction <>9__10_1;

		public static UnityAction <>9__10_2;

		public static UnityAction <>9__10_3;

		public static Func<KeyValuePair<string, int>, int> <>9__11_2;

		public static Func<QuestRequirement, string> <>9__11_0;

		public static Func<KeyValuePair<string, int>, int> <>9__12_2;

		internal void <CreateUI>b__10_0()
		{
			List<QuestConfig> visibleQuests = QuestUtils.GetVisibleQuests();
			if (visibleQuests.Count > 0)
			{
				QuestConfig questConfig = visibleQuests[currentIndex];
				if (SimpleQuestPro.trackedQuests.Contains(questConfig.ID))
				{
					SimpleQuestPro.trackedQuests.Remove(questConfig.ID);
				}
				else
				{
					SimpleQuestPro.trackedQuests.Add(questConfig.ID);
				}
				UpdateUI();
				UpdateHUD();
				QuestUtils.PlaySfx("sfx_gui_mouse_over");
			}
		}

		internal void <CreateUI>b__10_1()
		{
			int count = QuestUtils.GetVisibleQuests().Count;
			if (count > 0)
			{
				currentIndex = (currentIndex - 1 + count) % count;
				currentIconIndex = 0;
				UpdateUI();
				QuestUtils.PlaySfx("sfx_book_page");
			}
		}

		internal void <CreateUI>b__10_2()
		{
			int count = QuestUtils.GetVisibleQuests().Count;
			if (count > 0)
			{
				currentIndex = (currentIndex + 1) % count;
				currentIconIndex = 0;
				UpdateUI();
				QuestUtils.PlaySfx("sfx_book_page");
			}
		}

		internal void <CreateUI>b__10_3()
		{
			showHistoryMode = !showHistoryMode;
			currentIndex = 0;
			UpdateUI();
			QuestUtils.PlaySfx("sfx_book_page");
		}

		internal int <UpdateUI>b__11_2(KeyValuePair<string, int> x)
		{
			return x.Value;
		}

		internal string <UpdateUI>b__11_0(QuestRequirement x)
		{
			return $"{QuestUtils.GetItemName(x.Prefab)} x{x.Amount}";
		}

		internal int <UpdateHUD>b__12_2(KeyValuePair<string, int> x)
		{
			return x.Value;
		}
	}

	public static GameObject window;

	public static GameObject hudPanel;

	public static Text infoText;

	public static Text pageText;

	public static Text btnText;

	public static Text titleText;

	public static Text historyBtnText;

	public static Text hudText;

	public static Text trackBtnText;

	public static GameObject btnFinish;

	public static GameObject btnHistory;

	public static GameObject btnTrack;

	public static Image rewardIcon;

	public static int currentIndex;

	public static int currentIconIndex;

	public static float iconTimer;

	public static bool showHistoryMode;

	private static bool hudAttachedToMinimap;

	private static Image hudBackground;

	private static CanvasGroup hudCanvasGroup;

	private static readonly Color hudGhostColor = new Color(0.22f, 0.16f, 0.1f, 0f);

	private static Transform ResolveMainUiRoot()
	{
		if ((Object)(object)GUIManager.CustomGUIFront != (Object)null)
		{
			return GUIManager.CustomGUIFront.transform;
		}
		if ((Object)(object)Hud.instance != (Object)null)
		{
			return ((Component)Hud.instance).transform;
		}
		return null;
	}

	private static void DestroySafe(GameObject go)
	{
		if ((Object)(object)go != (Object)null)
		{
			Object.Destroy((Object)(object)go);
		}
	}

	public static void CleanupUI()
	{
		DestroySafe(window);
		DestroySafe(hudPanel);
		window = null;
		hudPanel = null;
		infoText = null;
		pageText = null;
		btnText = null;
		titleText = null;
		historyBtnText = null;
		hudText = null;
		trackBtnText = null;
		btnFinish = null;
		btnHistory = null;
		btnTrack = null;
		rewardIcon = null;
		hudBackground = null;
		hudCanvasGroup = null;
		hudAttachedToMinimap = false;
	}

	private static string L(string key, string fallback)
	{
		string text = "$" + key;
		string text2 = ((Localization.instance != null) ? Localization.instance.Localize(text) : text);
		if (!(text2 == text) && !string.IsNullOrEmpty(text2))
		{
			return text2;
		}
		return fallback;
	}

	private static bool IsTrackerDragAllowed()
	{
		if ((Object)(object)Menu.instance != (Object)null)
		{
			return Menu.IsVisible();
		}
		return false;
	}

	public static void SetTrackerInteractionEnabled(bool enabled)
	{
		if ((Object)(object)hudBackground != (Object)null)
		{
			((Graphic)hudBackground).raycastTarget = enabled;
		}
		if ((Object)(object)hudCanvasGroup != (Object)null)
		{
			hudCanvasGroup.blocksRaycasts = enabled;
			hudCanvasGroup.interactable = enabled;
		}
	}

	private static Vector2 ToSavedTopLeft(RectTransform rectTransform)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		Vector2 anchoredPosition = rectTransform.anchoredPosition;
		Rect rect = rectTransform.rect;
		return anchoredPosition - new Vector2(((Rect)(ref rect)).width, 0f);
	}

	private static Vector2 FromSavedTopLeft(RectTransform rectTransform, Vector2 savedTopLeft)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		Rect rect = rectTransform.rect;
		return savedTopLeft + new Vector2(((Rect)(ref rect)).width, 0f);
	}

	private static void ClampRectToScreen(RectTransform rectTransform)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)rectTransform == (Object)null))
		{
			Vector3[] array = (Vector3[])(object)new Vector3[4];
			rectTransform.GetWorldCorners(array);
			Vector3 zero = Vector3.zero;
			if (array[0].x < 0f)
			{
				zero.x += 0f - array[0].x;
			}
			if (array[2].x > (float)Screen.width)
			{
				zero.x -= array[2].x - (float)Screen.width;
			}
			if (array[0].y < 0f)
			{
				zero.y += 0f - array[0].y;
			}
			if (array[2].y > (float)Screen.height)
			{
				zero.y -= array[2].y - (float)Screen.height;
			}
			if (zero != Vector3.zero)
			{
				((Transform)rectTransform).position = ((Transform)rectTransform).position + zero;
			}
		}
	}

	private static void TryAttachHudToMinimap()
	{
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)hudPanel == (Object)null)
		{
			return;
		}
		RectTransform component = hudPanel.GetComponent<RectTransform>();
		if ((Object)(object)component == (Object)null)
		{
			return;
		}
		Minimap instance = Minimap.instance;
		if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_smallRoot == (Object)null)
		{
			Transform val = ResolveMainUiRoot();
			if ((Object)(object)val != (Object)null)
			{
				((Transform)component).SetParent(val, false);
				hudAttachedToMinimap = false;
				Debug.Log((object)"[MMOHeim SimpleQuest] Minimap root missing. Tracker parented to fallback UI root.");
			}
			else
			{
				Debug.LogWarning((object)"[MMOHeim SimpleQuest] Could not attach tracker: both minimap and fallback UI root are unavailable.");
			}
			hudAttachedToMinimap = false;
		}
		else
		{
			((Transform)component).SetParent(instance.m_smallRoot.transform, false);
			component.anchorMin = new Vector2(1f, 1f);
			component.anchorMax = new Vector2(1f, 1f);
			component.pivot = new Vector2(1f, 1f);
			component.sizeDelta = new Vector2(360f, 120f);
			LayoutRebuilder.ForceRebuildLayoutImmediate(component);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(-380f, -20f);
			Vector2 savedTopLeft = (((Object)(object)SimpleQuestPro.Instance != (Object)null) ? SimpleQuestPro.Instance.GetSavedTrackerPosition(val2) : val2);
			component.anchoredPosition = FromSavedTopLeft(component, savedTopLeft);
			ClampRectToScreen(component);
			hudAttachedToMinimap = true;
			Debug.Log((object)"[MMOHeim SimpleQuest] Tracker parented to Minimap.smallRoot.");
		}
	}

	public static void CreateUI()
	{
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: 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_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: 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_01a2: 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_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0208: Unknown result type (might be due to invalid IL or missing references)
		//IL_0219: Unknown result type (might be due to invalid IL or missing references)
		//IL_021f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0261: Unknown result type (might be due to invalid IL or missing references)
		//IL_0266: Unknown result type (might be due to invalid IL or missing references)
		//IL_027c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0287: Unknown result type (might be due to invalid IL or missing references)
		//IL_0298: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f3: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_037b: Unknown result type (might be due to invalid IL or missing references)
		//IL_038a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0399: Unknown result type (might be due to invalid IL or missing references)
		//IL_034d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0352: Unknown result type (might be due to invalid IL or missing references)
		//IL_0358: Expected O, but got Unknown
		//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0408: Unknown result type (might be due to invalid IL or missing references)
		//IL_0417: Unknown result type (might be due to invalid IL or missing references)
		//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d6: Expected O, but got Unknown
		//IL_0481: Unknown result type (might be due to invalid IL or missing references)
		//IL_0490: Unknown result type (might be due to invalid IL or missing references)
		//IL_049f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0449: Unknown result type (might be due to invalid IL or missing references)
		//IL_044e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0454: Expected O, but got Unknown
		//IL_0518: Unknown result type (might be due to invalid IL or missing references)
		//IL_0527: Unknown result type (might be due to invalid IL or missing references)
		//IL_0536: Unknown result type (might be due to invalid IL or missing references)
		//IL_0578: Unknown result type (might be due to invalid IL or missing references)
		//IL_0582: Expected O, but got Unknown
		//IL_05db: Unknown result type (might be due to invalid IL or missing references)
		//IL_05e5: Expected O, but got Unknown
		//IL_0602: Unknown result type (might be due to invalid IL or missing references)
		//IL_0617: Unknown result type (might be due to invalid IL or missing references)
		//IL_062c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0641: Unknown result type (might be due to invalid IL or missing references)
		//IL_0655: Unknown result type (might be due to invalid IL or missing references)
		//IL_0673: Unknown result type (might be due to invalid IL or missing references)
		//IL_06bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_06c6: Expected O, but got Unknown
		//IL_06fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_070a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0719: Unknown result type (might be due to invalid IL or missing references)
		//IL_072a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0730: Unknown result type (might be due to invalid IL or missing references)
		//IL_0755: Unknown result type (might be due to invalid IL or missing references)
		//IL_0787: Unknown result type (might be due to invalid IL or missing references)
		//IL_079c: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f5: Expected O, but got Unknown
		//IL_07bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_07c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_07dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_07f2: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)window != (Object)null && (Object)(object)hudPanel != (Object)null)
		{
			return;
		}
		CleanupUI();
		if (GUIManager.Instance == null)
		{
			Debug.LogWarning((object)"[MMOHeim SimpleQuest] CreateUI aborted: GUIManager.Instance is null.");
			return;
		}
		Transform val = ResolveMainUiRoot();
		if ((Object)(object)val == (Object)null)
		{
			Debug.LogWarning((object)"[MMOHeim SimpleQuest] CreateUI aborted: no valid UI root (CustomGUIFront/Hud) is available.");
			return;
		}
		try
		{
			window = GUIManager.Instance.CreateWoodpanel(val, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 600f, 550f, true);
			Image component = window.GetComponent<Image>();
			if ((Object)(object)component != (Object)null)
			{
				((Graphic)component).color = new Color(0.6f, 0.6f, 0.6f, 1f);
			}
			titleText = GUIManager.Instance.CreateText("", window.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -20f), GUIManager.Instance.AveriaSerifBold, 18, new Color(1f, 0.84f, 0f, 1f), false, Color.clear, 400f, 30f, false).GetComponent<Text>();
			titleText.alignment = (TextAnchor)4;
			pageText = GUIManager.Instance.CreateText("", window.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -40f), GUIManager.Instance.AveriaSerifBold, 14, Color.white, false, Color.clear, 200f, 30f, false).GetComponent<Text>();
			pageText.alignment = (TextAnchor)4;
			infoText = GUIManager.Instance.CreateText("", window.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 60f), GUIManager.Instance.AveriaSerifBold, 17, Color.white, false, Color.clear, 500f, 350f, false).GetComponent<Text>();
			infoText.alignment = (TextAnchor)4;
			GameObject val2 = new GameObject("RewardIcon", new Type[1] { typeof(Image) });
			val2.transform.SetParent(window.transform, false);
			rewardIcon = val2.GetComponent<Image>();
			RectTransform component2 = val2.GetComponent<RectTransform>();
			component2.anchoredPosition = new Vector2(0f, -145f);
			component2.sizeDelta = new Vector2(64f, 64f);
			val2.SetActive(false);
			btnTrack = GUIManager.Instance.CreateButton(L("sq_track", "TRACK"), window.transform, new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(-100f, 45f), 130f, 30f);
			trackBtnText = btnTrack.GetComponentInChildren<Text>();
			ButtonClickedEvent onClick = btnTrack.GetComponent<Button>().onClick;
			object obj = <>c.<>9__10_0;
			if (obj == null)
			{
				UnityAction val3 = delegate
				{
					List<QuestConfig> visibleQuests = QuestUtils.GetVisibleQuests();
					if (visibleQuests.Count > 0)
					{
						QuestConfig questConfig = visibleQuests[currentIndex];
						if (SimpleQuestPro.trackedQuests.Contains(questConfig.ID))
						{
							SimpleQuestPro.trackedQuests.Remove(questConfig.ID);
						}
						else
						{
							SimpleQuestPro.trackedQuests.Add(questConfig.ID);
						}
						UpdateUI();
						UpdateHUD();
						QuestUtils.PlaySfx("sfx_gui_mouse_over");
					}
				};
				<>c.<>9__10_0 = val3;
				obj = (object)val3;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
			ButtonClickedEvent onClick2 = GUIManager.Instance.CreateButton("<", window.transform, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(60f, 0f), 45f, 45f).GetComponent<Button>().onClick;
			object obj2 = <>c.<>9__10_1;
			if (obj2 == null)
			{
				UnityAction val4 = delegate
				{
					int count2 = QuestUtils.GetVisibleQuests().Count;
					if (count2 > 0)
					{
						currentIndex = (currentIndex - 1 + count2) % count2;
						currentIconIndex = 0;
						UpdateUI();
						QuestUtils.PlaySfx("sfx_book_page");
					}
				};
				<>c.<>9__10_1 = val4;
				obj2 = (object)val4;
			}
			((UnityEvent)onClick2).AddListener((UnityAction)obj2);
			ButtonClickedEvent onClick3 = GUIManager.Instance.CreateButton(">", window.transform, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-60f, 0f), 45f, 45f).GetComponent<Button>().onClick;
			object obj3 = <>c.<>9__10_2;
			if (obj3 == null)
			{
				UnityAction val5 = delegate
				{
					int count = QuestUtils.GetVisibleQuests().Count;
					if (count > 0)
					{
						currentIndex = (currentIndex + 1) % count;
						currentIconIndex = 0;
						UpdateUI();
						QuestUtils.PlaySfx("sfx_book_page");
					}
				};
				<>c.<>9__10_2 = val5;
				obj3 = (object)val5;
			}
			((UnityEvent)onClick3).AddListener((UnityAction)obj3);
			btnHistory = GUIManager.Instance.CreateButton(L("sq_history", "HISTORY"), window.transform, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-90f, -40f), 130f, 30f);
			historyBtnText = btnHistory.GetComponentInChildren<Text>();
			ButtonClickedEvent onClick4 = btnHistory.GetComponent<Button>().onClick;
			object obj4 = <>c.<>9__10_3;
			if (obj4 == null)
			{
				UnityAction val6 = delegate
				{
					showHistoryMode = !showHistoryMode;
					currentIndex = 0;
					UpdateUI();
					QuestUtils.PlaySfx("sfx_book_page");
				};
				<>c.<>9__10_3 = val6;
				obj4 = (object)val6;
			}
			((UnityEvent)onClick4).AddListener((UnityAction)obj4);
			btnFinish = GUIManager.Instance.CreateButton("", window.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 45f), 200f, 40f);
			btnText = btnFinish.GetComponentInChildren<Text>();
			((UnityEvent)btnFinish.GetComponent<Button>().onClick).AddListener(new UnityAction(SimpleQuestPro.Instance.CompleteQuest));
			hudPanel = new GameObject("TrackerContainer", new Type[6]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(CanvasGroup),
				typeof(VerticalLayoutGroup),
				typeof(ContentSizeFitter),
				typeof(TrackerDragHandler)
			});
			RectTransform component3 = hudPanel.GetComponent<RectTransform>();
			((Transform)component3).SetParent(val, false);
			component3.anchorMin = new Vector2(1f, 1f);
			component3.anchorMax = new Vector2(1f, 1f);
			component3.pivot = new Vector2(1f, 1f);
			component3.anchoredPosition = new Vector2(-380f, -20f);
			component3.sizeDelta = new Vector2(360f, 280f);
			hudBackground = hudPanel.GetComponent<Image>();
			((Graphic)hudBackground).color = hudGhostColor;
			hudCanvasGroup = hudPanel.GetComponent<CanvasGroup>();
			SetTrackerInteractionEnabled(enabled: false);
			VerticalLayoutGroup component4 = hudPanel.GetComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)component4).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)component4).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)component4).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)component4).childForceExpandHeight = false;
			((LayoutGroup)component4).padding = new RectOffset(5, 5, 5, 5);
			ContentSizeFitter component5 = hudPanel.GetComponent<ContentSizeFitter>();
			component5.horizontalFit = (FitMode)2;
			component5.verticalFit = (FitMode)2;
			GameObject obj5 = GUIManager.Instance.CreateText("", hudPanel.transform, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0f, 0f), GUIManager.Instance.AveriaSerifBold, 16, Color.white, false, Color.clear, 360f, 280f, false);
			hudText = obj5.GetComponent<Text>();
			((Graphic)hudText).color = Color.white;
			hudText.horizontalOverflow = (HorizontalWrapMode)0;
			hudText.verticalOverflow = (VerticalWrapMode)1;
			hudText.alignment = (TextAnchor)0;
			Outline obj6 = obj5.AddComponent<Outline>();
			((Shadow)obj6).effectColor = Color.black;
			((Shadow)obj6).effectDistance = new Vector2(0.8f, -0.8f);
			((Shadow)obj6).useGraphicAlpha = true;
			RectTransform component6 = obj5.GetComponent<RectTransform>();
			if ((Object)(object)component6 != (Object)null)
			{
				component6.anchorMin = Vector2.zero;
				component6.anchorMax = Vector2.one;
				component6.offsetMin = new Vector2(5f, 5f);
				component6.offsetMax = new Vector2(-5f, -5f);
			}
			obj5.transform.SetAsLastSibling();
			TryAttachHudToMinimap();
			hudPanel.SetActive(false);
			window.SetActive(false);
			Debug.Log((object)("[MMOHeim SimpleQuest] CreateUI completed successfully. Main UI root: " + ((Object)val).name));
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("[MMOHeim SimpleQuest] CreateUI failed: " + ex));
			CleanupUI();
		}
	}

	public static void UpdateUI()
	{
		List<QuestConfig> visibleQuests = QuestUtils.GetVisibleQuests();
		titleText.text = (showHistoryMode ? ("<color=#FFD700><b>" + L("sq_history", "HERO HISTORY") + "</b></color>") : ("<color=#FFD700><b>" + Localization.instance.Localize("$sq_journal") + "</b></color>"));
		historyBtnText.text = (showHistoryMode ? L("sq_back", "BACK") : L("sq_history", "HISTORY"));
		if (visibleQuests.Count == 0)
		{
			infoText.text = (showHistoryMode ? ("\n\n" + L("sq_no_history", "No hero history yet.")) : ("\n\n" + L("sq_no_quests", "Quest list is empty")));
			pageText.text = "0 / 0";
			btnFinish.SetActive(false);
			btnTrack.SetActive(false);
			Image val = rewardIcon;
			if ((Object)(object)val != (Object)null)
			{
				((Component)val).gameObject.SetActive(false);
			}
			return;
		}
		btnFinish.SetActive(!showHistoryMode);
		btnTrack.SetActive(!showHistoryMode);
		if (currentIndex >= visibleQuests.Count)
		{
			currentIndex = 0;
		}
		QuestConfig questConfig = visibleQuests[currentIndex];
		trackBtnText.text = (SimpleQuestPro.trackedQuests.Contains(questConfig.ID) ? ("<color=#FF4500>" + L("sq_untrack", "UNTRACK") + "</color>") : L("sq_track", "TRACK"));
		bool flag = SimpleQuestPro.Instance.completedQuests.Contains(questConfig.ID);
		bool flag2 = true;
		string rarityColor = QuestUtils.GetRarityColor(questConfig.Rarity);
		string text = (showHistoryMode ? "\n<color=#00FF00><b>[ COMPLETED ]</b></color>\n" : "");
		string text2 = "\n<color=" + rarityColor + ">━━━━━━━━━━━━━━━━━━</color>\n";
		if (questConfig.Reqs != null)
		{
			foreach (QuestRequirement req in questConfig.Reqs)
			{
				int num = (flag ? req.Amount : QuestUtils.GetItemCount(req.Prefab));
				text2 += string.Format("• {0}: <color={1}><b>{2}</b> / {3}</color>\n", QuestUtils.GetItemName(req.Prefab), (num >= req.Amount) ? "#00FF00" : "#FF4500", num, req.Amount);
				if (!flag && num < req.Amount)
				{
					flag2 = false;
				}
			}
		}
		if (questConfig.KillReqs != null)
		{
			foreach (QuestRequirement i in questConfig.KillReqs)
			{
				int num2 = (flag ? i.Amount : SimpleQuestPro.playerKills.Where(delegate(KeyValuePair<string, int> x)
				{
					KeyValuePair<string, int> keyValuePair = x;
					return keyValuePair.Key.Equals(i.Prefab.Trim(), StringComparison.OrdinalIgnoreCase);
				}).Sum((KeyValuePair<string, int> x) => x.Value));
				int num3 = num2;
				text2 += string.Format("• {0}: <color={1}><b>{2}</b> / {3}</color>\n", Localization.instance.Localize("$" + i.Prefab.Trim()), (num3 >= i.Amount) ? "#00FF00" : "#FF4500", num3, i.Amount);
				if (!flag && num3 < i.Amount)
				{
					flag2 = false;
				}
			}
		}
		bool flag3 = QuestUtils.HasEnoughVanillaInventoryForRewards(questConfig, ((Humanoid)Player.m_localPlayer).GetInventory(), includeSlotsFreedByRequirements: true);
		if (flag)
		{
			btnText.text = L("sq_done", "DONE");
			((Selectable)btnFinish.GetComponent<Button>()).interactable = false;
		}
		else
		{
			btnText.text = ((!flag2) ? L("sq_not_enough", "NOT ENOUGH") : ((!flag3) ? L("sq_no_space", "NO SPACE") : ("<b>" + L("sq_finish", "COMPLETE") + "</b>")));
			((Selectable)btnFinish.GetComponent<Button>()).interactable = flag2 && flag3;
		}
		pageText.text = $"{currentIndex + 1} / {visibleQuests.Count}";
		SetRewardIcon((questConfig.RewardItems != null && questConfig.RewardItems.Count > 0) ? questConfig.RewardItems[currentIconIndex % questConfig.RewardItems.Count].Prefab : questConfig.RewardItem);
		string text3 = ((questConfig.RewardItems != null && questConfig.RewardItems.Count > 0) ? string.Join(", ", questConfig.RewardItems.Select((QuestRequirement x) => $"{QuestUtils.GetItemName(x.Prefab)} x{x.Amount}")) : $"{QuestUtils.GetItemName(questConfig.RewardItem)} x{questConfig.RewardAmount}");
		string text4 = text3;
		if (questConfig.ExpReward > 0)
		{
			text4 += $" | <color=#00BFFF>+{questConfig.ExpReward} XP</color>";
		}
		infoText.text = string.Concat("<size=26><color=", rarityColor, "><b>", questConfig.Title, "</b></color></size>\n", text, "<i>", questConfig.Goal, "</i>\n", text2, "\n<color=#FFD700><b>" + L("sq_reward", "REWARD") + ":</b></color> ", text4);
		UpdateHUD();
	}

	public static void UpdateHUD()
	{
		if (!hudAttachedToMinimap)
		{
			TryAttachHudToMinimap();
		}
		if ((Object)(object)hudPanel == (Object)null)
		{
			return;
		}
		if (SimpleQuestPro.trackedQuests == null || SimpleQuestPro.trackedQuests.Count == 0 || (Object)(object)Player.m_localPlayer == (Object)null)
		{
			hudPanel.SetActive(false);
			return;
		}
		string text = "";
		foreach (string id in SimpleQuestPro.trackedQuests.ToList())
		{
			QuestConfig questConfig = SimpleQuestPro.Instance.serverQuests.Quests.FirstOrDefault((QuestConfig x) => x.ID.Equals(id, StringComparison.OrdinalIgnoreCase));
			if (questConfig == null)
			{
				continue;
			}
			if (SimpleQuestPro.Instance.completedQuests.Contains(questConfig.ID))
			{
				SimpleQuestPro.trackedQuests.Remove(id);
				continue;
			}
			text = text + "<b><color=" + QuestUtils.GetRarityColor(questConfig.Rarity) + ">" + questConfig.Title + "</color></b>\n";
			if (questConfig.Reqs != null)
			{
				foreach (QuestRequirement req in questConfig.Reqs)
				{
					int itemCount = QuestUtils.GetItemCount(req.Prefab);
					string text2 = ((itemCount >= req.Amount) ? "#00FF00" : "white");
					text += $"<b> • {QuestUtils.GetItemName(req.Prefab)}: <color={text2}>{itemCount}/{req.Amount}</color></b>\n";
				}
			}
			if (questConfig.KillReqs != null)
			{
				foreach (QuestRequirement i in questConfig.KillReqs)
				{
					int num = SimpleQuestPro.playerKills.Where(delegate(KeyValuePair<string, int> x)
					{
						KeyValuePair<string, int> keyValuePair = x;
						return keyValuePair.Key.Equals(i.Prefab.Trim(), StringComparison.OrdinalIgnoreCase);
					}).Sum((KeyValuePair<string, int> x) => x.Value);
					string text3 = ((num >= i.Amount) ? "#00FF00" : "white");
					text += string.Format("<b> • {0}: <color={1}>{2}/{3}</color></b>\n", Localization.instance.Localize("$" + i.Prefab.Trim()), text3, num, i.Amount);
				}
			}
			text += "\n";
		}
		if (!string.IsNullOrEmpty(text))
		{
			hudText.text = text;
			hudPanel.SetActive(true);
		}
		else
		{
			hudPanel.SetActive(false);
		}
	}

	public static void SetRewardIcon(string prefabName)
	{
		if (!((Object)(object)rewardIcon == (Object)null) && !string.IsNullOrEmpty(prefabName))
		{
			ZNetScene instance = ZNetScene.instance;
			ItemDrop val;
			if ((Object)(object)instance == (Object)null)
			{
				val = null;
			}
			else
			{
				GameObject prefab = instance.GetPrefab(prefabName);
				val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<ItemDrop>() : null);
			}
			ItemDrop val2 = val;
			if ((Object)(object)val2 != (Object)null)
			{
				rewardIcon.sprite = val2.m_itemData.GetIcon();
				((Component)rewardIcon).gameObject.SetActive(true);
			}
			else
			{
				((Component)rewardIcon).gameObject.SetActive(false);
			}
		}
	}
}
public static class QuestUtils
{
	public const int VanillaPlayerInventoryWidth = 8;

	public const int VanillaPlayerInventoryHeight = 4;

	public static List<QuestConfig> GetVisibleQuests()
	{
		if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)SimpleQuestPro.Instance == (Object)null)
		{
			return new List<QuestConfig>();
		}
		if (QuestUI.showHistoryMode)
		{
			return SimpleQuestPro.Instance.serverQuests.Quests.Where((QuestConfig q) => SimpleQuestPro.Instance.completedQuests.Contains(q.ID)).ToList();
		}
		return SimpleQuestPro.Instance.serverQuests.Quests.Where((QuestConfig q) => (string.IsNullOrEmpty(q.PreReqID) || SimpleQuestPro.Instance.completedQuests.Contains(q.PreReqID)) && !SimpleQuestPro.Instance.completedQuests.Contains(q.ID)).ToList();
	}

	public static string GetRarityColor(string rarity)
	{
		if (string.IsNullOrEmpty(rarity))
		{
			return "#4d2600";
		}
		return rarity.ToLower() switch
		{
			"mythic" => "#FF4500", 
			"legendary" => "#FFD700", 
			"epic" => "#9400D3", 
			"rare" => "#1E90FF", 
			"common" => "#696969", 
			_ => "#4d2600", 
		};
	}

	public static int GetItemCount(string prefab)
	{
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			return 0;
		}
		return (from x in ((Humanoid)localPlayer).GetInventory().GetAllItems()
			where (Object)(object)x.m_dropPrefab != (Object)null && string.Equals(((Object)x.m_dropPrefab).name, prefab, StringComparison.OrdinalIgnoreCase)
			select x).Sum((ItemData x) => x.m_stack);
	}

	public static string GetItemName(string prefab)
	{
		if (string.IsNullOrEmpty(prefab))
		{
			return "";
		}
		string[] array = new string[3]
		{
			"$item_" + prefab.ToLower(),
			"$" + prefab,
			"$" + prefab.ToLower()
		};
		foreach (string text in array)
		{
			string text2 = Localization.instance.Localize(text);
			if (!text2.StartsWith("$"))
			{
				return text2;
			}
		}
		return prefab;
	}

	public static void PlaySfx(string sfxName)
	{
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)ZNetScene.instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null))
		{
			GameObject prefab = ZNetScene.instance.GetPrefab(sfxName);
			if ((Object)(object)prefab == (Object)null)
			{
				prefab = ZNetScene.instance.GetPrefab("sfx_gui_click");
			}
			if ((Object)(object)prefab != (Object)null)
			{
				Object.Instantiate<GameObject>(prefab, ((Component)Utils.GetMainCamera()).transform.position, Quaternion.identity);
			}
		}
	}

	public static int CountVanillaEmptyInventorySlots(Inventory inventory)
	{
		if (inventory == null)
		{
			return 0;
		}
		int num = 0;
		for (int i = 0; i < 4; i++)
		{
			for (int j = 0; j < 8; j++)
			{
				if (inventory.GetItemAt(j, i) == null)
				{
					num++;
				}
			}
		}
		return num;
	}

	public static int CountSlotsFreedByTurningInRequirements(QuestConfig quest, Inventory inventory)
	{
		if (quest == null || inventory == null || quest.Reqs == null)
		{
			return 0;
		}
		int num = 0;
		foreach (QuestRequirement questRequirement in quest.Reqs)
		{
			int num2 = questRequirement.Amount;
			List<ItemData> list = (from x in inventory.GetAllItems()
				where (Object)(object)x.m_dropPrefab != (Object)null && string.Equals(((Object)x.m_dropPrefab).name, questRequirement.Prefab, StringComparison.OrdinalIgnoreCase)
				select x).ToList();
			int num3 = list.Count - 1;
			while (num3 >= 0 && num2 > 0)
			{
				int num4 = Math.Min(list[num3].m_stack, num2);
				num2 -= num4;
				if (num4 >= list[num3].m_stack)
				{
					num++;
				}
				num3--;
			}
		}
		return num;
	}

	public static int CountItemRewardLines(QuestConfig quest)
	{
		if (quest == null)
		{
			return 0;
		}
		if (quest.RewardItems != null && quest.RewardItems.Count > 0)
		{
			return quest.RewardItems.Count((QuestRequirement reward) => !string.IsNullOrEmpty(reward.Prefab) && reward.Amount > 0);
		}
		return (!string.IsNullOrEmpty(quest.RewardItem) && quest.RewardAmount > 0) ? 1 : 0;
	}

	public static bool HasEnoughVanillaInventoryForRewards(QuestConfig quest, Inventory inventory, bool includeSlotsFreedByRequirements)
	{
		int num = CountItemRewardLines(quest);
		if (num <= 0)
		{
			return true;
		}
		int num2 = CountVanillaEmptyInventorySlots(inventory);
		if (includeSlotsFreedByRequirements)
		{
			num2 += CountSlotsFreedByTurningInRequirements(quest, inventory);
		}
		return num2 >= num;
	}

	public static void ShowInsufficientInventoryWarning()
	{
		Player localPlayer = Player.m_localPlayer;
		if (!((Object)(object)localPlayer == (Object)null))
		{
			string text = Localization.instance.Localize("$sq_inventory_warning");
			if (string.IsNullOrEmpty(text) || text == "$sq_inventory_warning")
			{
				text = "<color=yellow>Clear space in your inventory before claiming this quest reward.</color>";
			}
			((Character)localPlayer).Message((MessageType)1, text, 0, (Sprite)null);
		}
	}

	public static bool TryGrantQuestRewards(QuestConfig quest, Inventory inventory)
	{
		if (quest == null || inventory == null)
		{
			return true;
		}
		if (CountItemRewardLines(quest) > 0 && !HasEnoughVanillaInventoryForRewards(quest, inventory, includeSlotsFreedByRequirements: false))
		{
			return false;
		}
		if (quest.RewardItems != null && quest.RewardItems.Count > 0)
		{
			foreach (QuestRequirement rewardItem in quest.RewardItems)
			{
				if (!string.IsNullOrEmpty(rewardItem.Prefab) && rewardItem.Amount > 0 && inventory.AddItem(rewardItem.Prefab, rewardItem.Amount, 1, 0, 0L, "", false) == null)
				{
					return false;
				}
			}
		}
		else if (!string.IsNullOrEmpty(quest.RewardItem) && quest.RewardAmount > 0 && inventory.AddItem(quest.RewardItem, quest.RewardAmount, 1, 0, 0L, "", false) == null)
		{
			return false;
		}
		return true;
	}

	public static void AddExp(int amount)
	{
		if ((Object)(object)Player.m_localPlayer == (Object)null)
		{
			return;
		}
		try
		{
			if (!Chainloader.PluginInfos.ContainsKey("WackyMole.EpicMMOSystem"))
			{
				return;
			}
			Type type = ((object)Chainloader.PluginInfos["WackyMole.EpicMMOSystem"].Instance).GetType().Assembly.GetType("EpicMMOSystem.LevelSystem");
			if (type == null)
			{
				return;
			}
			PropertyInfo property = type.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public);
			object obj = ((property != null) ? property.GetValue(null) : null);
			if (obj == null)
			{
				return;
			}
			MethodInfo method = type.GetMethod("AddExp", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (method != null)
			{
				ParameterInfo[] parameters = method.GetParameters();
				if (parameters.Length == 2)
				{
					object obj2 = ((parameters[0].ParameterType == typeof(Player)) ? Player.m_localPlayer : Convert.ChangeType(amount, parameters[0].ParameterType));
					object obj3 = ((parameters[1].ParameterType == typeof(Player)) ? Player.m_localPlayer : Convert.ChangeType(amount, parameters[1].ParameterType));
					method.Invoke(obj, new object[2] { obj2, obj3 });
				}
				else if (parameters.Length == 1)
				{
					object obj4 = Convert.ChangeType(amount, parameters[0].ParameterType);
					method.Invoke(obj, new object[1] { obj4 });
				}
			}
		}
		catch
		{
		}
	}
}
[BepInPlugin("com.mmoheim.simplequest", "MMOHeim SimpleQuest", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class SimpleQuestPro : BaseUnityPlugin
{
	[CompilerGenerated]
	private sealed class <OnClientQuestRequest>d__16 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public SimpleQuestPro <>4__this;

		public long sender;

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

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

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

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

		private bool MoveNext()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			int num = <>1__state;
			SimpleQuestPro simpleQuestPro = <>4__this;
			if (num != 0)
			{
				return false;
			}
			<>1__state = -1;
			if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && simpleQuestPro.questSyncRPC != null)
			{
				ZPackage val = new ZPackage();
				val.Write(RawServerJson ?? string.Empty);
				simpleQuestPro.questSyncRPC.SendPackage(sender, val);
			}
			return false;
		}

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

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

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

		private object <>2__current;

		public ZPackage package;

		public SimpleQuestPro <>4__this;

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

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

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

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

		private bool MoveNext()
		{
			int num = <>1__state;
			SimpleQuestPro simpleQuestPro = <>4__this;
			if (num != 0)
			{
				return false;
			}
			<>1__state = -1;
			if (package != null)
			{
				try
				{
					string text = package.ReadString();
					if (!string.IsNullOrEmpty(text))
					{
						RawServerJson = text;
						simpleQuestPro.serverQuests = JsonConvert.DeserializeObject<QuestList>(text) ?? new QuestList();
						if ((Object)(object)QuestUI.window != (Object)null)
						{
							QuestUI.UpdateUI();
						}
						QuestUI.UpdateHUD();
					}
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)simpleQuestPro).Logger.LogError((object)("Failed to apply synced quest data: " + ex.Message));
				}
			}
			return false;
		}

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

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

	private const string LogPrefix = "[MMOHeim SimpleQuest] ";

	public const string ModGUID = "com.mmoheim.simplequest";

	public const string ModName = "MMOHeim SimpleQuest";

	public const string ModVersion = "1.0.0";

	public const string ConfigFolderName = "MMOHeim SimpleQuest";

	public static SimpleQuestPro Instance;

	private ConfigEntry<KeyCode> questKey;

	public static ConfigEntry<float> TrackerPositionX;

	public static ConfigEntry<float> TrackerPositionY;

	public QuestList serverQuests = new QuestList();

	public HashSet<string> completedQuests = new HashSet<string>();

	public static Dictionary<string, int> playerKills = new Dictionary<string, int>();

	public static HashSet<string> trackedQuests = new HashSet<string>();

	private CustomRPC questSyncRPC;

	private static string RawServerJson = string.Empty;

	private bool isFirstSpawn = true;

	public bool IsWindowActive()
	{
		if ((Object)(object)QuestUI.window != (Object)null)
		{
			return QuestUI.window.activeSelf;
		}
		return false;
	}

	private void Awake()
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Expected O, but got Unknown
		//IL_00b9: Expected O, but got Unknown
		Instance = this;
		new Harmony("com.mmoheim.simplequest").PatchAll();
		LoadLocalization();
		questKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "QuestKey", (KeyCode)108, "Quest journal key.");
		TrackerPositionX = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "TrackerPositionX", -18f, "Saved HUD tracker X anchored position.");
		TrackerPositionY = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "TrackerPositionY", -10f, "Saved HUD tracker Y anchored position.");
		EnsureQuestsFile();
		LoadQuestsLocal();
		questSyncRPC = NetworkManager.Instance.AddRPC("QuestSync", new CoroutineHandler(OnClientQuestRequest), new CoroutineHandler(OnServerQuestReceived));
		((BaseUnityPlugin)this).Logger.LogInfo((object)"MMOHeim SimpleQuest version 1.0.0");
	}

	private void Update()
	{
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Expected O, but got Unknown
		//IL_0171: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Player.m_localPlayer == (Object)null)
		{
			isFirstSpawn = true;
			return;
		}
		if (isFirstSpawn)
		{
			isFirstSpawn = false;
			LoadProgress();
			LoadQuestsLocal();
			if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer())
			{
				questSyncRPC.SendPackage(ZNet.instance.GetServerPeer().m_uid, new ZPackage());
			}
		}
		if (IsWindowActive())
		{
			if (Input.GetKeyDown((KeyCode)9) || Input.GetKeyDown((KeyCode)27))
			{
				ToggleUI();
				return;
			}
			UpdateIconSlideshow();
			float axis = Input.GetAxis("Mouse ScrollWheel");
			if (axis != 0f)
			{
				int count = QuestUtils.GetVisibleQuests().Count;
				if (count > 0)
				{
					if (axis > 0f)
					{
						QuestUI.currentIndex = (QuestUI.currentIndex - 1 + count) % count;
					}
					else
					{
						QuestUI.currentIndex = (QuestUI.currentIndex + 1) % count;
					}
					QuestUI.currentIconIndex = 0;
					QuestUI.UpdateUI();
					QuestUtils.PlaySfx("sfx_book_page");
				}
			}
		}
		if ((Object)(object)QuestUI.hudPanel != (Object)null)
		{
			bool flag = !IsWindowActive() && !QuestUI.showHistoryMode && trackedQuests.Count > 0;
			QuestUI.hudPanel.SetActive(flag);
			if (flag)
			{
				QuestUI.SetTrackerInteractionEnabled((Object)(object)Menu.instance != (Object)null && Menu.IsVisible());
			}
		}
		if (!Chat.instance.HasFocus() && !InventoryGui.IsVisible() && Input.GetKeyDown(questKey.Value))
		{
			ToggleUI();
		}
	}

	private void UpdateIconSlideshow()
	{
		List<QuestConfig> visibleQuests = QuestUtils.GetVisibleQuests();
		if (visibleQuests.Count == 0)
		{
			return;
		}
		QuestConfig questConfig = visibleQuests[Math.Min(QuestUI.currentIndex, visibleQuests.Count - 1)];
		if (questConfig.RewardItems != null && questConfig.RewardItems.Count > 1)
		{
			QuestUI.iconTimer += Time.deltaTime;
			if (QuestUI.iconTimer >= 2f)
			{
				QuestUI.iconTimer = 0f;
				QuestUI.currentIconIndex = (QuestUI.currentIconIndex + 1) % questConfig.RewardItems.Count;
				QuestUI.SetRewardIcon(questConfig.RewardItems[QuestUI.currentIconIndex].Prefab);
			}
		}
	}

	public void ToggleUI()
	{
		if ((Object)(object)QuestUI.window == (Object)null)
		{
			QuestUI.CreateUI();
			if ((Object)(object)QuestUI.window == (Object)null)
			{
				QuestUI.CleanupUI();
				((BaseUnityPlugin)this).Logger.LogWarning((object)"[MMOHeim SimpleQuest] ToggleUI aborted: QuestUI.CreateUI could not create the window yet.");
				return;
			}
		}
		bool flag = !QuestUI.window.activeSelf;
		if (flag)
		{
			QuestUI.showHistoryMode = false;
			QuestUI.currentIndex = 0;
			QuestUI.UpdateUI();
			QuestUtils.PlaySfx("sfx_gui_mouse_over");
		}
		else
		{
			SaveProgress();
			QuestUtils.PlaySfx("sfx_gui_mouse_over");
		}
		QuestUI.window.SetActive(flag);
		GUIManager.BlockInput(flag);
		Cursor.visible = flag;
		Cursor.lockState = (CursorLockMode)((!flag) ? 1 : 0);
	}

	public void CompleteQuest()
	{
		List<QuestConfig> visibleQuests = QuestUtils.GetVisibleQuests();
		if (visibleQuests.Count == 0)
		{
			return;
		}
		QuestConfig questConfig = visibleQuests[QuestUI.currentIndex];
		if (completedQuests.Contains(questConfig.ID))
		{
			return;
		}
		Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
		if (questConfig.Reqs != null)
		{
			foreach (QuestRequirement req in questConfig.Reqs)
			{
				if (QuestUtils.GetItemCount(req.Prefab) < req.Amount)
				{
					return;
				}
			}
		}
		if (questConfig.KillReqs != null)
		{
			foreach (QuestRequirement i in questConfig.KillReqs)
			{
				if (playerKills.Where(delegate(KeyValuePair<string, int> x)
				{
					KeyValuePair<string, int> keyValuePair = x;
					return keyValuePair.Key.Equals(i.Prefab.Trim(), StringComparison.OrdinalIgnoreCase);
				}).Sum((KeyValuePair<string, int> x) => x.Value) < i.Amount)
				{
					return;
				}
			}
		}
		if (!QuestUtils.HasEnoughVanillaInventoryForRewards(questConfig, inventory, includeSlotsFreedByRequirements: true))
		{
			QuestUtils.ShowInsufficientInventoryWarning();
			return;
		}
		if (questConfig.Reqs != null)
		{
			foreach (QuestRequirement req2 in questConfig.Reqs)
			{
				int num = req2.Amount;
				List<ItemData> list = inventory.GetAllItems().ToList();
				for (int num2 = list.Count - 1; num2 >= 0; num2--)
				{
					if ((Object)(object)list[num2].m_dropPrefab != (Object)null && string.Equals(((Object)list[num2].m_dropPrefab).name, req2.Prefab, StringComparison.OrdinalIgnoreCase))
					{
						int num3 = Math.Min(list[num2].m_stack, num);
						ItemData obj = list[num2];
						obj.m_stack -= num3;
						num -= num3;
						if (list[num2].m_stack <= 0)
						{
							inventory.RemoveItem(list[num2]);
						}
						if (num <= 0)
						{
							break;
						}
					}
				}
			}
		}
		if (!QuestUtils.HasEnoughVanillaInventoryForRewards(questConfig, inventory, includeSlotsFreedByRequirements: false))
		{
			QuestUtils.ShowInsufficientInventoryWarning();
			return;
		}
		if (!QuestUtils.TryGrantQuestRewards(questConfig, inventory))
		{
			QuestUtils.ShowInsufficientInventoryWarning();
			return;
		}
		if (questConfig.ExpReward > 0)
		{
			QuestUtils.AddExp(questConfig.ExpReward);
		}
		completedQuests.Add(questConfig.ID);
		SaveProgress();
		QuestUI.UpdateUI();
		QuestUtils.PlaySfx("sfx_coins_up");
		((Character)Player.m_localPlayer).Message((MessageType)2, Localization.instance.Localize("$sq_success"), 0, (Sprite)null);
	}

	private void LoadLocalization()
	{
		//IL_016f: Expected O, but got Unknown
		try
		{
			string text = Path.Combine(GetTranslationsDirectory(), "English.json");
			Debug.Log((object)("[MMOHeim SimpleQuest] Loading forced English localization from: " + text));
			if (!File.Exists(text))
			{
				Debug.LogError((object)("[MMOHeim SimpleQuest] English localization file not found: " + text));
				return;
			}
			Dictionary<string, string> dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(File.ReadAllText(text));
			if (dictionary == null)
			{
				Debug.LogError((object)("[MMOHeim SimpleQuest] English localization file is empty or invalid JSON object: " + text));
				return;
			}
			foreach (KeyValuePair<string, string> item in new Dictionary<string, string>
			{
				{ "sq_track", "TRACK" },
				{ "sq_untrack", "UNTRACK" },
				{ "sq_no_history", "No quest history yet." },
				{ "sq_inventory_warning", "<color=yellow>Clear space in your inventory before claiming this quest reward.</color>" }
			})
			{
				if (!dictionary.ContainsKey(item.Key))
				{
					dictionary[item.Key] = item.Value;
				}
			}
			foreach (KeyValuePair<string, string> item2 in dictionary)
			{
				LocalizationManager.Instance.AddToken(item2.Key, item2.Value, false);
			}
			Debug.Log((object)$"[MMOHeim SimpleQuest] Loaded {dictionary.Count} localization tokens from forced English file.");
		}
		catch (IOException ex)
		{
			Debug.LogError((object)("[MMOHeim SimpleQuest] I/O error while loading English localization: " + ex.Message));
		}
		catch (JsonException val)
		{
			JsonException val2 = val;
			Debug.LogError((object)("[MMOHeim SimpleQuest] JSON parse error while loading English localization: " + ((Exception)(object)val2).Message));
		}
		catch (Exception ex2)
		{
			Debug.LogError((object)("[MMOHeim SimpleQuest] Unexpected localization load error: " + ex2));
		}
	}

	private string GetPluginDirectory()
	{
		return Path.GetDirectoryName(typeof(SimpleQuestPro).Assembly.Location) ?? Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? Paths.PluginPath;
	}

	private string GetTranslationsDirectory()
	{
		return Path.Combine(GetPluginDirectory(), "translations");
	}

	private string GetConfigDataDirectory()
	{
		return Path.Combine(Paths.ConfigPath, "MMOHeim SimpleQuest");
	}

	private void EnsureConfigDataDirectory()
	{
		Directory.CreateDirectory(GetConfigDataDirectory());
	}

	private string GetQuestsFilePath()
	{
		return Path.Combine(GetConfigDataDirectory(), "quests.json");
	}

	private string GetBundledQuestsFilePath()
	{
		return Path.Combine(GetPluginDirectory(), "Quests", "quests.json");
	}

	private void EnsureQuestsFile()
	{
		EnsureConfigDataDirectory();
		string questsFilePath = GetQuestsFilePath();
		if (!File.Exists(questsFilePath))
		{
			string bundledQuestsFilePath = GetBundledQuestsFilePath();
			if (File.Exists(bundledQuestsFilePath))
			{
				File.Copy(bundledQuestsFilePath, questsFilePath);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[MMOHeim SimpleQuest] Created quests.json in config from bundled default.");
			}
			else
			{
				File.WriteAllText(questsFilePath, "{\"Quests\":[]}");
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[MMOHeim SimpleQuest] Created empty quests.json in config.");
			}
		}
	}

	private void LoadQuestsLocal()
	{
		EnsureQuestsFile();
		string questsFilePath = GetQuestsFilePath();
		if (File.Exists(questsFilePath))
		{
			RawServerJson = File.ReadAllText(questsFilePath);
			serverQuests = JsonConvert.DeserializeObject<QuestList>(RawServerJson) ?? new QuestList();
		}
	}

	[IteratorStateMachine(typeof(<OnClientQuestRequest>d__16))]
	private IEnumerator OnClientQuestRequest(long sender, ZPackage package)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <OnClientQuestRequest>d__16(0)
		{
			<>4__this = this,
			sender = sender
		};
	}

	[IteratorStateMachine(typeof(<OnServerQuestReceived>d__17))]
	private IEnumerator OnServerQuestReceived(long sender, ZPackage package)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <OnServerQuestReceived>d__17(0)
		{
			<>4__this = this,
			package = package
		};
	}

	private string GetProgressFilePath(string playerName)
	{
		return Path.Combine(GetConfigDataDirectory(), "progress_" + playerName + ".sav");
	}

	private void MigrateLegacyProgressIfNeeded(string playerName)
	{
		string progressFilePath = GetProgressFilePath(playerName);
		if (!File.Exists(progressFilePath))
		{
			string text = Path.Combine(Paths.ConfigPath, "SimpleQuest", "progress_" + playerName + ".sav");
			if (File.Exists(text))
			{
				EnsureConfigDataDirectory();
				File.Copy(text, progressFilePath);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[MMOHeim SimpleQuest] Migrated progress save to config folder.");
			}
		}
	}

	private void LoadProgress()
	{
		string playerName = Player.m_localPlayer.GetPlayerName();
		MigrateLegacyProgressIfNeeded(playerName);
		string progressFilePath = GetProgressFilePath(playerName);
		if (File.Exists(progressFilePath))
		{
			string[] source = File.ReadAllLines(progressFilePath);
			completedQuests = new HashSet<string>(source.Where((string l) => !l.StartsWith("KILLS:")));
			string text = source.FirstOrDefault((string l) => l.StartsWith("KILLS:"));
			if (text != null)
			{
				playerKills = JsonConvert.DeserializeObject<Dictionary<string, int>>(text.Replace("KILLS:", "")) ?? new Dictionary<string, int>();
			}
		}
	}

	private void SaveProgress()
	{
		EnsureConfigDataDirectory();
		string progressFilePath = GetProgressFilePath(Player.m_localPlayer.GetPlayerName());
		List<string> list = completedQuests.ToList();
		list.Add("KILLS:" + JsonConvert.SerializeObject((object)playerKills));
		File.WriteAllLines(progressFilePath, list);
	}

	public Vector2 GetSavedTrackerPosition(Vector2 fallback)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		return new Vector2((TrackerPositionX != null) ? TrackerPositionX.Value : fallback.x, (TrackerPositionY != null) ? TrackerPositionY.Value : fallback.y);
	}

	public void SaveTrackerPosition(Vector2 anchoredPosition)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		if (TrackerPositionX != null)
		{
			TrackerPositionX.Value = anchoredPosition.x;
		}
		if (TrackerPositionY != null)
		{
			TrackerPositionY.Value = anchoredPosition.y;
		}
		((BaseUnityPlugin)this).Config.Save();
	}
}
[HarmonyPatch(typeof(Character), "ApplyDamage")]
public static class UniversalKillPatch
{
	private static void Postfix(Character __instance, HitData hit)
	{
		if ((Object)(object)__instance == (Object)null || __instance.IsPlayer() || !(__instance.GetHealth() <= 0f))
		{
			return;
		}
		string prefabName = Utils.GetPrefabName(((Component)__instance).gameObject).Trim();
		if (!SimpleQuestPro.playerKills.ContainsKey(prefabName))
		{
			SimpleQuestPro.playerKills[prefabName] = 0;
		}
		SimpleQuestPro.playerKills[prefabName]++;
		if ((Object)(object)SimpleQuestPro.Instance != (Object)null)
		{
			foreach (QuestConfig quest in SimpleQuestPro.Instance.serverQuests.Quests)
			{
				if (SimpleQuestPro.Instance.completedQuests.Contains(quest.ID))
				{
					continue;
				}
				QuestRequirement questRequirement = quest.KillReqs?.FirstOrDefault((QuestRequirement k) => k.Prefab.Trim().Equals(prefabName, StringComparison.OrdinalIgnoreCase));
				if (questRequirement != null)
				{
					int num = SimpleQuestPro.playerKills[prefabName];
					string arg = Localization.instance.Localize("$" + prefabName);
					Player localPlayer = Player.m_localPlayer;
					if ((Object)(object)localPlayer != (Object)null)
					{
						((Character)localPlayer).Message((MessageType)1, $"<b><color=#FFD700>{arg}: {num} / {questRequirement.Amount}</color></b>", 0, (Sprite)null);
					}
				}
			}
			if (SimpleQuestPro.Instance.IsWindowActive())
			{
				QuestUI.UpdateUI();
			}
		}
		QuestUI.UpdateHUD();
	}
}