Decompiled source of RtDQuestForge v0.3.2

plugins/RtDQuestForge.dll

Decompiled 20 hours 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.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using RtDQuestForge.UI;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("RtDQuestForge")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+dff8797f63ab654d317b40942f0390fdcdc58576")]
[assembly: AssemblyProduct("RtDQuestForge")]
[assembly: AssemblyTitle("RtDQuestForge")]
[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 RtDQuestForge
{
	public static class QuestConfigLoader
	{
		private const string DefaultFileName = "quests_default.json";

		public static QuestList LoadAll(string configDir, ManualLogSource logger)
		{
			Directory.CreateDirectory(configDir);
			EnsureDefaultFileExists(configDir, logger);
			string[] array = (from f in Directory.GetFiles(configDir, "*.json")
				where !Path.GetFileName(f).StartsWith("progress_", StringComparison.OrdinalIgnoreCase)
				select f).OrderBy<string, string>(Path.GetFileName, StringComparer.OrdinalIgnoreCase).ToArray();
			QuestList questList = new QuestList();
			HashSet<string> seenIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			string[] array2 = array;
			foreach (string file in array2)
			{
				MergeFile(file, questList, seenIds, logger);
			}
			logger.LogMessage((object)("Loaded " + questList.Quests.Count + " quest(s) from " + array.Length + " file(s)."));
			return questList;
		}

		private static void MergeFile(string file, QuestList combined, HashSet<string> seenIds, ManualLogSource logger)
		{
			//IL_003b: Expected O, but got Unknown
			string fileName = Path.GetFileName(file);
			string text;
			try
			{
				text = File.ReadAllText(file);
			}
			catch (IOException arg)
			{
				logger.LogWarning((object)$"Exception caught while reading {fileName}: {arg}");
				return;
			}
			QuestList questList;
			try
			{
				questList = JsonConvert.DeserializeObject<QuestList>(text);
			}
			catch (JsonException ex)
			{
				JsonException arg2 = ex;
				logger.LogWarning((object)$"Exception caught while parsing {fileName}, file was skipped: {arg2}");
				return;
			}
			if (questList == null || questList.Quests == null)
			{
				return;
			}
			foreach (QuestConfig quest in questList.Quests)
			{
				if (string.IsNullOrWhiteSpace(quest.ID))
				{
					logger.LogWarning((object)("Skipped a quest with no ID in " + fileName + " ('" + quest.Title + "')."));
				}
				else if (!seenIds.Add(quest.ID))
				{
					logger.LogWarning((object)("Duplicate quest ID '" + quest.ID + "' in " + fileName + " was skipped, already loaded from another file."));
				}
				else
				{
					quest.SourceFile = Path.GetFileNameWithoutExtension(file);
					combined.Quests.Add(quest);
				}
			}
		}

		private static QuestConfig MakeQuest(string id, string title, string goal, string rarity, List<ObjectiveEntry> kills = null, List<ObjectiveEntry> gathers = null, List<RewardEntry> rewards = null, List<SkillRewardEntry> skills = null, int expReward = 0, string preReqID = null)
		{
			QuestConfig questConfig = new QuestConfig();
			questConfig.ID = id;
			questConfig.Title = title;
			questConfig.Goal = goal;
			questConfig.Rarity = rarity;
			questConfig.PreReqID = preReqID;
			if (kills != null)
			{
				questConfig.KillReqs = kills;
			}
			if (gathers != null)
			{
				questConfig.GatherReqs = gathers;
			}
			if (rewards != null)
			{
				questConfig.RewardItems = rewards;
			}
			if (skills != null)
			{
				questConfig.SkillRewards = skills;
			}
			questConfig.ExpReward = expReward;
			return questConfig;
		}

		private static ObjectiveEntry Obj(string prefab, int amount)
		{
			return new ObjectiveEntry
			{
				Prefab = prefab,
				Amount = amount
			};
		}

		private static RewardEntry Item(string prefab, int amount)
		{
			return new RewardEntry
			{
				Prefab = prefab,
				Amount = amount
			};
		}

		private static SkillRewardEntry Skill(string skill, float amount)
		{
			return new SkillRewardEntry
			{
				Skill = skill,
				Amount = amount
			};
		}

		private static void EnsureDefaultFileExists(string configDir, ManualLogSource logger)
		{
			try
			{
				string text = Path.Combine(configDir, "quests_default.json");
				if (!File.Exists(text))
				{
					QuestList questList = new QuestList();
					List<QuestConfig> quests = questList.Quests;
					quests.Add(MakeQuest("example_meadows_boar", "Boar Trouble", "The boars are trampling the crops. Cull a few near the settlement.", "Common", new List<ObjectiveEntry> { Obj("Boar", 6) }, null, new List<RewardEntry>
					{
						Item("Coins", 20),
						Item("LeatherScraps", 5)
					}, new List<SkillRewardEntry> { Skill("Clubs", 5f) }));
					quests.Add(MakeQuest("example_meadows_deer", "The Hunt Begins", "Prove your bow. Bring down deer and carry back the meat.", "Common", new List<ObjectiveEntry> { Obj("Deer", 5) }, new List<ObjectiveEntry> { Obj("DeerMeat", 4) }, new List<RewardEntry>
					{
						Item("Coins", 25),
						Item("ArrowWood", 25)
					}, new List<SkillRewardEntry> { Skill("Bows", 8f) }, 0, "example_meadows_boar"));
					quests.Add(MakeQuest("example_bf_greydwarf", "Into the Black Forest", "The greydwarves swarm the treeline. Cut them down and collect their eyes.", "Uncommon", new List<ObjectiveEntry> { Obj("Greydwarf", 10) }, new List<ObjectiveEntry> { Obj("GreydwarfEye", 8) }, new List<RewardEntry>
					{
						Item("Coins", 30),
						Item("Resin", 15)
					}, new List<SkillRewardEntry> { Skill("Blocking", 6f) }, 120));
					quests.Add(MakeQuest("example_bf_troll", "Troll Toll", "A troll is tearing through the forest. Put it down and take its hide.", "Rare", new List<ObjectiveEntry> { Obj("Troll", 1) }, new List<ObjectiveEntry> { Obj("TrollHide", 3) }, new List<RewardEntry>
					{
						Item("Coins", 75),
						Item("MeadHealthMinor", 3)
					}, new List<SkillRewardEntry> { Skill("Axes", 10f) }, 250, "example_bf_greydwarf"));
					quests.Add(MakeQuest("example_swamp_draugr", "The Restless Dead", "Draugr and blobs haunt the swamp. Clear them and gather entrails.", "Rare", new List<ObjectiveEntry>
					{
						Obj("Draugr", 10),
						Obj("Blob", 6)
					}, new List<ObjectiveEntry> { Obj("Entrails", 5) }, new List<RewardEntry>
					{
						Item("Coins", 60),
						Item("ArrowIron", 30)
					}, new List<SkillRewardEntry> { Skill("Spears", 10f) }, 300));
					quests.Add(MakeQuest("example_swamp_iron", "Iron from the Muck", "Dredge scrap iron from the crypts and recover withered bones.", "Rare", null, new List<ObjectiveEntry>
					{
						Obj("IronScrap", 10),
						Obj("WitheredBone", 3)
					}, new List<RewardEntry>
					{
						Item("Coins", 80),
						Item("ArrowIron", 40)
					}, null, 0, "example_swamp_draugr"));
					quests.Add(MakeQuest("example_mountain_wolf", "Cold Fangs", "Wolves stalk the peaks. Hunt them and bring back pelts and fangs.", "Epic", new List<ObjectiveEntry> { Obj("Wolf", 10) }, new List<ObjectiveEntry>
					{
						Obj("WolfPelt", 6),
						Obj("WolfFang", 3)
					}, new List<RewardEntry>
					{
						Item("Coins", 100),
						Item("MeadStaminaMinor", 4)
					}, new List<SkillRewardEntry> { Skill("Bows", 12f) }, 400));
					quests.Add(MakeQuest("example_mountain_silver", "Silver Veins", "Face the mountain's elite draugr and mine obsidian and silver.", "Epic", new List<ObjectiveEntry> { Obj("Draugr_Elite", 5) }, new List<ObjectiveEntry>
					{
						Obj("Obsidian", 10),
						Obj("SilverOre", 5)
					}, new List<RewardEntry>
					{
						Item("Coins", 120),
						Item("ArrowFrost", 40)
					}, new List<SkillRewardEntry> { Skill("Blocking", 12f) }, 0, "example_mountain_wolf"));
					quests.Add(MakeQuest("example_plains_goblin", "War in the Plains", "The fulings muster for war. Break their ranks and take black metal.", "Epic", new List<ObjectiveEntry>
					{
						Obj("Goblin", 15),
						Obj("GoblinBrute", 3)
					}, new List<ObjectiveEntry> { Obj("BlackMetalScrap", 8) }, new List<RewardEntry>
					{
						Item("Coins", 150),
						Item("ArrowNeedle", 40)
					}, new List<SkillRewardEntry> { Skill("Polearms", 12f) }, 600));
					quests.Add(MakeQuest("example_plains_lox", "Taming the Herd", "The lox roam the grasslands. Bring a few down and carry back the meat.", "Epic", new List<ObjectiveEntry> { Obj("Lox", 3) }, new List<ObjectiveEntry> { Obj("LoxMeat", 5) }, new List<RewardEntry>
					{
						Item("Coins", 120),
						Item("MeadHealthMedium", 3)
					}, new List<SkillRewardEntry> { Skill("Spears", 12f) }, 0, "example_plains_goblin"));
					quests.Add(MakeQuest("example_ocean_fish", "Gone Fishing", "Cast a line off the shore and bring back a good haul of raw fish.", "Common", null, new List<ObjectiveEntry> { Obj("FishRaw", 10) }, new List<RewardEntry>
					{
						Item("Coins", 40),
						Item("MeadStaminaMinor", 3)
					}, new List<SkillRewardEntry> { Skill("Swim", 6f) }));
					quests.Add(MakeQuest("example_ocean_serpent", "Terror of the Deep", "A serpent prowls the open water. Slay it and harvest its meat and scales.", "Legendary", new List<ObjectiveEntry> { Obj("Serpent", 1) }, new List<ObjectiveEntry>
					{
						Obj("SerpentScale", 3),
						Obj("SerpentMeat", 3)
					}, new List<RewardEntry>
					{
						Item("Coins", 200),
						Item("MeadHealthMedium", 5),
						Item("ArrowSilver", 50)
					}, new List<SkillRewardEntry> { Skill("Spears", 15f) }, 800, "example_ocean_fish"));
					quests.Add(MakeQuest("example_mistlands_seeker", "The Mist Hunters", "Seekers skitter through the mist. Cut them apart for meat and carapace.", "Epic", new List<ObjectiveEntry> { Obj("Seeker", 8) }, new List<ObjectiveEntry>
					{
						Obj("Carapace", 6),
						Obj("BugMeat", 4)
					}, new List<RewardEntry>
					{
						Item("Coins", 150),
						Item("ArrowNeedle", 40)
					}, new List<SkillRewardEntry> { Skill("Knives", 12f) }, 700));
					quests.Add(MakeQuest("example_mistlands_brute", "Hive Breaker", "Break the hive's guardians: a brute and a gjall, and take the royal jelly.", "Legendary", new List<ObjectiveEntry>
					{
						Obj("SeekerBrute", 3),
						Obj("Gjall", 1)
					}, new List<ObjectiveEntry> { Obj("RoyalJelly", 3) }, new List<RewardEntry>
					{
						Item("Coins", 200),
						Item("MeadHealthMedium", 4)
					}, new List<SkillRewardEntry> { Skill("Blocking", 14f) }, 900, "example_mistlands_seeker"));
					quests.Add(MakeQuest("example_ashlands_charred", "Ashes to Ashes", "The charred legions march. Cut down warriors and archers and gather their bones.", "Legendary", new List<ObjectiveEntry>
					{
						Obj("Charred_Melee", 8),
						Obj("Charred_Archer", 4)
					}, new List<ObjectiveEntry> { Obj("CharredBone", 8) }, new List<RewardEntry>
					{
						Item("Coins", 200),
						Item("ArrowFrost", 40)
					}, new List<SkillRewardEntry> { Skill("Swords", 14f) }, 1000));
					quests.Add(MakeQuest("example_ashlands_morgen", "Bone and Bile", "Hunt the morgen and a bonemaw serpent, and cut out a morgen's heart.", "Legendary", new List<ObjectiveEntry>
					{
						Obj("Morgen", 3),
						Obj("BonemawSerpent", 1)
					}, new List<ObjectiveEntry> { Obj("MorgenHeart", 3) }, new List<RewardEntry>
					{
						Item("Coins", 300),
						Item("MeadHealthMedium", 5)
					}, new List<SkillRewardEntry> { Skill("Polearms", 15f) }, 1200, "example_ashlands_charred"));
					quests.Add(MakeQuest("example_deepnorth_moose", "The Great Hunt", "Moose roam the frozen wastes. Bring them down for hide and meat.", "Legendary", new List<ObjectiveEntry> { Obj("Moose", 6) }, new List<ObjectiveEntry>
					{
						Obj("MooseHide", 5),
						Obj("MooseMeat", 5)
					}, new List<RewardEntry>
					{
						Item("Coins", 250),
						Item("ArrowSilver", 50)
					}, new List<SkillRewardEntry> { Skill("Bows", 14f) }, 1000));
					quests.Add(MakeQuest("example_deepnorth_frozen", "The Frozen Heart", "Face the barka and the fryslings of the deep cold, and claim their frost cores.", "Legendary", new List<ObjectiveEntry>
					{
						Obj("Frysling", 6),
						Obj("Barka", 2)
					}, new List<ObjectiveEntry>
					{
						Obj("FrostCore", 4),
						Obj("BarkaBranch", 2)
					}, new List<RewardEntry>
					{
						Item("Coins", 400),
						Item("MeadHealthMedium", 6),
						Item("ArrowFrost", 50)
					}, new List<SkillRewardEntry> { Skill("Spears", 16f) }, 1500, "example_deepnorth_moose"));
					File.WriteAllText(text, JsonConvert.SerializeObject((object)questList, (Formatting)1));
					logger.LogMessage((object)("Created starter quest file at " + text + " with " + quests.Count + " quest(s)."));
				}
			}
			catch (Exception arg)
			{
				logger.LogWarning((object)$"Exception caught while creating the default quest file: {arg}");
			}
		}
	}
	[BepInPlugin("soloredis.rtdquestforge", "RtDQuestForge", "0.3.2")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInIncompatibility("blacks7ar.SeedBed")]
	internal class QuestForgePlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "soloredis.rtdquestforge";

		public const string PluginName = "RtDQuestForge";

		public const string PluginVersion = "0.3.2";

		public static QuestManager Manager;

		private static ManualLogSource StaticLogger;

		private static ConfigEntry<bool> LoggingEnable;

		private static ConfigEntry<bool> PartySharingEnable;

		private static ConfigEntry<float> PartySharingRange;

		private ConfigEntry<KeyboardShortcut> JournalHotkey;

		private Harmony HarmonyInstance;

		private QuestJournalPanel Journal;

		public static bool VerboseLogging => LoggingEnable != null && LoggingEnable.Value;

		public static bool PartySharing => PartySharingEnable == null || PartySharingEnable.Value;

		public static float PartyShareRange => (PartySharingRange != null) ? PartySharingRange.Value : 70f;

		private void Awake()
		{
			StaticLogger = ((BaseUnityPlugin)this).Logger;
			CreateConfigs();
			JSONSupport();
			LoadQuests();
			PatchGame();
			QuestSync.Init(((BaseUnityPlugin)this).Logger);
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private void CreateConfigs()
		{
			//IL_002e: 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_003c: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Expected O, but got Unknown
			try
			{
				((BaseUnityPlugin)this).Config.SaveOnConfigSet = true;
				LoggingEnable = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "Enable", false, new ConfigDescription("Enables verbose diagnostic logging.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
				{
					IsAdminOnly = false
				} }));
				JournalHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "JournalHotkey", new KeyboardShortcut((KeyCode)108, Array.Empty<KeyCode>()), new ConfigDescription("Key to open the quest journal.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
				{
					IsAdminOnly = false
				} }));
				PartySharingEnable = ((BaseUnityPlugin)this).Config.Bind<bool>("Party Sharing", "Enable", true, new ConfigDescription("Share kill credit with SocialSystem party members near the kill.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
				{
					IsAdminOnly = true
				} }));
				PartySharingRange = ((BaseUnityPlugin)this).Config.Bind<float>("Party Sharing", "Range", 70f, new ConfigDescription("How close a party member must be to the kill, in metres, to receive credit.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 200f), new object[1] { (object)new ConfigurationManagerAttributes
				{
					IsAdminOnly = true
				} }));
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)$"Exception caught while adding configuration values: {arg}");
			}
		}

		private void JSONSupport()
		{
			try
			{
				string text = Path.Combine(Paths.ConfigPath, "RtDQuestForge", "translations");
				Directory.CreateDirectory(text);
				string text2 = Path.Combine(text, "English.json");
				if (!File.Exists(text2))
				{
					File.WriteAllText(text2, "{\n  \"rtdqf_journal_title\": \"Quest Journal\",\n  \"rtdqf_active\": \"Active\",\n  \"rtdqf_completed\": \"Completed\",\n  \"rtdqf_page\": \"Page\",\n  \"rtdqf_accept\": \"Accept\",\n  \"rtdqf_abandon\": \"Abandon\",\n  \"rtdqf_slay\": \"Slay\",\n  \"rtdqf_gather\": \"Gather\",\n  \"rtdqf_reward\": \"Reward\",\n  \"rtdqf_requires\": \"Requires\",\n  \"rtdqf_mmo_exp\": \"MMO EXP\",\n  \"rtdqf_quest_complete\": \"Quest Complete\"\n}\n");
					((BaseUnityPlugin)this).Logger.LogMessage((object)("Created default translation file at " + text2));
				}
				CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
				string[] files = Directory.GetFiles(text, "*.json");
				foreach (string path in files)
				{
					string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
					localization.AddJsonFile(fileNameWithoutExtension, File.ReadAllText(path));
				}
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)$"Exception caught while loading localization files: {arg}");
			}
		}

		private void LoadQuests()
		{
			try
			{
				string configDir = Path.Combine(Paths.ConfigPath, "RtDQuestForge");
				Manager = new QuestManager(configDir, ((BaseUnityPlugin)this).Logger);
				Manager.LoadQuestDefinitions();
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)$"Exception caught while loading quest definitions: {arg}");
			}
		}

		private void PatchGame()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			try
			{
				HarmonyInstance = new Harmony("soloredis.rtdquestforge");
				HarmonyInstance.PatchAll();
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)$"Exception caught while applying Harmony patches: {arg}");
			}
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if (!(((Scene)(ref scene)).name != "main"))
			{
				BuildUI();
			}
		}

		private void BuildUI()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			try
			{
				if ((Object)(object)Journal == (Object)null)
				{
					GameObject val = new GameObject("QuestForge_JournalHost");
					Object.DontDestroyOnLoad((Object)(object)val);
					Journal = val.AddComponent<QuestJournalPanel>();
					Journal.Init(Manager, ((BaseUnityPlugin)this).Logger);
				}
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)$"Exception caught while building UI: {arg}");
			}
		}

		private void Update()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)Journal == (Object)null)
			{
				return;
			}
			KeyboardShortcut value;
			if (Journal.IsOpen)
			{
				if (!Input.GetKeyDown((KeyCode)27) && !Menu.IsVisible())
				{
					value = JournalHotkey.Value;
					if (!((KeyboardShortcut)(ref value)).IsDown())
					{
						return;
					}
				}
				Journal.Hide();
			}
			else if ((!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !Console.IsVisible() && !TextInput.IsVisible())
			{
				value = JournalHotkey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					Journal.Toggle();
				}
			}
		}

		public static void HandleQuestCompleted(QuestConfig quest)
		{
			try
			{
				RewardGranter.GrantRewards(quest, StaticLogger);
				QuestSync.ReportCompletion(quest.ID);
				if ((Object)(object)Player.m_localPlayer != (Object)null)
				{
					string text = ((Localization.instance != null) ? Localization.instance.Localize("$rtdqf_quest_complete") : "Quest Complete");
					((Character)Player.m_localPlayer).Message((MessageType)2, text + ": " + quest.Title, 0, (Sprite)null, false);
				}
			}
			catch (Exception arg)
			{
				ManualLogSource staticLogger = StaticLogger;
				if (staticLogger != null)
				{
					staticLogger.LogWarning((object)$"Exception caught while granting quest rewards: {arg}");
				}
			}
		}
	}
	public class QuestManager
	{
		public QuestList AllQuests;

		public QuestProgressData Progress;

		private readonly string ConfigDir;

		private readonly ManualLogSource Logger;

		private string ProgressFilePath;

		public event Action<QuestConfig> OnQuestCompleted;

		public event Action<QuestConfig, string, int, int> OnObjectiveProgress;

		public QuestManager(string configDir, ManualLogSource logger)
		{
			ConfigDir = configDir;
			Logger = logger;
			AllQuests = new QuestList();
			Progress = new QuestProgressData();
		}

		public void LoadQuestDefinitions()
		{
			try
			{
				AllQuests = QuestConfigLoader.LoadAll(ConfigDir, Logger);
			}
			catch (Exception arg)
			{
				Logger.LogWarning((object)$"Exception caught while loading quest definitions: {arg}");
			}
		}

		public void ApplyServerQuestList(QuestList list)
		{
			AllQuests = ((list != null) ? list : new QuestList());
		}

		public void ApplyServerCompletions(IEnumerable<string> questIDs)
		{
			bool flag = false;
			foreach (string questID in questIDs)
			{
				if (Progress.CompletedQuestIDs.Add(questID))
				{
					Progress.AcceptedQuestIDs.Remove(questID);
					Progress.TrackedQuestIDs.Remove(questID);
					flag = true;
				}
			}
			if (flag)
			{
				SaveProgress();
			}
		}

		public void LoadProgress(string characterName)
		{
			try
			{
				ProgressFilePath = Path.Combine(ConfigDir, "progress_" + SanitizeFileName(characterName) + ".json");
				if (File.Exists(ProgressFilePath))
				{
					Progress = JsonConvert.DeserializeObject<QuestProgressData>(File.ReadAllText(ProgressFilePath));
					if (Progress == null)
					{
						Progress = new QuestProgressData();
					}
				}
				else
				{
					Progress = new QuestProgressData();
				}
			}
			catch (Exception arg)
			{
				Logger.LogWarning((object)$"Exception caught while loading progress file, starting fresh: {arg}");
				Progress = new QuestProgressData();
			}
		}

		public void SaveProgress()
		{
			try
			{
				if (!string.IsNullOrEmpty(ProgressFilePath))
				{
					File.WriteAllText(ProgressFilePath, JsonConvert.SerializeObject((object)Progress, (Formatting)1));
				}
			}
			catch (Exception arg)
			{
				Logger.LogWarning((object)$"Exception caught while saving progress file: {arg}");
			}
		}

		public IEnumerable<QuestConfig> GetAvailableQuests()
		{
			return AllQuests.Quests.Where((QuestConfig q) => !Progress.CompletedQuestIDs.Contains(q.ID) && (string.IsNullOrEmpty(q.PreReqID) || Progress.CompletedQuestIDs.Contains(q.PreReqID)));
		}

		public void AcceptQuest(QuestConfig quest)
		{
			Progress.AcceptedQuestIDs.Add(quest.ID);
			Progress.TrackedQuestIDs.Add(quest.ID);
			SaveProgress();
		}

		public void AbandonQuest(QuestConfig quest)
		{
			Progress.AcceptedQuestIDs.Remove(quest.ID);
			Progress.TrackedQuestIDs.Remove(quest.ID);
			foreach (ObjectiveEntry killReq in quest.KillReqs)
			{
				Progress.KillCounts.Remove(quest.ID + ":" + killReq.Prefab);
			}
			foreach (ObjectiveEntry gatherReq in quest.GatherReqs)
			{
				Progress.GatherCounts.Remove(quest.ID + ":" + gatherReq.Prefab);
			}
			SaveProgress();
		}

		public void RegisterKill(string prefabName)
		{
			RegisterObjective(prefabName, (QuestConfig q) => q.KillReqs, Progress.KillCounts, 1);
		}

		public void RegisterGather(string prefabName, int amountAdded)
		{
			RegisterObjective(prefabName, (QuestConfig q) => q.GatherReqs, Progress.GatherCounts, amountAdded);
		}

		private void RegisterObjective(string prefabName, Func<QuestConfig, List<ObjectiveEntry>> selector, Dictionary<string, int> counters, int amount)
		{
			try
			{
				bool flag = false;
				foreach (QuestConfig item in (from q in GetAvailableQuests()
					where Progress.AcceptedQuestIDs.Contains(q.ID)
					select q).ToList())
				{
					List<ObjectiveEntry> list = selector(item);
					if (list == null)
					{
						continue;
					}
					ObjectiveEntry objectiveEntry = list.FirstOrDefault((ObjectiveEntry o) => string.Equals(o.Prefab, prefabName, StringComparison.OrdinalIgnoreCase));
					if (objectiveEntry != null)
					{
						string key = item.ID + ":" + prefabName;
						counters.TryGetValue(key, out var value);
						value = (counters[key] = Math.Min(value + amount, objectiveEntry.Amount));
						flag = true;
						if (this.OnObjectiveProgress != null)
						{
							this.OnObjectiveProgress(item, prefabName, value, objectiveEntry.Amount);
						}
						if (IsQuestComplete(item))
						{
							CompleteQuest(item);
						}
					}
				}
				if (flag)
				{
					SaveProgress();
				}
			}
			catch (Exception arg)
			{
				Logger.LogWarning((object)$"Exception caught while registering objective progress for {prefabName}: {arg}");
			}
		}

		private bool IsQuestComplete(QuestConfig quest)
		{
			int value;
			bool flag = quest.KillReqs.All((ObjectiveEntry o) => Progress.KillCounts.TryGetValue(quest.ID + ":" + o.Prefab, out value) && value >= o.Amount);
			bool flag2 = quest.GatherReqs.All((ObjectiveEntry o) => Progress.GatherCounts.TryGetValue(quest.ID + ":" + o.Prefab, out value) && value >= o.Amount);
			return flag && flag2;
		}

		private void CompleteQuest(QuestConfig quest)
		{
			Progress.CompletedQuestIDs.Add(quest.ID);
			Progress.TrackedQuestIDs.Remove(quest.ID);
			Progress.AcceptedQuestIDs.Remove(quest.ID);
			SaveProgress();
			if (this.OnQuestCompleted != null)
			{
				this.OnQuestCompleted(quest);
			}
		}

		private static string SanitizeFileName(string name)
		{
			char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
			foreach (char oldChar in invalidFileNameChars)
			{
				name = name.Replace(oldChar, '_');
			}
			return name;
		}
	}
	public class QuestList
	{
		public List<QuestConfig> Quests = new List<QuestConfig>();
	}
	public class QuestConfig
	{
		public string ID;

		public string Title;

		public string Goal;

		public string Rarity = "Common";

		public string PreReqID;

		public List<ObjectiveEntry> KillReqs = new List<ObjectiveEntry>();

		public List<ObjectiveEntry> GatherReqs = new List<ObjectiveEntry>();

		public List<RewardEntry> RewardItems = new List<RewardEntry>();

		public List<SkillRewardEntry> SkillRewards = new List<SkillRewardEntry>();

		public int ExpReward;

		public string SourceFile;
	}
	public class ObjectiveEntry
	{
		public string Prefab;

		public int Amount;
	}
	public class RewardEntry
	{
		public string Prefab;

		public int Amount = 1;
	}
	public class SkillRewardEntry
	{
		public string Skill;

		public float Amount;
	}
	public class QuestProgressData
	{
		public HashSet<string> CompletedQuestIDs = new HashSet<string>();

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

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

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

		public Dictionary<string, int> GatherCounts = new Dictionary<string, int>();
	}
	public static class QuestSync
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static CoroutineHandler <0>__OnServerReceive;

			public static CoroutineHandler <1>__OnClientReceive;

			public static CoroutineHandler <2>__OnKillServerReceive;

			public static CoroutineHandler <3>__OnKillClientReceive;

			public static CoroutineHandler <4>__OnCompletionServerReceive;

			public static CoroutineHandler <5>__OnCompletionClientReceive;
		}

		private static CustomRPC SyncRpc;

		private static CustomRPC KillRpc;

		private static CustomRPC CompletionRpc;

		private static Dictionary<long, HashSet<string>> ServerCompletions;

		private const byte CompletionSync = 0;

		private const byte CompletionRecord = 1;

		private static ManualLogSource Logger;

		public static void Init(ManualLogSource logger)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//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_0077: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Expected O, but got Unknown
			try
			{
				Logger = logger;
				NetworkManager instance = NetworkManager.Instance;
				object obj = <>O.<0>__OnServerReceive;
				if (obj == null)
				{
					CoroutineHandler val = OnServerReceive;
					<>O.<0>__OnServerReceive = val;
					obj = (object)val;
				}
				object obj2 = <>O.<1>__OnClientReceive;
				if (obj2 == null)
				{
					CoroutineHandler val2 = OnClientReceive;
					<>O.<1>__OnClientReceive = val2;
					obj2 = (object)val2;
				}
				SyncRpc = instance.AddRPC("rtdqf_questsync", (CoroutineHandler)obj, (CoroutineHandler)obj2);
				NetworkManager instance2 = NetworkManager.Instance;
				object obj3 = <>O.<2>__OnKillServerReceive;
				if (obj3 == null)
				{
					CoroutineHandler val3 = OnKillServerReceive;
					<>O.<2>__OnKillServerReceive = val3;
					obj3 = (object)val3;
				}
				object obj4 = <>O.<3>__OnKillClientReceive;
				if (obj4 == null)
				{
					CoroutineHandler val4 = OnKillClientReceive;
					<>O.<3>__OnKillClientReceive = val4;
					obj4 = (object)val4;
				}
				KillRpc = instance2.AddRPC("rtdqf_killcredit", (CoroutineHandler)obj3, (CoroutineHandler)obj4);
				NetworkManager instance3 = NetworkManager.Instance;
				object obj5 = <>O.<4>__OnCompletionServerReceive;
				if (obj5 == null)
				{
					CoroutineHandler val5 = OnCompletionServerReceive;
					<>O.<4>__OnCompletionServerReceive = val5;
					obj5 = (object)val5;
				}
				object obj6 = <>O.<5>__OnCompletionClientReceive;
				if (obj6 == null)
				{
					CoroutineHandler val6 = OnCompletionClientReceive;
					<>O.<5>__OnCompletionClientReceive = val6;
					obj6 = (object)val6;
				}
				CompletionRpc = instance3.AddRPC("rtdqf_completions", (CoroutineHandler)obj5, (CoroutineHandler)obj6);
			}
			catch (Exception arg)
			{
				logger.LogWarning((object)$"Exception caught while registering the quest sync RPCs: {arg}");
			}
		}

		public static void RequestFromServer()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			try
			{
				if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer() && SyncRpc != null)
				{
					ZNetPeer serverPeer = ZNet.instance.GetServerPeer();
					if (serverPeer != null)
					{
						SyncRpc.SendPackage(serverPeer.m_uid, new ZPackage());
						Logger.LogMessage((object)"Requested quest list from the server.");
						SendCompletionSync(serverPeer);
					}
				}
			}
			catch (Exception arg)
			{
				Logger.LogWarning((object)$"Exception caught while requesting quest sync: {arg}");
			}
		}

		public static void SendKillCredit(long killerPlayerID, string prefabName)
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			try
			{
				if (KillRpc == null || (Object)(object)ZNet.instance == (Object)null)
				{
					return;
				}
				if (QuestForgePlugin.VerboseLogging)
				{
					Logger.LogMessage((object)("Broadcasting kill credit package for " + killerPlayerID + " (" + prefabName + ")."));
				}
				if (ZNet.instance.IsServer())
				{
					DeliverKillCredit(killerPlayerID, prefabName);
					return;
				}
				ZNetPeer serverPeer = ZNet.instance.GetServerPeer();
				if (serverPeer != null)
				{
					ZPackage val = new ZPackage();
					val.Write(killerPlayerID);
					val.Write(prefabName);
					KillRpc.SendPackage(serverPeer.m_uid, val);
				}
			}
			catch (Exception arg)
			{
				Logger.LogWarning((object)$"Exception caught while sending kill credit for {prefabName}: {arg}");
			}
		}

		private static void DeliverKillCredit(long killerPlayerID, string prefabName)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			if ((Object)(object)Player.m_localPlayer != (Object)null && Player.m_localPlayer.GetPlayerID() == killerPlayerID && QuestForgePlugin.Manager != null)
			{
				QuestForgePlugin.Manager.RegisterKill(prefabName);
			}
			foreach (ZNetPeer peer in ZNet.instance.GetPeers())
			{
				ZPackage val = new ZPackage();
				val.Write(killerPlayerID);
				val.Write(prefabName);
				KillRpc.SendPackage(peer.m_uid, val);
			}
		}

		private static void SendCompletionSync(ZNetPeer serverPeer)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			if (CompletionRpc == null || (Object)(object)Player.m_localPlayer == (Object)null || QuestForgePlugin.Manager == null)
			{
				return;
			}
			ZPackage val = new ZPackage();
			val.Write((byte)0);
			val.Write(Player.m_localPlayer.GetPlayerID());
			HashSet<string> completedQuestIDs = QuestForgePlugin.Manager.Progress.CompletedQuestIDs;
			val.Write(completedQuestIDs.Count);
			foreach (string item in completedQuestIDs)
			{
				val.Write(item);
			}
			CompletionRpc.SendPackage(serverPeer.m_uid, val);
		}

		public static void ReportCompletion(string questID)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			try
			{
				if (CompletionRpc != null && !((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer() && !((Object)(object)Player.m_localPlayer == (Object)null))
				{
					ZNetPeer serverPeer = ZNet.instance.GetServerPeer();
					if (serverPeer != null)
					{
						ZPackage val = new ZPackage();
						val.Write((byte)1);
						val.Write(Player.m_localPlayer.GetPlayerID());
						val.Write(questID);
						CompletionRpc.SendPackage(serverPeer.m_uid, val);
					}
				}
			}
			catch (Exception arg)
			{
				Logger.LogWarning((object)$"Exception caught while reporting quest completion {questID}: {arg}");
			}
		}

		private static IEnumerator OnCompletionServerReceive(long sender, ZPackage package)
		{
			try
			{
				byte kind = package.ReadByte();
				long playerID = package.ReadLong();
				HashSet<string> completed = GetServerCompletions(playerID);
				bool changed = false;
				switch (kind)
				{
				case 0:
				{
					int count = package.ReadInt();
					for (int i = 0; i < count; i++)
					{
						if (completed.Add(package.ReadString()))
						{
							changed = true;
						}
					}
					ZPackage response = new ZPackage();
					response.Write(completed.Count);
					foreach (string questID in completed)
					{
						response.Write(questID);
					}
					CompletionRpc.SendPackage(sender, response);
					break;
				}
				case 1:
					if (completed.Add(package.ReadString()))
					{
						changed = true;
					}
					break;
				}
				if (changed)
				{
					SaveServerCompletions();
				}
			}
			catch (Exception ex)
			{
				Exception ex2 = ex;
				Logger.LogWarning((object)$"Exception caught while handling quest completions from peer {sender}: {ex2}");
			}
			yield break;
		}

		private static IEnumerator OnCompletionClientReceive(long sender, ZPackage package)
		{
			try
			{
				int count = package.ReadInt();
				List<string> completed = new List<string>(count);
				for (int i = 0; i < count; i++)
				{
					completed.Add(package.ReadString());
				}
				if (QuestForgePlugin.Manager != null)
				{
					QuestForgePlugin.Manager.ApplyServerCompletions(completed);
					Logger.LogMessage((object)("Applied " + completed.Count + " completed quest(s) from the server."));
				}
			}
			catch (Exception ex)
			{
				Exception ex2 = ex;
				Logger.LogWarning((object)$"Exception caught while applying completed quests from the server: {ex2}");
			}
			yield break;
		}

		private static string ServerCompletionsPath()
		{
			return Path.Combine(Paths.ConfigPath, "RtDQuestForge", "serverdata", "completions.json");
		}

		private static HashSet<string> GetServerCompletions(long playerID)
		{
			if (ServerCompletions == null)
			{
				ServerCompletions = new Dictionary<long, HashSet<string>>();
				string path = ServerCompletionsPath();
				if (File.Exists(path))
				{
					try
					{
						Dictionary<long, HashSet<string>> dictionary = JsonConvert.DeserializeObject<Dictionary<long, HashSet<string>>>(File.ReadAllText(path));
						if (dictionary != null)
						{
							ServerCompletions = dictionary;
						}
					}
					catch (Exception arg)
					{
						Logger.LogWarning((object)$"Exception caught while loading server completions, starting empty: {arg}");
					}
				}
			}
			if (!ServerCompletions.TryGetValue(playerID, out var value))
			{
				value = new HashSet<string>();
				ServerCompletions[playerID] = value;
			}
			return value;
		}

		private static void SaveServerCompletions()
		{
			try
			{
				string path = ServerCompletionsPath();
				Directory.CreateDirectory(Path.GetDirectoryName(path));
				File.WriteAllText(path, JsonConvert.SerializeObject((object)ServerCompletions, (Formatting)1));
			}
			catch (Exception arg)
			{
				Logger.LogWarning((object)$"Exception caught while saving server completions: {arg}");
			}
		}

		private static IEnumerator OnServerReceive(long sender, ZPackage package)
		{
			try
			{
				string json = JsonConvert.SerializeObject((object)QuestForgePlugin.Manager.AllQuests);
				ZPackage response = new ZPackage();
				response.Write(json);
				SyncRpc.SendPackage(sender, response);
				Logger.LogMessage((object)("Sent quest list to peer " + sender + "."));
			}
			catch (Exception ex)
			{
				Exception ex2 = ex;
				Logger.LogWarning((object)$"Exception caught while sending quest sync to peer {sender}: {ex2}");
			}
			yield break;
		}

		private static IEnumerator OnClientReceive(long sender, ZPackage package)
		{
			try
			{
				string json = package.ReadString();
				QuestList serverList = JsonConvert.DeserializeObject<QuestList>(json);
				if (serverList != null && serverList.Quests != null)
				{
					QuestForgePlugin.Manager.ApplyServerQuestList(serverList);
					Logger.LogMessage((object)("Applied " + serverList.Quests.Count + " quest(s) from the server."));
				}
			}
			catch (Exception ex)
			{
				Exception ex2 = ex;
				Logger.LogWarning((object)$"Exception caught while applying quest sync from the server: {ex2}");
			}
			yield break;
		}

		private static IEnumerator OnKillServerReceive(long sender, ZPackage package)
		{
			try
			{
				long killerPlayerID = package.ReadLong();
				string prefabName = package.ReadString();
				if (QuestForgePlugin.VerboseLogging)
				{
					Logger.LogMessage((object)("Server forwarding kill credit for " + killerPlayerID + " (" + prefabName + ") to all peers."));
				}
				DeliverKillCredit(killerPlayerID, prefabName);
			}
			catch (Exception ex)
			{
				Exception ex2 = ex;
				Logger.LogWarning((object)$"Exception caught while forwarding kill credit: {ex2}");
			}
			yield break;
		}

		private static IEnumerator OnKillClientReceive(long sender, ZPackage package)
		{
			try
			{
				if (QuestForgePlugin.VerboseLogging)
				{
					Logger.LogMessage((object)("Kill credit package received from peer " + sender + "."));
				}
				long killerPlayerID = package.ReadLong();
				string prefabName = package.ReadString();
				if ((Object)(object)Player.m_localPlayer != (Object)null && Player.m_localPlayer.GetPlayerID() == killerPlayerID && QuestForgePlugin.Manager != null)
				{
					if (QuestForgePlugin.VerboseLogging)
					{
						Logger.LogMessage((object)("Kill credit matched local player, registering " + prefabName + "."));
					}
					QuestForgePlugin.Manager.RegisterKill(prefabName);
				}
			}
			catch (Exception ex)
			{
				Exception ex2 = ex;
				Logger.LogWarning((object)$"Exception caught while applying kill credit: {ex2}");
			}
			yield break;
		}
	}
	public static class RewardGranter
	{
		private const string EpicMmoGuid = "WackyMole.EpicMMOSystem";

		public static void GrantRewards(QuestConfig quest, ManualLogSource logger)
		{
			if (!((Object)(object)Player.m_localPlayer == (Object)null))
			{
				GrantItems(quest, logger);
				GrantSkillXP(quest, logger);
				GrantEpicMmoXP(quest, logger);
			}
		}

		private static void GrantItems(QuestConfig quest, ManualLogSource logger)
		{
			try
			{
				foreach (RewardEntry rewardItem in quest.RewardItems)
				{
					GameObject prefab = ZNetScene.instance.GetPrefab(rewardItem.Prefab);
					if ((Object)(object)prefab == (Object)null)
					{
						logger.LogWarning((object)("Reward prefab '" + rewardItem.Prefab + "' on quest '" + quest.ID + "' does not exist and was skipped."));
						continue;
					}
					ItemDrop component = prefab.GetComponent<ItemDrop>();
					if ((Object)(object)component == (Object)null)
					{
						logger.LogWarning((object)("Prefab '" + rewardItem.Prefab + "' on quest '" + quest.ID + "' has no ItemDrop component."));
						continue;
					}
					Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
					int num = rewardItem.Amount;
					int val = Math.Max(1, component.m_itemData.m_shared.m_maxStackSize);
					while (num > 0)
					{
						int num2 = Math.Min(num, val);
						ItemData val2 = component.m_itemData.Clone();
						val2.m_stack = num2;
						val2.m_dropPrefab = prefab;
						if (!inventory.AddItem(val2))
						{
							((Humanoid)Player.m_localPlayer).DropItem(inventory, val2, val2.m_stack);
						}
						num -= num2;
					}
				}
			}
			catch (Exception arg)
			{
				logger.LogWarning((object)$"Exception caught while granting item rewards for quest '{quest.ID}': {arg}");
			}
		}

		private static void GrantSkillXP(QuestConfig quest, ManualLogSource logger)
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				foreach (SkillRewardEntry skillReward in quest.SkillRewards)
				{
					if (!Enum.TryParse<SkillType>(skillReward.Skill, ignoreCase: true, out SkillType result))
					{
						logger.LogWarning((object)("Unknown skill '" + skillReward.Skill + "' on quest '" + quest.ID + "'."));
					}
					else
					{
						((Character)Player.m_localPlayer).RaiseSkill(result, skillReward.Amount);
					}
				}
			}
			catch (Exception arg)
			{
				logger.LogWarning((object)$"Exception caught while granting skill XP for quest '{quest.ID}': {arg}");
			}
		}

		private static void GrantEpicMmoXP(QuestConfig quest, ManualLogSource logger)
		{
			if (quest.ExpReward <= 0 || !Chainloader.PluginInfos.ContainsKey("WackyMole.EpicMMOSystem"))
			{
				return;
			}
			try
			{
				object instance = Chainloader.PluginInfos["WackyMole.EpicMMOSystem"].Instance;
				Type type = 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 == 1)
					{
						object obj2 = Convert.ChangeType(quest.ExpReward, parameters[0].ParameterType);
						method.Invoke(obj, new object[1] { obj2 });
					}
					else if (parameters.Length == 2)
					{
						object obj3 = ((parameters[0].ParameterType == typeof(Player)) ? Player.m_localPlayer : Convert.ChangeType(quest.ExpReward, parameters[0].ParameterType));
						object obj4 = ((parameters[1].ParameterType == typeof(Player)) ? Player.m_localPlayer : Convert.ChangeType(quest.ExpReward, parameters[1].ParameterType));
						method.Invoke(obj, new object[2] { obj3, obj4 });
					}
				}
			}
			catch (Exception arg)
			{
				logger.LogWarning((object)$"Exception caught while granting EpicMMO XP for quest '{quest.ID}': {arg}");
			}
		}
	}
}
namespace RtDQuestForge.UI
{
	public class QuestJournalPanel : MonoBehaviour
	{
		private QuestManager Manager;

