Improve AI squad pathing and regrouping behavior.

Ensure the target location can be pathed to by all units in the squad, so the squad won't get stuck if some units can't make it. Improve the choice of leader for the squad. We attempt to a choose a leader whose locomotor is the most restrictive in terms of passable terrain. This maximises the chance that the squad will be able to follow the leader along the path to the target. We also keep this choice of leader as the squad advances, this avoids the squad constantly switching leaders and regrouping backwards in some cases.
This commit is contained in:
RoosterDragon
2023-07-20 19:08:49 +01:00
committed by Gustas
parent 24536fa296
commit a67e85e092
6 changed files with 80 additions and 33 deletions

View File

@@ -153,10 +153,13 @@ namespace OpenRA.Mods.Common.Traits
return false;
var targetTypes = a.GetEnabledTargetTypes();
return !targetTypes.IsEmpty && !targetTypes.Overlaps(Info.IgnoredEnemyTargetTypes);
if (targetTypes.IsEmpty || targetTypes.Overlaps(Info.IgnoredEnemyTargetTypes))
return false;
return IsNotHiddenUnit(a);
}
public bool IsNotHiddenUnit(Actor a)
bool IsNotHiddenUnit(Actor a)
{
var hasModifier = false;
var visModifiers = a.TraitsImplementing<IVisibilityModifier>();
@@ -244,7 +247,7 @@ namespace OpenRA.Mods.Common.Traits
// Then check which are in weapons range of the source.
var activeAttackBases = sourceActor.TraitsImplementing<AttackBase>().Where(Exts.IsTraitEnabled).ToArray();
var enemiesAndSourceAttackRanges = actors
.Where(a => IsPreferredEnemyUnit(a) && IsNotHiddenUnit(a))
.Where(IsPreferredEnemyUnit)
.Select(a => (Actor: a, AttackBases: activeAttackBases.Where(ab => ab.HasAnyValidWeapons(Target.FromActor(a))).ToList()))
.Where(x => x.AttackBases.Count > 0)
.Select(x => (x.Actor, Range: x.AttackBases.Max(ab => ab.GetMaximumRangeVersusTarget(Target.FromActor(x.Actor)))))
@@ -462,7 +465,7 @@ namespace OpenRA.Mods.Common.Traits
var protectSq = GetSquadOfType(SquadType.Protection);
protectSq ??= RegisterNewSquad(bot, SquadType.Protection, (attacker, WVec.Zero));
if (protectSq.IsValid && !protectSq.IsTargetValid())
if (protectSq.IsValid && !protectSq.IsTargetValid(protectSq.CenterUnit()))
protectSq.SetActorToTarget((attacker, WVec.Zero));
if (!protectSq.IsValid)