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);
}
}