Decompiled source of ExpandedRoster v0.3.0

BepInEx\plugins\ExpandedRoster.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using ExpandedRoster.Bard;
using ExpandedRoster.Bard.Ascendancies;
using ExpandedRoster.Bard.Buffs;
using ExpandedRoster.Bard.Skills;
using ExpandedRoster.Druid;
using ExpandedRoster.Druid.Ascendancies;
using ExpandedRoster.Druid.Buffs;
using ExpandedRoster.Druid.Skills;
using ExpandedRoster.Monk;
using ExpandedRoster.Monk.Ascendancies;
using ExpandedRoster.Monk.Buffs;
using ExpandedRoster.Monk.Skills;
using ExpandedRoster.Necromancer;
using ExpandedRoster.Necromancer.Ascendancies;
using ExpandedRoster.Necromancer.Buffs;
using ExpandedRoster.Necromancer.Skills;
using HarmonyLib;
using LootClicker.Entities;
using LootClicker.Entities.Buffs;
using LootClicker.Entities.Characters;
using LootClicker.Entities.Monsters;
using LootClicker.Entities.Skills;
using LootClicker.Inventory;
using LootClicker.Items;
using LootClicker.Services;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("ExpandedRoster")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ExpandedRoster")]
[assembly: AssemblyTitle("ExpandedRoster")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 ExpandedRoster
{
	public abstract class ModdedClassDef
	{
		public abstract CharacterClass ClassId { get; }

		public abstract SkillCategory Category { get; }

		public abstract string ClassName { get; }

		public abstract string ClassIconPath { get; }

		public abstract EquipmentID ClassRelicId { get; }

		public abstract EquipmentID[] AscendancyRelicIds { get; }

		public abstract AttributeStat[] ClassRelicAttributes { get; }

		public abstract AttributeStat[] AscendancyRelicAttributes { get; }

		public abstract AttributeStat[] AscendancyDefensiveAttributes { get; }

		public abstract Character CreateCharacter();

		public abstract Skill[] CreateAllSkills(Character owner);

		public abstract Buff[] CreateAllBuffs();

		public abstract AscendancyDef[] GetAscendancies();

		public abstract void EquipStartingGear(Character character);

		public virtual CharacterPassive GetClassPassive(Character character)
		{
			return null;
		}

		public virtual CharacterPassive GetDamagePassive(Character character)
		{
			return null;
		}

		public abstract Skill[] CreateDefaultAttacks(Character owner);

		public abstract Skill[] CreateOffensiveCooldowns(Character owner);

		public abstract Skill[] CreateDefensiveCooldowns(Character owner);

		protected static void EquipWithDefaults(Character c, EquipableItem weapon, EquipableItem offhand = null, byte statMultiplier = 1)
		{
			if (weapon != null)
			{
				AddDefaultAttributes(weapon, statMultiplier);
				c.Equipment.EquipItem(weapon, true, (InventoryBase)null, -1, -1);
			}
			if (offhand != null)
			{
				AddDefaultAttributes(offhand, statMultiplier);
				c.Equipment.EquipItem(offhand, true, (InventoryBase)null, -1, -1);
			}
		}

		private static void AddDefaultAttributes(EquipableItem item, byte statMultiplier)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			item.Attributes.Clear();
			HealthPoints val = new HealthPoints
			{
				Locked = true,
				MaxRank = 10
			};
			((AttributeBase)val).SetValue(1, statMultiplier);
			item.Attributes.Add((AttributeBase)(object)val);
			Luck val2 = new Luck
			{
				Locked = true,
				MaxRank = 10
			};
			((AttributeBase)val2).SetValue(1, statMultiplier);
			item.Attributes.Add((AttributeBase)(object)val2);
		}
	}
	public class AscendancyDef
	{
		public AscendancyClass Class;

		public string Name;

		public string IconPath;

		public Ascendancy Instance;

		public AscendancyPower Power;

		public string PowerTooltip;

		public bool PowerIsProc;
	}
	public class ClassButtonState
	{
		public Image Panel;

		public Button ButtonComponent;

		public bool Initialized;
	}
	public static class ClassRegistry
	{
		public static readonly List<ModdedClassDef> All = new List<ModdedClassDef>();

		public static readonly Dictionary<CharacterClass, ModdedClassDef> ByClassId = new Dictionary<CharacterClass, ModdedClassDef>();

		public static readonly Dictionary<CharacterClass, ClassButtonState> ButtonStates = new Dictionary<CharacterClass, ClassButtonState>();

		public static bool UIInitialized;

		public static void Register(ModdedClassDef def)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected I4, but got Unknown
			if (ByClassId.ContainsKey(def.ClassId))
			{
				Plugin.Log.LogWarning((object)("ClassRegistry: " + def.ClassName + " already registered, skipping."));
				return;
			}
			All.Add(def);
			ByClassId[def.ClassId] = def;
			ButtonStates[def.ClassId] = new ClassButtonState();
			Plugin.Log.LogInfo((object)$"ClassRegistry: Registered {def.ClassName} (ClassId={(int)def.ClassId})");
		}

		public static ModdedClassDef Get(CharacterClass classId)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			ByClassId.TryGetValue(classId, out var value);
			return value;
		}

		public static bool IsModdedClass(CharacterClass classId)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return ByClassId.ContainsKey(classId);
		}
	}
	[BepInPlugin("com.corga.expandedroster", "ExpandedRoster", "0.3.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.corga.expandedroster";

		public const string PluginName = "ExpandedRoster";

		public const string PluginVersion = "0.3.0";

		internal static ManualLogSource Log;

		internal static Harmony HarmonyInstance;

		internal static string DebugLogPath;

		private static string _altLog = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "NecroRuntime.log");

		private int _frameCount;

		internal static void DebugLog(string msg)
		{
			try
			{
				File.AppendAllText(DebugLogPath, msg + "\n");
			}
			catch
			{
			}
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)msg);
			}
		}

		private void Awake()
		{
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Expected O, but got Unknown
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			DebugLogPath = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "NecroDebug.log");
			try
			{
				File.WriteAllText(DebugLogPath, $"=== ExpandedRoster Debug Log {DateTime.Now} ===\n");
			}
			catch
			{
			}
			DebugLog("ExpandedRoster v0.3.0 loaded!");
			DebugLog("Location: " + ((BaseUnityPlugin)this).Info.Location);
			ClassRegistry.Register(new NecromancerClassDef());
			ClassRegistry.Register(new MonkClassDef());
			ClassRegistry.Register(new DruidClassDef());
			ClassRegistry.Register(new BardClassDef());
			Assembly assembly = typeof(SkillStore).Assembly;
			DebugLog("Assembly-CSharp: " + assembly.FullName);
			MethodInfo methodInfo = AccessTools.Method(typeof(SkillStore), "SetupSkillStore", (Type[])null, (Type[])null);
			DebugLog($"SkillStore.SetupSkillStore: {methodInfo != null} -> {methodInfo}");
			MethodInfo methodInfo2 = AccessTools.Method(typeof(CharacterCreationController), "SetupPanel", (Type[])null, (Type[])null);
			DebugLog($"CharacterCreationController.SetupPanel: {methodInfo2 != null} -> {methodInfo2}");
			if (methodInfo != null)
			{
				MethodInfo method = typeof(Plugin).GetMethod("TestPostfix", BindingFlags.Static | BindingFlags.NonPublic);
				HarmonyInstance = new Harmony("com.corga.expandedroster");
				HarmonyInstance.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				DebugLog("Manual test patch applied on SetupSkillStore");
			}
			HarmonyInstance.PatchAll();
			foreach (MethodBase patchedMethod in HarmonyInstance.GetPatchedMethods())
			{
				DebugLog("  Patched: " + patchedMethod.DeclaringType?.Name + "." + patchedMethod.Name);
			}
			if (methodInfo != null)
			{
				Patches patchInfo = Harmony.GetPatchInfo((MethodBase)methodInfo);
				if (patchInfo != null)
				{
					DebugLog($"  SetupSkillStore postfixes: {patchInfo.Postfixes.Count}");
					foreach (Patch postfix in patchInfo.Postfixes)
					{
						DebugLog("    - " + postfix.owner + ": " + postfix.PatchMethod.DeclaringType?.Name + "." + postfix.PatchMethod.Name);
					}
				}
			}
			DebugLog("Harmony patches applied.");
		}

		private void OnEnable()
		{
			try
			{
				File.AppendAllText(_altLog, $"[{DateTime.Now}] OnEnable\n");
			}
			catch
			{
			}
			DebugLog("[LIFECYCLE] OnEnable");
		}

		private void Start()
		{
			try
			{
				File.AppendAllText(_altLog, $"[{DateTime.Now}] Start\n");
			}
			catch
			{
			}
			DebugLog("[LIFECYCLE] Start");
		}

		private void Update()
		{
			_frameCount++;
			if (_frameCount <= 3 || _frameCount % 600 == 0)
			{
				string text = $"[{DateTime.Now}] Update frame={_frameCount}";
				try
				{
					File.AppendAllText(_altLog, text + "\n");
				}
				catch
				{
				}
				DebugLog(text);
			}
		}

		private void OnDisable()
		{
			try
			{
				File.AppendAllText(_altLog, $"[{DateTime.Now}] OnDisable\n");
			}
			catch
			{
			}
		}

		private void OnDestroy()
		{
			try
			{
				File.AppendAllText(_altLog, $"[{DateTime.Now}] OnDestroy\n");
			}
			catch
			{
			}
		}

		private static void TestPostfix()
		{
			try
			{
				File.AppendAllText(_altLog, $"[{DateTime.Now}] TestPostfix FIRED\n");
			}
			catch
			{
			}
			try
			{
				File.AppendAllText(DebugLogPath, "[NECRO-TEST] MANUAL POSTFIX FIRED\n");
			}
			catch
			{
			}
		}
	}
	public static class SpriteHelper
	{
		private static readonly Dictionary<string, Sprite> _cache = new Dictionary<string, Sprite>();

		public static Sprite LoadEmbedded(string resourceName)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			if (_cache.TryGetValue(resourceName, out var value))
			{
				return value;
			}
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string text = "ExpandedRoster." + resourceName + ".png";
			using Stream stream = executingAssembly.GetManifestResourceStream(text);
			if (stream == null)
			{
				Plugin.DebugLog("[SpriteHelper] Embedded resource not found: " + text);
				return null;
			}
			byte[] array = new byte[stream.Length];
			stream.Read(array, 0, array.Length);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			((Texture)val).filterMode = (FilterMode)1;
			if (!ImageConversion.LoadImage(val, array))
			{
				Plugin.DebugLog("[SpriteHelper] Failed to decode image: " + text);
				return null;
			}
			Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
			((Object)val2).name = resourceName;
			_cache[resourceName] = val2;
			return val2;
		}
	}
}
namespace ExpandedRoster.Patches
{
	[HarmonyPatch(typeof(SkillStore), "SetupSkillStore")]
	public static class SkillStorePatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			//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)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			Plugin.DebugLog("[MOD] SkillStore.SetupSkillStore postfix FIRED");
			try
			{
				foreach (ModdedClassDef item in ClassRegistry.All)
				{
					SkillCategory category = item.Category;
					if (!SkillStore.SkillCategoryLookup.ContainsKey(category))
					{
						SkillStore.SkillCategoryLookup[category] = new List<Skill>();
					}
					Skill[] array = item.CreateAllSkills(null);
					Skill[] array2 = array;
					foreach (Skill val in array2)
					{
						if (val != null)
						{
							SkillStore.SkillDatabase[val.ID] = val;
							SkillStore.SkillClassLookup[val.ID] = item.ClassId;
							SkillStore.SkillCategoryLookup[category].Add(val);
							SkillStore.SkillOrder.Add(val.ID);
						}
					}
					Plugin.Log.LogInfo((object)$"Registered {array.Length} {item.ClassName} skills.");
				}
				TextHelperPatches.ApplyIfNeeded(Plugin.HarmonyInstance);
				RelicPatches.ApplyIfNeeded(Plugin.HarmonyInstance);
				AscendancyPowerTooltipPatch.ApplyIfNeeded(Plugin.HarmonyInstance);
				WeaponTooltipConversionPatch.Apply(Plugin.HarmonyInstance);
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Failed to register modded skills: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(AscendancyStore), "SetupAscendancies")]
	public static class AscendancyStorePatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			//IL_002a: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				foreach (ModdedClassDef item in ClassRegistry.All)
				{
					Sprite value = Resources.Load<Sprite>(item.ClassIconPath);
					AscendancyStore.ClassIcons[item.ClassId] = value;
					AscendancyDef[] ascendancies = item.GetAscendancies();
					foreach (AscendancyDef ascendancyDef in ascendancies)
					{
						AscendancyStore.AscendancyDatabase[ascendancyDef.Class] = ascendancyDef.Instance;
						AscendancyStore.AscendancyPowers[ascendancyDef.Class] = ascendancyDef.Power;
						AscendancyStore.AscendancyIcons[ascendancyDef.Class] = Resources.Load<Sprite>(ascendancyDef.IconPath);
					}
					Plugin.Log.LogInfo((object)("Registered " + item.ClassName + " ascendancies."));
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Failed to register modded ascendancies: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(Character), "SetupPassives")]
	public static class SetupPassivesPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Character __instance)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Invalid comparison between Unknown and I4
			if (__instance == null || __instance.Passives == null || !ClassRegistry.ByClassId.TryGetValue(__instance.Class, out var value))
			{
				return;
			}
			CharacterPassive classPassive = value.GetClassPassive(__instance);
			if (classPassive != null)
			{
				__instance.Passives.Insert(3, classPassive);
				for (int i = 0; i < __instance.Passives.Count; i++)
				{
					((Passive)__instance.Passives[i]).ID = (byte)(i + 1);
				}
			}
			CharacterPassive damagePassive = value.GetDamagePassive(__instance);
			if (damagePassive == null)
			{
				return;
			}
			for (int j = 0; j < __instance.Passives.Count; j++)
			{
				CharacterPassive val = __instance.Passives[j];
				if (val.RequiredLevel == 20 && val.Attributes != null && val.Attributes.Length == 1 && (int)val.Attributes[0].Item1 == 10)
				{
					((Passive)damagePassive).ID = (byte)(j + 1);
					__instance.Passives[j] = damagePassive;
					break;
				}
			}
		}
	}
	public static class AscendancyPowerTooltipPatch
	{
		private static bool _applied;

		public static void ApplyIfNeeded(Harmony harmony)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			if (!_applied)
			{
				_applied = true;
				MethodInfo methodInfo = AccessTools.Method(typeof(AscendancyStore), "GetAscendancyPowerTooltipText", (Type[])null, (Type[])null);
				MethodInfo method = typeof(AscendancyPowerTooltipPatch).GetMethod("Prefix", BindingFlags.Static | BindingFlags.NonPublic);
				harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Plugin.DebugLog("[MOD] AscendancyPowerTooltipPatch applied (deferred)");
			}
		}

		private static bool Prefix(AscendancyClass ascendancyClass, int multi, ref string __result)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			foreach (ModdedClassDef item in ClassRegistry.All)
			{
				AscendancyDef[] ascendancies = item.GetAscendancies();
				foreach (AscendancyDef ascendancyDef in ascendancies)
				{
					if (ascendancyDef.Class == ascendancyClass && ascendancyDef.PowerTooltip != null)
					{
						StringBuilder stringBuilder = new StringBuilder();
						string value = (ascendancyDef.PowerIsProc ? (TextHelper.AscensionTitle + " " + TextHelper.ProcTitle) : TextHelper.AscensionTitle);
						stringBuilder.AppendLine(value);
						stringBuilder.Append(ascendancyDef.PowerTooltip);
						__result = stringBuilder.ToString();
						return false;
					}
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(BuffStore), "SetupBuffs")]
	public static class BuffStorePatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				foreach (ModdedClassDef item in ClassRegistry.All)
				{
					Buff[] array = item.CreateAllBuffs();
					Buff[] array2 = array;
					foreach (Buff val in array2)
					{
						if (val != null)
						{
							BuffStore.BuffDatabase[val.ID] = val;
						}
					}
					Plugin.Log.LogInfo((object)$"Registered {array.Length} {item.ClassName} buffs.");
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Failed to register modded buffs: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(GameData), "AddNewCharacter")]
	public static class AddNewCharacterPatch
	{
		[HarmonyPrefix]
		private static void Prefix(Character characterToAdd)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			ClassRegistry.Get(characterToAdd.Class)?.EquipStartingGear(characterToAdd);
		}
	}
	[HarmonyPatch(typeof(CharacterCreationController), "CreateCharacter")]
	public static class CreateCharacterPatch
	{
		[HarmonyPostfix]
		private static void Postfix(CharacterCreationController __instance)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Traverse val = Traverse.Create((object)__instance);
				ModdedClassDef moddedClassDef = ClassRegistry.Get(val.Property("CurrentClass", (object[])null).GetValue<CharacterClass>());
				if (moddedClassDef == null || val.Property("CharacterEdit", (object[])null).GetValue<bool>())
				{
					return;
				}
				TMP_InputField value = val.Field("CharacterNameInput").GetValue<TMP_InputField>();
				if (!((Object)(object)value == (Object)null) && !string.IsNullOrEmpty(value.text))
				{
					Character val2 = moddedClassDef.CreateCharacter();
					val2.UpdateName(value.text);
					Image value2 = val.Field("AvatarIcon").GetValue<Image>();
					if (val.Property("CustomAvatar", (object[])null).GetValue<bool>())
					{
						string value3 = val.Property("CustomAvatarName", (object[])null).GetValue<string>();
						val2.UpdateAvatar(value2.sprite, value3);
					}
					else
					{
						val2.UpdateAvatar(value2.sprite);
					}
					GameData.AddNewCharacter(val2);
					val.Method("CloseWindow", Array.Empty<object>()).GetValue();
					Plugin.Log.LogInfo((object)("Created new " + moddedClassDef.ClassName + " character."));
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Failed to create modded character: {arg}");
			}
		}
	}
	[HarmonyPatch]
	public static class LoadCharacterPatch
	{
		internal static int _pendingClassId = -1;

		[HarmonyTargetMethod]
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(typeof(SaveFile), "LoadCharacter", (Type[])null, (Type[])null);
		}

		internal static Character CreateModdedCharacter()
		{
			ModdedClassDef moddedClassDef = ClassRegistry.Get((CharacterClass)_pendingClassId);
			if (moddedClassDef != null)
			{
				return moddedClassDef.CreateCharacter();
			}
			Plugin.DebugLog($"[MOD] Unknown modded class ID {_pendingClassId}, falling back to first registered");
			if (ClassRegistry.All.Count <= 0)
			{
				return null;
			}
			return ClassRegistry.All[0].CreateCharacter();
		}

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Expected O, but got Unknown
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Expected O, but got Unknown
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			ConstructorInfo constructorInfo = AccessTools.Constructor(typeof(Paladin), (Type[])null, false);
			MethodInfo methodInfo = AccessTools.Method(typeof(LoadCharacterPatch), "CreateModdedCharacter", (Type[])null, (Type[])null);
			FieldInfo fieldInfo = AccessTools.Field(typeof(LoadCharacterPatch), "_pendingClassId");
			if (constructorInfo == null || methodInfo == null)
			{
				Plugin.Log.LogError((object)"LoadCharacter transpiler: Could not find constructors/methods");
				return list;
			}
			int num = -1;
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Newobj && list[i].operand is ConstructorInfo constructorInfo2 && constructorInfo2 == constructorInfo)
				{
					num = i;
					break;
				}
			}
			if (num < 0)
			{
				Plugin.Log.LogError((object)"LoadCharacter transpiler: Could not find Paladin constructor");
				return list;
			}
			int num2 = -1;
			for (int num3 = num - 1; num3 >= 0; num3--)
			{
				if (list[num3].opcode == OpCodes.Switch)
				{
					num2 = num3;
					break;
				}
			}
			if (num2 < 0)
			{
				Plugin.Log.LogError((object)"LoadCharacter transpiler: Could not find CharacterClass switch opcode");
				return list;
			}
			bool flag = false;
			for (int num4 = num2 - 1; num4 >= Math.Max(0, num2 - 10); num4--)
			{
				if (list[num4].opcode == OpCodes.Call && list[num4].operand is MethodInfo methodInfo2 && methodInfo2.Name == "ReadByte")
				{
					list.Insert(num4 + 1, new CodeInstruction(OpCodes.Dup, (object)null));
					list.Insert(num4 + 2, new CodeInstruction(OpCodes.Stsfld, (object)fieldInfo));
					num2 += 2;
					num += 2;
					flag = true;
					Plugin.Log.LogInfo((object)"LoadCharacter transpiler: Inserted class ID capture");
					break;
				}
			}
			if (!flag)
			{
				Plugin.Log.LogError((object)"LoadCharacter transpiler: Could not find ReadByte before switch");
				return list;
			}
			int localIndex = GetLocalIndex(list[num + 1]);
			if (localIndex < 0)
			{
				Plugin.Log.LogError((object)"LoadCharacter transpiler: Could not determine character local index");
				return list;
			}
			int index = num2 + 1;
			CodeInstruction val = new CodeInstruction(OpCodes.Call, (object)methodInfo);
			CodeInstruction item = MakeStloc(localIndex);
			val.labels.AddRange(list[index].labels);
			list[index].labels.Clear();
			list.Insert(index, item);
			list.Insert(index, val);
			Plugin.Log.LogInfo((object)"LoadCharacter transpiler: Injected factory as switch default case");
			return list;
		}

		private static int GetLocalIndex(CodeInstruction instr)
		{
			if (instr.opcode == OpCodes.Stloc_0)
			{
				return 0;
			}
			if (instr.opcode == OpCodes.Stloc_1)
			{
				return 1;
			}
			if (instr.opcode == OpCodes.Stloc_2)
			{
				return 2;
			}
			if (instr.opcode == OpCodes.Stloc_3)
			{
				return 3;
			}
			if (instr.opcode == OpCodes.Stloc_S && instr.operand is LocalBuilder localBuilder)
			{
				return localBuilder.LocalIndex;
			}
			if (instr.opcode == OpCodes.Stloc_S)
			{
				object operand = instr.operand;
				if (operand is byte)
				{
					return (byte)operand;
				}
			}
			if (instr.opcode == OpCodes.Stloc && instr.operand is LocalBuilder localBuilder2)
			{
				return localBuilder2.LocalIndex;
			}
			if (instr.opcode == OpCodes.Stloc)
			{
				object operand = instr.operand;
				if (operand is int)
				{
					return (int)operand;
				}
			}
			return -1;
		}

		private static bool IsLdloc(CodeInstruction instr, int localIndex)
		{
			switch (localIndex)
			{
			case 0:
				return instr.opcode == OpCodes.Ldloc_0;
			case 1:
				return instr.opcode == OpCodes.Ldloc_1;
			case 2:
				return instr.opcode == OpCodes.Ldloc_2;
			case 3:
				return instr.opcode == OpCodes.Ldloc_3;
			default:
				if (instr.opcode == OpCodes.Ldloc_S || instr.opcode == OpCodes.Ldloc)
				{
					if (instr.operand is LocalBuilder localBuilder)
					{
						return localBuilder.LocalIndex == localIndex;
					}
					if (instr.operand is byte b)
					{
						return b == localIndex;
					}
					if (instr.operand is int num)
					{
						return num == localIndex;
					}
				}
				return false;
			}
		}

		private static CodeInstruction MakeStloc(int localIndex)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			return (CodeInstruction)(localIndex switch
			{
				0 => (object)new CodeInstruction(OpCodes.Stloc_0, (object)null), 
				1 => (object)new CodeInstruction(OpCodes.Stloc_1, (object)null), 
				2 => (object)new CodeInstruction(OpCodes.Stloc_2, (object)null), 
				3 => (object)new CodeInstruction(OpCodes.Stloc_3, (object)null), 
				_ => (object)new CodeInstruction(OpCodes.Stloc_S, (object)(byte)localIndex), 
			});
		}
	}
	[HarmonyPatch(typeof(AscendancySelectionController), "LoadCharacter")]
	public static class AscendancySelectionPatch
	{
		[HarmonyPostfix]
		private static void Postfix(AscendancySelectionController __instance, Character character)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			if (character == null)
			{
				return;
			}
			ModdedClassDef moddedClassDef = ClassRegistry.Get(character.Class);
			if (moddedClassDef == null)
			{
				return;
			}
			try
			{
				AscendancyDef[] ascendancies = moddedClassDef.GetAscendancies();
				if (ascendancies != null && ascendancies.Length >= 3)
				{
					Traverse obj = Traverse.Create((object)__instance);
					obj.Property("AscendancyClass1", (object[])null).SetValue((object)ascendancies[0].Class);
					obj.Property("AscendancyClass2", (object[])null).SetValue((object)ascendancies[1].Class);
					obj.Property("AscendancyClass3", (object[])null).SetValue((object)ascendancies[2].Class);
					TMP_Text value = obj.Field("AscendancyName1").GetValue<TMP_Text>();
					TMP_Text value2 = obj.Field("AscendancyName2").GetValue<TMP_Text>();
					TMP_Text value3 = obj.Field("AscendancyName3").GetValue<TMP_Text>();
					Image value4 = obj.Field("AscendancyImage1").GetValue<Image>();
					Image value5 = obj.Field("AscendancyImage2").GetValue<Image>();
					Image value6 = obj.Field("AscendancyImage3").GetValue<Image>();
					if ((Object)(object)value != (Object)null)
					{
						value.text = ascendancies[0].Name;
					}
					if ((Object)(object)value2 != (Object)null)
					{
						value2.text = ascendancies[1].Name;
					}
					if ((Object)(object)value3 != (Object)null)
					{
						value3.text = ascendancies[2].Name;
					}
					if ((Object)(object)value4 != (Object)null)
					{
						value4.sprite = AscendancyStore.GetIcon(ascendancies[0].Class);
					}
					if ((Object)(object)value5 != (Object)null)
					{
						value5.sprite = AscendancyStore.GetIcon(ascendancies[1].Class);
					}
					if ((Object)(object)value6 != (Object)null)
					{
						value6.sprite = AscendancyStore.GetIcon(ascendancies[2].Class);
					}
					obj.Method("SelectAscendancy", new Type[1] { typeof(AscendancyClass) }, (object[])null).GetValue(new object[1] { ascendancies[0].Class });
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Failed to setup {moddedClassDef.ClassName} ascendancy selection: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(CharacterCreationController), "LoadClassPreview")]
	public static class LoadClassPreviewPatch
	{
		[HarmonyPostfix]
		private static void Postfix(CharacterCreationController __instance, CharacterClass newClass)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			ModdedClassDef moddedClassDef = ClassRegistry.Get(newClass);
			if (moddedClassDef == null)
			{
				return;
			}
			try
			{
				Traverse val = Traverse.Create((object)__instance);
				if (val.Property("CurrentClass", (object[])null).GetValue<CharacterClass>() != moddedClassDef.ClassId)
				{
					val.Property("CurrentClass", (object[])null).SetValue((object)moddedClassDef.ClassId);
				}
				Character testCharacter = GameData.TestCharacter;
				List<DisplaySkillController> value = val.Field("DefaultSkills").GetValue<List<DisplaySkillController>>();
				Skill[] skills = moddedClassDef.CreateDefaultAttacks(testCharacter);
				LoadSkillPreview(value, skills);
				List<DisplaySkillController> value2 = val.Field("OffensiveSkills").GetValue<List<DisplaySkillController>>();
				Skill[] skills2 = moddedClassDef.CreateOffensiveCooldowns(testCharacter);
				LoadSkillPreview(value2, skills2);
				List<DisplaySkillController> value3 = val.Field("DefensiveSkills").GetValue<List<DisplaySkillController>>();
				Skill[] skills3 = moddedClassDef.CreateDefensiveCooldowns(testCharacter);
				LoadSkillPreview(value3, skills3);
				List<DisplaySkillController> value4 = val.Field("AscendancySkills").GetValue<List<DisplaySkillController>>();
				AscendancyDef[] ascendancies = moddedClassDef.GetAscendancies();
				if (value4 != null && ascendancies != null)
				{
					int num = Math.Min(ascendancies.Length, value4.Count);
					for (int i = 0; i < num; i++)
					{
						DisplaySkillController obj = value4[i];
						if (obj != null)
						{
							obj.LoadAscendancy(ascendancies[i].Class, 1);
						}
					}
				}
				GameObject value5 = val.Field("ClassPreviewPanel").GetValue<GameObject>();
				if ((Object)(object)value5 != (Object)null && !value5.activeSelf)
				{
					value5.SetActive(true);
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Failed to load {moddedClassDef.ClassName} class preview: {arg}");
			}
		}

		private static void LoadSkillPreview(List<DisplaySkillController> controllers, Skill[] skills)
		{
			if (controllers == null || skills == null)
			{
				return;
			}
			int num = Math.Min(skills.Length, controllers.Count);
			for (int i = 0; i < num; i++)
			{
				DisplaySkillController obj = controllers[i];
				if (obj != null)
				{
					obj.LoadSkill(skills[i], true);
				}
			}
		}
	}
	[HarmonyPatch(typeof(CharacterCreationController), "SetupPanel")]
	public static class SetupPanelPatch
	{
		[HarmonyPostfix]
		private static void Postfix(CharacterCreationController __instance)
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: 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_0353: Expected O, but got Unknown
			//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_041e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0423: Unknown result type (might be due to invalid IL or missing references)
			//IL_0434: Unknown result type (might be due to invalid IL or missing references)
			//IL_0447: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_045d: Unknown result type (might be due to invalid IL or missing references)
			Plugin.DebugLog("[MOD] SetupPanel postfix FIRED");
			if (ClassRegistry.UIInitialized)
			{
				return;
			}
			try
			{
				Image paladinPanel = __instance.PaladinPanel;
				if ((Object)(object)paladinPanel == (Object)null)
				{
					Plugin.DebugLog("[MOD] PaladinPanel is null, aborting");
					return;
				}
				GameObject gameObject = ((Component)paladinPanel).gameObject;
				Transform parent = gameObject.transform.parent;
				RectTransform component = ((Component)__instance.WarriorPanel).GetComponent<RectTransform>();
				RectTransform component2 = ((Component)__instance.RangerPanel).GetComponent<RectTransform>();
				RectTransform component3 = ((Component)__instance.MagePanel).GetComponent<RectTransform>();
				RectTransform component4 = gameObject.GetComponent<RectTransform>();
				TMP_Text componentInChildren = ((Component)__instance.WarriorPanel).GetComponentInChildren<TMP_Text>(true);
				Plugin.DebugLog($"[MOD] Warrior pos={component.anchoredPosition} size={component.sizeDelta} pivot={component.pivot} anchor=({component.anchorMin},{component.anchorMax})");
				Plugin.DebugLog($"[MOD] Ranger pos={component2.anchoredPosition} size={component2.sizeDelta}");
				Plugin.DebugLog($"[MOD] Mage pos={component3.anchoredPosition} size={component3.sizeDelta}");
				Plugin.DebugLog($"[MOD] Paladin pos={component4.anchoredPosition} size={component4.sizeDelta}");
				float y = component.sizeDelta.y;
				float x = component.sizeDelta.x;
				float[] array = new float[4]
				{
					component.anchoredPosition.x,
					component2.anchoredPosition.x,
					component3.anchoredPosition.x,
					component4.anchoredPosition.x
				};
				float num = 4f;
				int count = ClassRegistry.All.Count;
				int num2 = 4;
				int num3 = (count + num2 - 1) / num2;
				for (int i = 0; i < count; i++)
				{
					ModdedClassDef moddedClassDef = ClassRegistry.All[i];
					ClassButtonState classButtonState = ClassRegistry.ButtonStates[moddedClassDef.ClassId];
					if (!classButtonState.Initialized)
					{
						int num4 = i / num2;
						int num5 = i % num2;
						float num6 = component.anchoredPosition.y - (float)(num4 + 1) * (y + num);
						GameObject val = Object.Instantiate<GameObject>(gameObject, parent);
						((Object)val).name = moddedClassDef.ClassName + "Button";
						classButtonState.ButtonComponent = val.GetComponent<Button>();
						classButtonState.Panel = val.GetComponent<Image>();
						RectTransform component5 = val.GetComponent<RectTransform>();
						float num7 = array[num5 % array.Length];
						component5.anchoredPosition = new Vector2(num7, num6);
						component5.sizeDelta = new Vector2(x, y);
						ReplaceClonedButtonIcon(val, classButtonState.Panel, moddedClassDef.ClassIconPath);
						val.SetActive(true);
						ReplaceClonedButtonText(val, componentInChildren, "PaladinText", moddedClassDef.ClassName + "Text", moddedClassDef.ClassName);
						((UnityEventBase)classButtonState.ButtonComponent.onClick).RemoveAllListeners();
						ModdedClassDef capturedDef = moddedClassDef;
						((UnityEvent)classButtonState.ButtonComponent.onClick).AddListener((UnityAction)delegate
						{
							//IL_0011: Unknown result type (might be due to invalid IL or missing references)
							__instance.LoadClassPreview(capturedDef.ClassId);
						});
						if ((Object)(object)GameData.GameController != (Object)null)
						{
							classButtonState.Panel.sprite = GameData.GameController.DefaultBackground;
						}
						classButtonState.Initialized = true;
						Plugin.DebugLog("[MOD] " + moddedClassDef.ClassName + " button created");
					}
				}
				float num8 = (float)num3 * (y + num);
				float num9 = 30f;
				float num10 = num8 + num9;
				RectTransform component6 = ((Component)parent).GetComponent<RectTransform>();
				if ((Object)(object)component6 != (Object)null)
				{
					Vector2 sizeDelta = component6.sizeDelta;
					sizeDelta.y += num8;
					component6.sizeDelta = sizeDelta;
				}
				Transform parent2 = parent.parent;
				object obj;
				if (parent2 == null)
				{
					obj = null;
				}
				else
				{
					Transform parent3 = parent2.parent;
					obj = ((parent3 != null) ? ((Component)parent3).GetComponent<RectTransform>() : null);
				}
				RectTransform val2 = (RectTransform)obj;
				if ((Object)(object)val2 != (Object)null)
				{
					Vector2 sizeDelta2 = val2.sizeDelta;
					sizeDelta2.y += num10;
					val2.sizeDelta = sizeDelta2;
				}
				if ((Object)(object)component6 != (Object)null)
				{
					Vector2 anchoredPosition = component6.anchoredPosition;
					anchoredPosition.y -= num9;
					component6.anchoredPosition = anchoredPosition;
				}
				ClassRegistry.UIInitialized = true;
				Plugin.DebugLog($"[MOD] All {count} class button(s) injected OK");
			}
			catch (Exception arg)
			{
				Plugin.DebugLog($"[MOD] SetupPanel ERROR: {arg}");
			}
		}

		private static void ReplaceClonedButtonIcon(GameObject buttonGO, Image panelImage, string iconPath)
		{
			Image[] componentsInChildren = buttonGO.GetComponentsInChildren<Image>(true);
			Sprite val = Resources.Load<Sprite>(iconPath);
			if (!((Object)(object)val != (Object)null))
			{
				return;
			}
			Image[] array = componentsInChildren;
			foreach (Image val2 in array)
			{
				if (!((Object)(object)val2 == (Object)(object)panelImage))
				{
					val2.sprite = val;
				}
			}
		}

		private static void ReplaceClonedButtonText(GameObject buttonGO, TMP_Text refTMP, string oldTextName, string newTextName, string displayText)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			Transform val = buttonGO.transform.Find(oldTextName);
			if ((Object)(object)val != (Object)null)
			{
				GameObject val2 = new GameObject(newTextName);
				val2.transform.SetParent(buttonGO.transform, false);
				TextMeshProUGUI val3 = val2.AddComponent<TextMeshProUGUI>();
				((TMP_Text)val3).text = displayText;
				if ((Object)(object)refTMP != (Object)null)
				{
					((TMP_Text)val3).font = refTMP.font;
					((TMP_Text)val3).fontSize = refTMP.fontSize * 0.85f;
					((Graphic)val3).color = ((Graphic)refTMP).color;
					((TMP_Text)val3).alignment = refTMP.alignment;
					((TMP_Text)val3).enableWordWrapping = false;
					((TMP_Text)val3).overflowMode = (TextOverflowModes)0;
				}
				RectTransform component = ((Component)val).GetComponent<RectTransform>();
				RectTransform component2 = val2.GetComponent<RectTransform>();
				component2.anchorMin = component.anchorMin;
				component2.anchorMax = component.anchorMax;
				component2.pivot = component.pivot;
				component2.anchoredPosition = component.anchoredPosition;
				component2.sizeDelta = component.sizeDelta;
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
		}
	}
	[HarmonyPatch(typeof(CharacterCreationController), "LoadCreationMenu")]
	public static class LoadCreationMenuPatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			foreach (KeyValuePair<CharacterClass, ClassButtonState> buttonState in ClassRegistry.ButtonStates)
			{
				ClassButtonState value = buttonState.Value;
				if ((Object)(object)value.Panel != (Object)null && (Object)(object)GameData.GameController != (Object)null)
				{
					value.Panel.sprite = GameData.GameController.DefaultBackground;
				}
				if ((Object)(object)value.ButtonComponent != (Object)null)
				{
					((Behaviour)value.ButtonComponent).enabled = true;
				}
			}
		}
	}
	[HarmonyPatch(typeof(CharacterCreationController), "UpdateClassButtons")]
	public static class UpdateClassButtonsPatch
	{
		[HarmonyPostfix]
		private static void Postfix(CharacterClass characterClass)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<CharacterClass, ClassButtonState> buttonState in ClassRegistry.ButtonStates)
			{
				ClassButtonState value = buttonState.Value;
				if ((Object)(object)value.Panel != (Object)null && (Object)(object)GameData.GameController != (Object)null)
				{
					value.Panel.sprite = ((characterClass == buttonState.Key) ? GameData.GameController.MenuBackground : GameData.GameController.DefaultBackground);
				}
			}
		}
	}
	[HarmonyPatch(typeof(CharacterCreationController), "LoadCharacter")]
	public static class LoadCharacterEditPatch
	{
		[HarmonyPostfix]
		private static void Postfix(CharacterCreationController __instance, Character character)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (character == null)
			{
				return;
			}
			foreach (KeyValuePair<CharacterClass, ClassButtonState> buttonState in ClassRegistry.ButtonStates)
			{
				ClassButtonState value = buttonState.Value;
				if ((Object)(object)value.ButtonComponent != (Object)null)
				{
					((Behaviour)value.ButtonComponent).enabled = false;
				}
				if (character.Class == buttonState.Key && (Object)(object)value.Panel != (Object)null)
				{
					value.Panel.sprite = GameData.GameController?.MenuBackground;
				}
			}
		}
	}
	public static class TextHelperPatches
	{
		internal static bool Applied;

		public static void ApplyIfNeeded(Harmony harmony)
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Expected O, but got Unknown
			if (Applied)
			{
				return;
			}
			try
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(TextHelper), "GetClassString", (Type[])null, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(typeof(TextHelper), "GetAscendancyString", (Type[])null, (Type[])null);
				MethodInfo methodInfo3 = AccessTools.Method(typeof(TextHelper), "GetSkillCategory", (Type[])null, (Type[])null);
				MethodInfo methodInfo4 = AccessTools.Method(typeof(TextHelperPatches), "GetClassStringPostfix", (Type[])null, (Type[])null);
				MethodInfo methodInfo5 = AccessTools.Method(typeof(TextHelperPatches), "GetAscendancyStringPostfix", (Type[])null, (Type[])null);
				MethodInfo methodInfo6 = AccessTools.Method(typeof(TextHelperPatches), "GetSkillCategoryPostfix", (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				if (methodInfo2 != null)
				{
					harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(methodInfo5), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				if (methodInfo3 != null)
				{
					harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(methodInfo6), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				Applied = true;
				Plugin.Log.LogInfo((object)"TextHelper patches applied (deferred).");
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Failed to apply TextHelper patches: {arg}");
			}
		}

		private static void GetClassStringPostfix(CharacterClass characterClass, ref string __result)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			ModdedClassDef moddedClassDef = ClassRegistry.Get(characterClass);
			if (moddedClassDef != null)
			{
				__result = moddedClassDef.ClassName;
			}
		}

		private static void GetAscendancyStringPostfix(AscendancyClass ascendancyClass, ref string __result)
		{
			//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)
			foreach (ModdedClassDef item in ClassRegistry.All)
			{
				AscendancyDef[] ascendancies = item.GetAscendancies();
				foreach (AscendancyDef ascendancyDef in ascendancies)
				{
					if (ascendancyDef.Class == ascendancyClass)
					{
						__result = ascendancyDef.Name;
						return;
					}
				}
			}
		}

		private static void GetSkillCategoryPostfix(SkillCategory skillCategory, ref string __result)
		{
			//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)
			foreach (ModdedClassDef item in ClassRegistry.All)
			{
				if (item.Category == skillCategory)
				{
					__result = item.ClassName;
					break;
				}
			}
		}
	}
	public static class RelicPatches
	{
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public static class RelicInventoryPatch
		{
			[HarmonyPostfix]
			private static void Postfix(RelicInventory __instance)
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					foreach (KeyValuePair<AscendancyClass, EquipmentID> item in AscRelicMap)
					{
						EquipmentID value = item.Value;
						AscendancyClass key = item.Key;
						((VaultInventory)__instance).CompatibleItems.Add(value);
						if (AscAttrMap.TryGetValue(key, out var value2))
						{
							Traverse.Create((object)__instance).Method("AddAttributeFilters", new Type[2]
							{
								typeof(EquipmentID),
								typeof(List<AttributeStat>)
							}, (object[])null).GetValue(new object[2] { value, value2 });
						}
					}
				}
				catch (Exception arg)
				{
					Plugin.Log.LogError((object)$"Failed to patch RelicInventory: {arg}");
				}
			}
		}

		internal static bool Applied;

		private static readonly Dictionary<CharacterClass, EquipmentID> ClassRelicMap = new Dictionary<CharacterClass, EquipmentID>();

		private static readonly Dictionary<AscendancyClass, EquipmentID> AscRelicMap = new Dictionary<AscendancyClass, EquipmentID>();

		private static readonly Dictionary<CharacterClass, List<AttributeStat>> ClassAttrMap = new Dictionary<CharacterClass, List<AttributeStat>>();

		private static readonly Dictionary<AscendancyClass, List<AttributeStat>> AscAttrMap = new Dictionary<AscendancyClass, List<AttributeStat>>();

		private static readonly Dictionary<AscendancyClass, List<AttributeStat>> AscDefAttrMap = new Dictionary<AscendancyClass, List<AttributeStat>>();

		internal static readonly Dictionary<EquipmentID, string> RelicIconMap = new Dictionary<EquipmentID, string>();

		public static void ApplyIfNeeded(Harmony harmony)
		{
			if (Applied)
			{
				return;
			}
			try
			{
				RegisterRelics();
				PatchMethods(harmony);
				Applied = true;
				Plugin.Log.LogInfo((object)"Relic patches applied — custom relics registered.");
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Failed to apply relic patches: {arg}");
			}
		}

		private static void RegisterRelics()
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Expected O, but got Unknown
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Expected O, but got Unknown
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			string text = Locale.GetText("relic_name");
			(MaterialID, int)[] salvageMaterials = new(MaterialID, int)[4]
			{
				((MaterialID)20, 4),
				((MaterialID)14, 4),
				((MaterialID)2, 4),
				((MaterialID)8, 4)
			};
			(MaterialID, int)[] salvageMaterials2 = new(MaterialID, int)[4]
			{
				((MaterialID)22, 4),
				((MaterialID)16, 4),
				((MaterialID)4, 4),
				((MaterialID)10, 4)
			};
			foreach (ModdedClassDef item in ClassRegistry.All)
			{
				AscendancyDef[] ascendancies = item.GetAscendancies();
				EquipmentID[] ascendancyRelicIds = item.AscendancyRelicIds;
				AddRelicToDatabase(new RelicBase
				{
					Name = item.ClassName + " " + text,
					Icon = item.ClassIconPath.Replace("Icons/Classes/", ""),
					ID = item.ClassRelicId,
					MinItemLevel = 20,
					Type = (RelicType)0,
					SalvageMaterials = salvageMaterials,
					MaxRarity = (Rarity)2,
					ClassRequirement = item.ClassId,
					DropLocation = (DropLocation)19
				});
				ClassRelicMap[item.ClassId] = item.ClassRelicId;
				ClassAttrMap[item.ClassId] = new List<AttributeStat>(item.ClassRelicAttributes);
				for (int i = 0; i < ascendancies.Length && i < ascendancyRelicIds.Length; i++)
				{
					AddRelicToDatabase((RelicBase)new AscendancyRelicBase
					{
						Name = ascendancies[i].Name + " " + text,
						Icon = item.ClassIconPath.Replace("Icons/Classes/", ""),
						ID = ascendancyRelicIds[i],
						Type = (RelicType)1,
						SalvageMaterials = salvageMaterials2,
						MaxRarity = (Rarity)5,
						AscendancyRequirement = ascendancies[i].Class,
						DropLocation = (DropLocation)20
					});
					AscRelicMap[ascendancies[i].Class] = ascendancyRelicIds[i];
					AscAttrMap[ascendancies[i].Class] = new List<AttributeStat>(item.AscendancyRelicAttributes);
					AscDefAttrMap[ascendancies[i].Class] = new List<AttributeStat>(item.AscendancyDefensiveAttributes);
				}
				Plugin.Log.LogInfo((object)$"Registered {item.ClassName} relics: 1 class + {ascendancies.Length} ascendancy.");
			}
			RelicIconMap[(EquipmentID)9000] = "Necromancer.Icons.RelicNecromancer";
			RelicIconMap[(EquipmentID)9001] = "Necromancer.Icons.RelicLichLord";
			RelicIconMap[(EquipmentID)9003] = "Necromancer.Icons.RelicHemomancer";
			RelicIconMap[(EquipmentID)9002] = "Necromancer.Icons.RelicPlaguelord";
			RelicIconMap[(EquipmentID)9010] = "Monk.Icons.RelicMonk";
			RelicIconMap[(EquipmentID)9011] = "Monk.Icons.RelicWindwalker";
			RelicIconMap[(EquipmentID)9012] = "Monk.Icons.RelicIronhand";
			RelicIconMap[(EquipmentID)9013] = "Monk.Icons.RelicSpiritfist";
			RelicIconMap[(EquipmentID)9020] = "Druid.Icons.RelicDruid";
			RelicIconMap[(EquipmentID)9021] = "Druid.Icons.RelicArchdruid";
			RelicIconMap[(EquipmentID)9022] = "Druid.Icons.RelicStormbringer";
			RelicIconMap[(EquipmentID)9023] = "Druid.Icons.RelicBeastwarden";
			RelicIconMap[(EquipmentID)9030] = "Bard.Icons.RelicBard";
			RelicIconMap[(EquipmentID)9031] = "Bard.Icons.RelicVirtuoso";
			RelicIconMap[(EquipmentID)9032] = "Bard.Icons.RelicTroubadour";
			RelicIconMap[(EquipmentID)9033] = "Bard.Icons.RelicDirgesinger";
		}

		private static void AddRelicToDatabase(RelicBase relic)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			Equipment.Database[((EquipmentBase)relic).ID] = (EquipmentBase)(object)relic;
			if (RelicBases.RelicDatabase.ContainsKey(relic.Type))
			{
				RelicBases.RelicDatabase[relic.Type].Add(((EquipmentBase)relic).ID);
			}
		}

		private static void PatchMethods(Harmony harmony)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected O, but got Unknown
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Expected O, but got Unknown
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Expected O, but got Unknown
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Expected O, but got Unknown
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(typeof(RelicBases), "GetRelicRoll", new Type[1] { typeof(int) }, (Type[])null);
			if (methodInfo != null)
			{
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(RelicPatches), "GetRelicRollLevelPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo2 = AccessTools.Method(typeof(RelicBases), "GetRelicRoll", new Type[1] { typeof(CharacterClass) }, (Type[])null);
			if (methodInfo2 != null)
			{
				harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(RelicPatches), "GetRelicRollClassPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo3 = AccessTools.Method(typeof(RelicBases), "GetRelicRoll", new Type[1] { typeof(AscendancyClass) }, (Type[])null);
			if (methodInfo3 != null)
			{
				harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(RelicPatches), "GetRelicRollAscPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo4 = AccessTools.Method(typeof(RelicBases), "GetAttributesForRelic", new Type[1] { typeof(CharacterClass) }, (Type[])null);
			if (methodInfo4 != null)
			{
				harmony.Patch((MethodBase)methodInfo4, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(RelicPatches), "GetAttrsClassPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo5 = AccessTools.Method(typeof(RelicBases), "GetAttributesForRelic", new Type[1] { typeof(AscendancyClass) }, (Type[])null);
			if (methodInfo5 != null)
			{
				harmony.Patch((MethodBase)methodInfo5, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(RelicPatches), "GetAttrsAscPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo6 = AccessTools.Method(typeof(RelicBases), "GetAttributesForRelic", new Type[2]
			{
				typeof(AscendancyClass),
				typeof(AttributeType)
			}, (Type[])null);
			if (methodInfo6 != null)
			{
				harmony.Patch((MethodBase)methodInfo6, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(RelicPatches), "GetAttrsAscTypePostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo7 = AccessTools.Method(typeof(RelicBase), "GetIcon", (Type[])null, (Type[])null);
			if (methodInfo7 != null)
			{
				harmony.Patch((MethodBase)methodInfo7, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(RelicPatches), "GetIconPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		private static void GetRelicRollLevelPostfix(int itemLevel, ref EquipmentID __result)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected I4, but got Unknown
			int count = ClassRegistry.All.Count;
			if (count == 0)
			{
				return;
			}
			if (itemLevel >= 20 && itemLevel < 100)
			{
				int num = 4 + count;
				int num2 = Random.Range(0, num);
				if (num2 >= 4)
				{
					ModdedClassDef moddedClassDef = ClassRegistry.All[num2 - 4];
					__result = (EquipmentID)(int)moddedClassDef.ClassRelicId;
				}
			}
			else
			{
				if (itemLevel < 100 || itemLevel > 150)
				{
					return;
				}
				int num3 = count * 3;
				int num4 = 12 + num3;
				int num5 = Random.Range(0, num4);
				if (num5 < 12)
				{
					return;
				}
				int num6 = num5 - 12;
				int num7 = num6 / 3;
				int num8 = num6 % 3;
				if (num7 < ClassRegistry.All.Count)
				{
					EquipmentID[] ascendancyRelicIds = ClassRegistry.All[num7].AscendancyRelicIds;
					if (num8 < ascendancyRelicIds.Length)
					{
						__result = ascendancyRelicIds[num8];
					}
				}
			}
		}

		private static void GetRelicRollClassPostfix(CharacterClass characterClass, ref EquipmentID __result)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected I4, but got Unknown
			if (ClassRelicMap.TryGetValue(characterClass, out var value))
			{
				__result = (EquipmentID)(int)value;
			}
		}

		private static void GetRelicRollAscPostfix(AscendancyClass ascendancyClass, ref EquipmentID __result)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected I4, but got Unknown
			if (AscRelicMap.TryGetValue(ascendancyClass, out var value))
			{
				__result = (EquipmentID)(int)value;
			}
		}

		private static void GetAttrsClassPostfix(CharacterClass characterClass, ref List<AttributeStat> __result)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (ClassAttrMap.TryGetValue(characterClass, out var value))
			{
				__result = new List<AttributeStat>(value);
			}
		}

		private static void GetAttrsAscPostfix(AscendancyClass ascendancyClass, ref List<AttributeStat> __result)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (AscAttrMap.TryGetValue(ascendancyClass, out var value))
			{
				__result = new List<AttributeStat>(value);
			}
		}

		private static void GetAttrsAscTypePostfix(AscendancyClass ascendancyClass, AttributeType attributeType, ref List<AttributeStat> __result)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected I4, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (!AscAttrMap.ContainsKey(ascendancyClass))
			{
				return;
			}
			switch ((int)attributeType)
			{
			case 0:
				__result = new List<AttributeStat>
				{
					(AttributeStat)61,
					(AttributeStat)8,
					(AttributeStat)19,
					(AttributeStat)62,
					(AttributeStat)23
				};
				break;
			case 1:
			{
				if (AscDefAttrMap.TryGetValue(ascendancyClass, out var value))
				{
					__result = new List<AttributeStat>(value);
				}
				break;
			}
			case 2:
				__result = new List<AttributeStat>
				{
					(AttributeStat)50,
					(AttributeStat)52
				};
				break;
			}
		}

		private static void GetIconPostfix(RelicBase __instance, ref Sprite __result)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (RelicIconMap.TryGetValue(((EquipmentBase)__instance).ID, out var value))
			{
				Sprite val = SpriteHelper.LoadEmbedded(value);
				if ((Object)(object)val != (Object)null)
				{
					__result = val;
				}
			}
		}
	}
	[HarmonyPatch(typeof(SkillGlossaryController), "SetupSkillGlossary")]
	public static class SkillGlossaryPatch
	{
		[HarmonyPostfix]
		private static void Postfix(SkillGlossaryController __instance)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				foreach (ModdedClassDef item in ClassRegistry.All)
				{
					List<Skill> skillsFromCategory = SkillStore.GetSkillsFromCategory(item.Category);
					if (skillsFromCategory != null && skillsFromCategory.Count > 0)
					{
						Traverse.Create((object)__instance).Method("SetupSkillGroup", new object[2] { item.Category, skillsFromCategory }).GetValue();
					}
				}
			}
			catch (Exception arg)
			{
				Plugin.DebugLog($"[MOD] Failed to add glossary groups: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(Character), "UpdateDamageStats")]
	public static class WeaponDamageConversionPatch
	{
		[HarmonyPrefix]
		private static void Prefix(Character __instance)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Invalid comparison between Unknown and I4
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Invalid comparison between Unknown and I4
			object obj;
			if (__instance == null)
			{
				obj = null;
			}
			else
			{
				CharacterEquipment equipment = __instance.Equipment;
				obj = ((equipment != null) ? equipment.Mainhand : null);
			}
			if (obj == null)
			{
				return;
			}
			WeaponTypes weaponType = __instance.Equipment.Mainhand.WeaponType;
			if ((int)weaponType != 2 && (int)weaponType != 8)
			{
				return;
			}
			if (MonkConstants.HasElemConversion(__instance))
			{
				if ((int)__instance.Equipment.Mainhand.DamageType == 0)
				{
					__instance.Equipment.Mainhand.DamageType = (DamageTypes)2;
				}
			}
			else if ((int)__instance.Class == 6 && (int)__instance.Equipment.Mainhand.DamageType == 2)
			{
				__instance.Equipment.Mainhand.DamageType = (DamageTypes)0;
			}
		}
	}
	[HarmonyPatch(typeof(MasteryPassivePanelController), "Setup")]
	public static class PassiveBorderExpansionPatch
	{
		[HarmonyPostfix]
		private static void Postfix(MasteryPassivePanelController __instance)
		{
			if (!(AccessTools.Property(typeof(MasteryPassivePanelController), "PassiveBorders")?.GetValue(__instance) is List<PassiveController> list))
			{
				return;
			}
			FieldInfo fieldInfo = AccessTools.Field(typeof(MasteryPassivePanelController), "PassiveBorderPrefab");
			FieldInfo fieldInfo2 = AccessTools.Field(typeof(MasteryPassivePanelController), "PassiveBorderPanel");
			object? obj = fieldInfo?.GetValue(__instance);
			GameObject val = (GameObject)((obj is GameObject) ? obj : null);
			object? obj2 = fieldInfo2?.GetValue(__instance);
			GameObject val2 = (GameObject)((obj2 is GameObject) ? obj2 : null);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null))
			{
				for (int i = 0; i < 15; i++)
				{
					GameObject obj3 = Object.Instantiate<GameObject>(val);
					TransformExtensions.SetParentScaled(obj3.transform, val2.transform, false);
					PassiveController component = obj3.GetComponent<PassiveController>();
					component.Deactivate();
					list.Add(component);
				}
				Plugin.DebugLog($"[MOD] PassiveBorders expanded to {list.Count}");
			}
		}
	}
	public static class WeaponTooltipConversionPatch
	{
		private static bool _applied;

		public static void Apply(Harmony harmony)
		{
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			//IL_00a5: Expected O, but got Unknown
			if (!_applied)
			{
				_applied = true;
				MethodInfo method = typeof(ItemTooltip).GetMethod("LoadTooltip", new Type[2]
				{
					typeof(Weapon),
					typeof(StringBuilder).MakeByRefType()
				});
				if (method == null)
				{
					Plugin.Log.LogWarning((object)"[MOD] Could not find ItemTooltip.LoadTooltip(Weapon, ref StringBuilder)");
					return;
				}
				MethodInfo method2 = typeof(WeaponTooltipConversionPatch).GetMethod("Prefix", BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo method3 = typeof(WeaponTooltipConversionPatch).GetMethod("Postfix", BindingFlags.Static | BindingFlags.NonPublic);
				harmony.Patch((MethodBase)method, new HarmonyMethod(method2), new HarmonyMethod(method3), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Plugin.DebugLog("[MOD] WeaponTooltipConversionPatch applied");
			}
		}

		private static void Prefix(Weapon weapon, out DamageTypes __state)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			__state = (DamageTypes)12;
			if (weapon == null)
			{
				return;
			}
			WeaponTypes weaponType = weapon.WeaponType;
			if ((int)weaponType == 2 || (int)weaponType == 8)
			{
				Character currentCharacter = GameData.CurrentCharacter;
				if (currentCharacter != null && MonkConstants.HasElemConversion(currentCharacter) && (int)weapon.DamageType == 0)
				{
					__state = (DamageTypes)0;
					weapon.DamageType = (DamageTypes)2;
				}
			}
		}

		private static void Postfix(Weapon weapon, DamageTypes __state)
		{
			//IL_0000: 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)
			if ((int)__state == 0 && weapon != null)
			{
				Character currentCharacter = GameData.CurrentCharacter;
				object obj;
				if (currentCharacter == null)
				{
					obj = null;
				}
				else
				{
					CharacterEquipment equipment = currentCharacter.Equipment;
					obj = ((equipment != null) ? equipment.Mainhand : null);
				}
				if (weapon != obj)
				{
					weapon.DamageType = __state;
				}
			}
		}
	}
	[HarmonyPatch(typeof(ItemComparison), "GetItemComparison", new Type[]
	{
		typeof(Character),
		typeof(EquipableItem),
		typeof(bool),
		typeof(bool)
	})]
	public static class ComparatorConversionPatch
	{
		[HarmonyPrefix]
		private static void Prefix(Character character, EquipableItem newItem, out DamageTypes __state)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Invalid comparison between Unknown and I4
			__state = (DamageTypes)12;
			if (character != null && newItem != null && MonkConstants.HasElemConversion(character))
			{
				Weapon val = (Weapon)(object)((newItem is Weapon) ? newItem : null);
				if (val != null && (int)val.DamageType == 0 && ((int)val.WeaponType == 2 || (int)val.WeaponType == 8))
				{
					__state = (DamageTypes)0;
					val.DamageType = (DamageTypes)2;
				}
			}
		}

		[HarmonyPostfix]
		private static void Postfix(Character character, EquipableItem newItem, DamageTypes __state)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if ((int)__state != 0)
			{
				return;
			}
			Weapon val = (Weapon)(object)((newItem is Weapon) ? newItem : null);
			if (val != null)
			{
				object obj;
				if (character == null)
				{
					obj = null;
				}
				else
				{
					CharacterEquipment equipment = character.Equipment;
					obj = ((equipment != null) ? equipment.Mainhand : null);
				}
				if (val != obj)
				{
					val.DamageType = __state;
				}
			}
		}
	}
}
namespace ExpandedRoster.Necromancer
{
	public static class NecroConstants
	{
		public const CharacterClass NecromancerClass = 5;

