Allow mods to define custom manifest metadata.

This commit is contained in:
Paul Chote
2015-03-07 09:29:50 +00:00
parent 31710c1644
commit 5552000d69
2 changed files with 44 additions and 1 deletions

View File

@@ -18,6 +18,7 @@ using OpenRA.Primitives;
namespace OpenRA
{
public enum TileShape { Rectangle, Diamond }
public interface IGlobalModData { }
// Describes what is to be loaded in order to run a mod
public class Manifest
@@ -54,10 +55,19 @@ namespace OpenRA
[Desc("Default subcell index used if SubCellInit is absent", "0 - full cell, 1 - first sub-cell")]
public readonly int SubCellDefaultIndex = 3;
readonly string[] reservedModuleNames = { "Metadata", "Folders", "MapFolders", "Packages", "Rules",
"Sequences", "VoxelSequences", "Cursors", "Chrome", "Assemblies", "ChromeLayout", "Weapons",
"Voices", "Notifications", "Music", "Translations", "TileSets", "ChromeMetrics", "Missions",
"ServerTraits", "LoadScreen", "LobbyDefaults", "ContentInstaller", "Fonts", "TileSize",
"TileShape", "SubCells", "SupportsMapsFrom", "SpriteFormats" };
readonly TypeDictionary modules = new TypeDictionary();
readonly Dictionary<string, MiniYaml> yaml;
public Manifest(string mod)
{
var path = Platform.ResolvePath(".", "mods", mod, "mod.yaml");
var yaml = new MiniYaml(null, MiniYaml.FromFile(path)).ToDictionary();
yaml = new MiniYaml(null, MiniYaml.FromFile(path)).ToDictionary();
Mod = FieldLoader.Load<ModMetadata>(yaml["Metadata"]);
Mod.Id = mod;
@@ -133,6 +143,23 @@ namespace OpenRA
SpriteFormats = FieldLoader.GetValue<string[]>("SpriteFormats", yaml["SpriteFormats"].Value);
}
public void LoadCustomData(ObjectCreator oc)
{
foreach (var kv in yaml)
{
if (reservedModuleNames.Contains(kv.Key))
continue;
var t = oc.FindType(kv.Key);
if (t == null || !typeof(IGlobalModData).IsAssignableFrom(t))
throw new InvalidDataException("`{0}` is not a valid mod manifest entry.".F(kv.Key));
var module = oc.CreateObject<IGlobalModData>(kv.Key);
FieldLoader.Load(module, kv.Value);
modules.Add(module);
}
}
static string[] YamlList(Dictionary<string, MiniYaml> yaml, string key, bool parsePaths = false)
{
if (!yaml.ContainsKey(key))
@@ -152,5 +179,19 @@ namespace OpenRA
return new ReadOnlyDictionary<string, string>(inner);
}
public T Get<T>() where T : IGlobalModData
{
var module = modules.GetOrDefault<T>();
// Lazily create the default values if not explicitly defined.
if (module == null)
{
module = (T)Game.ModData.ObjectCreator.CreateBasic(typeof(T));
modules.Add(module);
}
return module;
}
}
}

View File

@@ -38,6 +38,8 @@ namespace OpenRA
Languages = new string[0];
Manifest = new Manifest(mod);
ObjectCreator = new ObjectCreator(Manifest);
Manifest.LoadCustomData(ObjectCreator);
if (useLoadScreen)
{
LoadScreen = ObjectCreator.CreateObject<ILoadScreen>(Manifest.LoadScreen.Value);