routing modifier keys where they need to be

This commit is contained in:
Chris Forbes
2009-12-16 11:31:53 +13:00
parent 6d59339b84
commit 5bf3e05f03
18 changed files with 100 additions and 84 deletions

View File

@@ -77,7 +77,7 @@ namespace OpenRa.Game
return traits.WithInterface<Traits.IRender>().SelectMany( x => x.Render( this ) ); return traits.WithInterface<Traits.IRender>().SelectMany( x => x.Render( this ) );
} }
public Order Order( int2 xy, bool lmb ) public Order Order( int2 xy, MouseInput mi )
{ {
if (Owner != Game.LocalPlayer) if (Owner != Game.LocalPlayer)
return null; return null;
@@ -91,7 +91,7 @@ namespace OpenRa.Game
underCursor = null; underCursor = null;
return traits.WithInterface<Traits.IOrder>() return traits.WithInterface<Traits.IOrder>()
.Select( x => x.IssueOrder( this, xy, lmb, underCursor ) ) .Select( x => x.IssueOrder( this, xy, mi, underCursor ) )
.FirstOrDefault( x => x != null ); .FirstOrDefault( x => x != null );
} }

View File

@@ -331,7 +331,7 @@ namespace OpenRa.Game
return false; return false;
if (mi.Event == MouseInputEvent.Down) if (mi.Event == MouseInputEvent.Down)
action(mi.Button == MouseButtons.Left); action(mi.Button == MouseButton.Left);
return true; return true;
} }

View File

