big cleanup of Controller mess

This commit is contained in:
Chris Forbes
2010-01-03 16:40:24 +13:00
parent 43498a123e
commit e742097046
9 changed files with 144 additions and 114 deletions

View File

@@ -141,63 +141,14 @@ namespace OpenRa.Game
public Cursor ChooseCursor()
{
var mods = GetModifierKeys();
var mi = new MouseInput {
Location = (Game.CellSize * dragEnd - Game.viewport.Location).ToInt2(),
var mi = new MouseInput
{
Location = (Game.CellSize * MousePosition - Game.viewport.Location).ToInt2(),
Button = MouseButton.Right,
Modifiers = mods,
IsFake = true,
Modifiers = GetModifierKeys(),
};
var c = orderGenerator.Order(dragEnd.ToInt2(), mi)
.Where(o => o.Validate())
.Select(o => CursorForOrderString(o.OrderString, o.Subject, o.TargetLocation))
.FirstOrDefault(a => a != null);
return c ??
(Game.SelectActorsInBox(Game.CellSize * dragEnd, Game.CellSize * dragEnd).Any()
? Cursor.Select : Cursor.Default);
}
Cursor CursorForOrderString( string s, Actor a, int2 location )
{
var movement = a.traits.WithInterface<IMovement>().FirstOrDefault();
switch( s )
{
case "Attack": return Cursor.Attack;
case "Heal": return Cursor.Heal;
case "C4": return Cursor.C4;
case "Move":
if (movement.CanEnterCell(location))
return Cursor.Move;
else
return Cursor.MoveBlocked;
case "DeployMcv":
var factBuildingInfo = (BuildingInfo)Rules.UnitInfo[ "fact" ];
if( Game.CanPlaceBuilding( factBuildingInfo, a.Location - new int2( 1, 1 ), a, false ) )
return Cursor.Deploy;
else
return Cursor.DeployBlocked;
case "Deploy": return Cursor.Deploy;
case "Chronoshift":
if (movement.CanEnterCell(location))
return Cursor.Chronoshift;
else
return Cursor.MoveBlocked;
case "Enter": return Cursor.Enter;
case "Deliver": return Cursor.Enter;
case "Infiltrate": return Cursor.Enter;
case "Capture": return Cursor.Capture;
case "Harvest": return Cursor.Attack; // TODO: special harvest cursor?
case "PlaceBuilding": return Cursor.Default;
case "Sell": return Cursor.Sell;
case "NoSell": return Cursor.SellBlocked;
case "Repair": return Cursor.Repair;
case "NoRepair": return Cursor.RepairBlocked;
default:
return null;
}
return orderGenerator.GetCursor(MousePosition.ToInt2(), mi);
}
Cache<int, List<Actor>> controlGroups = new Cache<int, List<Actor>>(_ => new List<Actor>());
@@ -205,9 +156,11 @@ namespace OpenRa.Game
public void DoControlGroup(int group, Modifiers mods)
{
var uog = orderGenerator as UnitOrderGenerator;
if (uog == null) return;
if (mods.HasModifier(Modifiers.Ctrl))
{
if (uog == null || !uog.selection.Any())
if (!uog.selection.Any())
return;
controlGroups[group].Clear();
@@ -225,7 +178,6 @@ namespace OpenRa.Game
return;
}
if (uog == null) return;
CombineSelection(controlGroups[group], mods.HasModifier(Modifiers.Shift), false);
}

View File

@@ -200,7 +200,6 @@ namespace OpenRa.Game
public int2 Location;
public MouseButton Button;
public Modifiers Modifiers;
public bool IsFake;
}
enum MouseInputEvent { Down, Move, Up };

View File

@@ -7,5 +7,6 @@ namespace OpenRa.Game
IEnumerable<Order> Order( int2 xy, MouseInput mi );
void Tick();
void Render();
Cursor GetCursor(int2 xy, MouseInput mi);
}
}

View File

