remove FP sillyness from FindUnits & friends

This commit is contained in:
Chris Forbes
2011-05-04 22:25:35 +12:00
parent ccc245ded4
commit 9b3e6c5c4a
10 changed files with 48 additions and 40 deletions

View File

@@ -28,8 +28,8 @@ namespace OpenRA
IOccupySpace OccupiesSpace; IOccupySpace OccupiesSpace;
IHasLocation HasLocation; IHasLocation HasLocation;
Lazy<IMove> Move; Lazy<IMove> Move;
public Cached<RectangleF> Bounds; public Cached<Rectangle> Bounds;
public Cached<RectangleF> ExtendedBounds; public Cached<Rectangle> ExtendedBounds;
public int2 Location public int2 Location
{ get { { get {
@@ -76,12 +76,12 @@ namespace OpenRA
{ {
var si = Info.Traits.GetOrDefault<SelectableInfo>(); var si = Info.Traits.GetOrDefault<SelectableInfo>();
if (si != null && si.Bounds != null) if (si != null && si.Bounds != null)
return new float2(si.Bounds[0], si.Bounds[1]); return new int2(si.Bounds[0], si.Bounds[1]);
// auto size from render // auto size from render
var firstSprite = TraitsImplementing<IRender>().SelectMany(ApplyIRender).FirstOrDefault(); var firstSprite = TraitsImplementing<IRender>().SelectMany(ApplyIRender).FirstOrDefault();
if (firstSprite.Sprite == null) return float2.Zero; if (firstSprite.Sprite == null) return int2.Zero;
return firstSprite.Sprite.size * firstSprite.Scale; return (firstSprite.Sprite.size * firstSprite.Scale).ToInt2();
}); });
ApplyIRender = x => x.Render(this); ApplyIRender = x => x.Render(this);
@@ -104,7 +104,7 @@ namespace OpenRA
get { return currentActivity == null; } get { return currentActivity == null; }
} }
OpenRA.FileFormats.Lazy<float2> Size; OpenRA.FileFormats.Lazy<int2> Size;
// note: these delegates are cached to avoid massive allocation. // note: these delegates are cached to avoid massive allocation.
Func<IRender, IEnumerable<Renderable>> ApplyIRender; Func<IRender, IEnumerable<Renderable>> ApplyIRender;
@@ -120,24 +120,27 @@ namespace OpenRA
// vertically to altitude = 0 to support FindUnitsInCircle queries // vertically to altitude = 0 to support FindUnitsInCircle queries
// When false, the bounding box is given for the actor // When false, the bounding box is given for the actor
// at its current altitude // at its current altitude
RectangleF CalculateBounds(bool useAltitude) Rectangle CalculateBounds(bool useAltitude)
{ {
var size = Size.Value; var size = Size.Value;
var loc = CenterLocation - 0.5f * size; var loc = CenterLocation - size / 2;
var si = Info.Traits.GetOrDefault<SelectableInfo>(); var si = Info.Traits.GetOrDefault<SelectableInfo>();
if (si != null && si.Bounds != null && si.Bounds.Length > 2) if (si != null && si.Bounds != null && si.Bounds.Length > 2)
loc += new float2(si.Bounds[2], si.Bounds[3]); {
loc.X += si.Bounds[2];
loc.Y += si.Bounds[3];
}
var move = Move.Value; var move = Move.Value;
if (move != null) if (move != null)
{ {
loc -= new float2(0, move.Altitude); loc.Y -= move.Altitude;
if (useAltitude) if (useAltitude)
size = new float2(size.X, size.Y + move.Altitude); size = new int2(size.X, size.Y + move.Altitude);
} }
return new RectangleF(loc.X, loc.Y, size.X, size.Y); return new Rectangle(loc.X, loc.Y, size.X, size.Y);
} }
public bool IsInWorld { get; internal set; } public bool IsInWorld { get; internal set; }

View File

