Move Interactable and Selectable to Mods.Common.

This commit is contained in:
Paul Chote
2020-02-29 11:29:06 +00:00
committed by atlimit8
parent c5139fb6c2
commit 73a78eadb1
9 changed files with 50 additions and 27 deletions

View File

@@ -70,7 +70,7 @@ namespace OpenRA.Orders
bool useSelect; bool useSelect;
if (Game.Settings.Game.UseClassicMouseStyle && !InputOverridesSelection(world, worldPixel, mi)) if (Game.Settings.Game.UseClassicMouseStyle && !InputOverridesSelection(world, worldPixel, mi))
useSelect = target.Type == TargetType.Actor && target.Actor.Info.HasTraitInfo<SelectableInfo>(); useSelect = target.Type == TargetType.Actor && target.Actor.Info.HasTraitInfo<ISelectableInfo>();
else else
{ {
var ordersWithCursor = world.Selection.Actors var ordersWithCursor = world.Selection.Actors
@@ -81,7 +81,7 @@ namespace OpenRA.Orders
if (cursorOrder != null) if (cursorOrder != null)
return cursorOrder.Cursor; return cursorOrder.Cursor;
useSelect = target.Type == TargetType.Actor && target.Actor.Info.HasTraitInfo<SelectableInfo>() && useSelect = target.Type == TargetType.Actor && target.Actor.Info.HasTraitInfo<ISelectableInfo>() &&
(mi.Modifiers.HasModifier(Modifiers.Shift) || !world.Selection.Actors.Any()); (mi.Modifiers.HasModifier(Modifiers.Shift) || !world.Selection.Actors.Any());
} }

View File