		public const EquipmentID NecromancerRelic = 9000;

		public const EquipmentID LichRelic = 9001;

		public const EquipmentID BloodLordRelic = 9002;

		public const EquipmentID HexbladeRelic = 9003;

		public const SkillCategory NecromancerCategory = 4;

		public const SkillID SoulSiphon = 1100;

		public const SkillID BoneLance = 1101;

		public const SkillID ShadowBolt = 1102;

		public const SkillID WitheringTouch = 1103;

		public const SkillID PlagueStrike = 1104;

		public const SkillID HexBolt = 1105;

		public const SkillID SpectralBarrage = 1106;

		public const SkillID CorpseExplosion = 1200;

		public const SkillID DarkPact = 1201;

		public const SkillID SoulStorm = 1202;

		public const SkillID Pestilence = 1203;

		public const SkillID BoneArmour = 1300;

		public const SkillID LifeTap = 1301;

		public const SkillID SpiritWard = 1302;

		public const AscendancyClass LichClass = 13;

		public const AscendancyClass BloodLordClass = 14;

		public const AscendancyClass HexbladeClass = 15;

		public const BuffID HexOfWeakness = 500;

		public const BuffID HexOfFragility = 501;

		public const BuffID HexOfLethargy = 502;

		public const BuffID HexOfRuin = 503;

