diff --git a/OpenRA.Mods.Common/AI/States/GroundStates.cs b/OpenRA.Mods.Common/AI/States/GroundStates.cs index 8d9163e46a..a424302df5 100644 --- a/OpenRA.Mods.Common/AI/States/GroundStates.cs +++ b/OpenRA.Mods.Common/AI/States/GroundStates.cs @@ -20,6 +20,11 @@ namespace OpenRA.Mods.Common.AI { return base.ShouldFlee(owner, enemies => !AttackOrFleeFuzzy.Default.CanAttack(owner.Units, enemies)); } + + protected Actor FindClosestEnemy(Squad owner) + { + return owner.Bot.FindClosestEnemy(owner.Units.First().CenterPosition); + } } class GroundUnitsIdleState : GroundStateBase, IState @@ -33,11 +38,11 @@ namespace OpenRA.Mods.Common.AI if (!owner.IsTargetValid) { - var t = owner.Bot.FindClosestEnemy(owner.Units.First().CenterPosition); - if (t == null) + var closestEnemy = FindClosestEnemy(owner); + if (closestEnemy == null) return; - owner.TargetActor = t; + owner.TargetActor = closestEnemy; } var enemyUnits = owner.World.FindActorsInCircle(owner.TargetActor.CenterPosition, WDist.FromCells(10)) @@ -72,7 +77,7 @@ namespace OpenRA.Mods.Common.AI if (!owner.IsTargetValid) { - var closestEnemy = owner.Bot.FindClosestEnemy(owner.Units.Random(owner.Random).CenterPosition); + var closestEnemy = FindClosestEnemy(owner); if (closestEnemy != null) owner.TargetActor = closestEnemy; else @@ -88,8 +93,11 @@ namespace OpenRA.Mods.Common.AI var ownUnits = owner.World.FindActorsInCircle(leader.CenterPosition, WDist.FromCells(owner.Units.Count) / 3) .Where(a => a.Owner == owner.Units.First().Owner && owner.Units.Contains(a)).ToHashSet(); + if (ownUnits.Count < owner.Units.Count) { + // Since units have different movement speeds, they get separated while approaching the target. + // Let them regroup into tighter formation. owner.Bot.QueueOrder(new Order("Stop", leader, false)); foreach (var unit in owner.Units.Where(a => !ownUnits.Contains(a))) owner.Bot.QueueOrder(new Order("AttackMove", unit, false) { TargetLocation = leader.Location }); @@ -127,7 +135,7 @@ namespace OpenRA.Mods.Common.AI if (!owner.IsTargetValid) { - var closestEnemy = owner.Bot.FindClosestEnemy(owner.Units.Random(owner.Random).CenterPosition); + var closestEnemy = FindClosestEnemy(owner); if (closestEnemy != null) owner.TargetActor = closestEnemy; else @@ -139,7 +147,7 @@ namespace OpenRA.Mods.Common.AI foreach (var a in owner.Units) if (!BusyAttack(a)) - owner.Bot.QueueOrder(new Order("Attack", a, false) { TargetActor = owner.Bot.FindClosestEnemy(a.CenterPosition) }); + owner.Bot.QueueOrder(new Order("Attack", a, false) { TargetActor = owner.TargetActor }); if (ShouldFlee(owner)) owner.FuzzyStateMachine.ChangeState(owner, new GroundUnitsFleeState(), true);