diff --git a/OpenRA.Game/World.cs b/OpenRA.Game/World.cs
index 37774d7db2..349605b610 100644
--- a/OpenRA.Game/World.cs
+++ b/OpenRA.Game/World.cs
@@ -130,7 +130,7 @@ namespace OpenRA
}
}
- public Selection Selection = new Selection();
+ public readonly Selection Selection = new Selection();
public void CancelInputMode() { OrderGenerator = new UnitOrderGenerator(); }
diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
index 43de252fa4..9cbe974a7e 100644
--- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
+++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
@@ -657,7 +657,6 @@
-
@@ -824,6 +823,10 @@
+
+
+
+
diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/Hotkeys/CycleBasesHotkeyLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/Hotkeys/CycleBasesHotkeyLogic.cs
new file mode 100644
index 0000000000..045930e746
--- /dev/null
+++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/Hotkeys/CycleBasesHotkeyLogic.cs
@@ -0,0 +1,75 @@
+#region Copyright & License Information
+/*
+ * Copyright 2007-2017 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, either version 3 of
+ * the License, or (at your option) any later version. For more
+ * information, see COPYING.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using OpenRA.Graphics;
+using OpenRA.Mods.Common.Lint;
+using OpenRA.Mods.Common.Traits;
+using OpenRA.Traits;
+using OpenRA.Widgets;
+
+namespace OpenRA.Mods.Common.Widgets.Logic.Ingame
+{
+ [ChromeLogicArgsHotkeys("CycleBasesKey")]
+ public class CycleBasesHotkeyLogic : SingleHotkeyBaseLogic
+ {
+ readonly Viewport viewport;
+ readonly Selection selection;
+ readonly World world;
+
+ [ObjectCreator.UseCtor]
+ public CycleBasesHotkeyLogic(Widget widget, WorldRenderer worldRenderer, World world, Dictionary logicArgs)
+ : base(widget, "CycleBasesKey", "WORLD_KEYHANDLER", logicArgs)
+ {
+ viewport = worldRenderer.Viewport;
+ selection = world.Selection;
+ this.world = world;
+ }
+
+ protected override bool OnHotkeyActivated(KeyInput e)
+ {
+ var player = world.RenderPlayer ?? world.LocalPlayer;
+
+ var bases = world.ActorsHavingTrait()
+ .Where(a => a.Owner == player)
+ .ToList();
+
+ // If no BaseBuilding exist pick the first selectable Building.
+ if (!bases.Any())
+ {
+ var building = world.ActorsHavingTrait()
+ .FirstOrDefault(a => a.Owner == player && a.Info.HasTraitInfo());
+
+ // No buildings left
+ if (building == null)
+ return true;
+
+ selection.Combine(world, new Actor[] { building }, false, true);
+ viewport.Center(selection.Actors);
+ return true;
+ }
+
+ var next = bases
+ .SkipWhile(b => !selection.Contains(b))
+ .Skip(1)
+ .FirstOrDefault();
+
+ if (next == null)
+ next = bases.First();
+
+ selection.Combine(world, new Actor[] { next }, false, true);
+ viewport.Center(selection.Actors);
+
+ return true;
+ }
+ }
+}
diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/Hotkeys/CycleProductionActorsHotkeyLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/Hotkeys/CycleProductionActorsHotkeyLogic.cs
new file mode 100644
index 0000000000..b550855885
--- /dev/null
+++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/Hotkeys/CycleProductionActorsHotkeyLogic.cs
@@ -0,0 +1,65 @@
+#region Copyright & License Information
+/*
+ * Copyright 2007-2017 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, either version 3 of
+ * the License, or (at your option) any later version. For more
+ * information, see COPYING.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using OpenRA.Graphics;
+using OpenRA.Mods.Common.Lint;
+using OpenRA.Mods.Common.Traits;
+using OpenRA.Widgets;
+
+namespace OpenRA.Mods.Common.Widgets.Logic.Ingame
+{
+ [ChromeLogicArgsHotkeys("CycleProductionActorsKey")]
+ public class CycleProductionActorsHotkeyLogic : SingleHotkeyBaseLogic
+ {
+ readonly Viewport viewport;
+ readonly Selection selection;
+ readonly World world;
+
+ [ObjectCreator.UseCtor]
+ public CycleProductionActorsHotkeyLogic(Widget widget, WorldRenderer worldRenderer, World world, Dictionary logicArgs)
+ : base(widget, "CycleProductionActorsKey", "WORLD_KEYHANDLER", logicArgs)
+ {
+ viewport = worldRenderer.Viewport;
+ selection = world.Selection;
+ this.world = world;
+ }
+
+ protected override bool OnHotkeyActivated(KeyInput e)
+ {
+ var player = world.RenderPlayer ?? world.LocalPlayer;
+
+ var facilities = world.ActorsHavingTrait()
+ .Where(a => a.Owner == player && !a.Info.HasTraitInfo())
+ .OrderBy(f => f.Info.TraitInfo().Produces.First())
+ .ToList();
+
+ if (!facilities.Any())
+ return true;
+
+ var next = facilities
+ .SkipWhile(b => !selection.Contains(b))
+ .Skip(1)
+ .FirstOrDefault();
+
+ if (next == null)
+ next = facilities.First();
+
+ Game.Sound.PlayNotification(world.Map.Rules, null, "Sounds", "ClickSound", null);
+
+ selection.Combine(world, new Actor[] { next }, false, true);
+ viewport.Center(selection.Actors);
+
+ return true;
+ }
+ }
+}
diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/Hotkeys/JumpToLastEventHotkeyLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/Hotkeys/JumpToLastEventHotkeyLogic.cs
new file mode 100644
index 0000000000..f5988b56e5
--- /dev/null
+++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/Hotkeys/JumpToLastEventHotkeyLogic.cs
@@ -0,0 +1,44 @@
+#region Copyright & License Information
+/*
+ * Copyright 2007-2017 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, either version 3 of
+ * the License, or (at your option) any later version. For more
+ * information, see COPYING.
+ */
+#endregion
+
+using System.Collections.Generic;
+using OpenRA.Graphics;
+using OpenRA.Mods.Common.Lint;
+using OpenRA.Mods.Common.Traits;
+using OpenRA.Widgets;
+
+namespace OpenRA.Mods.Common.Widgets.Logic.Ingame
+{
+ [ChromeLogicArgsHotkeys("JumpToLastEventKey")]
+ public class JumpToLastEventHotkeyLogic : SingleHotkeyBaseLogic
+ {
+ readonly Viewport viewport;
+ readonly RadarPings radarPings;
+
+ [ObjectCreator.UseCtor]
+ public JumpToLastEventHotkeyLogic(Widget widget, WorldRenderer worldRenderer, World world, Dictionary logicArgs)
+ : base(widget, "JumpToLastEventKey", "WORLD_KEYHANDLER", logicArgs)
+ {
+ viewport = worldRenderer.Viewport;
+ radarPings = world.WorldActor.TraitOrDefault();
+ }
+
+ protected override bool OnHotkeyActivated(KeyInput e)
+ {
+ if (radarPings == null || radarPings.LastPingPosition == null)
+ return true;
+
+ viewport.Center(radarPings.LastPingPosition.Value);
+
+ return true;
+ }
+ }
+}
diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/Hotkeys/JumpToSelectedActorsHotkeyLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/Hotkeys/JumpToSelectedActorsHotkeyLogic.cs
new file mode 100644
index 0000000000..0418ba3e9b
--- /dev/null
+++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/Hotkeys/JumpToSelectedActorsHotkeyLogic.cs
@@ -0,0 +1,40 @@
+#region Copyright & License Information
+/*
+ * Copyright 2007-2017 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, either version 3 of
+ * the License, or (at your option) any later version. For more
+ * information, see COPYING.
+ */
+#endregion
+
+using System.Collections.Generic;
+using OpenRA.Graphics;
+using OpenRA.Mods.Common.Lint;
+using OpenRA.Widgets;
+
+namespace OpenRA.Mods.Common.Widgets.Logic.Ingame
+{
+ [ChromeLogicArgsHotkeys("JumpToSelectedActorsKey")]
+ public class JumpToSelectedActorsHotkeyLogic : SingleHotkeyBaseLogic
+ {
+ readonly Viewport viewport;
+ readonly Selection selection;
+
+ [ObjectCreator.UseCtor]
+ public JumpToSelectedActorsHotkeyLogic(Widget widget, WorldRenderer worldRenderer, World world, Dictionary logicArgs)
+ : base(widget, "JumpToSelectedActorsKey", "WORLD_KEYHANDLER", logicArgs)
+ {
+ viewport = worldRenderer.Viewport;
+ selection = world.Selection;
+ }
+
+ protected override bool OnHotkeyActivated(KeyInput e)
+ {
+ viewport.Center(selection.Actors);
+
+ return true;
+ }
+ }
+}
diff --git a/OpenRA.Mods.Common/Widgets/WorldCommandWidget.cs b/OpenRA.Mods.Common/Widgets/WorldCommandWidget.cs
deleted file mode 100644
index 7c991dbd68..0000000000
--- a/OpenRA.Mods.Common/Widgets/WorldCommandWidget.cs
+++ /dev/null
@@ -1,148 +0,0 @@
-#region Copyright & License Information
-/*
- * Copyright 2007-2017 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, either version 3 of
- * the License, or (at your option) any later version. For more
- * information, see COPYING.
- */
-#endregion
-
-using System;
-using System.Drawing;
-using System.Linq;
-using OpenRA.Graphics;
-using OpenRA.Mods.Common.Traits;
-using OpenRA.Traits;
-using OpenRA.Widgets;
-
-namespace OpenRA.Mods.Common.Widgets
-{
- /// Contains all functions that are valid for players and observers/spectators.
- public class WorldCommandWidget : Widget
- {
- readonly World world;
- readonly WorldRenderer worldRenderer;
- readonly RadarPings radarPings;
-
- [ObjectCreator.UseCtor]
- public WorldCommandWidget(World world, WorldRenderer worldRenderer)
- {
- this.world = world;
- this.worldRenderer = worldRenderer;
- radarPings = world.WorldActor.TraitOrDefault();
- }
-
- public override string GetCursor(int2 pos) { return null; }
- public override Rectangle GetEventBounds() { return Rectangle.Empty; }
-
- public override bool HandleKeyPress(KeyInput e)
- {
- if (world == null)
- return false;
-
- return ProcessInput(e);
- }
-
- bool ProcessInput(KeyInput e)
- {
- if (e.Event == KeyInputEvent.Down)
- {
- var key = Hotkey.FromKeyInput(e);
- var ks = Game.Settings.Keys;
-
- if (key == ks.CycleBaseKey)
- return CycleBases();
-
- if (key == ks.CycleProductionBuildingsKey)
- return CycleProductionBuildings();
-
- if (key == ks.ToLastEventKey)
- return ToLastEvent();
-
- if (key == ks.ToSelectionKey)
- return ToSelection();
- }
-
- return false;
- }
-
- bool CycleBases()
- {
- var player = world.RenderPlayer ?? world.LocalPlayer;
-
- var bases = world.ActorsHavingTrait()
- .Where(a => a.Owner == player)
- .ToList();
-
- // If no BaseBuilding exist pick the first selectable Building.
- if (!bases.Any())
- {
- var building = world.ActorsHavingTrait()
- .FirstOrDefault(a => a.Owner == player && a.Info.HasTraitInfo());
-
- // No buildings left
- if (building == null)
- return true;
-
- world.Selection.Combine(world, new Actor[] { building }, false, true);
- return ToSelection();
- }
-
- var next = bases
- .SkipWhile(b => !world.Selection.Contains(b))
- .Skip(1)
- .FirstOrDefault();
-
- if (next == null)
- next = bases.First();
-
- world.Selection.Combine(world, new Actor[] { next }, false, true);
-
- return ToSelection();
- }
-
- bool CycleProductionBuildings()
- {
- var player = world.RenderPlayer ?? world.LocalPlayer;
-
- var facilities = world.ActorsHavingTrait()
- .Where(a => a.Owner == player && !a.Info.HasTraitInfo())
- .OrderBy(f => f.Info.TraitInfo().Produces.First())
- .ToList();
-
- if (!facilities.Any())
- return true;
-
- var next = facilities
- .SkipWhile(b => !world.Selection.Contains(b))
- .Skip(1)
- .FirstOrDefault();
-
- if (next == null)
- next = facilities.First();
-
- world.Selection.Combine(world, new Actor[] { next }, false, true);
-
- Game.Sound.PlayNotification(world.Map.Rules, null, "Sounds", "ClickSound", null);
-
- return ToSelection();
- }
-
- bool ToLastEvent()
- {
- if (radarPings == null || radarPings.LastPingPosition == null)
- return true;
-
- worldRenderer.Viewport.Center(radarPings.LastPingPosition.Value);
- return true;
- }
-
- bool ToSelection()
- {
- worldRenderer.Viewport.Center(world.Selection.Actors);
- return true;
- }
- }
-}
diff --git a/mods/cnc/chrome/ingame.yaml b/mods/cnc/chrome/ingame.yaml
index f185bbd44f..de545149c4 100644
--- a/mods/cnc/chrome/ingame.yaml
+++ b/mods/cnc/chrome/ingame.yaml
@@ -9,6 +9,12 @@ Container@INGAME_ROOT:
NextMusicKey: NextMusic
TakeScreenshotKey: TakeScreenshot
MuteAudioKey: ToggleMute
+ LogicKeyListener@WORLD_KEYHANDLER:
+ Logic: CycleBasesHotkeyLogic, CycleProductionActorsHotkeyLogic, JumpToLastEventHotkeyLogic, JumpToSelectedActorsHotkeyLogic
+ CycleBasesKey: CycleBase
+ CycleProductionActorsKey: CycleProductionBuildings
+ JumpToLastEventKey: ToLastEvent
+ JumpToSelectedActorsKey: ToSelection
Container@WORLD_ROOT:
Logic: LoadIngamePerfLogic
Children:
@@ -44,9 +50,6 @@ Container@INGAME_ROOT:
BookmarkSaveKeyPrefix: MapBookmarkSave
BookmarkRestoreKeyPrefix: MapBookmarkRestore
BookmarkKeyCount: 4
- WorldCommand:
- Width: WINDOW_RIGHT
- Height: WINDOW_BOTTOM
Container@GAME_TIMER_BLOCK:
Logic: GameTimerLogic
X: WINDOW_RIGHT / 2 - WIDTH
diff --git a/mods/common/chrome/ingame.yaml b/mods/common/chrome/ingame.yaml
index eee5a75ee7..7777821928 100644
--- a/mods/common/chrome/ingame.yaml
+++ b/mods/common/chrome/ingame.yaml
@@ -9,6 +9,12 @@ Container@INGAME_ROOT:
NextMusicKey: NextMusic
TakeScreenshotKey: TakeScreenshot
MuteAudioKey: ToggleMute
+ LogicKeyListener@WORLD_KEYHANDLER:
+ Logic: CycleBasesHotkeyLogic, CycleProductionActorsHotkeyLogic, JumpToLastEventHotkeyLogic, JumpToSelectedActorsHotkeyLogic
+ CycleBasesKey: CycleBase
+ CycleProductionActorsKey: CycleProductionBuildings
+ JumpToLastEventKey: ToLastEvent
+ JumpToSelectedActorsKey: ToSelection
Container@WORLD_ROOT:
Logic: LoadIngamePerfLogic
Children:
@@ -40,9 +46,6 @@ Container@INGAME_ROOT:
BookmarkSaveKeyPrefix: MapBookmarkSave
BookmarkRestoreKeyPrefix: MapBookmarkRestore
BookmarkKeyCount: 4
- WorldCommand:
- Width: WINDOW_RIGHT
- Height: WINDOW_BOTTOM
StrategicProgress@STRATEGIC_PROGRESS:
X: WINDOW_RIGHT / 2
Y: 40