diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj
index fa6d6941db..034dc789b9 100644
--- a/OpenRA.Game/OpenRA.Game.csproj
+++ b/OpenRA.Game/OpenRA.Game.csproj
@@ -156,6 +156,7 @@
+
diff --git a/OpenRA.Game/Orders/UnitOrderGenerator.cs b/OpenRA.Game/Orders/UnitOrderGenerator.cs
index 899d6ba3f3..3edcb4b08c 100644
--- a/OpenRA.Game/Orders/UnitOrderGenerator.cs
+++ b/OpenRA.Game/Orders/UnitOrderGenerator.cs
@@ -162,23 +162,4 @@ namespace OpenRA.Orders
}
}
}
-
- public static class SelectableExts
- {
- public static int SelectionPriority(this ActorInfo a)
- {
- var selectableInfo = a.Traits.GetOrDefault();
- return selectableInfo != null ? selectableInfo.Priority : int.MinValue;
- }
-
- public static Actor WithHighestSelectionPriority(this IEnumerable actors)
- {
- return actors.MaxByOrDefault(a => a.Info.SelectionPriority());
- }
-
- public static FrozenActor WithHighestSelectionPriority(this IEnumerable actors)
- {
- return actors.MaxByOrDefault(a => a.Info.SelectionPriority());
- }
- }
}
diff --git a/OpenRA.Game/SelectableExts.cs b/OpenRA.Game/SelectableExts.cs
new file mode 100644
index 0000000000..d762485870
--- /dev/null
+++ b/OpenRA.Game/SelectableExts.cs
@@ -0,0 +1,67 @@
+#region Copyright & License Information
+/*
+ * Copyright 2007-2015 The OpenRA Developers (see AUTHORS)
+ * This file is part of OpenRA, which is free software. It is made
+ * available to you under the terms of the GNU General Public License
+ * as published by the Free Software Foundation. For more information,
+ * see COPYING.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace OpenRA.Traits
+{
+ public static class SelectableExts
+ {
+ public static int SelectionPriority(this ActorInfo a)
+ {
+ var selectableInfo = a.Traits.GetOrDefault();
+ return selectableInfo != null ? selectableInfo.Priority : int.MinValue;
+ }
+
+ const int PriorityRange = 30;
+
+ public static int SelectionPriority(this Actor a)
+ {
+ var basePriority = a.Info.Traits.Get().Priority;
+ var lp = a.World.LocalPlayer;
+
+ if (a.Owner == lp || lp == null)
+ return basePriority;
+
+ switch (lp.Stances[a.Owner])
+ {
+ case Stance.Ally: return basePriority - PriorityRange;
+ case Stance.Neutral: return basePriority - 2 * PriorityRange;
+ case Stance.Enemy: return basePriority - 3 * PriorityRange;
+
+ default:
+ throw new InvalidOperationException();
+ }
+ }
+
+ public static Actor WithHighestSelectionPriority(this IEnumerable actors)
+ {
+ return actors.MaxByOrDefault(a => a.Info.SelectionPriority());
+ }
+
+ public static FrozenActor WithHighestSelectionPriority(this IEnumerable actors)
+ {
+ return actors.MaxByOrDefault(a => a.Info.SelectionPriority());
+ }
+
+ static readonly Actor[] NoActors = { };
+
+ public static IEnumerable SubsetWithHighestSelectionPriority(this IEnumerable actors)
+ {
+ return actors.GroupBy(x => x.SelectionPriority())
+ .OrderByDescending(g => g.Key)
+ .Select(g => g.AsEnumerable())
+ .DefaultIfEmpty(NoActors)
+ .FirstOrDefault();
+ }
+ }
+}
diff --git a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs
index af381f97e5..d65f31a443 100644
--- a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs
+++ b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs
@@ -8,7 +8,6 @@
*/
#endregion
-using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
@@ -22,8 +21,6 @@ namespace OpenRA.Widgets
{
public class WorldInteractionControllerWidget : Widget
{
- static readonly Actor[] NoActors = { };
-
protected readonly World World;
readonly WorldRenderer worldRenderer;
int2? dragStart, dragEnd;
@@ -238,7 +235,7 @@ namespace OpenRA.Widgets
else if (key == Game.Settings.Keys.SelectAllUnitsKey)
{
// Select actors on the screen which belong to the current player
- var ownUnitsOnScreen = SelectActorsOnScreen(World, worldRenderer, null, player);
+ var ownUnitsOnScreen = SelectActorsOnScreen(World, worldRenderer, null, player).SubsetWithHighestSelectionPriority();
World.Selection.Combine(World, ownUnitsOnScreen, false, false);
}
else if (key == Game.Settings.Keys.SelectUnitsByTypeKey)
@@ -275,23 +272,24 @@ namespace OpenRA.Widgets
static IEnumerable SelectActorsOnScreen(World world, WorldRenderer wr, IEnumerable selectionClasses, Player player)
{
- return SelectActorsByPlayerByClass(world.ScreenMap.ActorsInBox(wr.Viewport.TopLeft, wr.Viewport.BottomRight), selectionClasses, player);
+ return SelectActorsByOwnerAndSelectionClass(world.ScreenMap.ActorsInBox(wr.Viewport.TopLeft, wr.Viewport.BottomRight), player, selectionClasses);
}
static IEnumerable SelectActorsInWorld(World world, IEnumerable selectionClasses, Player player)
{
- return SelectActorsByPlayerByClass(world.ActorMap.ActorsInWorld(), selectionClasses, player);
+ return SelectActorsByOwnerAndSelectionClass(world.ActorMap.ActorsInWorld(), player, selectionClasses);
}
- static IEnumerable SelectActorsByPlayerByClass(IEnumerable actors, IEnumerable selectionClasses, Player player)
+ static IEnumerable SelectActorsByOwnerAndSelectionClass(IEnumerable actors, Player owner, IEnumerable selectionClasses)
{
return actors.Where(a =>
{
- if (a.Owner != player)
+ if (a.Owner != owner)
return false;
+
var s = a.TraitOrDefault();
- // sc == null means that units, that meet all other criteria, get selected
+ // selectionClasses == null means that units, that meet all other criteria, get selected
return s != null && (selectionClasses == null || selectionClasses.Contains(s.Class));
});
}
@@ -304,11 +302,7 @@ namespace OpenRA.Widgets
return world.ScreenMap.ActorsInBox(a, b)
.Where(x => x.HasTrait() && (x.Owner.IsAlliedWith(world.RenderPlayer) || !world.FogObscures(x)))
- .GroupBy(x => x.GetSelectionPriority())
- .OrderByDescending(g => g.Key)
- .Select(g => g.AsEnumerable())
- .DefaultIfEmpty(NoActors)
- .FirstOrDefault();
+ .SubsetWithHighestSelectionPriority();
}
bool ToggleStatusBars()
@@ -324,28 +318,4 @@ namespace OpenRA.Widgets
return true;
}
}
-
- static class PriorityExts
- {
- const int PriorityRange = 30;
-
- public static int GetSelectionPriority(this Actor a)
- {
- var basePriority = a.Info.Traits.Get().Priority;
- var lp = a.World.LocalPlayer;
-
- if (a.Owner == lp || lp == null)
- return basePriority;
-
- switch (lp.Stances[a.Owner])
- {
- case Stance.Ally: return basePriority - PriorityRange;
- case Stance.Neutral: return basePriority - 2 * PriorityRange;
- case Stance.Enemy: return basePriority - 3 * PriorityRange;
-
- default:
- throw new InvalidOperationException();
- }
- }
- }
}
\ No newline at end of file