add new long WRange.RangeSquared to avoid integer overflows

This commit is contained in:
Matthias Mailänder
2015-05-31 23:51:30 +02:00
parent 79edf648a7
commit ea5003cd2d
15 changed files with 18 additions and 22 deletions

View File

@@ -54,11 +54,10 @@ namespace OpenRA.Mods.Common.Activities
protected bool TryGetAlternateTargetInCircle(
Actor self, WRange radius, Action<Target> update, Func<Actor, bool> primaryFilter, Func<Actor, bool>[] preferenceFilters = null)
{
var radiusSquared = radius.Range * radius.Range;
var diff = new WVec(radius, radius, WRange.Zero);
var candidates = self.World.ActorMap.ActorsInBox(self.CenterPosition - diff, self.CenterPosition + diff)
.Where(primaryFilter).Select(a => new { Actor = a, Ls = (self.CenterPosition - a.CenterPosition).HorizontalLengthSquared })
.Where(p => p.Ls <= radiusSquared).OrderBy(p => p.Ls).Select(p => p.Actor);
.Where(p => p.Ls <= radius.RangeSquared).OrderBy(p => p.Ls).Select(p => p.Actor);
if (preferenceFilters != null)
foreach (var filter in preferenceFilters)
{

View File

@@ -48,8 +48,8 @@ namespace OpenRA.Mods.Common.Activities
var maxCells = (maxRange.Range + 1023) / 1024;
var minCells = minRange.Range / 1024;
var outerSq = maxRange.Range * maxRange.Range;
var innerSq = minRange.Range * minRange.Range;
var outerSq = maxRange.RangeSquared;
var innerSq = minRange.RangeSquared;
var center = Target.CenterPosition;
return map.FindTilesInAnnulus(targetPosition, minCells + 1, maxCells).Where(c =>

View File

@@ -181,7 +181,7 @@ namespace OpenRA.Mods.Common.Effects
var cell = world.Map.CellContaining(pos);
var shouldExplode = (pos.Z < 0) // Hit the ground
|| (dist.LengthSquared < info.CloseEnough.Range * info.CloseEnough.Range) // Within range
|| (dist.LengthSquared < info.CloseEnough.RangeSquared) // Within range
|| (info.RangeLimit != 0 && ticks > info.RangeLimit) // Ran out of fuel
|| (info.Blockable && world.ActorMap.GetUnitsAt(cell).Any(a => a.HasTrait<IBlocksProjectiles>())) // Hit a wall or other blocking obstacle
|| !world.Map.Contains(cell) // This also avoids an IndexOutOfRangeException in GetTerrainInfo below.

View File

@@ -110,7 +110,7 @@ namespace OpenRA.Mods.Common.Traits
var d = self.CenterPosition - other.CenterPosition;
var distSq = d.HorizontalLengthSquared;
if (distSq > info.IdealSeparation.Range * info.IdealSeparation.Range)
if (distSq > info.IdealSeparation.RangeSquared)
return WVec.Zero;
if (distSq < 1)

View File

@@ -262,9 +262,8 @@ namespace OpenRA.Mods.Common.Traits
if (modifiers.HasModifier(TargetModifiers.ForceAttack))
{
var maxRange = ab.GetMaximumRange().Range;
var targetRange = (self.World.Map.CenterOfCell(location) - self.CenterPosition).HorizontalLengthSquared;
if (targetRange > maxRange * maxRange)
if (targetRange > ab.GetMaximumRange().RangeSquared)
cursor = ab.Info.OutsideRangeCursor;
return true;

View File

@@ -141,7 +141,7 @@ namespace OpenRA.Mods.Common.Traits
return;
var targetCell = self.World.Map.CellContaining(target.CenterPosition);
if ((self.CenterPosition - target.CenterPosition).LengthSquared < transport.MinimumDistance.Range * transport.MinimumDistance.Range)
if ((self.CenterPosition - target.CenterPosition).LengthSquared < transport.MinimumDistance.RangeSquared)
return;
transport.RequestTransport(targetCell, nextActivity);

View File

@@ -106,7 +106,7 @@ namespace OpenRA.Mods.Common.Traits
public void UnitProducedByOther(Actor self, Actor producer, Actor produced)
{
// Work around for actors produced within the region not triggering until the second tick
if ((produced.CenterPosition - self.CenterPosition).HorizontalLengthSquared <= info.Range.Range * info.Range.Range)
if ((produced.CenterPosition - self.CenterPosition).HorizontalLengthSquared <= info.Range.RangeSquared)
{
var stance = self.Owner.Stances[produced.Owner];
if (!info.ValidStances.HasFlag(stance))

View File

@@ -85,7 +85,6 @@ namespace OpenRA.Mods.Common.Traits
{
var mi = self.Info.Traits.Get<MobileInfo>();
var targetCell = world.Map.CellContaining(target);
var rangeSquared = range.Range * range.Range;
// Correct for SubCell offset
target -= world.Map.OffsetOfSubCell(srcSub);
@@ -93,7 +92,7 @@ namespace OpenRA.Mods.Common.Traits
// Select only the tiles that are within range from the requested SubCell
// This assumes that the SubCell does not change during the path traversal
var tilesInRange = world.Map.FindTilesInCircle(targetCell, range.Range / 1024 + 1)
.Where(t => (world.Map.CenterOfCell(t) - target).LengthSquared <= rangeSquared
.Where(t => (world.Map.CenterOfCell(t) - target).LengthSquared <= range.RangeSquared
&& mi.CanEnterCell(self.World as World, self as Actor, t));
// See if there is any cell within range that does not involve a cross-domain request

View File

@@ -66,7 +66,7 @@ namespace OpenRA.Mods.Common.Warheads
continue;
// If the impact position is within any actor's health radius, we have a direct hit
if ((unit.CenterPosition - pos).LengthSquared <= healthInfo.Radius.Range * healthInfo.Radius.Range)
if ((unit.CenterPosition - pos).LengthSquared <= healthInfo.Radius.RangeSquared)
return true;
}