		public const BuffID HexOfTorment = 504;

		public const BuffID BoneArmourBuff = 510;

		public const BuffID LifeTapBuff = 511;

		public const BuffID SpiritWardBuff = 512;

		public const BuffID SpiritWardHeal = 513;

		public const BuffID DarkPactBuff = 514;

		public const BuffID SoulStormBuff = 515;

		public const BuffID UndyingFormBuff = 516;

		public const BuffID UndyingRageBuff = 517;

		public const BuffID HexMasteryBuff = 518;

		public const float NecromancerBaseHealth = 90f;

		public const int NecromancerBaseHealthIncrement = 9;
	}
	public class NecromancerCharacter : Character
	{
		public override CharacterClass Class => (CharacterClass)5;

		public NecromancerCharacter()
		{
			((Character)this).DefaultAttacks = new List<DefaultAttack>
			{
				(DefaultAttack)(object)new SoulSiphon((Character)(object)this),
				(DefaultAttack)(object)new BoneLance((Character)(object)this),
				(DefaultAttack)(object)new ShadowBolt((Character)(object)this),
				(DefaultAttack)(object)new WitheringTouch((Character)(object)this),
				(DefaultAttack)(object)new PlagueStrike((Character)(object)this),
				(DefaultAttack)(object)new HexBolt((Character)(object)this),
				(DefaultAttack)(object)new SpectralBarrage((Character)(object)this)
			};
			((Character)this).OffensiveCooldowns = new List<OffensiveCooldown>
			{
				(OffensiveCooldown)(object)new CorpseExplosion((Character)(object)this),
				(OffensiveCooldown)(object)new DarkPact((Character)(object)this),
				(OffensiveCooldown)(object)new SoulStorm((Character)(object)this),
				(OffensiveCooldown)(object)new Pestilence((Character)(object)this)
			};
			((Character)this).DefensiveCooldowns = new List<DefensiveCooldown>
			{
				(DefensiveCooldown)(object)new BoneArmour((Character)(object)this),
				(DefensiveCooldown)(object)new LifeTap((Character)(object)this),
				(DefensiveCooldown)(object)new SpiritWard((Character)(object)this)
			};
			((Character)this).SetupSkillDictionary();
			((Entity)this).BaseHealth = 90f;
			((Entity)this).BaseHealthIncrement = 9;
			((Entity)this).UpdateHealth();
			((Entity)this).CurrentHealth = ((Entity)this).MaxHealth;
			((Character)this).SetupPassives();
			((Character)this).SetupLoadouts();
			((Character)this).LoadSkill(((Character)this).DefaultAttacks[0]);
		}
	}
	public class NecromancerClassDef : ModdedClassDef
	{
		public override CharacterClass ClassId => (CharacterClass)5;

