Support split sprites for fog/shroud.

This commit is contained in:
Paul Chote
2014-06-20 23:35:03 +12:00
parent 8c4dcb7fe0
commit 8f046c7c5a
9 changed files with 61 additions and 34 deletions

View File

@@ -8,6 +8,7 @@
*/ */
#endregion #endregion
using System;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
using OpenRA; using OpenRA;
@@ -19,7 +20,8 @@ namespace OpenRA.Mods.RA
public class ShroudRendererInfo : ITraitInfo public class ShroudRendererInfo : ITraitInfo
{ {
public readonly string Sequence = "shroud"; 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 ShroudPalette = "shroud";
public readonly string FogPalette = "fog"; public readonly string FogPalette = "fog";
@@ -31,8 +33,14 @@ namespace OpenRA.Mods.RA
[Desc("Use the upper four bits when calculating frame")] [Desc("Use the upper four bits when calculating frame")]
public readonly bool UseExtendedIndex = false; public readonly bool UseExtendedIndex = false;
[Desc("Palette index for synthesized unexplored tile")] [Desc("Override for source art that doesn't define a fully shrouded tile")]
public readonly int ShroudColor = 12; 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 readonly BlendMode ShroudBlend = BlendMode.Alpha;
public object Create(ActorInitializer init) { return new ShroudRenderer(init.world, this); } public object Create(ActorInitializer init) { return new ShroudRenderer(init.world, this); }
} }
@@ -57,8 +65,7 @@ namespace OpenRA.Mods.RA
} }
readonly ShroudRendererInfo info; readonly ShroudRendererInfo info;
readonly Sprite[] sprites; readonly Sprite[] shroudSprites, fogSprites;
readonly Sprite unexploredTile;
readonly int[] spriteMap; readonly int[] spriteMap;
readonly CellLayer<ShroudTile> tiles; readonly CellLayer<ShroudTile> tiles;
readonly int variantStride; readonly int variantStride;
@@ -78,13 +85,33 @@ namespace OpenRA.Mods.RA
shroudHash = -1; shroudHash = -1;
// Load sprite variants // Load sprite variants
sprites = new Sprite[info.Variants.Length * info.Index.Length]; if (info.ShroudVariants.Length != info.FogVariants.Length)
variantStride = info.Index.Length; throw new InvalidOperationException("ShroudRenderer must define the same number of shroud and fog variants!");
for (var j = 0; j < info.Variants.Length; j++)
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++) 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 // Mapping of shrouded directions -> sprite index
@@ -92,22 +119,14 @@ namespace OpenRA.Mods.RA
for (var i = 0; i < info.Index.Length; i++) for (var i = 0; i < info.Index.Length; i++)
spriteMap[info.Index[i]] = i; spriteMap[info.Index[i]] = i;
// Synthesize unexplored tile if it isn't defined if (info.OverrideFullShroud != null)
if (!info.Index.Contains(0)) spriteMap[info.OverrideShroudIndex] = variantStride - 1;
{
var ts = Game.modData.Manifest.TileSize;
var data = Exts.MakeArray<byte>(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]];
} }
static int FoggedEdges(Shroud s, CPos p, bool useExtendedIndex) static int FoggedEdges(Shroud s, CPos p, bool useExtendedIndex)
{ {
if (!s.IsVisible(p)) if (!s.IsVisible(p))
return 15; return useExtendedIndex ? 240 : 15;
// If a side is shrouded then we also count the corners // If a side is shrouded then we also count the corners
var u = 0; var u = 0;
@@ -134,7 +153,7 @@ namespace OpenRA.Mods.RA
static int ShroudedEdges(Shroud s, CPos p, bool useExtendedIndex) static int ShroudedEdges(Shroud s, CPos p, bool useExtendedIndex)
{ {
if (!s.IsExplored(p)) if (!s.IsExplored(p))
return 15; return useExtendedIndex ? 240 : 15;
// If a side is shrouded then we also count the corners // If a side is shrouded then we also count the corners
var u = 0; var u = 0;
@@ -181,7 +200,7 @@ namespace OpenRA.Mods.RA
foreach (var cell in map.Cells) foreach (var cell in map.Cells)
{ {
var screen = wr.ScreenPosition(cell.CenterPosition); 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); tiles[cell] = new ShroudTile(cell, screen, variant);
} }
@@ -194,10 +213,7 @@ namespace OpenRA.Mods.RA
if (flags == 0) if (flags == 0)
return null; return null;
if (flags == 15) return shroudSprites[variant * variantStride + spriteMap[flags]];
return unexploredTile;
return sprites[variant * variantStride + spriteMap[flags]];
} }
void Update(Shroud shroud) void Update(Shroud shroud)
@@ -215,8 +231,8 @@ namespace OpenRA.Mods.RA
var t = tiles[cell]; var t = tiles[cell];
var shrouded = ObserverShroudedEdges(t.Position, map.Bounds, info.UseExtendedIndex); var shrouded = ObserverShroudedEdges(t.Position, map.Bounds, info.UseExtendedIndex);
t.Shroud = GetTile(shrouded, t.Variant); t.Shroud = shrouded != 0 ? shroudSprites[t.Variant * variantStride + spriteMap[shrouded]] : null;
t.Fog = GetTile(shrouded, t.Variant); t.Fog = shrouded != 0 ? fogSprites[t.Variant * variantStride + spriteMap[shrouded]] : null;
} }
} }
else else
@@ -227,8 +243,8 @@ namespace OpenRA.Mods.RA
var shrouded = ShroudedEdges(shroud, t.Position, info.UseExtendedIndex); var shrouded = ShroudedEdges(shroud, t.Position, info.UseExtendedIndex);
var fogged = FoggedEdges(shroud, t.Position, info.UseExtendedIndex); var fogged = FoggedEdges(shroud, t.Position, info.UseExtendedIndex);
t.Shroud = GetTile(shrouded, t.Variant); t.Shroud = shrouded != 0 ? shroudSprites[t.Variant * variantStride + spriteMap[shrouded]] : null;
t.Fog = GetTile(fogged, t.Variant); t.Fog = fogged != 0 ? fogSprites[t.Variant * variantStride + spriteMap[fogged]] : null;
} }
} }
} }

