Decompiled source of PedanticItemStackChanges v1.0.2

StackChanges.dll

Decompiled 11 hours ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using IL.RoR2;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On.RoR2.Projectile;
using R2API;
using RoR2;
using RoR2.Projectile;
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.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("StackChanges")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ccda5084511894f1e75b3ba350d8409188b9502e")]
[assembly: AssemblyProduct("StackChanges")]
[assembly: AssemblyTitle("StackChanges")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace StackChanges;

[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("com.Sagittariod.StackChanges", "Pedantic Item Stack Changes", "1.0.2")]
public class StackChanges : BaseUnityPlugin
{
	public static ConfigEntry<float> chronicExpansionBaseBuffValue;

	public static ConfigEntry<float> chronicExpansionAdditiveBuffValue;

	public static ConfigEntry<float> bolsteringLanternBaseBuffValue;

	public static ConfigEntry<float> bolsteringLanternAdditiveBuffValue;

	public static ConfigEntry<float> dynamiteFirstStackDamage;

	public static ConfigEntry<float> dynamiteAdditionalStackDamage;

	public static ConfigEntry<float> luminousShotFirstStackDamage;

	public static ConfigEntry<float> luminousShotAdditionalStackDamage;

	public static ConfigEntry<float> eclipseLiteBaseBarrier;

	public static ConfigEntry<float> eclipseLiteStackBarrier;

	public static ConfigEntry<float> runicLensBaseProcChance;

	public static ConfigEntry<float> runicLensStackProcChance;

	public static ConfigEntry<int> warBondsBaseBuffCount;

	public static ConfigEntry<int> warBondsStackBuffCount;

	public static StackChanges Instance { get; private set; }

	public void Awake()
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Expected O, but got Unknown
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Expected O, but got Unknown
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Expected O, but got Unknown
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Expected O, but got Unknown
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Expected O, but got Unknown
		BindConfigs();
		UpdateItemDescriptions();
		Harmony val = new Harmony("com.Sagittariod.StackChanges");
		val.PatchAll();
		ProjectileController.Start += new hook_Start(ProjectileController_Start);
		RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(RecalculateStatsAPI_GetStatCoefficients);
		CharacterBody.OnSkillCooldown += new Manipulator(CharacterBody_OnSkillCooldown_IL);
		GlobalEventManager.ProcessHitEnemy += new Manipulator(GlobalEventManager_ProcessHitEnemy_IL);
	}

	private void BindConfigs()
	{
		chronicExpansionBaseBuffValue = ((BaseUnityPlugin)this).Config.Bind<float>("Chronic Expansion", "First Stack Buff", 0.035f, "Vanilla = 0.035");
		chronicExpansionAdditiveBuffValue = ((BaseUnityPlugin)this).Config.Bind<float>("Chronic Expansion", "Additional Stack Buff", 0.0175f, "Vanilla = 0.01");
		bolsteringLanternBaseBuffValue = ((BaseUnityPlugin)this).Config.Bind<float>("Bolstering Lantern", "First Stack Buff", 0.1f, "Vanilla = 0.1");
		bolsteringLanternAdditiveBuffValue = ((BaseUnityPlugin)this).Config.Bind<float>("Bolstering Lantern", "Additional Stack Buff", 0.05f, "Vanilla = 0.035");
		dynamiteFirstStackDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Box of Dynamite", "Base Damage Coefficient", 2.4f, "Vanilla = 2.4");
		dynamiteAdditionalStackDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Box of Dynamite", "Extra Damage Coefficient per Stack", 2.4f, "Vanilla = 0.85");
		luminousShotFirstStackDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Luminous Shot", "Base Damage Coefficient", 1.2f, "Vanilla = 1.75");
		luminousShotAdditionalStackDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Luminous Shot", "Extra Damage Coefficient per Stack", 0.6f, "Vanilla = 0.5");
		eclipseLiteBaseBarrier = ((BaseUnityPlugin)this).Config.Bind<float>("Eclipse Lite", "Base Barrier", 0.008f, "Vanilla = 0.01");
		eclipseLiteStackBarrier = ((BaseUnityPlugin)this).Config.Bind<float>("Eclipse Lite", "Extra Barrier per Stack", 0.004f, "Vanilla = 0.0025");
		runicLensBaseProcChance = ((BaseUnityPlugin)this).Config.Bind<float>("Runic Lens", "Base Chance Increase per 100% Damage", 3f, "Vanilla = 3.0");
		runicLensStackProcChance = ((BaseUnityPlugin)this).Config.Bind<float>("Runic Lens", "Extra Chance Increase per 100% Damage per Stack", 0f, "Vanilla = 3.0");
		warBondsBaseBuffCount = ((BaseUnityPlugin)this).Config.Bind<int>("War Bonds", "Base Max Buff Count", 15, "Vanilla = 15");
		warBondsStackBuffCount = ((BaseUnityPlugin)this).Config.Bind<int>("War Bonds", "Extra Max Buff Count per Stack", 0, "Vanilla = 5");
	}

	private void UpdateItemDescriptions()
	{
		LanguageAPI.Add("ITEM_INCREASEDAMAGEONMULTIKILL_DESC", $"Killing an enemy increases your damage by <style=cIsDamage>{chronicExpansionBaseBuffValue.Value * 100f}%</style> <style=cStack>(+{chronicExpansionAdditiveBuffValue.Value * 100f}% per stack)</style>, up to <style=cIsUtility>10</style> <style=cStack>(+5 per stack)</style>, for <style=cIsUtility>7s</style>. Dealing damage refreshes the timer.");
		LanguageAPI.Add("ITEM_ATTACKSPEEDPERNEARBYALLYORENEMY_DESC", $"Increase your <style=cIsDamage>attack speed</style> by <style=cIsDamage>{bolsteringLanternBaseBuffValue.Value * 100f}%</style> <style=cStack>(+{bolsteringLanternAdditiveBuffValue.Value * 100f}% per stack)</style> for up to <style=cIsUtility>3</style> <style=cStack>(+1 per stack)</style> enemies and allies within <style=cIsUtility>20</style> meters.");
		LanguageAPI.Add("ITEM_DRONESDROPDYNAMITE_DESC", $"Gain <style=cIsDamage>Lt. Droneboy</style>. While in combat, your drones drop sticks of dynamite that detonate for <style=cIsDamage>{dynamiteFirstStackDamage.Value * 100f}% damage</style> <style=cStack>(+{dynamiteAdditionalStackDamage.Value * 100f}% per stack)</style>, stunning enemies. Recharges after <style=cIsUtility>10</style> seconds.");
		LanguageAPI.Add("ITEM_INCREASEPRIMARYDAMAGE_DESC", $"Activating your <style=cIsUtility>Secondary skill</style> stores up to <style=cIsUtility>5 charges</style> <style=cStack>(+1 per stack)</style>. Requires <style=cIsUtility>3 charges</style> for your <style=cIsUtility>Primary skill</style> to fire lightning strikes, dealing <style=cIsDamage>{luminousShotFirstStackDamage.Value * 100f}% TOTAL damage</style> <style=cStack>(+{luminousShotAdditionalStackDamage.Value * 100f}% per stack)</style> each. <style=cIsUtility>Reduces Secondary skill cooldown by 20%</style>.");
		LanguageAPI.Add("ITEM_BARRIERONCOOLDOWN_DESC", $"When a skill comes off cooldown, gain a <style=cIsDamage>temporary barrier</style> for <style=cIsHealing>{eclipseLiteBaseBarrier.Value * 100f}%</style> <style=cStack>(+{eclipseLiteStackBarrier.Value * 100f}% per stack)</style> of your maximum health per second of the skill's base cooldown.");
		LanguageAPI.Add("ITEM_METEORATTACKONHIGHDAMAGE_DESC", $"<style=cIsDamage>3%</style> chance on hit to call down a meteor, dealing <style=cIsDamage>2000%</style> base damage. Every <style=cIsDamage>100%</style> attack damage dealt increases the activation chance by <style=cIsDamage>{runicLensBaseProcChance.Value}%</style> <style=cStack>(+{runicLensStackProcChance.Value}% per stack)</style> and damage by <style=cIsDamage>150%</style> <style=cStack>(+50% per stack)</style>.");
		LanguageAPI.Add("ITEM_BARRAGEONBOSS_DESC", $"During boss events, <style=cIsUtility>5</style> missiles bombard the area, dealing <style=cIsDamage>2.5%</style> <style=cStack>(+2.5% per stack)</style> <style=cIsDamage>of boss' Max Health in damage</style>. Before the boss event, gain additional missiles, up to a maximum of <style=cIsUtility>{warBondsBaseBuffCount.Value}</style> <style=cStack>(+{warBondsStackBuffCount.Value} per stack)</style>, per <style=cIsUtility>50</style> gold gained. <style=cIsUtility>Gold requirement scales over time</style>.");
	}

	private void ScaleProjectile(ProjectileController controller, ItemDef item, float vanillaBase, float vanillaStack, float customBase, float customStack)
	{
		GameObject owner = controller.owner;
		CharacterBody val = ((owner != null) ? owner.GetComponent<CharacterBody>() : null);
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		int itemCountEffective = val.inventory.GetItemCountEffective(item);
		if (itemCountEffective > 0)
		{
			ProjectileDamage component = ((Component)controller).GetComponent<ProjectileDamage>();
			if (Object.op_Implicit((Object)(object)component))
			{
				float num = vanillaBase + vanillaStack * (float)(itemCountEffective - 1);
				float num2 = customBase + customStack * (float)(itemCountEffective - 1);
				component.damage *= num2 / num;
			}
		}
	}

	private void RecalculateStatsAPI_GetStatCoefficients(CharacterBody sender, StatHookEventArgs args)
	{
		int buffCount = sender.GetBuffCount(Buffs.IncreaseDamageBuff);
		int itemCountEffective = sender.inventory.GetItemCountEffective(Items.IncreaseDamageOnMultiKill);
		float num = 0.035f + 0.01f * (float)(itemCountEffective - 1);
		float num2 = chronicExpansionBaseBuffValue.Value + chronicExpansionAdditiveBuffValue.Value * (float)(itemCountEffective - 1);
		args.damageMultAdd += (num2 - num) * (float)buffCount;
		int buffCount2 = sender.GetBuffCount(Buffs.AttackSpeedPerNearbyAllyOrEnemyBuff);
		int itemCountEffective2 = sender.inventory.GetItemCountEffective(Items.AttackSpeedPerNearbyAllyOrEnemy);
		float num3 = 0.1f + 0.035f * (float)(itemCountEffective2 - 1);
		float num4 = bolsteringLanternBaseBuffValue.Value + bolsteringLanternAdditiveBuffValue.Value * (float)(itemCountEffective2 - 1);
		args.attackSpeedMultAdd += (num4 - num3) * (float)buffCount2;
	}

	private void ProjectileController_Start(orig_Start orig, ProjectileController self)
	{
		orig.Invoke(self);
		if (((Object)self).name.StartsWith("DynamiteProjectile"))
		{
			ScaleProjectile(self, Items.DronesDropDynamite, 2.4f, 0.85f, dynamiteFirstStackDamage.Value, dynamiteAdditionalStackDamage.Value);
		}
		if (((Object)self).name.StartsWith("LuminousShotProjectile"))
		{
			ScaleProjectile(self, Items.IncreasePrimaryDamage, 1.75f, 0.5f, luminousShotFirstStackDamage.Value, luminousShotAdditionalStackDamage.Value);
		}
	}

	private void CharacterBody_OnSkillCooldown_IL(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(new Func<Instruction, bool>[1]
		{
			(Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, 0.01f)
		}))
		{
			val.Next.Operand = eclipseLiteBaseBarrier.Value;
		}
		if (val.TryGotoNext(new Func<Instruction, bool>[1]
		{
			(Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, 0.0025f)
		}))
		{
			val.Next.Operand = eclipseLiteStackBarrier.Value;
		}
	}

	private void GlobalEventManager_ProcessHitEnemy_IL(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(new Func<Instruction, bool>[1]
		{
			(Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, typeof(Items), "MeteorAttackOnHighDamage")
		}))
		{
			if (val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, 3f)
			}))
			{
				val.Next.Operand = runicLensStackProcChance.Value;
			}
			if (val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, 3f)
			}))
			{
				val.Next.Operand = runicLensBaseProcChance.Value;
			}
		}
	}
}
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
public class BarrageOnBossBehaviour_maxBuffCount_Patch
{
	[HarmonyILManipulator]
	public static void ILManipulator(ILContext il)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Expected O, but got Unknown
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		ILCursor val = new ILCursor(il);
		if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
		{
			(Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 15)
		}))
		{
			int index = val.Index;
			val.Index = index - 1;
			val.Remove();
			val.Emit(OpCodes.Ldc_I4, StackChanges.warBondsBaseBuffCount.Value);
		}
		val.Index = 0;
		if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
		{
			(Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 5)
		}))
		{
			int index = val.Index;
			val.Index = index - 1;
			val.Remove();
			val.Emit(OpCodes.Ldc_I4, StackChanges.warBondsStackBuffCount.Value);
		}
	}
}