		public override SkillCategory Category => (SkillCategory)4;

		public override string ClassName => "Necromancer";

		public override string ClassIconPath => "Icons/Classes/Mage";

		public override EquipmentID ClassRelicId => (EquipmentID)9000;

		public override EquipmentID[] AscendancyRelicIds
		{
			get
			{
				EquipmentID[] array = new EquipmentID[3];
				RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
				return (EquipmentID[])(object)array;
			}
		}

		public override AttributeStat[] ClassRelicAttributes
		{
			get
			{
				AttributeStat[] array = new AttributeStat[8];
				RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
				return (AttributeStat[])(object)array;
			}
		}

		public override AttributeStat[] AscendancyRelicAttributes
		{
			get
			{
				AttributeStat[] array = new AttributeStat[12];
				RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
				return (AttributeStat[])(object)array;
			}
		}

		public override AttributeStat[] AscendancyDefensiveAttributes
		{
			get
			{
				AttributeStat[] array = new AttributeStat[5];
				RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
				return (AttributeStat[])(object)array;
			}
		}

		public override Character CreateCharacter()
		{
			return (Character)(object)new NecromancerCharacter();
		}

		public override Skill[] CreateAllSkills(Character owner)
		{
			return (Skill[])(object)new Skill[14]
			{
				(Skill)new SoulSiphon(owner),
				(Skill)new BoneLance(owner),
				(Skill)new ShadowBolt(owner),
				(Skill)new WitheringTouch(owner),
				(Skill)new PlagueStrike(owner),
				(Skill)new HexBolt(owner),
				(Skill)new SpectralBarrage(owner),
				(Skill)new CorpseExplosion(owner),
				(Skill)new DarkPact(owner),
				(Skill)new SoulStorm(owner),
				(Skill)new Pestilence(owner),
				(Skill)new BoneArmour(owner),
				(Skill)new LifeTap(owner),
				(Skill)new SpiritWard(owner)
			};
		}

