Move selection hotkeys out of world interaction widget
- Split SelectionUtils for selecting actors in the world to a static class - Split selection hotkeys into their own logic classes
This commit is contained in:
committed by
Matthias Mailänder
parent
e9cc89a336
commit
a537346580
@@ -0,0 +1,66 @@
|
|||||||
|
#region Copyright & License Information
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2021 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, either version 3 of
|
||||||
|
* the License, or (at your option) any later version. For more
|
||||||
|
* information, see COPYING.
|
||||||
|
*/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using OpenRA.Graphics;
|
||||||
|
using OpenRA.Mods.Common.Lint;
|
||||||
|
using OpenRA.Traits;
|
||||||
|
using OpenRA.Widgets;
|
||||||
|
|
||||||
|
namespace OpenRA.Mods.Common.Widgets.Logic.Ingame
|
||||||
|
{
|
||||||
|
[ChromeLogicArgsHotkeys("SelectAllUnitsKey")]
|
||||||
|
public class SelectAllUnitsHotkeyLogic : SingleHotkeyBaseLogic
|
||||||
|
{
|
||||||
|
readonly World world;
|
||||||
|
readonly WorldRenderer worldRenderer;
|
||||||
|
readonly ISelection selection;
|
||||||
|
|
||||||
|
public readonly string ClickSound = ChromeMetrics.Get<string>("ClickSound");
|
||||||
|
|
||||||
|
[ObjectCreator.UseCtor]
|
||||||
|
public SelectAllUnitsHotkeyLogic(Widget widget, ModData modData, WorldRenderer worldRenderer, World world, Dictionary<string, MiniYaml> logicArgs)
|
||||||
|
: base(widget, modData, "SelectAllUnitsKey", "WORLD_KEYHANDLER", logicArgs)
|
||||||
|
{
|
||||||
|
this.world = world;
|
||||||
|
this.worldRenderer = worldRenderer;
|
||||||
|
selection = world.Selection;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnHotkeyActivated(KeyInput e)
|
||||||
|
{
|
||||||
|
if (world.IsGameOver)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var eligiblePlayers = SelectionUtils.GetPlayersToIncludeInSelection(world);
|
||||||
|
|
||||||
|
// Select actors on the screen which belong to the current player(s)
|
||||||
|
var ownUnitsOnScreen = SelectionUtils.SelectActorsOnScreen(world, worldRenderer, null, eligiblePlayers).SubsetWithHighestSelectionPriority(e.Modifiers).ToList();
|
||||||
|
|
||||||
|
// Check if selecting actors on the screen has selected new units
|
||||||
|
if (ownUnitsOnScreen.Count > selection.Actors.Count())
|
||||||
|
TextNotificationsManager.AddFeedbackLine("Selected across screen.");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Select actors in the world that have highest selection priority
|
||||||
|
ownUnitsOnScreen = SelectionUtils.SelectActorsInWorld(world, null, eligiblePlayers).SubsetWithHighestSelectionPriority(e.Modifiers).ToList();
|
||||||
|
TextNotificationsManager.AddFeedbackLine("Selected across map.");
|
||||||
|
}
|
||||||
|
|
||||||
|
selection.Combine(world, ownUnitsOnScreen, false, false);
|
||||||
|
|
||||||
|
Game.Sound.PlayNotification(world.Map.Rules, world.LocalPlayer, "Sounds", ClickSound, null);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
#region Copyright & License Information
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2021 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, either version 3 of
|
||||||
|
* the License, or (at your option) any later version. For more
|
||||||
|
* information, see COPYING.
|
||||||
|
*/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using OpenRA.Graphics;
|
||||||
|
using OpenRA.Mods.Common.Lint;
|
||||||
|
using OpenRA.Mods.Common.Traits;
|
||||||
|
using OpenRA.Traits;
|
||||||
|
using OpenRA.Widgets;
|
||||||
|
|
||||||
|
namespace OpenRA.Mods.Common.Widgets.Logic.Ingame
|
||||||
|
{
|
||||||
|
[ChromeLogicArgsHotkeys("SelectUnitsByTypeKey")]
|
||||||
|
public class SelectUnitsByTypeHotkeyLogic : SingleHotkeyBaseLogic
|
||||||
|
{
|
||||||
|
readonly World world;
|
||||||
|
readonly WorldRenderer worldRenderer;
|
||||||
|
readonly ISelection selection;
|
||||||
|
|
||||||
|
public readonly string ClickSound = ChromeMetrics.Get<string>("ClickSound");
|
||||||
|
public readonly string ClickDisabledSound = ChromeMetrics.Get<string>("ClickDisabledSound");
|
||||||
|
|
||||||
|
[ObjectCreator.UseCtor]
|
||||||
|
public SelectUnitsByTypeHotkeyLogic(Widget widget, ModData modData, WorldRenderer worldRenderer, World world, Dictionary<string, MiniYaml> logicArgs)
|
||||||
|
: base(widget, modData, "SelectUnitsByTypeKey", "WORLD_KEYHANDLER", logicArgs)
|
||||||
|
{
|
||||||
|
this.world = world;
|
||||||
|
this.worldRenderer = worldRenderer;
|
||||||
|
selection = world.Selection;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnHotkeyActivated(KeyInput e)
|
||||||
|
{
|
||||||
|
if (world.IsGameOver)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!selection.Actors.Any())
|
||||||
|
{
|
||||||
|
TextNotificationsManager.AddFeedbackLine("Nothing selected.");
|
||||||
|
Game.Sound.PlayNotification(world.Map.Rules, world.LocalPlayer, "Sounds", ClickDisabledSound, null);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var eligiblePlayers = SelectionUtils.GetPlayersToIncludeInSelection(world);
|
||||||
|
|
||||||
|
var ownedActors = 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 = ownedActors
|
||||||
|
.Select(a => a.Trait<ISelectable>().Class)
|
||||||
|
.ToHashSet();
|
||||||
|
|
||||||
|
// Select actors on the screen that have the same selection class as one of the already selected actors
|
||||||
|
var newSelection = SelectionUtils.SelectActorsOnScreen(world, worldRenderer, selectedClasses, eligiblePlayers).ToList();
|
||||||
|
|
||||||
|
// Check if selecting actors on the screen has selected new units
|
||||||
|
if (newSelection.Count > selection.Actors.Count())
|
||||||
|
TextNotificationsManager.AddFeedbackLine("Selected across screen.");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Select actors in the world that have the same selection class as one of the already selected actors
|
||||||
|
newSelection = SelectionUtils.SelectActorsInWorld(world, selectedClasses, eligiblePlayers).ToList();
|
||||||
|
TextNotificationsManager.AddFeedbackLine("Selected across map.");
|
||||||
|
}
|
||||||
|
|
||||||
|
selection.Combine(world, newSelection, true, false);
|
||||||
|
|
||||||
|
Game.Sound.PlayNotification(world.Map.Rules, world.LocalPlayer, "Sounds", ClickSound, null);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
83
OpenRA.Mods.Common/Widgets/SelectionUtils.cs
Normal file
83
OpenRA.Mods.Common/Widgets/SelectionUtils.cs
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
#region Copyright & License Information
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2021 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, either version 3 of
|
||||||
|
* the License, or (at your option) any later version. For more
|
||||||
|
* information, see COPYING.
|
||||||
|
*/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using OpenRA.Graphics;
|
||||||
|
using OpenRA.Mods.Common.Traits;
|
||||||
|
using OpenRA.Traits;
|
||||||
|
|
||||||
|
namespace OpenRA.Mods.Common.Widgets
|
||||||
|
{
|
||||||
|
public static class SelectionUtils
|
||||||
|
{
|
||||||
|
public 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, players, selectionClasses);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<Actor> SelectActorsInWorld(World world, IEnumerable<string> selectionClasses, IEnumerable<Player> players)
|
||||||
|
{
|
||||||
|
return SelectActorsByOwnerAndSelectionClass(world.Actors.Where(a => a.IsInWorld), players, selectionClasses);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<Actor> SelectActorsByOwnerAndSelectionClass(IEnumerable<Actor> actors, IEnumerable<Player> owners, IEnumerable<string> selectionClasses)
|
||||||
|
{
|
||||||
|
return actors.Where(a =>
|
||||||
|
{
|
||||||
|
if (!owners.Contains(a.Owner))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var s = a.TraitOrDefault<ISelectable>();
|
||||||
|
|
||||||
|
// selectionClasses == null means that units, that meet all other criteria, get selected
|
||||||
|
return s != null && (selectionClasses == null || selectionClasses.Contains(s.Class));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<Actor> SelectHighestPriorityActorAtPoint(World world, int2 a, Modifiers modifiers)
|
||||||
|
{
|
||||||
|
var selected = world.ScreenMap.ActorsAtMouse(a)
|
||||||
|
.Where(x => x.Actor.Info.HasTraitInfo<ISelectableInfo>() && (x.Actor.Owner.IsAlliedWith(world.RenderPlayer) || !world.FogObscures(x.Actor)))
|
||||||
|
.WithHighestSelectionPriority(a, modifiers);
|
||||||
|
|
||||||
|
if (selected != null)
|
||||||
|
yield return selected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<Actor> SelectActorsInBoxWithDeadzone(World world, int2 a, int2 b, Modifiers modifiers)
|
||||||
|
{
|
||||||
|
// For dragboxes that are too small, shrink the dragbox to a single point (point b)
|
||||||
|
if ((a - b).Length <= Game.Settings.Game.SelectionDeadzone)
|
||||||
|
a = b;
|
||||||
|
|
||||||
|
if (a == b)
|
||||||
|
return SelectHighestPriorityActorAtPoint(world, a, modifiers);
|
||||||
|
|
||||||
|
return world.ScreenMap.ActorsInMouseBox(a, b)
|
||||||
|
.Select(x => x.Actor)
|
||||||
|
.Where(x => x.Info.HasTraitInfo<ISelectableInfo>() && (x.Owner.IsAlliedWith(world.RenderPlayer) || !world.FogObscures(x)))
|
||||||
|
.SubsetWithHighestSelectionPriority(modifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Player[] GetPlayersToIncludeInSelection(World world)
|
||||||
|
{
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
return isShroudDisabled || isEveryone ? world.Players : new[] { viewer };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,9 +22,6 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
{
|
{
|
||||||
public class WorldInteractionControllerWidget : Widget
|
public class WorldInteractionControllerWidget : Widget
|
||||||
{
|
{
|
||||||
public readonly HotkeyReference SelectAllKey = new HotkeyReference();
|
|
||||||
public readonly HotkeyReference SelectSameTypeKey = new HotkeyReference();
|
|
||||||
|
|
||||||
protected readonly World World;
|
protected readonly World World;
|
||||||
readonly WorldRenderer worldRenderer;
|
readonly WorldRenderer worldRenderer;
|
||||||
readonly Color normalSelectionColor;
|
readonly Color normalSelectionColor;
|
||||||
@@ -72,12 +69,12 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
Game.Renderer.RgbaColorRenderer.DrawRect(a, b, 1, color);
|
Game.Renderer.RgbaColorRenderer.DrawRect(a, b, 1, color);
|
||||||
|
|
||||||
// Render actors in the dragbox
|
// Render actors in the dragbox
|
||||||
rollover = SelectActorsInBoxWithDeadzone(World, dragStart, mousePos, modifiers);
|
rollover = SelectionUtils.SelectActorsInBoxWithDeadzone(World, dragStart, mousePos, modifiers);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Render actors under the mouse pointer
|
// Render actors under the mouse pointer
|
||||||
rollover = SelectActorsInBoxWithDeadzone(World, mousePos, mousePos, modifiers);
|
rollover = SelectionUtils.SelectActorsInBoxWithDeadzone(World, mousePos, mousePos, modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
worldRenderer.World.Selection.SetRollover(rollover);
|
worldRenderer.World.Selection.SetRollover(rollover);
|
||||||
@@ -127,11 +124,7 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
var unit = World.ScreenMap.ActorsAtMouse(mousePos)
|
var unit = World.ScreenMap.ActorsAtMouse(mousePos)
|
||||||
.WithHighestSelectionPriority(mousePos, mi.Modifiers);
|
.WithHighestSelectionPriority(mousePos, mi.Modifiers);
|
||||||
|
|
||||||
// Players to be included in the selection (the viewer or all players in "Disable shroud" / "All players" mode)
|
var eligiblePlayers = SelectionUtils.GetPlayersToIncludeInSelection(World);
|
||||||
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))
|
if (unit != null && eligiblePlayers.Contains(unit.Owner))
|
||||||
{
|
{
|
||||||
@@ -139,7 +132,7 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
if (s != null)
|
if (s != null)
|
||||||
{
|
{
|
||||||
// Select actors on the screen that have the same selection class as the actor under the mouse cursor
|
// 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 }, eligiblePlayers);
|
var newSelection = SelectionUtils.SelectActorsOnScreen(World, worldRenderer, new HashSet<string> { s.Class }, eligiblePlayers);
|
||||||
|
|
||||||
World.Selection.Combine(World, newSelection, true, false);
|
World.Selection.Combine(World, newSelection, true, false);
|
||||||
}
|
}
|
||||||
@@ -158,7 +151,7 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
*/
|
*/
|
||||||
if (isDragging && (uog.ClearSelectionOnLeftClick || IsValidDragbox))
|
if (isDragging && (uog.ClearSelectionOnLeftClick || IsValidDragbox))
|
||||||
{
|
{
|
||||||
var newSelection = SelectActorsInBoxWithDeadzone(World, dragStart, mousePos, mi.Modifiers);
|
var newSelection = SelectionUtils.SelectActorsInBoxWithDeadzone(World, dragStart, mousePos, mi.Modifiers);
|
||||||
World.Selection.Combine(World, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == mousePos);
|
World.Selection.Combine(World, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == mousePos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -233,128 +226,5 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
return World.OrderGenerator.GetCursor(World, cell, worldPixel, mi);
|
return World.OrderGenerator.GetCursor(World, cell, worldPixel, mi);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool HandleKeyPress(KeyInput e)
|
|
||||||
{
|
|
||||||
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(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())
|
|
||||||
TextNotificationsManager.AddFeedbackLine("Selected across screen.");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Select actors in the world that have highest selection priority
|
|
||||||
ownUnitsOnScreen = SelectActorsInWorld(World, null, eligiblePlayers).SubsetWithHighestSelectionPriority(e.Modifiers).ToList();
|
|
||||||
TextNotificationsManager.AddFeedbackLine("Selected across map.");
|
|
||||||
}
|
|
||||||
|
|
||||||
World.Selection.Combine(World, ownUnitsOnScreen, false, false);
|
|
||||||
|
|
||||||
Game.Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Sounds", ClickSound, null);
|
|
||||||
}
|
|
||||||
else if (SelectSameTypeKey.IsActivatedBy(e) && !World.IsGameOver)
|
|
||||||
{
|
|
||||||
if (!World.Selection.Actors.Any())
|
|
||||||
{
|
|
||||||
TextNotificationsManager.AddFeedbackLine("Nothing selected.");
|
|
||||||
Game.Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Sounds", ClickDisabledSound, null);
|
|
||||||
|
|
||||||
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 = ownedActors
|
|
||||||
.Select(a => a.Trait<ISelectable>().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, eligiblePlayers).ToList();
|
|
||||||
|
|
||||||
// Check if selecting actors on the screen has selected new units
|
|
||||||
if (newSelection.Count > World.Selection.Actors.Count())
|
|
||||||
TextNotificationsManager.AddFeedbackLine("Selected across screen.");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Select actors in the world that have the same selection class as one of the already selected actors
|
|
||||||
newSelection = SelectActorsInWorld(World, selectedClasses, eligiblePlayers).ToList();
|
|
||||||
TextNotificationsManager.AddFeedbackLine("Selected across map.");
|
|
||||||
}
|
|
||||||
|
|
||||||
World.Selection.Combine(World, newSelection, true, false);
|
|
||||||
|
|
||||||
Game.Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Sounds", ClickSound, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
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, players, selectionClasses);
|
|
||||||
}
|
|
||||||
|
|
||||||
static IEnumerable<Actor> SelectActorsInWorld(World world, IEnumerable<string> selectionClasses, IEnumerable<Player> players)
|
|
||||||
{
|
|
||||||
return SelectActorsByOwnerAndSelectionClass(world.Actors.Where(a => a.IsInWorld), players, selectionClasses);
|
|
||||||
}
|
|
||||||
|
|
||||||
static IEnumerable<Actor> SelectActorsByOwnerAndSelectionClass(IEnumerable<Actor> actors, IEnumerable<Player> owners, IEnumerable<string> selectionClasses)
|
|
||||||
{
|
|
||||||
return actors.Where(a =>
|
|
||||||
{
|
|
||||||
if (!owners.Contains(a.Owner))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
var s = a.TraitOrDefault<ISelectable>();
|
|
||||||
|
|
||||||
// selectionClasses == null means that units, that meet all other criteria, get selected
|
|
||||||
return s != null && (selectionClasses == null || selectionClasses.Contains(s.Class));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
static IEnumerable<Actor> SelectHighestPriorityActorAtPoint(World world, int2 a, Modifiers modifiers)
|
|
||||||
{
|
|
||||||
var selected = world.ScreenMap.ActorsAtMouse(a)
|
|
||||||
.Where(x => x.Actor.Info.HasTraitInfo<ISelectableInfo>() && (x.Actor.Owner.IsAlliedWith(world.RenderPlayer) || !world.FogObscures(x.Actor)))
|
|
||||||
.WithHighestSelectionPriority(a, modifiers);
|
|
||||||
|
|
||||||
if (selected != null)
|
|
||||||
yield return selected;
|
|
||||||
}
|
|
||||||
|
|
||||||
static IEnumerable<Actor> SelectActorsInBoxWithDeadzone(World world, int2 a, int2 b, Modifiers modifiers)
|
|
||||||
{
|
|
||||||
// For dragboxes that are too small, shrink the dragbox to a single point (point b)
|
|
||||||
if ((a - b).Length <= Game.Settings.Game.SelectionDeadzone)
|
|
||||||
a = b;
|
|
||||||
|
|
||||||
if (a == b)
|
|
||||||
return SelectHighestPriorityActorAtPoint(world, a, modifiers);
|
|
||||||
|
|
||||||
return world.ScreenMap.ActorsInMouseBox(a, b)
|
|
||||||
.Select(x => x.Actor)
|
|
||||||
.Where(x => x.Info.HasTraitInfo<ISelectableInfo>() && (x.Owner.IsAlliedWith(world.RenderPlayer) || !world.FogObscures(x)))
|
|
||||||
.SubsetWithHighestSelectionPriority(modifiers);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ Container@INGAME_ROOT:
|
|||||||
TakeScreenshotKey: TakeScreenshot
|
TakeScreenshotKey: TakeScreenshot
|
||||||
MuteAudioKey: ToggleMute
|
MuteAudioKey: ToggleMute
|
||||||
LogicKeyListener@WORLD_KEYHANDLER:
|
LogicKeyListener@WORLD_KEYHANDLER:
|
||||||
Logic: CycleBasesHotkeyLogic, CycleProductionActorsHotkeyLogic, CycleHarvestersHotkeyLogic, JumpToLastEventHotkeyLogic, JumpToSelectedActorsHotkeyLogic, ResetZoomHotkeyLogic, TogglePlayerStanceColorHotkeyLogic, CycleStatusBarsHotkeyLogic, PauseHotkeyLogic, RemoveFromControlGroupHotkeyLogic
|
Logic: CycleBasesHotkeyLogic, CycleProductionActorsHotkeyLogic, CycleHarvestersHotkeyLogic, JumpToLastEventHotkeyLogic, JumpToSelectedActorsHotkeyLogic, ResetZoomHotkeyLogic, TogglePlayerStanceColorHotkeyLogic, CycleStatusBarsHotkeyLogic, PauseHotkeyLogic, RemoveFromControlGroupHotkeyLogic, SelectUnitsByTypeHotkeyLogic, SelectAllUnitsHotkeyLogic
|
||||||
RemoveFromControlGroupKey: RemoveFromControlGroup
|
RemoveFromControlGroupKey: RemoveFromControlGroup
|
||||||
CycleBasesKey: CycleBase
|
CycleBasesKey: CycleBase
|
||||||
CycleProductionActorsKey: CycleProductionBuildings
|
CycleProductionActorsKey: CycleProductionBuildings
|
||||||
@@ -21,6 +21,8 @@ Container@INGAME_ROOT:
|
|||||||
TogglePlayerStanceColorKey: TogglePlayerStanceColor
|
TogglePlayerStanceColorKey: TogglePlayerStanceColor
|
||||||
CycleStatusBarsKey: CycleStatusBars
|
CycleStatusBarsKey: CycleStatusBars
|
||||||
PauseKey: Pause
|
PauseKey: Pause
|
||||||
|
SelectAllUnitsKey: SelectAllUnits
|
||||||
|
SelectUnitsByTypeKey: SelectUnitsByType
|
||||||
Container@WORLD_ROOT:
|
Container@WORLD_ROOT:
|
||||||
Children:
|
Children:
|
||||||
LogicTicker@DISCONNECT_WATCHER:
|
LogicTicker@DISCONNECT_WATCHER:
|
||||||
@@ -39,8 +41,6 @@ Container@INGAME_ROOT:
|
|||||||
WorldInteractionController@INTERACTION_CONTROLLER:
|
WorldInteractionController@INTERACTION_CONTROLLER:
|
||||||
Width: WINDOW_RIGHT
|
Width: WINDOW_RIGHT
|
||||||
Height: WINDOW_BOTTOM
|
Height: WINDOW_BOTTOM
|
||||||
SelectAllKey: SelectAllUnits
|
|
||||||
SelectSameTypeKey: SelectUnitsByType
|
|
||||||
Container@PLAYER_ROOT:
|
Container@PLAYER_ROOT:
|
||||||
Container@MENU_ROOT:
|
Container@MENU_ROOT:
|
||||||
TooltipContainer@TOOLTIP_CONTAINER:
|
TooltipContainer@TOOLTIP_CONTAINER:
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ Container@INGAME_ROOT:
|
|||||||
TakeScreenshotKey: TakeScreenshot
|
TakeScreenshotKey: TakeScreenshot
|
||||||
MuteAudioKey: ToggleMute
|
MuteAudioKey: ToggleMute
|
||||||
LogicKeyListener@WORLD_KEYHANDLER:
|
LogicKeyListener@WORLD_KEYHANDLER:
|
||||||
Logic: CycleBasesHotkeyLogic, CycleProductionActorsHotkeyLogic, CycleHarvestersHotkeyLogic, JumpToLastEventHotkeyLogic, JumpToSelectedActorsHotkeyLogic, ResetZoomHotkeyLogic, TogglePlayerStanceColorHotkeyLogic, CycleStatusBarsHotkeyLogic, PauseHotkeyLogic, RemoveFromControlGroupHotkeyLogic
|
Logic: CycleBasesHotkeyLogic, CycleProductionActorsHotkeyLogic, CycleHarvestersHotkeyLogic, JumpToLastEventHotkeyLogic, JumpToSelectedActorsHotkeyLogic, ResetZoomHotkeyLogic, TogglePlayerStanceColorHotkeyLogic, CycleStatusBarsHotkeyLogic, PauseHotkeyLogic, RemoveFromControlGroupHotkeyLogic, SelectUnitsByTypeHotkeyLogic, SelectAllUnitsHotkeyLogic
|
||||||
RemoveFromControlGroupKey: RemoveFromControlGroup
|
RemoveFromControlGroupKey: RemoveFromControlGroup
|
||||||
CycleBasesKey: CycleBase
|
CycleBasesKey: CycleBase
|
||||||
CycleProductionActorsKey: CycleProductionBuildings
|
CycleProductionActorsKey: CycleProductionBuildings
|
||||||
@@ -21,6 +21,8 @@ Container@INGAME_ROOT:
|
|||||||
TogglePlayerStanceColorKey: TogglePlayerStanceColor
|
TogglePlayerStanceColorKey: TogglePlayerStanceColor
|
||||||
CycleStatusBarsKey: CycleStatusBars
|
CycleStatusBarsKey: CycleStatusBars
|
||||||
PauseKey: Pause
|
PauseKey: Pause
|
||||||
|
SelectAllUnitsKey: SelectAllUnits
|
||||||
|
SelectUnitsByTypeKey: SelectUnitsByType
|
||||||
Container@WORLD_ROOT:
|
Container@WORLD_ROOT:
|
||||||
Logic: LoadIngamePerfLogic
|
Logic: LoadIngamePerfLogic
|
||||||
Children:
|
Children:
|
||||||
@@ -37,8 +39,6 @@ Container@INGAME_ROOT:
|
|||||||
WorldInteractionController@INTERACTION_CONTROLLER:
|
WorldInteractionController@INTERACTION_CONTROLLER:
|
||||||
Width: WINDOW_RIGHT
|
Width: WINDOW_RIGHT
|
||||||
Height: WINDOW_BOTTOM
|
Height: WINDOW_BOTTOM
|
||||||
SelectAllKey: SelectAllUnits
|
|
||||||
SelectSameTypeKey: SelectUnitsByType
|
|
||||||
ViewportController:
|
ViewportController:
|
||||||
Width: WINDOW_RIGHT
|
Width: WINDOW_RIGHT
|
||||||
Height: WINDOW_BOTTOM
|
Height: WINDOW_BOTTOM
|
||||||
|
|||||||
Reference in New Issue
Block a user