diff --git a/OpenRA.Game/Manifest.cs b/OpenRA.Game/Manifest.cs index 97ab264891..25564bfaca 100644 --- a/OpenRA.Game/Manifest.cs +++ b/OpenRA.Game/Manifest.cs @@ -20,6 +20,17 @@ namespace OpenRA { public interface IGlobalModData { } + public sealed class TerrainFormat : IGlobalModData + { + public readonly string Type; + public readonly IReadOnlyDictionary Metadata; + public TerrainFormat(MiniYaml yaml) + { + Type = yaml.Value; + Metadata = new ReadOnlyDictionary(yaml.ToDictionary()); + } + } + public sealed class SpriteSequenceFormat : IGlobalModData { public readonly string Type; diff --git a/OpenRA.Game/Map/TileSet.cs b/OpenRA.Game/Map/TileSet.cs index 38891a2d1b..0bd864a350 100644 --- a/OpenRA.Game/Map/TileSet.cs +++ b/OpenRA.Game/Map/TileSet.cs @@ -19,6 +19,11 @@ using OpenRA.Traits; namespace OpenRA { + public interface ITerrainLoader + { + ITerrainInfo ParseTerrain(IReadOnlyFileSystem fileSystem, string path); + } + public interface ITerrainInfo { string Id { get; } diff --git a/OpenRA.Game/ModData.cs b/OpenRA.Game/ModData.cs index d28e006651..7067771029 100644 --- a/OpenRA.Game/ModData.cs +++ b/OpenRA.Game/ModData.cs @@ -30,6 +30,7 @@ namespace OpenRA public readonly IPackageLoader[] PackageLoaders; public readonly ISoundLoader[] SoundLoaders; public readonly ISpriteLoader[] SpriteLoaders; + public readonly ITerrainLoader TerrainLoader; public readonly ISpriteSequenceLoader SpriteSequenceLoader; public readonly IModelSequenceLoader ModelSequenceLoader; public readonly IVideoLoader[] VideoLoaders; @@ -75,6 +76,14 @@ namespace OpenRA SpriteLoaders = ObjectCreator.GetLoaders(Manifest.SpriteFormats, "sprite"); VideoLoaders = ObjectCreator.GetLoaders(Manifest.VideoFormats, "video"); + var terrainFormat = Manifest.Get(); + var terrainLoader = ObjectCreator.FindType(terrainFormat.Type + "Loader"); + var terrainCtor = terrainLoader?.GetConstructor(new[] { typeof(ModData) }); + if (terrainLoader == null || !terrainLoader.GetInterfaces().Contains(typeof(ITerrainLoader)) || terrainCtor == null) + throw new InvalidOperationException("Unable to find a terrain loader for type '{0}'.".F(terrainFormat.Type)); + + TerrainLoader = (ITerrainLoader)terrainCtor.Invoke(new[] { this }); + var sequenceFormat = Manifest.Get(); var sequenceLoader = ObjectCreator.FindType(sequenceFormat.Type + "Loader"); var sequenceCtor = sequenceLoader != null ? sequenceLoader.GetConstructor(new[] { typeof(ModData) }) : null; @@ -101,7 +110,7 @@ namespace OpenRA foreach (var file in Manifest.TileSets) { - var t = new TileSet(DefaultFileSystem, file); + var t = TerrainLoader.ParseTerrain(DefaultFileSystem, file); items.Add(t.Id, t); } diff --git a/OpenRA.Mods.Common/Terrain/DefaultTerrain.cs b/OpenRA.Mods.Common/Terrain/DefaultTerrain.cs new file mode 100644 index 0000000000..bf1244ad3c --- /dev/null +++ b/OpenRA.Mods.Common/Terrain/DefaultTerrain.cs @@ -0,0 +1,26 @@ +#region Copyright & License Information +/* + * Copyright 2007-2020 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. For more + * information, see COPYING. + */ +#endregion + +using OpenRA.FileSystem; +using OpenRA.Graphics; + +namespace OpenRA.Mods.Common.Terrain +{ + public class DefaultTerrainLoader : ITerrainLoader + { + public DefaultTerrainLoader(ModData modData) { } + + public ITerrainInfo ParseTerrain(IReadOnlyFileSystem fileSystem, string path) + { + return new TileSet(fileSystem, path); + } + } +} diff --git a/mods/all/mod.yaml b/mods/all/mod.yaml index aecd52761b..b674078b64 100644 --- a/mods/all/mod.yaml +++ b/mods/all/mod.yaml @@ -29,6 +29,8 @@ SoundFormats: SpriteFormats: +TerrainFormat: DefaultTerrain + SpriteSequenceFormat: DefaultSpriteSequence ModelSequenceFormat: PlaceholderModelSequence diff --git a/mods/cnc/mod.yaml b/mods/cnc/mod.yaml index 14aa1ff0ae..a638de99fb 100644 --- a/mods/cnc/mod.yaml +++ b/mods/cnc/mod.yaml @@ -214,6 +214,8 @@ SpriteFormats: ShpTD, TmpTD, ShpTS, TmpRA VideoFormats: Vqa +TerrainFormat: DefaultTerrain + SpriteSequenceFormat: ClassicTilesetSpecificSpriteSequence TilesetExtensions: TEMPERAT: .tem diff --git a/mods/d2k/mod.yaml b/mods/d2k/mod.yaml index 6e75f21e48..f1d0ab462d 100644 --- a/mods/d2k/mod.yaml +++ b/mods/d2k/mod.yaml @@ -196,6 +196,8 @@ SpriteFormats: R8, ShpTD, TmpRA VideoFormats: Vqa +TerrainFormat: DefaultTerrain + SpriteSequenceFormat: DefaultSpriteSequence ModelSequenceFormat: PlaceholderModelSequence diff --git a/mods/modcontent/mod.yaml b/mods/modcontent/mod.yaml index 948dcf510b..c01ad6daa7 100644 --- a/mods/modcontent/mod.yaml +++ b/mods/modcontent/mod.yaml @@ -65,6 +65,8 @@ SoundFormats: SpriteFormats: PngSheet +TerrainFormat: DefaultTerrain + SpriteSequenceFormat: DefaultSpriteSequence ModelSequenceFormat: PlaceholderModelSequence diff --git a/mods/ra/mod.yaml b/mods/ra/mod.yaml index d3d3b3772d..45ad7ee267 100644 --- a/mods/ra/mod.yaml +++ b/mods/ra/mod.yaml @@ -220,6 +220,8 @@ SpriteFormats: ShpD2, ShpTD, TmpRA, TmpTD, ShpTS VideoFormats: Vqa +TerrainFormat: DefaultTerrain + SpriteSequenceFormat: ClassicTilesetSpecificSpriteSequence TilesetExtensions: TEMPERAT: .tem diff --git a/mods/ts/mod.yaml b/mods/ts/mod.yaml index a5a604d634..a56fd201da 100644 --- a/mods/ts/mod.yaml +++ b/mods/ts/mod.yaml @@ -249,6 +249,8 @@ SpriteFormats: ShpTS, TmpTS, ShpTD VideoFormats: Vqa +TerrainFormat: DefaultTerrain + SpriteSequenceFormat: TilesetSpecificSpriteSequence TilesetExtensions: TEMPERATE: .tem