diff --git a/OpenRA.FileFormats/Filesystem/D2kSoundResources.cs b/OpenRA.FileFormats/FileSystem/D2kSoundResources.cs similarity index 100% rename from OpenRA.FileFormats/Filesystem/D2kSoundResources.cs rename to OpenRA.FileFormats/FileSystem/D2kSoundResources.cs diff --git a/OpenRA.FileFormats/Filesystem/FileSystem.cs b/OpenRA.FileFormats/FileSystem/FileSystem.cs similarity index 95% rename from OpenRA.FileFormats/Filesystem/FileSystem.cs rename to OpenRA.FileFormats/FileSystem/FileSystem.cs index 886f308046..6046908e67 100644 --- a/OpenRA.FileFormats/Filesystem/FileSystem.cs +++ b/OpenRA.FileFormats/FileSystem/FileSystem.cs @@ -19,8 +19,8 @@ namespace OpenRA.FileFormats public static class FileSystem { public static List MountedFolders = new List(); - static Cache> classicHashIndex = new Cache>( _ => new List() ); - static Cache> crcHashIndex = new Cache>( _ => new List() ); + static Cache> classicHashIndex = new Cache>(_ => new List()); + static Cache> crcHashIndex = new Cache>(_ => new List()); public static List FolderPaths = new List(); @@ -89,11 +89,12 @@ namespace OpenRA.FileFormats public static void Mount(string name, string annotation) { var optional = name.StartsWith("~"); - if (optional) name = name.Substring(1); + if (optional) + name = name.Substring(1); // paths starting with ^ are relative to the support dir if (name.StartsWith("^")) - name = Platform.SupportDir+name.Substring(1); + name = Platform.SupportDir + name.Substring(1); FolderPaths.Add(name); Action a = () => FileSystem.MountInner(OpenPackage(name, annotation, order++)); @@ -115,7 +116,7 @@ namespace OpenRA.FileFormats public static bool Unmount(IFolder mount) { - return (MountedFolders.RemoveAll(f => f == mount) > 0); + return MountedFolders.RemoveAll(f => f == mount) > 0; } public static void Mount(IFolder mount) @@ -151,7 +152,7 @@ namespace OpenRA.FileFormats public static Stream OpenWithExts(string filename, params string[] exts) { - if (filename.IndexOfAny(new char[] { '/', '\\' } ) == -1) + if (filename.IndexOfAny(new char[] { '/', '\\' }) == -1) { foreach (var ext in exts) { diff --git a/OpenRA.FileFormats/Filesystem/Folder.cs b/OpenRA.FileFormats/FileSystem/Folder.cs similarity index 100% rename from OpenRA.FileFormats/Filesystem/Folder.cs rename to OpenRA.FileFormats/FileSystem/Folder.cs diff --git a/OpenRA.FileFormats/Filesystem/InstallShieldPackage.cs b/OpenRA.FileFormats/FileSystem/InstallShieldPackage.cs similarity index 100% rename from OpenRA.FileFormats/Filesystem/InstallShieldPackage.cs rename to OpenRA.FileFormats/FileSystem/InstallShieldPackage.cs diff --git a/OpenRA.FileFormats/Filesystem/MixFile.cs b/OpenRA.FileFormats/FileSystem/MixFile.cs similarity index 100% rename from OpenRA.FileFormats/Filesystem/MixFile.cs rename to OpenRA.FileFormats/FileSystem/MixFile.cs diff --git a/OpenRA.FileFormats/Filesystem/ZipFile.cs b/OpenRA.FileFormats/FileSystem/ZipFile.cs similarity index 100% rename from OpenRA.FileFormats/Filesystem/ZipFile.cs rename to OpenRA.FileFormats/FileSystem/ZipFile.cs diff --git a/OpenRA.FileFormats/Manifest.cs b/OpenRA.FileFormats/Manifest.cs index 63ec0b0c38..43515a02e1 100644 --- a/OpenRA.FileFormats/Manifest.cs +++ b/OpenRA.FileFormats/Manifest.cs @@ -19,7 +19,7 @@ namespace OpenRA.FileFormats public class Manifest { public readonly string[] - Mods, Folders, Rules, ServerTraits, + Mods, Folders, MapFolders, Rules, ServerTraits, Sequences, VoxelSequences, Cursors, Chrome, Assemblies, ChromeLayout, Weapons, Voices, Notifications, Music, Movies, Translations, TileSets, ChromeMetrics, PackageContents; @@ -39,6 +39,7 @@ namespace OpenRA.FileFormats // TODO: Use fieldloader Folders = YamlList(yaml, "Folders"); + MapFolders = YamlList(yaml, "MapFolders"); Packages = yaml["Packages"].NodesDict.ToDictionary(x => x.Key, x => x.Value.Value); Rules = YamlList(yaml, "Rules"); ServerTraits = YamlList(yaml, "ServerTraits"); diff --git a/OpenRA.FileFormats/OpenRA.FileFormats.csproj b/OpenRA.FileFormats/OpenRA.FileFormats.csproj index ecdf6dfe9b..f8f42f2b1c 100644 --- a/OpenRA.FileFormats/OpenRA.FileFormats.csproj +++ b/OpenRA.FileFormats/OpenRA.FileFormats.csproj @@ -90,11 +90,6 @@ - - - - - @@ -148,11 +143,16 @@ - + + + + + + diff --git a/OpenRA.Game/ModData.cs b/OpenRA.Game/ModData.cs index 138d75978d..b736ef2840 100755 --- a/OpenRA.Game/ModData.cs +++ b/OpenRA.Game/ModData.cs @@ -34,12 +34,21 @@ namespace OpenRA { string[] noMaps = { }; + // ignore optional flag + if (dir.StartsWith("~")) + dir = dir.Substring(1); + + // paths starting with ^ are relative to the user directory + if (dir.StartsWith("^")) + dir = Platform.SupportDir + dir.Substring(1); + if (!Directory.Exists(dir)) return noMaps; - return Directory.GetDirectories(dir) - .Concat(Directory.GetFiles(dir, "*.zip")) - .Concat(Directory.GetFiles(dir, "*.oramap")); + var dirsWithMaps = Directory.GetDirectories(dir) + .Where(d => Directory.GetFiles(d, "map.yaml").Any() && Directory.GetFiles(d, "map.bin").Any()); + + return dirsWithMaps.Concat(Directory.GetFiles(dir, "*.oramap")); } public ModData(params string[] mods) @@ -52,7 +61,7 @@ namespace OpenRA LoadScreen.Display(); WidgetLoader = new WidgetLoader(this); - AvailableMaps = FindMaps(Manifest.Mods); + AvailableMaps = FindMaps(); // HACK: Mount only local folders so we have a half-working environment for the asset installer FileSystem.UnmountAll(); @@ -138,10 +147,9 @@ namespace OpenRA return map; } - Dictionary FindMaps(string[] mods) + Dictionary FindMaps() { - var paths = mods.SelectMany(p => FindMapsIn("mods{0}{1}{0}maps{0}".F(Path.DirectorySeparatorChar, p))) - .Concat(mods.SelectMany(p => FindMapsIn("{1}maps{0}{2}{0}".F(Path.DirectorySeparatorChar, Platform.SupportDir, p)))); + var paths = Manifest.MapFolders.SelectMany(f => FindMapsIn(f)); var ret = new Dictionary(); diff --git a/mods/cnc/mod.yaml b/mods/cnc/mod.yaml index acc99f5a70..32ca45d723 100644 --- a/mods/cnc/mod.yaml +++ b/mods/cnc/mod.yaml @@ -11,6 +11,10 @@ Folders: ./mods/cnc/uibits ~^/Content/cnc +MapFolders: + ./mods/cnc/maps + ~^/maps/cnc + Packages: overrides.mix bluetib.mix diff --git a/mods/d2k/mod.yaml b/mods/d2k/mod.yaml index 15b269af13..9f132f842a 100644 --- a/mods/d2k/mod.yaml +++ b/mods/d2k/mod.yaml @@ -14,6 +14,10 @@ Folders: ~^/Content/d2k/GAMESFX ~^/Content/d2k/Music +MapFolders: + ./mods/d2k/maps + ~^/maps/d2k + Packages: SOUND.RS diff --git a/mods/d2k/sequences/map.yaml b/mods/d2k/sequences/map.yaml deleted file mode 100644 index f2e820645a..0000000000 --- a/mods/d2k/sequences/map.yaml +++ /dev/null @@ -1,24 +0,0 @@ -crate: - idle: DATA.R8 - Start: 102 - ZOffset: -511 - Offset: -16,-16 - land: DATA.R8 - Start: 102 - ZOffset: -511 - Offset: -16,-16 - -spicebloom: - make: DATA.R8 - Start: 107 - Length: 3 - Offset: -16,-16 - active: DATA.R8 - Start: 109 - Length: 1 - ZOffset: -511 - Offset: -16,-16 - idle: DATA.R8 - Start: 109 - ZOffset: -511 - Offset: -16,-16 \ No newline at end of file diff --git a/mods/ra/mod.yaml b/mods/ra/mod.yaml index 085986af9a..394eb836c9 100644 --- a/mods/ra/mod.yaml +++ b/mods/ra/mod.yaml @@ -12,6 +12,10 @@ Folders: ./mods/ra/uibits ~^/Content/ra +MapFolders: + ./mods/ra/maps + ~^/maps/ra + Packages: ~main.mix redalert.mix diff --git a/mods/ts/mod.yaml b/mods/ts/mod.yaml index e9f041a190..63adc87e73 100644 --- a/mods/ts/mod.yaml +++ b/mods/ts/mod.yaml @@ -14,6 +14,10 @@ Folders: # Red Alert ./mods/ra/uibits +MapFolders: + ./mods/ts/maps + ~^/maps/ts + Packages: # Red Alert interior.mix