Add RequiresMods tag to the mod Manifest
List required mods and their versions to enable mod dependencies on another mods. Also used for identifying the engine version by `modchooser`'s version.
This commit is contained in:
@@ -253,6 +253,13 @@ namespace OpenRA
|
||||
RunAfterDelay(Settings.Server.NatDiscoveryTimeout, UPnP.StoppingNatDiscovery);
|
||||
}
|
||||
|
||||
public static bool IsModInstalled(string modId)
|
||||
{
|
||||
return Manifest.AllMods[modId].RequiresMods.All(mod => ModMetadata.AllMods.ContainsKey(mod.Key)
|
||||
&& ModMetadata.AllMods[mod.Key].Version == mod.Value
|
||||
&& IsModInstalled(mod.Key));
|
||||
}
|
||||
|
||||
public static void InitializeMod(string mod, Arguments args)
|
||||
{
|
||||
// Clear static state if we have switched mods
|
||||
@@ -276,8 +283,8 @@ namespace OpenRA
|
||||
ModData.Dispose();
|
||||
ModData = null;
|
||||
|
||||
// Fall back to default if the mod doesn't exist
|
||||
if (!ModMetadata.AllMods.ContainsKey(mod))
|
||||
// Fall back to default if the mod doesn't exist or has missing prerequisites.
|
||||
if (!ModMetadata.AllMods.ContainsKey(mod) || !IsModInstalled(mod))
|
||||
mod = new GameSettings().Mod;
|
||||
|
||||
Console.WriteLine("Loading mod: {0}", mod);
|
||||
|
||||
@@ -32,6 +32,8 @@ namespace OpenRA
|
||||
// Describes what is to be loaded in order to run a mod
|
||||
public class Manifest
|
||||
{
|
||||
public static readonly Dictionary<string, Manifest> AllMods = LoadMods();
|
||||
|
||||
public readonly ModMetadata Mod;
|
||||
public readonly string[]
|
||||
Folders, Rules, ServerTraits,
|
||||
@@ -44,6 +46,7 @@ namespace OpenRA
|
||||
public readonly MiniYaml LoadScreen;
|
||||
public readonly MiniYaml LobbyDefaults;
|
||||
|
||||
public readonly Dictionary<string, string> RequiresMods;
|
||||
public readonly Dictionary<string, Pair<string, int>> Fonts;
|
||||
|
||||
public readonly string[] SpriteFormats = { };
|
||||
@@ -51,7 +54,7 @@ namespace OpenRA
|
||||
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", "Fonts", "SupportsMapsFrom", "SpriteFormats" };
|
||||
"ServerTraits", "LoadScreen", "LobbyDefaults", "Fonts", "SupportsMapsFrom", "SpriteFormats", "RequiresMods" };
|
||||
|
||||
readonly TypeDictionary modules = new TypeDictionary();
|
||||
readonly Dictionary<string, MiniYaml> yaml;
|
||||
@@ -98,6 +101,8 @@ namespace OpenRA
|
||||
return Pair.New(nd["Font"].Value, Exts.ParseIntegerInvariant(nd["Size"].Value));
|
||||
});
|
||||
|
||||
RequiresMods = yaml["RequiresMods"].ToDictionary(my => my.Value);
|
||||
|
||||
// Allow inherited mods to import parent maps.
|
||||
var compat = new List<string>();
|
||||
compat.Add(mod);
|
||||
@@ -174,5 +179,29 @@ namespace OpenRA
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
static Dictionary<string, Manifest> LoadMods()
|
||||
{
|
||||
var basePath = Platform.ResolvePath(".", "mods");
|
||||
var mods = Directory.GetDirectories(basePath)
|
||||
.Select(x => x.Substring(basePath.Length + 1));
|
||||
|
||||
var ret = new Dictionary<string, Manifest>();
|
||||
foreach (var mod in mods)
|
||||
{
|
||||
try
|
||||
{
|
||||
var manifest = new Manifest(mod);
|
||||
ret.Add(mod, manifest);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Write("debug", "An exception occured while trying to load mod {0}:", mod);
|
||||
Log.Write("debug", ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
readonly Dictionary<string, Sprite> previews = new Dictionary<string, Sprite>();
|
||||
readonly Dictionary<string, Sprite> logos = new Dictionary<string, Sprite>();
|
||||
readonly Cache<ModMetadata, bool> modInstallStatus;
|
||||
readonly Cache<string, bool> modPrerequisitesFulfilled;
|
||||
readonly Widget modChooserPanel;
|
||||
readonly ButtonWidget loadButton;
|
||||
readonly SheetBuilder sheetBuilder;
|
||||
@@ -38,6 +39,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
[ObjectCreator.UseCtor]
|
||||
public ModBrowserLogic(Widget widget)
|
||||
{
|
||||
modInstallStatus = new Cache<ModMetadata, bool>(IsModInstalled);
|
||||
modPrerequisitesFulfilled = new Cache<string, bool>(Game.IsModInstalled);
|
||||
|
||||
modChooserPanel = widget;
|
||||
loadButton = modChooserPanel.Get<ButtonWidget>("LOAD_BUTTON");
|
||||
loadButton.OnClick = () => LoadMod(selectedMod);
|
||||
@@ -93,8 +97,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
catch (Exception) { }
|
||||
}
|
||||
|
||||
modInstallStatus = new Cache<ModMetadata, bool>(IsModInstalled);
|
||||
|
||||
ModMetadata initialMod;
|
||||
ModMetadata.AllMods.TryGetValue(Game.Settings.Game.PreviousMod, out initialMod);
|
||||
SelectMod(initialMod != null && initialMod.Id != "modchooser" ? initialMod : ModMetadata.AllMods["ra"]);
|
||||
@@ -157,6 +159,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
modOffset = selectedIndex - 4;
|
||||
|
||||
loadButton.Text = modInstallStatus[mod] ? "Load Mod" : "Install Assets";
|
||||
|
||||
loadButton.Text = modPrerequisitesFulfilled[mod.Id] ? loadButton.Text : "Prerequisites missing!";
|
||||
}
|
||||
|
||||
void LoadMod(ModMetadata mod)
|
||||
|
||||
@@ -4,6 +4,9 @@ Metadata:
|
||||
Version: {DEV_VERSION}
|
||||
Author: the OpenRA Developers
|
||||
|
||||
RequiresMods:
|
||||
modchooser: {DEV_VERSION}
|
||||
|
||||
Folders:
|
||||
.
|
||||
./mods/cnc
|
||||
|
||||
@@ -4,6 +4,9 @@ Metadata:
|
||||
Version: {DEV_VERSION}
|
||||
Author: the OpenRA Developers
|
||||
|
||||
RequiresMods:
|
||||
modchooser: {DEV_VERSION}
|
||||
|
||||
Folders:
|
||||
.
|
||||
./mods/d2k
|
||||
|
||||
@@ -4,6 +4,8 @@ Metadata:
|
||||
Author: The OpenRA Developers
|
||||
Hidden: true
|
||||
|
||||
RequiresMods:
|
||||
|
||||
Folders:
|
||||
.
|
||||
./mods/modchooser
|
||||
|
||||
@@ -4,6 +4,9 @@ Metadata:
|
||||
Version: {DEV_VERSION}
|
||||
Author: the OpenRA Developers
|
||||
|
||||
RequiresMods:
|
||||
modchooser: {DEV_VERSION}
|
||||
|
||||
Folders:
|
||||
.
|
||||
./mods/ra
|
||||
|
||||
@@ -4,6 +4,9 @@ Metadata:
|
||||
Version: {DEV_VERSION}
|
||||
Author: the OpenRA Developers
|
||||
|
||||
RequiresMods:
|
||||
modchooser: {DEV_VERSION}
|
||||
|
||||
Folders:
|
||||
.
|
||||
# Tiberian Sun
|
||||
|
||||
Reference in New Issue
Block a user