selection persists across OG changes

This commit is contained in:
Chris Forbes
2010-02-08 19:05:49 +13:00
parent 853f9ae6d5
commit 37af0f2f04
4 changed files with 45 additions and 53 deletions

View File

@@ -13,6 +13,7 @@ namespace OpenRa
public class Controller : IHandleInput public class Controller : IHandleInput
{ {
public IOrderGenerator orderGenerator; public IOrderGenerator orderGenerator;
public Selection selection = new Selection();
readonly Func<Modifiers> GetModifierKeys; readonly Func<Modifiers> GetModifierKeys;
@@ -22,10 +23,7 @@ namespace OpenRa
CancelInputMode(); CancelInputMode();
} }
public void CancelInputMode() public void CancelInputMode() { orderGenerator = new UnitOrderGenerator(); }
{
orderGenerator = new UnitOrderGenerator(new Actor[] { });
}
public bool ToggleInputMode<T>() where T : IOrderGenerator, new() public bool ToggleInputMode<T>() where T : IOrderGenerator, new()
{ {
@@ -83,7 +81,7 @@ namespace OpenRa
if (orderGenerator is UnitOrderGenerator) if (orderGenerator is UnitOrderGenerator)
{ {
var newSelection = world.SelectActorsInBox(Game.CellSize * dragStart, Game.CellSize * xy); var newSelection = world.SelectActorsInBox(Game.CellSize * dragStart, Game.CellSize * xy);
CombineSelection(world, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy); selection.Combine(world, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy);
} }
dragStart = dragEnd = xy; dragStart = dragEnd = xy;
@@ -98,29 +96,6 @@ namespace OpenRa
return true; return true;
} }
void CombineSelection(World world, IEnumerable<Actor> newSelection, bool isCombine, bool isClick)
{
var oldSelection = (orderGenerator is UnitOrderGenerator)
? (orderGenerator as UnitOrderGenerator).selection : new Actor[] { }.AsEnumerable();
if (isClick)
{
var adjNewSelection = newSelection.Take(1); /* todo: select BEST, not FIRST */
orderGenerator = new UnitOrderGenerator(isCombine
? oldSelection.SymmetricDifference(adjNewSelection) : adjNewSelection);
}
else
orderGenerator = new UnitOrderGenerator(isCombine
? oldSelection.Union(newSelection) : newSelection);
var voicedUnit = ((UnitOrderGenerator)orderGenerator).selection
.Where(a => a.traits.Contains<Unit>()
&& a.Owner == world.LocalPlayer)
.FirstOrDefault();
Sound.PlayVoice("Select", voicedUnit);
}
public Pair<float2, float2>? SelectionBox public Pair<float2, float2>? SelectionBox
{ {
get get
@@ -158,20 +133,17 @@ namespace OpenRa
public void DoControlGroup(World world, int group, Modifiers mods) public void DoControlGroup(World world, int group, Modifiers mods)
{ {
var uog = orderGenerator as UnitOrderGenerator;
if (uog == null) return;
if (mods.HasModifier(Modifiers.Ctrl)) if (mods.HasModifier(Modifiers.Ctrl))
{ {
if (!uog.selection.Any()) if (!selection.Actors.Any())
return; return;
controlGroups[group].Clear(); controlGroups[group].Clear();
for (var i = 0; i < 10; i++) /* all control groups */ for (var i = 0; i < 10; i++) /* all control groups */
controlGroups[i].RemoveAll(a => uog.selection.Contains(a)); controlGroups[i].RemoveAll(a => selection.Actors.Contains(a));
controlGroups[group].AddRange(uog.selection); controlGroups[group].AddRange(selection.Actors);
return; return;
} }
@@ -181,7 +153,8 @@ namespace OpenRa
return; return;
} }
CombineSelection(world, controlGroups[group], mods.HasModifier(Modifiers.Shift), false); selection.Combine(world, controlGroups[group],
mods.HasModifier(Modifiers.Shift), false);
} }
public int? GetControlGroupForActor(Actor a) public int? GetControlGroupForActor(Actor a)
@@ -191,4 +164,33 @@ namespace OpenRa
.FirstOrDefault(); .FirstOrDefault();
} }
} }
public class Selection
{
List<Actor> actors = new List<Actor>();
public void Combine(World world, IEnumerable<Actor> newSelection, bool isCombine, bool isClick)
{
var oldSelection = actors.AsEnumerable();
if (isClick)
{
var adjNewSelection = newSelection.Take(1); /* todo: select BEST, not FIRST */
actors = (isCombine ? oldSelection.SymmetricDifference(adjNewSelection) : adjNewSelection).ToList();
}
else
actors = (isCombine ? oldSelection.Union(newSelection) : newSelection).ToList();
var voicedUnit = actors.FirstOrDefault(a => a.traits.Contains<Unit>() && a.Owner == world.LocalPlayer);
Sound.PlayVoice("Select", voicedUnit);
}
public IEnumerable<Actor> Actors { get { return actors; } }
public void Clear() { actors = new List<Actor>(); }
public void Tick(World world)
{
actors.RemoveAll(a => !a.IsInWorld);
}
}
} }

View File

@@ -154,8 +154,8 @@ namespace OpenRa
if (orderManager.IsReadyForNextFrame) if (orderManager.IsReadyForNextFrame)
{ {
orderManager.Tick(world); orderManager.Tick(world);
if (controller.orderGenerator != null)
controller.orderGenerator.Tick(world); controller.orderGenerator.Tick(world);
controller.selection.Tick(world);
world.Tick(); world.Tick();
} }

View File

@@ -8,16 +8,9 @@ namespace OpenRa.Orders
{ {
class UnitOrderGenerator : IOrderGenerator class UnitOrderGenerator : IOrderGenerator
{ {
public readonly List<Actor> selection;
public UnitOrderGenerator( IEnumerable<Actor> selected )
{
selection = selected.ToList();
}
public IEnumerable<Order> Order( World world, int2 xy, MouseInput mi ) public IEnumerable<Order> Order( World world, int2 xy, MouseInput mi )
{ {
foreach( var unit in selection ) foreach( var unit in Game.controller.selection.Actors )
{ {
var ret = unit.Order( xy, mi ); var ret = unit.Order( xy, mi );
if( ret != null ) if( ret != null )
@@ -25,14 +18,11 @@ namespace OpenRa.Orders
} }
} }
public void Tick( World world ) public void Tick( World world ) {}
{
selection.RemoveAll(a => !a.IsInWorld);
}
public void Render( World world ) public void Render( World world )
{ {
foreach( var a in selection ) foreach( var a in Game.controller.selection.Actors )
world.WorldRenderer.DrawSelectionBox( a, Color.White, true ); world.WorldRenderer.DrawSelectionBox( a, Color.White, true );
} }

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using OpenRa.Graphics; using OpenRa.Graphics;
using OpenRa.Orders; using OpenRa.Orders;
@@ -27,8 +28,7 @@ namespace OpenRa.Traits
public IEnumerable<Renderable> Render(Actor self) public IEnumerable<Renderable> Render(Actor self)
{ {
var uog = Game.controller.orderGenerator as UnitOrderGenerator; if (self.Owner == self.World.LocalPlayer && Game.controller.selection.Actors.Contains(self))
if (uog != null && self.Owner == self.World.LocalPlayer && uog.selection.Contains(self))
yield return Util.Centered(self, yield return Util.Centered(self,
anim.Image, Util.CenterOfCell(rallyPoint)); anim.Image, Util.CenterOfCell(rallyPoint));
} }