diff --git a/OpenRA.Game/Settings.cs b/OpenRA.Game/Settings.cs index 9878eedbba..34d79e33bf 100644 --- a/OpenRA.Game/Settings.cs +++ b/OpenRA.Game/Settings.cs @@ -178,6 +178,42 @@ namespace OpenRA public Hotkey TogglePixelDoubleKey = new Hotkey(Keycode.PERIOD, Modifiers.None); public Hotkey DevReloadChromeKey = new Hotkey(Keycode.C, Modifiers.Ctrl | Modifiers.Shift); + + public Hotkey Production01Key = new Hotkey(Keycode.F1, Modifiers.None); + public Hotkey Production02Key = new Hotkey(Keycode.F2, Modifiers.None); + public Hotkey Production03Key = new Hotkey(Keycode.F3, Modifiers.None); + public Hotkey Production04Key = new Hotkey(Keycode.F4, Modifiers.None); + public Hotkey Production05Key = new Hotkey(Keycode.F5, Modifiers.None); + public Hotkey Production06Key = new Hotkey(Keycode.F6, Modifiers.None); + public Hotkey Production07Key = new Hotkey(Keycode.F7, Modifiers.None); + public Hotkey Production08Key = new Hotkey(Keycode.F8, Modifiers.None); + public Hotkey Production09Key = new Hotkey(Keycode.F9, Modifiers.None); + public Hotkey Production10Key = new Hotkey(Keycode.F10, Modifiers.None); + public Hotkey Production11Key = new Hotkey(Keycode.F11, Modifiers.None); + public Hotkey Production12Key = new Hotkey(Keycode.F12, Modifiers.None); + + public Hotkey Production13Key = new Hotkey(Keycode.F1, Modifiers.Ctrl); + public Hotkey Production14Key = new Hotkey(Keycode.F2, Modifiers.Ctrl); + public Hotkey Production15Key = new Hotkey(Keycode.F3, Modifiers.Ctrl); + public Hotkey Production16Key = new Hotkey(Keycode.F4, Modifiers.Ctrl); + public Hotkey Production17Key = new Hotkey(Keycode.F5, Modifiers.Ctrl); + public Hotkey Production18Key = new Hotkey(Keycode.F6, Modifiers.Ctrl); + public Hotkey Production19Key = new Hotkey(Keycode.F7, Modifiers.Ctrl); + public Hotkey Production20Key = new Hotkey(Keycode.F8, Modifiers.Ctrl); + public Hotkey Production21Key = new Hotkey(Keycode.F9, Modifiers.Ctrl); + public Hotkey Production22Key = new Hotkey(Keycode.F10, Modifiers.Ctrl); + public Hotkey Production23Key = new Hotkey(Keycode.F11, Modifiers.Ctrl); + public Hotkey Production24Key = new Hotkey(Keycode.F12, Modifiers.Ctrl); + + + public Hotkey GetProductionHotkey(int index) + { + var field = GetType().GetField("Production{0:D2}Key".F(index + 1)); + if (field == null) + return Hotkey.Invalid; + + return (Hotkey)field.GetValue(this); + } } public class IrcSettings diff --git a/OpenRA.Mods.D2k/Widgets/BuildPaletteWidget.cs b/OpenRA.Mods.D2k/Widgets/BuildPaletteWidget.cs index 2e121ab391..fa0b685bfa 100644 --- a/OpenRA.Mods.D2k/Widgets/BuildPaletteWidget.cs +++ b/OpenRA.Mods.D2k/Widgets/BuildPaletteWidget.cs @@ -233,6 +233,8 @@ namespace OpenRA.Mods.D2k.Widgets // Icons string tooltipItem = null; + var tooltipHotkey = Hotkey.Invalid; + var i = 0; foreach (var item in allBuildables) { var rect = new RectangleF(origin.X + x * IconWidth, origin.Y + IconHeight * y, IconWidth, IconHeight); @@ -244,7 +246,10 @@ namespace OpenRA.Mods.D2k.Widgets var firstOfThis = queue.AllQueued().FirstOrDefault(a => a.Item == item.Name); if (rect.Contains(Viewport.LastMousePos)) + { tooltipItem = item.Name; + tooltipHotkey = Game.Settings.Keys.GetProductionHotkey(i); + } var overlayPos = drawPos + new float2(32, 16); @@ -271,6 +276,7 @@ namespace OpenRA.Mods.D2k.Widgets buttons.Add(Pair.New(new Rectangle((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height), HandleClick(closureName, world))); if (++x == Columns) { x = 0; y++; } + i++; } if (x != 0) y++; @@ -291,7 +297,7 @@ namespace OpenRA.Mods.D2k.Widgets // Tooltip if (tooltipItem != null && !paletteAnimating && paletteOpen) - DrawProductionTooltip(world, tooltipItem, + DrawProductionTooltip(world, tooltipItem, tooltipHotkey, new float2(Game.Renderer.Resolution.Width, origin.Y + numActualRows * IconHeight + 9).ToInt2()); } @@ -466,7 +472,7 @@ namespace OpenRA.Mods.D2k.Widgets font.DrawText(text, pos - new int2(font.Measure(text).X, 0), c); } - void DrawProductionTooltip(World world, string unit, int2 pos) + void DrawProductionTooltip(World world, string unit, Hotkey hotkey, int2 pos) { pos.Y += 15; @@ -485,7 +491,7 @@ namespace OpenRA.Mods.D2k.Widgets WidgetUtils.DrawPanel("dialog4", new Rectangle(Game.Renderer.Resolution.Width - 300, pos.Y, 300, longDescSize + 65)); Game.Renderer.Fonts["Bold"].DrawText( - tooltip.Name + (buildable.Hotkey.IsValid() ? " ({0})".F(buildable.Hotkey.DisplayString()) : ""), + tooltip.Name + (hotkey.IsValid() ? " ({0})".F(hotkey.DisplayString()) : ""), p.ToInt2() + new int2(5, 5), Color.White); var resources = pl.PlayerActor.Trait(); @@ -526,8 +532,20 @@ namespace OpenRA.Mods.D2k.Widgets if (!paletteOpen) return false; if (CurrentQueue == null) return false; - var toBuild = CurrentQueue.BuildableItems().FirstOrDefault(b => b.Traits.Get().Hotkey == Hotkey.FromKeyInput(e)); + var key = Hotkey.FromKeyInput(e); + var ks = Game.Settings.Keys; + var slot = -1; + for (var i = 0; i < 24; i++) + { + if (ks.GetProductionHotkey(i) == key) + { + slot = i; + break; + } + } + var allBuildables = CurrentQueue.AllItems().OrderBy(a => a.Traits.Get().BuildPaletteOrder).ToArray(); + var toBuild = allBuildables.ElementAtOrDefault(slot); if (toBuild != null) { Sound.PlayNotification(world.Map.Rules, null, "Sounds", "TabClick", null); diff --git a/OpenRA.Mods.RA/Widgets/Logic/ProductionTooltipLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/ProductionTooltipLogic.cs index 96cae4ea8f..7778a1c66e 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/ProductionTooltipLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/ProductionTooltipLogic.cs @@ -27,7 +27,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic var pm = palette.World.LocalPlayer.PlayerActor.Trait(); var pr = palette.World.LocalPlayer.PlayerActor.Trait(); - widget.IsVisible = () => palette.TooltipActor != null; + widget.IsVisible = () => palette.TooltipIcon != null; var nameLabel = widget.Get("NAME"); var hotkeyLabel = widget.Get("HOTKEY"); var requiresLabel = widget.Get("REQUIRES"); @@ -44,29 +44,31 @@ namespace OpenRA.Mods.RA.Widgets.Logic var font = Game.Renderer.Fonts[nameLabel.Font]; var descFont = Game.Renderer.Fonts[descLabel.Font]; var requiresFont = Game.Renderer.Fonts[requiresLabel.Font]; - string lastActor = null; + ActorInfo lastActor = null; tooltipContainer.BeforeRender = () => { - var actor = palette.TooltipActor; + if (palette.TooltipIcon == null) + return; + + var actor = palette.TooltipIcon.Actor; if (actor == null || actor == lastActor) return; - var info = mapRules.Actors[actor]; - var tooltip = info.Traits.Get(); - var buildable = info.Traits.Get(); - var cost = info.Traits.Get().Cost; - var pi = info.Traits.GetOrDefault(); + var tooltip = actor.Traits.Get(); + var buildable = actor.Traits.Get(); + var cost = actor.Traits.Get().Cost; + var pi = actor.Traits.GetOrDefault(); nameLabel.GetText = () => tooltip.Name; + var hotkey = palette.TooltipIcon.Hotkey; var nameWidth = font.Measure(tooltip.Name).X; - var hotkeyText = "({0})".F(buildable.Hotkey.DisplayString()); - var hotkeyWidth = buildable.Hotkey.IsValid() ? font.Measure(hotkeyText).X + 2 * nameLabel.Bounds.X : 0; + var hotkeyText = "({0})".F(hotkey.DisplayString()); + var hotkeyWidth = hotkey.IsValid() ? font.Measure(hotkeyText).X + 2 * nameLabel.Bounds.X : 0; hotkeyLabel.GetText = () => hotkeyText; hotkeyLabel.Bounds.X = nameWidth + 2 * nameLabel.Bounds.X; - hotkeyLabel.Visible = buildable.Hotkey.IsValid(); - + hotkeyLabel.Visible = hotkey.IsValid(); var prereqs = buildable.Prerequisites.Select(a => ActorName(mapRules, a)).Where(s => !s.StartsWith("~")); var requiresString = prereqs.Any() ? requiresLabel.Text.F(prereqs.JoinWith(", ")) : ""; @@ -81,7 +83,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic powerIcon.IsVisible = () => power != 0; var lowpower = pm.PowerState != PowerState.Normal; - var time = palette.CurrentQueue == null ? 0 : palette.CurrentQueue.GetBuildTime(actor) + var time = palette.CurrentQueue == null ? 0 : palette.CurrentQueue.GetBuildTime(actor.Name) * (lowpower ? palette.CurrentQueue.Info.LowPowerSlowdown : 1); var timeString = WidgetUtils.FormatTime(time); timeLabel.GetText = () => timeString; diff --git a/OpenRA.Mods.RA/Widgets/Logic/SettingsLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/SettingsLogic.cs index 4b3a7b51bb..6d9c0a2d0b 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/SettingsLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/SettingsLogic.cs @@ -305,6 +305,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic var hotkeyHeader = hotkeyList.Get("HEADER"); var globalTemplate = hotkeyList.Get("GLOBAL_TEMPLATE"); var unitTemplate = hotkeyList.Get("UNIT_TEMPLATE"); + var productionTemplate = hotkeyList.Get("PRODUCTION_TEMPLATE"); hotkeyList.RemoveChildren(); // Game @@ -376,6 +377,20 @@ namespace OpenRA.Mods.RA.Widgets.Logic BindHotkeyPref(kv, ks, unitTemplate, hotkeyList); } + // Production + { + var hotkeys = new Dictionary(); + for (var i = 1; i <= 24; i++) + hotkeys.Add("Production{0:D2}Key".F(i), "Slot {0}".F(i)); + + var header = ScrollItemWidget.Setup(hotkeyHeader, () => true, () => {}); + header.Get("LABEL").GetText = () => "Production Commands"; + hotkeyList.AddChild(header); + + foreach (var kv in hotkeys) + BindHotkeyPref(kv, ks, productionTemplate, hotkeyList); + } + // Developer { var hotkeys = new Dictionary() diff --git a/OpenRA.Mods.RA/Widgets/ProductionPaletteWidget.cs b/OpenRA.Mods.RA/Widgets/ProductionPaletteWidget.cs index b8088a9398..64609f7117 100644 --- a/OpenRA.Mods.RA/Widgets/ProductionPaletteWidget.cs +++ b/OpenRA.Mods.RA/Widgets/ProductionPaletteWidget.cs @@ -25,6 +25,7 @@ namespace OpenRA.Mods.RA.Widgets { public class ProductionIcon { + public ActorInfo Actor; public string Name; public Hotkey Hotkey; public Sprite Sprite; @@ -53,7 +54,7 @@ namespace OpenRA.Mods.RA.Widgets public int IconCount { get; private set; } public event Action OnIconCountChanged = (a, b) => {}; - public string TooltipActor { get; private set; } + public ProductionIcon TooltipIcon { get; private set; } public readonly World World; readonly OrderManager orderManager; @@ -116,7 +117,7 @@ namespace OpenRA.Mods.RA.Widgets .Select(i => i.Value).FirstOrDefault(); if (mi.Event == MouseInputEvent.Move) - TooltipActor = icon != null ? icon.Name : null; + TooltipIcon = icon; if (icon == null) return false; @@ -218,6 +219,7 @@ namespace OpenRA.Mods.RA.Widgets var oldIconCount = IconCount; IconCount = 0; + var ks = Game.Settings.Keys; var rb = RenderBounds; foreach (var item in allBuildables) { @@ -229,8 +231,9 @@ namespace OpenRA.Mods.RA.Widgets var pi = new ProductionIcon() { + Actor = item, Name = item.Name, - Hotkey = item.Traits.Get().Hotkey, + Hotkey = ks.GetProductionHotkey(IconCount), Sprite = icon.Image, Pos = new float2(rect.Location), Queued = CurrentQueue.AllQueued().Where(a => a.Item == item.Name).ToList(), diff --git a/mods/cnc/chrome/settings.yaml b/mods/cnc/chrome/settings.yaml index 183b6e7265..e5cf54d542 100644 --- a/mods/cnc/chrome/settings.yaml +++ b/mods/cnc/chrome/settings.yaml @@ -399,6 +399,20 @@ Container@SETTINGS_PANEL: X: PARENT_RIGHT-WIDTH+1 Width: 80 Height: 25 + Container@PRODUCTION_TEMPLATE: + Width: 173 + Height: 25 + Visible: false + Children: + Label@FUNCTION: + Y: 0-1 + Width: PARENT_RIGHT - 84 + Height: 25 + Align: Right + HotkeyEntry@HOTKEY: + X: PARENT_RIGHT-WIDTH+1 + Width: 80 + Height: 25 Container@ADVANCED_PANEL: Width: PARENT_RIGHT Height: PARENT_BOTTOM diff --git a/mods/ra/chrome/settings.yaml b/mods/ra/chrome/settings.yaml index a12c52277d..d81d63fddd 100644 --- a/mods/ra/chrome/settings.yaml +++ b/mods/ra/chrome/settings.yaml @@ -404,6 +404,20 @@ Background@SETTINGS_PANEL: X: PARENT_RIGHT-WIDTH+1 Width: 80 Height: 25 + Container@PRODUCTION_TEMPLATE: + Width: 173 + Height: 25 + Visible: false + Children: + Label@FUNCTION: + Y: 0-1 + Width: PARENT_RIGHT - 84 + Height: 25 + Align: Right + HotkeyEntry@HOTKEY: + X: PARENT_RIGHT-WIDTH+1 + Width: 80 + Height: 25 Container@ADVANCED_PANEL: X: 5 Y: 50