Allow mods to define custom manifest metadata.
This commit is contained in:
@@ -18,6 +18,7 @@ using OpenRA.Primitives;
|
|||||||
namespace OpenRA
|
namespace OpenRA
|
||||||
{
|
{
|
||||||
public enum TileShape { Rectangle, Diamond }
|
public enum TileShape { Rectangle, Diamond }
|
||||||
|
public interface IGlobalModData { }
|
||||||
|
|
||||||
// Describes what is to be loaded in order to run a mod
|
// Describes what is to be loaded in order to run a mod
|
||||||
public class Manifest
|
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")]
|
[Desc("Default subcell index used if SubCellInit is absent", "0 - full cell, 1 - first sub-cell")]
|
||||||
public readonly int SubCellDefaultIndex = 3;
|
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)
|
public Manifest(string mod)
|
||||||
{
|
{
|
||||||
var path = Platform.ResolvePath(".", "mods", mod, "mod.yaml");
|
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 = FieldLoader.Load<ModMetadata>(yaml["Metadata"]);
|
||||||
Mod.Id = mod;
|
Mod.Id = mod;
|
||||||
@@ -133,6 +143,23 @@ namespace OpenRA
|
|||||||
SpriteFormats = FieldLoader.GetValue<string[]>("SpriteFormats", yaml["SpriteFormats"].Value);
|
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)
|
static string[] YamlList(Dictionary<string, MiniYaml> yaml, string key, bool parsePaths = false)
|
||||||
{
|
{
|
||||||
if (!yaml.ContainsKey(key))
|
if (!yaml.ContainsKey(key))
|
||||||
@@ -152,5 +179,19 @@ namespace OpenRA
|
|||||||
|
|
||||||
return new ReadOnlyDictionary<string, string>(inner);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ namespace OpenRA
|
|||||||
Languages = new string[0];
|
Languages = new string[0];
|
||||||
Manifest = new Manifest(mod);
|
Manifest = new Manifest(mod);
|
||||||
ObjectCreator = new ObjectCreator(Manifest);
|
ObjectCreator = new ObjectCreator(Manifest);
|
||||||
|
Manifest.LoadCustomData(ObjectCreator);
|
||||||
|
|
||||||
if (useLoadScreen)
|
if (useLoadScreen)
|
||||||
{
|
{
|
||||||
LoadScreen = ObjectCreator.CreateObject<ILoadScreen>(Manifest.LoadScreen.Value);
|
LoadScreen = ObjectCreator.CreateObject<ILoadScreen>(Manifest.LoadScreen.Value);
|
||||||
|
|||||||
Reference in New Issue
Block a user