diff --git a/OpenRA.Mods.Common/Graphics/DefaultSpriteSequence.cs b/OpenRA.Mods.Common/Graphics/DefaultSpriteSequence.cs index be63b5b721..e8c7197b7a 100644 --- a/OpenRA.Mods.Common/Graphics/DefaultSpriteSequence.cs +++ b/OpenRA.Mods.Common/Graphics/DefaultSpriteSequence.cs @@ -60,6 +60,7 @@ namespace OpenRA.Mods.Common.Graphics public class DefaultSpriteSequence : ISpriteSequence { + static readonly WRange DefaultShadowSpriteZOffset = new WRange(-5); readonly Sprite[] sprites; readonly bool reverseFacings, transpose; @@ -76,9 +77,18 @@ namespace OpenRA.Mods.Common.Graphics public int ShadowZOffset { get; private set; } public int[] Frames { get; private set; } - protected virtual string GetSpriteSrc(ModData modData, TileSet tileSet, string sequence, string animation, MiniYaml info, Dictionary d) + protected virtual string GetSpriteSrc(ModData modData, TileSet tileSet, string sequence, string animation, string sprite, Dictionary d) { - return info.Value ?? sequence; + return sprite ?? sequence; + } + + protected static T LoadField(Dictionary d, string key, T fallback) + { + MiniYaml value; + if (d.TryGetValue(key, out value)) + return FieldLoader.GetValue(key, value.Value); + + return fallback; } public DefaultSpriteSequence(ModData modData, TileSet tileSet, SpriteCache cache, ISpriteSequenceLoader loader, string sequence, string animation, MiniYaml info) @@ -86,78 +96,48 @@ namespace OpenRA.Mods.Common.Graphics Name = animation; Loader = loader; var d = info.ToDictionary(); - var offset = float2.Zero; - var blendMode = BlendMode.Alpha; try { - if (d.ContainsKey("Start")) - Start = Exts.ParseIntegerInvariant(d["Start"].Value); + Start = LoadField(d, "Start", 0); + ShadowStart = LoadField(d, "ShadowStart", -1); + ShadowZOffset = LoadField(d, "ShadowZOffset", DefaultShadowSpriteZOffset).Range; + ZOffset = LoadField(d, "ZOffset", WRange.Zero).Range; + Tick = LoadField(d, "Tick", 40); + transpose = LoadField(d, "Transpose", false); + Frames = LoadField(d, "Frames", null); - if (d.ContainsKey("Offset")) - offset = FieldLoader.GetValue("Offset", d["Offset"].Value); + Facings = LoadField(d, "Facings", 1); + if (Facings < 0) + { + reverseFacings = true; + Facings = -Facings; + } - if (d.ContainsKey("BlendMode")) - blendMode = FieldLoader.GetValue("BlendMode", d["BlendMode"].Value); + var offset = LoadField(d, "Offset", float2.Zero); + var blendMode = LoadField(d, "BlendMode", BlendMode.Alpha); // Apply offset to each sprite in the sequence // Different sequences may apply different offsets to the same frame - var src = GetSpriteSrc(modData, tileSet, sequence, animation, info, d); + var src = GetSpriteSrc(modData, tileSet, sequence, animation, info.Value, d); sprites = cache[src].Select( s => new Sprite(s.Sheet, s.Bounds, s.Offset + offset, s.Channel, blendMode)).ToArray(); - if (!d.ContainsKey("Length")) - Length = 1; - else if (d["Length"].Value == "*") + MiniYaml length; + if (d.TryGetValue("Length", out length) && length.Value == "*") Length = sprites.Length - Start; else - Length = Exts.ParseIntegerInvariant(d["Length"].Value); + Length = LoadField(d, "Length", 1); - if (d.ContainsKey("Stride")) - Stride = Exts.ParseIntegerInvariant(d["Stride"].Value); - else - Stride = Length; - - if (d.ContainsKey("Facings")) + // Plays the animation forwards, and then in reverse + if (LoadField(d, "Reverses", false)) { - var f = Exts.ParseIntegerInvariant(d["Facings"].Value); - Facings = Math.Abs(f); - reverseFacings = f < 0; + var frames = Frames ?? Exts.MakeArray(Length, i => Start + i); + Frames = frames.Concat(frames.Skip(1).Take(frames.Length - 2).Reverse()).ToArray(); + Length = 2 * Length - 2; } - else - Facings = 1; - if (d.ContainsKey("Tick")) - Tick = Exts.ParseIntegerInvariant(d["Tick"].Value); - else - Tick = 40; - - if (d.ContainsKey("Transpose")) - transpose = bool.Parse(d["Transpose"].Value); - - if (d.ContainsKey("Frames")) - Frames = Array.ConvertAll(d["Frames"].Value.Split(','), Exts.ParseIntegerInvariant); - - if (d.ContainsKey("ShadowStart")) - ShadowStart = Exts.ParseIntegerInvariant(d["ShadowStart"].Value); - else - ShadowStart = -1; - - if (d.ContainsKey("ShadowZOffset")) - { - WRange r; - if (WRange.TryParse(d["ShadowZOffset"].Value, out r)) - ShadowZOffset = r.Range; - } - else - ShadowZOffset = -5; - - if (d.ContainsKey("ZOffset")) - { - WRange r; - if (WRange.TryParse(d["ZOffset"].Value, out r)) - ZOffset = r.Range; - } + Stride = LoadField(d, "Stride", Length); if (Length > Stride) throw new InvalidOperationException( diff --git a/mods/ts/sequences/structures.yaml b/mods/ts/sequences/structures.yaml index f638ce4649..27c6697140 100644 --- a/mods/ts/sequences/structures.yaml +++ b/mods/ts/sequences/structures.yaml @@ -358,12 +358,13 @@ garadr: ShadowStart: 5 Tick: 400 idle-dish: gtradr_a - Frames: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 - Length: 28 + Length: 15 + Reverses: True Tick: 200 damaged-idle-dish: gtradr_a - Frames: 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16 - Length: 28 + Start: 15 + Length: 15 + Reverses: True Tick: 240 make: gtradrmk Length: 20