Ror2AggroTools.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using On.RoR2;
using On.RoR2.CharacterAI;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.CharacterAI;
using UnityEngine;
using UnityEngine.Networking;

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

public enum AggroPriority
{
	None = -3,
	LowAggro = -1,
	Normal = 0,
	HighAggro = 1,
	Killeth = 2
}
public static class Aggro
{
	public static void AggroMinionsToEnemy(CharacterBody leaderBody, CharacterBody victimBody, bool killethAggro = false)
	{
		if (Object.op_Implicit((Object)(object)victimBody))
		{
			ApplyAggroBuff(victimBody, killethAggro);
			if (Object.op_Implicit((Object)(object)leaderBody))
			{
				ResetMinionAggro(leaderBody);
			}
		}
	}

	public static void ApplyAggroBuff(CharacterBody victim, bool killethAggro = false)
	{
		if (NetworkServer.active)
		{
			if (killethAggro)
			{
				victim.AddTimedBuff(AggroToolsPlugin.killethAggro, 10f);
			}
			else
			{
				victim.AddTimedBuff(AggroToolsPlugin.priorityAggro, 10f);
			}
		}
	}

	public static void ShedAggroFromCharacter(CharacterBody body)
	{
		ShedAggroFromCharacter(((Component)body).gameObject);
	}

	public static void ShedAggroFromCharacter(GameObject gameObject)
	{
		BaseAI[] array = Object.FindObjectsOfType<BaseAI>();
		BaseAI[] array2 = array;
		foreach (BaseAI val in array2)
		{
			if ((Object)(object)val.currentEnemy.gameObject == (Object)(object)gameObject)
			{
				ResetAggro(val);
			}
		}
	}

	public static void ResetAllyAggro(CharacterMaster master)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		BaseAI[] array = Object.FindObjectsOfType<BaseAI>();
		BaseAI[] array2 = array;
		foreach (BaseAI val in array2)
		{
			if (val.master.teamIndex == master.teamIndex)
			{
				ResetAggro(val);
			}
		}
	}

	public static void ResetMinionAggro(CharacterBody leaderBody)
	{
		BaseAI[] array = Object.FindObjectsOfType<BaseAI>();
		BaseAI[] array2 = array;
		foreach (BaseAI val in array2)
		{
			if ((Object)(object)val.leader.characterBody == (Object)(object)leaderBody)
			{
				ResetAggroIfApplicable(val);
			}
		}
	}

	public static void ResetAggro(BaseAI baseAI)
	{
		baseAI.currentEnemy.Reset();
	}

	public static void ResetAggroIfApplicable(BaseAI baseAI)
	{
		HurtBox val = baseAI.FindEnemyHurtBox(float.PositiveInfinity, baseAI.fullVision, false);
		HealthComponent val2 = val?.healthComponent;
		if ((Object)(object)val2 != (Object)(object)baseAI.currentEnemy.healthComponent && Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.body) && Object.op_Implicit((Object)(object)baseAI.currentEnemy.characterBody))
		{
			AggroPriority aggroPriority = GetAggroPriority(val.healthComponent?.body);
			AggroPriority aggroPriority2 = GetAggroPriority(baseAI.currentEnemy.characterBody);
			if (aggroPriority >= aggroPriority2 && aggroPriority > AggroPriority.Normal)
			{
				baseAI.currentEnemy.gameObject = ((Component)val2).gameObject;
				baseAI.currentEnemy.bestHurtBox = val;
				baseAI.enemyAttention = baseAI.enemyAttentionDuration;
			}
		}
	}

	public static AggroPriority GetAggroPriority(CharacterBody body)
	{
		if ((Object)(object)body == (Object)null || !body.healthComponent.alive)
		{
			return AggroPriority.None;
		}
		if (body.HasBuff(Buffs.Cloak))
		{
			return AggroPriority.LowAggro;
		}
		if (body.HasBuff(AggroToolsPlugin.killethAggro))
		{
			return AggroPriority.Killeth;
		}
		if (body.HasBuff(AggroToolsPlugin.priorityAggro))
		{
			return AggroPriority.HighAggro;
		}
		return AggroPriority.Normal;
	}
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("com.RiskOfBrainrot.Ror2AggroTools", "Ror2AggroTools", "1.0.1")]
[R2APISubmoduleDependency(new string[] { "LanguageAPI", "ContentAddition", "DamageAPI", "RecalculateStatsAPI" })]
public class AggroToolsPlugin : BaseUnityPlugin
{
	public const string guid = "com.RiskOfBrainrot.Ror2AggroTools";

	public const string teamName = "RiskOfBrainrot";

	public const string modName = "Ror2AggroTools";

	public const string version = "1.0.1";

	public const float lowPriorityAggroWeight = 3f;

	public const float highPriorityAggroWeight = 100f;

	public const float priorityAggroDuration = 10f;

	public static BuffDef killethAggro;

	public static BuffDef priorityAggro;

	public static ModdedDamageType AggroOnHit;

	public static PluginInfo PInfo { get; private set; }