@@ -16,13 +16,14 @@ namespace OpenRa.Game.Orders
public IEnumerable<Order> Order(int2 xy, MouseInput mi)
{
if (mi.IsFake)
{
// this order is never actually issued, but it's used for choosing a cursor
yield return new Order("PlaceBuilding", Producer.Owner.PlayerActor, null, xy, Building.Name);
yield break;
if (mi.Button == MouseButton.Right)
Game.controller.CancelInputMode();
return InnerOrder(xy, mi);
}
IEnumerable<Order> InnerOrder(int2 xy, MouseInput mi)
{
if (mi.Button == MouseButton.Left)
{
if (!Game.CanPlaceBuilding(Building, xy, null, true)
@@ -34,8 +35,6 @@ namespace OpenRa.Game.Orders
yield return new Order("PlaceBuilding", Producer.Owner.PlayerActor, null, xy, Building.Name);
}
else
Game.controller.CancelInputMode();
}
public void Tick()
@@ -49,5 +48,10 @@ namespace OpenRa.Game.Orders
{
Game.worldRenderer.uiOverlay.DrawBuildingGrid( Building );
}
public Cursor GetCursor(int2 xy, MouseInput mi)
{
return Cursor.Default;
}
}
}

View File

@@ -11,12 +11,16 @@ namespace OpenRa.Game.Orders
{
public IEnumerable<Order> Order(int2 xy, MouseInput mi)
{
if (!mi.IsFake && mi.Button == MouseButton.Right)
{
if (mi.Button == MouseButton.Right)
Game.controller.CancelInputMode();
yield break;
return OrderInner(xy, mi);
}
IEnumerable<Order> OrderInner(int2 xy, MouseInput mi)
{
if (mi.Button == MouseButton.Left)
{
var loc = mi.Location + Game.viewport.Location;
var underCursor = Game.FindUnits(loc, loc)
.Where(a => a.Owner == Game.LocalPlayer
@@ -25,28 +29,30 @@ namespace OpenRa.Game.Orders
var building = underCursor != null ? underCursor.Info as BuildingInfo : null;
if (building == null || !building.Repairable || underCursor.Health == building.Strength)
{
yield return new Order("NoRepair", Game.LocalPlayer.PlayerActor, null, int2.Zero, null);
yield break;
}
if (building != null && building.Repairable && underCursor.Health < building.Strength)
yield return new Order("Repair", underCursor, null, int2.Zero, null);
}
}
public void Tick()
{
if (Game.Settings.RepairRequiresConyard)
{
if (!Game.Settings.RepairRequiresConyard)
return;
var hasFact = Game.world.Actors
.Any(a => a.Owner == Game.LocalPlayer && a.traits.Contains<ConstructionYard>());
if (!hasFact)
Game.controller.CancelInputMode();
}
}
public void Render() {}
public Cursor GetCursor(int2 xy, MouseInput mi)
{
mi.Button = MouseButton.Left;
return OrderInner(xy, mi).Any()
? Cursor.Repair : Cursor.RepairBlocked;
}
}
}

View File

@@ -11,12 +11,16 @@ namespace OpenRa.Game.Orders
{
public IEnumerable<Order> Order(int2 xy, MouseInput mi)
{
if (!mi.IsFake && mi.Button == MouseButton.Right)
{
if (mi.Button == MouseButton.Right)
Game.controller.CancelInputMode();
yield break;
return OrderInner(xy, mi);
}
IEnumerable<Order> OrderInner(int2 xy, MouseInput mi)
{
if (mi.Button == MouseButton.Left)
{
var loc = mi.Location + Game.viewport.Location;
var underCursor = Game.FindUnits(loc, loc)
.Where(a => a.Owner == Game.LocalPlayer
@@ -25,16 +29,19 @@ namespace OpenRa.Game.Orders
var building = underCursor != null ? underCursor.Info as BuildingInfo : null;
if (building == null || building.Unsellable)
{
yield return new Order("NoSell", Game.LocalPlayer.PlayerActor, null, int2.Zero, null);
yield break;
}
if (building != null && !building.Unsellable)
yield return new Order("Sell", underCursor, null, int2.Zero, null);
}
}
public void Tick() {}
public void Render() {}
public Cursor GetCursor(int2 xy, MouseInput mi)
{
mi.Button = MouseButton.Left;
return OrderInner(xy, mi).Any()
? Cursor.Sell : Cursor.SellBlocked;
}
}
}

View File

@@ -31,5 +31,10 @@ namespace OpenRa.Game.Orders
{
Game.worldRenderer.DrawSelectionBox(self, Color.White, true);
}
public Cursor GetCursor(int2 xy, MouseInput mi)
{
return Cursor.Chronoshift;
}
}
}

