diff --git a/OpenRA.Mods.RA/ShroudRenderer.cs b/OpenRA.Mods.RA/ShroudRenderer.cs index c3820479c5..f6de9030de 100644 --- a/OpenRA.Mods.RA/ShroudRenderer.cs +++ b/OpenRA.Mods.RA/ShroudRenderer.cs @@ -8,6 +8,7 @@ */ #endregion +using System; using System.Drawing; using System.Linq; using OpenRA; @@ -19,7 +20,8 @@ namespace OpenRA.Mods.RA public class ShroudRendererInfo : ITraitInfo { public readonly string Sequence = "shroud"; - public readonly string[] Variants = new[] { "shroud" }; + public readonly string[] ShroudVariants = new[] { "shroud" }; + public readonly string[] FogVariants = new[] { "fog" }; public readonly string ShroudPalette = "shroud"; public readonly string FogPalette = "fog"; @@ -31,8 +33,14 @@ namespace OpenRA.Mods.RA [Desc("Use the upper four bits when calculating frame")] public readonly bool UseExtendedIndex = false; - [Desc("Palette index for synthesized unexplored tile")] - public readonly int ShroudColor = 12; + [Desc("Override for source art that doesn't define a fully shrouded tile")] + public readonly string OverrideFullShroud = null; + public readonly int OverrideShroudIndex = 15; + + [Desc("Override for source art that doesn't define a fully fogged tile")] + public readonly string OverrideFullFog = null; + public readonly int OverrideFogIndex = 15; + public readonly BlendMode ShroudBlend = BlendMode.Alpha; public object Create(ActorInitializer init) { return new ShroudRenderer(init.world, this); } } @@ -57,8 +65,7 @@ namespace OpenRA.Mods.RA } readonly ShroudRendererInfo info; - readonly Sprite[] sprites; - readonly Sprite unexploredTile; + readonly Sprite[] shroudSprites, fogSprites; readonly int[] spriteMap; readonly CellLayer tiles; readonly int variantStride; @@ -78,13 +85,33 @@ namespace OpenRA.Mods.RA shroudHash = -1; // Load sprite variants - sprites = new Sprite[info.Variants.Length * info.Index.Length]; - variantStride = info.Index.Length; - for (var j = 0; j < info.Variants.Length; j++) + if (info.ShroudVariants.Length != info.FogVariants.Length) + throw new InvalidOperationException("ShroudRenderer must define the same number of shroud and fog variants!"); + + if ((info.OverrideFullFog == null) ^ (info.OverrideFullShroud == null)) + throw new InvalidOperationException("ShroudRenderer must cannot define overrides for only one of shroud or fog!"); + + var variantCount = info.ShroudVariants.Length; + variantStride = info.Index.Length + (info.OverrideFullShroud != null ? 1 : 0); + shroudSprites = new Sprite[variantCount * variantStride]; + fogSprites = new Sprite[variantCount * variantStride]; + + for (var j = 0; j < variantCount; j++) { - var seq = map.SequenceProvider.GetSequence(info.Sequence, info.Variants[j]); + var shroud = map.SequenceProvider.GetSequence(info.Sequence, info.ShroudVariants[j]); + var fog = map.SequenceProvider.GetSequence(info.Sequence, info.FogVariants[j]); for (var i = 0; i < info.Index.Length; i++) - sprites[j * variantStride + i] = seq.GetSprite(i); + { + shroudSprites[j * variantStride + i] = shroud.GetSprite(i); + fogSprites[j * variantStride + i] = fog.GetSprite(i); + } + + if (info.OverrideFullShroud != null) + { + var i = (j + 1) * variantStride - 1; + shroudSprites[i] = map.SequenceProvider.GetSequence(info.Sequence, info.OverrideFullShroud).GetSprite(0); + fogSprites[i] = map.SequenceProvider.GetSequence(info.Sequence, info.OverrideFullFog).GetSprite(0); + } } // Mapping of shrouded directions -> sprite index @@ -92,22 +119,14 @@ namespace OpenRA.Mods.RA for (var i = 0; i < info.Index.Length; i++) spriteMap[info.Index[i]] = i; - // Synthesize unexplored tile if it isn't defined - if (!info.Index.Contains(0)) - { - var ts = Game.modData.Manifest.TileSize; - var data = Exts.MakeArray(ts.Width * ts.Height, _ => (byte)info.ShroudColor); - var s = map.SequenceProvider.SpriteLoader.SheetBuilder.Add(data, ts); - unexploredTile = new Sprite(s.sheet, s.bounds, s.offset, s.channel, info.ShroudBlend); - } - else - unexploredTile = sprites[spriteMap[0]]; + if (info.OverrideFullShroud != null) + spriteMap[info.OverrideShroudIndex] = variantStride - 1; } static int FoggedEdges(Shroud s, CPos p, bool useExtendedIndex) { if (!s.IsVisible(p)) - return 15; + return useExtendedIndex ? 240 : 15; // If a side is shrouded then we also count the corners var u = 0; @@ -134,7 +153,7 @@ namespace OpenRA.Mods.RA static int ShroudedEdges(Shroud s, CPos p, bool useExtendedIndex) { if (!s.IsExplored(p)) - return 15; + return useExtendedIndex ? 240 : 15; // If a side is shrouded then we also count the corners var u = 0; @@ -181,7 +200,7 @@ namespace OpenRA.Mods.RA foreach (var cell in map.Cells) { var screen = wr.ScreenPosition(cell.CenterPosition); - var variant = Game.CosmeticRandom.Next(info.Variants.Length); + var variant = Game.CosmeticRandom.Next(info.ShroudVariants.Length); tiles[cell] = new ShroudTile(cell, screen, variant); } @@ -194,10 +213,7 @@ namespace OpenRA.Mods.RA if (flags == 0) return null; - if (flags == 15) - return unexploredTile; - - return sprites[variant * variantStride + spriteMap[flags]]; + return shroudSprites[variant * variantStride + spriteMap[flags]]; } void Update(Shroud shroud) @@ -215,8 +231,8 @@ namespace OpenRA.Mods.RA var t = tiles[cell]; var shrouded = ObserverShroudedEdges(t.Position, map.Bounds, info.UseExtendedIndex); - t.Shroud = GetTile(shrouded, t.Variant); - t.Fog = GetTile(shrouded, t.Variant); + t.Shroud = shrouded != 0 ? shroudSprites[t.Variant * variantStride + spriteMap[shrouded]] : null; + t.Fog = shrouded != 0 ? fogSprites[t.Variant * variantStride + spriteMap[shrouded]] : null; } } else @@ -227,8 +243,8 @@ namespace OpenRA.Mods.RA var shrouded = ShroudedEdges(shroud, t.Position, info.UseExtendedIndex); var fogged = FoggedEdges(shroud, t.Position, info.UseExtendedIndex); - t.Shroud = GetTile(shrouded, t.Variant); - t.Fog = GetTile(fogged, t.Variant); + t.Shroud = shrouded != 0 ? shroudSprites[t.Variant * variantStride + spriteMap[shrouded]] : null; + t.Fog = fogged != 0 ? fogSprites[t.Variant * variantStride + spriteMap[fogged]] : null; } } } diff --git a/mods/cnc/bits/fullshroud.shp b/mods/cnc/bits/fullshroud.shp new file mode 100644 index 0000000000..6d687e204c Binary files /dev/null and b/mods/cnc/bits/fullshroud.shp differ diff --git a/mods/cnc/rules/world.yaml b/mods/cnc/rules/world.yaml index f40d5491ca..3eb91bd8a8 100644 --- a/mods/cnc/rules/world.yaml +++ b/mods/cnc/rules/world.yaml @@ -72,7 +72,10 @@ World: Name: fog Fog: true ShroudRenderer: - Variants: typea, typeb, typec, typed + ShroudVariants: typea, typeb, typec, typed + FogVariants: typea, typeb, typec, typed + OverrideFullShroud: full + OverrideFullFog: full Country@gdi: Name: GDI Race: gdi diff --git a/mods/cnc/sequences/misc.yaml b/mods/cnc/sequences/misc.yaml index f03536b144..7923c38446 100644 --- a/mods/cnc/sequences/misc.yaml +++ b/mods/cnc/sequences/misc.yaml @@ -442,6 +442,7 @@ shroud: typed: shadow Start: 36 Length: 12 + full: fullshroud # Note: The order of smudges and craters determines # the index that is mapped to them in maps diff --git a/mods/d2k/bits/fullshroud.shp b/mods/d2k/bits/fullshroud.shp new file mode 100644 index 0000000000..e778274b51 Binary files /dev/null and b/mods/d2k/bits/fullshroud.shp differ diff --git a/mods/d2k/rules/world.yaml b/mods/d2k/rules/world.yaml index 7b72401fdd..065254f6a8 100644 --- a/mods/d2k/rules/world.yaml +++ b/mods/d2k/rules/world.yaml @@ -87,9 +87,11 @@ World: Offset: 12007 InvertColor: true ShroudRenderer: - Variants: typea, typeb, typec, typed + ShroudVariants: typea, typeb, typec, typed + FogVariants: typea, typeb, typec, typed Index: 11, 3, 7, 9, 6, 13, 12, 14, 4, 8, 2, 1, 5, 10 - ShroudColor: 31 + OverrideFullShroud: full + OverrideFullFog: full ShroudBlend: Multiply Country@Atreides: Name: Atreides diff --git a/mods/d2k/sequences/misc.yaml b/mods/d2k/sequences/misc.yaml index eec8df8a7c..9d99c60a6f 100644 --- a/mods/d2k/sequences/misc.yaml +++ b/mods/d2k/sequences/misc.yaml @@ -347,6 +347,8 @@ shroud: Length: 14 Offset: -16,-16 BlendMode: Multiply + full: fullshroud + BlendMode: Multiply rockcraters: rockcrater1: DATA diff --git a/mods/ra/rules/world.yaml b/mods/ra/rules/world.yaml index 26d5a21173..441c3a3f3c 100644 --- a/mods/ra/rules/world.yaml +++ b/mods/ra/rules/world.yaml @@ -87,6 +87,7 @@ World: Name: fog Fog: true ShroudRenderer: + FogVariants: shroud Index: 255, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 20, 40, 56, 65, 97, 130, 148, 194, 24, 33, 66, 132, 28, 41, 67, 134, 1, 2, 4, 8, 3, 6, 12, 9, 7, 14, 13, 11, 5, 10, 15, 255 UseExtendedIndex: true Country@0: diff --git a/mods/ts/sequences/misc.yaml b/mods/ts/sequences/misc.yaml index 59e152eadd..2f73cc9c2c 100644 --- a/mods/ts/sequences/misc.yaml +++ b/mods/ts/sequences/misc.yaml @@ -387,6 +387,8 @@ resources: shroud: shroud: shadow #TODO: use shroud.shp Length: * + fog: shadow + Length: * scorches: #TODO: make use of 07-12 as well sc1: burnt01