@@ -20,7 +20,7 @@ namespace OpenRA.Traits
{ {
public static int SelectionPriority(this ActorInfo a, Modifiers modifiers) public static int SelectionPriority(this ActorInfo a, Modifiers modifiers)
{ {
var selectableInfo = a.TraitInfoOrDefault<SelectableInfo>(); var selectableInfo = a.TraitInfoOrDefault<ISelectableInfo>();
return selectableInfo != null ? BaseSelectionPriority(selectableInfo, modifiers) : int.MinValue; return selectableInfo != null ? BaseSelectionPriority(selectableInfo, modifiers) : int.MinValue;
} }
@@ -28,7 +28,7 @@ namespace OpenRA.Traits
public static int SelectionPriority(this Actor a, Modifiers modifiers) public static int SelectionPriority(this Actor a, Modifiers modifiers)
{ {
var info = a.Info.TraitInfo<SelectableInfo>(); var info = a.Info.TraitInfo<ISelectableInfo>();
var basePriority = BaseSelectionPriority(info, modifiers); var basePriority = BaseSelectionPriority(info, modifiers);
var viewer = (a.World.LocalPlayer == null || a.World.LocalPlayer.Spectating) ? a.World.RenderPlayer : a.World.LocalPlayer; var viewer = (a.World.LocalPlayer == null || a.World.LocalPlayer.Spectating) ? a.World.RenderPlayer : a.World.LocalPlayer;
@@ -47,7 +47,7 @@ namespace OpenRA.Traits
} }
} }
static int BaseSelectionPriority(SelectableInfo info, Modifiers modifiers) static int BaseSelectionPriority(ISelectableInfo info, Modifiers modifiers)
{ {
var priority = info.Priority; var priority = info.Priority;

View File

@@ -440,6 +440,22 @@ namespace OpenRA.Traits
bool SpatiallyPartitionable { get; } bool SpatiallyPartitionable { get; }
} }
[Flags]
public enum SelectionPriorityModifiers
{
None = 0,
Ctrl = 1,
Alt = 2
}
[RequireExplicitImplementation]
public interface ISelectableInfo : ITraitInfoInterface
{
int Priority { get; }
SelectionPriorityModifiers PriorityModifiers { get; }
string Voice { get; }
}
public interface ISelection public interface ISelection
{ {
int Hash { get; } int Hash { get; }

View File

@@ -11,6 +11,7 @@
using System; using System;
using System.Linq; using System.Linq;
using OpenRA.Mods.Common.Traits;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Lint namespace OpenRA.Mods.Common.Lint

View File

@@ -12,8 +12,9 @@
using System.Linq; using System.Linq;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Primitives; using OpenRA.Primitives;
using OpenRA.Traits;
namespace OpenRA.Traits namespace OpenRA.Mods.Common.Traits
{ {
[Desc("Used to enable mouse interaction on actors that are not Selectable.")] [Desc("Used to enable mouse interaction on actors that are not Selectable.")]
public class InteractableInfo : ITraitInfo, IMouseBoundsInfo, IDecorationBoundsInfo public class InteractableInfo : ITraitInfo, IMouseBoundsInfo, IDecorationBoundsInfo

View File

@@ -10,19 +10,12 @@
#endregion #endregion
using System; using System;
using OpenRA.Traits;
namespace OpenRA.Traits namespace OpenRA.Mods.Common.Traits
{ {
[Flags]
public enum SelectionPriorityModifiers
{
None = 0,
Ctrl = 1,
Alt = 2
}
[Desc("This actor is selectable. Defines bounds of selectable area, selection class, selection priority and selection priority modifiers.")] [Desc("This actor is selectable. Defines bounds of selectable area, selection class, selection priority and selection priority modifiers.")]
public class SelectableInfo : InteractableInfo public class SelectableInfo : InteractableInfo, ISelectableInfo
{ {
public readonly int Priority = 10; public readonly int Priority = 10;
@@ -40,18 +33,24 @@ namespace OpenRA.Traits
public readonly string Voice = "Select"; public readonly string Voice = "Select";
public override object Create(ActorInitializer init) { return new Selectable(init.Self, this); } public override object Create(ActorInitializer init) { return new Selectable(init.Self, this); }
int ISelectableInfo.Priority { get { return Priority; } }
SelectionPriorityModifiers ISelectableInfo.PriorityModifiers { get { return PriorityModifiers; } }
string ISelectableInfo.Voice { get { return Voice; } }
} }
public class Selectable : Interactable public class Selectable : Interactable, ISelectable
{ {
public readonly string Class = null; readonly string selectionClass = null;
public readonly SelectableInfo Info; public readonly SelectableInfo Info;
public Selectable(Actor self, SelectableInfo info) public Selectable(Actor self, SelectableInfo info)
: base(info) : base(info)
{ {
Class = string.IsNullOrEmpty(info.Class) ? self.Info.Name : info.Class; selectionClass = string.IsNullOrEmpty(info.Class) ? self.Info.Name : info.Class;
Info = info; Info = info;
} }
string ISelectable.Class { get { return selectionClass; } }
} }
} }

View File

@@ -123,13 +123,12 @@ namespace OpenRA.Mods.Common.Traits
// Play the selection voice from one of the selected actors // Play the selection voice from one of the selected actors
// TODO: This probably should only be considering the newly selected actors // TODO: This probably should only be considering the newly selected actors
// TODO: Ship this into an INotifySelection trait to remove the engine dependency on Selectable
foreach (var actor in actors) foreach (var actor in actors)
{ {
if (actor.Owner != world.LocalPlayer || !actor.IsInWorld) if (actor.Owner != world.LocalPlayer || !actor.IsInWorld)
continue; continue;
var selectable = actor.Info.TraitInfoOrDefault<SelectableInfo>(); var selectable = actor.Info.TraitInfoOrDefault<ISelectableInfo>();
if (selectable == null || !actor.HasVoice(selectable.Voice)) if (selectable == null || !actor.HasVoice(selectable.Voice))
continue; continue;

View File

@@ -636,4 +636,10 @@ namespace OpenRA.Mods.Common.Traits
{ {
void NotifyTimerExpired(Actor self); void NotifyTimerExpired(Actor self);
} }
[RequireExplicitImplementation]
public interface ISelectable
{
string Class { get; }
}
} }

View File

@@ -13,6 +13,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Mods.Common.Effects; using OpenRA.Mods.Common.Effects;
using OpenRA.Mods.Common.Traits;
using OpenRA.Orders; using OpenRA.Orders;
using OpenRA.Primitives; using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
@@ -127,7 +128,7 @@ namespace OpenRA.Mods.Common.Widgets
if (!IsValidDragbox && World.Selection.Actors.Any() && !multiClick) if (!IsValidDragbox && World.Selection.Actors.Any() && !multiClick)
{ {
var selectableActor = World.ScreenMap.ActorsAtMouse(mousePos).Select(a => a.Actor).Any(x => var selectableActor = World.ScreenMap.ActorsAtMouse(mousePos).Select(a => a.Actor).Any(x =>
x.Info.HasTraitInfo<SelectableInfo>() && (x.Owner.IsAlliedWith(World.RenderPlayer) || !World.FogObscures(x))); x.Info.HasTraitInfo<ISelectableInfo>() && (x.Owner.IsAlliedWith(World.RenderPlayer) || !World.FogObscures(x)));
if (!selectableActor || uog.InputOverridesSelection(World, mousePos, mi)) if (!selectableActor || uog.InputOverridesSelection(World, mousePos, mi))
{ {
@@ -153,7 +154,7 @@ namespace OpenRA.Mods.Common.Widgets
if (unit != null && eligiblePlayers.Contains(unit.Owner)) if (unit != null && eligiblePlayers.Contains(unit.Owner))
{ {
var s = unit.TraitOrDefault<Selectable>(); var s = unit.TraitOrDefault<ISelectable>();
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
@@ -305,7 +306,7 @@ namespace OpenRA.Mods.Common.Widgets
// Get all the selected actors' selection classes // Get all the selected actors' selection classes
var selectedClasses = ownedActors var selectedClasses = ownedActors
.Select(a => a.Trait<Selectable>().Class) .Select(a => a.Trait<ISelectable>().Class)
.ToHashSet(); .ToHashSet();
// Select actors on the screen that have the same selection class as one of the already selected actors // Select actors on the screen that have the same selection class as one of the already selected actors
@@ -346,7 +347,7 @@ namespace OpenRA.Mods.Common.Widgets
if (!owners.Contains(a.Owner)) if (!owners.Contains(a.Owner))
return false; return false;
var s = a.TraitOrDefault<Selectable>(); var s = a.TraitOrDefault<ISelectable>();
// selectionClasses == 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)); return s != null && (selectionClasses == null || selectionClasses.Contains(s.Class));
@@ -356,7 +357,7 @@ namespace OpenRA.Mods.Common.Widgets
static IEnumerable<Actor> SelectHighestPriorityActorAtPoint(World world, int2 a, Modifiers modifiers) static IEnumerable<Actor> SelectHighestPriorityActorAtPoint(World world, int2 a, Modifiers modifiers)
{ {
var selected = world.ScreenMap.ActorsAtMouse(a) var selected = world.ScreenMap.ActorsAtMouse(a)
.Where(x => x.Actor.Info.HasTraitInfo<SelectableInfo>() && (x.Actor.Owner.IsAlliedWith(world.RenderPlayer) || !world.FogObscures(x.Actor))) .Where(x => x.Actor.Info.HasTraitInfo<ISelectableInfo>() && (x.Actor.Owner.IsAlliedWith(world.RenderPlayer) || !world.FogObscures(x.Actor)))
.WithHighestSelectionPriority(a, modifiers); .WithHighestSelectionPriority(a, modifiers);
if (selected != null) if (selected != null)
@@ -374,7 +375,7 @@ namespace OpenRA.Mods.Common.Widgets
return world.ScreenMap.ActorsInMouseBox(a, b) return world.ScreenMap.ActorsInMouseBox(a, b)
.Select(x => x.Actor) .Select(x => x.Actor)
.Where(x => x.Info.HasTraitInfo<SelectableInfo>() && (x.Owner.IsAlliedWith(world.RenderPlayer) || !world.FogObscures(x))) .Where(x => x.Info.HasTraitInfo<ISelectableInfo>() && (x.Owner.IsAlliedWith(world.RenderPlayer) || !world.FogObscures(x)))
.SubsetWithHighestSelectionPriority(modifiers); .SubsetWithHighestSelectionPriority(modifiers);
} }
} }