From 9b3e6c5c4a9859c16a6e42dd374a8ff3e2849bdc Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Wed, 4 May 2011 22:25:35 +1200 Subject: [PATCH] remove FP sillyness from FindUnits & friends --- OpenRA.Game/Actor.cs | 27 ++++++++++--------- OpenRA.Game/Graphics/Viewport.cs | 3 +++ OpenRA.Game/Graphics/WorldRenderer.cs | 4 +-- OpenRA.Game/Traits/World/SpatialBins.cs | 10 +++---- .../WorldInteractionControllerWidget.cs | 22 ++++++++------- OpenRA.Game/WorldUtils.cs | 12 ++++----- OpenRA.Mods.RA/AutoHeal.cs | 2 +- OpenRA.Mods.RA/AutoTarget.cs | 2 +- OpenRA.Mods.RA/Combat.cs | 4 +-- OpenRA.Mods.RA/Render/RenderBuildingWall.cs | 2 +- 10 files changed, 48 insertions(+), 40 deletions(-) diff --git a/OpenRA.Game/Actor.cs b/OpenRA.Game/Actor.cs index 890f0d158a..87172130ff 100755 --- a/OpenRA.Game/Actor.cs +++ b/OpenRA.Game/Actor.cs @@ -28,8 +28,8 @@ namespace OpenRA IOccupySpace OccupiesSpace; IHasLocation HasLocation; Lazy Move; - public Cached Bounds; - public Cached ExtendedBounds; + public Cached Bounds; + public Cached ExtendedBounds; public int2 Location { get { @@ -76,12 +76,12 @@ namespace OpenRA { var si = Info.Traits.GetOrDefault(); 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 var firstSprite = TraitsImplementing().SelectMany(ApplyIRender).FirstOrDefault(); - if (firstSprite.Sprite == null) return float2.Zero; - return firstSprite.Sprite.size * firstSprite.Scale; + if (firstSprite.Sprite == null) return int2.Zero; + return (firstSprite.Sprite.size * firstSprite.Scale).ToInt2(); }); ApplyIRender = x => x.Render(this); @@ -104,7 +104,7 @@ namespace OpenRA get { return currentActivity == null; } } - OpenRA.FileFormats.Lazy Size; + OpenRA.FileFormats.Lazy Size; // note: these delegates are cached to avoid massive allocation. Func> ApplyIRender; @@ -120,24 +120,27 @@ namespace OpenRA // vertically to altitude = 0 to support FindUnitsInCircle queries // When false, the bounding box is given for the actor // at its current altitude - RectangleF CalculateBounds(bool useAltitude) + Rectangle CalculateBounds(bool useAltitude) { var size = Size.Value; - var loc = CenterLocation - 0.5f * size; + var loc = CenterLocation - size / 2; var si = Info.Traits.GetOrDefault(); 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; if (move != null) { - loc -= new float2(0, move.Altitude); + loc.Y -= move.Altitude; 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; } diff --git a/OpenRA.Game/Graphics/Viewport.cs b/OpenRA.Game/Graphics/Viewport.cs index 3fd6c7aae8..591061229a 100755 --- a/OpenRA.Game/Graphics/Viewport.cs +++ b/OpenRA.Game/Graphics/Viewport.cs @@ -110,6 +110,9 @@ namespace OpenRA.Graphics 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) { scrollPosition = this.NormalizeScrollPosition((Game.CellSize*loc - screenSize / 2).ToInt2()); diff --git a/OpenRA.Game/Graphics/WorldRenderer.cs b/OpenRA.Game/Graphics/WorldRenderer.cs index f25fde4cea..b363ad1866 100644 --- a/OpenRA.Game/Graphics/WorldRenderer.cs +++ b/OpenRA.Game/Graphics/WorldRenderer.cs @@ -58,8 +58,8 @@ namespace OpenRA.Graphics bounds.Offset((int)Game.viewport.Location.X, (int)Game.viewport.Location.Y); var actors = world.FindUnits( - new float2(bounds.Left, bounds.Top), - new float2(bounds.Right, bounds.Bottom)); + new int2(bounds.Left, bounds.Top), + new int2(bounds.Right, bounds.Bottom)); var renderables = actors.SelectMany(a => a.Render()) .OrderBy(r => r, comparer); diff --git a/OpenRA.Game/Traits/World/SpatialBins.cs b/OpenRA.Game/Traits/World/SpatialBins.cs index 1d7b6a3f1b..1739930adb 100644 --- a/OpenRA.Game/Traits/World/SpatialBins.cs +++ b/OpenRA.Game/Traits/World/SpatialBins.cs @@ -54,10 +54,10 @@ namespace OpenRA.Traits if (bounds.Left >= Game.CellSize * self.World.Map.Bounds.Right) continue; if (bounds.Top >= Game.CellSize * self.World.Map.Bounds.Bottom) continue; - var i1 = Math.Max(0, (int)bounds.Left / scale); - var i2 = Math.Min(bins.GetUpperBound(0), (int)bounds.Right / scale); - var j1 = Math.Max(0, (int)bounds.Top / scale); - var j2 = Math.Min(bins.GetUpperBound(1), (int)bounds.Bottom / scale); + var i1 = Math.Max(0, bounds.Left / scale); + var i2 = Math.Min(bins.GetUpperBound(0), bounds.Right / scale); + var j1 = Math.Max(0, bounds.Top / scale); + var j2 = Math.Min(bins.GetUpperBound(1), bounds.Bottom / scale); for (var j = j1; j <= j2; j++) for (var i = i1; i <= i2; i++) @@ -77,7 +77,7 @@ namespace OpenRA.Traits public IEnumerable 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) .Distinct() diff --git a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs index cf3a1da4bc..871b939cf7 100644 --- a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs +++ b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs @@ -8,6 +8,7 @@ */ #endregion +using System; using System.Collections.Generic; using System.Drawing; using System.Linq; @@ -15,7 +16,6 @@ using OpenRA.FileFormats; using OpenRA.Graphics; using OpenRA.Orders; using OpenRA.Traits; -using System; namespace OpenRA.Widgets { @@ -23,6 +23,7 @@ namespace OpenRA.Widgets { readonly World world; readonly WorldRenderer worldRenderer; + [ObjectCreator.UseCtor] public WorldInteractionControllerWidget([ObjectCreator.Param] World world, [ObjectCreator.Param] WorldRenderer worldRenderer) { @@ -35,7 +36,7 @@ namespace OpenRA.Widgets var selbox = SelectionBox; 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); return; @@ -54,12 +55,12 @@ namespace OpenRA.Widgets worldRenderer.DrawRollover(u); } - float2 dragStart, dragEnd; + int2 dragStart, dragEnd; // TODO: WorldInteractionController doesn't support delegate methods for mouse input 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) { dragStart = dragEnd = xy; @@ -73,7 +74,7 @@ namespace OpenRA.Widgets { 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); } @@ -89,20 +90,20 @@ namespace OpenRA.Widgets return true; } - public Pair? SelectionBox + public Pair? SelectionBox { get { 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; - 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 ) ); world.PlayVoiceForOrders(orders); @@ -119,6 +120,7 @@ namespace OpenRA.Widgets Modifiers = Game.GetModifierKeys() }; + // TODO: fix this up. return world.OrderGenerator.GetCursor( world, Game.viewport.ViewToWorld(mi).ToInt2(), mi ); } ); } @@ -141,7 +143,7 @@ namespace OpenRA.Widgets } static readonly Actor[] NoActors = {}; - IEnumerable SelectActorsInBox(World world, float2 a, float2 b) + IEnumerable SelectActorsInBox(World world, int2 a, int2 b) { return world.FindUnits(a, b) .Where( x => x.HasTrait() && world.LocalShroud.IsVisible(x) ) diff --git a/OpenRA.Game/WorldUtils.cs b/OpenRA.Game/WorldUtils.cs index a8db341db5..387008e9c7 100755 --- a/OpenRA.Game/WorldUtils.cs +++ b/OpenRA.Game/WorldUtils.cs @@ -23,27 +23,27 @@ namespace OpenRA { public static IEnumerable 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)); } - public static IEnumerable FindUnits(this World world, float2 a, float2 b) + public static IEnumerable FindUnits(this World world, int2 a, int2 b) { var u = float2.Min(a, b).ToInt2(); var v = float2.Max(a, b).ToInt2(); return world.WorldActor.Trait().ActorsInBox(u,v); } - public static IEnumerable FindUnitsInCircle(this World world, float2 a, float r) + public static IEnumerable FindUnitsInCircle(this World world, int2 a, int r) { using (new PerfSample("FindUnitsInCircle")) { - var min = a - new float2(r, r); - var max = a + new float2(r, r); + var min = a - new int2(r, r); + var max = a + new int2(r, r); 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)); diff --git a/OpenRA.Mods.RA/AutoHeal.cs b/OpenRA.Mods.RA/AutoHeal.cs index 01a64aa366..63bcbeaa10 100644 --- a/OpenRA.Mods.RA/AutoHeal.cs +++ b/OpenRA.Mods.RA/AutoHeal.cs @@ -21,7 +21,7 @@ namespace OpenRA.Mods.RA public void TickIdle( Actor self ) { var attack = self.Trait(); - 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 .Where(a => a != self && a.AppearsFriendlyTo(self)) diff --git a/OpenRA.Mods.RA/AutoTarget.cs b/OpenRA.Mods.RA/AutoTarget.cs index 3c092d536d..9d1711a15a 100644 --- a/OpenRA.Mods.RA/AutoTarget.cs +++ b/OpenRA.Mods.RA/AutoTarget.cs @@ -95,7 +95,7 @@ namespace OpenRA.Mods.RA nextScanTime = (int)(25 * (info.ScanTimeAverage + (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 .Where(a => a.Owner != null && a.AppearsHostileTo(self)) diff --git a/OpenRA.Mods.RA/Combat.cs b/OpenRA.Mods.RA/Combat.cs index 37ee804484..19d6275884 100755 --- a/OpenRA.Mods.RA/Combat.cs +++ b/OpenRA.Mods.RA/Combat.cs @@ -80,7 +80,7 @@ namespace OpenRA.Mods.RA case DamageModel.Normal: { 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) { @@ -92,7 +92,7 @@ namespace OpenRA.Mods.RA case DamageModel.PerCell: { 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, (int)(warhead.Damage * warhead.EffectivenessAgainst(unit)), warhead); } break; diff --git a/OpenRA.Mods.RA/Render/RenderBuildingWall.cs b/OpenRA.Mods.RA/Render/RenderBuildingWall.cs index 125ad38201..f50d35790e 100644 --- a/OpenRA.Mods.RA/Render/RenderBuildingWall.cs +++ b/OpenRA.Mods.RA/Render/RenderBuildingWall.cs @@ -56,7 +56,7 @@ namespace OpenRA.Mods.RA.Render 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) .Where(a => a.Info == self.Info && a != self);