Decompiled source of AcolyteFavorRework v1.0.0

AcolyteFavorRework.dll

Decompiled 12 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using On.RoR2;
using On.RoR2.Items;
using RoR2;
using RoR2.Items;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("AcolyteFavorRework")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("AcolyteFavorRework")]
[assembly: AssemblyTitle("AcolyteFavorRework")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace AcolyteFavorRework;

[BepInPlugin("AcolyteFavorRework", "AcolyteFavorRework", "1.0.0")]
public class AcolyteFavorReworkPlugin : BaseUnityPlugin
{
	public const string PluginGUID = "AcolyteFavorRework";

	public const string PluginName = "AcolyteFavorRework";

	public const string PluginVersion = "1.0.0";

	private const string PassiveDescToken = "ACOLYTE_PASSIVE_DESCRIPTION";

	private static ConfigEntry<int> maxAttackSpeedPercent;

	private static ConfigEntry<float> secondsToMax;

	private static ConfigEntry<bool> matchMercenaryRegen;

	private readonly Dictionary<CharacterBody, float> combatTimers = new Dictionary<CharacterBody, float>();

	private readonly List<CharacterBody> staleBodies = new List<CharacterBody>();

	private void Awake()
	{
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Expected O, but got Unknown
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Expected O, but got Unknown
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Expected O, but got Unknown
		maxAttackSpeedPercent = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxAttackSpeedPercent", 30, "Maximum bonus attack speed (in percent) gained from staying in combat.");
		secondsToMax = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SecondsToMax", 10f, "Seconds of continuous combat needed to reach the maximum bonus. The bonus resets once out of combat.");
		matchMercenaryRegen = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "MatchMercenaryRegen", true, "Give Acolyte the same base health regeneration (and per-level regen) as Mercenary.");
		((ResourceAvailability)(ref BodyCatalog.availability)).CallWhenAvailable((Action)CopyMercenaryRegen);
		HealthComponent.Heal += new hook_Heal(HealthComponent_Heal);
		ConvertHealingToAttackSpeedBehavior.RecalculateBaseAttackSpeedBuffCount += new hook_RecalculateBaseAttackSpeedBuffCount(SkipRegenConversion);
		Language.GetLocalizedStringByToken += new hook_GetLocalizedStringByToken(Language_GetLocalizedStringByToken);
	}

	private void CopyMercenaryRegen()
	{
		if (matchMercenaryRegen.Value)
		{
			GameObject val = BodyCatalog.FindBodyPrefab("MercBody");
			GameObject val2 = BodyCatalog.FindBodyPrefab("AcolyteBody");
			CharacterBody val3 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<CharacterBody>() : null);
			CharacterBody val4 = (Object.op_Implicit((Object)(object)val2) ? val2.GetComponent<CharacterBody>() : null);
			if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val4))
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not find MercBody or AcolyteBody; regen not changed.");
				return;
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"Acolyte regen {val4.baseRegen} (+{val4.levelRegen}/lvl) -> Mercenary's {val3.baseRegen} (+{val3.levelRegen}/lvl)");
			val4.baseRegen = val3.baseRegen;
			val4.levelRegen = val3.levelRegen;
		}
	}

	private static bool HasFavor(CharacterBody body)
	{
		if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.inventory))
		{
			return body.inventory.GetItemCountEffective(Items.ConvertHealingToAttackSpeed) > 0;
		}
		return false;
	}

	private static float HealthComponent_Heal(orig_Heal orig, HealthComponent self, float amount, ProcChainMask procChainMask, bool nonRegen)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		if (Object.op_Implicit((Object)(object)self) && HasFavor(self.body))
		{
			((ProcChainMask)(ref procChainMask)).AddProc((ProcType)31);
		}
		return orig.Invoke(self, amount, procChainMask, nonRegen);
	}

	private static void SkipRegenConversion(orig_RecalculateBaseAttackSpeedBuffCount orig, ConvertHealingToAttackSpeedBehavior self)
	{
	}

	private static string Language_GetLocalizedStringByToken(orig_GetLocalizedStringByToken orig, Language self, string token)
	{
		if (token == "ACOLYTE_PASSIVE_DESCRIPTION")
		{
			return "The Acolyte heals normally. Gain up to <style=cIsDamage>" + maxAttackSpeedPercent.Value + "% attack speed</style> the longer you stay <style=cIsDamage>in combat</style>.";
		}
		return orig.Invoke(self, token);
	}

	private void FixedUpdate()
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		if (!NetworkServer.active)
		{
			combatTimers.Clear();
			return;
		}
		float num = Mathf.Max(0, maxAttackSpeedPercent.Value);
		float num2 = Mathf.Max(0.01f, secondsToMax.Value);
		BuffIndex buffIndex = Buffs.AcoAttackSpeed.buffIndex;
		foreach (CharacterBody readOnlyInstances in CharacterBody.readOnlyInstancesList)
		{
			if (HasFavor(readOnlyInstances))
			{
				combatTimers.TryGetValue(readOnlyInstances, out var value);
				value = (readOnlyInstances.outOfCombat ? 0f : Mathf.Min(value + Time.fixedDeltaTime, num2));
				combatTimers[readOnlyInstances] = value;
				int num3 = Mathf.FloorToInt(value / num2 * num);
				if (readOnlyInstances.GetBuffCount(buffIndex) != num3)
				{
					readOnlyInstances.SetBuffCount(buffIndex, num3);
				}
			}
		}
		staleBodies.Clear();
		foreach (CharacterBody key in combatTimers.Keys)
		{
			if (!Object.op_Implicit((Object)(object)key))
			{
				staleBodies.Add(key);
			}
		}
		foreach (CharacterBody staleBody in staleBodies)
		{
			combatTimers.Remove(staleBody);
		}
	}
}