Add maximum and minimum range vs. target checks

This adresses the issue that actors would ignore the validity of weapons when deciding the attack distance versus a target. This could result in actors staying out of range of a weapon valid versus target if they carried a weapon with higher range but invalid versus target.
This commit is contained in:
reaperrr
2016-06-16 15:22:38 +02:00
parent 8e3415e70e
commit 2f1a6e8807
2 changed files with 49 additions and 3 deletions

View File

@@ -82,12 +82,12 @@ namespace OpenRA.Mods.Common.Activities
// Fly towards the target // Fly towards the target
// TODO: Fix that the helicopter won't do anything if it has multiple weapons with different ranges // TODO: Fix that the helicopter won't do anything if it has multiple weapons with different ranges
// and the weapon with the longest range is out of ammo // and the weapon with the longest range is out of ammo
if (!target.IsInRange(self.CenterPosition, attackHeli.GetMaximumRange())) if (!target.IsInRange(self.CenterPosition, attackHeli.GetMaximumRangeVersusTarget(target)))
helicopter.SetPosition(self, helicopter.CenterPosition + helicopter.FlyStep(desiredFacing)); helicopter.SetPosition(self, helicopter.CenterPosition + helicopter.FlyStep(desiredFacing));
// Fly backwards from the target // Fly backwards from the target
// TODO: Same problem as with MaximumRange // TODO: Same problem as with MaximumRange
if (target.IsInRange(self.CenterPosition, attackHeli.GetMinimumRange())) if (target.IsInRange(self.CenterPosition, attackHeli.GetMinimumRangeVersusTarget(target)))
{ {
// Facing 0 doesn't work with the following position change // Facing 0 doesn't work with the following position change
var facing = 1; var facing = 1;

View File

@@ -230,6 +230,52 @@ namespace OpenRA.Mods.Common.Traits
return max; return max;
} }
public WDist GetMinimumRangeVersusTarget(Target target)
{
if (IsTraitDisabled)
return WDist.Zero;
// PERF: Avoid LINQ.
var min = WDist.MaxValue;
foreach (var armament in Armaments)
{
if (armament.IsTraitDisabled)
continue;
if (!armament.Weapon.IsValidAgainst(target, self.World, self))
continue;
var range = armament.Weapon.MinRange;
if (min > range)
min = range;
}
return min != WDist.MaxValue ? min : WDist.Zero;
}
public WDist GetMaximumRangeVersusTarget(Target target)
{
if (IsTraitDisabled)
return WDist.Zero;
// PERF: Avoid LINQ.
var max = WDist.Zero;
foreach (var armament in Armaments)
{
if (armament.IsTraitDisabled)
continue;
if (!armament.Weapon.IsValidAgainst(target, self.World, self))
continue;
var range = armament.MaxRange();
if (max < range)
max = range;
}
return max;
}
// Enumerates all armaments, that this actor possesses, that can be used against Target t // Enumerates all armaments, that this actor possesses, that can be used against Target t
public IEnumerable<Armament> ChooseArmamentsForTarget(Target t, bool forceAttack) public IEnumerable<Armament> ChooseArmamentsForTarget(Target t, bool forceAttack)
{ {
@@ -282,7 +328,7 @@ namespace OpenRA.Mods.Common.Traits
public bool IsReachableTarget(Target target, bool allowMove) public bool IsReachableTarget(Target target, bool allowMove)
{ {
return HasAnyValidWeapons(target) return HasAnyValidWeapons(target)
&& (target.IsInRange(self.CenterPosition, GetMaximumRange()) || (allowMove && self.Info.HasTraitInfo<IMoveInfo>())); && (target.IsInRange(self.CenterPosition, GetMaximumRangeVersusTarget(target)) || (allowMove && self.Info.HasTraitInfo<IMoveInfo>()));
} }
public Stance UnforcedAttackTargetStances() public Stance UnforcedAttackTargetStances()