diff --git a/OpenRA.Game/HotkeyDefinition.cs b/OpenRA.Game/HotkeyDefinition.cs new file mode 100644 index 0000000000..ea97a28bf9 --- /dev/null +++ b/OpenRA.Game/HotkeyDefinition.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 System.Linq; + +namespace OpenRA +{ + public sealed class HotkeyDefinition + { + public readonly string Name; + public readonly Hotkey Default = Hotkey.Invalid; + public readonly string Description = ""; + public readonly HashSet Types = new HashSet(); + + public HotkeyDefinition(string name, MiniYaml node) + { + Name = name; + + if (!string.IsNullOrEmpty(node.Value)) + Default = FieldLoader.GetValue("value", node.Value); + + var descriptionNode = node.Nodes.FirstOrDefault(n => n.Key == "Description"); + if (descriptionNode != null) + Description = descriptionNode.Value.Value; + + var typesNode = node.Nodes.FirstOrDefault(n => n.Key == "Types"); + if (typesNode != null) + Types = FieldLoader.GetValue>("Types", typesNode.Value.Value); + } + } +} \ No newline at end of file diff --git a/OpenRA.Game/HotkeyManager.cs b/OpenRA.Game/HotkeyManager.cs new file mode 100644 index 0000000000..421fec1aeb --- /dev/null +++ b/OpenRA.Game/HotkeyManager.cs @@ -0,0 +1,69 @@ +#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.Collections.Generic; +using OpenRA.FileSystem; + +namespace OpenRA +{ + public sealed class HotkeyManager + { + readonly KeySettings settings; + readonly Dictionary keys = new Dictionary(); + + public HotkeyManager(IReadOnlyFileSystem fileSystem, KeySettings settings, Manifest manifest) + { + this.settings = settings; + + var keyDefinitions = MiniYaml.Load(fileSystem, manifest.Hotkeys, null); + foreach (var kd in keyDefinitions) + keys[kd.Key] = new HotkeyDefinition(kd.Key, kd.Value); + } + + internal Func GetHotkeyReference(string name) + { + var ret = settings.GetHotkeyReference(name); + if (ret != null) + return ret; + + HotkeyDefinition keyDefinition; + if (keys.TryGetValue(name, out keyDefinition)) + return () => keyDefinition.Default; + + // Not a mod-defined hotkey, so try and parse as a hardcoded definition + Hotkey key; + if (!Hotkey.TryParse(name, out key)) + key = Hotkey.Invalid; + + return () => key; + } + + public void Set(string name, Hotkey value) + { + var field = settings.GetType().GetField(name + "Key"); + if (field == null) + return; + + field.SetValue(settings, value); + } + + public HotkeyReference this[string name] + { + get + { + return new HotkeyReference(GetHotkeyReference(name)); + } + } + + public IEnumerable Definitions { get { return keys.Values; } } + } +} diff --git a/OpenRA.Game/Input/HotkeyReference.cs b/OpenRA.Game/Input/HotkeyReference.cs index 83f75d66fa..9c38112706 100644 --- a/OpenRA.Game/Input/HotkeyReference.cs +++ b/OpenRA.Game/Input/HotkeyReference.cs @@ -27,6 +27,11 @@ namespace OpenRA getValue = Invalid; } + internal HotkeyReference(Func getValue) + { + this.getValue = getValue; + } + public HotkeyReference(string name, KeySettings settings) { // Try parsing the value as a reference to a named hotkey diff --git a/OpenRA.Game/Manifest.cs b/OpenRA.Game/Manifest.cs index fd0df0f62f..8914b631e1 100644 --- a/OpenRA.Game/Manifest.cs +++ b/OpenRA.Game/Manifest.cs @@ -59,7 +59,7 @@ namespace OpenRA Rules, ServerTraits, Sequences, ModelSequences, Cursors, Chrome, Assemblies, ChromeLayout, Weapons, Voices, Notifications, Music, Translations, TileSets, - ChromeMetrics, MapCompatibility, Missions; + ChromeMetrics, MapCompatibility, Missions, Hotkeys; public readonly IReadOnlyDictionary Packages; public readonly IReadOnlyDictionary MapFolders; @@ -72,7 +72,7 @@ namespace OpenRA readonly string[] reservedModuleNames = { "Metadata", "Folders", "MapFolders", "Packages", "Rules", "Sequences", "ModelSequences", "Cursors", "Chrome", "Assemblies", "ChromeLayout", "Weapons", - "Voices", "Notifications", "Music", "Translations", "TileSets", "ChromeMetrics", "Missions", + "Voices", "Notifications", "Music", "Translations", "TileSets", "ChromeMetrics", "Missions", "Hotkeys", "ServerTraits", "LoadScreen", "Fonts", "SupportsMapsFrom", "SoundFormats", "SpriteFormats", "RequiresMods", "PackageFormats" }; @@ -111,6 +111,7 @@ namespace OpenRA TileSets = YamlList(yaml, "TileSets"); ChromeMetrics = YamlList(yaml, "ChromeMetrics"); Missions = YamlList(yaml, "Missions"); + Hotkeys = YamlList(yaml, "Hotkeys"); ServerTraits = YamlList(yaml, "ServerTraits"); diff --git a/OpenRA.Game/ModData.cs b/OpenRA.Game/ModData.cs index ee55a79e4e..8f84960d40 100644 --- a/OpenRA.Game/ModData.cs +++ b/OpenRA.Game/ModData.cs @@ -31,6 +31,7 @@ namespace OpenRA public readonly ISpriteLoader[] SpriteLoaders; public readonly ISpriteSequenceLoader SpriteSequenceLoader; public readonly IModelSequenceLoader ModelSequenceLoader; + public readonly HotkeyManager Hotkeys; public ILoadScreen LoadScreen { get; private set; } public CursorProvider CursorProvider { get; private set; } public FS ModFiles; @@ -89,6 +90,8 @@ namespace OpenRA ModelSequenceLoader = (IModelSequenceLoader)modelCtor.Invoke(new[] { this }); ModelSequenceLoader.OnMissingModelError = s => Log.Write("debug", s); + Hotkeys = new HotkeyManager(ModFiles, Game.Settings.Keys, Manifest); + defaultRules = Exts.Lazy(() => Ruleset.LoadDefaults(this)); defaultTileSets = Exts.Lazy(() => { diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index 4aab0ea06b..125d4a5b74 100644 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -261,6 +261,8 @@ + +