Decompiled source of ExpandedRoster v0.3.0
BepInEx\plugins\ExpandedRoster.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
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