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 IOrderGenerator orderGenerator;
public Selection selection = new Selection();
readonly Func<Modifiers> GetModifierKeys;
@@ -22,10 +23,7 @@ namespace OpenRa
CancelInputMode();
}
public void CancelInputMode()
{
orderGenerator = new UnitOrderGenerator(new Actor[] { });
}
public void CancelInputMode() { orderGenerator = new UnitOrderGenerator(); }
public bool ToggleInputMode<T>() where T : IOrderGenerator, new()
{
@@ -83,7 +81,7 @@ namespace OpenRa
if (orderGenerator is UnitOrderGenerator)
{
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;
@@ -98,29 +96,6 @@ namespace OpenRa
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
{
get
@@ -158,20 +133,17 @@ namespace OpenRa
public void DoControlGroup(World world, int group, Modifiers mods)
{
var uog = orderGenerator as UnitOrderGenerator;
if (uog == null) return;
if (mods.HasModifier(Modifiers.Ctrl))
{
if (!uog.selection.Any())
if (!selection.Actors.Any())
return;
controlGroups[group].Clear();
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;
}
@@ -181,7 +153,8 @@ namespace OpenRa
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)
@@ -191,4 +164,33 @@ namespace OpenRa
.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

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

View File

@@ -8,16 +8,9 @@ namespace OpenRa.Orders
{
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 )
{
foreach( var unit in selection )
foreach( var unit in Game.controller.selection.Actors )
{
var ret = unit.Order( xy, mi );
if( ret != null )
@@ -25,14 +18,11 @@ namespace OpenRa.Orders
}
}
public void Tick( World world )
{
selection.RemoveAll(a => !a.IsInWorld);
}
public void Tick( 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 );
}

View File

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