		public override Buff[] CreateAllBuffs()
		{
			return (Buff[])(object)new Buff[11]
			{
				(Buff)new HexOfWeaknessBuff(),
				(Buff)new HexOfFragilityBuff(),
				(Buff)new HexOfLethargyBuff(),
				(Buff)new HexOfRuinBuff(),
				(Buff)new HexOfTormentBuff(),
				(Buff)new BoneArmourBuff(),
				(Buff)new LifeTapBuff(),
				(Buff)new SpiritWardBuff(),
				(Buff)new DarkPactBuff(),
				(Buff)new SoulStormBuff(),
				(Buff)new UndyingFormBuff()
			};
		}

		public override AscendancyDef[] GetAscendancies()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			return new AscendancyDef[3]
			{
				new AscendancyDef
				{
					Class = (AscendancyClass)13,
					Name = "Lich",
					IconPath = "Icons/Classes/Archmage",
					Instance = (Ascendancy)(object)new Lich(null),
					Power = (AscendancyPower)(object)new LichPower(),
					PowerIsProc = true,
					PowerTooltip = string.Format("When your Barrier is depleted deal {0} of the Barrier lost as Area Damage and restore {1} of Max Barrier. {2} Seconds Cooldown", TextHelper.GetTooltipPercent(500.0, false, "#95FF6D", false), TextHelper.GetTooltipPercent(250.0, false, "#95FF6D", false), TextHelper.GetTooltipDuration(15000, "#FFFFFF"))
				},
				new AscendancyDef
				{
					Class = (AscendancyClass)14,
					Name = "Blood Lord",
					IconPath = "Icons/Classes/Renegade",
					Instance = (Ascendancy)(object)new BloodLord(null),
					Power = (AscendancyPower)(object)new BloodLordPower(),
					PowerIsProc = true,
					PowerTooltip = string.Format("Your Skills sacrifice {0} of Current HP to deal that amount as bonus damage to all targets hit", TextHelper.GetTooltipPercent(20.0, false, "#FF6666", false))
				},
				new AscendancyDef
				{
					Class = (AscendancyClass)15,
					Name = "Hexblade",
					IconPath = "Icons/Classes/Battlemage",
					Instance = (Ascendancy)(object)new Hexblade(null),
					Power = (AscendancyPower)(object)new HexbladePower(),
					PowerIsProc = true,
					PowerTooltip = string.Format("Hex Detonation: Hitting enemies with {0}+ hexes consumes all hexes for {1} Weapon Damage per hex consumed", TextHelper.GetHtmlText("3", "#FFFFFF", false, -1), TextHelper.GetTooltipPercent(300.0, false, "#95FF6D", false))
				}
			};
		}

