Fix actors with AttackFollow moving away from their targets on amove
This commit is contained in:
committed by
Matthias Mailänder
parent
b88ebd8499
commit
0134f63f4d
@@ -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)
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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]
|
||||||
|
|||||||
Reference in New Issue
Block a user