Rework the internals of AttackMoveActivity
Avoids creating and throwing away inner activities unnecessarily
This commit is contained in:
@@ -24,7 +24,9 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
readonly AutoTarget autoTarget;
|
readonly AutoTarget autoTarget;
|
||||||
readonly AttackMove attackMove;
|
readonly AttackMove attackMove;
|
||||||
|
|
||||||
|
bool runningInnerActivity = false;
|
||||||
int token = Actor.InvalidConditionToken;
|
int token = Actor.InvalidConditionToken;
|
||||||
|
Target target = Target.Invalid;
|
||||||
|
|
||||||
public AttackMoveActivity(Actor self, Func<Activity> getInner, bool assaultMoving = false)
|
public AttackMoveActivity(Actor self, Func<Activity> getInner, bool assaultMoving = false)
|
||||||
{
|
{
|
||||||
@@ -37,9 +39,6 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
|
|
||||||
protected override void OnFirstRun(Actor self)
|
protected override void OnFirstRun(Actor self)
|
||||||
{
|
{
|
||||||
// Start moving.
|
|
||||||
QueueChild(getInner());
|
|
||||||
|
|
||||||
if (attackMove == null)
|
if (attackMove == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -51,27 +50,35 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
|
|
||||||
public override bool Tick(Actor self)
|
public override bool Tick(Actor self)
|
||||||
{
|
{
|
||||||
// We are not currently attacking a target, so scan for new targets.
|
if (IsCanceling)
|
||||||
if (!IsCanceling && ChildActivity != null && ChildActivity.NextActivity == null && autoTarget != null)
|
return TickChild(self);
|
||||||
|
|
||||||
|
// We are currently not attacking, so scan for new targets.
|
||||||
|
if (autoTarget != null && (ChildActivity == null || runningInnerActivity))
|
||||||
{
|
{
|
||||||
// ScanForTarget already limits the scanning rate for performance so we don't need to do that here.
|
// ScanForTarget already limits the scanning rate for performance so we don't need to do that here.
|
||||||
var target = autoTarget.ScanForTarget(self, false, true);
|
target = autoTarget.ScanForTarget(self, false, true);
|
||||||
|
|
||||||
|
// Cancel the current inner activity and queue attack activities if we find a new target.
|
||||||
if (target.Type != TargetType.Invalid)
|
if (target.Type != TargetType.Invalid)
|
||||||
{
|
{
|
||||||
// We have found a target so cancel the current move activity and queue attack activities.
|
runningInnerActivity = false;
|
||||||
ChildActivity.Cancel(self);
|
ChildActivity?.Cancel(self);
|
||||||
var attackBases = autoTarget.ActiveAttackBases;
|
|
||||||
foreach (var ab in attackBases)
|
|
||||||
QueueChild(ab.GetAttackActivity(self, AttackSource.AttackMove, target, false, false));
|
|
||||||
|
|
||||||
// Make sure to continue moving when the attack activities have finished.
|
foreach (var ab in autoTarget.ActiveAttackBases)
|
||||||
|
QueueChild(ab.GetAttackActivity(self, AttackSource.AttackMove, target, false, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Continue with the inner activity (or queue a new one) when there are no targets.
|
||||||
|
if (ChildActivity == null)
|
||||||
|
{
|
||||||
|
runningInnerActivity = true;
|
||||||
QueueChild(getInner());
|
QueueChild(getInner());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The last queued childactivity is guaranteed to be the inner move, so if the childactivity
|
// If the inner activity finished, we have reached our destination and there are no more enemies on our path.
|
||||||
// queue is empty it means we have reached our destination and there are no more enemies on our path.
|
return TickChild(self) && runningInnerActivity;
|
||||||
return TickChild(self);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnLastRun(Actor self)
|
protected override void OnLastRun(Actor self)
|
||||||
|
|||||||
Reference in New Issue
Block a user