Binary file not shown.

View File

@@ -72,7 +72,10 @@ World:
Name: fog Name: fog
Fog: true Fog: true
ShroudRenderer: ShroudRenderer:
Variants: typea, typeb, typec, typed ShroudVariants: typea, typeb, typec, typed
FogVariants: typea, typeb, typec, typed
OverrideFullShroud: full
OverrideFullFog: full
Country@gdi: Country@gdi:
Name: GDI Name: GDI
Race: gdi Race: gdi

View File

@@ -442,6 +442,7 @@ shroud:
typed: shadow typed: shadow
Start: 36 Start: 36
Length: 12 Length: 12
full: fullshroud
# Note: The order of smudges and craters determines # Note: The order of smudges and craters determines
# the index that is mapped to them in maps # the index that is mapped to them in maps

Binary file not shown.

View File

@@ -87,9 +87,11 @@ World:
Offset: 12007 Offset: 12007
InvertColor: true InvertColor: true
ShroudRenderer: 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 Index: 11, 3, 7, 9, 6, 13, 12, 14, 4, 8, 2, 1, 5, 10
ShroudColor: 31 OverrideFullShroud: full
OverrideFullFog: full
ShroudBlend: Multiply ShroudBlend: Multiply
Country@Atreides: Country@Atreides:
Name: Atreides Name: Atreides

View File

@@ -347,6 +347,8 @@ shroud:
Length: 14 Length: 14
Offset: -16,-16 Offset: -16,-16
BlendMode: Multiply BlendMode: Multiply
full: fullshroud
BlendMode: Multiply
rockcraters: rockcraters:
rockcrater1: DATA rockcrater1: DATA

View File

@@ -87,6 +87,7 @@ World:
Name: fog Name: fog
Fog: true Fog: true
ShroudRenderer: 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 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 UseExtendedIndex: true
Country@0: Country@0:

View File

@@ -387,6 +387,8 @@ resources:
shroud: shroud:
shroud: shadow #TODO: use shroud.shp shroud: shadow #TODO: use shroud.shp
Length: * Length: *
fog: shadow
Length: *
scorches: #TODO: make use of 07-12 as well scorches: #TODO: make use of 07-12 as well
sc1: burnt01 sc1: burnt01