Merge pull request #10246 from penev92/terrainPalettes

Allow tile templates to define their own palette
This commit is contained in:
Oliver Brakmann
2016-01-17 21:39:28 +01:00
14 changed files with 39 additions and 21 deletions

View File

@@ -9,25 +9,32 @@
#endregion #endregion
using System; using System;
using System.Collections.Generic;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Graphics namespace OpenRA.Graphics
{ {
sealed class TerrainRenderer : IDisposable sealed class TerrainRenderer : IDisposable
{ {
readonly TerrainSpriteLayer terrain; readonly World world;
readonly Dictionary<string, TerrainSpriteLayer> spriteLayers = new Dictionary<string, TerrainSpriteLayer>();
readonly Theater theater; readonly Theater theater;
readonly CellLayer<TerrainTile> mapTiles; readonly CellLayer<TerrainTile> mapTiles;
readonly CellLayer<byte> mapHeight; readonly CellLayer<byte> mapHeight;
public TerrainRenderer(World world, WorldRenderer wr) public TerrainRenderer(World world, WorldRenderer wr)
{ {
this.world = world;
theater = wr.Theater; theater = wr.Theater;
mapTiles = world.Map.MapTiles.Value; mapTiles = world.Map.MapTiles.Value;
mapHeight = world.Map.MapHeight.Value; mapHeight = world.Map.MapHeight.Value;
terrain = new TerrainSpriteLayer(world, wr, theater.Sheet, BlendMode.Alpha, foreach (var template in world.TileSet.Templates)
wr.Palette("terrain"), wr.World.Type != WorldType.Editor); {
var palette = template.Value.Palette ?? TileSet.TerrainPaletteInternalName;
spriteLayers.GetOrAdd(palette, pal =>
new TerrainSpriteLayer(world, wr, theater.Sheet, BlendMode.Alpha, wr.Palette(palette), wr.World.Type != WorldType.Editor));
}
foreach (var cell in world.Map.AllCells) foreach (var cell in world.Map.AllCells)
UpdateCell(cell); UpdateCell(cell);
@@ -38,12 +45,18 @@ namespace OpenRA.Graphics
public void UpdateCell(CPos cell) public void UpdateCell(CPos cell)
{ {
terrain.Update(cell, theater.TileSprite(mapTiles[cell])); var tile = mapTiles[cell];
var palette = world.TileSet.Templates[tile.Type].Palette ?? TileSet.TerrainPaletteInternalName;
var sprite = theater.TileSprite(tile);
foreach (var kv in spriteLayers)
kv.Value.Update(cell, palette == kv.Key ? sprite : null);
} }
public void Draw(WorldRenderer wr, Viewport viewport) public void Draw(WorldRenderer wr, Viewport viewport)
{ {
terrain.Draw(viewport); foreach (var kv in spriteLayers.Values)
kv.Draw(wr.Viewport);
foreach (var r in wr.World.WorldActor.TraitsImplementing<IRenderOverlay>()) foreach (var r in wr.World.WorldActor.TraitsImplementing<IRenderOverlay>())
r.Render(wr); r.Render(wr);
} }
@@ -52,7 +65,9 @@ namespace OpenRA.Graphics
{ {
mapTiles.CellEntryChanged -= UpdateCell; mapTiles.CellEntryChanged -= UpdateCell;
mapHeight.CellEntryChanged -= UpdateCell; mapHeight.CellEntryChanged -= UpdateCell;
terrain.Dispose();
foreach (var kv in spriteLayers.Values)
kv.Dispose();
} }
} }
} }

View File

@@ -73,6 +73,7 @@ namespace OpenRA
public readonly int2 Size; public readonly int2 Size;
public readonly bool PickAny; public readonly bool PickAny;
public readonly string Category; public readonly string Category;
public readonly string Palette;
readonly TerrainTileInfo[] tileInfo; readonly TerrainTileInfo[] tileInfo;
@@ -166,6 +167,8 @@ namespace OpenRA
public class TileSet public class TileSet
{ {
public const string TerrainPaletteInternalName = "terrain";
public readonly string Name; public readonly string Name;
public readonly string Id; public readonly string Id;
public readonly int SheetSize = 512; public readonly int SheetSize = 512;

View File

@@ -16,7 +16,7 @@ namespace OpenRA.Traits
public class FixedColorPaletteInfo : ITraitInfo public class FixedColorPaletteInfo : ITraitInfo
{ {
[Desc("The name of the palette to base off.")] [Desc("The name of the palette to base off.")]
[PaletteReference] public readonly string Base = "terrain"; [PaletteReference] public readonly string Base = TileSet.TerrainPaletteInternalName;
[Desc("The name of the resulting palette")] [Desc("The name of the resulting palette")]
[PaletteDefinition] public readonly string Name = "resources"; [PaletteDefinition] public readonly string Name = "resources";

View File

@@ -17,7 +17,7 @@ namespace OpenRA.Traits
{ {
public readonly string Sequence = "resources"; public readonly string Sequence = "resources";
[SequenceReference("Sequence")] public readonly string[] Variants = { }; [SequenceReference("Sequence")] public readonly string[] Variants = { };
[PaletteReference] public readonly string Palette = "terrain"; [PaletteReference] public readonly string Palette = TileSet.TerrainPaletteInternalName;
public readonly int ResourceType = 1; public readonly int ResourceType = 1;
public readonly int ValuePerUnit = 0; public readonly int ValuePerUnit = 0;

View File

@@ -18,7 +18,7 @@ namespace OpenRA.Mods.Common.Traits
public class BibInfo : ITraitInfo, Requires<BuildingInfo>, IRenderActorPreviewSpritesInfo, Requires<RenderSpritesInfo> public class BibInfo : ITraitInfo, Requires<BuildingInfo>, IRenderActorPreviewSpritesInfo, Requires<RenderSpritesInfo>
{ {
[SequenceReference] public readonly string Sequence = "bib"; [SequenceReference] public readonly string Sequence = "bib";
[PaletteReference] public readonly string Palette = "terrain"; [PaletteReference] public readonly string Palette = TileSet.TerrainPaletteInternalName;
public readonly bool HasMinibib = false; public readonly bool HasMinibib = false;
public object Create(ActorInitializer init) { return new Bib(init.Self, this); } public object Create(ActorInitializer init) { return new Bib(init.Self, this); }

View File

@@ -192,7 +192,7 @@ namespace OpenRA.Mods.Common.Traits
{ {
if (!initialized) if (!initialized)
{ {
var palette = wr.Palette("terrain"); var palette = wr.Palette(TileSet.TerrainPaletteInternalName);
renderables = new Dictionary<ushort, IRenderable[]>(); renderables = new Dictionary<ushort, IRenderable[]>();
foreach (var t in info.Templates) foreach (var t in info.Templates)
renderables.Add(t.First, TemplateRenderables(wr, palette, t.First)); renderables.Add(t.First, TemplateRenderables(wr, palette, t.First));

View File

@@ -20,7 +20,7 @@ namespace OpenRA.Mods.Common.Traits
public class PlaceBuildingInfo : ITraitInfo public class PlaceBuildingInfo : ITraitInfo
{ {
[Desc("Palette to use for rendering the placement sprite.")] [Desc("Palette to use for rendering the placement sprite.")]
[PaletteReference] public readonly string Palette = "terrain"; [PaletteReference] public readonly string Palette = TileSet.TerrainPaletteInternalName;
[Desc("Play NewOptionsNotification this many ticks after building placement.")] [Desc("Play NewOptionsNotification this many ticks after building placement.")]
public readonly int NewOptionsNotificationDelay = 10; public readonly int NewOptionsNotificationDelay = 10;

View File

@@ -149,7 +149,7 @@ namespace OpenRA.Mods.Common.Traits
public IEnumerable<IRenderable> Render(WorldRenderer wr, World world) public IEnumerable<IRenderable> Render(WorldRenderer wr, World world)
{ {
var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos); var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos);
var pal = wr.Palette("terrain"); var pal = wr.Palette(TileSet.TerrainPaletteInternalName);
foreach (var t in world.Map.FindTilesInCircle(xy, range)) foreach (var t in world.Map.FindTilesInCircle(xy, range))
yield return new SpriteRenderable(tile, wr.World.Map.CenterOfCell(t), WVec.Zero, -511, pal, 1f, true); yield return new SpriteRenderable(tile, wr.World.Map.CenterOfCell(t), WVec.Zero, -511, pal, 1f, true);

View File

@@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Traits
{ {
[PaletteReference] [PaletteReference]
[Desc("Palette to use for rendering the placement sprite.")] [Desc("Palette to use for rendering the placement sprite.")]
public readonly string Palette = "terrain"; public readonly string Palette = TileSet.TerrainPaletteInternalName;
[Desc("Sequence image where the selection overlay types are defined.")] [Desc("Sequence image where the selection overlay types are defined.")]
public readonly string Image = "editor-overlay"; public readonly string Image = "editor-overlay";

View File

@@ -33,7 +33,7 @@ namespace OpenRA.Mods.Common.Traits
[PaletteReference] public readonly string SmokePalette = "effect"; [PaletteReference] public readonly string SmokePalette = "effect";
[PaletteReference] public readonly string Palette = "terrain"; [PaletteReference] public readonly string Palette = TileSet.TerrainPaletteInternalName;
public object Create(ActorInitializer init) { return new SmudgeLayer(init.Self, this); } public object Create(ActorInitializer init) { return new SmudgeLayer(init.Self, this); }
} }

View File

@@ -18,7 +18,6 @@ namespace OpenRA.Mods.Common.Widgets
public class TerrainTemplatePreviewWidget : Widget public class TerrainTemplatePreviewWidget : Widget
{ {
public Func<float> GetScale = () => 1f; public Func<float> GetScale = () => 1f;
public string Palette = "terrain";
readonly WorldRenderer worldRenderer; readonly WorldRenderer worldRenderer;
readonly TileSet tileset; readonly TileSet tileset;
@@ -93,7 +92,8 @@ namespace OpenRA.Mods.Common.Widgets
var u = gridType == MapGridType.Rectangular ? x : (x - y) / 2f; var u = gridType == MapGridType.Rectangular ? x : (x - y) / 2f;
var v = gridType == MapGridType.Rectangular ? y : (x + y) / 2f; var v = gridType == MapGridType.Rectangular ? y : (x + y) / 2f;
var pos = origin + scale * (new float2(u * ts.Width, (v - 0.5f * tileInfo.Height) * ts.Height) - 0.5f * sprite.Size); var pos = origin + scale * (new float2(u * ts.Width, (v - 0.5f * tileInfo.Height) * ts.Height) - 0.5f * sprite.Size);
Game.Renderer.SpriteRenderer.DrawSprite(sprite, pos, worldRenderer.Palette(Palette), size); var palette = Template.Palette ?? TileSet.TerrainPaletteInternalName;
Game.Renderer.SpriteRenderer.DrawSprite(sprite, pos, worldRenderer.Palette(palette), size);
} }
} }
} }

View File

@@ -18,7 +18,7 @@ namespace OpenRA.Mods.D2k.Traits
public class BuildableTerrainLayerInfo : ITraitInfo public class BuildableTerrainLayerInfo : ITraitInfo
{ {
[Desc("Palette to render the layer sprites in.")] [Desc("Palette to render the layer sprites in.")]
public readonly string Palette = "terrain"; public readonly string Palette = TileSet.TerrainPaletteInternalName;
public object Create(ActorInitializer init) { return new BuildableTerrainLayer(init.Self, this); } public object Create(ActorInitializer init) { return new BuildableTerrainLayer(init.Self, this); }
} }

View File

@@ -121,7 +121,7 @@ namespace OpenRA.Mods.RA.Traits
if (self.Owner != self.World.LocalPlayer || Minefield == null) if (self.Owner != self.World.LocalPlayer || Minefield == null)
yield break; yield break;
var pal = wr.Palette("terrain"); var pal = wr.Palette(TileSet.TerrainPaletteInternalName);
foreach (var c in Minefield) foreach (var c in Minefield)
yield return new SpriteRenderable(tile, self.World.Map.CenterOfCell(c), yield return new SpriteRenderable(tile, self.World.Map.CenterOfCell(c),
WVec.Zero, -511, pal, 1f, true); WVec.Zero, -511, pal, 1f, true);
@@ -181,7 +181,7 @@ namespace OpenRA.Mods.RA.Traits
var minefield = GetMinefieldCells(minefieldStart, lastMousePos, var minefield = GetMinefieldCells(minefieldStart, lastMousePos,
minelayer.Info.TraitInfo<MinelayerInfo>().MinefieldDepth); minelayer.Info.TraitInfo<MinelayerInfo>().MinefieldDepth);
var pal = wr.Palette("terrain"); var pal = wr.Palette(TileSet.TerrainPaletteInternalName);
foreach (var c in minefield) foreach (var c in minefield)
{ {
var tile = movement.CanEnterCell(c, null, false) ? tileOk : tileBlocked; var tile = movement.CanEnterCell(c, null, false) ? tileOk : tileBlocked;

View File

@@ -145,7 +145,7 @@ namespace OpenRA.Mods.RA.Traits
{ {
var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos); var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos);
var tiles = world.Map.FindTilesInCircle(xy, range); var tiles = world.Map.FindTilesInCircle(xy, range);
var pal = wr.Palette("terrain"); var pal = wr.Palette(TileSet.TerrainPaletteInternalName);
foreach (var t in tiles) foreach (var t in tiles)
yield return new SpriteRenderable(tile, wr.World.Map.CenterOfCell(t), WVec.Zero, -511, pal, 1f, true); yield return new SpriteRenderable(tile, wr.World.Map.CenterOfCell(t), WVec.Zero, -511, pal, 1f, true);
} }
@@ -224,7 +224,7 @@ namespace OpenRA.Mods.RA.Traits
public IEnumerable<IRenderable> Render(WorldRenderer wr, World world) public IEnumerable<IRenderable> Render(WorldRenderer wr, World world)
{ {
var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos); var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos);
var pal = wr.Palette("terrain"); var pal = wr.Palette(TileSet.TerrainPaletteInternalName);
// Source tiles // Source tiles
foreach (var t in world.Map.FindTilesInCircle(sourceLocation, range)) foreach (var t in world.Map.FindTilesInCircle(sourceLocation, range))