Files
OpenRA/OpenRA.Mods.Common/Traits/BotModules/Squads/States/ProtectionStates.cs
RoosterDragon a67e85e092 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.
2023-09-11 14:56:59 +03:00

81 lines
2.2 KiB
C#

#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using System.Linq;
namespace OpenRA.Mods.Common.Traits.BotModules.Squads
{
sealed class UnitsForProtectionIdleState : GroundStateBase, IState
{
public void Activate(Squad owner) { }
public void Tick(Squad owner) { owner.FuzzyStateMachine.ChangeState(owner, new UnitsForProtectionAttackState(), true); }
public void Deactivate(Squad owner) { }
}
sealed class UnitsForProtectionAttackState : GroundStateBase, IState
{
public const int BackoffTicks = 4;
internal int Backoff = BackoffTicks;
public void Activate(Squad owner) { }
public void Tick(Squad owner)
{
if (!owner.IsValid)
return;
var leader = Leader(owner);
if (!owner.IsTargetValid(leader))
{
var target = owner.SquadManager.FindClosestEnemy(leader, WDist.FromCells(owner.SquadManager.Info.ProtectionScanRadius));
owner.SetActorToTarget(target);
if (target.Actor == null)
{
owner.FuzzyStateMachine.ChangeState(owner, new UnitsForProtectionFleeState(), true);
return;
}
}
if (!owner.IsTargetVisible)
{
if (Backoff < 0)
{
owner.FuzzyStateMachine.ChangeState(owner, new UnitsForProtectionFleeState(), true);
Backoff = BackoffTicks;
return;
}
Backoff--;
}
else
owner.Bot.QueueOrder(new Order("AttackMove", null, owner.Target, false, groupedActors: owner.Units.ToArray()));
}
public void Deactivate(Squad owner) { }
}
sealed class UnitsForProtectionFleeState : GroundStateBase, IState
{
public void Activate(Squad owner) { }
public void Tick(Squad owner)
{
if (!owner.IsValid)
return;
GoToRandomOwnBuilding(owner);
owner.FuzzyStateMachine.ChangeState(owner, new UnitsForProtectionIdleState(), true);
}
public void Deactivate(Squad owner) { owner.SquadManager.UnregisterSquad(owner); }
}
}