Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of 2R4RStatUtils v1.0.2
BorboStatUtils.dll
Decompiled 2 years agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using IL.RoR2; using Mono.Cecil.Cil; using MonoMod.Cil; using On.RoR2; using R2API; using R2API.Utils; using RoR2; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("BorboStatUtils")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("BorboStatUtils")] [assembly: AssemblyTitle("BorboStatUtils")] [assembly: AssemblyVersion("1.0.0.0")] namespace BorboStatUtils; [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.HouseOfFruits.2R4RStatUtils", "2R4RStatUtils", "1.0.2")] [R2APISubmoduleDependency(new string[] { "LanguageAPI" })] public class BorboStatUtils : BaseUnityPlugin { public delegate void LuckHookEventHandler(CharacterBody sender, ref float luck); public delegate void ExecuteHookEventHandler(CharacterBody sender, ref float executeThreshold); public const string guid = "com.HouseOfFruits.2R4RStatUtils"; public const string teamName = "HouseOfFruits"; public const string modName = "2R4RStatUtils"; public const string version = "1.0.2"; public const string executeKeywordToken = "2R4R_EXECUTION_KEYWORD"; public const float survivorExecuteThreshold = 0.15f; public static PluginInfo PInfo { get; private set; } public static event LuckHookEventHandler ModifyLuckStat { add { SetLuckHooks(); _modifyLuckStat += value; } remove { _modifyLuckStat -= value; if (BorboStatUtils._modifyLuckStat != null) { Delegate[] invocationList = BorboStatUtils._modifyLuckStat.GetInvocationList(); if (invocationList == null || invocationList.Length != 0) { return; } } UnsetLuckHooks(); } } private static event LuckHookEventHandler _modifyLuckStat; public static event ExecuteHookEventHandler GetExecutionThreshold { add { SetExecutionHooks(); _getExecutionThreshold += value; } remove { _getExecutionThreshold -= value; if (BorboStatUtils._getExecutionThreshold != null) { Delegate[] invocationList = BorboStatUtils._getExecutionThreshold.GetInvocationList(); if (invocationList == null || invocationList.Length != 0) { return; } } UnsetExecutionHooks(); } } private static event ExecuteHookEventHandler _getExecutionThreshold; public void Awake() { LanguageAPI.Add("2R4R_EXECUTION_KEYWORD", "<style=cKeywordName>Finisher</style><style=cSub>Enemies targeted by this skill can be <style=cIsHealth>instantly killed</style> if below " + $"<style=cIsHealth>{15.000001f}% health</style>.</style>"); } internal static void SetLuckHooks() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown CharacterBody.RecalculateStats += new hook_RecalculateStats(RecalculateLuckStat); } internal static void UnsetLuckHooks() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown CharacterBody.RecalculateStats -= new hook_RecalculateStats(RecalculateLuckStat); } private static void RecalculateLuckStat(orig_RecalculateStats orig, CharacterBody self) { orig.Invoke(self); CalculateLuck(self); } public static void CalculateLuck(CharacterBody self) { CharacterMaster master = self.master; if ((Object)(object)master == (Object)null) { return; } float luck = 0f; if (Object.op_Implicit((Object)(object)self) && BorboStatUtils._modifyLuckStat != null) { Delegate[] invocationList = BorboStatUtils._modifyLuckStat.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { LuckHookEventHandler luckHookEventHandler = (LuckHookEventHandler)invocationList[i]; try { luckHookEventHandler(self, ref luck); } catch (Exception ex) { Debug.LogError((object)ex); } } } if (Object.op_Implicit((Object)(object)self.inventory)) { luck += (float)self.inventory.GetItemCount(Items.Clover); luck -= (float)self.inventory.GetItemCount(Items.LunarBadLuck); } master.luck = luck; } internal static void SetExecutionHooks() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown HealthComponent.TakeDamage += new Manipulator(InterceptExecutionThreshold); HealthComponent.GetHealthBarValues += new hook_GetHealthBarValues(DisplayExecutionThreshold); } internal static void UnsetExecutionHooks() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown HealthComponent.TakeDamage -= new Manipulator(InterceptExecutionThreshold); HealthComponent.GetHealthBarValues -= new hook_GetHealthBarValues(DisplayExecutionThreshold); } private static void InterceptExecutionThreshold(ILContext il) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); int thresholdPosition = 0; val.GotoNext((MoveType)2, new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, float.NegativeInfinity), (Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref thresholdPosition) }); val.GotoNext((MoveType)0, new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<HealthComponent>(x, "get_isInFrozenState") }); val.Emit(OpCodes.Ldloc, thresholdPosition); val.Emit(OpCodes.Ldarg, 0); val.EmitDelegate<Func<float, HealthComponent, float>>((Func<float, HealthComponent, float>)((float currentThreshold, HealthComponent hc) => RecalculateExecutionThreshold(currentThreshold, hc))); val.Emit(OpCodes.Stloc, thresholdPosition); } private static float RecalculateExecutionThreshold(float currentThreshold, HealthComponent healthComponent) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) float executeThreshold = currentThreshold; CharacterBody body = healthComponent.body; if ((Object)(object)body != (Object)null && !((Enum)body.bodyFlags).HasFlag((Enum)(object)(BodyFlags)16) && BorboStatUtils._getExecutionThreshold != null) { Delegate[] invocationList = BorboStatUtils._getExecutionThreshold.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { ExecuteHookEventHandler executeHookEventHandler = (ExecuteHookEventHandler)invocationList[i]; try { executeHookEventHandler(body, ref executeThreshold); } catch (Exception ex) { Debug.LogError((object)ex); } } } return executeThreshold; } public static float ModifyExecutionThreshold(float currentThreshold, float newThreshold, bool condition) { if (condition) { currentThreshold = Mathf.Max(currentThreshold, newThreshold); } return currentThreshold; } private static HealthBarValues DisplayExecutionThreshold(orig_GetHealthBarValues orig, HealthComponent self) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) HealthBarValues val = orig.Invoke(self); val.cullFraction = Mathf.Clamp01(RecalculateExecutionThreshold(val.cullFraction, self)); return val; } }