@@ -110,6 +110,9 @@ namespace OpenRA.Graphics
return ViewToWorld(mi.Location); return ViewToWorld(mi.Location);
} }
public int2 ViewToWorldPx(int2 loc) { return loc + Location.ToInt2(); }
public int2 ViewToWorldPx(MouseInput mi) { return ViewToWorldPx(mi.Location); }
public void Center(float2 loc) public void Center(float2 loc)
{ {
scrollPosition = this.NormalizeScrollPosition((Game.CellSize*loc - screenSize / 2).ToInt2()); scrollPosition = this.NormalizeScrollPosition((Game.CellSize*loc - screenSize / 2).ToInt2());

View File

@@ -58,8 +58,8 @@ namespace OpenRA.Graphics
bounds.Offset((int)Game.viewport.Location.X, (int)Game.viewport.Location.Y); bounds.Offset((int)Game.viewport.Location.X, (int)Game.viewport.Location.Y);
var actors = world.FindUnits( var actors = world.FindUnits(
new float2(bounds.Left, bounds.Top), new int2(bounds.Left, bounds.Top),
new float2(bounds.Right, bounds.Bottom)); new int2(bounds.Right, bounds.Bottom));
var renderables = actors.SelectMany(a => a.Render()) var renderables = actors.SelectMany(a => a.Render())
.OrderBy(r => r, comparer); .OrderBy(r => r, comparer);

View File

@@ -54,10 +54,10 @@ namespace OpenRA.Traits
if (bounds.Left >= Game.CellSize * self.World.Map.Bounds.Right) continue; if (bounds.Left >= Game.CellSize * self.World.Map.Bounds.Right) continue;
if (bounds.Top >= Game.CellSize * self.World.Map.Bounds.Bottom) continue; if (bounds.Top >= Game.CellSize * self.World.Map.Bounds.Bottom) continue;
var i1 = Math.Max(0, (int)bounds.Left / scale); var i1 = Math.Max(0, bounds.Left / scale);
var i2 = Math.Min(bins.GetUpperBound(0), (int)bounds.Right / scale); var i2 = Math.Min(bins.GetUpperBound(0), bounds.Right / scale);
var j1 = Math.Max(0, (int)bounds.Top / scale); var j1 = Math.Max(0, bounds.Top / scale);
var j2 = Math.Min(bins.GetUpperBound(1), (int)bounds.Bottom / scale); var j2 = Math.Min(bins.GetUpperBound(1), bounds.Bottom / scale);
for (var j = j1; j <= j2; j++) for (var j = j1; j <= j2; j++)
for (var i = i1; i <= i2; i++) for (var i = i1; i <= i2; i++)
@@ -77,7 +77,7 @@ namespace OpenRA.Traits
public IEnumerable<Actor> ActorsInBox(int2 a, int2 b) public IEnumerable<Actor> ActorsInBox(int2 a, int2 b)
{ {
var r = RectangleF.FromLTRB(a.X, a.Y, b.X, b.Y); var r = Rectangle.FromLTRB(a.X, a.Y, b.X, b.Y);
return ActorsInBins(a.X / scale, b.X / scale, a.Y / scale, b.Y / scale) return ActorsInBins(a.X / scale, b.X / scale, a.Y / scale, b.Y / scale)
.Distinct() .Distinct()

View File

@@ -8,6 +8,7 @@
*/ */
#endregion #endregion
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
@@ -15,7 +16,6 @@ using OpenRA.FileFormats;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Orders; using OpenRA.Orders;
using OpenRA.Traits; using OpenRA.Traits;
using System;
namespace OpenRA.Widgets namespace OpenRA.Widgets
{ {
@@ -23,6 +23,7 @@ namespace OpenRA.Widgets
{ {
readonly World world; readonly World world;
readonly WorldRenderer worldRenderer; readonly WorldRenderer worldRenderer;
[ObjectCreator.UseCtor] [ObjectCreator.UseCtor]
public WorldInteractionControllerWidget([ObjectCreator.Param] World world, [ObjectCreator.Param] WorldRenderer worldRenderer) public WorldInteractionControllerWidget([ObjectCreator.Param] World world, [ObjectCreator.Param] WorldRenderer worldRenderer)
{ {
@@ -35,7 +36,7 @@ namespace OpenRA.Widgets
var selbox = SelectionBox; var selbox = SelectionBox;
if (selbox == null) if (selbox == null)
{ {
foreach (var u in SelectActorsInBox(world, Game.CellSize * dragStart, Game.CellSize * dragStart)) foreach (var u in SelectActorsInBox(world, dragStart, dragStart))
worldRenderer.DrawRollover(u); worldRenderer.DrawRollover(u);
return; return;
@@ -54,12 +55,12 @@ namespace OpenRA.Widgets
worldRenderer.DrawRollover(u); worldRenderer.DrawRollover(u);
} }
float2 dragStart, dragEnd; int2 dragStart, dragEnd;
// TODO: WorldInteractionController doesn't support delegate methods for mouse input // TODO: WorldInteractionController doesn't support delegate methods for mouse input
public override bool HandleMouseInput(MouseInput mi) public override bool HandleMouseInput(MouseInput mi)
{ {
var xy = Game.viewport.ViewToWorld(mi); var xy = Game.viewport.ViewToWorldPx(mi);
if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down) if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down)
{ {
dragStart = dragEnd = xy; dragStart = dragEnd = xy;
@@ -73,7 +74,7 @@ namespace OpenRA.Widgets
{ {
if (world.OrderGenerator is UnitOrderGenerator) if (world.OrderGenerator is UnitOrderGenerator)
{ {
var newSelection = SelectActorsInBox(world, Game.CellSize * dragStart, Game.CellSize * xy); var newSelection = SelectActorsInBox(world, dragStart, xy);
world.Selection.Combine(world, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy); world.Selection.Combine(world, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy);
} }
@@ -89,20 +90,20 @@ namespace OpenRA.Widgets
return true; return true;
} }
public Pair<float2, float2>? SelectionBox public Pair<int2, int2>? SelectionBox
{ {
get get
{ {
if (dragStart == dragEnd) return null; if (dragStart == dragEnd) return null;
return Pair.New(Game.CellSize * dragStart, Game.CellSize * dragEnd); return Pair.New(dragStart, dragEnd);
} }
} }
public void ApplyOrders(World world, float2 xy, MouseInput mi) public void ApplyOrders(World world, int2 xy, MouseInput mi)
{ {
if (world.OrderGenerator == null) return; if (world.OrderGenerator == null) return;
var orders = world.OrderGenerator.Order(world, xy.ToInt2(), mi).ToArray(); var orders = world.OrderGenerator.Order(world, Traits.Util.CellContaining(xy), mi).ToArray();
orders.Do( o => world.IssueOrder( o ) ); orders.Do( o => world.IssueOrder( o ) );
world.PlayVoiceForOrders(orders); world.PlayVoiceForOrders(orders);
@@ -119,6 +120,7 @@ namespace OpenRA.Widgets
Modifiers = Game.GetModifierKeys() Modifiers = Game.GetModifierKeys()
}; };
// TODO: fix this up.
return world.OrderGenerator.GetCursor( world, Game.viewport.ViewToWorld(mi).ToInt2(), mi ); return world.OrderGenerator.GetCursor( world, Game.viewport.ViewToWorld(mi).ToInt2(), mi );
} ); } );
} }
@@ -141,7 +143,7 @@ namespace OpenRA.Widgets
} }
static readonly Actor[] NoActors = {}; static readonly Actor[] NoActors = {};
IEnumerable<Actor> SelectActorsInBox(World world, float2 a, float2 b) IEnumerable<Actor> SelectActorsInBox(World world, int2 a, int2 b)
{ {
return world.FindUnits(a, b) return world.FindUnits(a, b)
.Where( x => x.HasTrait<Selectable>() && world.LocalShroud.IsVisible(x) ) .Where( x => x.HasTrait<Selectable>() && world.LocalShroud.IsVisible(x) )

View File

@@ -23,27 +23,27 @@ namespace OpenRA
{ {
public static IEnumerable<Actor> FindUnitsAtMouse(this World world, int2 mouseLocation) public static IEnumerable<Actor> FindUnitsAtMouse(this World world, int2 mouseLocation)
{ {
var loc = mouseLocation + Game.viewport.Location; var loc = Game.viewport.ViewToWorldPx(mouseLocation);
return FindUnits(world, loc, loc).Where(a => world.LocalShroud.IsVisible(a)); return FindUnits(world, loc, loc).Where(a => world.LocalShroud.IsVisible(a));
} }
public static IEnumerable<Actor> FindUnits(this World world, float2 a, float2 b) public static IEnumerable<Actor> FindUnits(this World world, int2 a, int2 b)
{ {
var u = float2.Min(a, b).ToInt2(); var u = float2.Min(a, b).ToInt2();
var v = float2.Max(a, b).ToInt2(); var v = float2.Max(a, b).ToInt2();
return world.WorldActor.Trait<SpatialBins>().ActorsInBox(u,v); return world.WorldActor.Trait<SpatialBins>().ActorsInBox(u,v);
} }
public static IEnumerable<Actor> FindUnitsInCircle(this World world, float2 a, float r) public static IEnumerable<Actor> FindUnitsInCircle(this World world, int2 a, int r)
{ {
using (new PerfSample("FindUnitsInCircle")) using (new PerfSample("FindUnitsInCircle"))
{ {
var min = a - new float2(r, r); var min = a - new int2(r, r);
var max = a + new float2(r, r); var max = a + new int2(r, r);
var actors = world.FindUnits(min, max); var actors = world.FindUnits(min, max);
var rect = new RectangleF(min.X, min.Y, max.X - min.X, max.Y - min.Y); var rect = new Rectangle(min.X, min.Y, max.X - min.X, max.Y - min.Y);
var inBox = actors.Where(x => x.ExtendedBounds.Value.IntersectsWith(rect)); var inBox = actors.Where(x => x.ExtendedBounds.Value.IntersectsWith(rect));

View File

@@ -21,7 +21,7 @@ namespace OpenRA.Mods.RA
public void TickIdle( Actor self ) public void TickIdle( Actor self )
{ {
var attack = self.Trait<AttackBase>(); var attack = self.Trait<AttackBase>();
var inRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * attack.GetMaximumRange()); var inRange = self.World.FindUnitsInCircle(self.CenterLocation, (int)(Game.CellSize * attack.GetMaximumRange()));
var target = inRange var target = inRange
.Where(a => a != self && a.AppearsFriendlyTo(self)) .Where(a => a != self && a.AppearsFriendlyTo(self))

View File

@@ -95,7 +95,7 @@ namespace OpenRA.Mods.RA
nextScanTime = (int)(25 * (info.ScanTimeAverage + nextScanTime = (int)(25 * (info.ScanTimeAverage +
(self.World.SharedRandom.NextDouble() * 2 - 1) * info.ScanTimeSpread)); (self.World.SharedRandom.NextDouble() * 2 - 1) * info.ScanTimeSpread));
var inRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range); var inRange = self.World.FindUnitsInCircle(self.CenterLocation, (int)(Game.CellSize * range));
return inRange return inRange
.Where(a => a.Owner != null && a.AppearsHostileTo(self)) .Where(a => a.Owner != null && a.AppearsHostileTo(self))

View File

@@ -80,7 +80,7 @@ namespace OpenRA.Mods.RA
case DamageModel.Normal: case DamageModel.Normal:
{ {
var maxSpread = warhead.Spread * (float)Math.Log(Math.Abs(warhead.Damage), 2); var maxSpread = warhead.Spread * (float)Math.Log(Math.Abs(warhead.Damage), 2);
var hitActors = world.FindUnitsInCircle(args.dest, maxSpread); var hitActors = world.FindUnitsInCircle(args.dest, (int)maxSpread);
foreach (var victim in hitActors) foreach (var victim in hitActors)
{ {
@@ -92,7 +92,7 @@ namespace OpenRA.Mods.RA
case DamageModel.PerCell: case DamageModel.PerCell:
{ {
foreach (var t in world.FindTilesInCircle(targetTile, warhead.Size[0])) foreach (var t in world.FindTilesInCircle(targetTile, warhead.Size[0]))
foreach (var unit in world.FindUnits(Game.CellSize * t, Game.CellSize * (t + new float2(1,1)))) foreach (var unit in world.FindUnits(Game.CellSize * t, Game.CellSize * (t + new int2(1,1))))
unit.InflictDamage(args.firedBy, unit.InflictDamage(args.firedBy,
(int)(warhead.Damage * warhead.EffectivenessAgainst(unit)), warhead); (int)(warhead.Damage * warhead.EffectivenessAgainst(unit)), warhead);
} break; } break;

View File

@@ -56,7 +56,7 @@ namespace OpenRA.Mods.RA.Render
if (!hasTicked) if (!hasTicked)
{ {
var oneCell = new float2(Game.CellSize, Game.CellSize); var oneCell = new int2(Game.CellSize, Game.CellSize);
var adjWalls = self.World.FindUnits(self.CenterLocation - oneCell, self.CenterLocation + oneCell) var adjWalls = self.World.FindUnits(self.CenterLocation - oneCell, self.CenterLocation + oneCell)
.Where(a => a.Info == self.Info && a != self); .Where(a => a.Info == self.Info && a != self);