		private ManualLogSource Logger;

		private GameObject RootPanel;

		private RectTransform ActiveListContainer;

		private RectTransform CompletedListContainer;

		private readonly List<GameObject> EntryPool = new List<GameObject>();

		private int CurrentPageIndex;

		private float lastPageChange;

		private List<string> SourceFiles = new List<string>();

		private GameObject PagerRoot;

		private Text PagerLabel;

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

		public bool IsOpen => (Object)(object)RootPanel != (Object)null && RootPanel.activeSelf;

		private static string L(string token)
		{
			return (Localization.instance != null) ? Localization.instance.Localize(token) : token;
		}

		public void Init(QuestManager manager, ManualLogSource logger)
		{
			Manager = manager;
			Logger = logger;
			BuildUI();
			Hide();
		}

		public void Toggle()
		{
			if (IsOpen)
			{
				Hide();
			}
			else
			{
				Show();
			}
		}

		public void Show()
		{
			RootPanel.SetActive(true);
			Refresh();
			GUIManager.BlockInput(true);
		}

		public void Hide()
		{
			RootPanel.SetActive(false);
			GUIManager.BlockInput(false);
		}

		public void Refresh()
		{
			try
			{
				foreach (GameObject item in EntryPool)
				{
					Object.Destroy((Object)(object)item);
				}
				EntryPool.Clear();
				if (Manager != null)
				{
					SourceFiles = Manager.AllQuests.Quests.Select((QuestConfig q) => string.IsNullOrEmpty(q.SourceFile) ? "Quests" : q.SourceFile).Distinct().OrderBy<string, string>((string name) => name, StringComparer.OrdinalIgnoreCase)
						.ToList();
					if (SourceFiles.Count == 0)
					{
						SourceFiles.Add("Quests");
					}
					if (CurrentPageIndex >= SourceFiles.Count)
					{
						CurrentPageIndex = 0;
					}
					string currentFile = SourceFiles[CurrentPageIndex];
					PagerRoot.SetActive(SourceFiles.Count > 1);
					PagerLabel.text = L("$rtdqf_page") + " " + (CurrentPageIndex + 1) + "/" + SourceFiles.Count;
					List<QuestConfig> pageQuests = Manager.AllQuests.Quests.Where((QuestConfig q) => (string.IsNullOrEmpty(q.SourceFile) ? "Quests" : q.SourceFile) == currentFile).ToList();
					List<QuestConfig> first = (from q in Manager.GetAvailableQuests()
						where pageQuests.Contains(q)
						select q).ToList();
					List<QuestConfig> second = pageQuests.Where((QuestConfig q) => !Manager.Progress.CompletedQuestIDs.Contains(q.ID) && !string.IsNullOrEmpty(q.PreReqID) && !Manager.Progress.CompletedQuestIDs.Contains(q.PreReqID)).ToList();
					List<QuestConfig> quests = pageQuests.Where((QuestConfig q) => Manager.Progress.CompletedQuestIDs.Contains(q.ID)).ToList();
					FillColumn(ActiveListContainer, first.Concat(second).ToList());
					FillColumn(CompletedListContainer, quests);
				}
			}
			catch (Exception arg)
			{
				Logger.LogWarning((object)$"Exception caught while refreshing the quest journal: {arg}");
			}
		}

