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 ) );
}
public Order Order( int2 xy, bool lmb )
public Order Order( int2 xy, MouseInput mi )
{
if (Owner != Game.LocalPlayer)
return null;
@@ -91,7 +91,7 @@ namespace OpenRa.Game
underCursor = null;
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 );
}

View File

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

View File

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

View File

@@ -8,6 +8,7 @@ using OpenRa.Game.GameRules;
using OpenRa.Game.Graphics;
using OpenRa.Game.Support;
using OpenRa.Game.Traits;
using System.Windows.Forms;
namespace OpenRa.Game
{
@@ -47,7 +48,8 @@ namespace OpenRa.Game
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);
world = new World();
@@ -55,7 +57,7 @@ namespace OpenRa.Game
for( int i = 0 ; i < 8 ; i++ )
{
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.traits.Add( new Traits.ProductionQueue( a ) );
Game.world.Add( a );
@@ -65,7 +67,7 @@ namespace OpenRa.Game
Rules.Map.InitOreDensity();
controller = new Controller();
Game.controller = controller;
worldRenderer = new WorldRenderer( renderer );
SequenceProvider.Initialize(useAftermath);

View File

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

View File

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

View File

@@ -58,8 +58,10 @@ namespace OpenRa.Game
renderer = new Renderer( this, GetResolution( settings ), windowed );
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),
settings.GetValue("player", 1), useAftermath);
settings.GetValue("player", 1), useAftermath, controller );
SequenceProvider.ForcePrecache();
@@ -79,18 +81,23 @@ namespace OpenRa.Game
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)
{
base.OnMouseDown(e);
lastPos = new int2(e.Location);
Game.viewport.DispatchMouseInput(new MouseInput
{
Button = e.Button,
Event = MouseInputEvent.Down,
Location = new int2(e.Location),
Modifiers = ModifierKeys,
});
DispatchMouseInput(MouseInputEvent.Down, e);
}
protected override void OnMouseMove(MouseEventArgs e)
@@ -104,26 +111,13 @@ namespace OpenRa.Game
lastPos = p;
}
Game.viewport.DispatchMouseInput(new MouseInput
{
Button = e.Button,
Event = MouseInputEvent.Move,
Location = new int2(e.Location),
Modifiers = ModifierKeys,
});
DispatchMouseInput(MouseInputEvent.Move, e);
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
Game.viewport.DispatchMouseInput(new MouseInput
{
Button = e.Button,
Event = MouseInputEvent.Up,
Location = new int2(e.Location),
Modifiers = ModifierKeys,
});
DispatchMouseInput(MouseInputEvent.Up, e);
}
protected override void OnKeyDown(KeyEventArgs e)
@@ -141,7 +135,7 @@ namespace OpenRa.Game
if (!Game.chat.isChatting)
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)
@@ -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
{
public MouseInputEvent Event;
public int2 Location;
public MouseButtons Button;
public Keys Modifiers;
public MouseButton Button;
public Modifiers Modifiers;
}
enum MouseInputEvent { Down, Move, Up };

View File

@@ -14,9 +14,9 @@ namespace OpenRa.Game
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 ) )
yield break;

View File

@@ -125,9 +125,9 @@ namespace OpenRa.Game.Traits
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 (!Combat.HasAnyValidWeapons(self, underCursor)) return null;
return Order.Attack(self, underCursor);

View File

@@ -1,5 +1,4 @@

namespace OpenRa.Game.Traits
namespace OpenRa.Game.Traits
{
class Harvester : IOrder
{
@@ -25,9 +24,9 @@ namespace OpenRa.Game.Traits
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
&& underCursor.Owner == self.Owner

View File

@@ -16,9 +16,9 @@ namespace OpenRa.Game.Traits
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)
return Order.Move(self, xy);

View File

@@ -6,9 +6,9 @@ namespace OpenRa.Game.Traits
{
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;
return Order.DeployMcv(self);

View File

@@ -28,9 +28,9 @@ namespace OpenRa.Game.Traits
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 (xy == toCell) return null;
return Order.Move(self, xy);

View File

@@ -23,7 +23,7 @@ namespace OpenRa.Game.Traits
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.
return null;

View File

@@ -24,9 +24,9 @@ namespace OpenRa.Game.Traits
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);
}

View File

@@ -13,7 +13,7 @@ namespace OpenRa.Game.Traits
interface INotifyBuildComplete { void BuildingComplete (Actor self); }
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 );
}
interface IProducer { bool Produce( Actor self, UnitInfo producee ); }

View File

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