Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of HealthComponentAPI v1.2.1
HealthComponentAPI.dll
Decompiled a year agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Logging; using HDeMods.HCAPI; using IL.RoR2; using Microsoft.CodeAnalysis; using Mono.Cecil.Cil; using MonoMod.Cil; using On.RoR2; using RoR2; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("HDeDeDe")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright (c) HDeDeDe/Ethan 2024")] [assembly: AssemblyDescription("is api for healthcomponent. designed to be like RecalculateStatsAPI.")] [assembly: AssemblyFileVersion("1.2.1")] [assembly: AssemblyInformationalVersion("1.2.1+2f724521b7cd62c70872839156738b43f145be6a")] [assembly: AssemblyProduct("HealthComponentAPI")] [assembly: AssemblyTitle("HealthComponentAPI")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/HDeDeDe/HealthComponentAPI")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.1.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 HDeMods { public static class HealthComponentAPI { public delegate void UpdateHealthEventHandler(HealthComponent sender, UpdateHealthEventArgs args); public delegate void HealEventHandler(HealthComponent sender, HealEventArgs args); public delegate void TakeDamageEventHandler(HealthComponent sender, in DamageInfo damageInfo, TakeDamageArgs args); public class UpdateHealthEventArgs : EventArgs { public float finalRegenMultAdd; public float finalRegenFlatAdd; public float barrierDecayRateMultAdd; public float barrierDecayRateFlatAdd; public float shieldRechargeRateMultAdd; public float shieldRechargeRateFlatAdd; public float adaptiveArmorDecayRateMultAdd; public float adaptiveArmorDecayRateFlatAdd; } public class HealEventArgs : EventArgs { public bool enableEclipseHealReduction; public float damageCoyoteTimerMultAdd; public float damageCoyoteTimerFlatAdd; public float critHealMultAdd; public float critHealFlatAdd; public float finalHealAmountMultAdd; public float finalHealAmountFlatAdd; } public class TakeDamageArgs : EventArgs { public bool rejectDamage; public bool rejectForce; public float adaptiveArmorBuildRateMultAdd; public float adaptiveArmorBuildRateFlatAdd; public float adaptiveArmorMaxMultAdd; public float adaptiveArmorMaxFlatAdd; public float finalDamageAmountMultAdd; public float finalDamageAmountFlatAdd; public float damageForceMultAdd; public Vector3 damageForceFlatAdd = Vector3.zero; } [CompilerGenerated] private static class <>O { public static Manipulator <0>__HealthComponent_ServerFixedUpdate; public static Manipulator <1>__HealthComponent_Heal; public static Manipulator <2>__HealthComponent_TakeDamageProcess_Heal; public static Manipulator <3>__HealthComponent_TakeDamageProcess; public static Action<HealthComponent> <4>__GetHealthMod; public static Action<HealthComponent> <5>__GetHealMod; public static Action<HealthComponent, DamageInfo> <6>__GetTakeDamageMod; public static hook_TakeDamageProcess <7>__HealthComponent_TakeDamageProcess; public static hook_Heal <8>__HealthComponent_Heal; } private static UpdateHealthEventArgs HealthStats; private static HealEventArgs HealStats; private static TakeDamageArgs TakeDamageStats; private static bool _healthHookSet; private static bool _healHooksSet; private static bool _takeDamageHooksSet; public const string PluginGUID = "HDeDeDe.HealthComponentAPI"; public const string PluginAuthor = "HDeDeDe"; public const string PluginName = "HealthComponentAPI"; public const string PluginVersion = "1.2.1"; private static event UpdateHealthEventHandler _getHealthStats; private static event HealEventHandler _getHealStats; private static event TakeDamageEventHandler _getTakeDamageStats; public static event Action<HealthComponent, DamageInfo> OnTakeDamageProcess; public static event Func<HealthComponent, float, ProcChainMask, bool, float> OnHealServerProcess; public static event UpdateHealthEventHandler GetHealthStats { add { SetHealthHook(); _getHealthStats += value; } remove { _getHealthStats -= value; if (HealthComponentAPI._getHealthStats != null) { Delegate[] invocationList = HealthComponentAPI._getHealthStats.GetInvocationList(); if (invocationList == null || invocationList.Length != 0) { return; } } UnsetHealthHook(); } } public static event HealEventHandler GetHealStats { add { SetHealHooks(); _getHealStats += value; } remove { _getHealStats -= value; if (HealthComponentAPI._getHealStats != null) { Delegate[] invocationList = HealthComponentAPI._getHealStats.GetInvocationList(); if (invocationList == null || invocationList.Length != 0) { return; } } UnsetHealHooks(); } } public static event TakeDamageEventHandler GetTakeDamageStats { add { SetTakeDamageHooks(); _getTakeDamageStats += value; } remove { _getTakeDamageStats -= value; if (HealthComponentAPI._getTakeDamageStats != null) { Delegate[] invocationList = HealthComponentAPI._getTakeDamageStats.GetInvocationList(); if (invocationList == null || invocationList.Length != 0) { return; } } UnsetTakeDamageHooks(); } } internal static void SetHealthHook() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown if (!_healthHookSet) { object obj = <>O.<0>__HealthComponent_ServerFixedUpdate; if (obj == null) { Manipulator val = HealthComponent_ServerFixedUpdate; <>O.<0>__HealthComponent_ServerFixedUpdate = val; obj = (object)val; } HealthComponent.ServerFixedUpdate += (Manipulator)obj; _healthHookSet = true; } } internal static void UnsetHealthHook() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown object obj = <>O.<0>__HealthComponent_ServerFixedUpdate; if (obj == null) { Manipulator val = HealthComponent_ServerFixedUpdate; <>O.<0>__HealthComponent_ServerFixedUpdate = val; obj = (object)val; } HealthComponent.ServerFixedUpdate -= (Manipulator)obj; _healthHookSet = false; } internal static void SetHealHooks() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown if (!_healHooksSet) { object obj = <>O.<1>__HealthComponent_Heal; if (obj == null) { Manipulator val = HealthComponent_Heal; <>O.<1>__HealthComponent_Heal = val; obj = (object)val; } HealthComponent.Heal += (Manipulator)obj; object obj2 = <>O.<2>__HealthComponent_TakeDamageProcess_Heal; if (obj2 == null) { Manipulator val2 = HealthComponent_TakeDamageProcess_Heal; <>O.<2>__HealthComponent_TakeDamageProcess_Heal = val2; obj2 = (object)val2; } HealthComponent.TakeDamageProcess += (Manipulator)obj2; _healHooksSet = true; } } internal static void UnsetHealHooks() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown object obj = <>O.<1>__HealthComponent_Heal; if (obj == null) { Manipulator val = HealthComponent_Heal; <>O.<1>__HealthComponent_Heal = val; obj = (object)val; } HealthComponent.Heal -= (Manipulator)obj; object obj2 = <>O.<2>__HealthComponent_TakeDamageProcess_Heal; if (obj2 == null) { Manipulator val2 = HealthComponent_TakeDamageProcess_Heal; <>O.<2>__HealthComponent_TakeDamageProcess_Heal = val2; obj2 = (object)val2; } HealthComponent.TakeDamageProcess -= (Manipulator)obj2; _healHooksSet = false; } internal static void SetTakeDamageHooks() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown if (!_takeDamageHooksSet) { object obj = <>O.<3>__HealthComponent_TakeDamageProcess; if (obj == null) { Manipulator val = HealthComponent_TakeDamageProcess; <>O.<3>__HealthComponent_TakeDamageProcess = val; obj = (object)val; } HealthComponent.TakeDamageProcess += (Manipulator)obj; _takeDamageHooksSet = true; } } internal static void UnsetTakeDamageHooks() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown object obj = <>O.<3>__HealthComponent_TakeDamageProcess; if (obj == null) { Manipulator val = HealthComponent_TakeDamageProcess; <>O.<3>__HealthComponent_TakeDamageProcess = val; obj = (object)val; } HealthComponent.TakeDamageProcess -= (Manipulator)obj; _takeDamageHooksSet = false; } private static void GetHealthMod(HealthComponent hc) { HealthStats = new UpdateHealthEventArgs(); if (HealthComponentAPI._getHealthStats == null) { return; } Delegate[] invocationList = HealthComponentAPI._getHealthStats.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { UpdateHealthEventHandler updateHealthEventHandler = (UpdateHealthEventHandler)invocationList[i]; try { updateHealthEventHandler(hc, HealthStats); } catch (Exception arg) { Log.Error($"Exception thrown by : {updateHealthEventHandler.Method.DeclaringType?.Name}.{updateHealthEventHandler.Method.Name}:\n{arg}"); } } } private static void GetHealMod(HealthComponent hc) { HealStats = new HealEventArgs(); if (HealthComponentAPI._getHealStats == null) { return; } Delegate[] invocationList = HealthComponentAPI._getHealStats.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { HealEventHandler healEventHandler = (HealEventHandler)invocationList[i]; try { healEventHandler(hc, HealStats); } catch (Exception arg) { Log.Error($"Exception thrown by : {healEventHandler.Method.DeclaringType?.Name}.{healEventHandler.Method.Name}:\n{arg}"); } } } private static void GetTakeDamageMod(HealthComponent hc, DamageInfo dm) { TakeDamageStats = new TakeDamageArgs(); if (HealthComponentAPI._getTakeDamageStats == null) { return; } Delegate[] invocationList = HealthComponentAPI._getTakeDamageStats.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { TakeDamageEventHandler takeDamageEventHandler = (TakeDamageEventHandler)invocationList[i]; try { takeDamageEventHandler(hc, in dm, TakeDamageStats); } catch (Exception arg) { Log.Error($"Exception thrown by : {takeDamageEventHandler.Method.DeclaringType?.Name}.{takeDamageEventHandler.Method.Name}:\n{arg}"); } } } private static void HealthComponent_ServerFixedUpdate(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0008: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Action<HealthComponent>>((Action<HealthComponent>)GetHealthMod); RecalcFinalRegenAccumulator(val); RecalcBarrierDecayRate(val); RecalcShieldRechargeRate(val); RecalcAdaptiveArmorDecayRate(val); } private static void HealthComponent_Heal(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0008: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Action<HealthComponent>>((Action<HealthComponent>)GetHealMod); RecalcCoyoteTimer(val); RecalcCritHeal(val); HalveHealing(val); RecalcFinalHeal(val); } private static void HealthComponent_TakeDamageProcess_Heal(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0008: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Action<HealthComponent>>((Action<HealthComponent>)GetHealMod); RecalcCoyoteTimer(val); } private static void HealthComponent_TakeDamageProcess(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Ldarg_1); val.EmitDelegate<Action<HealthComponent, DamageInfo>>((Action<HealthComponent, DamageInfo>)GetTakeDamageMod); RecalcDamageForce(val); RejectDamageCheck(val); RecalcAdaptiveArmorBuildRate(val); RecalcAdaptiveArmorMax(val); RecalcFinalDamage(val); } internal static void AddOnHooks() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown object obj = <>O.<7>__HealthComponent_TakeDamageProcess; if (obj == null) { hook_TakeDamageProcess val = HealthComponent_TakeDamageProcess; <>O.<7>__HealthComponent_TakeDamageProcess = val; obj = (object)val; } HealthComponent.TakeDamageProcess += (hook_TakeDamageProcess)obj; object obj2 = <>O.<8>__HealthComponent_Heal; if (obj2 == null) { hook_Heal val2 = HealthComponent_Heal; <>O.<8>__HealthComponent_Heal = val2; obj2 = (object)val2; } HealthComponent.Heal += (hook_Heal)obj2; } internal static void RemoveOnHooks() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown object obj = <>O.<7>__HealthComponent_TakeDamageProcess; if (obj == null) { hook_TakeDamageProcess val = HealthComponent_TakeDamageProcess; <>O.<7>__HealthComponent_TakeDamageProcess = val; obj = (object)val; } HealthComponent.TakeDamageProcess -= (hook_TakeDamageProcess)obj; object obj2 = <>O.<8>__HealthComponent_Heal; if (obj2 == null) { hook_Heal val2 = HealthComponent_Heal; <>O.<8>__HealthComponent_Heal = val2; obj2 = (object)val2; } HealthComponent.Heal -= (hook_Heal)obj2; } private static float HealthComponent_Heal(orig_Heal orig, HealthComponent self, float amount, ProcChainMask procChainMask, bool nonRegen = true) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { Debug.LogWarning((object)"[Server] function 'System.Single RoR2.HealthComponent::Heal(System.Single, RoR2.ProcChainMask, System.Boolean)' called on client"); return 0f; } HealthComponentAPI.OnHealServerProcess?.Invoke(self, amount, procChainMask, nonRegen); return orig.Invoke(self, amount, procChainMask, nonRegen); } private static void HealthComponent_TakeDamageProcess(orig_TakeDamageProcess orig, HealthComponent self, DamageInfo damageInfo) { HealthComponentAPI.OnTakeDamageProcess?.Invoke(self, damageInfo); orig.Invoke(self, damageInfo); } private static void RecalcCoyoteTimer(ILCursor c) { if (!c.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchStfld<HealthComponent>(x, "recentlyTookDamageCoyoteTimer") })) { Log.Fatal("Failed to hook Coyote Timer!"); Log.Fatal(c.Context); } else { c.EmitDelegate<Func<float, float>>((Func<float, float>)((float damageCoyoteTimer) => damageCoyoteTimer * (1f + HealStats.damageCoyoteTimerMultAdd) + HealStats.damageCoyoteTimerFlatAdd)); } } private static void RecalcCritHeal(ILCursor c) { ILLabel val = default(ILLabel); float num = default(float); if (!c.TryGotoNext(new Func<Instruction, bool>[5] { (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, 1), (Instruction x) => ILPatternMatchingExt.MatchBrfalse(x, ref val), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 1), (Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, ref num), (Instruction x) => ILPatternMatchingExt.MatchMul(x) })) { Log.Fatal("Failed to hook Crit Heal!"); Log.Fatal(c.Context); return; } c.Index += 4; c.EmitDelegate<Func<float, float>>((Func<float, float>)((float critHealMultiplier) => critHealMultiplier * (1f + HealStats.critHealMultAdd) + HealStats.critHealFlatAdd)); } private static void HalveHealing(ILCursor c) { if (c.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallvirt<TeamComponent>(x, "get_teamIndex") })) { c.EmitDelegate<Func<sbyte, sbyte>>((Func<sbyte, sbyte>)((sbyte teamIndex) => (sbyte)(HealStats.enableEclipseHealReduction ? 1 : teamIndex))); } else { Log.Error("Failed to hook teamIndex! Attempting healing hook."); Log.Error(c.Context); } if (!c.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallvirt<Run>(x, "get_selectedDifficulty") })) { Log.Fatal("Failed to hook Eclipse 5 healing!"); Log.Fatal(c.Context); } else { c.EmitDelegate<Func<int, int>>((Func<int, int>)((int difficulty) => (!HealStats.enableEclipseHealReduction) ? difficulty : 7)); } } private static void RecalcFinalHeal(ILCursor c) { //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) if (OptionalMods.MoreStats.enabled) { int num = default(int); if (!c.TryGotoNext((MoveType)2, new Func<Instruction, bool>[3] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 1), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, ref num) })) { Log.Fatal("Failed to hook Final Healing with MoreStats!"); Log.Fatal(c.Context); return; } c.Index += 2; } else { if (!c.TryGotoNext(new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 1), (Instruction x) => ILPatternMatchingExt.MatchStloc(x, 2) })) { Log.Fatal("Failed to hook Final Healing!"); Log.Fatal(c.Context); return; } c.Index += 1; } c.EmitDelegate<Func<float, float>>((Func<float, float>)((float finalHeal) => finalHeal * (1f + HealStats.finalHealAmountMultAdd) + HealStats.finalHealAmountFlatAdd)); c.Emit(OpCodes.Starg, 1); c.Emit(OpCodes.Ldarg_1); } private static void RecalcFinalRegenAccumulator(ILCursor c) { if (!c.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallvirt<CharacterBody>(x, "get_regen") })) { Log.Fatal("Failed to hook Regen Accumulator!"); Log.Fatal(c.Context); } else { c.EmitDelegate<Func<float, float>>((Func<float, float>)((float regen) => regen * (1f + HealthStats.finalRegenMultAdd) + HealthStats.finalRegenFlatAdd)); } } private static void RecalcBarrierDecayRate(ILCursor c) { if (!c.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallvirt<CharacterBody>(x, "get_barrierDecayRate") })) { Log.Fatal("Failed to hook Barrier Decay Rate!"); Log.Fatal(c.Context); } else { c.EmitDelegate<Func<float, float>>((Func<float, float>)((float barrierDecayRate) => barrierDecayRate * (1f + HealthStats.barrierDecayRateMultAdd) + HealthStats.barrierDecayRateFlatAdd)); } } private static void RecalcShieldRechargeRate(ILCursor c) { float num = default(float); if (!c.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchCallvirt<CharacterBody>(x, "get_maxShield"), (Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, ref num) })) { Log.Fatal("Failed to hook Shield Recharge Rate!"); Log.Fatal(c.Context); } else { c.EmitDelegate<Func<float, float>>((Func<float, float>)((float shieldRechargeRate) => shieldRechargeRate * (1f + HealthStats.shieldRechargeRateMultAdd) + HealthStats.shieldRechargeRateFlatAdd)); } } private static void RecalcAdaptiveArmorDecayRate(ILCursor c) { float num = default(float); if (!c.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchLdfld<HealthComponent>(x, "adaptiveArmorValue"), (Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, ref num) })) { Log.Fatal("Failed to hook Adaptive Armor Decay Rate!"); Log.Fatal(c.Context); } else { c.EmitDelegate<Func<float, float>>((Func<float, float>)((float adaptiveArmorDecayRate) => adaptiveArmorDecayRate * (1f + HealthStats.adaptiveArmorDecayRateMultAdd) + HealthStats.adaptiveArmorDecayRateFlatAdd)); } } private static void RecalcDamageForce(ILCursor c) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) ILLabel val = default(ILLabel); if (!c.TryGotoNext(new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchLdfld<DamageInfo>(x, "canRejectForce"), (Instruction x) => ILPatternMatchingExt.MatchBrtrue(x, ref val) })) { Log.Fatal("Failed to hook Reject Force!"); Log.Fatal(c.Context); return; } c.Index += 1; c.EmitDelegate<Func<bool, bool>>((Func<bool, bool>)((bool reject) => !TakeDamageStats.rejectForce && reject)); c.Emit(OpCodes.Ldarg_1); c.EmitDelegate<Action<DamageInfo>>((Action<DamageInfo>)delegate(DamageInfo dm) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (TakeDamageStats.rejectForce) { dm.canRejectForce = false; } dm.force *= 1f + TakeDamageStats.damageForceMultAdd; dm.force += TakeDamageStats.damageForceFlatAdd; }); } private static void RejectDamageCheck(ILCursor c) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) ILLabel val = default(ILLabel); if (!c.TryGotoNext((MoveType)0, new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchLdfld<DamageInfo>(x, "rejected"), (Instruction x) => ILPatternMatchingExt.MatchBrfalse(x, ref val) })) { Log.Fatal("Failed to hook Reject Damage!"); Log.Fatal(c.Context); return; } c.EmitDelegate<Action<DamageInfo>>((Action<DamageInfo>)delegate(DamageInfo dm) { if (TakeDamageStats.rejectDamage) { dm.rejected = true; } }); c.Emit(OpCodes.Ldarg_1); } private static void RecalcAdaptiveArmorBuildRate(ILCursor c) { float num = default(float); if (!c.TryGotoNext(new Func<Instruction, bool>[4] { (Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, ref num), (Instruction x) => ILPatternMatchingExt.MatchMul(x), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdflda<HealthComponent>(x, "itemCounts") })) { Log.Fatal("Failed to hook Adaptive Armor Build Rate!"); Log.Fatal(c.Context); return; } c.Index += 1; c.EmitDelegate<Func<float, float>>((Func<float, float>)((float adaptiveArmorBuildRate) => adaptiveArmorBuildRate * (1f + TakeDamageStats.adaptiveArmorBuildRateMultAdd) + TakeDamageStats.adaptiveArmorBuildRateFlatAdd)); } private static void RecalcAdaptiveArmorMax(ILCursor c) { int num2 = default(int); float num = default(float); if (!c.TryGotoNext((MoveType)2, new Func<Instruction, bool>[4] { (Instruction x) => ILPatternMatchingExt.MatchLdfld<HealthComponent>(x, "adaptiveArmorValue"), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num2), (Instruction x) => ILPatternMatchingExt.MatchAdd(x), (Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, ref num) })) { Log.Fatal("Failed to hook Adaptive Armor Max Value!"); Log.Fatal(c.Context); } else { c.EmitDelegate<Func<float, float>>((Func<float, float>)((float adaptiveArmorMaxValue) => adaptiveArmorMaxValue * (1f + TakeDamageStats.adaptiveArmorMaxMultAdd) + TakeDamageStats.adaptiveArmorMaxFlatAdd)); } } private static void RecalcFinalDamage(ILCursor c) { //IL_006a: 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_00a9: Unknown result type (might be due to invalid IL or missing references) ILLabel val = default(ILLabel); if (!c.TryGotoNext((MoveType)0, new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchLdfld<DamageInfo>(x, "canRejectForce"), (Instruction x) => ILPatternMatchingExt.MatchBrfalse(x, ref val) })) { Log.Fatal("Failed to hook Final Damage!"); Log.Fatal(c.Context); return; } c.Emit(OpCodes.Ldloc, 7); c.Emit(OpCodes.Ldarg_1); c.EmitDelegate<Func<float, DamageInfo, float>>((Func<float, DamageInfo, float>)delegate(float damageToDeal, DamageInfo dm) { dm.damage = dm.damage * (1f + TakeDamageStats.finalDamageAmountMultAdd) + TakeDamageStats.finalDamageAmountFlatAdd; return damageToDeal * (1f + TakeDamageStats.finalDamageAmountMultAdd) + TakeDamageStats.finalDamageAmountFlatAdd; }); c.Emit(OpCodes.Stloc, 7); } } [BepInPlugin("HDeDeDe.HealthComponentAPI", "HealthComponentAPI", "1.2.1")] public sealed class HealthComponentAPIPlugin : BaseUnityPlugin { private void Awake() { Log.Init(((BaseUnityPlugin)this).Logger); HealthComponentAPI.AddOnHooks(); } private void OnDestroy() { HealthComponentAPI.UnsetHealthHook(); HealthComponentAPI.UnsetHealHooks(); HealthComponentAPI.UnsetTakeDamageHooks(); HealthComponentAPI.RemoveOnHooks(); } } public class OptionalMods { internal class SandSwept { private static bool enabled => Chainloader.PluginInfos.ContainsKey("com.TeamSandswept.Sandswept"); } internal class Hex3 { private static bool enabled => Chainloader.PluginInfos.ContainsKey("com.Hex3.Hex3Mod"); } internal class MoreStats { public static bool enabled => Chainloader.PluginInfos.ContainsKey("com.RiskOfBrainrot.MoreStats"); } } internal static class HcRefVal { public const float shieldRechargeRate = 0.5f; public const float barrierDecayRate = 30f; public const float adaptiveArmorDecayRate = 40f; public const TeamIndex plr = 1; public const DifficultyIndex e5 = 7; public const float critHealMultiplier = 2f; public const float damageCoyoteTimer = 0.2f; public const float adaptiveArmorBuildRate = 30f; public const float adaptiveArmorMaxValue = 400f; } } namespace HDeMods.HCAPI { internal static class Log { private static ManualLogSource m_logSource; internal static void Init(ManualLogSource logSource) { m_logSource = logSource; } internal static void Debug(object data) { m_logSource.LogDebug(data); } internal static void Error(object data) { m_logSource.LogError(data); } internal static void Fatal(object data) { m_logSource.LogFatal(data); } internal static void Info(object data) { m_logSource.LogInfo(data); } internal static void Message(object data) { m_logSource.LogMessage(data); } internal static void Warning(object data) { m_logSource.LogWarning(data); } } }