View File

@@ -1,6 +1,8 @@
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using OpenRa.Game.Traits;
using OpenRa.Game.GameRules;
namespace OpenRa.Game.Orders
{
@@ -33,5 +35,59 @@ namespace OpenRa.Game.Orders
foreach( var a in selection )
Game.worldRenderer.DrawSelectionBox( a, Color.White, true );
}
public Cursor GetCursor(int2 xy, MouseInput mi)
{
return ChooseCursor(mi);
}
Cursor ChooseCursor( MouseInput mi )
{
var p = Game.controller.MousePosition;
var c = Order(p.ToInt2(), mi)
.Where(o => o.Validate())
.Select(o => CursorForOrderString(o.OrderString, o.Subject, o.TargetLocation))
.FirstOrDefault(a => a != null);
return c ??
(Game.SelectActorsInBox(Game.CellSize * p,
Game.CellSize * p).Any()
? Cursor.Select : Cursor.Default);
}
Cursor CursorForOrderString(string s, Actor a, int2 location)
{
var movement = a.traits.WithInterface<IMovement>().FirstOrDefault();
switch (s)
{
case "Attack": return Cursor.Attack;
case "Heal": return Cursor.Heal;
case "C4": return Cursor.C4;
case "Move":
if (movement.CanEnterCell(location))
return Cursor.Move;
else
return Cursor.MoveBlocked;
case "DeployMcv":
var factBuildingInfo = (BuildingInfo)Rules.UnitInfo["fact"];
if (Game.CanPlaceBuilding(factBuildingInfo, a.Location - new int2(1, 1), a, false))
return Cursor.Deploy;
else
return Cursor.DeployBlocked;
case "Deploy": return Cursor.Deploy;
case "Chronoshift":
if (movement.CanEnterCell(location))
return Cursor.Chronoshift;
else
return Cursor.MoveBlocked;
case "Enter": return Cursor.Enter;
case "Deliver": return Cursor.Enter;
case "Infiltrate": return Cursor.Enter;
case "Capture": return Cursor.Capture;
case "Harvest": return Cursor.Attack; // TODO: special harvest cursor?
default:
return null;
}
}
}
}

View File

@@ -18,21 +18,20 @@ namespace OpenRa.Game.Traits
public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor)
{
if (mi.Button == MouseButton.Left) return null;
if( mi.Button == MouseButton.Right && xy == self.Location && remainingChargeTime <= 0 )
{
if( mi.IsFake )
return new Order( "Deploy", self, null, int2.Zero, null );
else
Game.controller.orderGenerator = new TeleportOrderGenerator( self );
}
return null;
}
public void ResolveOrder(Actor self, Order order)
{
if (order.OrderString == "Deploy")
{
Game.controller.orderGenerator = new TeleportOrderGenerator(self);
return;
}
var movement = self.traits.WithInterface<IMovement>().FirstOrDefault();
if (order.OrderString == "Chronoshift" && movement.CanEnterCell(order.TargetLocation))
{
@@ -46,6 +45,7 @@ namespace OpenRa.Game.Traits
public float GetSpeedModifier()
{
// ARGH! You must not do this, it will desync!
return (Game.controller.orderGenerator is TeleportOrderGenerator) ? 0f : 1f;
}