Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RATS v0.1.1
Ror2AggroTools.dll
Decompiled 9 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); } }