Add support for "select all" and "select by type" for multiple players

This commit is contained in:
Ivaylo Draganov
2019-07-01 23:49:33 +03:00
committed by abcdefg30
parent 7cfc65010f
commit 017eca3dc1
2 changed files with 36 additions and 20 deletions

View File

@@ -31,12 +31,12 @@ namespace OpenRA.Traits
var info = a.Info.TraitInfo<SelectableInfo>();
var basePriority = BaseSelectionPriority(info, modifiers);
var lp = a.World.LocalPlayer;
var viewer = (a.World.LocalPlayer == null || a.World.LocalPlayer.Spectating) ? a.World.RenderPlayer : a.World.LocalPlayer;
if (a.Owner == lp || lp == null)
if (a.Owner == viewer || viewer == null)
return basePriority;
switch (lp.Stances[a.Owner])
switch (viewer.Stances[a.Owner])
{
case Stance.Ally: return basePriority - PriorityRange;
case Stance.Neutral: return basePriority - 2 * PriorityRange;

View File

@@ -128,13 +128,19 @@ namespace OpenRA.Mods.Common.Widgets
var unit = World.ScreenMap.ActorsAtMouse(mousePos)
.WithHighestSelectionPriority(mousePos, mi.Modifiers);
if (unit != null && unit.Owner == (World.RenderPlayer ?? World.LocalPlayer))
// Players to be included in the selection (the viewer or all players in "Disable shroud" / "All players" mode)
var viewer = World.RenderPlayer ?? World.LocalPlayer;
var isShroudDisabled = viewer == null || (World.RenderPlayer == null && World.LocalPlayer.Spectating);
var isEveryone = viewer != null && viewer.NonCombatant && viewer.Spectating;
var eligiblePlayers = isShroudDisabled || isEveryone ? World.Players : new[] { viewer };
if (unit != null && eligiblePlayers.Contains(unit.Owner))
{
var s = unit.TraitOrDefault<Selectable>();
if (s != null)
{
// Select actors on the screen that have the same selection class as the actor under the mouse cursor
var newSelection = SelectActorsOnScreen(World, worldRenderer, new HashSet<string> { s.Class }, unit.Owner);
var newSelection = SelectActorsOnScreen(World, worldRenderer, new HashSet<string> { s.Class }, eligiblePlayers);
World.Selection.Combine(World, newSelection, true, false);
}
@@ -245,14 +251,18 @@ namespace OpenRA.Mods.Common.Widgets
public override bool HandleKeyPress(KeyInput e)
{
var player = World.RenderPlayer ?? World.LocalPlayer;
if (e.Event == KeyInputEvent.Down)
{
// Players to be included in the selection (the viewer or all players in "Disable shroud" / "All players" mode)
var viewer = World.RenderPlayer ?? World.LocalPlayer;
var isShroudDisabled = viewer == null || (World.RenderPlayer == null && World.LocalPlayer.Spectating);
var isEveryone = viewer != null && viewer.NonCombatant && viewer.Spectating;
var eligiblePlayers = isShroudDisabled || isEveryone ? World.Players : new[] { viewer };
if (SelectAllKey.IsActivatedBy(e) && !World.IsGameOver)
{
// Select actors on the screen which belong to the current player
var ownUnitsOnScreen = SelectActorsOnScreen(World, worldRenderer, null, player).SubsetWithHighestSelectionPriority(e.Modifiers).ToList();
// Select actors on the screen which belong to the current player(s)
var ownUnitsOnScreen = SelectActorsOnScreen(World, worldRenderer, null, eligiblePlayers).SubsetWithHighestSelectionPriority(e.Modifiers).ToList();
// Check if selecting actors on the screen has selected new units
if (ownUnitsOnScreen.Count > World.Selection.Actors.Count())
@@ -260,7 +270,7 @@ namespace OpenRA.Mods.Common.Widgets
else
{
// Select actors in the world that have highest selection priority
ownUnitsOnScreen = SelectActorsInWorld(World, null, player).SubsetWithHighestSelectionPriority(e.Modifiers).ToList();
ownUnitsOnScreen = SelectActorsInWorld(World, null, eligiblePlayers).SubsetWithHighestSelectionPriority(e.Modifiers).ToList();
Game.AddSystemLine("Battlefield Control", "Selected across map");
}
@@ -271,14 +281,20 @@ namespace OpenRA.Mods.Common.Widgets
if (!World.Selection.Actors.Any())
return false;
var ownedActors = World.Selection.Actors
.Where(x => !x.IsDead && eligiblePlayers.Contains(x.Owner))
.ToList();
if (!ownedActors.Any())
return false;
// Get all the selected actors' selection classes
var selectedClasses = World.Selection.Actors
.Where(x => !x.IsDead && x.Owner == player)
var selectedClasses = ownedActors
.Select(a => a.Trait<Selectable>().Class)
.ToHashSet();
// Select actors on the screen that have the same selection class as one of the already selected actors
var newSelection = SelectActorsOnScreen(World, worldRenderer, selectedClasses, player).ToList();
var newSelection = SelectActorsOnScreen(World, worldRenderer, selectedClasses, eligiblePlayers).ToList();
// Check if selecting actors on the screen has selected new units
if (newSelection.Count > World.Selection.Actors.Count())
@@ -286,7 +302,7 @@ namespace OpenRA.Mods.Common.Widgets
else
{
// Select actors in the world that have the same selection class as one of the already selected actors
newSelection = SelectActorsInWorld(World, selectedClasses, player).ToList();
newSelection = SelectActorsInWorld(World, selectedClasses, eligiblePlayers).ToList();
Game.AddSystemLine("Battlefield Control", "Selected across map");
}
@@ -297,22 +313,22 @@ namespace OpenRA.Mods.Common.Widgets
return false;
}
static IEnumerable<Actor> SelectActorsOnScreen(World world, WorldRenderer wr, IEnumerable<string> selectionClasses, Player player)
static IEnumerable<Actor> SelectActorsOnScreen(World world, WorldRenderer wr, IEnumerable<string> selectionClasses, IEnumerable<Player> players)
{
var actors = world.ScreenMap.ActorsInMouseBox(wr.Viewport.TopLeft, wr.Viewport.BottomRight).Select(a => a.Actor);
return SelectActorsByOwnerAndSelectionClass(actors, player, selectionClasses);
return SelectActorsByOwnerAndSelectionClass(actors, players, selectionClasses);
}
static IEnumerable<Actor> SelectActorsInWorld(World world, IEnumerable<string> selectionClasses, Player player)
static IEnumerable<Actor> SelectActorsInWorld(World world, IEnumerable<string> selectionClasses, IEnumerable<Player> players)
{
return SelectActorsByOwnerAndSelectionClass(world.Actors.Where(a => a.IsInWorld), player, selectionClasses);
return SelectActorsByOwnerAndSelectionClass(world.Actors.Where(a => a.IsInWorld), players, selectionClasses);
}
static IEnumerable<Actor> SelectActorsByOwnerAndSelectionClass(IEnumerable<Actor> actors, Player owner, IEnumerable<string> selectionClasses)
static IEnumerable<Actor> SelectActorsByOwnerAndSelectionClass(IEnumerable<Actor> actors, IEnumerable<Player> owners, IEnumerable<string> selectionClasses)
{
return actors.Where(a =>
{
if (a.Owner != owner)
if (!owners.Contains(a.Owner))
return false;
var s = a.TraitOrDefault<Selectable>();