diff --git a/OpenRa.Game/Controller.cs b/OpenRa.Game/Controller.cs index 14b7b586d2..cbe2d35fa3 100644 --- a/OpenRa.Game/Controller.cs +++ b/OpenRa.Game/Controller.cs @@ -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(), - Button = MouseButton.Right, - Modifiers = mods, - IsFake = true, + var mi = new MouseInput + { + Location = (Game.CellSize * MousePosition - Game.viewport.Location).ToInt2(), + Button = MouseButton.Right, + 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().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> controlGroups = new Cache>(_ => new List()); @@ -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); } diff --git a/OpenRa.Game/MainWindow.cs b/OpenRa.Game/MainWindow.cs index d3f8017fa1..8d1d61ce81 100755 --- a/OpenRa.Game/MainWindow.cs +++ b/OpenRa.Game/MainWindow.cs @@ -200,7 +200,6 @@ namespace OpenRa.Game public int2 Location; public MouseButton Button; public Modifiers Modifiers; - public bool IsFake; } enum MouseInputEvent { Down, Move, Up }; diff --git a/OpenRa.Game/Orders/IOrderGenerator.cs b/OpenRa.Game/Orders/IOrderGenerator.cs index 0bdfc382ea..88ac531764 100644 --- a/OpenRa.Game/Orders/IOrderGenerator.cs +++ b/OpenRa.Game/Orders/IOrderGenerator.cs @@ -7,5 +7,6 @@ namespace OpenRa.Game IEnumerable Order( int2 xy, MouseInput mi ); void Tick(); void Render(); + Cursor GetCursor(int2 xy, MouseInput mi); } } diff --git a/OpenRa.Game/Orders/PlaceBuildingOrderGenerator.cs b/OpenRa.Game/Orders/PlaceBuildingOrderGenerator.cs index 43bf7be963..5c9d2b25fc 100644 --- a/OpenRa.Game/Orders/PlaceBuildingOrderGenerator.cs +++ b/OpenRa.Game/Orders/PlaceBuildingOrderGenerator.cs @@ -16,13 +16,14 @@ namespace OpenRa.Game.Orders public IEnumerable 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 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; + } } } diff --git a/OpenRa.Game/Orders/RepairOrderGenerator.cs b/OpenRa.Game/Orders/RepairOrderGenerator.cs index 299c2e65a5..bc79d65ed4 100644 --- a/OpenRa.Game/Orders/RepairOrderGenerator.cs +++ b/OpenRa.Game/Orders/RepairOrderGenerator.cs @@ -11,42 +11,48 @@ namespace OpenRa.Game.Orders { public IEnumerable Order(int2 xy, MouseInput mi) { - if (!mi.IsFake && mi.Button == MouseButton.Right) - { + if (mi.Button == MouseButton.Right) Game.controller.CancelInputMode(); - yield break; - } - var loc = mi.Location + Game.viewport.Location; - var underCursor = Game.FindUnits(loc, loc) - .Where(a => a.Owner == Game.LocalPlayer - && a.traits.Contains() - && a.Info.Selectable).FirstOrDefault(); + return OrderInner(xy, mi); + } - var building = underCursor != null ? underCursor.Info as BuildingInfo : null; - - if (building == null || !building.Repairable || underCursor.Health == building.Strength) + IEnumerable OrderInner(int2 xy, MouseInput mi) + { + if (mi.Button == MouseButton.Left) { - yield return new Order("NoRepair", Game.LocalPlayer.PlayerActor, null, int2.Zero, null); - yield break; - } + var loc = mi.Location + Game.viewport.Location; + var underCursor = Game.FindUnits(loc, loc) + .Where(a => a.Owner == Game.LocalPlayer + && a.traits.Contains() + && a.Info.Selectable).FirstOrDefault(); - yield return new Order("Repair", underCursor, null, int2.Zero, null); + var building = underCursor != null ? underCursor.Info as BuildingInfo : null; + + 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) - { - var hasFact = Game.world.Actors - .Any(a => a.Owner == Game.LocalPlayer && a.traits.Contains()); + if (!Game.Settings.RepairRequiresConyard) + return; + + var hasFact = Game.world.Actors + .Any(a => a.Owner == Game.LocalPlayer && a.traits.Contains()); - if (!hasFact) - Game.controller.CancelInputMode(); - } + 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; + } } } diff --git a/OpenRa.Game/Orders/SellOrderGenerator.cs b/OpenRa.Game/Orders/SellOrderGenerator.cs index aac3baf3b5..3576c59d1e 100644 --- a/OpenRa.Game/Orders/SellOrderGenerator.cs +++ b/OpenRa.Game/Orders/SellOrderGenerator.cs @@ -11,30 +11,37 @@ namespace OpenRa.Game.Orders { public IEnumerable Order(int2 xy, MouseInput mi) { - if (!mi.IsFake && mi.Button == MouseButton.Right) - { + if (mi.Button == MouseButton.Right) Game.controller.CancelInputMode(); - yield break; - } - var loc = mi.Location + Game.viewport.Location; - var underCursor = Game.FindUnits(loc, loc) - .Where(a => a.Owner == Game.LocalPlayer - && a.traits.Contains() - && a.Info.Selectable).FirstOrDefault(); + return OrderInner(xy, mi); + } - var building = underCursor != null ? underCursor.Info as BuildingInfo : null; - - if (building == null || building.Unsellable) + IEnumerable OrderInner(int2 xy, MouseInput mi) + { + if (mi.Button == MouseButton.Left) { - yield return new Order("NoSell", Game.LocalPlayer.PlayerActor, null, int2.Zero, null); - yield break; - } + var loc = mi.Location + Game.viewport.Location; + var underCursor = Game.FindUnits(loc, loc) + .Where(a => a.Owner == Game.LocalPlayer + && a.traits.Contains() + && a.Info.Selectable).FirstOrDefault(); - yield return new Order("Sell", underCursor, null, int2.Zero, null); + var building = underCursor != null ? underCursor.Info as BuildingInfo : null; + + 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; + } } } diff --git a/OpenRa.Game/Orders/TeleportOrderGenerator.cs b/OpenRa.Game/Orders/TeleportOrderGenerator.cs index 0c14e694bb..3fca07bc4b 100644 --- a/OpenRa.Game/Orders/TeleportOrderGenerator.cs +++ b/OpenRa.Game/Orders/TeleportOrderGenerator.cs @@ -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; + } } } diff --git a/OpenRa.Game/Orders/UnitOrderGenerator.cs b/OpenRa.Game/Orders/UnitOrderGenerator.cs index 91515eec3a..c50379f4e4 100644 --- a/OpenRa.Game/Orders/UnitOrderGenerator.cs +++ b/OpenRa.Game/Orders/UnitOrderGenerator.cs @@ -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().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; + } + } } } diff --git a/OpenRa.Game/Traits/ChronoshiftDeploy.cs b/OpenRa.Game/Traits/ChronoshiftDeploy.cs index 4cb67319da..46220b51dd 100644 --- a/OpenRa.Game/Traits/ChronoshiftDeploy.cs +++ b/OpenRa.Game/Traits/ChronoshiftDeploy.cs @@ -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 new Order( "Deploy", self, null, int2.Zero, null ); 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().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; }