Decompiled source of 2R4RStatUtils v1.0.2

BorboStatUtils.dll

Decompiled a year ago
using 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;
	}
}