Make palettes and tilesets optional

This commit is contained in:
Gustas
2025-01-27 19:26:16 +02:00
committed by Matthias Mailänder
parent 4c04d4fa30
commit 84378969c3
2 changed files with 62 additions and 28 deletions

View File

@@ -44,15 +44,15 @@ namespace OpenRA.Graphics
public sealed class SequenceSet : IDisposable
{
public readonly string TileSet;
readonly ModData modData;
readonly string tileSet;
readonly IReadOnlyDictionary<string, IReadOnlyDictionary<string, ISpriteSequence>> images;
public SpriteCache SpriteCache { get; }
public SequenceSet(IReadOnlyFileSystem fileSystem, ModData modData, string tileSet, MiniYaml additionalSequences)
{
this.modData = modData;
this.tileSet = tileSet;
TileSet = tileSet;
SpriteCache = new SpriteCache(fileSystem, modData.SpriteLoaders, modData.SpriteSequenceLoader.BgraSheetSize, modData.SpriteSequenceLoader.IndexedSheetSize);
using (new Support.PerfTimer("LoadSequences"))
images = Load(fileSystem, additionalSequences);
@@ -97,7 +97,7 @@ namespace OpenRA.Graphics
if (node.Key.StartsWith(ActorInfo.AbstractActorPrefix))
continue;
images[node.Key] = modData.SpriteSequenceLoader.ParseSequences(modData, tileSet, SpriteCache, node);
images[node.Key] = modData.SpriteSequenceLoader.ParseSequences(modData, TileSet, SpriteCache, node);
}
return images;

View File

@@ -10,6 +10,7 @@
#endregion
using System;
using System.Collections.Generic;
using OpenRA.FileFormats;
using OpenRA.FileSystem;
using OpenRA.Graphics;
@@ -24,47 +25,80 @@ namespace OpenRA.Mods.Common.UtilityCommands
bool IUtilityCommand.ValidateArguments(string[] args)
{
return args.Length >= 3;
return args.Length >= 1;
}
[Desc("PALETTE", "TILESET-OR-MAP", "Exports sequence texture atlas as a set of png images.")]
[Desc("[PALETTE]", "[TILESET-OR-MAP]", "Exports texture atlas' as a set of png images. "
+ "If palette is not specified, only BGRA sheets are exported. "
+ "If tileset-or-map is not specified, all tilesets are exported.")]
void IUtilityCommand.Run(Utility utility, string[] args)
{
// HACK: The engine code assumes that Game.modData is set.
var modData = Game.ModData = utility.ModData;
var palette = new ImmutablePalette(args[1], [0], []);
var palette = args.Length > 1 ? new ImmutablePalette(args[1], [0], []) : null;
var sequences = new List<SequenceSet>();
SequenceSet sequences;
var tilesetUpper = args[2].ToUpperInvariant();
if (modData.DefaultTerrainInfo.ContainsKey(tilesetUpper))
sequences = new SequenceSet(modData.ModFiles, modData, tilesetUpper, null);
if (args.Length == 3)
{
var tilesetUpper = args[2].ToUpperInvariant();
if (modData.DefaultTerrainInfo.ContainsKey(tilesetUpper))
sequences.Add(new SequenceSet(modData.ModFiles, modData, tilesetUpper, null));
else
{
var mapPackage = new Folder(Platform.EngineDir).OpenPackage(args[2], modData.ModFiles);
if (mapPackage == null)
throw new InvalidOperationException($"{args[2]} is not a valid tileset or map path");
sequences.Add(new Map(modData, mapPackage).Sequences);
}
}
else
{
var mapPackage = new Folder(Platform.EngineDir).OpenPackage(args[2], modData.ModFiles);
if (mapPackage == null)
throw new InvalidOperationException($"{args[2]} is not a valid tileset or map path");
sequences = new Map(modData, mapPackage).Sequences;
foreach (var t in modData.DefaultTerrainInfo.Keys)
sequences.Add(new SequenceSet(modData.ModFiles, modData, t, null));
}
sequences.LoadSprites();
var count = 0;
var sb = sequences.SpriteCache.SheetBuilders[SheetType.Indexed];
foreach (var s in sb.AllSheets)
var sheetCount = 1;
foreach (var sequence in sequences)
{
var max = s == sb.Current ? (int)sb.CurrentChannel + 1 : 4;
for (var i = 0; i < max; i++)
s.AsPng((TextureChannel)ChannelMasks[i], palette).Save($"{count}.{i}.png", Png.Compression.BEST_SPEED);
sequence.LoadSprites();
count++;
var sequencesName = "sequences";
var terrainName = "tileset";
if (sequences.Count > 1)
{
var name = sequence.TileSet.ToLowerInvariant();
sequencesName += "." + name;
terrainName += "." + name;
}
var sb = sequence.SpriteCache.SheetBuilders[SheetType.Indexed];
foreach (var s in sb.AllSheets)
CommitSheet(sb, s, sequencesName, palette, ref sheetCount);
foreach (var s in sequence.SpriteCache.SheetBuilders[SheetType.BGRA].AllSheets)
CommitSheet(null, s, sequencesName, palette, ref sheetCount);
sequence.Dispose();
}
}
sb = sequences.SpriteCache.SheetBuilders[SheetType.BGRA];
foreach (var s in sb.AllSheets)
s.AsPng().Save($"{count++}.png", Png.Compression.BEST_SPEED);
static void CommitSheet(SheetBuilder builder, Sheet sheet, string name, ImmutablePalette palette, ref int count)
{
if (builder == null)
sheet.AsPng().Save($"{count++}.{name}.png", Png.Compression.BEST_SPEED);
else
{
if (palette != null)
{
var channels = sheet == builder.Current ? (int)builder.CurrentChannel + 1 : 4;
for (var i = 0; i < channels; i++)
sheet.AsPng((TextureChannel)ChannelMasks[i], palette).Save($"{count}.{i}.{name}.png", Png.Compression.BEST_SPEED);
count++;
}
}
}
}
}