diff --git a/OpenRA.Game/GameRules/Settings.cs b/OpenRA.Game/GameRules/Settings.cs index f1804f9fda..d388883f7f 100644 --- a/OpenRA.Game/GameRules/Settings.cs +++ b/OpenRA.Game/GameRules/Settings.cs @@ -165,6 +165,9 @@ namespace OpenRA.GameRules public Hotkey DeployKey = new Hotkey(Keycode.F, Modifiers.None); public Hotkey StanceCycleKey = new Hotkey(Keycode.Z, Modifiers.None); public Hotkey GuardKey = new Hotkey(Keycode.D, Modifiers.None); + + public Hotkey ObserverCombinedView = new Hotkey(Keycode.MINUS, Modifiers.None); + public Hotkey ObserverWorldView = new Hotkey(Keycode.EQUALS, Modifiers.None); } public class IrcSettings diff --git a/OpenRA.Mods.RA/Widgets/Logic/ObserverShroudSelectorLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/ObserverShroudSelectorLogic.cs index 8ad31630a8..90e5d443c2 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/ObserverShroudSelectorLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/ObserverShroudSelectorLogic.cs @@ -20,9 +20,12 @@ namespace OpenRA.Mods.RA.Widgets.Logic public class ObserverShroudSelectorLogic { CameraOption selected; + CameraOption combined, disableShroud; + IOrderedEnumerable> teams; class CameraOption { + public readonly Player Player; public readonly string Label; public readonly Color Color; public readonly string Race; @@ -31,6 +34,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic public CameraOption(ObserverShroudSelectorLogic logic, Player p) { + Player = p; Label = p.PlayerName; Color = p.Color.RGB; Race = p.Country.Race; @@ -40,6 +44,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic public CameraOption(ObserverShroudSelectorLogic logic, World w, string label, Player p) { + Player = p; Label = label; Color = Color.White; Race = null; @@ -53,23 +58,21 @@ namespace OpenRA.Mods.RA.Widgets.Logic { var groups = new Dictionary>(); - var teams = world.Players.Where(p => !p.NonCombatant) - .GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.ClientIndex) ?? new Session.Client()).Team).OrderBy(g => g.Key); - var noTeams = teams.Count() == 1; + teams = world.Players.Where(p => !p.NonCombatant) + .Select(p => new CameraOption(this, p)) + .GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.Player.ClientIndex) ?? new Session.Client()).Team) + .OrderBy(g => g.Key); + var noTeams = teams.Count() == 1; foreach (var t in teams) { var label = noTeams ? "Players" : t.Key == 0 ? "No Team" : "Team {0}".F(t.Key); - groups.Add(label, t.Select(p => new CameraOption(this, p))); + groups.Add(label, t); } - var combined = world.Players.First(p => p.InternalName == "Everyone"); - var disableShroud = new CameraOption(this, world, "Disable Shroud", null); - groups.Add("Other", new List() - { - new CameraOption(this, world, "All Players", combined), - disableShroud - }); + combined = new CameraOption(this, world, "All Players", world.Players.First(p => p.InternalName == "Everyone")); + disableShroud = new CameraOption(this, world, "Disable Shroud", null); + groups.Add("Other", new List() { combined, disableShroud }); var shroudSelector = widget.Get("SHROUD_SELECTOR"); shroudSelector.OnMouseDown = _ => @@ -115,7 +118,51 @@ namespace OpenRA.Mods.RA.Widgets.Logic shroudLabelAlt.GetText = () => selected.Label; shroudLabelAlt.GetColor = () => selected.Color; + var keyhandler = shroudSelector.Get("SHROUD_KEYHANDLER"); + keyhandler.OnKeyPress = HandleKeyPress; + selected = disableShroud; } + + public bool HandleKeyPress(KeyInput e) + { + if (e.Event == KeyInputEvent.Down) + { + var h = Hotkey.FromKeyInput(e); + if (h == Game.Settings.Keys.ObserverCombinedView) + { + selected = combined; + selected.OnClick(); + + return true; + } + + if (h == Game.Settings.Keys.ObserverWorldView) + { + selected = disableShroud; + selected.OnClick(); + + return true; + } + + if (e.Key >= Keycode.NUMBER_0 && e.Key <= Keycode.NUMBER_9) + { + var key = (int)e.Key - (int)Keycode.NUMBER_0; + var team = teams.Where(t => t.Key == key).SelectMany(s => s); + if (!team.Any()) + return false; + + if (e.Modifiers == Modifiers.Shift) + team = team.Reverse(); + + selected = team.SkipWhile(t => t.Player != selected.Player).Skip(1).FirstOrDefault() ?? team.FirstOrDefault(); + selected.OnClick(); + + return true; + } + } + + return false; + } } } diff --git a/OpenRA.Mods.RA/Widgets/Logic/SettingsLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/SettingsLogic.cs index d59cc7a376..ad4fb07e4c 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/SettingsLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/SettingsLogic.cs @@ -279,6 +279,12 @@ namespace OpenRA.Mods.RA.Widgets.Logic { "GuardKey", "Guard" } }; + var observerHotkeys = new Dictionary() + { + { "ObserverCombinedView", "All Players" }, + { "ObserverWorldView", "Disable Shroud" } + }; + var gs = Game.Settings.Game; var ks = Game.Settings.Keys; @@ -304,6 +310,13 @@ namespace OpenRA.Mods.RA.Widgets.Logic foreach (var kv in specialHotkeys) BindHotkeyPref(kv, ks, globalTemplate, hotkeyList); + var observerHeader = ScrollItemWidget.Setup(hotkeyHeader, () => true, () => {}); + observerHeader.Get("LABEL").GetText = () => "Observer Commands"; + hotkeyList.AddChild(observerHeader); + + foreach (var kv in observerHotkeys) + BindHotkeyPref(kv, ks, globalTemplate, hotkeyList); + var unitHeader = ScrollItemWidget.Setup(hotkeyHeader, () => true, () => {}); unitHeader.Get("LABEL").GetText = () => "Unit Commands"; hotkeyList.AddChild(unitHeader); diff --git a/mods/cnc/chrome/ingame.yaml b/mods/cnc/chrome/ingame.yaml index 6869282c68..4c2c4a8732 100644 --- a/mods/cnc/chrome/ingame.yaml +++ b/mods/cnc/chrome/ingame.yaml @@ -159,6 +159,7 @@ Container@OBSERVER_WIDGETS: Height:25 Font:Bold Children: + LogicKeyListener@SHROUD_KEYHANDLER: Image@FLAG: X:4 Y:4 diff --git a/mods/d2k/chrome/ingame-observer.yaml b/mods/d2k/chrome/ingame-observer.yaml index e72dd8a65d..e6b4c3b3e4 100644 --- a/mods/d2k/chrome/ingame-observer.yaml +++ b/mods/d2k/chrome/ingame-observer.yaml @@ -34,6 +34,7 @@ Container@OBSERVER_WIDGETS: Height:25 Font:Bold Children: + LogicKeyListener@SHROUD_KEYHANDLER: Image@FLAG: Width:23 Height:23 diff --git a/mods/ra/chrome/ingame-observer.yaml b/mods/ra/chrome/ingame-observer.yaml index ebb3cf3082..fd36d32d45 100644 --- a/mods/ra/chrome/ingame-observer.yaml +++ b/mods/ra/chrome/ingame-observer.yaml @@ -34,6 +34,7 @@ Container@OBSERVER_WIDGETS: Height:25 Font:Bold Children: + LogicKeyListener@SHROUD_KEYHANDLER: Image@FLAG: X:4 Y:4