diff --git a/OpenRA.Game/GameRules/Settings.cs b/OpenRA.Game/GameRules/Settings.cs index 800d206a5c..e270d78d49 100644 --- a/OpenRA.Game/GameRules/Settings.cs +++ b/OpenRA.Game/GameRules/Settings.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2013 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, @@ -112,6 +112,8 @@ namespace OpenRA.GameRules public MouseScrollType MouseScroll = MouseScrollType.Standard; public float ViewportEdgeScrollStep = 10f; + public bool UseClassicMouseStyle = false; + // Internal game settings public int Timestep = 40; diff --git a/OpenRA.Game/Orders/UnitOrderGenerator.cs b/OpenRA.Game/Orders/UnitOrderGenerator.cs index 98b0e97719..59fa07bb8c 100644 --- a/OpenRA.Game/Orders/UnitOrderGenerator.cs +++ b/OpenRA.Game/Orders/UnitOrderGenerator.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2013 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, @@ -17,7 +17,7 @@ namespace OpenRA.Orders { class UnitOrderGenerator : IOrderGenerator { - public IEnumerable Order( World world, CPos xy, MouseInput mi ) + public IEnumerable Order(World world, CPos xy, MouseInput mi) { var underCursor = world.FindUnitsAtMouse(mi.Location) .Where(a => a.HasTrait()) @@ -41,9 +41,9 @@ namespace OpenRA.Orders yield return CheckSameOrder(o.iot, o.trait.IssueOrder(o.self, o.iot, o.target, mi.Modifiers.HasModifier(Modifiers.Shift))); } - public void Tick( World world ) { } - public void RenderBeforeWorld( WorldRenderer wr, World world ) { } - public void RenderAfterWorld( WorldRenderer wr, World world ) { } + public void Tick(World world) { } + public void RenderBeforeWorld(WorldRenderer wr, World world) { } + public void RenderAfterWorld(WorldRenderer wr, World world) { } public string GetCursor(World world, CPos xy, MouseInput mi) { @@ -69,41 +69,43 @@ namespace OpenRA.Orders static UnitOrderResult OrderForUnit(Actor self, CPos xy, MouseInput mi, Actor underCursor) { + var ActionMouseButton = (Game.Settings.Game.UseClassicMouseStyle) ? MouseButton.Left : MouseButton.Right; + if (self.Owner != self.World.LocalPlayer) return null; if (self.Destroyed) return null; - if( mi.Button == MouseButton.Right ) + if (mi.Button == ActionMouseButton) { foreach( var o in self.TraitsImplementing() - .SelectMany( trait => trait.Orders - .Select( x => new { Trait = trait, Order = x } ) ) - .OrderByDescending( x => x.Order.OrderPriority ) ) + .SelectMany(trait => trait.Orders + .Select(x => new { Trait = trait, Order = x } )) + .OrderByDescending(x => x.Order.OrderPriority)) { - var actorsAt = self.World.ActorMap.GetUnitsAt( xy ).ToList(); + var actorsAt = self.World.ActorMap.GetUnitsAt(xy).ToList(); var forceAttack = mi.Modifiers.HasModifier(Modifiers.Ctrl); var forceQueue = mi.Modifiers.HasModifier(Modifiers.Shift); string cursor = null; - if( underCursor != null ) + if (underCursor != null) if (o.Order.CanTargetActor(self, underCursor, forceAttack, forceQueue, ref cursor)) - return new UnitOrderResult( self, o.Order, o.Trait, cursor, Target.FromActor( underCursor ) ); + return new UnitOrderResult(self, o.Order, o.Trait, cursor, Target.FromActor(underCursor)); if (o.Order.CanTargetLocation(self, xy, actorsAt, forceAttack, forceQueue, ref cursor)) - return new UnitOrderResult( self, o.Order, o.Trait, cursor, Target.FromCell( xy ) ); + return new UnitOrderResult(self, o.Order, o.Trait, cursor, Target.FromCell(xy)); } } return null; } - static Order CheckSameOrder( IOrderTargeter iot, Order order ) + static Order CheckSameOrder(IOrderTargeter iot, Order order) { - if( order == null && iot.OrderID != null ) - Game.Debug( "BUG: in order targeter - decided on {0} but then didn't order", iot.OrderID ); - else if( iot.OrderID != order.OrderString ) - Game.Debug( "BUG: in order targeter - decided on {0} but ordered {1}", iot.OrderID, order.OrderString ); + if (order == null && iot.OrderID != null) + Game.Debug("BUG: in order targeter - decided on {0} but then didn't order", iot.OrderID); + else if (iot.OrderID != order.OrderString) + Game.Debug("BUG: in order targeter - decided on {0} but ordered {1}", iot.OrderID, order.OrderString); return order; } @@ -115,7 +117,7 @@ namespace OpenRA.Orders public readonly string cursor; public readonly Target target; - public UnitOrderResult( Actor self, IOrderTargeter iot, IIssueOrder trait, string cursor, Target target ) + public UnitOrderResult(Actor self, IOrderTargeter iot, IIssueOrder trait, string cursor, Target target) { this.self = self; this.iot = iot; diff --git a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs index 4210d88a76..36ff61d05a 100644 --- a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs +++ b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2013 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, @@ -52,55 +52,72 @@ namespace OpenRA.Widgets public override bool HandleMouseInput(MouseInput mi) { var xy = Game.viewport.ViewToWorldPx(mi); + + var UseClassicMouseStyle = Game.Settings.Game.UseClassicMouseStyle; + + var HasBox = (SelectionBox != null) ? true : false; + var MultiClick = (mi.MultiTapCount >= 2) ? true : false; + var NothingSelected = !world.Selection.Actors.Any(); + if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down) { if (!TakeFocus(mi)) return false; - + dragStart = dragEnd = xy; - ApplyOrders(world, xy, mi); + + if (UseClassicMouseStyle) + ApplyOrders(world, xy, mi); } - + if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Move) dragEnd = xy; - + if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Up) { if (world.OrderGenerator is UnitOrderGenerator) { - if (mi.MultiTapCount == 2) + if ((UseClassicMouseStyle && NothingSelected) || (!UseClassicMouseStyle)) { - var unit = SelectActorsInBox(world, xy, xy, _ => true).FirstOrDefault(); - - var visibleWorld = Game.viewport.ViewBounds(world); - var topLeft = Game.viewport.ViewToWorldPx(new int2(visibleWorld.Left, visibleWorld.Top)); - var bottomRight = Game.viewport.ViewToWorldPx(new int2(visibleWorld.Right, visibleWorld.Bottom)); - var newSelection = SelectActorsInBox(world, topLeft, bottomRight, - a => unit != null && a.Info.Name == unit.Info.Name && a.Owner == unit.Owner); - - world.Selection.Combine(world, newSelection, true, false); - } - else - { - var newSelection = SelectActorsInBox(world, dragStart, xy, _ => true); - world.Selection.Combine(world, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy); + if (MultiClick) + { + var unit = SelectActorsInBox(world, xy, xy, _ => true).FirstOrDefault(); + + var visibleWorld = Game.viewport.ViewBounds(world); + var topLeft = Game.viewport.ViewToWorldPx(new int2(visibleWorld.Left, visibleWorld.Top)); + var bottomRight = Game.viewport.ViewToWorldPx(new int2(visibleWorld.Right, visibleWorld.Bottom)); + var newSelection2 = SelectActorsInBox(world, topLeft, bottomRight, + a => unit != null && a.Info.Name == unit.Info.Name && a.Owner == unit.Owner); + + world.Selection.Combine(world, newSelection2, true, false); + } + else + { + var newSelection = SelectActorsInBox(world, dragStart, xy, _ => true); + world.Selection.Combine(world, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy); + } } } - + dragStart = dragEnd = xy; LoseFocus(mi); } - + if (mi.Button == MouseButton.None && mi.Event == MouseInputEvent.Move) dragStart = dragEnd = xy; - + if (mi.Button == MouseButton.Right && mi.Event == MouseInputEvent.Down) - if (SelectionBox == null) /* don't issue orders while selecting */ + { + if (UseClassicMouseStyle) + world.Selection.Clear(); + else if (!HasBox) // don't issue orders while selecting ApplyOrders(world, xy, mi); - + } + return true; } + public Pair? SelectionBox { get @@ -115,14 +132,14 @@ namespace OpenRA.Widgets if (world.OrderGenerator == null) return; var orders = world.OrderGenerator.Order(world, xy.ToCPos(), mi).ToArray(); - orders.Do( o => world.IssueOrder( o ) ); + orders.Do(o => world.IssueOrder(o)); world.PlayVoiceForOrders(orders); } public override string GetCursor(int2 pos) { - return Sync.CheckSyncUnchanged( world, () => + return Sync.CheckSyncUnchanged(world, () => { if (SelectionBox != null) return null; /* always show an arrow while selecting */ @@ -130,12 +147,12 @@ namespace OpenRA.Widgets var mi = new MouseInput { Location = pos, - Button = MouseButton.Right, + Button = Game.Settings.Game.UseClassicMouseStyle ? MouseButton.Left : MouseButton.Right, Modifiers = Game.GetModifierKeys() }; // TODO: fix this up. - return world.OrderGenerator.GetCursor( world, Game.viewport.ViewToWorld(mi), mi ); + return world.OrderGenerator.GetCursor(world, Game.viewport.ViewToWorld(mi), mi); } ); } @@ -148,7 +165,7 @@ namespace OpenRA.Widgets world.Selection.DoControlGroup(world, e.KeyName[0] - '0', e.Modifiers); return true; } - else if(e.KeyName == "pause" || e.KeyName == "f3") + else if (e.KeyName == "pause" || e.KeyName == "f3") { world.IssueOrder(Order.PauseRequest()); } @@ -164,11 +181,11 @@ namespace OpenRA.Widgets IEnumerable SelectActorsInBox(World world, PPos a, PPos b, Func cond) { return world.FindUnits(a, b) - .Where( x => x.HasTrait() && world.RenderedShroud.IsVisible(x) && cond(x) ) + .Where(x => x.HasTrait() && world.RenderedShroud.IsVisible(x) && cond(x)) .GroupBy(x => x.GetSelectionPriority()) .OrderByDescending(g => g.Key) - .Select( g => g.AsEnumerable() ) - .DefaultIfEmpty( NoActors ) + .Select(g => g.AsEnumerable()) + .DefaultIfEmpty(NoActors) .FirstOrDefault(); } } diff --git a/OpenRA.Mods.Cnc/Widgets/Logic/CncSettingsLogic.cs b/OpenRA.Mods.Cnc/Widgets/Logic/CncSettingsLogic.cs index a4f30f8705..c8641f2b58 100644 --- a/OpenRA.Mods.Cnc/Widgets/Logic/CncSettingsLogic.cs +++ b/OpenRA.Mods.Cnc/Widgets/Logic/CncSettingsLogic.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2013 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, @@ -118,7 +118,9 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic inputButton.OnClick = () => Settings = PanelType.Input; inputButton.IsDisabled = () => Settings == PanelType.Input; - inputPane.Get("CLASSICORDERS_CHECKBOX").IsDisabled = () => true; + var classicMouseCheckbox = inputPane.Get("CLASSICORDERS_CHECKBOX"); + classicMouseCheckbox.IsChecked = () => gameSettings.UseClassicMouseStyle; + classicMouseCheckbox.OnClick = () => gameSettings.UseClassicMouseStyle ^= true; var scrollSlider = inputPane.Get("SCROLLSPEED_SLIDER"); scrollSlider.Value = gameSettings.ViewportEdgeScrollStep; diff --git a/OpenRA.Mods.RA/Widgets/Logic/SettingsMenuLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/SettingsMenuLogic.cs index a81e9ec86a..d6b4b847f4 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/SettingsMenuLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/SettingsMenuLogic.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2012 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2013 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, @@ -69,6 +69,10 @@ namespace OpenRA.Mods.RA.Widgets.Logic showShellmapCheckbox.IsChecked = () => Game.Settings.Game.ShowShellmap; showShellmapCheckbox.OnClick = () => Game.Settings.Game.ShowShellmap ^= true; + var useClassicMouseStyleCheckbox = general.Get("USE_CLASSIC_MOUSE_STYLE_CHECKBOX"); + useClassicMouseStyleCheckbox.IsChecked = () => Game.Settings.Game.UseClassicMouseStyle; + useClassicMouseStyleCheckbox.OnClick = () => Game.Settings.Game.UseClassicMouseStyle ^= true; + // Audio var audio = bg.Get("AUDIO_PANE"); var soundSettings = Game.Settings.Sound; diff --git a/OpenRA.Mods.RA/Widgets/WorldCommandWidget.cs b/OpenRA.Mods.RA/Widgets/WorldCommandWidget.cs index 2434bca958..30df3030cb 100644 --- a/OpenRA.Mods.RA/Widgets/WorldCommandWidget.cs +++ b/OpenRA.Mods.RA/Widgets/WorldCommandWidget.cs @@ -86,9 +86,11 @@ namespace OpenRA.Mods.RA.Widgets var actors = World.Selection.Actors .Where(a => a.Owner == World.LocalPlayer).ToArray(); + var ActionMouseButton = (Game.Settings.Game.UseClassicMouseStyle) ? MouseButton.Left : MouseButton.Right; + if (actors.Length > 0) World.OrderGenerator = new GenericSelectTarget(actors, "AttackMove", - "attackmove", MouseButton.Right); + "attackmove", ActionMouseButton); return true; } diff --git a/mods/cnc/chrome/settings.yaml b/mods/cnc/chrome/settings.yaml index 7ce9ba4fe3..7b97795882 100644 --- a/mods/cnc/chrome/settings.yaml +++ b/mods/cnc/chrome/settings.yaml @@ -208,7 +208,7 @@ Container@SETTINGS_PANEL: Width:250 Height:20 Font:Regular - Text:Left-Click Orders (Coming soon!) + Text:Left-Click Orders Label@SCROLL_TITLE: Font:Bold Text:Scroll Behavior diff --git a/mods/ra/chrome/settings.yaml b/mods/ra/chrome/settings.yaml index 65a064f15b..22e831761f 100644 --- a/mods/ra/chrome/settings.yaml +++ b/mods/ra/chrome/settings.yaml @@ -109,6 +109,12 @@ Background@SETTINGS_MENU: Width:200 Height:20 Text: Show Shellmap + Checkbox@USE_CLASSIC_MOUSE_STYLE_CHECKBOX: + X:0 + Y:180 + Width:200 + Height:20 + Text: Left-Click Orders Container@AUDIO_PANE: X:37 Y:100