Allow mods to define custom manifest metadata.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user