		public override void EquipStartingGear(Character character)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			try
			{
				EquipmentBase obj = Equipment.Database[(EquipmentID)29];
				Weapon weapon = new Weapon(1, (Rarity)1, (WeaponBase)(object)((obj is WeaponBase) ? obj : null), (List<AttributeBase>)null, -1);
				EquipmentBase obj2 = Equipment.Database[(EquipmentID)32];
				Ward offhand = new Ward(1, (Rarity)1, (WardBase)(object)((obj2 is WardBase) ? obj2 : null), (List<AttributeBase>)null, -1);
				ModdedClassDef.EquipWithDefaults(character, (EquipableItem)(object)weapon, (EquipableItem)(object)offhand, 1);
				Plugin.DebugLog("[NECRO] Equipped starting gear (SpellTome + Ward)");
			}
			catch (Exception arg)
			{
				Plugin.DebugLog($"[NECRO] Failed to equip starting gear: {arg}");
			}
		}

		public override Skill[] CreateDefaultAttacks(Character owner)
		{
			return (Skill[])(object)new Skill[7]
			{
				(Skill)new SoulSiphon(owner),
				(Skill)new BoneLance(owner),
				(Skill)new ShadowBolt(owner),
				(Skill)new WitheringTouch(owner),
				(Skill)new PlagueStrike(owner),
				(Skill)new HexBolt(owner),
				(Skill)new SpectralBarrage(owner)
			};
		}

		public override Skill[] CreateOffensiveCooldowns(Character owner)
		{
			return (Skill[])(object)new Skill[4]
			{
				(Skill)new CorpseExplosion(owner),
				(Skill)new DarkPact(owner),
				(Skill)new SoulStorm(owner),
				(Skill)new Pestilence(owner)
			};
		}

		public override Skill[] CreateDefensiveCooldowns(Character owner)
		{
			return (Skill[])(object)new Skill[3]
			{
				(Skill)new BoneArmour(owner),
				(Skill)new LifeTap(owner),
				(Skill)new SpiritWard(owner)
			};
		}

		public override CharacterPassive GetClassPassive(Character character)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			CharacterPassive val = new CharacterPassive(character);
			((Passive)val).Name = "Dark Resilience";
			((Passive)val).Description = Locale.GetText("passive_attributes_desc");
			val.Attributes = new(AttributeStat, int, double, bool, bool)[2]
			{
				((AttributeStat)27, 2, 0.2, false, true),
				((AttributeStat)30, 15, 0.0, true, false)
			};
			val.LevelScaling = true;
			((Passive)val).Icon = Resources.Load<Sprite>("Icons/Passives/Barrier");
			((Passive)val).MaxRank = 4;
			val.RequiredLevel = 1;
			return val;
		}

		public override CharacterPassive GetDamagePassive(Character character)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			CharacterPassive val = new CharacterPassive(character);
			((Passive)val).Name = AttributeStore.GetName((AttributeStat)11);
			((Passive)val).Description = Locale.GetText("passive_attribute_desc");
			val.Attributes = new(AttributeStat, int, double, bool, bool)[1] { ((AttributeStat)11, 50, 5.0, true, true) };
			val.LevelScaling = true;
			((Passive)val).Icon = Resources.Load<Sprite>("Icons/Passives/MagicDamage");
			((Passive)val).MaxRank = 4;
			val.RequiredLevel = 20;
			return val;
		}
	}
}
namespace ExpandedRoster.Necromancer.Skills
{
	public class SoulSiphon : DefaultAttack
	{
		private static readonly DamageTypes[] DefaultType;

		public const int BaseHealPercent = 10;

		public const int SoulFeastPerRank = 10;

		public const int DarkReachPenPerRank = 200;

		public const int VoraciousSoulPerRank = 50;

		public const int EssenceOverflowPerRank = 200;

		public const int CrimsonHungerPerRank = 40;

		public const int SoulburnChancePerRank = 200;

		public const int UnholyGraspPerRank = 40;

		public const int SoulReaverHealPerRank = 20;

		public override string Name => "Soul Siphon";

		public override string Description => "Siphon life energy from your target";

		public override SkillID ID => (SkillID)1100;

		public override int LevelRequirement => 1;

		public override int BaseDamage => 800;

		public override int BaseAttackTimeMulti => 900;

		public override int BaseTargets => 1;

		public override int BaseDuration => 0;

		public override DamageTypes[] DamageTypes => DefaultType;

		public override string BonusEffect
		{
			get
			{
				string tooltipPercent = TextHelper.GetTooltipPercent((double)(10 + 10 * ((Skill)this).InspectPassiveRank(1)), false, "#95FF6D", false);
				return TextHelper.GetHtmlText($"Restores {tooltipPercent} of Missing HP on hit.", "#518AD6", false, -1);
			}
		}

		public SoulSiphon(Character character)
		{
			((Skill)this).Character = character;
			((Skill)this).Icon = SpriteHelper.LoadEmbedded("Necromancer.Icons.SoulSiphon") ?? Resources.Load<Sprite>("Icons/Skills/Fireball");
			((Skill)this).GeneratePassives();
			((MasterySkill)this).SetupExperience();
		}

