Fix actors with AttackFollow moving away from their targets on amove

This commit is contained in:
abcdefg30
2022-03-27 19:04:32 +02:00
committed by Matthias Mailänder
parent b88ebd8499
commit 0134f63f4d
3 changed files with 27 additions and 14 deletions

View File

@@ -33,7 +33,7 @@ namespace OpenRA.Mods.Common.Traits
public override object Create(ActorInitializer init) { return new AttackFollow(init.Self, this); } public override object Create(ActorInitializer init) { return new AttackFollow(init.Self, this); }
} }
public class AttackFollow : AttackBase, INotifyOwnerChanged, IDisableAutoTarget, INotifyStanceChanged public class AttackFollow : AttackBase, INotifyOwnerChanged, IOverrideAutoTarget, INotifyStanceChanged
{ {
public new readonly AttackFollowInfo Info; public new readonly AttackFollowInfo Info;
public Target RequestedTarget { get; private set; } public Target RequestedTarget { get; private set; }
@@ -184,10 +184,22 @@ namespace OpenRA.Mods.Common.Traits
opportunityTargetIsPersistentTarget = false; opportunityTargetIsPersistentTarget = false;
} }
bool IDisableAutoTarget.DisableAutoTarget(Actor self) bool IOverrideAutoTarget.TryGetAutoTargetOverride(Actor self, out Target target)
{ {
return RequestedTarget.Type != TargetType.Invalid || if (RequestedTarget.Type != TargetType.Invalid)
(opportunityTargetIsPersistentTarget && OpportunityTarget.Type != TargetType.Invalid); {
target = RequestedTarget;
return true;
}
if (opportunityTargetIsPersistentTarget && OpportunityTarget.Type != TargetType.Invalid)
{
target = OpportunityTarget;
return true;
}
target = Target.Invalid;
return false;
} }
void INotifyStanceChanged.StanceChanged(Actor self, AutoTarget autoTarget, UnitStance oldStance, UnitStance newStance) void INotifyStanceChanged.StanceChanged(Actor self, AutoTarget autoTarget, UnitStance oldStance, UnitStance newStance)

View File

@@ -144,7 +144,7 @@ namespace OpenRA.Mods.Common.Traits
public UnitStance PredictedStance; public UnitStance PredictedStance;
UnitStance stance; UnitStance stance;
IDisableAutoTarget[] disableAutoTarget; IOverrideAutoTarget[] overrideAutoTarget;
INotifyStanceChanged[] notifyStanceChanged; INotifyStanceChanged[] notifyStanceChanged;
IEnumerable<AutoTargetPriorityInfo> activeTargetPriorities; IEnumerable<AutoTargetPriorityInfo> activeTargetPriorities;
int conditionToken = Actor.InvalidConditionToken; int conditionToken = Actor.InvalidConditionToken;
@@ -197,7 +197,7 @@ namespace OpenRA.Mods.Common.Traits
.OrderByDescending(ati => ati.Info.Priority).ToArray() .OrderByDescending(ati => ati.Info.Priority).ToArray()
.Where(Exts.IsTraitEnabled).Select(atp => atp.Info); .Where(Exts.IsTraitEnabled).Select(atp => atp.Info);
disableAutoTarget = self.TraitsImplementing<IDisableAutoTarget>().ToArray(); overrideAutoTarget = self.TraitsImplementing<IOverrideAutoTarget>().ToArray();
notifyStanceChanged = self.TraitsImplementing<INotifyStanceChanged>().ToArray(); notifyStanceChanged = self.TraitsImplementing<INotifyStanceChanged>().ToArray();
ApplyStanceCondition(self); ApplyStanceCondition(self);
@@ -229,8 +229,9 @@ namespace OpenRA.Mods.Common.Traits
if (attacker.Disposed) if (attacker.Disposed)
return; return;
foreach (var dat in disableAutoTarget) // Don't change targets when there is a target overriding auto-targeting
if (dat.DisableAutoTarget(self)) foreach (var oat in overrideAutoTarget)
if (oat.TryGetAutoTargetOverride(self, out _))
return; return;
if (!attacker.IsInWorld) if (!attacker.IsInWorld)
@@ -283,9 +284,9 @@ namespace OpenRA.Mods.Common.Traits
{ {
if ((ignoreScanInterval || nextScanTime <= 0) && ActiveAttackBases.Any()) if ((ignoreScanInterval || nextScanTime <= 0) && ActiveAttackBases.Any())
{ {
foreach (var dat in disableAutoTarget) foreach (var oat in overrideAutoTarget)
if (dat.DisableAutoTarget(self)) if (oat.TryGetAutoTargetOverride(self, out var existingTarget))
return Target.Invalid; return existingTarget;
if (!ignoreScanInterval) if (!ignoreScanInterval)
nextScanTime = self.World.SharedRandom.Next(Info.MinimumScanTimeInterval, Info.MaximumScanTimeInterval); nextScanTime = self.World.SharedRandom.Next(Info.MinimumScanTimeInterval, Info.MaximumScanTimeInterval);
@@ -294,7 +295,7 @@ namespace OpenRA.Mods.Common.Traits
{ {
// If we can't attack right now, there's no need to try and find a target. // If we can't attack right now, there's no need to try and find a target.
var attackStances = ab.UnforcedAttackTargetStances(); var attackStances = ab.UnforcedAttackTargetStances();
if (attackStances != OpenRA.Traits.PlayerRelationship.None) if (attackStances != PlayerRelationship.None)
{ {
var range = Info.ScanRadius > 0 ? WDist.FromCells(Info.ScanRadius) : ab.GetMaximumRange(); var range = Info.ScanRadius > 0 ? WDist.FromCells(Info.ScanRadius) : ab.GetMaximumRange();
return ChooseTarget(self, ab, attackStances, range, allowMove, allowTurn); return ChooseTarget(self, ab, attackStances, range, allowMove, allowTurn);

View File

@@ -309,9 +309,9 @@ namespace OpenRA.Mods.Common.Traits
} }
[RequireExplicitImplementation] [RequireExplicitImplementation]
public interface IDisableAutoTarget public interface IOverrideAutoTarget
{ {
bool DisableAutoTarget(Actor self); bool TryGetAutoTargetOverride(Actor self, out Target target);
} }
[RequireExplicitImplementation] [RequireExplicitImplementation]