		private void ChangePage(int direction)
		{
			if (SourceFiles.Count > 1 && !(Time.unscaledTime - lastPageChange < 0.2f))
			{
				lastPageChange = Time.unscaledTime;
				CurrentPageIndex += direction;
				if (CurrentPageIndex < 0)
				{
					CurrentPageIndex = SourceFiles.Count - 1;
				}
				if (CurrentPageIndex >= SourceFiles.Count)
				{
					CurrentPageIndex = 0;
				}
				Refresh();
			}
		}

		private void FillColumn(RectTransform container, List<QuestConfig> quests)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			float num2 = 150f;
			foreach (QuestConfig quest in quests)
			{
				GameObject item = BuildEntry(container, quest, num);
				EntryPool.Add(item);
				num -= num2;
			}
			container.sizeDelta = new Vector2(0f, Mathf.Abs(num) + 20f);
		}

		private void BuildUI()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_00b1: 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_00dd: 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_0165: 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_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: 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)
			GameObject val = new GameObject("QuestForge_JournalCanvas");
			val.transform.SetParent(((Component)this).transform, false);
			Canvas val2 = val.AddComponent<Canvas>();
			val2.renderMode = (RenderMode)0;
			val2.sortingOrder = 200;
			CanvasScaler val3 = val.AddComponent<CanvasScaler>();
			val3.uiScaleMode = (ScaleMode)1;
			val3.referenceResolution = new Vector2(1920f, 1080f);
			val3.matchWidthOrHeight = 0.5f;
			val.AddComponent<GraphicRaycaster>();
			RootPanel = new GameObject("Panel");
			RootPanel.transform.SetParent(val.transform, false);
			RectTransform val4 = RootPanel.AddComponent<RectTransform>();
			val4.sizeDelta = new Vector2(920f, 560f);
			val4.anchorMin = new Vector2(0.5f, 0.5f);
			val4.anchorMax = new Vector2(0.5f, 0.5f);
			val4.anchoredPosition = Vector2.zero;
			Image val5 = RootPanel.AddComponent<Image>();
			Sprite val6 = ((GUIManager.Instance != null) ? GUIManager.Instance.GetSprite("woodpanel_trophys") : null);
			if ((Object)(object)val6 != (Object)null)
			{
				val5.sprite = val6;
				val5.type = (Type)1;
				((Graphic)val5).color = Color.white;
			}
			else
			{
				((Graphic)val5).color = new Color(0.05f, 0.05f, 0.05f, 0.92f);
			}
			Text val7 = CreateText(RootPanel.transform, L("$rtdqf_journal_title"), 26, (TextAnchor)4);
			ApplyValheimHeaderStyle(val7);
			RectTransform component = ((Component)val7).GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(1f, 1f);
			component.pivot = new Vector2(0.5f, 1f);
			component.sizeDelta = new Vector2(0f, 40f);
			component.anchoredPosition = new Vector2(0f, -18f);
			BuildPager();
			ActiveListContainer = BuildColumn(L("$rtdqf_active"), 0f, 0.5f);
			CompletedListContainer = BuildColumn(L("$rtdqf_completed"), 0.5f, 1f);
		}

		private void BuildPager()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0045: 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)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: 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_00ca: Expected O, but got Unknown
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: 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_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Expected O, but got Unknown
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: 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)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			PagerRoot = new GameObject("Pager");
			PagerRoot.transform.SetParent(RootPanel.transform, false);
			RectTransform val = PagerRoot.AddComponent<RectTransform>();
			val.anchorMin = new Vector2(1f, 1f);
			val.anchorMax = new Vector2(1f, 1f);
			val.pivot = new Vector2(1f, 1f);
			val.sizeDelta = new Vector2(260f, 28f);
			val.anchoredPosition = new Vector2(-22f, -20f);
			Button val2 = CreateButton(PagerRoot.transform, "<", (UnityAction)delegate
			{
				ChangePage(-1);
			}, valheimStyle: false);
			RectTransform component = ((Component)val2).GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 0f);
			component.anchorMax = new Vector2(0f, 1f);
			component.pivot = new Vector2(0f, 0.5f);
			component.sizeDelta = new Vector2(28f, 0f);
			component.anchoredPosition = Vector2.zero;
			Button val3 = CreateButton(PagerRoot.transform, ">", (UnityAction)delegate
			{
				ChangePage(1);
			}, valheimStyle: false);
			RectTransform component2 = ((Component)val3).GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(1f, 0f);
			component2.anchorMax = new Vector2(1f, 1f);
			component2.pivot = new Vector2(1f, 0.5f);
			component2.sizeDelta = new Vector2(28f, 0f);
			component2.anchoredPosition = Vector2.zero;
			PagerLabel = CreateText(PagerRoot.transform, "", 12, (TextAnchor)4);
			RectTransform component3 = ((Component)PagerLabel).GetComponent<RectTransform>();
			component3.anchorMin = new Vector2(0f, 0f);
			component3.anchorMax = new Vector2(1f, 1f);
			component3.offsetMin = new Vector2(32f, 0f);
			component3.offsetMax = new Vector2(-32f, 0f);
		}

		private RectTransform BuildColumn(string header, float anchorLeft, float anchorRight)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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_00f8: 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_010f: Expected O, but got Unknown
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Expected O, but got Unknown
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Expected O, but got Unknown
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: 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_0294: 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)
			GameObject val = new GameObject("Column_" + header);
			val.transform.SetParent(RootPanel.transform, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = new Vector2(anchorLeft, 0f);
			val2.anchorMax = new Vector2(anchorRight, 1f);
			val2.offsetMin = new Vector2(18f, 22f);
			val2.offsetMax = new Vector2(-18f, -62f);
			Text val3 = CreateText(val.transform, header, 18, (TextAnchor)4);
			ApplyValheimHeaderStyle(val3);
			RectTransform component = ((Component)val3).GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(1f, 1f);
			component.pivot = new Vector2(0.5f, 1f);
			component.sizeDelta = new Vector2(0f, 26f);
			component.anchoredPosition = Vector2.zero;
			GameObject val4 = new GameObject("ScrollView");
			val4.transform.SetParent(val.transform, false);
			ScrollRect val5 = val4.AddComponent<ScrollRect>();
			RectTransform component2 = val4.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0f, 0f);
			component2.anchorMax = new Vector2(1f, 1f);
			component2.offsetMin = new Vector2(0f, 0f);
			component2.offsetMax = new Vector2(0f, -30f);
			GameObject val6 = new GameObject("Viewport");
			val6.transform.SetParent(val4.transform, false);
			RectTransform val7 = val6.AddComponent<RectTransform>();
			val7.anchorMin = Vector2.zero;
			val7.anchorMax = Vector2.one;
			val7.offsetMin = Vector2.zero;
			val7.offsetMax = Vector2.zero;
			((Graphic)val6.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.01f);
			val6.AddComponent<Mask>().showMaskGraphic = false;
			GameObject val8 = new GameObject("Content");
			val8.transform.SetParent(val6.transform, false);
			RectTransform val9 = val8.AddComponent<RectTransform>();
			val9.anchorMin = new Vector2(0f, 1f);
			val9.anchorMax = new Vector2(1f, 1f);
			val9.pivot = new Vector2(0.5f, 1f);
			val9.anchoredPosition = Vector2.zero;
			val9.sizeDelta = new Vector2(0f, 0f);
			val5.viewport = val7;
			val5.content = val9;
			val5.horizontal = false;
			val5.vertical = true;
			val5.scrollSensitivity = 500f;
			val5.inertia = false;
			val5.movementType = (MovementType)2;
			return val9;
		}

		private GameObject BuildEntry(RectTransform parent, QuestConfig quest, float y)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_0050: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: 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_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Expected O, but got Unknown
			//IL_0190: 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_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: 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_0345: 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_0373: 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_03cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_050b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0522: Unknown result type (might be due to invalid IL or missing references)
			//IL_0539: Unknown result type (might be due to invalid IL or missing references)
			//IL_0581: Unknown result type (might be due to invalid IL or missing references)
			//IL_058c: Expected O, but got Unknown
			//IL_05a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ff: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Quest_" + quest.ID);
			val.transform.SetParent((Transform)(object)parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = new Vector2(0f, 1f);
			val2.anchorMax = new Vector2(1f, 1f);
			val2.pivot = new Vector2(0.5f, 1f);
			val2.sizeDelta = new Vector2(0f, 140f);
			val2.anchoredPosition = new Vector2(0f, y);
			bool flag = Manager.Progress.CompletedQuestIDs.Contains(quest.ID);
			bool flag2 = Manager.Progress.AcceptedQuestIDs.Contains(quest.ID);
			bool flag3 = !flag && !string.IsNullOrEmpty(quest.PreReqID) && !Manager.Progress.CompletedQuestIDs.Contains(quest.PreReqID);
			((Graphic)val.AddComponent<Image>()).color = (Color)(flag3 ? new Color(0.35f, 0.35f, 0.35f) : QuestUIStyles.RarityColor(quest.Rarity));
			GameObject val3 = new GameObject("Inner");
			val3.transform.SetParent(val.transform, false);
			RectTransform val4 = val3.AddComponent<RectTransform>();
			val4.anchorMin = Vector2.zero;
			val4.anchorMax = Vector2.one;
			val4.offsetMin = new Vector2(3f, 3f);
			val4.offsetMax = new Vector2(-3f, -3f);
			Image val5 = val3.AddComponent<Image>();
			Sprite val6 = ((GUIManager.Instance != null) ? GUIManager.Instance.GetSprite("woodpanel_trophys") : null);
			if ((Object)(object)val6 != (Object)null)
			{
				val5.sprite = val6;
				val5.type = (Type)1;
				if (flag)
				{
					((Graphic)val5).color = new Color(0.55f, 0.75f, 0.55f, 1f);
				}
				else if (flag3)
				{
					((Graphic)val5).color = new Color(0.45f, 0.45f, 0.45f, 1f);
				}
				else if (flag2)
				{
					((Graphic)val5).color = new Color(1f, 0.92f, 0.75f, 1f);
				}
				else
				{
					((Graphic)val5).color = Color.white;
				}
			}
			else
			{
				((Graphic)val5).color = (flag ? new Color(0.08f, 0.14f, 0.08f, 0.95f) : new Color(0.1f, 0.1f, 0.1f, 0.95f));
			}
			Text val7 = CreateText(val3.transform, L(quest.Title), 16, (TextAnchor)0);
			RectTransform component = ((Component)val7).GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(1f, 1f);
			component.pivot = new Vector2(0f, 1f);
			component.sizeDelta = new Vector2(-16f, 20f);
			component.anchoredPosition = new Vector2(10f, -8f);
			Text val8 = CreateText(val3.transform, L(quest.Goal), 12, (TextAnchor)0);
			RectTransform component2 = ((Component)val8).GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0f, 0f);
			component2.anchorMax = new Vector2(1f, 1f);
			component2.offsetMin = new Vector2(10f, 62f);
			component2.offsetMax = new Vector2((float)((flag || flag3) ? (-10) : (-92)), -30f);
			string content;
			if (flag3)
			{
				QuestConfig questConfig = Manager.AllQuests.Quests.FirstOrDefault((QuestConfig q) => q.ID == quest.PreReqID);
				string text = ((questConfig != null) ? L(questConfig.Title) : quest.PreReqID);
				content = L("$rtdqf_requires") + ": " + text;
			}
			else
			{
				content = BuildDetailLine(quest);
			}
			Text val9 = CreateText(val3.transform, content, 11, (TextAnchor)6);
			((Graphic)val9).color = new Color(0.8f, 0.8f, 0.1f);
			RectTransform component3 = ((Component)val9).GetComponent<RectTransform>();
			component3.anchorMin = new Vector2(0f, 0f);
			component3.anchorMax = new Vector2(1f, 0f);
			component3.pivot = new Vector2(0.5f, 0f);
			component3.sizeDelta = new Vector2(-20f, 40f);
			component3.anchoredPosition = new Vector2(0f, 16f);
			if (!flag && !flag3)
			{
				Button val10 = CreateButton(val3.transform, flag2 ? L("$rtdqf_abandon") : L("$rtdqf_accept"), (UnityAction)delegate
				{
					if (Manager.Progress.AcceptedQuestIDs.Contains(quest.ID))
					{
						Manager.AbandonQuest(quest);
					}
					else
					{
						Manager.AcceptQuest(quest);
					}
					Refresh();
				}, valheimStyle: false);
				RectTransform component4 = ((Component)val10).GetComponent<RectTransform>();
				component4.anchorMin = new Vector2(1f, 1f);
				component4.anchorMax = new Vector2(1f, 1f);
				component4.pivot = new Vector2(1f, 1f);
				component4.sizeDelta = new Vector2(78f, 24f);
				component4.anchoredPosition = new Vector2(-8f, -8f);
			}
			return val;
		}

		private string BuildDetailLine(QuestConfig quest)
		{
			StringBuilder stringBuilder = new StringBuilder();
			foreach (ObjectiveEntry killReq in quest.KillReqs)
			{
				Manager.Progress.KillCounts.TryGetValue(quest.ID + ":" + killReq.Prefab, out var value);
				if (stringBuilder.Length > 0)
				{
					stringBuilder.Append("   ");
				}
				stringBuilder.Append(L("$rtdqf_slay") + " " + PrettyName(killReq.Prefab) + ": " + value + "/" + killReq.Amount);
			}
			foreach (ObjectiveEntry gatherReq in quest.GatherReqs)
			{
				Manager.Progress.GatherCounts.TryGetValue(quest.ID + ":" + gatherReq.Prefab, out var value2);
				if (stringBuilder.Length > 0)
				{
					stringBuilder.Append("   ");
				}
				stringBuilder.Append(L("$rtdqf_gather") + " " + PrettyName(gatherReq.Prefab) + ": " + value2 + "/" + gatherReq.Amount);
			}
			StringBuilder stringBuilder2 = new StringBuilder();
			foreach (RewardEntry rewardItem in quest.RewardItems)
			{
				if (stringBuilder2.Length > 0)
				{
					stringBuilder2.Append(", ");
				}
				stringBuilder2.Append(rewardItem.Amount + " " + PrettyName(rewardItem.Prefab));
			}
			foreach (SkillRewardEntry skillReward in quest.SkillRewards)
			{
				if (stringBuilder2.Length > 0)
				{
					stringBuilder2.Append(", ");
				}
				stringBuilder2.Append("+" + skillReward.Amount + " " + skillReward.Skill + " XP");
			}
			if (quest.ExpReward > 0 && Chainloader.PluginInfos.ContainsKey("WackyMole.EpicMMOSystem"))
			{
				if (stringBuilder2.Length > 0)
				{
					stringBuilder2.Append(", ");
				}
				stringBuilder2.Append(quest.ExpReward + " " + L("$rtdqf_mmo_exp"));
			}
			if (stringBuilder2.Length > 0)
			{
				if (stringBuilder.Length > 0)
				{
					stringBuilder.Append("\n");
				}
				stringBuilder.Append(L("$rtdqf_reward") + ": " + stringBuilder2);
			}
			return stringBuilder.ToString();
		}

		private static string PrettyName(string prefabName)
		{
			if (PrettyNameCache.TryGetValue(prefabName, out var value))
			{
				return value;
			}
			string text = prefabName;
			try
			{
				GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(prefabName) : null);
				if ((Object)(object)val != (Object)null)
				{
					Character component = val.GetComponent<Character>();
					if ((Object)(object)component != (Object)null && !string.IsNullOrEmpty(component.m_name))
					{
						text = L(component.m_name);
					}
					else
					{
						ItemDrop component2 = val.GetComponent<ItemDrop>();
						if ((Object)(object)component2 != (Object)null && !string.IsNullOrEmpty(component2.m_itemData.m_shared.m_name))
						{
							text = L(component2.m_itemData.m_shared.m_name);
						}
					}
				}
			}
			catch (Exception)
			{
				text = prefabName;
			}
			PrettyNameCache[prefabName] = text;
			return text;
		}

		private static Text CreateText(Transform parent, string content, int fontSize, TextAnchor anchor)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//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)
			GameObject val = new GameObject("Text");
			val.transform.SetParent(parent, false);
			Text val2 = val.AddComponent<Text>();
			val2.text = content;
			val2.fontSize = fontSize;
			val2.alignment = anchor;
			Font val3 = ((GUIManager.Instance != null) ? GUIManager.Instance.AveriaSerif : null);
			val2.font = (((Object)(object)val3 != (Object)null) ? val3 : Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf"));
			((Graphic)val2).color = new Color(0.15f, 0.09f, 0.05f);
			val2.horizontalOverflow = (HorizontalWrapMode)0;
			val2.verticalOverflow = (VerticalWrapMode)0;
			return val2;
		}

		private static void ApplyValheimHeaderStyle(Text text)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if (GUIManager.Instance != null)
			{
				Font averiaSerifBold = GUIManager.Instance.AveriaSerifBold;
				if ((Object)(object)averiaSerifBold != (Object)null)
				{
					text.font = averiaSerifBold;
				}
				((Graphic)text).color = GUIManager.Instance.ValheimOrange;
			}
		}

		private static Button CreateButton(Transform parent, string label, UnityAction onClick, bool valheimStyle = true)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: 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_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Button");
			val.transform.SetParent(parent, false);
			val.AddComponent<Image>();
			Button val2 = val.AddComponent<Button>();
			((UnityEvent)val2.onClick).AddListener(onClick);
			Text val3 = CreateText(val.transform, label, 12, (TextAnchor)4);
			RectTransform component = ((Component)val3).GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			if (valheimStyle && GUIManager.Instance != null)
			{
				GUIManager.Instance.ApplyButtonStyle(val2, 16);
			}
			else
			{
				Image component2 = val.GetComponent<Image>();
				Sprite val4 = ((GUIManager.Instance != null) ? GUIManager.Instance.GetSprite("button") : null);
				if ((Object)(object)val4 != (Object)null)
				{
					component2.sprite = val4;
					component2.type = (Type)1;
				}
				else
				{
					component2.sprite = null;
					((Graphic)component2).color = new Color(0.35f, 0.24f, 0.14f, 0.95f);
				}
				ColorBlock colors = ((Selectable)val2).colors;
				((ColorBlock)(ref colors)).normalColor = Color.white;
				((ColorBlock)(ref colors)).highlightedColor = new Color(1.25f, 1.25f, 1.25f, 1f);
				((ColorBlock)(ref colors)).pressedColor = new Color(0.75f, 0.75f, 0.75f, 1f);
				((Selectable)val2).colors = colors;
				val3.fontSize = ((label != null && label.Length <= 2) ? 18 : 12);
				if (GUIManager.Instance != null)
				{
					Font averiaSerifBold = GUIManager.Instance.AveriaSerifBold;
					if ((Object)(object)averiaSerifBold != (Object)null)
					{
						val3.font = averiaSerifBold;
					}
					((Graphic)val3).color = GUIManager.Instance.ValheimOrange;
				}
			}
			return val2;
		}
	}
	internal static class QuestUIStyles
	{
		public static Color RarityColor(string rarity)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: 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_00b1: 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_00d4: 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)
			return (Color)(((rarity != null) ? rarity.ToLowerInvariant() : "") switch
			{
				"common" => new Color(0.75f, 0.75f, 0.75f), 
				"uncommon" => new Color(0.3f, 0.8f, 0.3f), 
				"rare" => new Color(0.3f, 0.55f, 1f), 
				"epic" => new Color(0.65f, 0.3f, 0.9f), 
				"legendary" => new Color(1f, 0.65f, 0.1f), 
				_ => Color.white, 
			});
		}
	}
}
namespace RtDQuestForge.Patches
{
	[HarmonyPatch(typeof(Character), "OnDeath")]
	internal static class Patch_Character_OnDeath_KillTracking
	{
		private static readonly FieldInfo LastHitField = AccessTools.Field(typeof(Character), "m_lastHit");

