Decompiled source of ProcPatcher v1.1.1

ProcPatcher.dll

Decompiled 5 days ago
using 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.Configuration;
using IL.EntityStates.Headstompers;
using IL.RoR2;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using ProcSolver;
using RoR2;
using RoR2.Projectile;
using UnityEngine;
using UnityEngine.AddressableAssets;

[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.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("ProcPatcher")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ProcPatcher")]
[assembly: AssemblyTitle("ProcPatcher")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace ProcPatcher;

[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("com.RiskOfBrainrot.ProcPatcher", "ProcPatcher", "1.1.1")]
public class ProcPatcherPlugin : BaseUnityPlugin
{
	public const string guid = "com.RiskOfBrainrot.ProcPatcher";

	public const string teamName = "RiskOfBrainrot";

	public const string modName = "ProcPatcher";

	public const string version = "1.1.1";

	private static bool procSolverInstalled;

	public static PluginInfo PInfo { get; private set; }

	internal static ConfigFile CustomConfigFile { get; private set; }

	public static ConfigEntry<bool> ShurikenDamageSource { get; set; }

	public static ConfigEntry<bool> HeadstompersDamageSource { get; set; }

	public static ConfigEntry<bool> BleedChanceProcCoeff { get; set; }

	public static ConfigEntry<bool> RunicLensProcCoeff { get; set; }

	public static ConfigEntry<bool> ElectricBoomerangProcCoeff { get; set; }

	private void Awake()
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Expected O, but got Unknown
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Expected O, but got Unknown
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Expected O, but got Unknown
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		procSolverInstalled = Chainloader.PluginInfos.ContainsKey("com.RiskOfBrainrot.ProcSolver");
		CustomConfigFile = new ConfigFile(Paths.ConfigPath + "\\ProcPatcher.cfg", true);
		ShurikenDamageSource = CustomConfigFile.Bind<bool>("Proc Patcher : Damage Source", "Shuriken Damage Source", true, "Should Proc Patcher set Shuriken's Damage Source to Primary?");
		HeadstompersDamageSource = CustomConfigFile.Bind<bool>("Proc Patcher : Damage Source", "Headstompers Damage Source", true, "Should Proc Patcher set Headstompers's Damage Source to Primary?");
		BleedChanceProcCoeff = CustomConfigFile.Bind<bool>("Proc Patcher : Proc Coeff Interactions", "Should Bleed Proc Chance Be Affected By Proc Coefficient", true, "Should Bleed Proc Chance Be Affected By Proc Coefficient");
		RunicLensProcCoeff = CustomConfigFile.Bind<bool>("Proc Patcher : Proc Coeff Interactions", "Should Runic Lens Proc Chance Be Affected By Proc Coefficient", true, "Should Runic Lens Proc Chance Be Affected By Proc Coefficient");
		ElectricBoomerangProcCoeff = CustomConfigFile.Bind<bool>("Proc Patcher : Proc Coeff Interactions", "Should Electric Boomerang Proc Chance Be Affected By Proc Coefficient", true, "Should Electric Boomerang Proc Chance Be Affected By Proc Coefficient");
		GlobalEventManager.ProcessHitEnemy += new Manipulator(ProcCoeffFix_OnHitEnemy);
		if (ShurikenDamageSource.Value)
		{
			GameObject val = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/DLC1/PrimarySkillShuriken/ShurikenProjectile.prefab").WaitForCompletion();
			if ((Object)(object)val != (Object)null)
			{
				ProjectileDamage component = val.GetComponent<ProjectileDamage>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.damageType.damageSource = (DamageSource)1;
				}
			}
		}
		if (HeadstompersDamageSource.Value)
		{
			HeadstompersFall.DoStompExplosionAuthority += new Manipulator(DoHeadstompersDamageSource);
		}
	}

	private void DoHeadstompersDamageSource(ILContext il)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Expected O, but got Unknown
		ILCursor val = new ILCursor(il);
		if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
		{
			(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<BlastAttack>(x, "Fire")
		}))
		{
			val.EmitDelegate<Func<BlastAttack, BlastAttack>>((Func<BlastAttack, BlastAttack>)delegate(BlastAttack blastAttack)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				blastAttack.damageType.damageSource = (DamageSource)1;
				return blastAttack;
			});
		}
	}

	private void ProcCoeffFix_OnHitEnemy(ILContext il)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Expected O, but got Unknown
		ILCursor c = new ILCursor(il);
		FixChanceForProcItem(c, "RoR2.RoR2Content/Items", "BleedOnHitAndExplode", isChainProc: false, BleedChanceProcCoeff.Value);
		FixChanceForProcItem(c, "RoR2.RoR2Content/Items", "Missile");
		FixChanceForProcItem(c, "RoR2.DLC1Content/Items", "MissileVoid");
		FixChanceForProcItem(c, "RoR2.RoR2Content/Items", "ChainLightning");
		FixChanceForProcItem(c, "RoR2.DLC1Content/Items", "ChainLightningVoid");
		FixChanceForProcItem(c, "RoR2.RoR2Content/Items", "BounceNearby");
		FixChanceForProcItem(c, "RoR2.RoR2Content/Items", "StickyBomb", isChainProc: false);
		FixChanceForProcItem(c, "RoR2.RoR2Content/Items", "FireballsOnHit");
		FixChanceForProcItem(c, "RoR2.RoR2Content/Items", "LightningStrikeOnHit");
		FixChanceForProcItem(c, "RoR2.DLC2Content/Items", "MeteorAttackOnHighDamage", isChainProc: true, RunicLensProcCoeff.Value);
		FixChanceForProcItem(c, "RoR2.DLC2Content/Items", "StunAndPierce", isChainProc: true, ElectricBoomerangProcCoeff.Value);
	}

	private void FixChanceForProcItem(ILCursor c, string a, string b, bool isChainProc = true, bool fixProcCoeff = true)
	{
		//IL_0113: 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)
		c.Index = 0;
		if (!c.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
		{
			(Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, a, b),
			(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, "RoR2.Inventory", "GetItemCount")
		}))
		{
			Debug.LogError((object)(b + " Proc Hook Failed"));
		}
		else if (c.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
		{
			(Instruction x) => ILPatternMatchingExt.MatchLdfld<DamageInfo>(x, "procCoefficient")
		}))
		{
			c.Remove();
			c.EmitDelegate<Func<DamageInfo, float>>((Func<DamageInfo, float>)delegate(DamageInfo damageInfo)
			{
				float num2 = 1f;
				if (isChainProc)
				{
					num2 *= GetProcRate(damageInfo);
				}
				if (!fixProcCoeff)
				{
					num2 *= damageInfo.procCoefficient;
				}
				return num2;
			});
			Debug.Log((object)(b + " Proc Hook Success"));
		}
		else if (isChainProc && procSolverInstalled)
		{
			c.Emit(OpCodes.Ldarg_1);
			c.Emit(OpCodes.Ldloc, 6);
			c.EmitDelegate<Func<int, DamageInfo, CharacterMaster, int>>((Func<int, DamageInfo, CharacterMaster, int>)delegate(int itemCount, DamageInfo damageInfo, CharacterMaster master)
			{
				float num = _GetProcRate(damageInfo);
				return Util.CheckRoll(num * 100f, master) ? itemCount : 0;
			});
		}
	}

	public static float GetProcRate(DamageInfo damageInfo)
	{
		if (!procSolverInstalled)
		{
			return 1f;
		}
		return _GetProcRate(damageInfo);
	}

	[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
	private static float _GetProcRate(DamageInfo damageInfo)
	{
		return ProcSolverPlugin.GetProcRateMod(damageInfo);
	}
}