diff --git a/OpenRa.Game/Controller.cs b/OpenRa.Game/Controller.cs index c81820721a..a82700c6f8 100644 --- a/OpenRa.Game/Controller.cs +++ b/OpenRa.Game/Controller.cs @@ -93,8 +93,14 @@ namespace OpenRa.Game { if (!(orderGenerator is PlaceBuilding)) { - orderGenerator = new UnitOrderGenerator( - Game.SelectActorsInBox(Game.CellSize * dragStart, Game.CellSize * xy)); + var newSelection = Game.SelectActorsInBox(Game.CellSize * dragStart, Game.CellSize * xy); + var oldSelection = (orderGenerator is UnitOrderGenerator) + ? (orderGenerator as UnitOrderGenerator).selection : new Actor[] { }.AsEnumerable(); + + if (dragStart == xy) + orderGenerator = new UnitOrderGenerator(mi.Modifiers.HasModifier(Keys.Shift) ? oldSelection.SymmetricDifference(newSelection) : newSelection); + else + orderGenerator = new UnitOrderGenerator(mi.Modifiers.HasModifier(Keys.Shift) ? oldSelection.Union(newSelection) : newSelection); var voicedUnit = ((UnitOrderGenerator)orderGenerator).selection .Where(a => a.traits.Contains() diff --git a/OpenRa.Game/Exts.cs b/OpenRa.Game/Exts.cs index 7ebaab3e1e..187681e1d5 100644 --- a/OpenRa.Game/Exts.cs +++ b/OpenRa.Game/Exts.cs @@ -1,4 +1,8 @@  +using System.Windows.Forms; +using System.Collections.Generic; +using System.Linq; + namespace OpenRa.Game { static class Exts @@ -7,5 +11,16 @@ namespace OpenRa.Game { return string.Format(fmt, args); } + + public static bool HasModifier(this Keys k, Keys mod) + { + return (k & mod) == mod; + } + + public static IEnumerable SymmetricDifference(this IEnumerable xs, IEnumerable ys) + { + // this is probably a shockingly-slow way to do this, but it's concise. + return xs.Except(ys).Concat(ys.Except(xs)); + } } } diff --git a/OpenRa.Game/MainWindow.cs b/OpenRa.Game/MainWindow.cs index 73294f573b..048393137c 100755 --- a/OpenRa.Game/MainWindow.cs +++ b/OpenRa.Game/MainWindow.cs @@ -88,7 +88,8 @@ namespace OpenRa.Game { Button = e.Button, Event = MouseInputEvent.Down, - Location = new int2(e.Location) + Location = new int2(e.Location), + Modifiers = ModifierKeys, }); } @@ -107,7 +108,8 @@ namespace OpenRa.Game { Button = e.Button, Event = MouseInputEvent.Move, - Location = new int2(e.Location) + Location = new int2(e.Location), + Modifiers = ModifierKeys, }); } @@ -119,7 +121,8 @@ namespace OpenRa.Game { Button = e.Button, Event = MouseInputEvent.Up, - Location = new int2(e.Location) + Location = new int2(e.Location), + Modifiers = ModifierKeys, }); } @@ -154,6 +157,7 @@ namespace OpenRa.Game public MouseInputEvent Event; public int2 Location; public MouseButtons Button; + public Keys Modifiers; } enum MouseInputEvent { Down, Move, Up };