diff --git a/OpenRA.Game/Graphics/SequenceProvider.cs b/OpenRA.Game/Graphics/SequenceProvider.cs index 016d64fb55..2b1241ebf6 100644 --- a/OpenRA.Game/Graphics/SequenceProvider.cs +++ b/OpenRA.Game/Graphics/SequenceProvider.cs @@ -39,6 +39,7 @@ namespace OpenRA.Graphics public interface ISpriteSequenceLoader { + Action OnMissingSpriteError { get; set; } IReadOnlyDictionary ParseSequences(ModData modData, TileSet tileSet, SpriteCache cache, MiniYamlNode node); } diff --git a/OpenRA.Game/ModData.cs b/OpenRA.Game/ModData.cs index 38cacea1fd..58f4ed46ca 100644 --- a/OpenRA.Game/ModData.cs +++ b/OpenRA.Game/ModData.cs @@ -72,6 +72,7 @@ namespace OpenRA throw new InvalidOperationException("Unable to find a sequence loader for type '{0}'.".F(sequenceFormat.Type)); SpriteSequenceLoader = (ISpriteSequenceLoader)ctor.Invoke(new[] { this }); + SpriteSequenceLoader.OnMissingSpriteError = s => Log.Write("debug", s); // HACK: Mount only local folders so we have a half-working environment for the asset installer GlobalFileSystem.UnmountAll(); diff --git a/OpenRA.Mods.Common/Graphics/DefaultSpriteSequence.cs b/OpenRA.Mods.Common/Graphics/DefaultSpriteSequence.cs index a32a2cdaf2..be63b5b721 100644 --- a/OpenRA.Mods.Common/Graphics/DefaultSpriteSequence.cs +++ b/OpenRA.Mods.Common/Graphics/DefaultSpriteSequence.cs @@ -18,6 +18,7 @@ namespace OpenRA.Mods.Common.Graphics { public class DefaultSpriteSequenceLoader : ISpriteSequenceLoader { + public Action OnMissingSpriteError { get; set; } public DefaultSpriteSequenceLoader(ModData modData) { } public virtual ISpriteSequence CreateSequence(ModData modData, TileSet tileSet, SpriteCache cache, string sequence, string animation, MiniYaml info) @@ -48,7 +49,7 @@ namespace OpenRA.Mods.Common.Graphics catch (FileNotFoundException ex) { // Eat the FileNotFound exceptions from missing sprites - Log.Write("debug", ex.Message); + OnMissingSpriteError(ex.Message); } } } diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index b72e397c04..0ee62bda50 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -616,6 +616,7 @@ + diff --git a/OpenRA.Mods.Common/UtilityCommands/CheckSequenceSprites.cs b/OpenRA.Mods.Common/UtilityCommands/CheckSequenceSprites.cs new file mode 100644 index 0000000000..5a8fc92407 --- /dev/null +++ b/OpenRA.Mods.Common/UtilityCommands/CheckSequenceSprites.cs @@ -0,0 +1,51 @@ +#region Copyright & License Information +/* + * Copyright 2007-2015 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. For more information, + * see COPYING. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using OpenRA.FileSystem; +using OpenRA.Graphics; +using OpenRA.Traits; +using StyleCop; + +namespace OpenRA.Mods.Common.UtilityCommands +{ + class CheckSquenceSprites : IUtilityCommand + { + public string Name { get { return "--check-sequence-sprites"; } } + + [Desc("Check the sequence definitions for missing sprite files.")] + public void Run(ModData modData, string[] args) + { + // HACK: The engine code assumes that Game.modData is set. + Game.ModData = modData; + GlobalFileSystem.LoadFromManifest(Game.ModData.Manifest); + Game.ModData.SpriteSequenceLoader.OnMissingSpriteError = s => Console.WriteLine("\t" + s); + + foreach (var t in Game.ModData.Manifest.TileSets) + { + var ts = new TileSet(Game.ModData, t); + Console.WriteLine("Tileset: " + ts.Name); + var sc = new SpriteCache(modData.SpriteLoaders, ts.Extensions, new SheetBuilder(SheetType.Indexed)); + var sequenceFiles = modData.Manifest.Sequences; + + var nodes = sequenceFiles + .Select(s => MiniYaml.FromFile(s)) + .Aggregate(MiniYaml.MergeLiberal); + + foreach (var n in nodes) + Game.ModData.SpriteSequenceLoader.ParseSequences(Game.ModData, ts, sc, n); + } + } + } +}