Decompiled source of QuestMod v1.1.1

plugins/QuestMod/QuestMod.dll

Decompiled 18 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using HutongGames.PlayMaker;
using HutongGames.PlayMaker.Actions;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using QuestPlaymakerActions;
using Silksong.DataManager;
using Silksong.UnityHelper.Extensions;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("QuestMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.1.0")]
[assembly: AssemblyInformationalVersion("1.1.1+1e563a43f188437863cd4c109ecefc7245a7fabc")]
[assembly: AssemblyProduct("QuestMod")]
[assembly: AssemblyTitle("QuestMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace QuestMod
{
	public struct QuestInfo
	{
		public string Name;

		public string DisplayName;

		public bool IsAccepted;

		public bool IsCompleted;
	}
	public struct ChainInfo
	{
		public string ChainName;

		public string DisplayName;

		public string[] Steps;

		public int CurrentStep;

		public int TotalSteps;

		public bool IsFullyComplete;
	}
	public static class QuestAcceptance
	{
		public static string GetExclusionConflict(string questName)
		{
			if (!QuestRegistry.MutuallyExclusiveQuests.TryGetValue(questName, out string value))
			{
				return null;
			}
			IDictionary runtimeData = QuestDataAccess.GetRuntimeData();
			if (runtimeData == null || !runtimeData.Contains(value))
			{
				return null;
			}
			object qd = runtimeData[value];
			if (QuestDataAccess.IsAccepted(qd) || QuestDataAccess.IsCompleted(qd))
			{
				return value;
			}
			return null;
		}

		public static bool IsChainPrereqMet(string questName)
		{
			foreach (string[] value in QuestRegistry.ChainRegistry.Values)
			{
				for (int i = 0; i < value.Length; i++)
				{
					if (value[i] != questName)
					{
						continue;
					}
					if (i == 0)
					{
						return true;
					}
					IDictionary runtimeData = QuestDataAccess.GetRuntimeData();
					if (runtimeData == null)
					{
						return false;
					}
					for (int j = 0; j < i; j++)
					{
						if (!runtimeData.Contains(value[j]))
						{
							return false;
						}
						if (!QuestDataAccess.IsCompleted(runtimeData[value[j]]))
						{
							return false;
						}
					}
					return true;
				}
			}
			return true;
		}

		public static string GetDisplayName(string internalName)
		{
			if (QuestRegistry.DisplayNames.TryGetValue(internalName, out string value))
			{
				return value;
			}
			return internalName;
		}

		public static void Initialize()
		{
			QuestModPlugin.Log.LogInfo((object)"QuestAcceptance initialized");
		}

		public static void InjectAndAcceptAllQuests()
		{
			if (PlayerData.instance == null)
			{
				QuestModPlugin.Log.LogWarning((object)"InjectAndAcceptAllQuests: PlayerData not available yet");
				return;
			}
			IDictionary runtimeData = QuestDataAccess.GetRuntimeData();
			if (runtimeData == null)
			{
				QuestModPlugin.Log.LogWarning((object)"InjectAndAcceptAllQuests: RuntimeData not available yet");
				return;
			}
			FullQuestBase[] array = Resources.FindObjectsOfTypeAll<FullQuestBase>();
			int num = 0;
			int num2 = 0;
			FullQuestBase[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				string name = ((Object)array2[i]).name;
				if (string.IsNullOrEmpty(name))
				{
					continue;
				}
				if (QuestRegistry.ExcludedQuests.Contains(name))
				{
					QuestModPlugin.Log.LogInfo((object)("  SKIP [" + name + "]: excluded"));
					num2++;
				}
				else
				{
					if (runtimeData.Contains(name))
					{
						continue;
					}
					if (!QuestModPlugin.IsQuestDiscovered(name))
					{
						QuestModPlugin.Log.LogInfo((object)("  SKIP [" + name + "]: not discovered"));
						num2++;
						continue;
					}
					if (!IsChainPrereqMet(name))
					{
						QuestModPlugin.Log.LogInfo((object)("  SKIP [" + name + "]: chain prereq not met"));
						num2++;
						continue;
					}
					object anyValue = GetAnyValue(runtimeData);
					if (anyValue != null)
					{
						object value = QuestDataAccess.SetFields(anyValue, seen: true, accepted: true, completed: false, wasEver: false);
						runtimeData[name] = value;
						num++;
					}
				}
			}
			QuestModPlugin.Log.LogInfo((object)$"Injected {num} new quests into RuntimeData (skipped {num2} excluded, total ScriptableObjects: {array.Length})");
			AcceptAllQuests();
		}

		public static void ForceAcceptAllQuests()
		{
			ForceAllQuestsOp(complete: false);
		}

		public static void ForceCompleteAllQuests()
		{
			ForceAllQuestsOp(complete: true);
		}

		private static void ForceAllQuestsOp(bool complete)
		{
			if (PlayerData.instance == null)
			{
				return;
			}
			IDictionary runtimeData = QuestDataAccess.GetRuntimeData();
			if (runtimeData == null)
			{
				return;
			}
			bool blackThreadWorld = PlayerData.instance.blackThreadWorld;
			FullQuestBase[] array = Resources.FindObjectsOfTypeAll<FullQuestBase>();
			int num = 0;
			FullQuestBase[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				string name = ((Object)array2[i]).name;
				if (!string.IsNullOrEmpty(name) && !QuestRegistry.ExcludedQuests.Contains(name) && !runtimeData.Contains(name))
				{
					object anyValue = GetAnyValue(runtimeData);
					if (anyValue != null)
					{
						object value = QuestDataAccess.SetFields(anyValue, seen: true, accepted: true, completed: false, wasEver: false);
						runtimeData[name] = value;
						num++;
					}
				}
			}
			ModifyAllQuests(runtimeData, complete);
			PlayerData.instance.blackThreadWorld = blackThreadWorld;
			string arg = (complete ? "completed" : "accepted");
			QuestModPlugin.Log.LogInfo((object)$"Force {arg} ALL quests (injected {num} new, total ScriptableObjects: {array.Length}), act state preserved");
		}

		public static void AcceptAllQuests()
		{
			if (PlayerData.instance != null)
			{
				IDictionary runtimeData = QuestDataAccess.GetRuntimeData();
				if (runtimeData != null)
				{
					ModifyAllQuests(runtimeData, complete: false);
				}
			}
		}

		public static List<QuestInfo> GetQuestList()
		{
			List<QuestInfo> list = new List<QuestInfo>();
			if (PlayerData.instance == null)
			{
				return list;
			}
			IDictionary runtimeData = QuestDataAccess.GetRuntimeData();
			HashSet<string> hashSet = new HashSet<string>();
			if (runtimeData != null)
			{
				foreach (DictionaryEntry item in runtimeData)
				{
					if (item.Key is string text)
					{
						hashSet.Add(text);
						list.Add(new QuestInfo
						{
							Name = text,
							DisplayName = GetDisplayName(text),
							IsAccepted = QuestDataAccess.IsAccepted(item.Value),
							IsCompleted = QuestDataAccess.IsCompleted(item.Value)
						});
					}
				}
			}
			FullQuestBase[] array = Resources.FindObjectsOfTypeAll<FullQuestBase>();
			foreach (FullQuestBase val in array)
			{
				if (!string.IsNullOrEmpty(((Object)val).name) && !hashSet.Contains(((Object)val).name))
				{
					list.Add(new QuestInfo
					{
						Name = ((Object)val).name,
						DisplayName = GetDisplayName(((Object)val).name),
						IsAccepted = false,
						IsCompleted = false
					});
				}
			}
			list.Sort((QuestInfo a, QuestInfo b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase));
			return list;
		}

		public static void AcceptQuest(string name)
		{
			IDictionary dictionary;
			object qd;
			(dictionary, qd) = EnsureQuestEntry(name);
			if (dictionary != null)
			{
				qd = QuestDataAccess.SetFields(qd, seen: true, accepted: true, QuestDataAccess.IsCompleted(qd), QuestDataAccess.IsCompleted(qd));
				dictionary[name] = qd;
				QuestModPlugin.LogDebugInfo("Accepted: " + name);
			}
		}

		public static void CompleteQuest(string name)
		{
			IDictionary dictionary;
			object qd;
			(dictionary, qd) = EnsureQuestEntry(name);
			if (dictionary != null)
			{
				qd = QuestDataAccess.SetFields(qd, seen: true, accepted: true, completed: true, wasEver: true);
				dictionary[name] = qd;
				QuestModPlugin.LogDebugInfo("Completed: " + name);
			}
		}

		public static void UnacceptQuest(string name)
		{
			if (PlayerData.instance != null)
			{
				IDictionary runtimeData = QuestDataAccess.GetRuntimeData();
				if (runtimeData != null && runtimeData.Contains(name))
				{
					object qd = runtimeData[name];
					qd = QuestDataAccess.SetFields(qd, seen: true, accepted: false, completed: false, QuestDataAccess.IsCompleted(qd));
					runtimeData[name] = qd;
					QuestModPlugin.LogDebugInfo("Unaccepted: " + name);
				}
			}
		}

		public static void UncompleteQuest(string name)
		{
			if (PlayerData.instance != null)
			{
				IDictionary runtimeData = QuestDataAccess.GetRuntimeData();
				if (runtimeData != null && runtimeData.Contains(name))
				{
					object qd = runtimeData[name];
					qd = QuestDataAccess.SetFields(qd, seen: true, accepted: true, completed: false, wasEver: true);
					runtimeData[name] = qd;
					QuestModPlugin.LogDebugInfo("Uncompleted: " + name);
				}
			}
		}

		public static void CompleteAllQuests()
		{
			if (PlayerData.instance != null)
			{
				IDictionary runtimeData = QuestDataAccess.GetRuntimeData();
				if (runtimeData != null)
				{
					ModifyAllQuests(runtimeData, complete: true);
				}
			}
		}

		private static (IDictionary rt, object qd) EnsureQuestEntry(string name)
		{
			if (PlayerData.instance == null)
			{
				return (null, null);
			}
			IDictionary runtimeData = QuestDataAccess.GetRuntimeData();
			if (runtimeData == null)
			{
				return (null, null);
			}
			if (runtimeData.Contains(name))
			{
				return (runtimeData, runtimeData[name]);
			}
			object anyValue = GetAnyValue(runtimeData);
			if (anyValue == null)
			{
				return (null, null);
			}
			object item = (runtimeData[name] = QuestDataAccess.SetFields(anyValue, seen: false, accepted: false, completed: false, wasEver: false));
			QuestModPlugin.LogDebugInfo("Injected into RuntimeData: " + name);
			return (runtimeData, item);
		}

		private static void ModifyAllQuests(IDictionary rt, bool complete)
		{
			int num = 0;
			List<object> list = new List<object>();
			foreach (object key in rt.Keys)
			{
				list.Add(key);
			}
			foreach (string item in list)
			{
				if (IsChainPrereqMet(item))
				{
					object qd = rt[item];
					bool flag = QuestDataAccess.IsCompleted(qd);
					qd = QuestDataAccess.SetFields(qd, seen: true, accepted: true, complete || flag, complete || flag);
					rt[item] = qd;
					num++;
				}
			}
			string arg = (complete ? "Completed" : "Accepted");
			QuestModPlugin.Log.LogInfo((object)$"{arg} {num} quests");
		}

		public static bool IsChainStep(string name)
		{
			return QuestRegistry.ChainStepNames.Contains(name);
		}

		public static List<ChainInfo> GetChainList()
		{
			List<ChainInfo> list = new List<ChainInfo>();
			IDictionary runtimeData = QuestDataAccess.GetRuntimeData();
			foreach (KeyValuePair<string, string[]> item in QuestRegistry.ChainRegistry)
			{
				string key = item.Key;
				string[] value = item.Value;
				int num = -1;
				for (int num2 = value.Length - 1; num2 >= 0; num2--)
				{
					if (runtimeData != null && runtimeData.Contains(value[num2]))
					{
						object qd = runtimeData[value[num2]];
						if (QuestDataAccess.IsCompleted(qd))
						{
							num = num2;
							break;
						}
						if (QuestDataAccess.IsAccepted(qd))
						{
							num = num2;
							break;
						}
					}
				}
				string value2;
				string displayName = (QuestRegistry.ChainDisplayNames.TryGetValue(key, out value2) ? value2 : key);
				bool isFullyComplete = num == value.Length - 1 && runtimeData != null && runtimeData.Contains(value[num]) && QuestDataAccess.IsCompleted(runtimeData[value[num]]);
				list.Add(new ChainInfo
				{
					ChainName = key,
					DisplayName = displayName,
					Steps = value,
					CurrentStep = num,
					TotalSteps = value.Length,
					IsFullyComplete = isFullyComplete
				});
			}
			return list;
		}

		public static void AdvanceChain(string chainName)
		{
			if (!QuestRegistry.ChainRegistry.TryGetValue(chainName, out string[] value))
			{
				return;
			}
			IDictionary runtimeData = QuestDataAccess.GetRuntimeData();
			if (runtimeData == null)
			{
				return;
			}
			int num = -1;
			for (int num2 = value.Length - 1; num2 >= 0; num2--)
			{
				if (runtimeData.Contains(value[num2]))
				{
					object qd = runtimeData[value[num2]];
					if (QuestDataAccess.IsAccepted(qd) && !QuestDataAccess.IsCompleted(qd))
					{
						num = num2;
						break;
					}
					if (QuestDataAccess.IsCompleted(qd))
					{
						num = num2;
						break;
					}
				}
			}
			if (num >= 0 && !IsStepCompleted(runtimeData, value[num]))
			{
				CompleteQuest(value[num]);
				QuestModPlugin.Log.LogInfo((object)$"Chain '{chainName}': completed step {num + 1}/{value.Length} ({value[num]})");
			}
			int num3 = num + 1;
			if (num3 < value.Length)
			{
				AcceptQuest(value[num3]);
				QuestModPlugin.Log.LogInfo((object)$"Chain '{chainName}': accepted step {num3 + 1}/{value.Length} ({value[num3]})");
			}
		}

		public static void RewindChain(string chainName)
		{
			if (!QuestRegistry.ChainRegistry.TryGetValue(chainName, out string[] value))
			{
				return;
			}
			IDictionary runtimeData = QuestDataAccess.GetRuntimeData();
			if (runtimeData == null)
			{
				return;
			}
			int num = -1;
			for (int num2 = value.Length - 1; num2 >= 0; num2--)
			{
				if (runtimeData.Contains(value[num2]))
				{
					object qd = runtimeData[value[num2]];
					if (QuestDataAccess.IsAccepted(qd) || QuestDataAccess.IsCompleted(qd))
					{
						num = num2;
						break;
					}
				}
			}
			if (num >= 0)
			{
				if (!IsStepCompleted(runtimeData, value[num]))
				{
					UnacceptQuest(value[num]);
					QuestModPlugin.Log.LogInfo((object)$"Chain '{chainName}': unaccepted step {num + 1}/{value.Length} ({value[num]})");
				}
				else
				{
					UncompleteQuest(value[num]);
					QuestModPlugin.Log.LogInfo((object)$"Chain '{chainName}': uncompleted step {num + 1}/{value.Length} ({value[num]})");
				}
			}
		}

		private static bool IsStepCompleted(IDictionary rt, string name)
		{
			if (!rt.Contains(name))
			{
				return false;
			}
			return QuestDataAccess.IsCompleted(rt[name]);
		}

		private static object GetAnyValue(IDictionary dict)
		{
			IDictionaryEnumerator dictionaryEnumerator = dict.GetEnumerator();
			try
			{
				if (dictionaryEnumerator.MoveNext())
				{
					return ((DictionaryEntry)dictionaryEnumerator.Current).Value;
				}
			}
			finally
			{
				IDisposable disposable = dictionaryEnumerator as IDisposable;
				if (disposable != null)
				{
					disposable.Dispose();
				}
			}
			return null;
		}
	}
	public struct QuestTargetInfo
	{
		public string CounterName;

		public string DisplayName;

		public int CurrentCount;

		public int OriginalCount;

		public int TargetIndex;
	}
	public struct QuestOverrideInfo
	{
		public string QuestName;

		public string QuestTypeName;

		public int CompletedCount;

		public List<QuestTargetInfo> Targets;
	}
	public static class QuestCompletionOverrides
	{
		private static FieldInfo? targetsBackingField;

		private static FieldInfo? countField;

		private static Dictionary<string, int[]> originalCounts = new Dictionary<string, int[]>();

		private static Dictionary<string, int[]> overrideCounts = new Dictionary<string, int[]>();

		private static FullQuestBase[]? cachedQuests;

		public static bool IsInitialized { get; private set; }

		public static int GetMaxCap(string questName, int targetIndex)
		{
			if (QuestRegistry.MaxCaps.TryGetValue(questName, out int[] value) && targetIndex < value.Length)
			{
				return value[targetIndex];
			}
			return -1;
		}

		public static int ClampCount(string questName, int targetIndex, int value)
		{
			if (value < 0)
			{
				value = 0;
			}
			if (QuestModPlugin.DevRemoveLimits.Value)
			{
				return value;
			}
			int maxCap = GetMaxCap(questName, targetIndex);
			if (maxCap > 0 && value > maxCap)
			{
				value = maxCap;
			}
			return value;
		}

		public static int GetQoLCount(int originalCount)
		{
			return (originalCount + 1) / 2;
		}

		public static int GetFarmableCount(int originalCount)
		{
			int num = (originalCount + 1) / 2;
			if (num > 1 && num % 2 != 0)
			{
				num--;
			}
			return num;
		}

		public static void ApplyPresetAll(string preset)
		{
			if (!IsInitialized)
			{
				return;
			}
			if (cachedQuests == null)
			{
				CacheQuests();
			}
			if (cachedQuests == null || countField == null)
			{
				return;
			}
			FullQuestBase[] array = cachedQuests;
			for (int i = 0; i < array.Length; i++)
			{
				string text = ((Object)array[i]).name ?? "";
				if (QuestRegistry.QuestCategories.ContainsKey(text) && originalCounts.ContainsKey(text))
				{
					int[] array2 = originalCounts[text];
					for (int j = 0; j < array2.Length; j++)
					{
						SetTargetCount(text, j, preset switch
						{
							"set1" => 1, 
							"qol" => GetQoLCount(array2[j]), 
							"farmable" => (!QuestRegistry.FarmableExcluded.Contains(text)) ? GetFarmableCount(array2[j]) : array2[j], 
							_ => array2[j], 
						});
					}
				}
			}
			QuestModPlugin.LogDebugInfo("Applied preset '" + preset + "' to all quests");
		}

		public static string? GetCategory(string questName)
		{
			if (QuestRegistry.QuestCategories.TryGetValue(questName, out string value))
			{
				return value;
			}
			return null;
		}

		public static List<QuestOverrideInfo> GetQuestsByCategory(string category)
		{
			List<QuestOverrideInfo> allQuestsWithTargets = GetAllQuestsWithTargets();
			List<QuestOverrideInfo> list = new List<QuestOverrideInfo>();
			foreach (QuestOverrideInfo item in allQuestsWithTargets)
			{
				if (GetCategory(item.QuestName) == category)
				{
					list.Add(item);
				}
			}
			return list;
		}

		public static void Initialize()
		{
			Type type = typeof(FullQuestBase);
			while (type != null && type != typeof(Object))
			{
				foreach (FieldInfo declaredField in AccessTools.GetDeclaredFields(type))
				{
					if (declaredField.FieldType.IsArray && declaredField.FieldType.GetElementType()?.Name == "QuestTarget")
					{
						targetsBackingField = declaredField;
						countField = ReflectionCache.GetField(declaredField.FieldType.GetElementType(), "Count");
						QuestModPlugin.Log.LogInfo((object)("Found targets backing field: " + declaredField.Name + " on " + type.Name));
						break;
					}
				}
				if (targetsBackingField != null)
				{
					break;
				}
				type = type.BaseType;
			}
			if (targetsBackingField == null || countField == null)
			{
				QuestModPlugin.Log.LogWarning((object)"QuestCompletionOverrides: Could not find targets backing field");
				return;
			}
			IsInitialized = true;
			QuestModPlugin.Log.LogInfo((object)"QuestCompletionOverrides initialized");
		}

		internal static Array GetTargetsArray(FullQuestBase quest)
		{
			return targetsBackingField?.GetValue(quest) as Array;
		}

		public static void CacheQuests()
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			if (!IsInitialized)
			{
				return;
			}
			cachedQuests = Resources.FindObjectsOfTypeAll<FullQuestBase>();
			QuestModPlugin.Log.LogInfo((object)$"Cached {cachedQuests.Length} FullQuestBase objects");
			originalCounts.Clear();
			FullQuestBase[] array = cachedQuests;
			foreach (FullQuestBase obj in array)
			{
				string key = ((Object)obj).name ?? "";
				IReadOnlyList<QuestTarget> targets = obj.Targets;
				if (targets != null && targets.Count != 0)
				{
					int[] array2 = new int[targets.Count];
					for (int j = 0; j < targets.Count; j++)
					{
						array2[j] = targets[j].Count;
					}
					originalCounts[key] = array2;
				}
			}
		}

		public static List<QuestOverrideInfo> GetAllQuestsWithTargets()
		{
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			List<QuestOverrideInfo> list = new List<QuestOverrideInfo>();
			if (!IsInitialized)
			{
				return list;
			}
			if (cachedQuests == null)
			{
				CacheQuests();
			}
			if (cachedQuests == null || countField == null)
			{
				return list;
			}
			FullQuestBase[] array = cachedQuests;
			foreach (FullQuestBase val in array)
			{
				string text = ((Object)val).name ?? "";
				if (!QuestRegistry.QuestCategories.ContainsKey(text) || !QuestModPlugin.IsQuestDiscovered(text))
				{
					continue;
				}
				IReadOnlyList<QuestTarget> targets = val.Targets;
				if (targets == null || targets.Count == 0)
				{
					continue;
				}
				QuestOverrideInfo questOverrideInfo = default(QuestOverrideInfo);
				questOverrideInfo.QuestName = text;
				questOverrideInfo.QuestTypeName = ((object)val).GetType().Name;
				questOverrideInfo.CompletedCount = 0;
				questOverrideInfo.Targets = new List<QuestTargetInfo>();
				QuestOverrideInfo item = questOverrideInfo;
				IDictionary runtimeData = QuestDataAccess.GetRuntimeData();
				if (runtimeData != null && runtimeData.Contains(text))
				{
					object qd = runtimeData[text];
					item.CompletedCount = QuestDataAccess.GetCompletedCount(qd);
				}
				for (int j = 0; j < targets.Count; j++)
				{
					QuestTarget val2 = targets[j];
					int count = val2.Count;
					string text2 = ((object)val2.Counter)?.ToString() ?? "?";
					string displayName = text2;
					int originalCount = count;
					if (originalCounts.ContainsKey(text) && j < originalCounts[text].Length)
					{
						originalCount = originalCounts[text][j];
					}
					item.Targets.Add(new QuestTargetInfo
					{
						CounterName = text2,
						DisplayName = displayName,
						CurrentCount = count,
						OriginalCount = originalCount,
						TargetIndex = j
					});
				}
				list.Add(item);
			}
			return list;
		}

		public static bool SetTargetCount(string questName, int targetIndex, int newCount)
		{
			if (!IsInitialized)
			{
				return false;
			}
			if (cachedQuests == null)
			{
				CacheQuests();
			}
			if (cachedQuests == null || countField == null)
			{
				return false;
			}
			newCount = ClampCount(questName, targetIndex, newCount);
			FullQuestBase[] array = cachedQuests;
			foreach (FullQuestBase val in array)
			{
				if (((Object)val).name != questName)
				{
					continue;
				}
				Array targetsArray = GetTargetsArray(val);
				if (targetsArray == null || targetIndex >= targetsArray.Length)
				{
					return false;
				}
				object value = targetsArray.GetValue(targetIndex);
				countField.SetValue(value, newCount);
				targetsArray.SetValue(value, targetIndex);
				if (!overrideCounts.ContainsKey(questName))
				{
					int[] array2 = new int[targetsArray.Length];
					for (int j = 0; j < targetsArray.Length; j++)
					{
						object value2 = targetsArray.GetValue(j);
						array2[j] = (int)countField.GetValue(value2);
					}
					overrideCounts[questName] = array2;
				}
				else
				{
					overrideCounts[questName][targetIndex] = newCount;
				}
				QuestModSaveData saveData = QuestModPlugin.Instance.SaveData;
				if (saveData != null)
				{
					saveData.QuestTargetOverrides[$"{questName}:{targetIndex}"] = newCount;
				}
				QuestModPlugin.LogDebugInfo($"Set {questName} target[{targetIndex}] count to {newCount}");
				if (QuestRegistry.SharedTargetQuests.TryGetValue(questName, out string value3))
				{
					FullQuestBase[] array3 = cachedQuests;
					foreach (FullQuestBase val2 in array3)
					{
						if (((Object)val2).name != value3)
						{
							continue;
						}
						Array targetsArray2 = GetTargetsArray(val2);
						if (targetsArray2 == null || targetIndex >= targetsArray2.Length)
						{
							break;
						}
						object value4 = targetsArray2.GetValue(targetIndex);
						countField.SetValue(value4, newCount);
						targetsArray2.SetValue(value4, targetIndex);
						if (!overrideCounts.ContainsKey(value3))
						{
							int[] array4 = new int[targetsArray2.Length];
							for (int l = 0; l < targetsArray2.Length; l++)
							{
								object value5 = targetsArray2.GetValue(l);
								array4[l] = (int)countField.GetValue(value5);
							}
							overrideCounts[value3] = array4;
						}
						else
						{
							overrideCounts[value3][targetIndex] = newCount;
						}
						QuestModSaveData saveData2 = QuestModPlugin.Instance.SaveData;
						if (saveData2 != null)
						{
							saveData2.QuestTargetOverrides[$"{value3}:{targetIndex}"] = newCount;
						}
						break;
					}
				}
				return true;
			}
			return false;
		}

		public static void SetAllTargetCounts(string questName, int newCount)
		{
			if (!IsInitialized)
			{
				return;
			}
			if (cachedQuests == null)
			{
				CacheQuests();
			}
			if (cachedQuests == null || countField == null)
			{
				return;
			}
			FullQuestBase[] array = cachedQuests;
			foreach (FullQuestBase val in array)
			{
				if (((Object)val).name != questName)
				{
					continue;
				}
				Array targetsArray = GetTargetsArray(val);
				if (targetsArray != null)
				{
					for (int j = 0; j < targetsArray.Length; j++)
					{
						object value = targetsArray.GetValue(j);
						countField.SetValue(value, newCount);
						targetsArray.SetValue(value, j);
					}
					QuestModPlugin.LogDebugInfo($"Set all {targetsArray.Length} targets for {questName} to {newCount}");
				}
				break;
			}
		}

		public static void ResetToOriginal(string questName)
		{
			if (!IsInitialized || !originalCounts.ContainsKey(questName) || cachedQuests == null || countField == null)
			{
				return;
			}
			FullQuestBase[] array = cachedQuests;
			foreach (FullQuestBase val in array)
			{
				if (((Object)val).name != questName)
				{
					continue;
				}
				Array targetsArray = GetTargetsArray(val);
				if (targetsArray == null)
				{
					break;
				}
				int[] array2 = originalCounts[questName];
				for (int j = 0; j < targetsArray.Length && j < array2.Length; j++)
				{
					object value = targetsArray.GetValue(j);
					countField.SetValue(value, array2[j]);
					targetsArray.SetValue(value, j);
				}
				overrideCounts.Remove(questName);
				QuestModSaveData saveData = QuestModPlugin.Instance.SaveData;
				if (saveData != null)
				{
					List<string> list = new List<string>();
					foreach (string key in saveData.QuestTargetOverrides.Keys)
					{
						if (key.StartsWith(questName + ":"))
						{
							list.Add(key);
						}
					}
					foreach (string item in list)
					{
						saveData.QuestTargetOverrides.Remove(item);
					}
				}
				QuestModPlugin.LogDebugInfo("Reset " + questName + " to original counts");
				break;
			}
		}

		public static void ResetAll()
		{
			foreach (string item in new List<string>(originalCounts.Keys))
			{
				ResetToOriginal(item);
			}
		}

		public static void ApplySavedOverrides()
		{
			QuestModSaveData saveData = QuestModPlugin.Instance.SaveData;
			if (saveData == null || saveData.QuestTargetOverrides.Count == 0)
			{
				return;
			}
			if (cachedQuests == null)
			{
				CacheQuests();
			}
			int num = 0;
			foreach (KeyValuePair<string, int> questTargetOverride in saveData.QuestTargetOverrides)
			{
				string[] array = questTargetOverride.Key.Split(':');
				if (array.Length == 2)
				{
					string questName = array[0];
					if (int.TryParse(array[1], out var result) && SetTargetCount(questName, result, questTargetOverride.Value))
					{
						num++;
					}
				}
			}
			QuestModPlugin.Log.LogInfo((object)$"Applied {num} saved quest target overrides");
		}

		public static bool[] GetChecklistStatus(string questName)
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			if (!QuestRegistry.ChecklistQuests.ContainsKey(questName))
			{
				return new bool[0];
			}
			if (!IsInitialized || cachedQuests == null)
			{
				return new bool[QuestRegistry.ChecklistQuests[questName].Length];
			}
			FullQuestBase[] array = cachedQuests;
			foreach (FullQuestBase val in array)
			{
				if (!(((Object)val).name != questName))
				{
					IReadOnlyList<QuestTarget> targets = val.Targets;
					if (targets == null)
					{
						return new bool[QuestRegistry.ChecklistQuests[questName].Length];
					}
					bool[] array2 = new bool[targets.Count];
					for (int j = 0; j < targets.Count; j++)
					{
						array2[j] = targets[j].Count == 0;
					}
					return array2;
				}
			}
			return new bool[QuestRegistry.ChecklistQuests[questName].Length];
		}

		public static void ToggleChecklistTarget(string questName, int index, bool done)
		{
			SetTargetCount(questName, index, (!done) ? 1 : 0);
			if (!done && QuestRegistry.SequentialQuests.Contains(questName))
			{
				string[] array = QuestRegistry.ChecklistQuests[questName];
				for (int i = index + 1; i < array.Length; i++)
				{
					SetTargetCount(questName, i, 1);
				}
			}
		}
	}
	public static class SilkSoulOverrides
	{
		public struct PointEntry
		{
			public string QuestName;

			public float Value;

			public float DefaultValue;

			public int EntryIndex;
		}

		private static Type groupType;

		private static FieldInfo f_target;

		private static PropertyInfo p_currentValue;

		private static FieldInfo f_requiredCompleteTotalGroups;

		private static object cachedGroup;

		private static bool resolved;

		private static FieldInfo f_entries;

		private static FieldInfo f_entryQuest;

		private static FieldInfo f_entryValue;

		private static Array cachedEntries;

		private static bool entriesResolved;

		private static int? thresholdOverride;

		private static Dictionary<string, float> pointOverrides = new Dictionary<string, float>();

		public static bool HasEntries
		{
			get
			{
				if (cachedEntries != null && f_entryQuest != null)
				{
					return f_entryValue != null;
				}
				return false;
			}
		}

		public static bool TryResolve()
		{
			if (resolved)
			{
				return cachedGroup != null;
			}
			resolved = true;
			groupType = ReflectionCache.GetType("QuestCompleteTotalGroup");
			if (groupType == null)
			{
				return false;
			}
			f_target = ReflectionCache.GetField(groupType, "target");
			p_currentValue = ReflectionCache.GetProperty(groupType, "CurrentValueCount");
			Type type = ReflectionCache.GetType("FullQuestBase");
			if (type != null)
			{
				f_requiredCompleteTotalGroups = ReflectionCache.GetField(type, "requiredCompleteTotalGroups");
			}
			Type type2 = ReflectionCache.GetType("QuestManager");
			if (type2 == null)
			{
				return false;
			}
			MethodInfo methodInfo = AccessTools.Method(type2, "GetQuest", new Type[1] { typeof(string) }, (Type[])null);
			if (methodInfo == null)
			{
				return false;
			}
			object obj = methodInfo.Invoke(null, new object[1] { "Soul Snare Pre" });
			if (obj == null)
			{
				return false;
			}
			if (f_requiredCompleteTotalGroups != null && f_requiredCompleteTotalGroups.GetValue(obj) is Array array && array.Length > 0)
			{
				cachedGroup = array.GetValue(0);
				QuestModPlugin.Log.LogInfo((object)"SilkSoul: resolved CompleteTotalGroup");
				TryResolveEntries();
				return true;
			}
			QuestModPlugin.Log.LogWarning((object)"SilkSoul: could not resolve group from Soul Snare Pre");
			return false;
		}

		private static void TryResolveEntries()
		{
			if (entriesResolved || cachedGroup == null)
			{
				return;
			}
			entriesResolved = true;
			foreach (FieldInfo declaredField in AccessTools.GetDeclaredFields(groupType))
			{
				if (!declaredField.FieldType.IsArray || !(declaredField.GetValue(cachedGroup) is Array array) || array.Length == 0)
				{
					continue;
				}
				Type type = array.GetValue(0).GetType();
				FieldInfo fieldInfo = null;
				FieldInfo fieldInfo2 = null;
				foreach (FieldInfo declaredField2 in AccessTools.GetDeclaredFields(type))
				{
					if (declaredField2.FieldType.Name.Contains("Quest") || declaredField2.FieldType.Name.Contains("FullQuestBase"))
					{
						fieldInfo = declaredField2;
					}
					else if (declaredField2.FieldType == typeof(float) || declaredField2.FieldType == typeof(int))
					{
						fieldInfo2 = declaredField2;
					}
				}
				if (fieldInfo != null && fieldInfo2 != null)
				{
					f_entries = declaredField;
					f_entryQuest = fieldInfo;
					f_entryValue = fieldInfo2;
					cachedEntries = array;
					QuestModPlugin.Log.LogInfo((object)$"SilkSoul: resolved {array.Length} entries via field '{declaredField.Name}' (quest={fieldInfo.Name}, value={fieldInfo2.Name})");
					return;
				}
			}
			QuestModPlugin.Log.LogInfo((object)"SilkSoul: no entry array found — per-quest overrides not available");
		}

		public static List<PointEntry> GetPointEntries()
		{
			List<PointEntry> list = new List<PointEntry>();
			if (!HasEntries)
			{
				return list;
			}
			for (int i = 0; i < cachedEntries.Length; i++)
			{
				object value = cachedEntries.GetValue(i);
				object? value2 = f_entryQuest.GetValue(value);
				Object val = (Object)((value2 is Object) ? value2 : null);
				if (!(val == (Object)null))
				{
					string name = val.name;
					float num = ((!(f_entryValue.FieldType == typeof(float))) ? ((float)(int)f_entryValue.GetValue(value)) : ((float)f_entryValue.GetValue(value)));
					float defaultValue = (QuestRegistry.SilkSoulPointValues.ContainsKey(name) ? QuestRegistry.SilkSoulPointValues[name] : num);
					list.Add(new PointEntry
					{
						QuestName = name,
						Value = num,
						DefaultValue = defaultValue,
						EntryIndex = i
					});
				}
			}
			return list;
		}

		public static bool SetPointValue(int entryIndex, float value)
		{
			if (!HasEntries || entryIndex < 0 || entryIndex >= cachedEntries.Length)
			{
				return false;
			}
			object value2 = cachedEntries.GetValue(entryIndex);
			object? value3 = f_entryQuest.GetValue(value2);
			Object val = (Object)((value3 is Object) ? value3 : null);
			string text = ((val != (Object)null) ? val.name : "");
			object value4 = ((f_entryValue.FieldType == typeof(float)) ? ((object)value) : ((object)(int)value));
			ReflectionCache.WriteToArray(cachedEntries, entryIndex, value2, f_entryValue, value4);
			pointOverrides[text] = value;
			QuestModPlugin.LogDebugInfo($"SilkSoul: set {text} value to {value}");
			return true;
		}

		public static void ResetAllPointValues()
		{
			if (!HasEntries)
			{
				return;
			}
			for (int i = 0; i < cachedEntries.Length; i++)
			{
				object value = cachedEntries.GetValue(i);
				object? value2 = f_entryQuest.GetValue(value);
				Object val = (Object)((value2 is Object) ? value2 : null);
				if (!(val == (Object)null))
				{
					string name = val.name;
					if (QuestRegistry.SilkSoulPointValues.ContainsKey(name))
					{
						float num = QuestRegistry.SilkSoulPointValues[name];
						object value3 = ((f_entryValue.FieldType == typeof(float)) ? ((object)num) : ((object)(int)num));
						ReflectionCache.WriteToArray(cachedEntries, i, value, f_entryValue, value3);
					}
				}
			}
			pointOverrides.Clear();
		}

		public static int GetThreshold()
		{
			if (thresholdOverride.HasValue)
			{
				return thresholdOverride.Value;
			}
			return ReflectionCache.Read(cachedGroup, f_target, QuestRegistry.DefaultThreshold);
		}

		public static void SetThreshold(int value)
		{
			if (value < 0)
			{
				value = 0;
			}
			thresholdOverride = value;
			ReflectionCache.Write(cachedGroup, f_target, value);
			QuestModPlugin.LogDebugInfo($"SilkSoul: threshold set to {value}");
		}

		public static void ResetThreshold()
		{
			thresholdOverride = null;
			ReflectionCache.Write(cachedGroup, f_target, QuestRegistry.DefaultThreshold);
		}

		public static int GetCurrentPoints()
		{
			return ReflectionCache.Read(cachedGroup, p_currentValue, -1);
		}

		public static void Reset()
		{
			cachedGroup = null;
			cachedEntries = null;
			resolved = false;
			entriesResolved = false;
			thresholdOverride = null;
			pointOverrides.Clear();
		}
	}
	internal static class QuestDataAccess
	{
		private static readonly FieldInfo compField;

		private static readonly FieldInfo rtField;

		private static MemberInfo hasBeenSeenMember;

		private static MemberInfo isAcceptedMember;

		private static MemberInfo isCompletedMember;

		private static MemberInfo wasEverCompletedMember;

		private static MemberInfo completedCountMember;

		private static bool membersResolved;

		static QuestDataAccess()
		{
			compField = ReflectionCache.GetField(typeof(PlayerData), "QuestCompletionData");
			if (!(compField != null))
			{
				return;
			}
			rtField = ReflectionCache.GetField(compField.FieldType, "RuntimeData");
			if (rtField == null)
			{
				Type baseType = compField.FieldType.BaseType;
				while (baseType != null && rtField == null)
				{
					rtField = baseType.GetField("RuntimeData", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					baseType = baseType.BaseType;
				}
			}
		}

		private static void ResolveMembers(Type runtimeType)
		{
			if (!membersResolved)
			{
				hasBeenSeenMember = ReflectionCache.FindMember(runtimeType, "HasBeenSeen");
				isAcceptedMember = ReflectionCache.FindMember(runtimeType, "IsAccepted");
				isCompletedMember = ReflectionCache.FindMember(runtimeType, "IsCompleted");
				wasEverCompletedMember = ReflectionCache.FindMember(runtimeType, "WasEverCompleted");
				completedCountMember = ReflectionCache.FindMember(runtimeType, "CompletedCount");
				membersResolved = true;
				QuestModPlugin.LogDebugInfo("QuestDataAccess resolved members on runtime type " + runtimeType.FullName + ":");
				QuestModPlugin.LogDebugInfo("  HasBeenSeen=" + ReflectionCache.MemberTag(hasBeenSeenMember) + ", IsAccepted=" + ReflectionCache.MemberTag(isAcceptedMember) + ", IsCompleted=" + ReflectionCache.MemberTag(isCompletedMember) + ", WasEverCompleted=" + ReflectionCache.MemberTag(wasEverCompletedMember) + ", CompletedCount=" + ReflectionCache.MemberTag(completedCountMember));
			}
		}

		internal static IDictionary GetRuntimeData()
		{
			if (compField == null)
			{
				return null;
			}
			if (rtField == null)
			{
				return null;
			}
			if (PlayerData.instance == null)
			{
				return null;
			}
			object value = compField.GetValue(PlayerData.instance);
			if (value == null)
			{
				return null;
			}
			return rtField.GetValue(value) as IDictionary;
		}

		internal static bool IsAccepted(object qd)
		{
			if (qd == null)
			{
				return false;
			}
			if (!membersResolved)
			{
				ResolveMembers(qd.GetType());
			}
			return (bool)(ReflectionCache.ReadMember(isAcceptedMember, qd) ?? ((object)false));
		}

		internal static bool IsCompleted(object qd)
		{
			if (qd == null)
			{
				return false;
			}
			if (!membersResolved)
			{
				ResolveMembers(qd.GetType());
			}
			return (bool)(ReflectionCache.ReadMember(isCompletedMember, qd) ?? ((object)false));
		}

		internal static bool HasBeenSeen(object qd)
		{
			if (qd == null)
			{
				return false;
			}
			if (!membersResolved)
			{
				ResolveMembers(qd.GetType());
			}
			return (bool)(ReflectionCache.ReadMember(hasBeenSeenMember, qd) ?? ((object)false));
		}

		internal static int GetCompletedCount(object qd)
		{
			if (qd == null)
			{
				return 0;
			}
			if (!membersResolved)
			{
				ResolveMembers(qd.GetType());
			}
			return (int)(ReflectionCache.ReadMember(completedCountMember, qd) ?? ((object)0));
		}

		internal static object SetFields(object qd, bool seen, bool accepted, bool completed, bool wasEver)
		{
			if (qd == null)
			{
				return qd;
			}
			if (!membersResolved)
			{
				ResolveMembers(qd.GetType());
			}
			ReflectionCache.WriteMember(hasBeenSeenMember, qd, seen);
			ReflectionCache.WriteMember(isAcceptedMember, qd, accepted);
			ReflectionCache.WriteMember(isCompletedMember, qd, completed);
			ReflectionCache.WriteMember(wasEverCompletedMember, qd, wasEver);
			return qd;
		}
	}
	public class QuestModSaveData
	{
		public HashSet<string> InjectedQuests { get; set; } = new HashSet<string>();


		public HashSet<string> CompletedQuests { get; set; } = new HashSet<string>();


		public Dictionary<string, int> QuestTargetOverrides { get; set; } = new Dictionary<string, int>();


		public bool AllQuestsAvailable { get; set; }

		public bool AllQuestsAccepted { get; set; }
	}
	public static class QuestRegistry
	{
		public static HashSet<string> ExcludedQuests { get; private set; } = new HashSet<string>();


		public static Dictionary<string, string[]> ChainRegistry { get; private set; } = new Dictionary<string, string[]>();


		public static Dictionary<string, string> ChainDisplayNames { get; private set; } = new Dictionary<string, string>();


		public static HashSet<string> ChainStepNames { get; private set; } = new HashSet<string>();


		public static Dictionary<string, string> MutuallyExclusiveQuests { get; private set; } = new Dictionary<string, string>();


		public static Dictionary<string, string> SharedTargetQuests { get; private set; } = new Dictionary<string, string>();


		public static Dictionary<string, string> DisplayNames { get; private set; } = new Dictionary<string, string>();


		public static Dictionary<string, string> QuestCategories { get; private set; } = new Dictionary<string, string>();


		public static string[] Categories { get; private set; } = Array.Empty<string>();


		public static Dictionary<string, int[]> MaxCaps { get; private set; } = new Dictionary<string, int[]>();


		public static Dictionary<string, string[]> ChecklistQuests { get; private set; } = new Dictionary<string, string[]>();


		public static HashSet<string> SequentialQuests { get; private set; } = new HashSet<string>();


		public static HashSet<string> FarmableExcluded { get; private set; } = new HashSet<string>();


		public static int DefaultThreshold { get; private set; } = 17;


		public static Dictionary<string, float> SilkSoulPointValues { get; private set; } = new Dictionary<string, float>();


		public static string[] SilkSoulRequiredQuests { get; private set; } = Array.Empty<string>();


		public static bool IsLoaded { get; private set; }

		public static void Load()
		{
			if (IsLoaded)
			{
				return;
			}
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string text = "QuestMod.Data.QuestCapabilities.json";
			using Stream stream = executingAssembly.GetManifestResourceStream(text);
			if (stream == null)
			{
				QuestModPlugin.Log.LogError((object)("Failed to load embedded resource: " + text));
				return;
			}
			using StreamReader streamReader = new StreamReader(stream);
			JObject root = JObject.Parse(streamReader.ReadToEnd());
			LoadExcluded(root);
			LoadFarmableExclude(root);
			LoadMutuallyExclusive(root);
			LoadSharedTargets(root);
			LoadSilkSoul(root);
			LoadMaxCaps(root);
			LoadChecklist(root);
			LoadChains(root);
			LoadCategories(root);
			IsLoaded = true;
			QuestModPlugin.Log.LogInfo((object)$"QuestRegistry loaded: {DisplayNames.Count} quests, {ChainRegistry.Count} chains, {ChecklistQuests.Count} checklists, {MaxCaps.Count} max caps");
		}

		private static void LoadExcluded(JObject root)
		{
			JToken obj = root["excluded"];
			JArray val = (JArray)(object)((obj is JArray) ? obj : null);
			if (val == null)
			{
				return;
			}
			foreach (JToken item in val)
			{
				string text = Extensions.Value<string>((IEnumerable<JToken>)item);
				if (text != null)
				{
					ExcludedQuests.Add(text);
				}
			}
		}

		private static void LoadFarmableExclude(JObject root)
		{
			JToken obj = root["farmableExclude"];
			JArray val = (JArray)(object)((obj is JArray) ? obj : null);
			if (val == null)
			{
				return;
			}
			foreach (JToken item in val)
			{
				string text = Extensions.Value<string>((IEnumerable<JToken>)item);
				if (text != null)
				{
					FarmableExcluded.Add(text);
				}
			}
		}

		private static void LoadMutuallyExclusive(JObject root)
		{
			JToken obj = root["mutuallyExclusive"];
			JObject val = (JObject)(object)((obj is JObject) ? obj : null);
			if (val == null)
			{
				return;
			}
			foreach (KeyValuePair<string, JToken> item in val)
			{
				JToken value = item.Value;
				string text = ((value != null) ? Extensions.Value<string>((IEnumerable<JToken>)value) : null);
				if (text != null)
				{
					MutuallyExclusiveQuests[item.Key] = text;
				}
			}
		}

		private static void LoadSharedTargets(JObject root)
		{
			JToken obj = root["sharedTargets"];
			JObject val = (JObject)(object)((obj is JObject) ? obj : null);
			if (val == null)
			{
				return;
			}
			foreach (KeyValuePair<string, JToken> item in val)
			{
				JToken value = item.Value;
				string text = ((value != null) ? Extensions.Value<string>((IEnumerable<JToken>)value) : null);
				if (text != null)
				{
					SharedTargetQuests[item.Key] = text;
				}
			}
		}

		private static void LoadSilkSoul(JObject root)
		{
			JToken obj = root["silkSoul"];
			JObject val = (JObject)(object)((obj is JObject) ? obj : null);
			if (val == null)
			{
				return;
			}
			JToken val2 = val["defaultThreshold"];
			if (val2 != null)
			{
				DefaultThreshold = Extensions.Value<int>((IEnumerable<JToken>)val2);
			}
			JToken obj2 = val["requiredQuests"];
			JArray val3 = (JArray)(object)((obj2 is JArray) ? obj2 : null);
			if (val3 != null)
			{
				List<string> list = new List<string>();
				foreach (JToken item in val3)
				{
					string text = Extensions.Value<string>((IEnumerable<JToken>)item);
					if (text != null)
					{
						list.Add(text);
					}
				}
				SilkSoulRequiredQuests = list.ToArray();
			}
			JToken obj3 = val["pointValues"];
			JObject val4 = (JObject)(object)((obj3 is JObject) ? obj3 : null);
			if (val4 == null)
			{
				return;
			}
			foreach (KeyValuePair<string, JToken> item2 in val4)
			{
				SilkSoulPointValues[item2.Key] = Extensions.Value<float>((IEnumerable<JToken>)item2.Value);
			}
		}

		private static void LoadMaxCaps(JObject root)
		{
			JToken obj = root["maxCaps"];
			JObject val = (JObject)(object)((obj is JObject) ? obj : null);
			if (val == null)
			{
				return;
			}
			foreach (KeyValuePair<string, JToken> item in val)
			{
				JToken value = item.Value;
				JArray val2 = (JArray)(object)((value is JArray) ? value : null);
				if (val2 == null)
				{
					continue;
				}
				List<int> list = new List<int>();
				foreach (JToken item2 in val2)
				{
					list.Add(Extensions.Value<int>((IEnumerable<JToken>)item2));
				}
				MaxCaps[item.Key] = list.ToArray();
			}
		}

		private static void LoadChecklist(JObject root)
		{
			JToken obj = root["checklist"];
			JObject val = (JObject)(object)((obj is JObject) ? obj : null);
			if (val != null)
			{
				foreach (KeyValuePair<string, JToken> item in val)
				{
					JToken value = item.Value;
					JArray val2 = (JArray)(object)((value is JArray) ? value : null);
					if (val2 == null)
					{
						continue;
					}
					List<string> list = new List<string>();
					foreach (JToken item2 in val2)
					{
						string text = Extensions.Value<string>((IEnumerable<JToken>)item2);
						if (text != null)
						{
							list.Add(text);
						}
					}
					ChecklistQuests[item.Key] = list.ToArray();
				}
			}
			JToken obj2 = root["sequentialQuests"];
			JArray val3 = (JArray)(object)((obj2 is JArray) ? obj2 : null);
			if (val3 == null)
			{
				return;
			}
			foreach (JToken item3 in val3)
			{
				string text2 = Extensions.Value<string>((IEnumerable<JToken>)item3);
				if (text2 != null)
				{
					SequentialQuests.Add(text2);
				}
			}
		}

		private static void LoadChains(JObject root)
		{
			JToken obj = root["chains"];
			JObject val = (JObject)(object)((obj is JObject) ? obj : null);
			if (val == null)
			{
				return;
			}
			foreach (KeyValuePair<string, JToken> item in val)
			{
				string key = item.Key;
				JToken value = item.Value;
				JObject val2 = (JObject)(object)((value is JObject) ? value : null);
				if (val2 == null)
				{
					continue;
				}
				JToken obj2 = val2["display"];
				string text = ((obj2 != null) ? Extensions.Value<string>((IEnumerable<JToken>)obj2) : null);
				if (text != null)
				{
					ChainDisplayNames[key] = text;
				}
				JToken obj3 = val2["steps"];
				JArray val3 = (JArray)(object)((obj3 is JArray) ? obj3 : null);
				if (val3 == null)
				{
					continue;
				}
				List<string> list = new List<string>();
				foreach (JToken item2 in val3)
				{
					string text2 = Extensions.Value<string>((IEnumerable<JToken>)item2);
					if (text2 != null)
					{
						list.Add(text2);
						ChainStepNames.Add(text2);
					}
				}
				ChainRegistry[key] = list.ToArray();
			}
		}

		private static void LoadCategories(JObject root)
		{
			JToken obj = root["categories"];
			JObject val = (JObject)(object)((obj is JObject) ? obj : null);
			if (val == null)
			{
				return;
			}
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, JToken> item in val)
			{
				string key = item.Key;
				if (key == "Main Story")
				{
					continue;
				}
				list.Add(key);
				JToken value = item.Value;
				JObject val2 = (JObject)(object)((value is JObject) ? value : null);
				if (val2 == null)
				{
					continue;
				}
				foreach (KeyValuePair<string, JToken> item2 in val2)
				{
					string key2 = item2.Key;
					JToken value2 = item2.Value;
					LoadQuest(key2, (JObject?)(object)((value2 is JObject) ? value2 : null), key);
				}
			}
			JToken obj2 = val["Main Story"];
			JObject val3 = (JObject)(object)((obj2 is JObject) ? obj2 : null);
			if (val3 != null)
			{
				foreach (KeyValuePair<string, JToken> item3 in val3)
				{
					string key3 = item3.Key;
					JToken value3 = item3.Value;
					LoadQuest(key3, (JObject?)(object)((value3 is JObject) ? value3 : null), null);
				}
			}
			Categories = list.ToArray();
		}

		private static void LoadQuest(string questName, JObject? questObj, string? categoryName)
		{
			if (categoryName != null)
			{
				QuestCategories[questName] = categoryName;
			}
			if (questObj != null)
			{
				JToken obj = questObj["display"];
				string text = ((obj != null) ? Extensions.Value<string>((IEnumerable<JToken>)obj) : null);
				if (text != null)
				{
					DisplayNames[questName] = text;
				}
			}
		}
	}
	public class QuestGUI : MonoBehaviour
	{
		private bool show;

		private Vector2 questScroll;

		private Vector2 overrideScroll;

		private Rect rect = new Rect(20f, 20f, 580f, 580f);

		private int tab;

		private string[] tabs;

		private Action[] tabDrawers;

		private int categoryTab;

		private Dictionary<string, string> countInputs = new Dictionary<string, string>();

		private Dictionary<string, List<QuestOverrideInfo>> cachedByCategory = new Dictionary<string, List<QuestOverrideInfo>>();

		private float multiplier = 1f;

		private string multiplierText = "1.0";

		private Vector2 checklistScroll;

		private List<QuestInfo> cachedQuestList;

		private bool questListDirty = true;

		private Vector2 silkSoulScroll;

		private string thresholdInput = "";

		private Dictionary<string, string> pointInputs = new Dictionary<string, string>();

		private List<ChainInfo> cachedChainList;

		private List<QuestInfo> undoSnapshot;

		private void DrawChecklistTab()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (!QuestCompletionOverrides.IsInitialized)
			{
				GUILayout.Label("Not initialized - load a save first", Array.Empty<GUILayoutOption>());
				return;
			}
			checklistScroll = GUILayout.BeginScrollView(checklistScroll, Array.Empty<GUILayoutOption>());
			foreach (KeyValuePair<string, string[]> checklistQuest in QuestRegistry.ChecklistQuests)
			{
				string key = checklistQuest.Key;
				string[] value = checklistQuest.Value;
				bool flag = QuestRegistry.SequentialQuests.Contains(key);
				bool[] checklistStatus = QuestCompletionOverrides.GetChecklistStatus(key);
				int num = 0;
				for (int i = 0; i < checklistStatus.Length; i++)
				{
					if (checklistStatus[i])
					{
						num++;
					}
				}
				GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
				string text = (flag ? " (sequential)" : "");
				GUILayout.Label($"{key}{text}  ({num}/{value.Length})", GUI.skin.label, Array.Empty<GUILayoutOption>());
				for (int j = 0; j < value.Length && j < checklistStatus.Length; j++)
				{
					bool flag2 = checklistStatus[j];
					bool flag3 = true;
					if (flag && !flag2)
					{
						int num2 = -1;
						for (int k = 0; k < checklistStatus.Length; k++)
						{
							if (!checklistStatus[k])
							{
								num2 = k;
								break;
							}
						}
						flag3 = j == num2;
					}
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					GUILayout.Space(12f);
					string text2 = (flag2 ? "■" : "□") + " " + value[j];
					if (flag3)
					{
						if (GUILayout.Button(text2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
						{
							int index = j;
							QuestCompletionOverrides.ToggleChecklistTarget(key, index, !flag2);
						}
					}
					else
					{
						GUI.enabled = false;
						GUILayout.Button(text2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
						GUI.enabled = true;
					}
					GUILayout.EndHorizontal();
				}
				GUILayout.EndVertical();
				GUILayout.Space(3f);
			}
			GUILayout.EndScrollView();
		}

		private void Update()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = QuestModPlugin.GuiToggleKey.Value;
			if (!((KeyboardShortcut)(ref value)).IsDown())
			{
				return;
			}
			show = !show;
			if (show)
			{
				questListDirty = true;
				if (tab == 1)
				{
					RefreshOverrides();
				}
			}
		}

		private float GetGuiScale()
		{
			float value = QuestModPlugin.GuiScale.Value;
			if (value > 0f)
			{
				return Mathf.Round(value * 20f) / 20f;
			}
			float dpi = Screen.dpi;
			if (dpi <= 0f)
			{
				return 1f;
			}
			return Mathf.Round(Mathf.Clamp(dpi / 96f, 0.5f, 3f) * 20f) / 20f;
		}

		private void OnGUI()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			if (show)
			{
				float guiScale = GetGuiScale();
				Matrix4x4 matrix = GUI.matrix;
				GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(guiScale, guiScale, 1f));
				GUI.skin = QuestGUISkin.Get();
				KeyboardShortcut value = QuestModPlugin.GuiToggleKey.Value;
				KeyCode mainKey = ((KeyboardShortcut)(ref value)).MainKey;
				string text = ((object)(KeyCode)(ref mainKey)).ToString();
				Version version = typeof(QuestModPlugin).Assembly.GetName().Version;
				rect = GUI.Window(12345, rect, new WindowFunction(Draw), $"Quest Manager ({text}) v{version.Major}.{version.Minor}.{version.Build}");
				GUI.matrix = matrix;
			}
		}

		private void RefreshOverrides()
		{
			cachedByCategory.Clear();
			string[] categories = QuestRegistry.Categories;
			foreach (string text in categories)
			{
				cachedByCategory[text] = QuestCompletionOverrides.GetQuestsByCategory(text);
			}
		}

		private void Draw(int id)
		{
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Expected O, but got Unknown
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: 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_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			RebuildTabs();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			for (int i = 0; i < tabs.Length; i++)
			{
				GUIStyle val = ((i == tab) ? GUI.skin.GetStyle("ToolbarButtonActive") : GUI.skin.GetStyle("ToolbarButton"));
				if (GUILayout.Button(tabs[i], val, Array.Empty<GUILayoutOption>()))
				{
					if (i != tab && tabs[i] == "Targets")
					{
						RefreshOverrides();
					}
					tab = i;
				}
			}
			GUILayout.EndHorizontal();
			if (tab >= tabs.Length)
			{
				tab = 0;
			}
			GUILayout.Space(6f);
			tabDrawers[tab]();
			if (!string.IsNullOrEmpty(GUI.tooltip))
			{
				Vector2 mousePosition = Event.current.mousePosition;
				GUIContent val2 = new GUIContent(GUI.tooltip);
				Vector2 val3 = QuestGUISkin.TooltipStyle.CalcSize(val2);
				val3.x = Mathf.Min(val3.x, 280f);
				val3.y = QuestGUISkin.TooltipStyle.CalcHeight(val2, val3.x);
				float num = Mathf.Min(mousePosition.x + 12f, ((Rect)(ref rect)).width - val3.x - 10f);
				float num2 = Mathf.Min(mousePosition.y + 18f, ((Rect)(ref rect)).height - val3.y - 10f);
				GUI.Label(new Rect(num, num2, val3.x, val3.y), val2, QuestGUISkin.TooltipStyle);
			}
			GUI.DragWindow();
		}

		private void RebuildTabs()
		{
			List<string> list = new List<string> { "Quests", "Targets", "Checklist" };
			List<Action> list2 = new List<Action> { DrawQuestsTab, DrawCompletionTab, DrawChecklistTab };
			if (QuestModPlugin.EnableSilkSoulTab.Value)
			{
				list.Add("Silk & Soul");
				list2.Add(DrawSilkSoulTab);
			}
			list.Add("⚙ Tools");
			list2.Add(DrawToolsTab);
			tabs = list.ToArray();
			tabDrawers = list2.ToArray();
		}

		private void DrawQuestsTab()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Expected O, but got Unknown
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Expected O, but got Unknown
			if (questListDirty)
			{
				cachedQuestList = QuestAcceptance.GetQuestList();
				cachedChainList = QuestAcceptance.GetChainList();
				questListDirty = false;
			}
			questScroll = GUILayout.BeginScrollView(questScroll, Array.Empty<GUILayoutOption>());
			if (cachedChainList != null)
			{
				GUILayout.Label("Chains", QuestGUISkin.SectionHeader, Array.Empty<GUILayoutOption>());
				foreach (ChainInfo cachedChain in cachedChainList)
				{
					GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					string text;
					string text2;
					if (cachedChain.IsFullyComplete)
					{
						text = "Complete";
						text2 = "✓";
					}
					else if (cachedChain.CurrentStep < 0)
					{
						text = "Not started";
						text2 = "○";
					}
					else
					{
						string displayName = QuestAcceptance.GetDisplayName(cachedChain.Steps[cachedChain.CurrentStep]);
						text = $"Step {cachedChain.CurrentStep + 1}/{cachedChain.TotalSteps}: {displayName}";
						text2 = "◐";
					}
					string text3 = (QuestModPlugin.ShowQuestDisplayNames.Value ? cachedChain.DisplayName : cachedChain.ChainName);
					GUILayout.Label(new GUIContent(text2 + " " + text3, cachedChain.ChainName), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(200f) });
					GUILayout.Label(text, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) });
					GUILayout.FlexibleSpace();
					GUI.enabled = cachedChain.CurrentStep >= 0;
					if (GUILayout.Button("◀", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(25f) }))
					{
						QuestAcceptance.RewindChain(cachedChain.ChainName);
						questListDirty = true;
					}
					GUI.enabled = !cachedChain.IsFullyComplete;
					if (GUILayout.Button("▶", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(25f) }))
					{
						QuestAcceptance.AdvanceChain(cachedChain.ChainName);
						questListDirty = true;
					}
					GUI.enabled = true;
					GUILayout.EndHorizontal();
					GUILayout.EndVertical();
				}
			}
			if (cachedQuestList != null)
			{
				GUILayout.Space(6f);
				GUILayout.Label("Quests", QuestGUISkin.SectionHeader, Array.Empty<GUILayoutOption>());
				foreach (QuestInfo cachedQuest in cachedQuestList)
				{
					if (!QuestAcceptance.IsChainStep(cachedQuest.Name))
					{
						string obj = (cachedQuest.IsCompleted ? "✓" : (cachedQuest.IsAccepted ? "◐" : "○"));
						GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
						string text4 = (QuestModPlugin.ShowQuestDisplayNames.Value ? cachedQuest.DisplayName : cachedQuest.Name);
						GUILayout.Label(new GUIContent(obj + " " + text4, cachedQuest.Name), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(260f) });
						GUILayout.FlexibleSpace();
						if (!cachedQuest.IsAccepted && GUILayout.Button("Accept", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) }))
						{
							QuestAcceptance.AcceptQuest(cachedQuest.Name);
							questListDirty = true;
						}
						if (cachedQuest.IsAccepted && !cachedQuest.IsCompleted && GUILayout.Button("Drop", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(45f) }))
						{
							QuestAcceptance.UnacceptQuest(cachedQuest.Name);
							questListDirty = true;
						}
						if (cachedQuest.IsAccepted && !cachedQuest.IsCompleted && GUILayout.Button("Complete", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(65f) }))
						{
							QuestAcceptance.CompleteQuest(cachedQuest.Name);
							questListDirty = true;
						}
						if (cachedQuest.IsCompleted && GUILayout.Button("Undo", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }))
						{
							QuestAcceptance.UncompleteQuest(cachedQuest.Name);
							questListDirty = true;
						}
						GUILayout.EndHorizontal();
					}
				}
			}
			GUILayout.EndScrollView();
		}

		private void DrawSilkSoulTab()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_05df: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f5: 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_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0773: Unknown result type (might be due to invalid IL or missing references)
			//IL_0778: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0784: Unknown result type (might be due to invalid IL or missing references)
			//IL_077d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0815: Unknown result type (might be due to invalid IL or missing references)
			if (!SilkSoulOverrides.TryResolve())
			{
				GUILayout.Label("Silk & Soul data not available (load a save first)", Array.Empty<GUILayoutOption>());
				return;
			}
			int currentPoints = SilkSoulOverrides.GetCurrentPoints();
			int threshold = SilkSoulOverrides.GetThreshold();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Quest Points:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) });
			Color color = GUI.color;
			GUI.color = ((currentPoints >= threshold) ? Color.green : Color.white);
			GUILayout.Label($"{currentPoints} / {threshold}", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) });
			GUI.color = color;
			GUILayout.EndHorizontal();
			GUILayout.Space(3f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(new GUIContent("Threshold:", "Number of points needed to unlock Silk & Soul quest"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) });
			if (GUILayout.Button("−", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(22f) }))
			{
				SilkSoulOverrides.SetThreshold(threshold - 1);
				thresholdInput = (threshold - 1).ToString();
			}
			if (thresholdInput == "")
			{
				thresholdInput = threshold.ToString();
			}
			thresholdInput = GUILayout.TextField(thresholdInput, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) });
			if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(22f) }))
			{
				SilkSoulOverrides.SetThreshold(threshold + 1);
				thresholdInput = (threshold + 1).ToString();
			}
			if (GUILayout.Button("Set", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(32f) }) && int.TryParse(thresholdInput, out var result))
			{
				SilkSoulOverrides.SetThreshold(result);
			}
			if (GUILayout.Button("Reset", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(48f) }))
			{
				SilkSoulOverrides.ResetThreshold();
				thresholdInput = QuestRegistry.DefaultThreshold.ToString();
			}
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			if (threshold != QuestRegistry.DefaultThreshold)
			{
				GUILayout.Label($"  (default: {QuestRegistry.DefaultThreshold})", Array.Empty<GUILayoutOption>());
			}
			GUILayout.Space(4f);
			if (SilkSoulOverrides.HasEntries)
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				if (GUILayout.Button("Reset All Values", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) }))
				{
					SilkSoulOverrides.ResetAllPointValues();
					pointInputs.Clear();
				}
				if (GUILayout.Button("Set All to 0", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }))
				{
					foreach (SilkSoulOverrides.PointEntry pointEntry in SilkSoulOverrides.GetPointEntries())
					{
						SilkSoulOverrides.SetPointValue(pointEntry.EntryIndex, 0f);
						pointInputs[pointEntry.QuestName] = "0";
					}
				}
				GUILayout.FlexibleSpace();
				GUILayout.EndHorizontal();
			}
			GUILayout.Space(5f);
			silkSoulScroll = GUILayout.BeginScrollView(silkSoulScroll, Array.Empty<GUILayoutOption>());
			IDictionary runtimeData = QuestDataAccess.GetRuntimeData();
			if (SilkSoulOverrides.HasEntries)
			{
				List<SilkSoulOverrides.PointEntry> pointEntries = SilkSoulOverrides.GetPointEntries();
				GUILayout.Label("Quest Point Values (editable)", QuestGUISkin.SectionHeader, Array.Empty<GUILayoutOption>());
				foreach (SilkSoulOverrides.PointEntry item in pointEntries)
				{
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					bool num = runtimeData != null && runtimeData.Contains(item.QuestName) && QuestDataAccess.IsCompleted(runtimeData[item.QuestName]);
					Color color2 = GUI.color;
					GUI.color = (num ? Color.green : Color.white);
					string displayName = QuestAcceptance.GetDisplayName(item.QuestName);
					GUILayout.Label(num ? "✓" : "✗", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(14f) });
					GUILayout.Label(displayName, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(200f) });
					GUI.color = color2;
					string questName = item.QuestName;
					if (!pointInputs.ContainsKey(questName))
					{
						pointInputs[questName] = item.Value.ToString("0.##");
					}
					pointInputs[questName] = GUILayout.TextField(pointInputs[questName], (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) });
					if (GUILayout.Button("Set", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(32f) }) && float.TryParse(pointInputs[questName], out var result2))
					{
						SilkSoulOverrides.SetPointValue(item.EntryIndex, result2);
					}
					if (!(Math.Abs(item.Value - item.DefaultValue) < 0.01f))
					{
						GUI.color = Color.yellow;
						GUILayout.Label($"({item.DefaultValue:0.##})", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) });
						GUI.color = color2;
					}
					GUILayout.EndHorizontal();
				}
			}
			else
			{
				int num2 = 0;
				int num3 = QuestRegistry.SilkSoulRequiredQuests.Length;
				string[] silkSoulRequiredQuests = QuestRegistry.SilkSoulRequiredQuests;
				foreach (string key in silkSoulRequiredQuests)
				{
					if (runtimeData != null && runtimeData.Contains(key) && QuestDataAccess.IsCompleted(runtimeData[key]))
					{
						num2++;
					}
				}
				int num4 = 0;
				int count = QuestRegistry.SilkSoulPointValues.Count;
				foreach (KeyValuePair<string, float> silkSoulPointValue in QuestRegistry.SilkSoulPointValues)
				{
					if (runtimeData != null && runtimeData.Contains(silkSoulPointValue.Key) && QuestDataAccess.IsCompleted(runtimeData[silkSoulPointValue.Key]))
					{
						num4++;
					}
				}
				Color color3 = GUI.color;
				GUI.color = new Color(0.7f, 0.8f, 0.95f);
				GUILayout.Label($"Required: {num2}/{num3}  |  Optional: {num4}/{count}", Array.Empty<GUILayoutOption>());
				GUI.color = color3;
				GUILayout.Space(3f);
				GUILayout.Label("Required Quests", QuestGUISkin.SectionHeader, Array.Empty<GUILayoutOption>());
				silkSoulRequiredQuests = QuestRegistry.SilkSoulRequiredQuests;
				foreach (string text in silkSoulRequiredQuests)
				{
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					bool num5 = runtimeData != null && runtimeData.Contains(text) && QuestDataAccess.IsCompleted(runtimeData[text]);
					Color color4 = GUI.color;
					GUI.color = (num5 ? Color.green : Color.white);
					string displayName2 = QuestAcceptance.GetDisplayName(text);
					GUILayout.Label(num5 ? ("  ✓ " + displayName2) : ("  ✗ " + displayName2), Array.Empty<GUILayoutOption>());
					GUI.color = color4;
					GUILayout.EndHorizontal();
				}
				GUILayout.Space(5f);
				GUILayout.Label("Optional Quests (contribute points)", QuestGUISkin.SectionHeader, Array.Empty<GUILayoutOption>());
				foreach (KeyValuePair<string, float> silkSoulPointValue2 in QuestRegistry.SilkSoulPointValues)
				{
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					bool num6 = runtimeData != null && runtimeData.Contains(silkSoulPointValue2.Key) && QuestDataAccess.IsCompleted(runtimeData[silkSoulPointValue2.Key]);
					Color color5 = GUI.color;
					GUI.color = (num6 ? Color.green : Color.white);
					string displayName3 = QuestAcceptance.GetDisplayName(silkSoulPointValue2.Key);
					string text2 = ((silkSoulPointValue2.Value == 1f) ? "1 pt" : "0.5 pt");
					GUILayout.Label(num6 ? ("  ✓ " + displayName3) : ("  ✗ " + displayName3), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(250f) });
					GUILayout.Label("[" + text2 + "]", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
					GUI.color = color5;
					GUILayout.EndHorizontal();
				}
			}
			GUILayout.EndScrollView();
		}

		private void DrawCompletionTab()
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Expected O, but got Unknown
			//IL_0454: Unknown result type (might be due to invalid IL or missing references)
			//IL_045e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0463: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0421: Unknown result type (might be due to invalid IL or missing references)
			//IL_0518: Unknown result type (might be due to invalid IL or missing references)
			//IL_0535: Expected O, but got Unknown
			//IL_0535: Unknown result type (might be due to invalid IL or missing references)
			//IL_053a: Unknown result type (might be due to invalid IL or missing references)
			//IL_054e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0547: Unknown result type (might be due to invalid IL or missing references)
			//IL_0572: Unknown result type (might be due to invalid IL or missing references)
			bool value = QuestModPlugin.EnableCompletionOverrides.Value;
			if (!QuestCompletionOverrides.IsInitialized)
			{
				GUILayout.Label("Not initialized - load a save first", Array.Empty<GUILayoutOption>());
				return;
			}
			int num = categoryTab;
			categoryTab = GUILayout.Toolbar(categoryTab, QuestRegistry.Categories, Array.Empty<GUILayoutOption>());
			if (categoryTab != num)
			{
				multiplierText = multiplier.ToString("0.0");
			}
			GUILayout.Space(4f);
			GUI.enabled = value;
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(new GUIContent("Multiplier:", "Scale all targets in this category"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(68f) });
			multiplier = GUILayout.HorizontalSlider(multiplier, 0f, 1f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) });
			multiplier = Mathf.Round(multiplier * 20f) / 20f;
			string text = multiplier.ToString("0.0");
			if (text != multiplierText)
			{
				multiplierText = text;
			}
			multiplierText = GUILayout.TextField(multiplierText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(35f) });
			if (GUILayout.Button("Apply", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(48f) }) && float.TryParse(multiplierText, out var result))
			{
				multiplier = result;
				ApplyMultiplier(result);
			}
			if (GUILayout.Button("1x", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(28f) }))
			{
				multiplier = 1f;
				multiplierText = "1.0";
				ApplyMultiplier(1f);
			}
			if (GUILayout.Button(new GUIContent("R", "Reset this category to original values"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(24f) }))
			{
				ResetCategory();
			}
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Presets:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
			if (GUILayout.Button("Set to 1", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }))
			{
				QuestCompletionOverrides.ApplyPresetAll("set1");
				countInputs.Clear();
				RefreshOverrides();
			}
			if (GUILayout.Button("QoL Half", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(65f) }))
			{
				QuestCompletionOverrides.ApplyPresetAll("qol");
				countInputs.Clear();
				RefreshOverrides();
			}
			if (GUILayout.Button("Farmable", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(65f) }))
			{
				QuestCompletionOverrides.ApplyPresetAll("farmable");
				countInputs.Clear();
				RefreshOverrides();
			}
			if (GUILayout.Button("Default", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) }))
			{
				QuestCompletionOverrides.ApplyPresetAll("default");
				countInputs.Clear();
				RefreshOverrides();
			}
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			GUI.enabled = true;
			if (!value)
			{
				GUILayout.Label("Overrides disabled in config — counts are read-only", Array.Empty<GUILayoutOption>());
			}
			else if (QuestModPlugin.DevRemoveLimits.Value)
			{
				GUILayout.Label("⚠ DevRemoveLimits — no count limits (may break quest state)", Array.Empty<GUILayoutOption>());
			}
			GUILayout.Space(4f);
			string key = QuestRegistry.Categories[categoryTab];
			if (!cachedByCategory.ContainsKey(key) || cachedByCategory[key].Count == 0)
			{
				GUILayout.Label("No quests found in this category.", Array.Empty<GUILayoutOption>());
				return;
			}
			int num2 = 0;
			int num3 = 0;
			foreach (QuestOverrideInfo item in cachedByCategory[key])
			{
				foreach (QuestTargetInfo target in item.Targets)
				{
					num3++;
					if (target.CurrentCount != target.OriginalCount)
					{
						num2++;
					}
				}
			}
			if (num2 > 0)
			{
				Color color = GUI.color;
				GUI.color = new Color(1f, 0.85f, 0.4f);
				GUILayout.Label($"{num2} of {num3} targets modified", Array.Empty<GUILayoutOption>());
				GUI.color = color;
			}
			overrideScroll = GUILayout.BeginScrollView(overrideScroll, Array.Empty<GUILayoutOption>());
			bool flag = false;
			foreach (QuestOverrideInfo item2 in cachedByCategory[key])
			{
				GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				int num4 = 0;
				foreach (QuestTargetInfo target2 in item2.Targets)
				{
					num4 += target2.CurrentCount;
				}
				string text2 = $"[{item2.CompletedCount}/{num4}]";
				GUILayout.Label(new GUIContent(item2.QuestName, item2.QuestName), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(240f) });
				Color color2 = GUI.color;
				GUI.color = ((item2.CompletedCount >= num4) ? Color.green : Color.white);
				GUILayout.Label(text2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) });
				GUI.color = color2;
				GUILayout.FlexibleSpace();
				if (value && GUILayout.Button("Reset", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(48f) }))
				{
					QuestCompletionOverrides.ResetToOriginal(item2.QuestName);
					foreach (QuestTargetInfo target3 in item2.Targets)
					{
						string key2 = $"{item2.QuestName}_{target3.TargetIndex}";
						countInputs.Remove(key2);
					}
					flag = true;
				}
				GUILayout.EndHorizontal();
				foreach (QuestTargetInfo target4 in item2.Targets)
				{
					string key3 = $"{item2.QuestName}_{target4.TargetIndex}";
					if (!countInputs.ContainsKey(key3))
					{
						countInputs[key3] = target4.CurrentCount.ToString();
					}
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					GUILayout.Space(15f);
					string text3 = ((target4.CurrentCount != target4.OriginalCount) ? $"{target4.DisplayName} ({target4.OriginalCount}→{target4.CurrentCount})" : $"{target4.DisplayName} ({target4.OriginalCount})");
					int maxCap = QuestCompletionOverrides.GetMaxCap(item2.QuestName, target4.TargetIndex);
					if (maxCap > 0)
					{
						text3 += $" [max {maxCap}]";
					}
					GUILayout.Label(text3, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(210f) });
					if (!value)
					{
						GUILayout.EndHorizontal();
						continue;
					}
					if (item2.Targets.Count > 1)
					{
						bool flag2 = target4.CurrentCount > 0;
						bool flag3 = GUILayout.Toggle(flag2, "", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(18f) });
						if (flag3 != flag2)
						{
							int newCount = (flag3 ? target4.OriginalCount : 0);
							QuestCompletionOverrides.SetTargetCount(item2.QuestName, target4.TargetIndex, newCount);
							countInputs[key3] = newCount.ToString();
							flag = true;
						}
					}
					if (GUILayout.Button("−", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(22f) }))
					{
						int newCount2 = QuestCompletionOverrides.ClampCount(item2.QuestName, target4.TargetIndex, target4.CurrentCount - 1);
						QuestCompletionOverrides.SetTargetCount(item2.QuestName, target4.TargetIndex, newCount2);
						countInputs[key3] = newCount2.ToString();
						flag = true;
					}
					countInputs[key3] = GUILayout.TextField(countInputs[key3], (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(38f) });
					if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(22f) }))
					{
						int newCount3 = QuestCompletionOverrides.ClampCount(item2.QuestName, target4.TargetIndex, target4.CurrentCount + 1);
						QuestCompletionOverrides.SetTargetCount(item2.QuestName, target4.TargetIndex, newCount3);
						countInputs[key3] = newCount3.ToString();
						flag = true;
					}
					if (GUILayout.Button("Set", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(32f) }) && int.TryParse(countInputs[key3], out var result2))
					{
						QuestCompletionOverrides.SetTargetCount(item2.QuestName, target4.TargetIndex, result2);
						flag = true;
					}
					GUILayout.EndHorizontal();
				}
				GUILayout.EndVertical();
				GUILayout.Space(2f);
			}
			GUILayout.EndScrollView();
			if (flag)
			{
				RefreshOverrides();
			}
		}

		private void ApplyMultiplier(float mult)
		{
			string key = QuestRegistry.Categories[categoryTab];
			if (!cachedByCategory.ContainsKey(key))
			{
				return;
			}
			foreach (QuestOverrideInfo item in cachedByCategory[key])
			{
				foreach (QuestTargetInfo target in item.Targets)
				{
					int num = Mathf.Max(1, Mathf.RoundToInt((float)target.OriginalCount * mult));
					int newCount = ((num <= 1) ? 1 : ((num % 2 == 0) ? num : (num + 1)));
					string key2 = $"{item.QuestName}_{target.TargetIndex}";
					countInputs[key2] = newCount.ToString();
					QuestCompletionOverrides.SetTargetCount(item.QuestName, target.TargetIndex, newCount);
				}
			}
			RefreshOverrides();
		}

		private void ResetCategory()
		{
			string key = QuestRegistry.Categories[categoryTab];
			if (!cachedByCategory.ContainsKey(key))
			{
				return;
			}
			foreach (QuestOverrideInfo item in cachedByCategory[key])
			{
				QuestCompletionOverrides.ResetToOriginal(item.QuestName);
				foreach (QuestTargetInfo target in item.Targets)
				{
					string key2 = $"{item.QuestName}_{target.TargetIndex}";
					countInputs.Remove(key2);
				}
			}
			multiplier = 1f;
			multiplierText = "1.0";
			RefreshOverrides();
		}

		private void SnapshotBeforeMassOp()
		{
			undoSnapshot = QuestAcceptance.GetQuestList();
		}

		private void UndoMassOp()
		{
			if (undoSnapshot == null)
			{
				return;
			}
			foreach (QuestInfo item in undoSnapshot)
			{
				if (item.IsCompleted)
				{
					QuestAcceptance.CompleteQuest(item.Name);
				}
				else
				{
					QuestAcceptance.UncompleteQuest(item.Name);
				}
				if (item.IsAccepted)
				{
					QuestAcceptance.AcceptQuest(item.Name);
				}
				else
				{
					QuestAcceptance.UnacceptQuest(item.Name);
				}
			}
			undoSnapshot = null;
			questListDirty = true;
			QuestModPlugin.LogDebugInfo("Undid last mass operation");
		}

		private void DrawToolsTab()
		{
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Expected O, but got Unknown
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Expected O, but got Unknown
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Expected O, but got Unknown
			GUILayout.Label("Mass Operations", QuestGUISkin.SectionHeader, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("Accept Available", Array.Empty<GUILayoutOption>()))
			{
				SnapshotBeforeMassOp();
				QuestAcceptance.AcceptAllQuests();
				questListDirty = true;
			}
			if (GUILayout.Button("Complete Available", Array.Empty<GUILayoutOption>()))
			{
				SnapshotBeforeMassOp();
				QuestAcceptance.CompleteAllQuests();
				questListDirty = true;
			}
			GUILayout.EndHorizontal();
			if (QuestModPlugin.DevForceOperations.Value)
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				if (GUILayout.Button("Accept ALL (force)", Array.Empty<GUILayoutOption>()))
				{
					SnapshotBeforeMassOp();
					QuestAcceptance.ForceAcceptAllQuests();
					questListDirty = true;
				}
				if (GUILayout.Button("Complete ALL (force)", Array.Empty<GUILayoutOption>()))
				{
					SnapshotBeforeMassOp();
					QuestAcceptance.ForceCompleteAllQuests();
					questListDirty = true;
				}
				GUILayout.EndHorizontal();
			}
			GUI.enabled = undoSnapshot != null;
			if (GUILayout.Button("Undo Last Mass Operation", Array.Empty<GUILayoutOption>()))
			{
				UndoMassOp();
			}
			GUI.enabled = true;
			GUILayout.Space(10f);
			GUILayout.Label("Mode (this save)", QuestGUISkin.SectionHeader, Array.Empty<GUILayoutOption>());
			bool allQuestsAccepted = QuestModPlugin.AllQuestsAccepted;
			bool flag = GUILayout.Toggle(allQuestsAccepted, new GUIContent("All Quests Accepted", "Auto-inject and accept every quest each scene load. Forces Available + Wishboards on."), Array.Empty<GUILayoutOption>());
			if (flag != allQuestsAccepted)
			{
				QuestModPlugin.SetAllQuestsAccepted(flag);
			}
			GUI.enabled = !allQuestsAccepted;
			bool allQuestsAvailable = QuestModPlugin.AllQuestsAvailable;
			bool flag2 = GUILayout.Toggle(allQuestsAvailable, new GUIContent("  All Quests Available", "Bypasses act/chain prerequisites for this save."), Array.Empty<GUILayoutOption>());
			if (flag2 != allQuestsAvailable)
			{
				QuestModPlugin.SetAllQuestsAvailable(flag2);
			}
			GUI.enabled = true;
			GUILayout.Space(10f);
			GUILayout.Label("Quick Config", QuestGUISkin.SectionHeader, Array.Empty<GUILayoutOption>());
			bool value = QuestModPlugin.OnlyDiscoveredQuests.Value;
			bool flag3 = GUILayout.Toggle(value, new GUIContent("Only Discovered Quests", "Only show quests the player has encountered"), Array.Empty<GUILayoutOption>());
			if (flag3 != value)
			{
				QuestModPlugin.OnlyDiscoveredQuests.Value = flag3;
			}
			bool value2 = QuestModPlugin.QuestItemInvincible.Value;
			bool flag4 = GUILayout.Toggle(value2, "Quest Item Invincible", Array.Empty<GUILayoutOption>());
			if (flag4 != value2)
			{
				QuestModPlugin.QuestItemInvincible.Value = flag4;
			}
			bool value3 = QuestModPlugin.ShowQuestDisplayNames.Value;
			bool flag5 = GUILayout.Toggle(value3, "Show Display Names", Array.Empty<GUILayoutOption>());
			if (flag5 != value3)
			{
				QuestModPlugin.ShowQuestDisplayNames.Value = flag5;
			}
			GUILayout.Space(8f);
			if (PlayerData.instance != null)
			{
				bool blackThreadWorld = PlayerData.instance.blackThreadWorld;
				bool flag6 = GUILayout.Toggle(blackThreadWorld, "Act 3 (Black Thread World)", Array.Empty<GUILayoutOption>());
				if (flag6 != blackThreadWorld)
				{
					PlayerData.instance.blackThreadWorld = flag6;
				}
			}
		}
	}
	public static class QuestGUISkin
	{
		private static GUISkin skin;

		private static GUIStyle sectionHeader;

		private static GUIStyle tooltipStyle;

		private static Texture2D darkTex;

		private static Texture2D midTex;

		private static Texture2D lightTex;

		private static Texture2D accentTex;

		private static Texture2D hoverTex;

		private static Texture2D activeTex;

		private static Texture2D fieldTex;

		private static Texture2D greenTex;

		public static GUIStyle SectionHeader => sectionHeader;

		public static GUIStyle TooltipStyle => tooltipStyle;

		private static Texture2D MakeTex(Color col)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(2, 2);
			val.SetPixels((Color[])(object)new Color[4] { col, col, col, col });
			val.Apply();
			((Object)val).hideFlags = (HideFlags)52;
			return val;
		}

		public static GUISkin Get()
		{
			//IL_0027: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: 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_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Expected O, but got Unknown
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Expected O, but got Unknown
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Expected O, but got Unknown
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Expected O, but got Unknown
			//IL_0260: Expected O, but got Unknown
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: 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_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: 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_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Expected O, but got Unknown
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Expected O, but got Unknown
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Expected O, but got Unknown
			//IL_0335: Expected O, but got Unknown
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_0359: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_038c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Expected O, but got Unknown
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Expected O, but got Unknown
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b4: Expected O, but got Unknown
			//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c0: Expected O, but got Unknown
			//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f3: 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_0412: 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_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_0437: Unknown result type (might be due to invalid IL or missing references)
			//IL_0441: 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_044f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0459: Expected O, but got Unknown
			//IL_045e: Expected O, but got Unknown
			//IL_046d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0472: Unknown result type (might be due to invalid IL or missing references)
			//IL_0482: Unknown result type (might be due to invalid IL or missing references)
			//IL_0488: Unknown result type (might be due to invalid IL or missing references)
			//IL_0492: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04da: Unknown result type (might be due to invalid IL or missing references)
			//IL_04df: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e9: Expected O, but got Unknown
			//IL_04e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f8: Expected O, but got Unknown
			//IL_04fd: Expected O, but got Unknown
			//IL_0507: Unknown result type (might be due to invalid IL or missing references)
			//IL_050c: Unknown result type (might be due to invalid IL or missing references)
			//IL_051c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0531: Unknown result type (might be due to invalid IL or missing references)
			//IL_053b: Unknown result type (might be due to invalid IL or missing references)
			//IL_054b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0551: