Add AutoTarget support for FrozenActors.
This commit is contained in:
committed by
Oliver Brakmann
parent
c34dd4b824
commit
5f79c31a57
@@ -12,6 +12,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
@@ -117,7 +118,6 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public UnitStance Stance { get { return stance; } }
|
||||
|
||||
[Sync] public Actor Aggressor;
|
||||
[Sync] public Actor TargetedActor;
|
||||
|
||||
// NOT SYNCED: do not refer to this anywhere other than UI code
|
||||
public UnitStance PredictedStance;
|
||||
@@ -217,7 +217,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
bool allowMove;
|
||||
if (ShouldAttack(out allowMove))
|
||||
Attack(self, Aggressor, allowMove);
|
||||
Attack(self, Target.FromActor(Aggressor), allowMove);
|
||||
}
|
||||
|
||||
void INotifyIdle.TickIdle(Actor self)
|
||||
@@ -251,7 +251,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
--nextScanTime;
|
||||
}
|
||||
|
||||
public Actor ScanForTarget(Actor self, bool allowMove)
|
||||
public Target ScanForTarget(Actor self, bool allowMove)
|
||||
{
|
||||
if (nextScanTime <= 0 && activeAttackBases.Any())
|
||||
{
|
||||
@@ -269,48 +269,67 @@ namespace OpenRA.Mods.Common.Traits
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return Target.Invalid;
|
||||
}
|
||||
|
||||
public void ScanAndAttack(Actor self, bool allowMove)
|
||||
{
|
||||
var targetActor = ScanForTarget(self, allowMove);
|
||||
if (targetActor != null)
|
||||
Attack(self, targetActor, allowMove);
|
||||
var target = ScanForTarget(self, allowMove);
|
||||
if (target.Type != TargetType.Invalid)
|
||||
Attack(self, target, allowMove);
|
||||
}
|
||||
|
||||
void Attack(Actor self, Actor targetActor, bool allowMove)
|
||||
void Attack(Actor self, Target target, bool allowMove)
|
||||
{
|
||||
TargetedActor = targetActor;
|
||||
var target = Target.FromActor(targetActor);
|
||||
self.SetTargetLine(target, Color.Red, false);
|
||||
|
||||
foreach (var ab in activeAttackBases)
|
||||
ab.AttackTarget(target, false, allowMove);
|
||||
}
|
||||
|
||||
Actor ChooseTarget(Actor self, AttackBase ab, Stance attackStances, WDist scanRange, bool allowMove)
|
||||
Target ChooseTarget(Actor self, AttackBase ab, Stance attackStances, WDist scanRange, bool allowMove)
|
||||
{
|
||||
Actor chosenTarget = null;
|
||||
var chosenTarget = Target.Invalid;
|
||||
var chosenTargetPriority = int.MinValue;
|
||||
int chosenTargetRange = 0;
|
||||
|
||||
var activePriorities = activeTargetPriorities.ToList();
|
||||
if (activePriorities.Count == 0)
|
||||
return null;
|
||||
return chosenTarget;
|
||||
|
||||
var actorsInRange = self.World.FindActorsInCircle(self.CenterPosition, scanRange);
|
||||
foreach (var actor in actorsInRange)
|
||||
var targetsInRange = self.World.FindActorsInCircle(self.CenterPosition, scanRange)
|
||||
.Select(Target.FromActor)
|
||||
.Concat(self.Owner.FrozenActorLayer.FrozenActorsInCircle(self.World, self.CenterPosition, scanRange)
|
||||
.Select(Target.FromFrozenActor));
|
||||
|
||||
foreach (var target in targetsInRange)
|
||||
{
|
||||
// PERF: Most units can only attack enemy units. If this is the case but the target is not an enemy, we
|
||||
// can bail early and avoid the more expensive targeting checks and armament selection. For groups of
|
||||
// allied units, this helps significantly reduce the cost of auto target scans. This is important as
|
||||
// these groups will continuously rescan their allies until an enemy finally comes into range.
|
||||
if (attackStances == OpenRA.Traits.Stance.Enemy && !actor.AppearsHostileTo(self))
|
||||
BitSet<TargetableType> targetTypes;
|
||||
if (target.Type == TargetType.Actor)
|
||||
{
|
||||
// PERF: Most units can only attack enemy units. If this is the case but the target is not an enemy, we
|
||||
// can bail early and avoid the more expensive targeting checks and armament selection. For groups of
|
||||
// allied units, this helps significantly reduce the cost of auto target scans. This is important as
|
||||
// these groups will continuously rescan their allies until an enemy finally comes into range.
|
||||
if (attackStances == OpenRA.Traits.Stance.Enemy && !target.Actor.AppearsHostileTo(self))
|
||||
continue;
|
||||
|
||||
// Check whether we can auto-target this actor
|
||||
targetTypes = target.Actor.GetEnabledTargetTypes();
|
||||
|
||||
if (PreventsAutoTarget(self, target.Actor) || !target.Actor.CanBeViewedByPlayer(self.Owner))
|
||||
continue;
|
||||
}
|
||||
else if (target.Type == TargetType.FrozenActor)
|
||||
{
|
||||
if (attackStances == OpenRA.Traits.Stance.Enemy && self.Owner.Stances[target.FrozenActor.Owner] == OpenRA.Traits.Stance.Ally)
|
||||
continue;
|
||||
|
||||
targetTypes = target.FrozenActor.TargetTypes;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
// Check whether we can auto-target this actor
|
||||
var targetTypes = actor.GetEnabledTargetTypes();
|
||||
var validPriorities = activePriorities.Where(ati =>
|
||||
{
|
||||
// Already have a higher priority target
|
||||
@@ -324,11 +343,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return true;
|
||||
}).ToList();
|
||||
|
||||
if (validPriorities.Count == 0 || PreventsAutoTarget(self, actor) || !actor.CanBeViewedByPlayer(self.Owner))
|
||||
if (validPriorities.Count == 0)
|
||||
continue;
|
||||
|
||||
// Make sure that we can actually fire on the actor
|
||||
var target = Target.FromActor(actor);
|
||||
var armaments = ab.ChooseArmamentsForTarget(target, false);
|
||||
if (!allowMove)
|
||||
armaments = armaments.Where(arm =>
|
||||
@@ -342,10 +360,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
var targetRange = (target.CenterPosition - self.CenterPosition).Length;
|
||||
foreach (var ati in validPriorities)
|
||||
{
|
||||
if (chosenTarget == null || chosenTargetPriority < ati.Priority
|
||||
if (chosenTarget.Type == TargetType.Invalid || chosenTargetPriority < ati.Priority
|
||||
|| (chosenTargetPriority == ati.Priority && targetRange < chosenTargetRange))
|
||||
{
|
||||
chosenTarget = actor;
|
||||
chosenTarget = target;
|
||||
chosenTargetPriority = ati.Priority;
|
||||
chosenTargetRange = targetRange;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user