@@ -6,6 +6,7 @@ using OpenRa.Game.GameRules;
using OpenRa.Game.Graphics; using OpenRa.Game.Graphics;
using OpenRa.Game.Traits; using OpenRa.Game.Traits;
using IjwFramework.Collections; using IjwFramework.Collections;
using System;
namespace OpenRa.Game namespace OpenRa.Game
{ {
@@ -13,13 +14,20 @@ namespace OpenRa.Game
{ {
public IOrderGenerator orderGenerator; public IOrderGenerator orderGenerator;
readonly Func<Modifiers> GetModifierKeys;
public Controller(Func<Modifiers> getModifierKeys)
{
GetModifierKeys = getModifierKeys;
}
List<Order> recentOrders = new List<Order>(); List<Order> recentOrders = new List<Order>();
void ApplyOrders(float2 xy, bool left) void ApplyOrders(float2 xy, MouseInput mi)
{ {
var doVoice = null as Actor; var doVoice = null as Actor;
if (orderGenerator != null) if (orderGenerator != null)
foreach (var order in orderGenerator.Order(xy.ToInt2(), left)) foreach (var order in orderGenerator.Order(xy.ToInt2(), mi))
{ {
AddOrder( order ); AddOrder( order );
if (order.Subject != null && order.Player == Game.LocalPlayer) if (order.Subject != null && order.Player == Game.LocalPlayer)
@@ -34,18 +42,10 @@ namespace OpenRa.Game
public List<Order> GetRecentOrders( bool imm ) public List<Order> GetRecentOrders( bool imm )
{ {
if (imm) Func<Order, bool> p = o => o.IsImmediate ^ !imm;
{ var result = recentOrders.Where(p).ToList();
var result = recentOrders.Where(o => o.IsImmediate).ToList(); recentOrders.RemoveAll(o => p(o)); // ffs.
recentOrders.RemoveAll(o => o.IsImmediate); return result;
return result;
}
else
{
var result = recentOrders.Where(o => !o.IsImmediate).ToList();
recentOrders.RemoveAll(o => !o.IsImmediate);
return result;
}
} }
float2 dragStart, dragEnd; float2 dragStart, dragEnd;
@@ -53,32 +53,32 @@ namespace OpenRa.Game
{ {
var xy = Game.viewport.ViewToWorld(mi); var xy = Game.viewport.ViewToWorld(mi);
if (mi.Button == MouseButtons.Left && mi.Event == MouseInputEvent.Down) if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down)
{ {
if (!(orderGenerator is PlaceBuilding)) if (!(orderGenerator is PlaceBuilding))
dragStart = dragEnd = xy; dragStart = dragEnd = xy;
ApplyOrders(xy, true); ApplyOrders(xy, mi);
} }
if (mi.Button == MouseButtons.Left && mi.Event == MouseInputEvent.Move) if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Move)
dragEnd = xy; dragEnd = xy;
if (mi.Button == MouseButtons.Left && mi.Event == MouseInputEvent.Up) if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Up)
{ {
if (!(orderGenerator is PlaceBuilding)) if (!(orderGenerator is PlaceBuilding))
{ {
var newSelection = Game.SelectActorsInBox(Game.CellSize * dragStart, Game.CellSize * xy); var newSelection = Game.SelectActorsInBox(Game.CellSize * dragStart, Game.CellSize * xy);
CombineSelection(newSelection, mi.Modifiers.HasModifier(Keys.Shift), dragStart == xy); CombineSelection(newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy);
} }
dragStart = dragEnd = xy; dragStart = dragEnd = xy;
} }
if (mi.Button == MouseButtons.None && mi.Event == MouseInputEvent.Move) if (mi.Button == MouseButton.None && mi.Event == MouseInputEvent.Move)
dragStart = dragEnd = xy; dragStart = dragEnd = xy;
if (mi.Button == MouseButtons.Right && mi.Event == MouseInputEvent.Down) if (mi.Button == MouseButton.Right && mi.Event == MouseInputEvent.Down)
ApplyOrders(xy, false); ApplyOrders(xy, mi);
return true; return true;
} }
@@ -116,9 +116,11 @@ namespace OpenRa.Game
public Cursor ChooseCursor() public Cursor ChooseCursor()
{ {
var c = (orderGenerator is UnitOrderGenerator) ? orderGenerator.Order(dragEnd.ToInt2(), false) var mods = GetModifierKeys();
.Where( o => o.Validate() ) var c = (orderGenerator is UnitOrderGenerator) ? orderGenerator.Order(dragEnd.ToInt2(),
.Select(o => CursorForOrderString( o.OrderString, o.Subject, o.TargetLocation )) new MouseInput { Button = MouseButton.Right, Modifiers = mods })
.Where(o => o.Validate())
.Select(o => CursorForOrderString(o.OrderString, o.Subject, o.TargetLocation))
.FirstOrDefault(a => a != null) : null; .FirstOrDefault(a => a != null) : null;
return c ?? (Game.SelectActorsInBox(Game.CellSize * dragEnd, Game.CellSize * dragEnd).Any() ? Cursor.Select : Cursor.Default); return c ?? (Game.SelectActorsInBox(Game.CellSize * dragEnd, Game.CellSize * dragEnd).Any() ? Cursor.Select : Cursor.Default);
@@ -149,10 +151,10 @@ namespace OpenRa.Game
Cache<int, List<Actor>> cache = new Cache<int, List<Actor>>(_ => new List<Actor>()); Cache<int, List<Actor>> cache = new Cache<int, List<Actor>>(_ => new List<Actor>());
public void DoControlGroup(int group, Keys keys) public void DoControlGroup(int group, Modifiers mods)
{ {
var uog = orderGenerator as UnitOrderGenerator; var uog = orderGenerator as UnitOrderGenerator;
if (keys.HasModifier(Keys.Control)) if (mods.HasModifier(Modifiers.Ctrl))
{ {
if (uog == null || !uog.selection.Any()) if (uog == null || !uog.selection.Any())
return; return;
@@ -162,14 +164,14 @@ namespace OpenRa.Game
return; return;
} }
if (keys.HasModifier(Keys.Alt)) if (mods.HasModifier(Modifiers.Alt))
{ {
Game.viewport.Center(cache[group]); Game.viewport.Center(cache[group]);
return; return;
} }
if (uog == null) return; if (uog == null) return;
CombineSelection(cache[group], keys.HasModifier(Keys.Shift), false); CombineSelection(cache[group], mods.HasModifier(Modifiers.Shift), false);
} }
} }
} }

View File

@@ -12,7 +12,7 @@ namespace OpenRa.Game
return string.Format(fmt, args); return string.Format(fmt, args);
} }
public static bool HasModifier(this Keys k, Keys mod) public static bool HasModifier(this Modifiers k, Modifiers mod)
{ {
return (k & mod) == mod; return (k & mod) == mod;
} }

View File

@@ -8,6 +8,7 @@ using OpenRa.Game.GameRules;
using OpenRa.Game.Graphics; using OpenRa.Game.Graphics;
using OpenRa.Game.Support; using OpenRa.Game.Support;
using OpenRa.Game.Traits; using OpenRa.Game.Traits;
using System.Windows.Forms;
namespace OpenRa.Game namespace OpenRa.Game
{ {
@@ -47,7 +48,8 @@ namespace OpenRa.Game
public static bool skipMakeAnims = true; public static bool skipMakeAnims = true;
public static void Initialize(string mapName, Renderer renderer, int2 clientSize, int localPlayer, bool useAftermath) public static void Initialize(string mapName, Renderer renderer, int2 clientSize,
int localPlayer, bool useAftermath, Controller controller)
{ {
Rules.LoadRules(mapName, useAftermath); Rules.LoadRules(mapName, useAftermath);
world = new World(); world = new World();
@@ -55,7 +57,7 @@ namespace OpenRa.Game
for( int i = 0 ; i < 8 ; i++ ) for( int i = 0 ; i < 8 ; i++ )
{ {
var a = new Actor( null, new int2( int.MaxValue, int.MaxValue ), null ); var a = new Actor( null, new int2( int.MaxValue, int.MaxValue ), null );
players[ i ] = new Player( a, i, i, "Multi{0}".F( i ), Race.Soviet ); players[ i ] = new Player( a, i, i, "Multi{0}".F( i ), Race.Allies );
a.Owner = players[ i ]; a.Owner = players[ i ];
a.traits.Add( new Traits.ProductionQueue( a ) ); a.traits.Add( new Traits.ProductionQueue( a ) );
Game.world.Add( a ); Game.world.Add( a );
@@ -65,7 +67,7 @@ namespace OpenRa.Game
Rules.Map.InitOreDensity(); Rules.Map.InitOreDensity();
controller = new Controller(); Game.controller = controller;
worldRenderer = new WorldRenderer( renderer ); worldRenderer = new WorldRenderer( renderer );
SequenceProvider.Initialize(useAftermath); SequenceProvider.Initialize(useAftermath);

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Windows.Forms;
namespace OpenRa.Game.Graphics namespace OpenRa.Game.Graphics
{ {

View File

@@ -4,7 +4,7 @@ namespace OpenRa.Game
{ {
interface IOrderGenerator interface IOrderGenerator
{ {
IEnumerable<Order> Order( int2 xy, bool lmb ); IEnumerable<Order> Order( int2 xy, MouseInput mi );
void Tick(); void Tick();
void Render(); void Render();
} }

View File

@@ -58,8 +58,10 @@ namespace OpenRa.Game
renderer = new Renderer( this, GetResolution( settings ), windowed ); renderer = new Renderer( this, GetResolution( settings ), windowed );
SheetBuilder.Initialize( renderer ); SheetBuilder.Initialize( renderer );
var controller = new Controller( () => (Modifiers)(int)ModifierKeys ); /* a bit of insane input routing */
Game.Initialize(settings.GetValue("map", "scm12ea.ini"), renderer, new int2(ClientSize), Game.Initialize(settings.GetValue("map", "scm12ea.ini"), renderer, new int2(ClientSize),
settings.GetValue("player", 1), useAftermath); settings.GetValue("player", 1), useAftermath, controller );
SequenceProvider.ForcePrecache(); SequenceProvider.ForcePrecache();
@@ -79,18 +81,23 @@ namespace OpenRa.Game
int2 lastPos; int2 lastPos;
void DispatchMouseInput(MouseInputEvent ev, MouseEventArgs e)
{
Game.viewport.DispatchMouseInput(
new MouseInput
{
Button = (MouseButton)(int)e.Button,
Event = ev,
Location = new int2(e.Location),
Modifiers = (Modifiers)(int)ModifierKeys,
});
}
protected override void OnMouseDown(MouseEventArgs e) protected override void OnMouseDown(MouseEventArgs e)
{ {
base.OnMouseDown(e); base.OnMouseDown(e);
lastPos = new int2(e.Location); lastPos = new int2(e.Location);
DispatchMouseInput(MouseInputEvent.Down, e);
Game.viewport.DispatchMouseInput(new MouseInput
{
Button = e.Button,
Event = MouseInputEvent.Down,
Location = new int2(e.Location),
Modifiers = ModifierKeys,
});
} }
protected override void OnMouseMove(MouseEventArgs e) protected override void OnMouseMove(MouseEventArgs e)
@@ -104,26 +111,13 @@ namespace OpenRa.Game
lastPos = p; lastPos = p;
} }
Game.viewport.DispatchMouseInput(new MouseInput DispatchMouseInput(MouseInputEvent.Move, e);
{
Button = e.Button,
Event = MouseInputEvent.Move,
Location = new int2(e.Location),
Modifiers = ModifierKeys,
});
} }
protected override void OnMouseUp(MouseEventArgs e) protected override void OnMouseUp(MouseEventArgs e)
{ {
base.OnMouseUp(e); base.OnMouseUp(e);
DispatchMouseInput(MouseInputEvent.Up, e);
Game.viewport.DispatchMouseInput(new MouseInput
{
Button = e.Button,
Event = MouseInputEvent.Up,
Location = new int2(e.Location),
Modifiers = ModifierKeys,
});
} }
protected override void OnKeyDown(KeyEventArgs e) protected override void OnKeyDown(KeyEventArgs e)
@@ -141,7 +135,7 @@ namespace OpenRa.Game
if (!Game.chat.isChatting) if (!Game.chat.isChatting)
if (e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9) if (e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9)
Game.controller.DoControlGroup( (int)e.KeyCode - (int)Keys.D0, e.Modifiers ); Game.controller.DoControlGroup( (int)e.KeyCode - (int)Keys.D0, (Modifiers)(int)e.Modifiers );
} }
protected override void OnKeyPress(KeyPressEventArgs e) protected override void OnKeyPress(KeyPressEventArgs e)
@@ -155,12 +149,30 @@ namespace OpenRa.Game
} }
} }
[Flags]
enum MouseButton
{
None = (int)MouseButtons.None,
Left = (int)MouseButtons.Left,
Right = (int)MouseButtons.Right,
Middle = (int)MouseButtons.Middle,
}
[Flags]
enum Modifiers
{
None = (int)Keys.None,
Shift = (int)Keys.Shift,
Alt = (int)Keys.Alt,
Ctrl = (int)Keys.Control,
}
struct MouseInput struct MouseInput
{ {
public MouseInputEvent Event; public MouseInputEvent Event;
public int2 Location; public int2 Location;
public MouseButtons Button; public MouseButton Button;
public Keys Modifiers; public Modifiers Modifiers;
} }
enum MouseInputEvent { Down, Move, Up }; enum MouseInputEvent { Down, Move, Up };

View File

@@ -14,9 +14,9 @@ namespace OpenRa.Game
Building = (BuildingInfo)Rules.UnitInfo[ name ]; Building = (BuildingInfo)Rules.UnitInfo[ name ];
} }
public IEnumerable<Order> Order(int2 xy, bool lmb) public IEnumerable<Order> Order(int2 xy, MouseInput mi)
{ {
if( lmb ) if( mi.Button == MouseButton.Left )
{ {
if( !Game.CanPlaceBuilding( Building, xy, null, true ) ) if( !Game.CanPlaceBuilding( Building, xy, null, true ) )
yield break; yield break;

View File

@@ -125,9 +125,9 @@ namespace OpenRa.Game.Traits
return true; return true;
} }
public Order IssueOrder(Actor self, int2 xy, bool lmb, Actor underCursor) public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor)
{ {
if (lmb || underCursor == null) return null; if (mi.Button == MouseButton.Left || underCursor == null) return null;
if (underCursor.Owner == self.Owner) return null; if (underCursor.Owner == self.Owner) return null;
if (!Combat.HasAnyValidWeapons(self, underCursor)) return null; if (!Combat.HasAnyValidWeapons(self, underCursor)) return null;
return Order.Attack(self, underCursor); return Order.Attack(self, underCursor);

View File

@@ -1,5 +1,4 @@
 namespace OpenRa.Game.Traits
namespace OpenRa.Game.Traits
{ {
class Harvester : IOrder class Harvester : IOrder
{ {
@@ -25,9 +24,9 @@ namespace OpenRa.Game.Traits
gemsCarried = 0; gemsCarried = 0;
} }
public Order IssueOrder(Actor self, int2 xy, bool lmb, Actor underCursor) public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor)
{ {
if (lmb) return null; if (mi.Button == MouseButton.Left) return null;
if (underCursor != null if (underCursor != null
&& underCursor.Owner == self.Owner && underCursor.Owner == self.Owner

View File

@@ -16,9 +16,9 @@ namespace OpenRa.Game.Traits
targetLocation = self.Location; targetLocation = self.Location;
} }
public Order IssueOrder(Actor self, int2 xy, bool lmb, Actor underCursor) public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor)
{ {
if (lmb) return null; if (mi.Button == MouseButton.Left) return null;
if (underCursor == null) if (underCursor == null)
return Order.Move(self, xy); return Order.Move(self, xy);

View File

@@ -6,9 +6,9 @@ namespace OpenRa.Game.Traits
{ {
public McvDeploy(Actor self) { } public McvDeploy(Actor self) { }
public Order IssueOrder(Actor self, int2 xy, bool lmb, Actor underCursor) public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor)
{ {
if (lmb) return null; if (mi.Button == MouseButton.Left) return null;
if( xy != self.Location ) return null; if( xy != self.Location ) return null;
return Order.DeployMcv(self); return Order.DeployMcv(self);

View File

@@ -28,9 +28,9 @@ namespace OpenRa.Game.Traits
Game.UnitInfluence.Add(self, this); Game.UnitInfluence.Add(self, this);
} }
public Order IssueOrder(Actor self, int2 xy, bool lmb, Actor underCursor) public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor)
{ {
if (lmb) return null; if (mi.Button == MouseButton.Left) return null;
if (underCursor != null) return null; if (underCursor != null) return null;
if (xy == toCell) return null; if (xy == toCell) return null;
return Order.Move(self, xy); return Order.Move(self, xy);

View File

@@ -23,7 +23,7 @@ namespace OpenRa.Game.Traits
p.Value.Tick( self.Owner ); p.Value.Tick( self.Owner );
} }
public Order IssueOrder( Actor self, int2 xy, bool lmb, Actor underCursor ) public Order IssueOrder( Actor self, int2 xy, MouseInput mi, Actor underCursor )
{ {
// production isn't done by clicks in the world; the chrome handles it. // production isn't done by clicks in the world; the chrome handles it.
return null; return null;

View File

@@ -24,9 +24,9 @@ namespace OpenRa.Game.Traits
anim.Image, Util.CenterOfCell(rallyPoint)); anim.Image, Util.CenterOfCell(rallyPoint));
} }
public Order IssueOrder(Actor self, int2 xy, bool lmb, Actor underCursor) public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor)
{ {
if (lmb || underCursor != null) return null; if (mi.Button == MouseButton.Left || underCursor != null) return null;
return Order.SetRallyPoint(self, xy); return Order.SetRallyPoint(self, xy);
} }

View File

@@ -13,7 +13,7 @@ namespace OpenRa.Game.Traits
interface INotifyBuildComplete { void BuildingComplete (Actor self); } interface INotifyBuildComplete { void BuildingComplete (Actor self); }
interface IOrder interface IOrder
{ {
Order IssueOrder( Actor self, int2 xy, bool lmb, Actor underCursor ); Order IssueOrder( Actor self, int2 xy, MouseInput mi, Actor underCursor );
void ResolveOrder( Actor self, Order order ); void ResolveOrder( Actor self, Order order );
} }
interface IProducer { bool Produce( Actor self, UnitInfo producee ); } interface IProducer { bool Produce( Actor self, UnitInfo producee ); }

View File

@@ -13,11 +13,11 @@ namespace OpenRa.Game
selection = selected.ToList(); selection = selected.ToList();
} }
public IEnumerable<Order> Order( int2 xy, bool lmb ) public IEnumerable<Order> Order( int2 xy, MouseInput mi )
{ {
foreach( var unit in selection ) foreach( var unit in selection )
{ {
var ret = unit.Order( xy, lmb ); var ret = unit.Order( xy, mi );
if( ret != null ) if( ret != null )
yield return ret; yield return ret;
} }