	public void Awake()
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Expected O, but got Unknown
		PInfo = ((BaseUnityPlugin)this).Info;
		AIChanges.Init();
		AggroOnHit = DamageAPI.ReserveDamageType();
		priorityAggro = ScriptableObject.CreateInstance<BuffDef>();
		priorityAggro.canStack = false;
		priorityAggro.isHidden = true;
		priorityAggro.isDebuff = false;
		ContentAddition.AddBuffDef(priorityAggro);
		killethAggro = ScriptableObject.CreateInstance<BuffDef>();
		killethAggro.canStack = false;
		killethAggro.isHidden = true;
		killethAggro.isDebuff = false;
		ContentAddition.AddBuffDef(killethAggro);
		GlobalEventManager.ProcessHitEnemy += new hook_ProcessHitEnemy(AggroOnHitHook);
	}

	private void AggroOnHitHook(orig_ProcessHitEnemy orig, GlobalEventManager self, DamageInfo damageInfo, GameObject victim)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		orig.Invoke(self, damageInfo, victim);
		if (!damageInfo.rejected && damageInfo.procCoefficient > 0f && DamageAPI.HasModdedDamageType(damageInfo, AggroOnHit) && (Object)(object)victim != (Object)null && (Object)(object)damageInfo.attacker != (Object)null)
		{
			CharacterBody component = damageInfo.attacker.GetComponent<CharacterBody>();
			CharacterBody component2 = victim.GetComponent<CharacterBody>();
			if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null && component2.healthComponent.alive)
			{
				Aggro.AggroMinionsToEnemy(component, component2);
			}
		}
	}
}
public static class AIChanges
{
	public delegate void orig_setCurrentEnemy(BaseAI self, Target target);

	public static Dictionary<BaseAI, Target> aiTargetPairs;

	public static void Init()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Expected O, but got Unknown
		aiTargetPairs = new Dictionary<BaseAI, Target>();
		BaseAI.FindEnemyHurtBox += new hook_FindEnemyHurtBox(BaseAI_FindEnemyHurtbox);
		BaseAI.OnBodyDamaged += new hook_OnBodyDamaged(BaseAI_OnBodyDamaged);
	}

	private static void ClearTargetPairing(orig_OnDestroy orig, BaseAI self)
	{
		orig.Invoke(self);
		if (aiTargetPairs.ContainsKey(self))
		{
			aiTargetPairs.Remove(self);
		}
	}

	public static void Set_CurrentEnemy(orig_setCurrentEnemy orig, BaseAI self, Target target)
	{
		if (target != self.currentEnemy)
		{
			if (target == null)
			{
				aiTargetPairs.Remove(self);
			}
			else
			{
				aiTargetPairs[self] = target;
			}
		}
		orig(self, target);
	}

	private static HurtBox BaseAI_FindEnemyHurtbox(orig_FindEnemyHurtBox orig, BaseAI self, float maxDistance, bool full360Vision, bool filterByLoS)
	{
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		HurtBox result = orig.Invoke(self, maxDistance, full360Vision, filterByLoS);
		bool flag = false;
		IEnumerable<CandidateInfo> candidatesEnumerable = self.enemySearch.candidatesEnumerable;
		List<CandidateInfo> list = new List<CandidateInfo>();
		foreach (CandidateInfo item2 in candidatesEnumerable)
		{
			float num = item2.distanceSqr;
			CharacterBody val = item2.hurtBox.healthComponent?.body;
			if (Object.op_Implicit((Object)(object)val))
			{
				switch (Aggro.GetAggroPriority(val))
				{
				case AggroPriority.Killeth:
					return item2.hurtBox;
				case AggroPriority.HighAggro:
					flag = true;
					num /= 100f;
					break;
				case AggroPriority.LowAggro:
					flag = true;
					num *= 3f;
					break;
				}
			}
			CandidateInfo val2 = default(CandidateInfo);
			val2.hurtBox = item2.hurtBox;
			val2.position = item2.position;
			val2.dot = item2.dot;
			val2.distanceSqr = num;
			CandidateInfo item = val2;
			list.Add(item);
		}
		if (flag)
		{
			Func<CandidateInfo, float> sorter = self.enemySearch.GetSorter();
			if (sorter != null)
			{
				self.enemySearch.candidatesEnumerable = list.OrderBy(sorter).ToList();
			}
			return self.enemySearch.GetResults().FirstOrDefault();
		}
		return result;
	}

	private static void BaseAI_OnBodyDamaged(orig_OnBodyDamaged orig, BaseAI self, DamageReport damageReport)
	{
		if (damageReport.damageInfo != null && (Object)(object)damageReport.damageInfo.attacker != (Object)null)
		{
			if (!Object.op_Implicit((Object)(object)self.body) || (Object)(object)damageReport.damageInfo.attacker == (Object)(object)((Component)self.body).gameObject)
			{
				return;
			}
			Target currentEnemy = self.currentEnemy;
			AggroPriority aggroPriority = Aggro.GetAggroPriority((currentEnemy != null) ? currentEnemy.characterBody : null);
			AggroPriority aggroPriority2 = Aggro.GetAggroPriority(damageReport.attackerBody);
			if (aggroPriority > aggroPriority2)
			{
				return;
			}
			if (aggroPriority < aggroPriority2 && aggroPriority != AggroPriority.None)
			{
				self.currentEnemy.gameObject = null;
			}
		}
		orig.Invoke(self, damageReport);
	}
}