diff --git a/OpenRa.Game/Controller.cs b/OpenRa.Game/Controller.cs index bf16bce2cf..3b1a60221d 100644 --- a/OpenRa.Game/Controller.cs +++ b/OpenRa.Game/Controller.cs @@ -42,18 +42,21 @@ namespace OpenRa.Game if (!(orderGenerator is PlaceBuilding)) { if (dragStart != xy) - orderGenerator = new UnitOrderGenerator( game.FindUnits( Game.CellSize * dragStart, Game.CellSize * xy ) ); /* band-box select */ + orderGenerator = new UnitOrderGenerator( + game.SelectUnitsInBox( Game.CellSize * dragStart, Game.CellSize * xy ) ); else - orderGenerator = new UnitOrderGenerator( game.FindUnits( Game.CellSize * xy, Game.CellSize * xy ) ); /* click select */ + orderGenerator = new UnitOrderGenerator( + game.SelectUnitOrBuilding( Game.CellSize * xy ) ); } - dragStart = dragEnd; + dragStart = dragEnd = xy; } if (mi.Button == MouseButtons.None && mi.Event == MouseInputEvent.Move) { /* update the cursor to reflect the thing under us - note this - * needs to also happen when the *thing* changes, so per-frame hook */ + * needs to also happen when the *thing* changes, so per-frame hook */ + dragStart = dragEnd = xy; } if( mi.Button == MouseButtons.Right && mi.Event == MouseInputEvent.Down ) @@ -69,6 +72,19 @@ namespace OpenRa.Game if (dragStart == dragEnd) return null; return Pair.New(Game.CellSize * dragStart, Game.CellSize * dragEnd); } - } + } + + public Cursor ChooseCursor() + { + var uog = orderGenerator as UnitOrderGenerator; + + if (uog != null && uog.selection.Count > 0 && uog.selection.Any(a => a.traits.Contains())) + return Cursor.Move; + + if (game.SelectUnitOrBuilding(Game.CellSize * dragEnd).Any()) + return Cursor.Select; + + return Cursor.Default; + } } } diff --git a/OpenRa.Game/Cursor.cs b/OpenRa.Game/Cursor.cs index 67d68444a2..e5ab1a314a 100644 --- a/OpenRa.Game/Cursor.cs +++ b/OpenRa.Game/Cursor.cs @@ -18,14 +18,8 @@ namespace OpenRa.Game public Sprite GetSprite(int frame) { return sequence.GetSprite(frame); } public int2 GetHotspot() { return sequence.Hotspot; } - public static Cursor Default - { - get { return new Cursor("default"); } - } - - public static Cursor Move - { - get { return new Cursor("move"); } - } + public static Cursor Default { get { return new Cursor("default"); } } + public static Cursor Move { get { return new Cursor("move"); } } + public static Cursor Select { get { return new Cursor("select"); } } } } diff --git a/OpenRa.Game/Game.cs b/OpenRa.Game/Game.cs index 491225c691..1cf8676fe0 100644 --- a/OpenRa.Game/Game.cs +++ b/OpenRa.Game/Game.cs @@ -131,17 +131,28 @@ namespace OpenRa.Game return map.IsInMap(a.X, a.Y) && TerrainCosts.Cost(UnitMovementType.Wheel, terrain.tileSet.GetWalkability(map.MapTiles[a.X, a.Y])) < double.PositiveInfinity; + } + + IEnumerable FindUnits(float2 a, float2 b) + { + var min = float2.Min(a, b); + var max = float2.Max(a, b); + + var rect = new RectangleF(min.X, min.Y, max.X - min.X, max.Y - min.Y); + + return world.Actors + .Where(x => x.Bounds.IntersectsWith(rect)); } - public IEnumerable FindUnits(float2 a, float2 b) - { - var min = float2.Min(a, b); - var max = float2.Max(a, b); - - var rect = new RectangleF(min.X, min.Y, max.X - min.X, max.Y - min.Y); - - return world.Actors - .Where(x => (x.Owner == LocalPlayer) && (x.Bounds.IntersectsWith(rect))); + public IEnumerable SelectUnitsInBox(float2 a, float2 b) + { + return FindUnits(a, b).Where(x => x.Owner == LocalPlayer && x.traits.Contains()); + } + + public IEnumerable SelectUnitOrBuilding(float2 a) + { + var q = FindUnits(a, a); + return q.Where(x => x.traits.Contains()).Concat(q).Take(1); } } } diff --git a/OpenRa.Game/Graphics/WorldRenderer.cs b/OpenRa.Game/Graphics/WorldRenderer.cs index 0fe733e982..ab520609ba 100644 --- a/OpenRa.Game/Graphics/WorldRenderer.cs +++ b/OpenRa.Game/Graphics/WorldRenderer.cs @@ -75,7 +75,7 @@ namespace OpenRa.Game.Graphics lineRenderer.DrawLine(a + b + c, a + c, Color.White, Color.White); lineRenderer.DrawLine(a, a + c, Color.White, Color.White); - foreach (var u in game.FindUnits(selbox.Value.First, selbox.Value.Second)) + foreach (var u in game.SelectUnitsInBox(selbox.Value.First, selbox.Value.Second)) DrawSelectionBox(u, Color.Yellow, false); } diff --git a/OpenRa.Game/MainWindow.cs b/OpenRa.Game/MainWindow.cs index 9d377ae42a..3c0102eb02 100755 --- a/OpenRa.Game/MainWindow.cs +++ b/OpenRa.Game/MainWindow.cs @@ -80,9 +80,7 @@ using System.Runtime.InteropServices; game.Tick(); // rude hack - game.viewport.cursor = (game.controller.orderGenerator is UnitOrderGenerator) - && (game.controller.orderGenerator as UnitOrderGenerator).selection.Count > 0 - ? OpenRa.Game.Cursor.Move : OpenRa.Game.Cursor.Default; + game.viewport.cursor = game.controller.ChooseCursor(); Application.DoEvents(); } diff --git a/sequences.xml b/sequences.xml index 2c98143aca..75922cd451 100644 --- a/sequences.xml +++ b/sequences.xml @@ -332,7 +332,7 @@ - +