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 SummonFocusFire Stand A Lone v0.0.1
SummonFocusFire.dll
Decompiled a day agousing 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 EntityStates; using Microsoft.CodeAnalysis; using On.RoR2; 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 = ".NET Standard 2.1")] [assembly: AssemblyCompany("SummonFocusFire")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SummonFocusFire")] [assembly: AssemblyTitle("SummonFocusFire")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SummonFocusFire { [BepInPlugin("com.chronicrick.summonfocusfire", "SummonFocusFire - Stand-A-Lone", "0.0.1")] public sealed class Plugin : BaseUnityPlugin { private sealed class Order { public CharacterMaster owner; public GameObject target; public float expires; } private sealed class PrimaryWindow { public int lastStock; public float expires; public Type activationType; } private ConfigEntry<bool> enabled; private ConfigEntry<bool> includeMobile; private ConfigEntry<bool> includeStationary; private ConfigEntry<float> mobileRadius; private ConfigEntry<float> stationaryRadius; private ConfigEntry<float> focusSeconds; private ConfigEntry<float> commandCooldown; private readonly Dictionary<CharacterMaster, Order> orders = new Dictionary<CharacterMaster, Order>(); private readonly Dictionary<CharacterMaster, float> lastCommand = new Dictionary<CharacterMaster, float>(); private readonly Dictionary<CharacterMaster, PrimaryWindow> primaryWindows = new Dictionary<CharacterMaster, PrimaryWindow>(); private float nextScan; private void Awake() { //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("FocusFire", "Enabled", true, "Server-authoritative player-owned ally focus fire."); includeMobile = ((BaseUnityPlugin)this).Config.Bind<bool>("FocusFire", "IncludeMobileAllies", true, "Allow mobile AI allies to pursue designated targets."); includeStationary = ((BaseUnityPlugin)this).Config.Bind<bool>("FocusFire", "IncludeStationaryAllies", true, "Only command stationary AI allies if target is already in attack range."); mobileRadius = ((BaseUnityPlugin)this).Config.Bind<float>("FocusFire", "MobilePursuitRadiusMeters", 150f, "Maximum distance between a mobile ally and the designated target."); stationaryRadius = ((BaseUnityPlugin)this).Config.Bind<float>("FocusFire", "StationaryAttackRangeMeters", 45f, "Conservative range gate for stationary AI; does not change weapon range."); focusSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("FocusFire", "FocusDurationSeconds", 8f, "Duration of a focus-fire order after a qualifying hit."); commandCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("FocusFire", "CommandCooldownSeconds", 0.15f, "Rate-limit commands from rapid-fire primaries."); HealthComponent.TakeDamage += new hook_TakeDamage(OnDamage); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Summon Focus Fire - Stand-A-Lone 0.0.1 loaded (experimental primary-hit classifier)."); } private void OnDestroy() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown HealthComponent.TakeDamage -= new hook_TakeDamage(OnDamage); } private void FixedUpdate() { if (!NetworkServer.active || !enabled.Value || Time.fixedTime < nextScan) { return; } nextScan = Time.fixedTime + 0.05f; foreach (CharacterMaster readOnlyInstances in CharacterMaster.readOnlyInstancesList) { if (!Object.op_Implicit((Object)(object)readOnlyInstances) || !Object.op_Implicit((Object)(object)((Component)readOnlyInstances).GetComponent<PlayerCharacterMasterController>())) { continue; } CharacterBody body = readOnlyInstances.GetBody(); if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.skillLocator) && Object.op_Implicit((Object)(object)body.skillLocator.primary)) { GenericSkill primary = body.skillLocator.primary; if (!primaryWindows.TryGetValue(readOnlyInstances, out var value)) { value = new PrimaryWindow { lastStock = primary.stock }; primaryWindows[readOnlyInstances] = value; } if (primary.stock < value.lastStock) { value.expires = Time.fixedTime + 0.35f; } value.lastStock = primary.stock; if ((Object)(object)primary.skillDef != (Object)null && ((SerializableEntityStateType)(ref primary.skillDef.activationState)).stateType != null) { value.activationType = ((SerializableEntityStateType)(ref primary.skillDef.activationState)).stateType; } } } List<CharacterMaster> list = new List<CharacterMaster>(); foreach (KeyValuePair<CharacterMaster, Order> order in orders) { if (!Object.op_Implicit((Object)(object)order.Key) || !Object.op_Implicit((Object)(object)order.Value.owner) || !Object.op_Implicit((Object)(object)order.Value.target) || Time.fixedTime > order.Value.expires) { list.Add(order.Key); } else { ApplyTarget(order.Key, order.Value.target); } } foreach (CharacterMaster item in list) { orders.Remove(item); } } private void OnDamage(orig_TakeDamage orig, HealthComponent victim, DamageInfo info) { //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(victim, info); if (!NetworkServer.active || !enabled.Value || !Object.op_Implicit((Object)(object)victim) || !Object.op_Implicit((Object)(object)victim.body) || info == null || !Object.op_Implicit((Object)(object)info.attacker)) { return; } CharacterBody val = info.attacker.GetComponent<CharacterBody>() ?? info.attacker.GetComponentInParent<CharacterBody>(); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.master) || !Object.op_Implicit((Object)(object)((Component)val.master).GetComponent<PlayerCharacterMasterController>()) || !victim.alive || (Object)(object)victim.body.teamComponent == (Object)null || (Object)(object)val.teamComponent == (Object)null || victim.body.teamComponent.teamIndex == val.teamComponent.teamIndex || !IsLikelyDirectPrimaryHit(val, info) || (lastCommand.TryGetValue(val.master, out var value) && Time.fixedTime - value < commandCooldown.Value)) { return; } lastCommand[val.master] = Time.fixedTime; int num = 0; foreach (CharacterMaster readOnlyInstances in CharacterMaster.readOnlyInstancesList) { if (!Object.op_Implicit((Object)(object)readOnlyInstances) || (Object)(object)readOnlyInstances == (Object)(object)val.master || !Object.op_Implicit((Object)(object)readOnlyInstances.minionOwnership) || (Object)(object)readOnlyInstances.minionOwnership.ownerMaster != (Object)(object)val.master) { continue; } CharacterBody body = readOnlyInstances.GetBody(); if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.healthComponent) || !body.healthComponent.alive) { continue; } BaseAI component = ((Component)readOnlyInstances).GetComponent<BaseAI>(); if (!Object.op_Implicit((Object)(object)component)) { continue; } bool flag = IsStationary(readOnlyInstances, body); if ((!flag || includeStationary.Value) && (flag || includeMobile.Value)) { float num2 = (flag ? stationaryRadius.Value : mobileRadius.Value); Vector3 val2 = body.corePosition - victim.body.corePosition; if (!(((Vector3)(ref val2)).sqrMagnitude > num2 * num2)) { orders[readOnlyInstances] = new Order { owner = val.master, target = ((Component)victim.body).gameObject, expires = Time.fixedTime + focusSeconds.Value }; ApplyTarget(readOnlyInstances, ((Component)victim.body).gameObject); num++; } } } if (num > 0) { ((BaseUnityPlugin)this).Logger.LogDebug((object)("[FOCUS] " + ((Object)val).name + " directed " + num + " owned AI allies.")); } } private bool IsLikelyDirectPrimaryHit(CharacterBody attacker, DamageInfo info) { if (!primaryWindows.TryGetValue(attacker.master, out var value)) { return false; } bool flag = Time.fixedTime <= value.expires; bool flag2 = false; if (value.activationType != null) { EntityStateMachine[] components = ((Component)attacker).GetComponents<EntityStateMachine>(); foreach (EntityStateMachine val in components) { if ((Object)(object)val != (Object)null && val.state != null && value.activationType.IsAssignableFrom(((object)val.state).GetType())) { flag2 = true; } } } if (!flag && !flag2) { return false; } return (Object)(object)info.inflictor == (Object)null || (Object)(object)info.inflictor == (Object)(object)((Component)attacker).gameObject; } private static bool IsStationary(CharacterMaster master, CharacterBody body) { string text = (((Object)master).name + " " + ((Object)body).name).ToLowerInvariant(); if (text.Contains("turret") || text.Contains("polyp") || text.Contains("offshoot") || text.Contains("flower")) { return true; } CharacterMotor characterMotor = body.characterMotor; return (Object)(object)characterMotor == (Object)null && (Object)(object)((Component)body).GetComponent<Rigidbody>() == (Object)null; } private void ApplyTarget(CharacterMaster master, GameObject target) { if (!Object.op_Implicit((Object)(object)master) || !Object.op_Implicit((Object)(object)target)) { return; } BaseAI component = ((Component)master).GetComponent<BaseAI>(); if (!Object.op_Implicit((Object)(object)component)) { return; } try { object currentEnemy = component.currentEnemy; if (currentEnemy != null) { MethodInfo method = currentEnemy.GetType().GetMethod("SetTarget", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(GameObject) }, null); if (method != null) { method.Invoke(currentEnemy, new object[1] { target }); } } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogDebug((object)("[FOCUS] AI target assignment unavailable: " + ex.Message)); } } } }