		public override void GeneratePassives()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: 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)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Expected O, but got Unknown
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Expected O, but got Unknown
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Expected O, but got Unknown
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Expected O, but got Unknown
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Expected O, but got Unknown
			Passive[] passives = (Passive[])(object)new MasteryPassive[8]
			{
				new MasteryPassive
				{
					Name = "Soul Feast",
					Description = "{0} restores {1} more Missing HP on hit",
					Icon = Resources.Load<Sprite>("Icons/Talents/Recover"),
					MasteryLevelRequirement = 1,
					MaxRank = 5,
					MasterySkill = (MasterySkill)(object)this
				},
				new MasteryPassive
				{
					Name = "Dark Reach",
					Description = "{0} gains {1} Armour Penetration",
					Icon = Resources.Load<Sprite>("Icons/Talents/Overwhelm"),
					MasteryLevelRequirement = 1,
					MaxRank = 5,
					MasterySkill = (MasterySkill)(object)this
				},
				new MasteryPassive
				{
					Name = "Voracious Soul",
					Description = "{0} grants {1} Healing Effectiveness",
					Icon = Resources.Load<Sprite>("Icons/Talents/Hotspot"),
					MasteryLevelRequirement = 25,
					MaxRank = 5,
					MasterySkill = (MasterySkill)(object)this
				},
				new MasteryPassive
				{
					Name = "Essence Overflow",
					Description = "{0} converts {1} of overhealing into Barrier",
					Icon = Resources.Load<Sprite>("Icons/Talents/Valor"),
					MasteryLevelRequirement = 25,
					MaxRank = 5,
					MasterySkill = (MasterySkill)(object)this
				},
				new MasteryPassive
				{
					Name = "Crimson Hunger",
					Description = "{0} deals {1} More Damage when below 50% HP",
					Icon = Resources.Load<Sprite>("Icons/Talents/ChainStrength"),
					MasteryLevelRequirement = 50,
					MaxRank = 5,
					MasterySkill = (MasterySkill)(object)this
				},
				new MasteryPassive
				{
					Name = "Soulburn",
					Description = TextHelper.ProcTitle + "\n{0} has a {1} chance to apply {2}",
					Icon = Resources.Load<Sprite>("Icons/Talents/Flammability"),
					MasteryLevelRequirement = 50,
					MaxRank = 5,
					MasterySkill = (MasterySkill)(object)this
				},
				new MasteryPassive
				{
					Name = "Unholy Grasp",
					Description = TextHelper.ProcTitle + "\n{0} deals {1} More Damage to targets with a DoT",
					Icon = Resources.Load<Sprite>("Icons/Talents/EngulfingFlames"),
					MasteryLevelRequirement = 75,
					MaxRank = 1,
					MasterySkill = (MasterySkill)(object)this
				},
				new MasteryPassive
				{
					Name = "Soul Reaver",
					Description = "{0} heals {1} of Max HP on kill",
					Icon = Resources.Load<Sprite>("Icons/Talents/RollingFlames"),
					MasteryLevelRequirement = 75,
					MaxRank = 4,
					MasterySkill = (MasterySkill)(object)this
				}
			};
			((Skill)this).Passives = passives;
			((Skill)this).SetupPassivesIDs();
			((Skill)this).Passives[6].ExclusiveWith = ((Skill)this).Passives[7];
			((Skill)this).Passives[7].ExclusiveWith = ((Skill)this).Passives[6];
		}

		public override string[] GeneratePassiveTooltipValues(byte passiveID, int rank)
		{
			return passiveID switch
			{
				1 => new string[2]
				{
					((Skill)this).HtmlName,
					TextHelper.GetTooltipPercent((double)(10 * rank), false, "#95FF6D", false)
				}, 
				2 => new string[2]
				{
					((Skill)this).HtmlName,
					TextHelper.GetHtmlText((200 * rank).ToString(), "#95FF6D", false, -1)
				}, 
				3 => new string[2]
				{
					((Skill)this).HtmlName,
					TextHelper.GetTooltipPercent((double)(50 * rank), false, "#95FF6D", false)
				}, 
				4 => new string[2]
				{
					((Skill)this).HtmlName,
					TextHelper.GetTooltipPercent((double)(200 * rank), false, "#95FF6D", false)
				}, 
				5 => new string[2]
				{
					((Skill)this).HtmlName,
					TextHelper.GetTooltipPercent((double)(40 * rank), false, "#95FF6D", false)
				}, 
				6 => new string[3]
				{
					((Skill)this).HtmlName,
					TextHelper.GetTooltipPercent((double)(200 * rank), false, "#95FF6D", false),
					TextHelper.Disintegrate
				}, 
				7 => new string[2]
				{
					((Skill)this).HtmlName,
					TextHelper.GetTooltipPercent(200.0, false, "#95FF6D", false)
				}, 
				8 => new string[2]
				{
					((Skill)this).HtmlName,
					TextHelper.GetTooltipPercent((double)(25 * rank), false, "#95FF6D", false)
				}, 
				_ => new string[0], 
			};
		}

		public override void PerformSkill()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			if (((Skill)this).Character == null || ((Entity)((Skill)this).Character).ActiveEncounter == null || ((Entity)((Skill)this).Character).IsDead)
			{
				return;
			}
			List<Monster> monsterTargets = ((Entity)((Skill)this).Character).ActiveEncounter.GetMonsterTargets(((Skill)this).Character, ((DefaultAttack)this).Targets, (ICooldownSkill)null);
			if (monsterTargets == null || monsterTargets.Count <= 0)
			{
				return;
			}
			DamageGroup val = new DamageGroup((Entity)(object)((Skill)this).Character, ((Skill)this).GetDamageTypes(), (IDamageSource)(object)this, false);
			int num = ((Skill)this).InspectPassiveRank(2);
			int num2 = ((Skill)this).InspectPassiveRank(3);
			int num3 = ((Skill)this).InspectPassiveRank(4);
			int num4 = ((Skill)this).InspectPassiveRank(5);
			int num5 = ((Skill)this).InspectPassiveRank(6);
			int num6 = ((Skill)this).InspectPassiveRank(7);
			int num7 = ((Skill)this).InspectPassiveRank(8);
			int value = ((AttributeBase)((Entity)((Skill)this).Character).ArmourPenetration).Value;
			if (num > 0)
			{
				ArmourPenetration armourPenetration = ((Entity)((Skill)this).Character).ArmourPenetration;
				((AttributeBase)armourPenetration).Value = ((AttributeBase)armourPenetration).Value + 200 * num;
			}
			bool flag = (double)((Entity)((Skill)this).Character).CurrentHealth / (double)((Entity)((Skill)this).Character).MaxHealth < 0.5;
			foreach (Monster item in monsterTargets)
			{
				if (item == null || ((Entity)item).IsDead)
				{
					continue;
				}
				val.MoreDamage = 1000;
				if (num4 > 0 && flag)
				{
					val.AddMoreDamage(40 * num4);
				}
				if (num6 > 0 && (((Entity)item).GetBuff((BuffID)223) != null || ((Entity)item).GetBuff((BuffID)156) != null || ((Entity)item).IsPoisoned || ((Entity)item).IsBleeding || ((Entity)item).IsIgnited))
				{
					val.AddMoreDamage(200);
				}
				val.SetupDamageRange(((DefaultAttack)this).Damage, 0f);
				if (!((Entity)item).ApplyDamageRoll(val, true, false, (DamageOverTimeType)0, true))
				{
					continue;
				}
				int num8 = 10 + 10 * ((Skill)this).InspectPassiveRank(1);
				float num9 = ((Entity)((Skill)this).Character).MaxHealth - ((Entity)((Skill)this).Character).CurrentHealth;
				float num10 = num9 * (float)num8 / 1000f;
				if (num2 > 0)
				{
					num10 = num10 * (float)(1000 + 50 * num2) / 1000f;
				}
				int num11;
				if (((Skill)this).Character.Ascendancy is Lich lich)
				{
					num11 = (lich.EssenceDrainActive ? 1 : 0);
					if (num11 != 0 && ((Entity)((Skill)this).Character).MaxBarrier > 0f)
					{
						((Entity)((Skill)this).Character).HealBarrier(num10, (IDamageSource)(object)this, false, false, false);
						goto IL_0257;
					}
				}
				else
				{
					num11 = 0;
				}
				((Entity)((Skill)this).Character).HealHealth(num10, (IDamageSource)(object)this, false, false, true);
				goto IL_0257;
				IL_0257:
				if (num11 == 0 && num3 > 0 && ((Entity)((Skill)this).Character).MaxBarrier > 0f)
				{
					float num12 = num10 - num9;
					if (num12 > 0f)
					{
						floa