using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Landfall.TABS;
using Landfall.TABS.AI;
using Landfall.TABS.AI.Components;
using Landfall.TABS.AI.Components.Tags;
using Landfall.TABS.AI.Systems;
using Landfall.TABS.GameState;
using Microsoft.CodeAnalysis;
using Unity.Entities;
using Unity.Mathematics;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("SmarterAI")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SmarterAI")]
[assembly: AssemblyTitle("SmarterAI")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace SmarterAI
{
public class Bootstrap : MonoBehaviour
{
private static Bootstrap _instance;
private SmartTargetingSystem _system;
public static void Ensure()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Expected O, but got Unknown
if (!((Object)(object)_instance != (Object)null))
{
GameObject val = new GameObject("SmarterAI_Bootstrap");
Object.DontDestroyOnLoad((Object)val);
_instance = val.AddComponent<Bootstrap>();
}
}
private void Update()
{
if (_system == null && World.Active != null)
{
_system = World.Active.GetOrCreateManager<SmartTargetingSystem>();
}
}
public static bool InBattle()
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Invalid comparison between Unknown and I4
GameStateManager service = ServiceLocator.GetService<GameStateManager>();
if (service != null)
{
return (int)service.GameState == 1;
}
return false;
}
}
public static class MountUtils
{
private static readonly string[] MountNameKeys = new string[5] { "horse", "raptor", "chariot", "elephant", "mammoth" };
public static string Normalize(string name)
{
if (string.IsNullOrEmpty(name))
{
return "";
}
return name.ToLowerInvariant().Replace("prefabs_vb", "").Replace("unitbases_vb", "")
.Replace("(clone)", "")
.Trim();
}
public static bool IsMount(Unit unit)
{
if ((Object)(object)unit == (Object)null)
{
return false;
}
string text = Normalize(((Object)unit).name);
for (int i = 0; i < MountNameKeys.Length; i++)
{
if (text.Contains(MountNameKeys[i]))
{
return true;
}
}
try
{
if ((Object)(object)unit.unitBlueprint != (Object)null && (Object)(object)unit.unitBlueprint.UnitBase != (Object)null)
{
string text2 = Normalize(((Object)unit.unitBlueprint.UnitBase).name);
for (int j = 0; j < MountNameKeys.Length; j++)
{
if (text2.Contains(MountNameKeys[j]))
{
return true;
}
}
}
}
catch
{
}
return false;
}
}
[HarmonyPatch(typeof(Unit), "Start")]
internal static class UnitStartPatch
{
private static void Postfix(Unit __instance)
{
if (Plugin.Enabled.Value && !((Object)(object)__instance == (Object)null))
{
if ((Object)(object)((Component)__instance).GetComponent<SmartBrain>() == (Object)null)
{
((Component)__instance).gameObject.AddComponent<SmartBrain>();
}
bool num = MountUtils.IsMount(__instance) || __instance.IsRider;
float value = Plugin.TurnSpeedMultiplier.Value;
if (!num && value > 0.01f && value != 1f)
{
__instance.turnSpeed *= value;
}
}
}
}
[HarmonyPatch(typeof(UnitAPI), "SetAttackTarget")]
internal static class SetAttackTargetPatch
{
private static void Prefix(UnitAPI __instance, float3 targetPos, Rigidbody mainRig, DataHandler unitData, ref TargetData targetData, ref bool canSeeTarget, bool startAttack)
{
if (!Plugin.Enabled.Value || (Object)(object)__instance == (Object)null)
{
return;
}
Unit component = ((Component)__instance).GetComponent<Unit>();
if ((Object)(object)component == (Object)null)
{
return;
}
SmartBrain component2 = ((Component)__instance).GetComponent<SmartBrain>();
if ((Object)(object)component2 != (Object)null && component2.SuppressAttack)
{
canSeeTarget = false;
}
bool num = RangedHelper.IsRanged(component, __instance);
if (num && Plugin.ExtendedFireRange.Value && targetData.TargetInAttackRange == 0)
{
float num2 = RangedHelper.GetAttackRange(component, __instance) * Plugin.FireRangeMult.Value;
if (targetData.DistanceToTarget <= num2)
{
targetData.TargetInAttackRange = 1;
if (component.InRangeAttackCooldown > 0f)
{
component.InRangeAttackCooldown = 0f;
}
}
}
if (((num && Plugin.FriendlyFireCheck.Value) & canSeeTarget) && (Object)(object)mainRig != (Object)null && RangedHelper.FriendlyBlocked(__instance, component, mainRig))
{
canSeeTarget = false;
}
}
}
internal static class RangedHelper
{
private static readonly List<Unit> UnitCache = new List<Unit>();
private static float _nextRefresh;
public static bool FriendlyBlocked(UnitAPI api, Unit self, Rigidbody targetRig)
{
//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_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: 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_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_0128: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_012c: Unknown result type (might be due to invalid IL or missing references)
//IL_0131: Unknown result type (might be due to invalid IL or missing references)
//IL_0136: 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_013a: Unknown result type (might be due to invalid IL or missing references)
//IL_013c: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: 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_0156: Unknown result type (might be due to invalid IL or missing references)
Vector3 rightWeaponPosition = api.GetRightWeaponPosition();
Vector3 val = targetRig.position - rightWeaponPosition;
float magnitude = ((Vector3)(ref val)).magnitude;
if (magnitude < 0.01f)
{
return false;
}
Vector3 val2 = val / magnitude;
float value = Plugin.FriendlyObstacleMinDistance.Value;
float value2 = Plugin.FriendlyBlockRadius.Value;
Team team = self.Team;
Transform root = ((Component)self).transform.root;
List<Unit> units = GetUnits();
for (int i = 0; i < units.Count; i++)
{
Unit val3 = units[i];
if ((Object)(object)val3 == (Object)null || (Object)(object)val3 == (Object)(object)self || val3.Team != team || (Object)(object)val3.data == (Object)null || (Object)(object)val3.data.mainRig == (Object)null || val3.data.Dead || (Object)(object)((Component)val3).transform.root == (Object)(object)root)
{
continue;
}
Vector3 position = val3.data.mainRig.position;
float num = Vector3.Dot(position - rightWeaponPosition, val2);
if (!(num < value) && !(num > magnitude * Plugin.BlockMaxFraction.Value))
{
Vector3 val4 = rightWeaponPosition + val2 * num;
Vector3 val5 = position - val4;
val5.y = 0f;
if (!(Mathf.Abs(position.y - val4.y) > 2f) && ((Vector3)(ref val5)).magnitude < value2)
{
Plugin.Dbg("[SmarterAI] shot blocked by friendly " + ((Object)val3).name);
return true;
}
}
}
return false;
}
public static List<Unit> GetUnits()
{
if (Time.time >= _nextRefresh)
{
_nextRefresh = Time.time + 0.5f;
UnitCache.Clear();
Unit[] array = Object.FindObjectsOfType<Unit>();
for (int i = 0; i < array.Length; i++)
{
UnitCache.Add(array[i]);
}
}
return UnitCache;
}
public static bool IsRanged(WeaponHandler wh, UnitAPI api)
{
if ((Object)(object)api != (Object)null && api.IsRangedUnit)
{
return true;
}
if ((Object)(object)wh != (Object)null)
{
if ((Object)(object)wh.rightWeapon != (Object)null && wh.rightWeapon.isRange)
{
return true;
}
if ((Object)(object)wh.leftWeapon != (Object)null && wh.leftWeapon.isRange)
{
return true;
}
}
return false;
}
public static bool IsRanged(Unit unit, UnitAPI api)
{
if ((Object)(object)api == (Object)null)
{
return false;
}
if (api.IsRangedUnit)
{
return true;
}
if ((Object)(object)unit != (Object)null && (Object)(object)unit.WeaponHandler != (Object)null)
{
return IsRanged(unit.WeaponHandler, api);
}
return false;
}
public static float GetAttackRange(Unit unit, UnitAPI api)
{
float num = 0f;
WeaponHandler val = (((Object)(object)unit != (Object)null) ? unit.WeaponHandler : null);
if ((Object)(object)val != (Object)null)
{
if ((Object)(object)val.rightWeapon != (Object)null)
{
num = Mathf.Max(num, val.rightWeapon.maxRange);
}
if ((Object)(object)val.leftWeapon != (Object)null)
{
num = Mathf.Max(num, val.leftWeapon.maxRange);
}
}
if (num <= 0.01f && (Object)(object)api != (Object)null)
{
num = api.GetAttackRange();
}
if (num <= 0.01f && (Object)(object)unit != (Object)null)
{
num = unit.m_AttackDistance;
}
return Mathf.Max(0.01f, num);
}
}
[HarmonyPatch(typeof(WeaponHandler), "Attack")]
internal static class WeaponAttackRangePatch
{
private static readonly Dictionary<int, float[]> OriginalRanges = new Dictionary<int, float[]>();
private static bool IsRangedUnit(WeaponHandler wh, UnitAPI api)
{
return RangedHelper.IsRanged(wh, api);
}
private static void Prefix(WeaponHandler __instance)
{
if (!Plugin.Enabled.Value || !Plugin.ExtendedFireRange.Value || (Object)(object)__instance == (Object)null)
{
return;
}
UnitAPI component = ((Component)__instance).GetComponent<UnitAPI>();
if (!((Object)(object)component == (Object)null) && IsRangedUnit(__instance, component))
{
float value = Plugin.FireRangeMult.Value;
float[] array = new float[2];
int num = 0;
if ((Object)(object)__instance.rightWeapon != (Object)null)
{
array[num++] = __instance.rightWeapon.maxRange;
Weapon rightWeapon = __instance.rightWeapon;
rightWeapon.maxRange *= value;
}
if ((Object)(object)__instance.leftWeapon != (Object)null)
{
array[num++] = __instance.leftWeapon.maxRange;
Weapon leftWeapon = __instance.leftWeapon;
leftWeapon.maxRange *= value;
}
OriginalRanges[((Object)__instance).GetInstanceID()] = array;
}
}
private static void Postfix(WeaponHandler __instance)
{
if (!((Object)(object)__instance == (Object)null) && OriginalRanges.TryGetValue(((Object)__instance).GetInstanceID(), out var value))
{
OriginalRanges.Remove(((Object)__instance).GetInstanceID());
int num = 0;
if ((Object)(object)__instance.rightWeapon != (Object)null && num < value.Length && value[num] > 0f)
{
__instance.rightWeapon.maxRange = value[num++];
}
if ((Object)(object)__instance.leftWeapon != (Object)null && num < value.Length && value[num] > 0f)
{
__instance.leftWeapon.maxRange = value[num++];
}
}
}
}
[HarmonyPatch(typeof(UnitAPI), "SetLookDirection")]
internal static class LookDirectionOverridePatch
{
private static void Prefix(UnitAPI __instance, ref Vector3 localDirection)
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
if (Plugin.Enabled.Value && !((Object)(object)__instance == (Object)null))
{
SmartBrain component = ((Component)__instance).GetComponent<SmartBrain>();
if ((Object)(object)component != (Object)null && component.TryGetDesiredDirection(out var dir))
{
localDirection = dir;
}
}
}
}
[HarmonyPatch(typeof(UnitAPI), "SetMovementSpeed")]
internal static class MovementSpeedOverridePatch
{
private static void Prefix(UnitAPI __instance, ref float movementSpeed)
{
if (Plugin.Enabled.Value && !((Object)(object)__instance == (Object)null))
{
SmartBrain component = ((Component)__instance).GetComponent<SmartBrain>();
if ((Object)(object)component != (Object)null && component.TryGetDesiredSpeed(out var speed))
{
movementSpeed = speed;
}
}
}
}
[HarmonyPatch(typeof(Weapon), "Awake")]
internal static class SpreadPatch
{
private static void Postfix(Weapon __instance)
{
if (!Plugin.Enabled.Value || (Object)(object)__instance == (Object)null)
{
return;
}
RangeWeapon val = (RangeWeapon)(object)((__instance is RangeWeapon) ? __instance : null);
if ((Object)(object)val == (Object)null)
{
return;
}
if (Plugin.DisableCowardPenalty.Value)
{
val.extraSpreadInMelee = 0f;
val.extraCDInMelee = 0f;
}
if (Plugin.SpreadEnabled.Value)
{
float value = Plugin.AddedSpread.Value;
if (!(value <= 0f))
{
float num = Mathf.Max(0.01f, __instance.maxRange);
float num2 = Plugin.SpreadReferenceRange.Value / num;
float num3 = value * num2;
float spread = val.spread;
val.spread = Mathf.Sqrt(spread * spread + num3 * num3);
}
}
}
}
[BepInPlugin("local.smarterai", "Tactics", "1.12.0")]
public class Plugin : BaseUnityPlugin
{
public const string GUID = "local.smarterai";
public const string Name = "Tactics";
public const string Version = "1.12.0";
public static ManualLogSource Log;
public static ConfigEntry<bool> Enabled;
public static ConfigEntry<bool> DebugLog;
public static ConfigEntry<float> TurnSpeedMultiplier;
public static ConfigEntry<bool> SmarterTargeting;
public static ConfigEntry<float> CrowdWeight;
public static ConfigEntry<float> RetargetInterval;
public static ConfigEntry<float> SwitchMargin;
public static ConfigEntry<float> RangedThreshold;
public static ConfigEntry<bool> Spacing;
public static ConfigEntry<float> SeparationRadius;
public static ConfigEntry<float> SeparationWeight;
public static ConfigEntry<float> ObstacleRadius;
public static ConfigEntry<float> ObstacleWidth;
public static ConfigEntry<float> ObstacleWeight;
public static ConfigEntry<float> FlankMinDistance;
public static ConfigEntry<float> FlankStrength;
public static ConfigEntry<bool> ExtendedFireRange;
public static ConfigEntry<float> FireRangeMult;
public static ConfigEntry<bool> RangedKite;
public static ConfigEntry<float> FleeRangeMult;
public static ConfigEntry<float> FleeMaxDistance;
public static ConfigEntry<float> TurnBackDelay;
public static ConfigEntry<float> MinFleeTime;
public static ConfigEntry<float> TurnCompleteAngle;
public static ConfigEntry<float> MaxTurnTime;
public static ConfigEntry<float> FleeSpeed;
public static ConfigEntry<float> FleeExitBuffer;
public static ConfigEntry<float> FleeDistanceFactor;
public static ConfigEntry<bool> KiteOnlyWithoutMelee;
public static ConfigEntry<float> AwaitShotDuration;
public static ConfigEntry<float> MinKiteRange;
public static ConfigEntry<bool> MapClamp;
public static ConfigEntry<float> BoundsMargin;
public static ConfigEntry<bool> DisableCowardPenalty;
public static ConfigEntry<bool> SpreadEnabled;
public static ConfigEntry<float> AddedSpread;
public static ConfigEntry<float> SpreadReferenceRange;
public static ConfigEntry<bool> FriendlyFireCheck;
public static ConfigEntry<float> FriendlyObstacleMinDistance;
public static ConfigEntry<float> FriendlyBlockRadius;
public static ConfigEntry<float> BlockMaxFraction;
private void Awake()
{
//IL_05a8: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch.");
DebugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DebugLog", false, "Verbose logging.");
TurnSpeedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("General", "TurnSpeedMultiplier", 5f, "Global multiplier on unit turn speed (how fast they rotate to face a new direction).");
SmarterTargeting = ((BaseUnityPlugin)this).Config.Bind<bool>("1_Targeting", "Enabled", true, "Melee units re-pick targets preferring enemies that fewer allies already aim at.");
CrowdWeight = ((BaseUnityPlugin)this).Config.Bind<float>("1_Targeting", "CrowdWeight", 0.25f, "Weight of 'already targeted by N allies' in target scoring. Vanilla is 0.05. Higher = spread out more.");
RetargetInterval = ((BaseUnityPlugin)this).Config.Bind<float>("1_Targeting", "RetargetInterval", 0.6f, "Seconds between target re-picks per unit (prevents path thrashing).");
SwitchMargin = ((BaseUnityPlugin)this).Config.Bind<float>("1_Targeting", "SwitchMargin", 2f, "New target must score this much better than the current one to switch (hysteresis).");
RangedThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("1_Targeting", "RangedThreshold", 5f, "Attack range above which a unit counts as ranged (target re-pick only affects melee).");
Spacing = ((BaseUnityPlugin)this).Config.Bind<bool>("2_Spacing", "Enabled", true, "Melee units keep space from nearby units (both teams), steer around blockers, and fan out when approaching.");
SeparationRadius = ((BaseUnityPlugin)this).Config.Bind<float>("2_Spacing", "SeparationRadius", 0.4f, "Keep-away radius between units (m).");
SeparationWeight = ((BaseUnityPlugin)this).Config.Bind<float>("2_Spacing", "SeparationWeight", 2.5f, "Strength of the separation push.");
ObstacleRadius = ((BaseUnityPlugin)this).Config.Bind<float>("2_Spacing", "ObstacleRadius", 3f, "Units ahead closer than this are treated as path obstacles (m).");
ObstacleWidth = ((BaseUnityPlugin)this).Config.Bind<float>("2_Spacing", "ObstacleWidth", 1.2f, "Lateral corridor half-width for obstacle detection (m).");
ObstacleWeight = ((BaseUnityPlugin)this).Config.Bind<float>("2_Spacing", "ObstacleWeight", 4f, "Strength of obstacle avoidance steer.");
FlankMinDistance = ((BaseUnityPlugin)this).Config.Bind<float>("2_Spacing", "FlankMinDistance", 4f, "Beyond this distance to target, melee units add a lateral (flanking) offset (m).");
FlankStrength = ((BaseUnityPlugin)this).Config.Bind<float>("2_Spacing", "FlankStrength", 0f, "Strength of the flanking offset. 0 = off (keeps units on the nav path).");
ExtendedFireRange = ((BaseUnityPlugin)this).Config.Bind<bool>("3_RangedFire", "Enabled", true, "Ranged units may open fire at FireRangeMult x range; they still only stand still inside normal range.");
FireRangeMult = ((BaseUnityPlugin)this).Config.Bind<float>("3_RangedFire", "FireRangeMult", 1.5f, "Fire range multiplier.");
RangedKite = ((BaseUnityPlugin)this).Config.Bind<bool>("4_Kite", "Enabled", true, "After a ranged unit attacks while an enemy is within FleeRangeMult x range, it turns and flees until its weapon is ready again.");
FleeRangeMult = ((BaseUnityPlugin)this).Config.Bind<float>("4_Kite", "FleeRangeMult", 1.2f, "Flee trigger distance as a multiplier of attack range.");
FleeMaxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("4_Kite", "FleeMaxDistance", 15f, "Absolute cap for the flee trigger distance (m), so long-range units do not flee from far-away enemies.");
TurnBackDelay = ((BaseUnityPlugin)this).Config.Bind<float>("4_Kite", "TurnBackDelay", 1f, "Seconds to wait facing the enemy before resuming fire after turning back.");
MinFleeTime = ((BaseUnityPlugin)this).Config.Bind<float>("4_Kite", "MinFleeTime", 0.6f, "Minimum seconds a unit keeps fleeing once it starts (makes the retreat actually visible).");
TurnCompleteAngle = ((BaseUnityPlugin)this).Config.Bind<float>("4_Kite", "TurnCompleteAngle", 30f, "A unit counts as 'facing' its desired direction below this angle (degrees). Turning happens in place before moving.");
MaxTurnTime = ((BaseUnityPlugin)this).Config.Bind<float>("4_Kite", "MaxTurnTime", 0.4f, "After this many seconds of turning in place, the unit starts running even if not fully turned.");
FleeSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("4_Kite", "FleeSpeed", 1f, "Movement speed while fleeing.");
FleeExitBuffer = ((BaseUnityPlugin)this).Config.Bind<float>("4_Kite", "FleeExitBuffer", 2f, "Fleeing only stops when the closest enemy is beyond trigger distance + this buffer (m).");
FleeDistanceFactor = ((BaseUnityPlugin)this).Config.Bind<float>("4_Kite", "FleeDistanceFactor", 0.5f, "Flee destination = self + away-from-enemy direction * this * attack range. If that point has no ground / is blocked / off-map, the unit does NOT flee.");
KiteOnlyWithoutMelee = ((BaseUnityPlugin)this).Config.Bind<bool>("4_Kite", "KiteOnlyWithoutMelee", true, "Only units with NO melee weapon kite; units with a melee sidearm keep fighting.");
AwaitShotDuration = ((BaseUnityPlugin)this).Config.Bind<float>("4_Kite", "AwaitShotDuration", 1.5f, "Time the unit holds its firing stance (covers attack windup + shot) before it re-evaluates fleeing.");
MinKiteRange = ((BaseUnityPlugin)this).Config.Bind<float>("4_Kite", "MinKiteRange", 6f, "Units whose weapon range is below this never kite (keeps short-range 'ranged' units like ninjas fighting in melee).");
MapClamp = ((BaseUnityPlugin)this).Config.Bind<bool>("5_MapBounds", "Enabled", true, "Clamp movement destinations to the map circle, keeping units from pathing off the land.");
BoundsMargin = ((BaseUnityPlugin)this).Config.Bind<float>("5_MapBounds", "BoundsMargin", 0.5f, "Extra margin inside the map edge (m).");
DisableCowardPenalty = ((BaseUnityPlugin)this).Config.Bind<bool>("8_Coward", "Enabled", true, "Disable the vanilla 'coward' mechanic where some shooters get extra spread and longer attack cooldown when enemies are too close.");
SpreadEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("7_Spread", "Enabled", true, "Add extra spread to ranged weapons, in quadrature: newSpread = sqrt(old^2 + AddedSpread^2). Low-spread units get a big penalty, high-spread units barely change.");
AddedSpread = ((BaseUnityPlugin)this).Config.Bind<float>("7_Spread", "AddedSpread", 3f, "Base quadrature spread. Final added = AddedSpread * (SpreadReferenceRange / weapon range).");
SpreadReferenceRange = ((BaseUnityPlugin)this).Config.Bind<float>("7_Spread", "SpreadReferenceRange", 10f, "Weapon range whose accuracy factor is 1 (roughly a javelin). Longer ranges get a proportionally smaller spread penalty.");
FriendlyFireCheck = ((BaseUnityPlugin)this).Config.Bind<bool>("6_FriendlyFire", "Enabled", true, "Ranged units treat friendly units further than FriendlyObstacleMinDistance as line-of-sight obstacles.");
FriendlyObstacleMinDistance = ((BaseUnityPlugin)this).Config.Bind<float>("6_FriendlyFire", "FriendlyObstacleMinDistance", 1f, "Friendlies closer than this do NOT block the shot (m).");
FriendlyBlockRadius = ((BaseUnityPlugin)this).Config.Bind<float>("6_FriendlyFire", "FriendlyBlockRadius", 0.35f, "A friendly blocks the shot only if its body passes within this distance of the firing line (m).");
BlockMaxFraction = ((BaseUnityPlugin)this).Config.Bind<float>("6_FriendlyFire", "BlockMaxFraction", 0.6f, "Only friendlies within this fraction of the shot distance count as cover.");
new Harmony("local.smarterai").PatchAll();
Bootstrap.Ensure();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Tactics 1.12.0 loaded.");
}
public static void Dbg(string msg)
{
if (DebugLog != null && DebugLog.Value)
{
Log.LogInfo((object)msg);
}
}
}
public class SmartBrain : MonoBehaviour
{
private enum FleeState
{
None,
Fleeing,
TurnBack,
AwaitingShot
}
private Unit _unit;
private UnitAPI _api;
private DataHandler _data;
private WeaponHandler _wh;
private FleeState _flee;
private float _turnBackTimer;
private float _awaitShotTimer;
private float _fleeStartTime;
private float _flankSide = 1f;
private float _strafeSide = 1f;
private bool _blockedCached;
private float _nextBlockedCheck;
private float _blockedSince = -1f;
private float _nextScan;
private Vector3 _sepCache;
private Vector3 _avoidCache;
private Vector3 _headingSmoothed;
private Vector3 _fleeDest;
private bool _fleeDestValid;
private float _nextDestCheck;
private static int _mapLayerMask = -2;
private int _computedFrame = -1;
private bool _hasDirOverride;
private bool _hasSpeedOverride;
private Vector3 _desiredDir;
private float _desiredSpeed;
private bool _isMount;
private float _nextEnemyScan;
private float _closestEnemyDist = float.PositiveInfinity;
private Vector3 _closestEnemyPos;
private bool _computeLogged;
private static int _brainCount;
private static int _dirOverrides;
private static int _speedOverrides;
private static float _nextHeartbeat;
public bool SuppressAttack
{
get
{
if (_flee != FleeState.Fleeing)
{
return _flee == FleeState.TurnBack;
}
return true;
}
}
private static int MapLayerMask
{
get
{
if (_mapLayerMask == -2)
{
_mapLayerMask = LayerMask.GetMask(new string[1] { "Map" });
}
return _mapLayerMask;
}
}
private void Start()
{
_unit = ((Component)this).GetComponent<Unit>();
_data = ((Component)this).GetComponentInChildren<DataHandler>();
_api = ((Component)this).GetComponent<UnitAPI>();
_wh = ((Component)this).GetComponentInChildren<WeaponHandler>();
if ((Object)(object)_wh == (Object)null && (Object)(object)_unit != (Object)null)
{
_wh = _unit.WeaponHandler;
}
_isMount = MountUtils.IsMount(_unit) || ((Object)(object)_unit != (Object)null && _unit.IsRider);
Plugin.Log.LogInfo((object)("[SmarterAI] brain attached to " + (((Object)(object)_unit != (Object)null) ? ((Object)_unit).name : ((Object)this).name) + " mount=" + _isMount + " ranged=" + IsRanged()));
_brainCount++;
int instanceID = ((Object)this).GetInstanceID();
_flankSide = ((instanceID % 3 - 1 >= 0) ? 1f : (-1f));
_strafeSide = ((instanceID % 2 == 0) ? 1f : (-1f));
}
private bool IsMount()
{
if (_isMount)
{
return true;
}
return false;
}
private bool IsRanged()
{
if ((Object)(object)_api != (Object)null && _api.IsRangedUnit)
{
return true;
}
if ((Object)(object)_wh != (Object)null)
{
if ((Object)(object)_wh.rightWeapon != (Object)null && _wh.rightWeapon.isRange)
{
return true;
}
if ((Object)(object)_wh.leftWeapon != (Object)null && _wh.leftWeapon.isRange)
{
return true;
}
}
return false;
}
private float GetAttackRange()
{
return RangedHelper.GetAttackRange(_unit, _api);
}
private bool HasMeleeWeapon()
{
if ((Object)(object)_wh != (Object)null)
{
if ((Object)(object)_wh.rightWeapon != (Object)null && !_wh.rightWeapon.isRange)
{
return true;
}
if ((Object)(object)_wh.leftWeapon != (Object)null && !_wh.leftWeapon.isRange)
{
return true;
}
}
return false;
}
private void ScanClosestEnemy(Vector3 myPos)
{
//IL_0030: 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_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: 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_00a8: 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)
if (Time.time < _nextEnemyScan)
{
return;
}
_nextEnemyScan = Time.time + 0.15f;
_closestEnemyDist = float.PositiveInfinity;
Team team = _unit.Team;
List<Unit> units = RangedHelper.GetUnits();
for (int i = 0; i < units.Count; i++)
{
Unit val = units[i];
if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)_unit) && val.Team != team && !((Object)(object)val.data == (Object)null) && !((Object)(object)val.data.mainRig == (Object)null) && !val.data.Dead)
{
float num = Vector3.Distance(myPos, val.data.mainRig.position);
if (num < _closestEnemyDist)
{
_closestEnemyDist = num;
_closestEnemyPos = val.data.mainRig.position;
}
}
}
}
private float GetFleeTriggerDistance()
{
return Mathf.Min(GetAttackRange() * Plugin.FleeRangeMult.Value, Plugin.FleeMaxDistance.Value);
}
private bool WeaponReady()
{
Weapon val = null;
if ((Object)(object)_wh != (Object)null)
{
val = _wh.rightWeapon;
if ((Object)(object)val == (Object)null)
{
val = _wh.leftWeapon;
}
}
if ((Object)(object)val == (Object)null)
{
return true;
}
return val.internalCounter >= val.internalCooldown;
}
private float FacingAngleTo(Vector3 worldDir)
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: 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_0045: 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_0075: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_data == (Object)null || (Object)(object)_data.characterForwardObject == (Object)null)
{
return 0f;
}
Vector3 forward = _data.characterForwardObject.forward;
forward.y = 0f;
Vector3 val = worldDir;
val.y = 0f;
if (((Vector3)(ref forward)).sqrMagnitude < 0.001f || ((Vector3)(ref val)).sqrMagnitude < 0.001f)
{
return 0f;
}
return Vector3.Angle(forward, val);
}
private bool ComputeFleeDestination(Vector3 myPos, Vector3 enemyPos, out Vector3 dest)
{
//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_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: 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_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_0054: 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_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_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: 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)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0122: Unknown result type (might be due to invalid IL or missing references)
//IL_012c: 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_015a: Unknown result type (might be due to invalid IL or missing references)
//IL_0164: Unknown result type (might be due to invalid IL or missing references)
//IL_0169: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: 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_0176: 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_017d: Unknown result type (might be due to invalid IL or missing references)
//IL_019d: 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_01a3: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = myPos - enemyPos;
val.y = 0f;
dest = Vector3.zero;
if (((Vector3)(ref val)).sqrMagnitude < 0.001f)
{
return false;
}
((Vector3)(ref val)).Normalize();
dest = myPos + val * (GetAttackRange() * Plugin.FleeDistanceFactor.Value);
if ((Object)(object)MapSettings.Instance != (Object)null)
{
Vector3 mapCenter = MapSettings.Instance.m_mapCenter;
float num = MapSettings.Instance.m_mapRadius - Plugin.BoundsMargin.Value;
Vector2 val2 = default(Vector2);
((Vector2)(ref val2))..ctor(dest.x - mapCenter.x, dest.z - mapCenter.z);
if (((Vector2)(ref val2)).magnitude > num)
{
return false;
}
}
RaycastHit[] array = Physics.RaycastAll(dest + Vector3.up * 8f, Vector3.down, 25f);
if (array == null || array.Length == 0)
{
return false;
}
bool flag = false;
for (int i = 0; i < array.Length; i++)
{
RaycastHit val3 = array[i];
if (!((Object)(object)((RaycastHit)(ref val3)).collider == (Object)null) && !((Object)(object)((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent<DataHandler>() != (Object)null) && !(((RaycastHit)(ref val3)).point.y < myPos.y - 2.5f))
{
flag = true;
break;
}
}
if (!flag)
{
return false;
}
int mapLayerMask = MapLayerMask;
if (mapLayerMask != 0)
{
Vector3 val4 = myPos + Vector3.up * 0.6f;
Vector3 val5 = dest - val4;
val5.y = 0f;
float magnitude = ((Vector3)(ref val5)).magnitude;
if (magnitude > 0.01f && Physics.Raycast(val4, val5 / magnitude, magnitude, mapLayerMask))
{
return false;
}
}
return true;
}
private void RefreshFleeDestination(Vector3 myPos, Vector3 enemyPos)
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
if (!(Time.time < _nextDestCheck))
{
_nextDestCheck = Time.time + 0.25f;
_fleeDestValid = ComputeFleeDestination(myPos, enemyPos, out _fleeDest);
}
}
public bool TryGetDesiredDirection(out Vector3 dir)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
Compute();
dir = _desiredDir;
if (_hasDirOverride)
{
_dirOverrides++;
}
return _hasDirOverride;
}
public bool TryGetDesiredSpeed(out float speed)
{
Compute();
speed = _desiredSpeed;
if (_hasSpeedOverride)
{
_speedOverrides++;
}
return _hasSpeedOverride;
}
private static void Heartbeat(SmartBrain self)
{
if (Time.time >= _nextHeartbeat)
{
_nextHeartbeat = Time.time + 5f;
Plugin.Log.LogInfo((object)("[SmarterAI] heartbeat brains=" + _brainCount + " dirOverrides/5s=" + _dirOverrides + " speedOverrides/5s=" + _speedOverrides));
_dirOverrides = 0;
_speedOverrides = 0;
}
}
private void Compute()
{
if (_computedFrame == Time.frameCount)
{
return;
}
_computedFrame = Time.frameCount;
try
{
ComputeInner();
}
catch (Exception ex)
{
if (!_computeLogged)
{
_computeLogged = true;
Plugin.Log.LogError((object)("[SmarterAI] SmartBrain.Compute error: " + ex));
}
}
}
private void ComputeInner()
{
//IL_00bd: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: 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_00f0: 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_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_0116: Unknown result type (might be due to invalid IL or missing references)
//IL_067c: Unknown result type (might be due to invalid IL or missing references)
//IL_0681: Unknown result type (might be due to invalid IL or missing references)
//IL_069c: Unknown result type (might be due to invalid IL or missing references)
//IL_06a2: 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_06b0: Unknown result type (might be due to invalid IL or missing references)
//IL_06c8: Unknown result type (might be due to invalid IL or missing references)
//IL_06cf: Unknown result type (might be due to invalid IL or missing references)
//IL_06d5: Unknown result type (might be due to invalid IL or missing references)
//IL_06dc: Unknown result type (might be due to invalid IL or missing references)
//IL_06e1: Unknown result type (might be due to invalid IL or missing references)
//IL_06e2: Unknown result type (might be due to invalid IL or missing references)
//IL_06e7: 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_0739: Unknown result type (might be due to invalid IL or missing references)
//IL_0743: Unknown result type (might be due to invalid IL or missing references)
//IL_074c: Unknown result type (might be due to invalid IL or missing references)
//IL_0756: Unknown result type (might be due to invalid IL or missing references)
//IL_0706: Unknown result type (might be due to invalid IL or missing references)
//IL_070b: Unknown result type (might be due to invalid IL or missing references)
//IL_0770: Unknown result type (might be due to invalid IL or missing references)
//IL_0777: Unknown result type (might be due to invalid IL or missing references)
//IL_077c: Unknown result type (might be due to invalid IL or missing references)
//IL_077e: Unknown result type (might be due to invalid IL or missing references)
//IL_0785: Unknown result type (might be due to invalid IL or missing references)
//IL_078d: Unknown result type (might be due to invalid IL or missing references)
//IL_0793: Unknown result type (might be due to invalid IL or missing references)
//IL_079a: Unknown result type (might be due to invalid IL or missing references)
//IL_07a2: Unknown result type (might be due to invalid IL or missing references)
//IL_07a7: Unknown result type (might be due to invalid IL or missing references)
//IL_07a8: Unknown result type (might be due to invalid IL or missing references)
//IL_07ad: Unknown result type (might be due to invalid IL or missing references)
//IL_0829: Unknown result type (might be due to invalid IL or missing references)
//IL_082e: Unknown result type (might be due to invalid IL or missing references)
//IL_0834: Unknown result type (might be due to invalid IL or missing references)
//IL_0839: Unknown result type (might be due to invalid IL or missing references)
//IL_083f: Unknown result type (might be due to invalid IL or missing references)
//IL_0840: Unknown result type (might be due to invalid IL or missing references)
//IL_07cc: Unknown result type (might be due to invalid IL or missing references)
//IL_07d1: Unknown result type (might be due to invalid IL or missing references)
//IL_0887: Unknown result type (might be due to invalid IL or missing references)
//IL_088c: Unknown result type (might be due to invalid IL or missing references)
//IL_088d: Unknown result type (might be due to invalid IL or missing references)
//IL_0892: Unknown result type (might be due to invalid IL or missing references)
//IL_0896: Unknown result type (might be due to invalid IL or missing references)
//IL_089b: Unknown result type (might be due to invalid IL or missing references)
//IL_089d: Unknown result type (might be due to invalid IL or missing references)
//IL_08a2: Unknown result type (might be due to invalid IL or missing references)
//IL_08a4: Unknown result type (might be due to invalid IL or missing references)
//IL_08a9: Unknown result type (might be due to invalid IL or missing references)
//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
//IL_0a39: Unknown result type (might be due to invalid IL or missing references)
//IL_0a3b: Unknown result type (might be due to invalid IL or missing references)
//IL_0a41: Unknown result type (might be due to invalid IL or missing references)
//IL_0a43: Unknown result type (might be due to invalid IL or missing references)
//IL_0a72: Unknown result type (might be due to invalid IL or missing references)
//IL_0a73: Unknown result type (might be due to invalid IL or missing references)
//IL_05da: Unknown result type (might be due to invalid IL or missing references)
//IL_05df: Unknown result type (might be due to invalid IL or missing references)
//IL_05e0: Unknown result type (might be due to invalid IL or missing references)
//IL_05e5: Unknown result type (might be due to invalid IL or missing references)
//IL_05e9: Unknown result type (might be due to invalid IL or missing references)
//IL_05f4: Unknown result type (might be due to invalid IL or missing references)
//IL_05f9: Unknown result type (might be due to invalid IL or missing references)
//IL_05ff: Unknown result type (might be due to invalid IL or missing references)
//IL_0604: Unknown result type (might be due to invalid IL or missing references)
//IL_0609: Unknown result type (might be due to invalid IL or missing references)
//IL_0aa8: Unknown result type (might be due to invalid IL or missing references)
//IL_0aae: Unknown result type (might be due to invalid IL or missing references)
//IL_0ab4: Unknown result type (might be due to invalid IL or missing references)
//IL_0ac3: Unknown result type (might be due to invalid IL or missing references)
//IL_0ac8: Unknown result type (might be due to invalid IL or missing references)
//IL_0ace: Unknown result type (might be due to invalid IL or missing references)
//IL_0add: Unknown result type (might be due to invalid IL or missing references)
//IL_0ae2: Unknown result type (might be due to invalid IL or missing references)
//IL_0a8b: Unknown result type (might be due to invalid IL or missing references)
//IL_0a8d: Unknown result type (might be due to invalid IL or missing references)
//IL_0a9c: Unknown result type (might be due to invalid IL or missing references)
//IL_0aa1: 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_0372: Unknown result type (might be due to invalid IL or missing references)
//IL_0377: Unknown result type (might be due to invalid IL or missing references)
//IL_0ae7: Unknown result type (might be due to invalid IL or missing references)
//IL_0459: Unknown result type (might be due to invalid IL or missing references)
//IL_045e: Unknown result type (might be due to invalid IL or missing references)
//IL_028b: Unknown result type (might be due to invalid IL or missing references)
//IL_028d: Unknown result type (might be due to invalid IL or missing references)
//IL_039a: Unknown result type (might be due to invalid IL or missing references)
//IL_039f: Unknown result type (might be due to invalid IL or missing references)
//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
//IL_0390: Unknown result type (might be due to invalid IL or missing references)
//IL_0391: Unknown result type (might be due to invalid IL or missing references)
//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
//IL_0b1f: Unknown result type (might be due to invalid IL or missing references)
//IL_0b26: Unknown result type (might be due to invalid IL or missing references)
//IL_0b3b: Unknown result type (might be due to invalid IL or missing references)
//IL_0b40: Unknown result type (might be due to invalid IL or missing references)
//IL_0b4c: Unknown result type (might be due to invalid IL or missing references)
//IL_0b51: Unknown result type (might be due to invalid IL or missing references)
//IL_0b17: Unknown result type (might be due to invalid IL or missing references)
//IL_0b18: Unknown result type (might be due to invalid IL or missing references)
//IL_094e: Unknown result type (might be due to invalid IL or missing references)
//IL_0953: Unknown result type (might be due to invalid IL or missing references)
//IL_0955: Unknown result type (might be due to invalid IL or missing references)
//IL_0956: Unknown result type (might be due to invalid IL or missing references)
//IL_0958: Unknown result type (might be due to invalid IL or missing references)
//IL_095d: Unknown result type (might be due to invalid IL or missing references)
//IL_0481: Unknown result type (might be due to invalid IL or missing references)
//IL_0486: Unknown result type (might be due to invalid IL or missing references)
//IL_0487: Unknown result type (might be due to invalid IL or missing references)
//IL_048c: Unknown result type (might be due to invalid IL or missing references)
//IL_0477: Unknown result type (might be due to invalid IL or missing references)
//IL_0478: 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_03c4: Unknown result type (might be due to invalid IL or missing references)
//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
//IL_02db: Unknown result type (might be due to invalid IL or missing references)
//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
//IL_04ab: Unknown result type (might be due to invalid IL or missing references)
//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
//IL_09a8: Unknown result type (might be due to invalid IL or missing references)
//IL_09aa: Unknown result type (might be due to invalid IL or missing references)
//IL_09af: Unknown result type (might be due to invalid IL or missing references)
//IL_09b1: Unknown result type (might be due to invalid IL or missing references)
//IL_09b3: Unknown result type (might be due to invalid IL or missing references)
//IL_0986: Unknown result type (might be due to invalid IL or missing references)
//IL_0988: Unknown result type (might be due to invalid IL or missing references)
//IL_098c: Unknown result type (might be due to invalid IL or missing references)
//IL_099c: Unknown result type (might be due to invalid IL or missing references)
//IL_09a1: Unknown result type (might be due to invalid IL or missing references)
//IL_09a6: Unknown result type (might be due to invalid IL or missing references)
//IL_09cf: Unknown result type (might be due to invalid IL or missing references)
//IL_09d1: Unknown result type (might be due to invalid IL or missing references)
//IL_09e1: Unknown result type (might be due to invalid IL or missing references)
//IL_09e3: Unknown result type (might be due to invalid IL or missing references)
//IL_0a02: Unknown result type (might be due to invalid IL or missing references)
//IL_0a04: Unknown result type (might be due to invalid IL or missing references)
//IL_0a08: Unknown result type (might be due to invalid IL or missing references)
//IL_0a18: Unknown result type (might be due to invalid IL or missing references)
//IL_0a1d: Unknown result type (might be due to invalid IL or missing references)
//IL_0a22: Unknown result type (might be due to invalid IL or missing references)
_hasDirOverride = false;
_hasSpeedOverride = false;
Heartbeat(this);
if (!Plugin.Enabled.Value || (Object)(object)_unit == (Object)null || (Object)(object)_data == (Object)null || (Object)(object)_api == (Object)null || _data.Dead || !_api.Active || _api.IsRemotelyControlled || _api.IsPossessed || !Bootstrap.InBattle() || _isMount)
{
return;
}
Vector3 val = (((Object)(object)_data.mainRig != (Object)null) ? _data.mainRig.position : ((Component)this).transform.position);
Rigidbody targetMainRig = _data.targetMainRig;
Vector3 val2 = Vector3.zero;
float num = 0f;
if ((Object)(object)targetMainRig != (Object)null)
{
Vector3 val3 = targetMainRig.position - val;
val3.y = 0f;
num = ((Vector3)(ref val3)).magnitude;
if (num > 0.001f)
{
val2 = val3 / num;
}
}
bool flag = IsRanged();
Vector3 val7;
if (flag)
{
if (Plugin.RangedKite.Value && !IsMount() && GetAttackRange() >= Plugin.MinKiteRange.Value && (!Plugin.KiteOnlyWithoutMelee.Value || !HasMeleeWeapon()))
{
ScanClosestEnemy(val);
float fleeTriggerDistance = GetFleeTriggerDistance();
float num2 = fleeTriggerDistance + Plugin.FleeExitBuffer.Value;
bool flag2 = _closestEnemyDist < float.PositiveInfinity;
bool flag3 = flag2 && _closestEnemyDist < fleeTriggerDistance;
bool flag4 = !flag2 || _closestEnemyDist > num2;
if (_flee == FleeState.None && flag3)
{
RefreshFleeDestination(val, _closestEnemyPos);
_nextDestCheck = 0f;
RefreshFleeDestination(val, _closestEnemyPos);
if (_fleeDestValid)
{
_flee = FleeState.Fleeing;
_fleeStartTime = Time.time;
Plugin.Dbg("[SmarterAI] " + ((Object)_unit).name + " starts kiting toward safe ground");
}
}
if (_flee == FleeState.Fleeing)
{
if (flag4)
{
_flee = FleeState.None;
}
else if (WeaponReady() && Time.time - _fleeStartTime >= Plugin.MinFleeTime.Value)
{
_flee = FleeState.TurnBack;
_turnBackTimer = Plugin.TurnBackDelay.Value;
}
else if (flag2)
{
RefreshFleeDestination(val, _closestEnemyPos);
if (!_fleeDestValid)
{
_flee = FleeState.None;
return;
}
Vector3 val4 = _fleeDest - val;
val4.y = 0f;
if (((Vector3)(ref val4)).sqrMagnitude > 0.04f)
{
Vector3 worldDir = (_desiredDir = ((Vector3)(ref val4)).normalized);
_hasDirOverride = true;
bool flag5 = FacingAngleTo(worldDir) <= Plugin.TurnCompleteAngle.Value;
bool flag6 = Time.time - _fleeStartTime >= Plugin.MaxTurnTime.Value;
_desiredSpeed = ((flag5 || flag6) ? Plugin.FleeSpeed.Value : 0f);
_hasSpeedOverride = true;
}
else
{
_desiredSpeed = 0f;
_hasSpeedOverride = true;
}
return;
}
}
if (_flee == FleeState.TurnBack)
{
if (flag4)
{
_flee = FleeState.None;
}
else
{
Vector3 val5 = Vector3.zero;
if ((Object)(object)targetMainRig != (Object)null && ((Vector3)(ref val2)).sqrMagnitude > 0.001f)
{
val5 = val2;
}
else if (flag2)
{
val5 = _closestEnemyPos - val;
val5.y = 0f;
}
if (((Vector3)(ref val5)).sqrMagnitude > 0.001f)
{
_desiredDir = ((Vector3)(ref val5)).normalized;
_hasDirOverride = true;
_desiredSpeed = 0f;
_hasSpeedOverride = true;
}
if (FacingAngleTo(_desiredDir) <= Plugin.TurnCompleteAngle.Value)
{
_turnBackTimer -= Time.deltaTime;
}
if (!(_turnBackTimer <= 0f))
{
return;
}
_flee = FleeState.AwaitingShot;
_awaitShotTimer = Plugin.AwaitShotDuration.Value;
}
}
if (_flee == FleeState.AwaitingShot)
{
if (flag4)
{
_flee = FleeState.None;
}
else
{
Vector3 val6 = Vector3.zero;
if ((Object)(object)targetMainRig != (Object)null && ((Vector3)(ref val2)).sqrMagnitude > 0.001f)
{
val6 = val2;
}
else if (flag2)
{
val6 = _closestEnemyPos - val;
val6.y = 0f;
}
if (((Vector3)(ref val6)).sqrMagnitude > 0.001f)
{
_desiredDir = ((Vector3)(ref val6)).normalized;
_hasDirOverride = true;
_desiredSpeed = 0f;
_hasSpeedOverride = true;
}
_awaitShotTimer -= Time.deltaTime;
if (_awaitShotTimer <= 0f)
{
_flee = FleeState.None;
}
}
}
}
if (Plugin.FriendlyFireCheck.Value && (Object)(object)targetMainRig != (Object)null && num > 0.001f && (_flee == FleeState.None || _flee == FleeState.AwaitingShot))
{
if (Time.time >= _nextBlockedCheck)
{
_nextBlockedCheck = Time.time + 0.2f;
_blockedCached = RangedHelper.FriendlyBlocked(_api, _unit, targetMainRig);
if (_blockedCached && _blockedSince < 0f)
{
_blockedSince = Time.time;
}
if (!_blockedCached)
{
_blockedSince = -1f;
}
}
if (_blockedCached)
{
if (_blockedSince > 0f && Time.time - _blockedSince > 1.5f)
{
_strafeSide = 0f - _strafeSide;
_blockedSince = Time.time;
}
val7 = Vector3.Cross(Vector3.up, val2);
Vector3 val8 = ((Vector3)(ref val7)).normalized * _strafeSide + val2 * 0.25f;
val8.y = 0f;
if (((Vector3)(ref val8)).sqrMagnitude > 0.001f)
{
_desiredDir = ((Vector3)(ref val8)).normalized;
_hasDirOverride = true;
_dirOverrides++;
_desiredSpeed = 1.5f;
_hasSpeedOverride = true;
}
return;
}
}
}
if (Plugin.MapClamp.Value && (Object)(object)MapSettings.Instance != (Object)null)
{
Vector3 mapCenter = MapSettings.Instance.m_mapCenter;
float num3 = MapSettings.Instance.m_mapRadius - Plugin.BoundsMargin.Value;
Vector2 val9 = default(Vector2);
((Vector2)(ref val9))..ctor(val.x - mapCenter.x, val.z - mapCenter.z);
if (((Vector2)(ref val9)).magnitude > num3)
{
Vector3 val10 = new Vector3(mapCenter.x, val.y, mapCenter.z) - val;
val10.y = 0f;
if (((Vector3)(ref val10)).sqrMagnitude > 0.001f)
{
_desiredDir = ((Vector3)(ref val10)).normalized;
_hasDirOverride = true;
_desiredSpeed = 2f;
_hasSpeedOverride = true;
}
return;
}
if ((Object)(object)targetMainRig != (Object)null)
{
Vector2 val11 = default(Vector2);
((Vector2)(ref val11))..ctor(targetMainRig.position.x - mapCenter.x, targetMainRig.position.z - mapCenter.z);
if (((Vector2)(ref val11)).magnitude > num3)
{
Vector2 val12 = ((Vector2)(ref val11)).normalized * num3;
Vector3 val13 = new Vector3(mapCenter.x + val12.x, val.y, mapCenter.z + val12.y) - val;
val13.y = 0f;
if (((Vector3)(ref val13)).sqrMagnitude > 0.001f)
{
_desiredDir = ((Vector3)(ref val13)).normalized;
_hasDirOverride = true;
}
return;
}
}
}
if (!Plugin.Spacing.Value || flag || (Object)(object)targetMainRig == (Object)null || num < 0.001f || _data.distanceToTarget > 20f)
{
return;
}
float num4 = GetAttackRange() + 1f;
if (num <= num4)
{
_sepCache = Vector3.zero;
_avoidCache = Vector3.zero;
_headingSmoothed = val2;
return;
}
if (Time.time >= _nextScan)
{
_nextScan = Time.time + 0.1f * (0.8f + 0.4f * ((float)(((Object)this).GetInstanceID() & 0x3FF) / 1023f));
val7 = Vector3.Cross(Vector3.up, val2);
Vector3 normalized = ((Vector3)(ref val7)).normalized;
Vector3 val14 = Vector3.zero;
Vector3 val15 = Vector3.zero;
float value = Plugin.SeparationRadius.Value;
float value2 = Plugin.ObstacleRadius.Value;
float value3 = Plugin.ObstacleWidth.Value;
List<Unit> units = RangedHelper.GetUnits();
for (int i = 0; i < units.Count; i++)
{
Unit val16 = units[i];
if ((Object)(object)val16 == (Object)null || (Object)(object)val16 == (Object)(object)_unit || (Object)(object)val16.data == (Object)null || (Object)(object)val16.data.mainRig == (Object)null || val16.data.Dead)
{
continue;
}
Vector3 position = val16.data.mainRig.position;
Vector3 val17 = val - position;
val17.y = 0f;
float magnitude = ((Vector3)(ref val17)).magnitude;
if (magnitude < 0.001f)
{
continue;
}
if (magnitude < value)
{
val14 += val17 / magnitude * (1f - magnitude / value);
}
Vector3 val18 = -val17;
float num5 = Vector3.Dot(val18, val2);
if (num5 > 0f && num5 < value2 && num5 < num && Mathf.Abs(Vector3.Dot(val18, normalized)) < value3)
{
float num6 = Mathf.Sign(Vector3.Dot(normalized, val17));
if (num6 == 0f)
{
num6 = _flankSide;
}
val15 += normalized * num6 * (1f - num5 / value2);
}
}
_sepCache = val14;
_avoidCache = val15;
}
if (!(((Vector3)(ref _sepCache)).sqrMagnitude > 0.0025f) && !(((Vector3)(ref _avoidCache)).sqrMagnitude > 0.0025f))
{
_headingSmoothed = val2;
return;
}
Vector3 val19 = ((((Vector3)(ref _avoidCache)).sqrMagnitude > 0.0025f) ? (val2 * 0.35f + _avoidCache * Plugin.ObstacleWeight.Value + _sepCache * Plugin.SeparationWeight.Value) : (val2 + _sepCache * Plugin.SeparationWeight.Value));
val19.y = 0f;
if (!(((Vector3)(ref val19)).sqrMagnitude < 0.001f))
{
if (((Vector3)(ref _headingSmoothed)).sqrMagnitude < 0.001f)
{
_headingSmoothed = val2;
}
_headingSmoothed = Vector3.Slerp(_headingSmoothed, ((Vector3)(ref val19)).normalized, Mathf.Clamp01(Time.deltaTime * 7f));
_desiredDir = ((Vector3)(ref _headingSmoothed)).normalized;
_hasDirOverride = true;
}
}
}
public class SmartTargetingSystem : ComponentSystem
{
private ComponentGroup _units;
private ComponentGroup _targets;
private readonly Dictionary<Entity, float> _nextRetarget = new Dictionary<Entity, float>();
private static bool _announced;
protected override void OnCreateManager()
{
//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_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_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: 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_0033: 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_0046: 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_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: 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_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: 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)
_units = ((ComponentSystemBase)this).GetComponentGroup((ComponentType[])(object)new ComponentType[8]
{
ComponentType.ReadOnly<Team>(),
ComponentType.Create<HasTargetTag>(),
ComponentType.ReadOnly<PredictedPosition>(),
ComponentType.ReadOnly<Range>(),
ComponentType.ReadOnly<UnitTag>(),
ComponentType.ReadOnly<EnemyLeastWeightTargeting>(),
ComponentType.Subtractive<IsInPool>(),
ComponentType.Subtractive<IsDead>()
});
_targets = ((ComponentSystemBase)this).GetComponentGroup((ComponentType[])(object)new ComponentType[9]
{
ComponentType.ReadOnly<Team>(),
ComponentType.ReadOnly<HipPosition>(),
ComponentType.ReadOnly<TargetPriority>(),
ComponentType.ReadOnly<TargetThickness>(),
ComponentType.Create<BeingTargetedBy>(),
ComponentType.ReadOnly<UnitTag>(),
ComponentType.Create<IsTarget>(),
ComponentType.Subtractive<IsInPool>(),
ComponentType.Subtractive<IsDead>()
});
}
protected override void OnUpdate()
{
try
{
OnUpdateInner();
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("[SmarterAI] SmartTargetingSystem error: " + ex));
}
}
private void OnUpdateInner()
{
//IL_008d: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: 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_00f5: 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_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_010f: 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_011c: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_0173: Unknown result type (might be due to invalid IL or missing references)
//IL_019b: 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_01a2: Unknown result type (might be due to invalid IL or missing references)
//IL_0202: Unknown result type (might be due to invalid IL or missing references)
//IL_0207: Unknown result type (might be due to invalid IL or missing references)
//IL_020f: Unknown result type (might be due to invalid IL or missing references)
//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
//IL_028b: Unknown result type (might be due to invalid IL or missing references)
//IL_029a: Unknown result type (might be due to invalid IL or missing references)
//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
//IL_0224: Unknown result type (might be due to invalid IL or missing references)
//IL_0229: Unknown result type (might be due to invalid IL or missing references)
//IL_022e: Unknown result type (might be due to invalid IL or missing references)
//IL_0230: Unknown result type (might be due to invalid IL or missing references)
//IL_0232: Unknown result type (might be due to invalid IL or missing references)
//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
//IL_02fd: 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_031c: Unknown result type (might be due to invalid IL or missing references)
//IL_032d: Unknown result type (might be due to invalid IL or missing references)
//IL_0332: Unknown result type (might be due to invalid IL or missing references)
//IL_0366: Unknown result type (might be due to invalid IL or missing references)
//IL_0368: Unknown result type (might be due to invalid IL or missing references)
//IL_03b8: Unknown result type (might be due to invalid IL or missing references)
//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
//IL_024a: Unknown result type (might be due to invalid IL or missing references)
//IL_024f: Unknown result type (might be due to invalid IL or missing references)
//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
//IL_03d8: Unknown result type (might be due to invalid IL or missing references)
//IL_03da: Unknown result type (might be due to invalid IL or missing references)
//IL_03df: Unknown result type (might be due to invalid IL or missing references)
//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
//IL_03f7: Unknown result type (might be due to invalid IL or missing references)
//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
//IL_0401: Unknown result type (might be due to invalid IL or missing references)
//IL_0406: 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_0394: Unknown result type (might be due to invalid IL or missing references)
if (!Plugin.Enabled.Value || !Plugin.SmarterTargeting.Value || !Bootstrap.InBattle())
{
return;
}
if (!_announced)
{
_announced = true;
Plugin.Log.LogInfo((object)"[SmarterAI] SmartTargetingSystem active in battle.");
}
float value = Plugin.CrowdWeight.Value;
TeamSystem existingManager = ((ComponentSystemBase)this).World.GetExistingManager<TeamSystem>();
float value2 = Plugin.RangedThreshold.Value;
float value3 = Plugin.RetargetInterval.Value;
float value4 = Plugin.SwitchMargin.Value;
float time = Time.time;
for (int i = 0; i <= 1; i++)
{
_units.SetFilter<Team>(new Team
{
Value = i
});
_targets.SetFilter<Team>(new Team
{
Value = 1 - i
});
EntityArray entityArray = _units.GetEntityArray();
ComponentDataArray<HasTargetTag> componentDataArray = _units.GetComponentDataArray<HasTargetTag>();
ComponentDataArray<PredictedPosition> componentDataArray2 = _units.GetComponentDataArray<PredictedPosition>();
ComponentDataArray<Range> componentDataArray3 = _units.GetComponentDataArray<Range>();
EntityArray entityArray2 = _targets.GetEntityArray();
ComponentDataArray<HipPosition> componentDataArray4 = _targets.GetComponentDataArray<HipPosition>();
ComponentDataArray<TargetPriority> componentDataArray5 = _targets.GetComponentDataArray<TargetPriority>();
ComponentDataArray<BeingTargetedBy> componentDataArray6 = _targets.GetComponentDataArray<BeingTargetedBy>();
if (((EntityArray)(ref entityArray)).Length == 0 || ((EntityArray)(ref entityArray2)).Length == 0)
{
_units.ResetFilter();
_targets.ResetFilter();
continue;
}
float[] array = new float[((EntityArray)(ref entityArray2)).Length];
for (int j = 0; j < ((EntityArray)(ref entityArray2)).Length; j++)
{
array[j] = componentDataArray6[j].Value;
}
for (int k = 0; k < ((EntityArray)(ref entityArray)).Length; k++)
{
Range val = componentDataArray3[k];
if (val.AttackRange >= value2)
{
continue;
}
if (existingManager != null)
{
DataHandler dataHandler = existingManager.GetDataHandler(((EntityArray)(ref entityArray))[k]);
if ((Object)(object)dataHandler != (Object)null && (Object)(object)dataHandler.unit != (Object)null && (MountUtils.IsMount(dataHandler.unit) || dataHandler.unit.IsRider))
{
continue;
}
}
Entity val2 = ((EntityArray)(ref entityArray))[k];
if (_nextRetarget.TryGetValue(val2, out var value5) && time < value5)
{
Entity target = componentDataArray[k].Target;
if (!(target != Entity.Null))
{
continue;
}
for (int l = 0; l < ((EntityArray)(ref entityArray2)).Length; l++)
{
if (((EntityArray)(ref entityArray2))[l] == target)
{
array[l] += 1f;
break;
}
}
continue;
}
_nextRetarget[val2] = time + value3 * (0.8f + 0.4f * ((float)(val2.Index & 0x3FF) / 1023f));
float3 value6 = componentDataArray2[k].Value;
int num = -1;
float num2 = float.MinValue;
float num3 = float.MinValue;
Entity target2 = componentDataArray[k].Target;
for (int m = 0; m < ((EntityArray)(ref entityArray2)).Length; m++)
{
float num4 = (0f - math.length(componentDataArray4[m].Value - value6)) / componentDataArray5[m].Value - array[m] * val.AttackRange * value;
if (((EntityArray)(ref entityArray2))[m] == target2)
{
num3 = num4;
}
if (num4 > num2)
{
num2 = num4;
num = m;
}
}
if (num < 0)
{
continue;
}
if (target2 != Entity.Null && num3 != float.MinValue && num2 < num3 + value4)
{
for (int n = 0; n < ((EntityArray)(ref entityArray2)).Length; n++)
{
if (((EntityArray)(ref entityArray2))[n] == target2)
{
num = n;
break;
}
}
}
Entity val3 = ((EntityArray)(ref entityArray2))[num];
if (target2 != val3)
{
componentDataArray[k] = new HasTargetTag
{
Target = val3
};
((ComponentSystemBase)this).EntityManager.SetComponentData<IsTarget>(((EntityArray)(ref entityArray2))[num], new IsTarget
{
Targetee = val2
});
}
array[num] += 1f;
}
_units.ResetFilter();
_targets.ResetFilter();
}
}
}
}