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 Instinct v1.0.0
Instinct.dll
Decompiled 7 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.AI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyVersion("0.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 Instinct { [BepInPlugin("com.razaotium.instinct", "Instinct", "1.0.0")] public class Plugin : BaseUnityPlugin { public sealed class Fixed<T> { public readonly T Value; public Fixed(T v) { Value = v; } } public const string Guid = "com.razaotium.instinct"; public const string Version = "1.0.0"; private static ConfigEntry<bool> serverEnabled; private static bool localEnabled = true; public static Fixed<int> Tokens; public static Fixed<float> RingGap; public static Fixed<float> Spacing; public static Fixed<string> UseGameIn; public static Fixed<bool> ReadBlock; public static Fixed<bool> PunishTired; public static Fixed<bool> Flyers; public static Fixed<float> Recovery; public static Fixed<bool> Band; public static Fixed<bool> Audience; public static Fixed<bool> SideTeam; public static Fixed<bool> AfterDraw; public static Fixed<bool> CurveIn; public static Fixed<bool> RearWatch; public static Fixed<bool> Pincer; public static Fixed<bool> TurnWalk; public static Fixed<bool> NoCrossFront; public static Fixed<bool> PressOnMove; public static Fixed<bool> HitNow; public static Fixed<bool> Intercept; public static Fixed<bool> ChaseRunner; public static Fixed<bool> PassStrike; public static Fixed<bool> SpinWindup; public static Fixed<bool> KeepPressure; public static Fixed<bool> FreeArchers; public static Fixed<bool> Suppress; public static Fixed<bool> Dodge; public static Fixed<bool> Bubble; public static Fixed<bool> FlushOut; public static Fixed<bool> Shout; public static Fixed<float> DodgeChance; public static Fixed<float> RetreatChance; public static Fixed<bool> PredictReach; public static Fixed<float> Stagger; public static Fixed<bool> SteadyTarget; public static Fixed<float> Split; public static Fixed<string> NoClimb; public static Fixed<bool> Bridges; public static Fixed<float> StrikeDepth; public static Fixed<string> BridgePieces; public static Fixed<string> Styles; public static Fixed<float> NearGap; public static Fixed<float> FarGap; public static Fixed<float> DefendRadius; public static Fixed<float> Patience; public static Fixed<bool> FlankBehind; public static Fixed<float> AllyDown; public static Fixed<bool> StarSkill; private Harmony harmony; private float switchWarn; public static bool EnabledNow { get { if (serverEnabled == null) { return localEnabled; } return serverEnabled.Value; } } public static bool Active { get { if (EnabledNow) { return !ServerSwitch.ServerOff; } return false; } } private static Fixed<T> Opt<T>(T v) { return new Fixed<T>(v); } private void Awake() { //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Expected O, but got Unknown if (Application.isBatchMode) { serverEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "false turns Instinct off for every connected player; true turns it on. Re-read every 10 seconds."); } Tokens = Opt(2); RingGap = Opt(2.5f); Spacing = Opt(2.2f); UseGameIn = Opt("Draugr:pass,Skeleton:still,Skeleton:back_off,Skeleton:pass,Wolf:still,Wolf:strafe"); ReadBlock = Opt(v: true); PunishTired = Opt(v: true); Flyers = Opt(v: true); Suppress = Opt(v: true); Dodge = Opt(v: true); DodgeChance = Opt(0.5f); Bubble = Opt(v: true); RetreatChance = Opt(0.5f); FlushOut = Opt(v: true); Shout = Opt(v: true); Band = Opt(v: true); Audience = Opt(v: true); SideTeam = Opt(v: true); AfterDraw = Opt(v: true); TurnWalk = Opt(v: true); NoCrossFront = Opt(v: true); PressOnMove = Opt(v: true); PassStrike = Opt(v: true); FreeArchers = Opt(v: true); KeepPressure = Opt(v: true); SpinWindup = Opt(v: true); StrikeDepth = Opt(0.55f); ChaseRunner = Opt(v: true); HitNow = Opt(v: true); Intercept = Opt(v: true); Pincer = Opt(v: true); CurveIn = Opt(v: true); RearWatch = Opt(v: true); Recovery = Opt(0.5f); Stagger = Opt(0.45f); Bridges = Opt(v: true); BridgePieces = Opt("log,beam,pole,floor_1x1"); NoClimb = Opt("stair"); Split = Opt(0.5f); SteadyTarget = Opt(v: true); PredictReach = Opt(v: true); Styles = Opt("Wolf=close,Ulv=close,Fenring=close,Draugr_Ranged=far,GoblinArcher=far"); NearGap = Opt(0.8f); FarGap = Opt(4.5f); DefendRadius = Opt(12f); Patience = Opt(6f); FlankBehind = Opt(v: true); AllyDown = Opt(1.5f); StarSkill = Opt(v: true); harmony = new Harmony("com.razaotium.instinct"); harmony.PatchAll(typeof(Patches)); } private void Update() { try { ServerSwitch.Tick(this); } catch (Exception ex) { if (Time.time > switchWarn) { switchWarn = Time.time + 30f; ((BaseUnityPlugin)this).Logger.LogWarning((object)("Instinct: server switch " + ex.Message)); } } } private void OnDestroy() { if (harmony != null) { harmony.UnpatchSelf(); } Director.Fights.Clear(); Brain.States.Clear(); } } internal static class Acc { public static readonly FieldRef<BaseAI, Character> Char = AccessTools.FieldRefAccess<BaseAI, Character>("m_character"); public static readonly FieldRef<MonsterAI, Character> Target = AccessTools.FieldRefAccess<MonsterAI, Character>("m_targetCreature"); public static readonly FieldRef<MonsterAI, float> SinceSensed = AccessTools.FieldRefAccess<MonsterAI, float>("m_timeSinceSensedTargetCreature"); public static readonly FieldRef<MonsterAI, float> MinAttackInterval = AccessTools.FieldRefAccess<MonsterAI, float>("m_minAttackInterval"); } internal static class Reach { public class Info { public float Reach; public float Windup = 0.7f; public int N; } private class Pending { public float T; public Vector3 Pos; public Vector3 Fwd; public string Key; public Attack A; } private static readonly Dictionary<string, Info> Learned = new Dictionary<string, Info>(); private static readonly Dictionary<Humanoid, Pending> Open = new Dictionary<Humanoid, Pending>(); private static readonly FieldRef<Humanoid, Attack> CurAttack = AccessTools.FieldRefAccess<Humanoid, Attack>("m_currentAttack"); private static readonly FieldRef<Attack, Humanoid> AttChar = AccessTools.FieldRefAccess<Attack, Humanoid>("m_character"); public static string Key(Character me, ItemData w) { return Utils.GetPrefabName(((Component)me).gameObject) + "|" + w.m_shared.m_name; } public static bool Melee(Attack a) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 if (a != null) { if ((int)a.m_attackType != 0 && (int)a.m_attackType != 1) { return (int)a.m_attackType == 4; } return true; } return false; } private static Transform Origin(Humanoid h, Attack a) { if (!string.IsNullOrEmpty(a.m_attackOriginJoint)) { Transform val = Utils.FindChild(((Character)h).GetVisual().transform, a.m_attackOriginJoint, (IterativeSearchType)0); if ((Object)(object)val != (Object)null) { return val; } } return ((Component)h).transform; } private static float Sweep(Attack a) { return a.m_attackRange + a.m_attackRayWidth + Mathf.Max(0f, a.m_attackRayWidthCharExtra); } public static Info Get(Humanoid h, ItemData w) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) string key = Key((Character)(object)h, w); if (Learned.TryGetValue(key, out var value)) { return value; } Attack attack = w.m_shared.m_attack; value = new Info(); if (Melee(attack)) { Vector3 val = Origin(h, attack).position - ((Component)h).transform.position; value.Reach = Mathf.Max(0.5f, Vector3.Dot(new Vector3(val.x, 0f, val.z), ((Component)h).transform.forward)) + Sweep(attack); } else { value.Reach = w.m_shared.m_aiAttackRange; } Learned[key] = value; return value; } public static void Started(Humanoid h) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)h == (Object)null) && !((Character)h).IsPlayer()) { Attack a = CurAttack.Invoke(h); ItemData currentWeapon = h.GetCurrentWeapon(); if (Melee(a) && currentWeapon != null) { Vector3 forward = ((Component)h).transform.forward; forward.y = 0f; Open[h] = new Pending { T = Time.time, Pos = ((Component)h).transform.position, Fwd = ((Vector3)(ref forward)).normalized, Key = Key((Character)(object)h, currentWeapon), A = a }; } } } public static void Triggered(Attack a) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) Humanoid val = AttChar.Invoke(a); if ((Object)(object)val == (Object)null || !Open.TryGetValue(val, out var value) || value.A != a) { return; } Open.Remove(val); MonsterAI component = ((Component)val).GetComponent<MonsterAI>(); if ((Object)(object)component != (Object)null) { Director.Landed(component); } float num = Time.time - value.T; if (!(num <= 0.02f) && !(num > 3f)) { Vector3 val2 = Origin(val, a).position - value.Pos; val2.y = 0f; float num2 = Mathf.Max(0.3f, Vector3.Dot(val2, value.Fwd)) + Sweep(a); if (!Learned.TryGetValue(value.Key, out var value2)) { value2 = new Info(); Learned[value.Key] = value2; } if (value2.N == 0) { value2.Reach = num2; value2.Windup = num; } else { value2.Reach = Mathf.Lerp(value2.Reach, num2, 0.25f); value2.Windup = Mathf.Lerp(value2.Windup, num, 0.25f); } value2.N++; } } public static void Gaps(Character me, Character t, Info i, out float now, out float then) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)t).transform.position - ((Component)me).transform.position; val.y = 0f; now = ((Vector3)(ref val)).magnitude - t.GetRadius(); Vector3 velocity = t.GetVelocity(); velocity.y = 0f; Vector3 val2 = val + velocity * i.Windup; then = ((Vector3)(ref val2)).magnitude - t.GetRadius(); } public static void Prune() { List<Humanoid> list = null; foreach (KeyValuePair<Humanoid, Pending> item in Open) { if ((Object)(object)item.Key == (Object)null || Time.time - item.Value.T > 4f) { (list ?? (list = new List<Humanoid>())).Add(item.Key); } } if (list == null) { return; } foreach (Humanoid item2 in list) { Open.Remove(item2); } } } internal static class Targeting { private class Mem { public Character Cur; public float Since = -99f; public Character Rival; public float RivalSince = -99f; public readonly Dictionary<Character, float> Dmg = new Dictionary<Character, float>(); public float DmgAt; public Character LastHitter; public float LastHitAt = -99f; } private static readonly Dictionary<BaseAI, Mem> Mems = new Dictionary<BaseAI, Mem>(); private static readonly FieldRef<MonsterAI, float> UpdateTimer = AccessTools.FieldRefAccess<MonsterAI, float>("m_updateTargetTimer"); private const float MinCommit = 3f; private const float Dwell = 0.75f; private const float Margin = 1.3f; private const float MarginClose = 1.1f; private const float HalfLife = 8f; private static Mem Get(BaseAI ai) { if (!Mems.TryGetValue(ai, out var value)) { value = new Mem(); Mems[ai] = value; } return value; } public static bool Applies(BaseAI ai) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Invalid comparison between Unknown and I4 if (!Plugin.Active || !Plugin.SteadyTarget.Value || !(ai is MonsterAI)) { return false; } Character val = Acc.Char.Invoke(ai); if ((Object)(object)val == (Object)null || val.IsTamed() || val.IsBoss() || (int)val.GetFaction() == 8) { return false; } return true; } private static void Decay(Mem m) { float num = Time.time - m.DmgAt; m.DmgAt = Time.time; if (num <= 0f || m.Dmg.Count == 0) { return; } float num2 = Mathf.Pow(0.5f, num / 8f); foreach (Character item in new List<Character>(m.Dmg.Keys)) { float num3 = m.Dmg[item] * num2; if ((Object)(object)item == (Object)null || num3 < 0.05f) { m.Dmg.Remove(item); } else { m.Dmg[item] = num3; } } } public static void Damaged(BaseAI ai, float damage, Character attacker) { if (!((Object)(object)attacker == (Object)null) && Applies(ai)) { Character val = Acc.Char.Invoke(ai); Mem mem = Get(ai); Decay(mem); float num = Mathf.Clamp(damage / Mathf.Max(1f, val.GetMaxHealth()), 0.02f, 1f) * 60f; mem.Dmg.TryGetValue(attacker, out var value); mem.Dmg[attacker] = value + num; mem.LastHitter = attacker; mem.LastHitAt = Time.time; MonsterAI val2 = (MonsterAI)(object)((ai is MonsterAI) ? ai : null); if ((Object)(object)val2 != (Object)null && (Object)(object)attacker != (Object)(object)Acc.Target.Invoke(val2)) { UpdateTimer.Invoke(val2) = Mathf.Min(UpdateTimer.Invoke(val2), 0.1f); } } } private static float Threat(MonsterAI ai, Character me, Character c, Mem m) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)c).transform.position - ((Component)me).transform.position; float magnitude = ((Vector3)(ref val)).magnitude; float num = 10f / (1f + magnitude / 4f) / (1f + Plugin.Split.Value * (float)Director.CountOn(c, ai)); if (m.Dmg.TryGetValue(c, out var value)) { num += value; } return num; } public static Character Choose(MonsterAI ai, Character vanilla) { //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)vanilla == (Object)null) { return null; } Character val = Acc.Char.Invoke((BaseAI)(object)ai); Character val2 = Acc.Target.Invoke(ai); Mem mem = Get((BaseAI)(object)ai); float time = Time.time; Decay(mem); if ((Object)(object)mem.Cur != (Object)(object)val2) { mem.Cur = val2; mem.Since = time; } bool flag = (Object)(object)val2 != (Object)null && !val2.IsDead() && BaseAI.IsEnemy(val, val2) && ((BaseAI)ai).CanSenseTarget(val2); Character val3 = null; float num = -1f; float num2 = -1f; foreach (Character allCharacter in Character.GetAllCharacters()) { if ((Object)(object)allCharacter == (Object)null || allCharacter.IsDead() || allCharacter.m_aiSkipTarget || !BaseAI.IsEnemy(val, allCharacter) || ((Object)(object)allCharacter == (Object)(object)Player.m_localPlayer && CinematicsManager.IsPlaying())) { continue; } BaseAI baseAI = allCharacter.GetBaseAI(); if ((!((Object)(object)baseAI != (Object)null) || !baseAI.IsSleeping()) && ((BaseAI)ai).CanSenseTarget(allCharacter)) { float num3 = Threat(ai, val, allCharacter, mem); if ((Object)(object)allCharacter == (Object)(object)val2) { num2 = num3; } if (num3 > num) { num = num3; val3 = allCharacter; } } } if ((Object)(object)val3 == (Object)null) { return vanilla; } Character val4 = val3; if (flag && (Object)(object)val3 != (Object)(object)val2 && num2 > 0f) { float num4 = Vector3.Distance(((Component)val3).transform.position, ((Component)val).transform.position); bool flag2 = (Object)(object)val3 == (Object)(object)mem.LastHitter && time - mem.LastHitAt < 1.5f; bool flag3 = num > num2 * ((num4 < 3f) ? 1.1f : 1.3f); if ((Object)(object)mem.Rival != (Object)(object)val3) { mem.Rival = val3; mem.RivalSince = time; } bool flag4 = time - mem.RivalSince >= 0.75f || flag2; bool flag5 = time - mem.Since < 3f && !flag2; if (!flag3 || !flag4 || flag5) { val4 = val2; if (flag3) { UpdateTimer.Invoke(ai) = Mathf.Min(UpdateTimer.Invoke(ai), 0.3f); } } } else { mem.Rival = null; } if ((Object)(object)val4 != (Object)(object)val2) { Director.Leave(ai); mem.Cur = val4; mem.Since = time; mem.Rival = null; } return val4; } public static void Prune() { List<BaseAI> list = null; foreach (BaseAI key in Mems.Keys) { if ((Object)(object)key == (Object)null) { (list ?? (list = new List<BaseAI>())).Add(key); } } if (list == null) { return; } foreach (BaseAI item in list) { Mems.Remove(item); } } } internal static class NavPieces { public static bool Building; private static bool Blocked(Component c) { if ((Object)(object)c == (Object)null) { return false; } Piece componentInParent = c.GetComponentInParent<Piece>(); if ((Object)(object)componentInParent == (Object)null) { return false; } string prefabName = Utils.GetPrefabName(((Component)componentInParent).gameObject); string[] array = Plugin.NoClimb.Value.Split(','); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length > 0 && prefabName.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } return false; } public static void Filter(List<NavMeshBuildSource> results) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (!Building || results == null || string.IsNullOrEmpty(Plugin.NoClimb.Value) || !Plugin.Active) { return; } for (int i = 0; i < results.Count; i++) { NavMeshBuildSource value = results[i]; if (((NavMeshBuildSource)(ref value)).area != 1 && Blocked(((NavMeshBuildSource)(ref value)).component)) { ((NavMeshBuildSource)(ref value)).area = 1; results[i] = value; } } } } internal static class NavLinks { private class Link { public NavMeshLinkInstance Inst; public int Agent; } public struct Beam { public Vector3 A; public Vector3 B; } private class Seg { public int Id; public Vector3 A; public Vector3 B; public int Root; } private static readonly Dictionary<int, List<Link>> byPiece = new Dictionary<int, List<Link>>(); private static readonly Dictionary<int, HashSet<int>> doneAgents = new Dictionary<int, HashSet<int>>(); private static readonly List<Piece> tmp = new List<Piece>(); private static float next; public static int Count; public static readonly Dictionary<int, Beam> Beams = new Dictionary<int, Beam>(); public static readonly HashSet<int> BeamPieces = new HashSet<int>(); public static bool Candidate(Piece p, out Vector3 a, out Vector3 b) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: 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_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Unknown result type (might be due to invalid IL or missing references) //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_03fb: Unknown result type (might be due to invalid IL or missing references) //IL_0400: Unknown result type (might be due to invalid IL or missing references) //IL_0405: Unknown result type (might be due to invalid IL or missing references) //IL_0413: Unknown result type (might be due to invalid IL or missing references) //IL_0418: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_0422: Unknown result type (might be due to invalid IL or missing references) //IL_042a: Unknown result type (might be due to invalid IL or missing references) //IL_042f: Unknown result type (might be due to invalid IL or missing references) //IL_0434: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_027a: 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_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0284: 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) a = (b = Vector3.zero); string prefabName = Utils.GetPrefabName(((Component)p).gameObject); bool flag = false; string[] array = Plugin.BridgePieces.Value.Split(','); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length > 0 && prefabName.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0) { flag = true; break; } } if (!flag) { return false; } BoxCollider[] componentsInChildren = ((Component)p).GetComponentsInChildren<BoxCollider>(); foreach (BoxCollider val in componentsInChildren) { if ((Object)(object)val == (Object)null || ((Collider)val).isTrigger || !((Collider)val).enabled) { continue; } Transform transform = ((Component)val).transform; Vector3 val2 = Vector3.Scale(val.size, transform.lossyScale); Vector3 val3 = ((val2.x >= val2.z) ? transform.right : transform.forward); float num = Mathf.Max(val2.x, val2.z); float num2 = Mathf.Min(val2.x, val2.z); if (!(Mathf.Abs(val3.y) > 0.5f)) { if (num < 2f || num2 > 1.2f) { return false; } Vector3 val4 = transform.TransformPoint(val.center); Vector3 val5 = val3; val5.y = 0f; ((Vector3)(ref val5)).Normalize(); float y = val4.y + Mathf.Abs(val2.y) * 0.5f; a = val4 - val5 * num * 0.5f; a.y = y; b = val4 + val5 * num * 0.5f; b.y = y; return true; } } List<Vector3> list = new List<Vector3>(); float num3 = float.MinValue; MeshRenderer[] componentsInChildren2 = ((Component)p).GetComponentsInChildren<MeshRenderer>(); foreach (MeshRenderer val6 in componentsInChildren2) { if (!((Object)(object)val6 == (Object)null) && ((Renderer)val6).enabled) { Bounds localBounds = ((Renderer)val6).localBounds; for (int j = 0; j < 8; j++) { Vector3 val7 = ((Bounds)(ref localBounds)).center + Vector3.Scale(((Bounds)(ref localBounds)).extents, new Vector3((float)(((j & 1) != 0) ? 1 : (-1)), (float)(((j & 2) != 0) ? 1 : (-1)), (float)(((j & 4) != 0) ? 1 : (-1)))); Vector3 val8 = ((Component)val6).transform.TransformPoint(val7); list.Add(val8); num3 = Mathf.Max(num3, val8.y); } } } if (list.Count < 2) { return false; } float num4 = 0f; for (int k = 0; k < list.Count; k++) { for (int l = k + 1; l < list.Count; l++) { float num5 = Utils.DistanceXZ(list[k], list[l]); if (num5 > num4) { num4 = num5; a = list[k]; b = list[l]; } } } if (num4 < 2f) { return false; } Vector3 val9 = b - a; val9.y = 0f; ((Vector3)(ref val9)).Normalize(); Vector3 val10 = Vector3.Cross(Vector3.up, val9); float num6 = float.MaxValue; float num7 = float.MinValue; foreach (Vector3 item in list) { float num8 = Vector3.Dot(item, val10); num6 = Mathf.Min(num6, num8); num7 = Mathf.Max(num7, num8); } if (num7 - num6 > 1.2f) { return false; } float num9 = (num6 + num7) * 0.5f; a += val10 * (num9 - Vector3.Dot(a, val10)); a.y = num3; b += val10 * (num9 - Vector3.Dot(b, val10)); b.y = num3; return true; } private static float PathLen(NavMeshPath path) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) float num = 0f; Vector3[] corners = path.corners; for (int i = 1; i < corners.Length; i++) { num += Vector3.Distance(corners[i - 1], corners[i]); } return num; } private static float SegDist(Vector3 p, Vector3 a, Vector3 b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) Vector3 val = b - a; Vector3 val2 = p - a; val.y = 0f; val2.y = 0f; float num = ((((Vector3)(ref val)).sqrMagnitude > 0.0001f) ? Mathf.Clamp01(Vector3.Dot(val2, val) / ((Vector3)(ref val)).sqrMagnitude) : 0f); Vector3 val3 = val2 - val * num; return ((Vector3)(ref val3)).magnitude; } private static int Find(List<Seg> segs, int i) { while (segs[i].Root != i) { segs[i].Root = segs[segs[i].Root].Root; i = segs[i].Root; } return i; } public static void Tick() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Unknown result type (might be due to invalid IL or missing references) //IL_040e: Unknown result type (might be due to invalid IL or missing references) //IL_0413: Unknown result type (might be due to invalid IL or missing references) //IL_0418: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_04b1: Unknown result type (might be due to invalid IL or missing references) //IL_04b3: Unknown result type (might be due to invalid IL or missing references) //IL_04ba: Unknown result type (might be due to invalid IL or missing references) //IL_04bc: Unknown result type (might be due to invalid IL or missing references) //IL_0437: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_053d: Unknown result type (might be due to invalid IL or missing references) //IL_053f: Unknown result type (might be due to invalid IL or missing references) //IL_0541: Unknown result type (might be due to invalid IL or missing references) //IL_0546: Unknown result type (might be due to invalid IL or missing references) //IL_07d2: Unknown result type (might be due to invalid IL or missing references) //IL_045a: Unknown result type (might be due to invalid IL or missing references) //IL_045f: Unknown result type (might be due to invalid IL or missing references) //IL_0465: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_056a: Unknown result type (might be due to invalid IL or missing references) //IL_0598: Unknown result type (might be due to invalid IL or missing references) //IL_05af: Unknown result type (might be due to invalid IL or missing references) //IL_05b1: Unknown result type (might be due to invalid IL or missing references) //IL_05b3: Unknown result type (might be due to invalid IL or missing references) //IL_05b5: Unknown result type (might be due to invalid IL or missing references) //IL_05bc: Unknown result type (might be due to invalid IL or missing references) //IL_05c1: Unknown result type (might be due to invalid IL or missing references) //IL_05cd: Unknown result type (might be due to invalid IL or missing references) //IL_05d4: Unknown result type (might be due to invalid IL or missing references) //IL_05d6: Unknown result type (might be due to invalid IL or missing references) //IL_05dd: Unknown result type (might be due to invalid IL or missing references) //IL_05e2: Unknown result type (might be due to invalid IL or missing references) //IL_05ee: Unknown result type (might be due to invalid IL or missing references) //IL_0603: Unknown result type (might be due to invalid IL or missing references) //IL_060a: Expected O, but got Unknown //IL_060c: Unknown result type (might be due to invalid IL or missing references) //IL_0613: Unknown result type (might be due to invalid IL or missing references) //IL_0621: Unknown result type (might be due to invalid IL or missing references) //IL_0628: Unknown result type (might be due to invalid IL or missing references) //IL_062d: Unknown result type (might be due to invalid IL or missing references) //IL_0657: Unknown result type (might be due to invalid IL or missing references) //IL_0661: Unknown result type (might be due to invalid IL or missing references) //IL_066f: Unknown result type (might be due to invalid IL or missing references) //IL_06aa: Unknown result type (might be due to invalid IL or missing references) //IL_06ac: Unknown result type (might be due to invalid IL or missing references) //IL_06b1: Unknown result type (might be due to invalid IL or missing references) //IL_063a: Unknown result type (might be due to invalid IL or missing references) //IL_06c4: Unknown result type (might be due to invalid IL or missing references) //IL_06c6: Unknown result type (might be due to invalid IL or missing references) //IL_06f5: Unknown result type (might be due to invalid IL or missing references) //IL_06f7: Unknown result type (might be due to invalid IL or missing references) //IL_06fe: Unknown result type (might be due to invalid IL or missing references) //IL_0700: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.Active || !Plugin.Bridges.Value || Time.time < next || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)Pathfinding.instance == (Object)null) { return; } HashSet<AgentType> hashSet = Brain.AgentTypesInUse(); if (hashSet.Count == 0) { return; } next = Time.time + 5f; tmp.Clear(); Piece.GetAllPiecesInRadius(((Component)Player.m_localPlayer).transform.position, 60f, tmp); List<Seg> list = new List<Seg>(); foreach (Piece item in tmp) { if (!((Object)(object)item == (Object)null) && Candidate(item, out var a, out var b)) { list.Add(new Seg { Id = ((Object)item).GetInstanceID(), A = a, B = b, Root = list.Count }); } } for (int i = 0; i < list.Count; i++) { for (int j = i + 1; j < list.Count; j++) { Vector3 val = list[i].B - list[i].A; Vector3 val2 = list[j].B - list[j].A; val.y = 0f; val2.y = 0f; if (!(Mathf.Abs(Vector3.Dot(((Vector3)(ref val)).normalized, ((Vector3)(ref val2)).normalized)) < 0.95f) && !(Mathf.Abs(list[i].A.y - list[j].A.y) > 0.3f) && (SegDist(list[i].A, list[j].A, list[j].B) < 0.7f || SegDist(list[i].B, list[j].A, list[j].B) < 0.7f || SegDist(list[j].A, list[i].A, list[i].B) < 0.7f || SegDist(list[j].B, list[i].A, list[i].B) < 0.7f)) { int num = Find(list, i); int num2 = Find(list, j); if (num != num2) { list[num2].Root = num; } } } } Dictionary<int, List<Seg>> dictionary = new Dictionary<int, List<Seg>>(); for (int k = 0; k < list.Count; k++) { int key = Find(list, k); if (!dictionary.TryGetValue(key, out var value)) { value = (dictionary[key] = new List<Seg>()); } value.Add(list[k]); } HashSet<int> hashSet2 = new HashSet<int>(); BeamPieces.Clear(); NavMeshHit val8 = default(NavMeshHit); NavMeshHit val9 = default(NavMeshHit); foreach (List<Seg> value3 in dictionary.Values) { List<Vector3> list3 = new List<Vector3>(); int num3 = 17; List<int> list4 = new List<int>(); foreach (Seg item2 in value3) { list3.Add(item2.A); list3.Add(item2.B); list4.Add(item2.Id); } list4.Sort(); foreach (int item3 in list4) { num3 = num3 * 31 + item3; } Vector3 val3 = list3[0]; Vector3 val4 = list3[1]; float num4 = -1f; for (int l = 0; l < list3.Count; l++) { for (int m = l + 1; m < list3.Count; m++) { float num5 = Utils.DistanceXZ(list3[l], list3[m]); if (num5 > num4) { num4 = num5; val3 = list3[l]; val4 = list3[m]; } } } hashSet2.Add(num3); if (num4 >= 3f) { Beams[num3] = new Beam { A = val3, B = val4 }; foreach (Seg item4 in value3) { BeamPieces.Add(item4.Id); } } if (!byPiece.TryGetValue(num3, out var value2)) { value2 = new List<Link>(); byPiece[num3] = value2; doneAgents[num3] = new HashSet<int>(); } Vector3 val5 = val4 - val3; val5.y = 0f; ((Vector3)(ref val5)).Normalize(); foreach (AgentType item5 in hashSet) { int num6 = Brain.AgentIdOf(item5); if (num6 < 0 || !doneAgents[num3].Add(num6)) { continue; } NavMeshQueryFilter val6 = default(NavMeshQueryFilter); ((NavMeshQueryFilter)(ref val6)).agentTypeID = num6; ((NavMeshQueryFilter)(ref val6)).areaMask = -1; NavMeshQueryFilter val7 = val6; bool num7 = NavMesh.SamplePosition(val3 - val5 * 0.8f, ref val8, 2f, val7); bool flag = NavMesh.SamplePosition(val4 + val5 * 0.8f, ref val9, 2f, val7); if (!num7 || !flag) { continue; } NavMeshPath val10 = new NavMeshPath(); float num8 = Vector3.Distance(((NavMeshHit)(ref val8)).position, ((NavMeshHit)(ref val9)).position); if (!NavMesh.CalculatePath(((NavMeshHit)(ref val8)).position, ((NavMeshHit)(ref val9)).position, val7, val10) || (int)val10.status != 0 || !(PathLen(val10) < num8 * 1.6f)) { NavMeshLinkData val11 = default(NavMeshLinkData); ((NavMeshLinkData)(ref val11)).startPosition = ((NavMeshHit)(ref val8)).position; ((NavMeshLinkData)(ref val11)).endPosition = ((NavMeshHit)(ref val9)).position; ((NavMeshLinkData)(ref val11)).width = 0f; ((NavMeshLinkData)(ref val11)).costModifier = -1f; ((NavMeshLinkData)(ref val11)).bidirectional = true; ((NavMeshLinkData)(ref val11)).area = 0; ((NavMeshLinkData)(ref val11)).agentTypeID = num6; NavMeshLinkInstance inst = NavMesh.AddLink(val11); if (((NavMeshLinkInstance)(ref inst)).valid) { value2.Add(new Link { Inst = inst, Agent = num6 }); Count++; Beams[num3] = new Beam { A = val3, B = val4 }; } } } } List<int> list5 = null; foreach (int key2 in byPiece.Keys) { if (!hashSet2.Contains(key2)) { (list5 ?? (list5 = new List<int>())).Add(key2); } } if (list5 == null) { return; } foreach (int item6 in list5) { foreach (Link item7 in byPiece[item6]) { NavMesh.RemoveLink(item7.Inst); Count--; } byPiece.Remove(item6); doneAgents.Remove(item6); Beams.Remove(item6); } } } public static class ServerSwitch { private const string Rpc = "Instinct_State"; public static bool ServerOff; private static ZRoutedRpc regOn; private static float nextCheck; private static bool lastSent = true; private static DateTime cfgTime; public static void Tick(Plugin p) { if ((Object)(object)ZNet.instance == (Object)null || ZRoutedRpc.instance == null) { ServerOff = false; regOn = null; return; } if (regOn != ZRoutedRpc.instance) { ZRoutedRpc.instance.Register<ZPackage>("Instinct_State", (Action<long, ZPackage>)OnState); regOn = ZRoutedRpc.instance; ServerOff = false; lastSent = Plugin.EnabledNow; } if (!ZNet.instance.IsServer() || Time.time < nextCheck) { return; } nextCheck = Time.time + 10f; string configFilePath = ((BaseUnityPlugin)p).Config.ConfigFilePath; if (File.Exists(configFilePath)) { DateTime lastWriteTimeUtc = File.GetLastWriteTimeUtc(configFilePath); if (cfgTime != default(DateTime) && lastWriteTimeUtc != cfgTime) { ((BaseUnityPlugin)p).Config.Reload(); } cfgTime = lastWriteTimeUtc; } bool enabledNow = Plugin.EnabledNow; if (enabledNow == lastSent) { return; } lastSent = enabledNow; foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { SendTo(peer.m_uid); } } public static void SendTo(long uid) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown if (ZRoutedRpc.instance != null && uid != 0L) { ZPackage val = new ZPackage(); val.Write(Plugin.EnabledNow); val.Write("1.0.0"); ZRoutedRpc.instance.InvokeRoutedRPC(uid, "Instinct_State", new object[1] { val }); } } private static void OnState(long sender, ZPackage pkg) { if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer()) { ZNetPeer serverPeer = ZNet.instance.GetServerPeer(); if (serverPeer != null && sender == serverPeer.m_uid) { bool num = pkg.ReadBool(); pkg.ReadString(); _ = ServerOff; ServerOff = !num; } } } } internal static class Frame { public static MonsterAI Ai; public static bool Other; public static bool Combat; public static bool Eligible; public static bool Flyer; } internal static class Patches { [HarmonyPatch(typeof(MonsterAI), "UpdateAI")] [HarmonyPrefix] private static void UpdatePre(MonsterAI __instance) { Frame.Ai = __instance; Frame.Other = false; Frame.Combat = false; Frame.Eligible = Plugin.Active && Brain.Eligible(__instance); Frame.Flyer = Plugin.Active && Plugin.Flyers.Value && Brain.FlyerEligible(__instance); } [HarmonyPatch(typeof(MonsterAI), "UpdateAI")] [HarmonyPostfix] private static void UpdatePost(MonsterAI __instance, bool __result, float dt) { try { if (!__result || !((Object)(object)Frame.Ai == (Object)(object)__instance) || !Plugin.Active || !Brain.TryBeam(__instance, dt)) { if (__result && (Object)(object)Frame.Ai == (Object)(object)__instance && Frame.Flyer && Frame.Combat && !Frame.Other) { Brain.FlyTick(__instance, dt); } else if (__result && (Object)(object)Frame.Ai == (Object)(object)__instance && Frame.Eligible && Frame.Combat && !Frame.Other) { Brain.Tick(__instance, dt); } else { _ = Brain.Debug; } } } catch (Exception ex) { Debug.LogWarning((object)("Instinct: " + ex)); Frame.Eligible = false; } Frame.Ai = null; } private static void MarkOther(BaseAI ai) { if ((Object)(object)Frame.Ai == (Object)(object)ai) { Frame.Other = true; } } [HarmonyPatch(typeof(BaseAI), "Flee")] [HarmonyPrefix] private static void P1(BaseAI __instance) { MarkOther(__instance); } [HarmonyPatch(typeof(BaseAI), "MoveAwayAndDespawn")] [HarmonyPrefix] private static void P2(BaseAI __instance) { MarkOther(__instance); } [HarmonyPatch(typeof(BaseAI), "Follow")] [HarmonyPrefix] private static void P3(BaseAI __instance) { MarkOther(__instance); } [HarmonyPatch(typeof(BaseAI), "IdleMovement")] [HarmonyPrefix] private static void P4(BaseAI __instance) { MarkOther(__instance); } [HarmonyPatch(typeof(BaseAI), "MoveToWater")] [HarmonyPrefix] private static void P5(BaseAI __instance) { MarkOther(__instance); } [HarmonyPatch(typeof(BaseAI), "AvoidFire")] [HarmonyPostfix] private static void P6(BaseAI __instance, bool __result) { if (__result) { MarkOther(__instance); } } [HarmonyPatch(typeof(MonsterAI), "SelectBestAttack")] [HarmonyPostfix] private static void SelectPost(MonsterAI __instance, ItemData __result) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Frame.Ai != (Object)(object)__instance)) { if (__result == null || (int)__result.m_shared.m_aiTargetType != 0) { Frame.Eligible = false; } else { Frame.Combat = true; } } } [HarmonyPatch(typeof(BaseAI), "RandomMovementArroundPoint")] [HarmonyPrefix] private static bool CirclePre(BaseAI __instance, Vector3 point) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) MonsterAI val = (MonsterAI)(object)((__instance is MonsterAI) ? __instance : null); if ((Object)(object)val == (Object)null || (Object)(object)Frame.Ai != (Object)(object)val || !Frame.Eligible) { return true; } Character val2 = Acc.Target.Invoke(val); if ((Object)(object)val2 == (Object)null || Utils.DistanceXZ(((Component)val2).transform.position, point) > 1f) { return true; } Frame.Combat = true; return false; } [HarmonyPatch(typeof(MonsterAI), "DoAttack")] [HarmonyPrefix] private static bool AttackPre(MonsterAI __instance, Character target, bool isFriend, ref bool __result) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) if (isFriend || (Object)(object)Frame.Ai != (Object)(object)__instance || !Frame.Eligible || (Object)(object)target == (Object)null) { return true; } if (!Brain.RangedAllowed(__instance, target)) { __result = false; return false; } Director.Member member = Director.Join(__instance, target); if (Plugin.FreeArchers.Value && Brain.HoldsRanged(__instance)) { return true; } if (!member.Token && Brain.RangedRole(__instance, target)) { return true; } if (member.Token) { if (!Brain.InReach(__instance, target, out var _)) { __result = false; return false; } Vector3 velocity = target.GetVelocity(); velocity.y = 0f; if ((!Plugin.HitNow.Value || !(((Vector3)(ref velocity)).magnitude > 1f)) && !Director.OffBeat(__instance, target, Brain.WindupOf(__instance), out var _)) { __result = false; return false; } return true; } __result = false; return false; } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] [HarmonyPostfix] private static void PeerInfoPost(ZNet __instance, ZRpc rpc) { try { if (!__instance.IsServer()) { return; } foreach (ZNetPeer peer in __instance.GetPeers()) { if (peer.m_rpc == rpc) { ServerSwitch.SendTo(peer.m_uid); break; } } } catch (Exception ex) { Debug.LogWarning((object)("Instinct: server switch on join " + ex.Message)); } } [HarmonyPatch(typeof(BaseAI), "FindEnemy")] [HarmonyPostfix] private static void FindEnemyPost(BaseAI __instance, ref Character __result) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown if ((Object)(object)Frame.Ai != (Object)(object)__instance || !Targeting.Applies(__instance)) { return; } try { __result = Targeting.Choose((MonsterAI)__instance, __result); } catch (Exception ex) { Debug.LogWarning((object)("Instinct: " + ex.Message)); } } [HarmonyPatch(typeof(MonsterAI), "OnDamaged")] [HarmonyPostfix] private static void DamagedPost(MonsterAI __instance, float damage, Character attacker) { try { Targeting.Damaged((BaseAI)(object)__instance, damage, attacker); } catch (Exception ex) { Debug.LogWarning((object)("Instinct: " + ex.Message)); } try { Brain.Hurt(__instance, damage); } catch (Exception ex2) { Debug.LogWarning((object)("Instinct: " + ex2.Message)); } } [HarmonyPatch(typeof(Pathfinding), "BuildTile")] [HarmonyPrefix] private static void BuildTilePre() { NavPieces.Building = true; } [HarmonyPatch(typeof(Pathfinding), "BuildTile")] [HarmonyFinalizer] private static Exception BuildTileFin(Exception __exception) { NavPieces.Building = false; return __exception; } [HarmonyPatch(typeof(NavMeshBuilder), "CollectSources", new Type[] { typeof(Bounds), typeof(int), typeof(NavMeshCollectGeometry), typeof(int), typeof(List<NavMeshBuildMarkup>), typeof(List<NavMeshBuildSource>) })] [HarmonyPostfix] private static void CollectPost(List<NavMeshBuildSource> results) { try { NavPieces.Filter(results); } catch (Exception ex) { Debug.LogWarning((object)("Instinct: " + ex.Message)); } } [HarmonyPatch(typeof(Humanoid), "StartAttack")] [HarmonyPostfix] private static void StartAttackPost(Humanoid __instance, bool __result) { if (!__result) { return; } try { Reach.Started(__instance); } catch (Exception ex) { Debug.LogWarning((object)("Instinct: " + ex.Message)); } } [HarmonyPatch(typeof(Attack), "OnAttackTrigger")] [HarmonyPrefix] private static void AttackTriggerPre(Attack __instance) { try { Reach.Triggered(__instance); } catch (Exception ex) { Debug.LogWarning((object)("Instinct: " + ex.Message)); } } [HarmonyPatch(typeof(Humanoid), "EquipBestWeapon")] [HarmonyPostfix] private static void EquipBestPost(Humanoid __instance) { try { Brain.AfterEquipBest(__instance); } catch (Exception ex) { Debug.LogWarning((object)("Instinct: " + ex.Message)); } } [HarmonyPatch(typeof(MonsterAI), "DoAttack")] [HarmonyPostfix] private static void AttackPost(MonsterAI __instance, Character target, bool __result) { if (__result && (Object)(object)target != (Object)null) { Director.Attacked(__instance, target); } } } internal static class Director { public class Member { public MonsterAI Ai; public float LastSeen; public bool Token; public float TokenSince; public float AttackedAt = -99f; public float CooldownUntil; public float SwingStart = -99f; public float HitEta = -99f; public bool OnDeck; public float Slot; public bool HasSlot; public float WaitSince = -1f; public bool Charging; } public class Fight { public Character Target; public readonly List<Member> Members = new List<Member>(); public float LastUpdate; public float NextSlots; public float SlotCost = float.MaxValue; public int SlotCount; public float ShockUntil = -99f; public MonsterAI Sup; public Vector3 Spot; public bool HasSpot; public float PressUntil; } public static readonly Dictionary<Character, Fight> Fights = new Dictionary<Character, Fight>(); private static readonly List<Character> dead = new List<Character>(); private static float Quick(Member m) { if (!Plugin.StarSkill.Value) { return 1f; } Character val = Acc.Char.Invoke((BaseAI)(object)m.Ai); int num = ((!((Object)(object)val != (Object)null)) ? 1 : val.GetLevel()); return 1f / (1f + 0.35f * (float)Mathf.Max(0, num - 1)); } private static void PickSuppressor(Fight f) { //IL_008b: 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_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.Suppress.Value) { f.Sup = null; return; } bool flag = false; foreach (Member member in f.Members) { if ((Object)(object)member.Ai == (Object)(object)f.Sup && !member.Token && Brain.HasRanged(member.Ai)) { flag = true; } } if (flag) { return; } MonsterAI val = null; float num = float.MaxValue; Vector3 position = ((Component)f.Target).transform.position; foreach (Member member2 in f.Members) { if (!member2.Token && !((Object)(object)member2.Ai == (Object)null) && Brain.HasRanged(member2.Ai)) { float num2 = Utils.DistanceXZ(((Component)Acc.Char.Invoke((BaseAI)(object)member2.Ai)).transform.position, position); if (num2 < num) { num = num2; val = member2.Ai; } } } if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)f.Sup) { Brain.ShoutOf(val); } f.Sup = val; } public static bool IsSup(MonsterAI ai, Character t) { if (Fights.TryGetValue(t, out var value)) { return (Object)(object)value.Sup == (Object)(object)ai; } return false; } public static bool SomeoneEngaged(Character t, MonsterAI except) { //IL_0087: 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) if (!Fights.TryGetValue(t, out var value)) { return false; } foreach (Member member in value.Members) { if (!((Object)(object)member.Ai == (Object)(object)except) && !((Object)(object)member.Ai == (Object)null)) { Character obj = Acc.Char.Invoke((BaseAI)(object)member.Ai); Humanoid val = (Humanoid)(object)((obj is Humanoid) ? obj : null); ItemData val2 = (((Object)(object)val != (Object)null) ? val.GetCurrentWeapon() : null); if (val2 != null && !Brain.IsRanged(val2) && Utils.DistanceXZ(((Component)val).transform.position, ((Component)t).transform.position) - t.GetRadius() < val2.m_shared.m_aiAttackRange + 0.3f) { return true; } } } return false; } public static void GrantNow(MonsterAI ai, Character t) { if (!Fights.TryGetValue(t, out var value)) { return; } foreach (Member member in value.Members) { if ((Object)(object)member.Ai == (Object)(object)ai && !member.Token) { Grant(member, Time.time, charge: false); } } } public static void Release(MonsterAI ai, float cooldown) { foreach (Fight value in Fights.Values) { foreach (Member member in value.Members) { if ((Object)(object)member.Ai == (Object)(object)ai && member.Token) { member.Token = false; member.Charging = false; member.CooldownUntil = Time.time + cooldown; } } } } private static void Grant(Member m, float now, bool charge) { if (charge && (Object)(object)m.Ai != (Object)null) { Brain.ShoutOf(m.Ai); } m.Token = true; m.TokenSince = now; m.OnDeck = false; m.Charging = charge; m.WaitSince = -1f; } public static bool Pressing(Character t) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.PressOnMove.Value) { return false; } if (!Fights.TryGetValue(t, out var value)) { return false; } Vector3 position = ((Component)t).transform.position; if (!value.HasSpot) { value.Spot = position; value.HasSpot = true; } if (Utils.DistanceXZ(position, value.Spot) > 5f) { value.Spot = position; value.PressUntil = Time.time + 3f; } return Time.time < value.PressUntil; } public static bool Shaken(Character t) { if (Fights.TryGetValue(t, out var value)) { return Time.time < value.ShockUntil; } return false; } private static void AssignSlots(Fight f) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) int count = f.Members.Count; if (count == 0) { return; } Vector3 position = ((Component)f.Target).transform.position; if (count == 1) { Member member = f.Members[0]; member.Slot = Brain.AngleAround(position, ((Component)Acc.Char.Invoke((BaseAI)(object)member.Ai)).transform.position); member.HasSlot = true; f.SlotCount = 1; return; } Vector3 forward = ((Component)f.Target).transform.forward; float facing = Mathf.Atan2(forward.x, forward.z) * 57.29578f; List<KeyValuePair<float, Member>> list = new List<KeyValuePair<float, Member>>(); foreach (Member member2 in f.Members) { list.Add(new KeyValuePair<float, Member>(Brain.AngleAround(position, ((Component)Acc.Char.Invoke((BaseAI)(object)member2.Ai)).transform.position), member2)); } list.Sort((KeyValuePair<float, Member> a, KeyValuePair<float, Member> b) => a.Key.CompareTo(b.Key)); float num = 360f / (float)count; float num2 = 0f; bool flag = f.SlotCount == count; if (flag) { foreach (KeyValuePair<float, Member> item in list) { num2 += Mathf.Abs(Mathf.DeltaAngle(item.Key, item.Value.Slot)) + FrontCost(item.Value.Slot, facing); } } float num3 = float.MaxValue; float num4 = 0f; int num5 = 0; for (float num6 = 0f; num6 < num; num6 += 5f) { for (int num7 = 0; num7 < count; num7++) { float num8 = 0f; for (int num9 = 0; num9 < count; num9++) { float num10 = list[0].Key + num6 + (float)((num9 + num7) % count) * num; float num11 = Mathf.Abs(Mathf.DeltaAngle(list[num9].Key, num10)); num8 += num11 + FrontCost(num10, facing); } if (num8 < num3) { num3 = num8; num4 = num6; num5 = num7; } } } if (!flag || !(num3 > num2 * 0.8f - 10f)) { for (int num12 = 0; num12 < count; num12++) { list[num12].Value.Slot = list[0].Key + num4 + (float)((num12 + num5) % count) * num; list[num12].Value.HasSlot = true; } f.SlotCount = count; } } private static float FrontCost(float slot, float facing) { float num = Mathf.Abs(Mathf.DeltaAngle(slot, facing)); if (!(num < 30f)) { return 0f; } return (30f - num) * 2f; } private static Fight Get(Character t) { if (!Fights.TryGetValue(t, out var value)) { value = new Fight { Target = t }; Fights[t] = value; } return value; } public static Member Join(MonsterAI ai, Character t) { Fight fight = Get(t); Member member = null; foreach (Member member2 in fight.Members) { if ((Object)(object)member2.Ai == (Object)(object)ai) { member = member2; break; } } if (member == null) { member = new Member { Ai = ai }; fight.Members.Add(member); } member.LastSeen = Time.time; if (Time.time - fight.LastUpdate > 0.1f) { Update(fight); } return member; } public static bool HolderNear(Character t, MonsterAI me, float angle, float deg) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) if (!Fights.TryGetValue(t, out var value)) { return false; } Vector3 position = ((Component)t).transform.position; foreach (Member member in value.Members) { if (!((Object)(object)member.Ai == (Object)(object)me) && member.Token && !((Object)(object)member.Ai == (Object)null)) { Character val = Acc.Char.Invoke((BaseAI)(object)member.Ai); if ((Object)(object)val != (Object)null && Mathf.Abs(Mathf.DeltaAngle(Brain.AngleAround(position, ((Component)val).transform.position), angle)) < deg) { return true; } } } return false; } public static int CountOn(Character t, MonsterAI except) { if (!Fights.TryGetValue(t, out var value)) { return 0; } int num = 0; foreach (Member member in value.Members) { if ((Object)(object)member.Ai != (Object)(object)except && (Object)(object)member.Ai != (Object)null && Time.time - member.LastSeen < 1f) { num++; } } return num; } public static void Leave(MonsterAI ai) { foreach (Fight value in Fights.Values) { value.Members.RemoveAll((Member m) => (Object)(object)m.Ai == (Object)(object)ai); } } private static void Update(Fight f) { //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_03e7: Unknown result type (might be due to invalid IL or missing references) //IL_03ec: Unknown result type (might be due to invalid IL or missing references) //IL_0635: Unknown result type (might be due to invalid IL or missing references) //IL_063a: Unknown result type (might be due to invalid IL or missing references) float now = Time.time; f.LastUpdate = now; int num = f.Members.RemoveAll((Member m) => now - m.LastSeen < 0.6f && ((Object)(object)m.Ai == (Object)null || (Object)(object)Acc.Char.Invoke((BaseAI)(object)m.Ai) == (Object)null || Acc.Char.Invoke((BaseAI)(object)m.Ai).IsDead())); f.Members.RemoveAll((Member m) => (Object)(object)m.Ai == (Object)null || now - m.LastSeen > 1f || (Object)(object)Acc.Char.Invoke((BaseAI)(object)m.Ai) == (Object)null || Acc.Char.Invoke((BaseAI)(object)m.Ai).IsDead()); if (num > 0 && f.Members.Count > 0 && Plugin.AllyDown.Value > 0f) { f.ShockUntil = now + Plugin.AllyDown.Value; } if (f.Members.Count == 0) { return; } if (now > f.NextSlots || f.SlotCount != f.Members.Count) { f.NextSlots = now + 0.5f; AssignSlots(f); } PickSuppressor(f); int num2 = Mathf.Max(1, Plugin.Tokens.Value); if (Plugin.ChaseRunner.Value && Brain.Running(f.Target)) { num2 = Mathf.Max(num2, f.Members.Count); } if (f.Members.Count <= num2) { foreach (Member member4 in f.Members) { member4.OnDeck = false; member4.WaitSince = -1f; if (!member4.Token) { Grant(member4, now, charge: false); } } return; } Vector3 forward = ((Component)f.Target).transform.forward; float num3 = Mathf.Atan2(forward.x, forward.z) * 57.29578f; int num4 = 0; foreach (Member member5 in f.Members) { if (member5.Token) { Character val = Acc.Char.Invoke((BaseAI)(object)member5.Ai); bool flag = member5.AttackedAt > member5.TokenSince && member5.HitEta >= member5.AttackedAt && now >= member5.HitEta + 0.1f; bool num5 = member5.AttackedAt > member5.TokenSince && (flag || (!val.InAttack() && now - member5.AttackedAt > 0.4f)); bool flag2 = now - member5.TokenSince > 7f && now - member5.AttackedAt > 2f; if (num5 || flag2) { member5.Token = false; member5.Charging = false; member5.CooldownUntil = now + 1.2f * Quick(member5); member5.WaitSince = now; } else { num4++; } } } foreach (Member member6 in f.Members) { if (!member6.Token && member6.WaitSince < 0f) { member6.WaitSince = now; } } Vector3 position = ((Component)f.Target).transform.position; bool flag3 = Plugin.PunishTired.Value && f.Target is Player && ((Player)f.Target).GetStamina() < 5f; for (; num4 < num2; num4++) { Member member = null; float num6 = float.MaxValue; foreach (Member member7 in f.Members) { if (member7.Token || (now < member7.CooldownUntil && !flag3)) { continue; } float num7 = Utils.DistanceXZ(((Component)Acc.Char.Invoke((BaseAI)(object)member7.Ai)).transform.position, position) - Mathf.Min(6f, (now - member7.AttackedAt) * 0.4f); if (Plugin.FlankBehind.Value && member7.HasSlot) { float num8 = Mathf.Abs(Mathf.DeltaAngle(member7.Slot, num3)); if (num8 > 110f) { num7 -= 1.5f; } else if (num8 > 60f) { num7 -= 0.7f; } } if (num7 < num6) { num6 = num7; member = member7; } } if (member == null) { break; } Grant(member, now, charge: false); } if (Plugin.Patience.Value > 0f && num4 >= num2) { bool flag4 = false; float num9 = -99f; foreach (Member member8 in f.Members) { if (member8.Token && member8.Charging) { flag4 = true; } num9 = Mathf.Max(num9, member8.AttackedAt); } if (!flag4) { Member member2 = null; float num10 = 0f; foreach (Member member9 in f.Members) { if (!member9.Token && !(member9.WaitSince < 0f)) { float num11 = now - member9.WaitSince; float num12 = Plugin.Patience.Value * Quick(member9); if (now - num9 < 2f) { num12 += 2f; } if (num11 > num12 && num11 > num10) { num10 = num11; member2 = member9; } } } if (member2 != null) { Grant(member2, now, charge: true); } } } Member member3 = null; float num13 = float.MaxValue; foreach (Member member10 in f.Members) { member10.OnDeck = false; if (!member10.Token) { float num14 = Utils.DistanceXZ(((Component)Acc.Char.Invoke((BaseAI)(object)member10.Ai)).transform.position, position) - Mathf.Min(6f, (now - member10.AttackedAt) * 0.4f) + ((now < member10.CooldownUntil) ? 3f : 0f); if (num14 < num13) { num13 = num14; member3 = member10; } } } if (member3 != null) { member3.OnDeck = true; } } public static bool MayAttack(MonsterAI ai, Character t) { if (!Fights.TryGetValue(t, out var value)) { return true; } foreach (Member member in value.Members) { if ((Object)(object)member.Ai == (Object)(object)ai) { return member.Token; } } return true; } public static void Attacked(MonsterAI ai, Character t) { if (!Fights.TryGetValue(t, out var value)) { return; } foreach (Member member in value.Members) { if ((Object)(object)member.Ai == (Object)(object)ai) { member.AttackedAt = Time.time; member.SwingStart = Time.time; member.HitEta = Time.time + Brain.WindupOf(ai); } } } public static void Landed(MonsterAI ai) { foreach (Fight value in Fights.Values) { foreach (Member member in value.Members) { if ((Object)(object)member.Ai == (Object)(object)ai && Time.time - member.SwingStart < 3f) { member.HitEta = Time.time; } } } } public static bool OffBeat(MonsterAI ai, Character t, float windup, out string why) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) why = ""; float value = Plugin.Stagger.Value; if (value <= 0f || !Fights.TryGetValue(t, out var value2)) { return true; } if (Plugin.PunishTired.Value && t is Player && ((Player)t).GetStamina() < 5f) { return true; } float time = Time.time; float num = time + windup; foreach (Member member in value2.Members) { if (!((Object)(object)member.Ai == (Object)(object)ai) && !(time - member.SwingStart > 3f)) { Character val = Acc.Char.Invoke((BaseAI)(object)member.Ai); if (!((Object)(object)val == (Object)null) && !val.IsDead() && !val.IsStaggering() && (!(member.HitEta < time - 0.05f) || val.InAttack()) && num < member.HitEta + value && num > member.HitEta - value) { why = "taking turns (partner lands in " + (member.HitEta - time).ToString("0.00") + " s)"; return false; } } } return true; } public static int WaitRank(Character t, MonsterAI ai) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) if (!Fights.TryGetValue(t, out var value)) { return 0; } Character val = Acc.Char.Invoke((BaseAI)(object)ai); if ((Object)(object)val == (Object)null) { return 0; } float num = Utils.DistanceXZ(((Component)val).transform.position, ((Component)t).transform.position); int num2 = 0; foreach (Member member in value.Members) { if (!((Object)(object)member.Ai == (Object)(object)ai) && !member.Token && !((Object)(object)member.Ai == (Object)null)) { Character val2 = Acc.Char.Invoke((BaseAI)(object)member.Ai); if ((Object)(object)val2 != (Object)null && Utils.DistanceXZ(((Component)val2).transform.position, ((Component)t).transform.position) < num) { num2++; } } } return num2; } public static IEnumerable<Member> Others(Character t, MonsterAI ai) { if (!Fights.TryGetValue(t, out var value)) { yield break; } foreach (Member member in value.Members) { if ((Object)(object)member.Ai != (Object)(object)ai && (Object)(object)member.Ai != (Object)null) { yield return member; } } } public static void Prune() { dead.Clear(); foreach (KeyValuePair<Character, Fight> fight in Fights) { if ((Object)(object)fight.Key == (Object)null || (fight.Value.Members.Count == 0 && Time.time - fight.Value.LastUpdate > 5f)) { dead.Add(fight.Key); } } foreach (Character item in dead) { Fights.Remove(item); } } } internal static class Brain { public class State { public float LastActive; public string Mode = "vanilla"; public Vector3 TargetVel; public Vector3 SmoothDir; public readonly List<Vector3> Path = new List<Vector3>(); public Vector3 PathGoal = new Vector3(1E+09f, 0f, 0f); public float PathTime = -99f; public float DriftSign = 1f; public bool Repositioning; public bool TurnWalk; public float BateSince = -1f; public float SwingAt = -1f; public bool WasInAttack; public float ArsenalAt; public ItemData Melee; public ItemData Ranged; public float RecoverUntil; public string WhyNot = "vanilla"; public float WhyAt = -99f; public string Prefab; public float FarSince = -1f; public float FarGap; public float JumpNext; public bool OnBeam; public int MountTries; public float MountPauseUntil; public Vector3 SegStart; public bool HasSeg; public string Style = "advance"; public int BandSide; public float BandUntil; public float BandRestUntil; public bool BandIn; public bool BandOut; public int AfterKind; public float AfterUntil; public float AfterGoal; public int AfterSide; public int CurveSide; public float CurveUntil; public bool CurveRolled; public float DodgeNext; public float DodgeUntil; public int DodgeSide; public float HiddenSince = -1f; public float FlushUntil; public Vector3 FlushSpot; public bool FlushHasSpot; public float ShoutNext; public readonly Dictionary<string, float> Used = new Dictionary<string, float>(); public Vector3 Anchor; public bool HasAnchor; } public static readonly Dictionary<MonsterAI, State> States = new Dictionary<MonsterAI, State>(); private static float nextPrune; public static bool Debug; private static readonly Dictionary<MonsterAI, string> sitNow = new Dictionary<MonsterAI, string>(); private static readonly Dictionary<MonsterAI, KeyValuePair<string, float>> sitCand = new Dictionary<MonsterAI, KeyValuePair<string, float>>(); private static string useGameCache; private static HashSet<string> useGameSet = new HashSet<string>(); private static readonly List<Vector3> flyPath = new List<Vector3>(); private static MethodInfo doAttack; private static readonly Dictionary<AgentType, int> agentIds = new Dictionary<AgentType, int>(); private static MethodInfo getSettings; private static readonly FieldRef<Character, Rigidbody> BodyOf = AccessTools.FieldRefAccess<Character, Rigidbody>("m_body"); private static int pieceMask; private static int blockMask; private static string StyleOf(string prefab) { string result = "advance"; int num = -1; string[] array = Plugin.Styles.Value.Split(','); foreach (string text in array) { int num2 = text.IndexOf('='); if (num2 > 0) { string text2 = text.Substring(0, num2).Trim(); string text3 = text.Substring(num2 + 1).Trim().ToLowerInvariant(); if (text2.Length > num && prefab.StartsWith(text2, StringComparison.OrdinalIgnoreCase)) { result = text3; num = text2.Length; } } } return result; } private static float WaitGap(State s) { if (s.Style == "close") { return Plugin.NearGap.Value; } if (s.Style == "cautious") { return Plugin.FarGap.Value; } return Plugin.RingGap.Value; } public static bool HasRanged(MonsterAI ai) { State state = Get(ai); Arsenal(ai, state); return state.Ranged != null; } public static bool RangedRole(MonsterAI ai, Character t) { Character obj = Acc.Char.Invoke((BaseAI)(object)ai); Humanoid val = (Humanoid)(object)((obj is Humanoid) ? obj : null); if ((Object)(object)val == (Object)null || !IsRanged(val.GetCurrentWeapon())) { return false; } State state = Get(ai); if (!Plugin.Suppress.Value || !Director.IsSup(ai, t)) { return Time.time < state.FlushUntil; } return true; } public static void ShoutOf(MonsterAI ai) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.Shout.Value || (Object)(object)ai == (Object)null) { return; } State state = Get(ai); if (!(Time.time < state.ShoutNext)) { state.ShoutNext = Time.time + 6f; Character val = Acc.Char.Invoke((BaseAI)(object)ai); if ((Object)(object)val != (Object)null) { ((BaseAI)ai).m_alertedEffects.Create(((Component)val).transform.position, ((Component)val).transform.rotation, (Transform)null, 1f, -1, default(ZDOID)); } } } public static void Hurt(MonsterAI ai, float damage) { //IL_0087: 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) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: 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_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: 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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.Active || Plugin.RetreatChance.Value <= 0f || !Eligible(ai)) { return; } Character val = Acc.Char.Invoke((BaseAI)(object)ai); Character val2 = Acc.Target.Invoke(ai); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || damage < val.GetMaxHealth() * 0.15f || Random.value > Plugin.RetreatChance.Value) { return; } Director.Release(ai, 1.5f); State state = Get(ai); Vector3 val3 = ((Component)val2).transform.position - ((Component)val).transform.position; val3.y = 0f; if (!(((Vector3)(ref val3)).sqrMagnitude < 0.01f)) { Vector3 val4 = -((Vector3)(ref val3)).normalized; Vector3 val5 = Vector3.Cross(Vector3.up, ((Vector3)(ref val3)).normalized); int num = ((!(Random.value < 0.5f)) ? 1 : (-1)); Vector3 val6 = val4 * 0.4f + val5 * (float)num * 0.92f; if (!Free(val, ((Vector3)(ref val6)).normalized, 2f)) { num = -num; } state.AfterKind = 2; state.AfterSide = num; state.AfterGoal = ((Vector3)(ref val3)).magnitude + 3f; state.AfterUntil = Time.time + 1.5f; } } private static bool AimedAt(Character me, Character t) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) Player val = (Player)(object)((t is Player) ? t : null); if ((Object)(object)val == (Object)null || ((Humanoid)val).GetAttackDrawPercentage() < 0.3f) { return false; } Vector3 val2 = (((Object)(object)((Character)val).m_eye != (Object)null) ? ((Character)val).m_eye.position : (((Component)val).transform.position + Vector3.up * 1.6f)); Vector3 val3 = me.GetCenterPoint() - val2; float magnitude = ((Vector3)(ref val3)).magnitude; if (magnitude > 30f || magnitude < 1f) { return false; } float num = 8f + Mathf.Atan2(me.GetRadius(), magnitude) * 57.29578f; return Vector3.Angle(((Character)val).GetLookDir(), val3) < num; } public static float WindupOf(MonsterAI ai) { Character obj = Acc.Char.Invoke((BaseAI)(object)ai); Humanoid val = (Humanoid)(object)((obj is Humanoid) ? obj : null); ItemData val2 = (((Object)(object)val != (Object)null) ? val.GetCurrentWeapon() : null); if (val2 == null) { return 0.7f; } return Reach.Get(val, val2).Windup; } public static bool InReach(MonsterAI ai, Character t, out string why) { //IL_00e8: 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_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) why = ""; if (!Plugin.PredictReach.Value) { return true; } Character obj = Acc.Char.Invoke((BaseAI)(object)ai); Humanoid val = (Humanoid)(object)((obj is Humanoid) ? obj : null); ItemData val2 = (((Object)(object)val != (Object)null) ? val.GetCurrentWeapon() : null); if (val2 == null || IsRanged(val2) || !Reach.Melee(val2.m_shared.m_attack)) { return true; } Reach.Info info = Reach.Get(val, val2); Reach.Gaps((Character)(object)val, t, info, out var now, out var then); State state = Get(ai); why = "slack " + now.ToString("0.0") + "->" + then.ToString("0.0") + " reach " + info.Reach.ToString("0.0") + ((info.N == 0) ? "?" : ""); if (Mathf.Abs(((Component)t).transform.position.y - ((Component)val).transform.position.y) > Mathf.Max(1.5f, ((Character)val).GetHeight() * 0.6f)) { why += " height"; return false; } if (then <= info.Reach - 0.15f && now <= info.Reach + 0.75f) { state.FarSince = -1f; return true; } if (state.FarSince < 0f || now < state.FarGap - 0.3f) { state.FarSince = Time.time; state.FarGap = now; } Vector3 val3 = ((Component)t).transform.position - ((Component)val).transform.position; val3.y = 0f; Vector3 velocity = t.GetVelocity(); velocity.y = 0f; float num = ((((Vector3)(ref val3)).sqrMagnitude > 0.0001f) ? Vector3.Dot(velocity, ((Vector3)(ref val3)).normalized) : 0f); if (Time.time - state.FarSince > 1.5f && num < 1f) { state.FarSince = -1f; why += " stuck"; return true; } why += " far"; return false; } [Conditional("BENCH")] public static void Why(MonsterAI ai, string why) { if (Debug) { State state = Get(ai); state.WhyNot = why; state.WhyAt = Time.time; } } private static State Get(MonsterAI ai) { if (States.TryGetValue(ai, out var value)) { return value; } value = new State(); Character val = Acc.Char.Invoke((BaseAI)(object)ai); value.Prefab = Utils.GetPrefabName(((Component)val).gameObject); value.DriftSign = ((Random.value > 0.5f) ? 1f : (-1f)); value.Style = StyleOf(value.Prefab); States[ai] = value; return value; } public static bool Starts(string name, string list) { string[] array = list.Split(','); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length > 0 && name.StartsWith(text, StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } public static bool Eligible(MonsterAI ai) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Invalid comparison between Unknown and I4 Character val = Acc.Char.Invoke((BaseAI)(object)ai); if ((Object)(object)val == (Object)null || val.IsTamed() || val.IsBoss() || val.IsFlying() || val.IsSwimming() || !(val is Humanoid)) { return false; } if ((int)val.GetFaction() == 8) { return false; } Character val2 = Acc.Target.Invoke(ai); if ((Object)(object)val2 == (Object)null || val2.IsDead()) { return false; } if (Plugin.UseGameIn.Value.Length > 0 && GameBetterHere(ai, val, val2)) { return false; } return true; } public static string Situation(MonsterAI ai, Character me, Character t) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) Vector3 velocity = t.GetVelocity(); velocity.y = 0f; string text; if (((Vector3)(ref velocity)).magnitude < 1f) { text = "still"; } else { Vector3 val = ((Component)t).transform.position - ((Component)me).transform.position; val.y = 0f; float num = ((((Vector3)(ref val)).sqrMagnitude > 0.01f) ? Vector3.Dot(((Vector3)(ref velocity)).normalized, ((Vector3)(ref val)).normalized) : 0f); text = ((num > 0.5f) ? "back_off" : ((num < -0.5f) ? "pass" : "strafe")); } if (!sitNow.TryGetValue(ai, out var value)) { sitNow[ai] = text; return text; } if (text == value) { sitCand.Remove(ai); return value; } if (!sitCand.TryGetValue(ai, out var value2) || value2.Key != text) { sitCand[ai] = new KeyValuePair<string, float>(text, Time.time); return value; } if (Time.time - value2.Value >= 0.5f) { sitNow[ai] = text; sitCand.Remove(ai); return text; } return value; } private static bool GameBetterHere(MonsterAI ai, Character me, Character t) { string value = Plugin.UseGameIn.Value; if (value != useGameCache) { useGameCache = value; useGameSet = new HashSet<string>(); string[] array = value.Split(','); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length > 0) { useGameSet.Add(text); } } } return useGameSet.Contains(Utils.GetPrefabName(((Component)me).gameObject) + ":" + Situation(ai, me, t)); } public static bool FlyerEligible(MonsterAI ai) { Character val = Acc.Char.Invoke((BaseAI)(object)ai); if ((Object)(object)val == (Object)null || !val.IsFlying() || val.IsTamed() || val.IsBoss()) { return false; } Character val2 = Acc.Target.Invoke(ai); if ((Object)(object)val2 != (Object)null) { return !val2.IsDead(); } return false; } private static void Arsenal(MonsterAI ai, State s) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) if (s.ArsenalAt > 0f && Time.time - s.ArsenalAt < 5f) { return; } s.ArsenalAt = Time.time; s.Melee = null; s.Ranged = null; Character obj = Acc.Char.Invoke((BaseAI)(object)ai); Humanoid val = (Humanoid)(object)((obj is Humanoid) ? obj : null); if ((Object)(object)val == (Object)null || val.GetInventory() == null) { return; } foreach (ItemData allItem in val.GetInventory().GetAllItems()) { if (allItem == null || (int)allItem.m_shared.m_aiTargetType != 0 || allItem.m_shared.m_aiAttackRange <= 0f) { continue; } if (allItem.m_shared.m_aiAttackRange > 8f) { if (s.Ranged == null || allItem.m_shared.m_aiAttackRange > s.Ranged.m_shared.m_aiAttackRange) { s.Ranged = allItem; } } else if (s.Melee == null || allItem.m_shared.m_aiAttackRange > s.Melee.m_shared.m_aiAttackRange) { s.Melee = allItem; } } } public static bool IsRanged(ItemData w) { if (w != null) { return w.m_shared.m_aiAttackRange > 8f; } return false; } public static bool HoldsRanged(MonsterAI ai) { Character obj = Acc.Char.Invoke((BaseAI)(object)ai); Humanoid val = (Humanoid)(object)((obj is Humanoid) ? obj : null); ItemData val2 = (((Object)(object)val != (Object)null) ? val.GetCurrentWeapon() : null); if (val2 == null || val2.m_shared.m_aiAttackRange <= 8f) { return false; } State state = Get(ai); Arsenal(ai, state); return state.Melee == null; } public static bool RangedAllowed(MonsterAI ai, Character t) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) Character val = Acc.Char.Invoke((BaseAI)(object)ai); Humanoid val2 = (Humanoid)(object)((val is Humanoid) ? val : null); ItemData val3 = (((Object)(object)val2 != (Object)null) ? val2.GetCurrentWeapon() : null); if (!IsRanged(val3)) { return true; } State state = Get(ai); Arsenal(ai, state); float num = Utils.DistanceXZ(((Component)val).transform.position, ((Component)t).transform.position) - t.GetRadius(); float aiAttackRange = val3.m_shared.m_aiAttackRange; bool flag = !Blocked(val, t); if (state.Melee == null) { if (flag) { return num <= aiAttackRange * 0.8f; } return false; } if (Plugin.Suppress.Value && (!Plugin.ChaseRunner.Value || !Running(t)) && Director.IsSup(ai, t) && flag && num <= aiAttackRange * 0.8f && num > state.Melee.m_shared.m_aiAttackRange + 2f && !Director.SomeoneEngaged(t, ai)) { return true; } if (Time.time < state.FlushUntil && flag && num <= aiAttackRange * 0.8f) { return true; } Vector3 val4 = ((Component)t).transform.position - ((Component)val).transform.position; val4.y = 0f; bool flag2 = ((Vector3)(ref val4)).sqrMagnitude > 0.01f && Vector3.Dot(t.GetVelocity(), ((Vector3)(ref val4)).normalized) > 2f; bool flag3 = !Pathfinding.instance.HavePath(((Component)val).transform.position, ((Component)t).transform.position, ((BaseAI)ai).m_pathAgentType); int num2; if (flag && num <= aiAttackRange * 0.7f && num > state.Melee.m_shared.m_aiAttackRange + 4f) { if (flag3) { num2 = 1; goto IL_01f3; } if (flag2) { num2 = ((!Plugin.ChaseRunner.Value) ? 1 : 0); if (num2 != 0) { goto IL_01f3; } } else { num2 = 0; } } else { num2 = 0; } val2.EquipItem(state.Melee, true); goto IL_01f3; IL_01f3: return (byte)num2 != 0; } public static void AfterEquipBest(Humanoid h) { if (!Plugin.Active || (Object)(object)h == (Object)null) { return; } MonsterAI component = ((Component)h).GetComponent<MonsterAI>(); if (!((Object)(object)component == (Object)null) && Eligible(component)) { Character val = Acc.Target.Invoke(component); if (!((Object)(object)val == (Object)null) && IsRanged(h.GetCurrentWeapon())) { RangedAllowed(component, val); } } } public static void FlyTick(MonsterAI ai, float dt) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to inval