Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of RATS v0.1.1
Ror2AggroTools.dll
Decompiled 4 months agousing 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); } }