		private static readonly int PartyIdHash = StringExtensionMethods.GetStableHashCode("SocialSystem_PartyId");

		private static void Postfix(Character __instance)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || __instance is Player)
			{
				return;
			}
			HitData val = ((!(LastHitField != null)) ? ((HitData)null) : ((HitData)LastHitField.GetValue(__instance)));
			if (val == null)
			{
				return;
			}
			Character attacker = val.GetAttacker();
			Player val2 = (Player)(object)((attacker is Player) ? attacker : null);
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			string prefabName = Utils.GetPrefabName(((Component)__instance).gameObject);
			foreach (Player recipient in GetRecipients(val2, ((Component)__instance).transform.position))
			{
				if ((Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)recipient == (Object)(object)Player.m_localPlayer)
				{
					if (QuestForgePlugin.Manager != null)
					{
						QuestForgePlugin.Manager.RegisterKill(prefabName);
					}
					continue;
				}
				if (QuestForgePlugin.VerboseLogging)
				{
					Logger.LogMessage((object)("Routing kill credit: " + recipient.GetPlayerName() + " for " + prefabName));
				}
				QuestSync.SendKillCredit(recipient.GetPlayerID(), prefabName);
			}
		}

		private static List<Player> GetRecipients(Player killer, Vector3 killPosition)
		{
			//IL_009d: 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)
			List<Player> list = new List<Player>();
			list.Add(killer);
			if (!QuestForgePlugin.PartySharing)
			{
				return list;
			}
			int partyId = GetPartyId(killer);
			if (partyId == 0)
			{
				return list;
			}
			float partyShareRange = QuestForgePlugin.PartyShareRange;
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if (!((Object)(object)allPlayer == (Object)null) && !((Object)(object)allPlayer == (Object)(object)killer) && !((Character)allPlayer).IsDead() && GetPartyId(allPlayer) == partyId && !(Vector3.Distance(((Component)allPlayer).transform.position, killPosition) > partyShareRange))
				{
					list.Add(allPlayer);
				}
			}
			return list;
		}

		private static int GetPartyId(Player player)
		{
			ZNetView val = (((Object)(object)player != (Object)null) ? ((Component)player).GetComponent<ZNetView>() : null);
			ZDO val2 = (((Object)(object)val != (Object)null) ? val.GetZDO() : null);
			return (val2 != null) ? val2.GetInt(PartyIdHash, 0) : 0;
		}
	}
	[HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })]
	internal static class Patch_Inventory_AddItem_GatherTracking
	{
		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() && QuestForgePlugin.Manager != null)
			{
				QuestForgePlugin.Manager.RegisterGather(((Object)item.m_dropPrefab).name, item.m_stack);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "OnSpawned")]
	internal static class Patch_Player_OnSpawned_LoadProgress
	{
		private static bool EventsWired;

		private static void Postfix(Player __instance)
		{
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && QuestForgePlugin.Manager != null)
			{
				QuestForgePlugin.Manager.LoadProgress(__instance.GetPlayerName());
				QuestSync.RequestFromServer();
				if (!EventsWired)
				{
					EventsWired = true;
					QuestForgePlugin.Manager.OnQuestCompleted += QuestForgePlugin.HandleQuestCompleted;
				}
			}
		}
	}
}