From 0c51d73be9da81eb11628a97a8a507645dc072f2 Mon Sep 17 00:00:00 2001 From: Pavel Penev Date: Sun, 20 Dec 2015 15:50:01 +0200 Subject: [PATCH 1/3] Enable use of "custom" palettes per tile Templates Keep the tileset's palette as default, defined on the tileset, but override it for any tile templates that may want to do so with a palette defined on the template. --- OpenRA.Game/Graphics/TerrainRenderer.cs | 29 ++++++++++++++++++++----- OpenRA.Game/Map/TileSet.cs | 1 + 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/OpenRA.Game/Graphics/TerrainRenderer.cs b/OpenRA.Game/Graphics/TerrainRenderer.cs index a6011527b0..7ef1e011ea 100644 --- a/OpenRA.Game/Graphics/TerrainRenderer.cs +++ b/OpenRA.Game/Graphics/TerrainRenderer.cs @@ -9,25 +9,34 @@ #endregion using System; +using System.Collections.Generic; using OpenRA.Traits; namespace OpenRA.Graphics { sealed class TerrainRenderer : IDisposable { - readonly TerrainSpriteLayer terrain; + const string TerrainPalette = "terrain"; + + readonly World world; + readonly Dictionary spriteLayers = new Dictionary(); readonly Theater theater; readonly CellLayer mapTiles; readonly CellLayer mapHeight; public TerrainRenderer(World world, WorldRenderer wr) { + this.world = world; theater = wr.Theater; mapTiles = world.Map.MapTiles.Value; mapHeight = world.Map.MapHeight.Value; - terrain = new TerrainSpriteLayer(world, wr, theater.Sheet, BlendMode.Alpha, - wr.Palette("terrain"), wr.World.Type != WorldType.Editor); + foreach (var template in world.TileSet.Templates) + { + var palette = template.Value.Palette ?? TerrainPalette; + 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) UpdateCell(cell); @@ -38,12 +47,18 @@ namespace OpenRA.Graphics public void UpdateCell(CPos cell) { - terrain.Update(cell, theater.TileSprite(mapTiles[cell])); + var tile = mapTiles[cell]; + var palette = world.TileSet.Templates[tile.Type].Palette ?? TerrainPalette; + 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) { - terrain.Draw(viewport); + foreach (var kv in spriteLayers.Values) + kv.Draw(wr.Viewport); + foreach (var r in wr.World.WorldActor.TraitsImplementing()) r.Render(wr); } @@ -52,7 +67,9 @@ namespace OpenRA.Graphics { mapTiles.CellEntryChanged -= UpdateCell; mapHeight.CellEntryChanged -= UpdateCell; - terrain.Dispose(); + + foreach (var kv in spriteLayers.Values) + kv.Dispose(); } } } diff --git a/OpenRA.Game/Map/TileSet.cs b/OpenRA.Game/Map/TileSet.cs index c886fd1ed4..1750484aba 100644 --- a/OpenRA.Game/Map/TileSet.cs +++ b/OpenRA.Game/Map/TileSet.cs @@ -73,6 +73,7 @@ namespace OpenRA public readonly int2 Size; public readonly bool PickAny; public readonly string Category; + public readonly string Palette; readonly TerrainTileInfo[] tileInfo; From 861d1368a474b9b5054de80a43cb6dbefd744949 Mon Sep 17 00:00:00 2001 From: Pavel Penev Date: Sat, 2 Jan 2016 16:30:43 +0200 Subject: [PATCH 2/3] Unhardcode internal terrain palette name from all over the codebase --- OpenRA.Game/Graphics/TerrainRenderer.cs | 6 ++---- OpenRA.Game/Map/TileSet.cs | 2 ++ OpenRA.Game/Traits/Player/FixedColorPalette.cs | 2 +- OpenRA.Game/Traits/World/ResourceType.cs | 2 +- OpenRA.Mods.Common/Traits/Buildings/Bib.cs | 2 +- OpenRA.Mods.Common/Traits/Buildings/Bridge.cs | 2 +- OpenRA.Mods.Common/Traits/Player/PlaceBuilding.cs | 2 +- .../Traits/SupportPowers/GrantUpgradePower.cs | 2 +- OpenRA.Mods.Common/Traits/World/EditorSelectionLayer.cs | 2 +- OpenRA.Mods.Common/Traits/World/SmudgeLayer.cs | 2 +- OpenRA.Mods.Common/Widgets/TerrainTemplatePreviewWidget.cs | 2 +- OpenRA.Mods.D2k/Traits/World/BuildableTerrainLayer.cs | 2 +- OpenRA.Mods.RA/Traits/Minelayer.cs | 4 ++-- OpenRA.Mods.RA/Traits/SupportPowers/ChronoshiftPower.cs | 4 ++-- 14 files changed, 18 insertions(+), 18 deletions(-) diff --git a/OpenRA.Game/Graphics/TerrainRenderer.cs b/OpenRA.Game/Graphics/TerrainRenderer.cs index 7ef1e011ea..c46cd9a4f2 100644 --- a/OpenRA.Game/Graphics/TerrainRenderer.cs +++ b/OpenRA.Game/Graphics/TerrainRenderer.cs @@ -16,8 +16,6 @@ namespace OpenRA.Graphics { sealed class TerrainRenderer : IDisposable { - const string TerrainPalette = "terrain"; - readonly World world; readonly Dictionary spriteLayers = new Dictionary(); readonly Theater theater; @@ -33,7 +31,7 @@ namespace OpenRA.Graphics foreach (var template in world.TileSet.Templates) { - var palette = template.Value.Palette ?? TerrainPalette; + 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)); } @@ -48,7 +46,7 @@ namespace OpenRA.Graphics public void UpdateCell(CPos cell) { var tile = mapTiles[cell]; - var palette = world.TileSet.Templates[tile.Type].Palette ?? TerrainPalette; + 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); diff --git a/OpenRA.Game/Map/TileSet.cs b/OpenRA.Game/Map/TileSet.cs index 1750484aba..438131a2a8 100644 --- a/OpenRA.Game/Map/TileSet.cs +++ b/OpenRA.Game/Map/TileSet.cs @@ -167,6 +167,8 @@ namespace OpenRA public class TileSet { + public const string TerrainPaletteInternalName = "terrain"; + public readonly string Name; public readonly string Id; public readonly int SheetSize = 512; diff --git a/OpenRA.Game/Traits/Player/FixedColorPalette.cs b/OpenRA.Game/Traits/Player/FixedColorPalette.cs index 5997f777f4..aaa551222b 100644 --- a/OpenRA.Game/Traits/Player/FixedColorPalette.cs +++ b/OpenRA.Game/Traits/Player/FixedColorPalette.cs @@ -16,7 +16,7 @@ namespace OpenRA.Traits public class FixedColorPaletteInfo : ITraitInfo { [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")] [PaletteDefinition] public readonly string Name = "resources"; diff --git a/OpenRA.Game/Traits/World/ResourceType.cs b/OpenRA.Game/Traits/World/ResourceType.cs index 850d5645dc..e3268b5d53 100644 --- a/OpenRA.Game/Traits/World/ResourceType.cs +++ b/OpenRA.Game/Traits/World/ResourceType.cs @@ -17,7 +17,7 @@ namespace OpenRA.Traits { public readonly string Sequence = "resources"; [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 ValuePerUnit = 0; diff --git a/OpenRA.Mods.Common/Traits/Buildings/Bib.cs b/OpenRA.Mods.Common/Traits/Buildings/Bib.cs index 4ec09d3bfb..43ea569d05 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/Bib.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/Bib.cs @@ -18,7 +18,7 @@ namespace OpenRA.Mods.Common.Traits public class BibInfo : ITraitInfo, Requires, IRenderActorPreviewSpritesInfo, Requires { [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 object Create(ActorInitializer init) { return new Bib(init.Self, this); } diff --git a/OpenRA.Mods.Common/Traits/Buildings/Bridge.cs b/OpenRA.Mods.Common/Traits/Buildings/Bridge.cs index f6971dc45b..7ec7e03ccb 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/Bridge.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/Bridge.cs @@ -192,7 +192,7 @@ namespace OpenRA.Mods.Common.Traits { if (!initialized) { - var palette = wr.Palette("terrain"); + var palette = wr.Palette(TileSet.TerrainPaletteInternalName); renderables = new Dictionary(); foreach (var t in info.Templates) renderables.Add(t.First, TemplateRenderables(wr, palette, t.First)); diff --git a/OpenRA.Mods.Common/Traits/Player/PlaceBuilding.cs b/OpenRA.Mods.Common/Traits/Player/PlaceBuilding.cs index c4e5a92d3c..8a6337f40e 100644 --- a/OpenRA.Mods.Common/Traits/Player/PlaceBuilding.cs +++ b/OpenRA.Mods.Common/Traits/Player/PlaceBuilding.cs @@ -20,7 +20,7 @@ namespace OpenRA.Mods.Common.Traits public class PlaceBuildingInfo : ITraitInfo { [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.")] public readonly int NewOptionsNotificationDelay = 10; diff --git a/OpenRA.Mods.Common/Traits/SupportPowers/GrantUpgradePower.cs b/OpenRA.Mods.Common/Traits/SupportPowers/GrantUpgradePower.cs index 73c34759b9..4b2cf10e46 100644 --- a/OpenRA.Mods.Common/Traits/SupportPowers/GrantUpgradePower.cs +++ b/OpenRA.Mods.Common/Traits/SupportPowers/GrantUpgradePower.cs @@ -149,7 +149,7 @@ namespace OpenRA.Mods.Common.Traits public IEnumerable Render(WorldRenderer wr, World world) { 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)) yield return new SpriteRenderable(tile, wr.World.Map.CenterOfCell(t), WVec.Zero, -511, pal, 1f, true); diff --git a/OpenRA.Mods.Common/Traits/World/EditorSelectionLayer.cs b/OpenRA.Mods.Common/Traits/World/EditorSelectionLayer.cs index 74eb68d455..396380577d 100644 --- a/OpenRA.Mods.Common/Traits/World/EditorSelectionLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/EditorSelectionLayer.cs @@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Traits { [PaletteReference] [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.")] public readonly string Image = "editor-overlay"; diff --git a/OpenRA.Mods.Common/Traits/World/SmudgeLayer.cs b/OpenRA.Mods.Common/Traits/World/SmudgeLayer.cs index fb82c9e082..b1329df415 100644 --- a/OpenRA.Mods.Common/Traits/World/SmudgeLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/SmudgeLayer.cs @@ -33,7 +33,7 @@ namespace OpenRA.Mods.Common.Traits [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); } } diff --git a/OpenRA.Mods.Common/Widgets/TerrainTemplatePreviewWidget.cs b/OpenRA.Mods.Common/Widgets/TerrainTemplatePreviewWidget.cs index 70bf4aa7bc..ecc8a12d74 100644 --- a/OpenRA.Mods.Common/Widgets/TerrainTemplatePreviewWidget.cs +++ b/OpenRA.Mods.Common/Widgets/TerrainTemplatePreviewWidget.cs @@ -18,7 +18,7 @@ namespace OpenRA.Mods.Common.Widgets public class TerrainTemplatePreviewWidget : Widget { public Func GetScale = () => 1f; - public string Palette = "terrain"; + public string Palette = TileSet.TerrainPaletteInternalName; readonly WorldRenderer worldRenderer; readonly TileSet tileset; diff --git a/OpenRA.Mods.D2k/Traits/World/BuildableTerrainLayer.cs b/OpenRA.Mods.D2k/Traits/World/BuildableTerrainLayer.cs index 3555380ba4..1593df75f0 100644 --- a/OpenRA.Mods.D2k/Traits/World/BuildableTerrainLayer.cs +++ b/OpenRA.Mods.D2k/Traits/World/BuildableTerrainLayer.cs @@ -18,7 +18,7 @@ namespace OpenRA.Mods.D2k.Traits public class BuildableTerrainLayerInfo : ITraitInfo { [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); } } diff --git a/OpenRA.Mods.RA/Traits/Minelayer.cs b/OpenRA.Mods.RA/Traits/Minelayer.cs index 8234b54023..d9c084c1dd 100644 --- a/OpenRA.Mods.RA/Traits/Minelayer.cs +++ b/OpenRA.Mods.RA/Traits/Minelayer.cs @@ -121,7 +121,7 @@ namespace OpenRA.Mods.RA.Traits if (self.Owner != self.World.LocalPlayer || Minefield == null) yield break; - var pal = wr.Palette("terrain"); + var pal = wr.Palette(TileSet.TerrainPaletteInternalName); foreach (var c in Minefield) yield return new SpriteRenderable(tile, self.World.Map.CenterOfCell(c), WVec.Zero, -511, pal, 1f, true); @@ -181,7 +181,7 @@ namespace OpenRA.Mods.RA.Traits var minefield = GetMinefieldCells(minefieldStart, lastMousePos, minelayer.Info.TraitInfo().MinefieldDepth); - var pal = wr.Palette("terrain"); + var pal = wr.Palette(TileSet.TerrainPaletteInternalName); foreach (var c in minefield) { var tile = movement.CanEnterCell(c, null, false) ? tileOk : tileBlocked; diff --git a/OpenRA.Mods.RA/Traits/SupportPowers/ChronoshiftPower.cs b/OpenRA.Mods.RA/Traits/SupportPowers/ChronoshiftPower.cs index 09f590eb32..554dd6df4c 100644 --- a/OpenRA.Mods.RA/Traits/SupportPowers/ChronoshiftPower.cs +++ b/OpenRA.Mods.RA/Traits/SupportPowers/ChronoshiftPower.cs @@ -145,7 +145,7 @@ namespace OpenRA.Mods.RA.Traits { var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos); var tiles = world.Map.FindTilesInCircle(xy, range); - var pal = wr.Palette("terrain"); + var pal = wr.Palette(TileSet.TerrainPaletteInternalName); foreach (var t in tiles) 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 Render(WorldRenderer wr, World world) { var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos); - var pal = wr.Palette("terrain"); + var pal = wr.Palette(TileSet.TerrainPaletteInternalName); // Source tiles foreach (var t in world.Map.FindTilesInCircle(sourceLocation, range)) From 288de5284e15fe4e577d6d86d65987e53f579105 Mon Sep 17 00:00:00 2001 From: Pavel Penev Date: Mon, 11 Jan 2016 00:07:38 +0200 Subject: [PATCH 3/3] Fix TerrainTemplatePreviewWidget to use proper palettes --- OpenRA.Mods.Common/Widgets/TerrainTemplatePreviewWidget.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenRA.Mods.Common/Widgets/TerrainTemplatePreviewWidget.cs b/OpenRA.Mods.Common/Widgets/TerrainTemplatePreviewWidget.cs index ecc8a12d74..bafeb36e53 100644 --- a/OpenRA.Mods.Common/Widgets/TerrainTemplatePreviewWidget.cs +++ b/OpenRA.Mods.Common/Widgets/TerrainTemplatePreviewWidget.cs @@ -18,7 +18,6 @@ namespace OpenRA.Mods.Common.Widgets public class TerrainTemplatePreviewWidget : Widget { public Func GetScale = () => 1f; - public string Palette = TileSet.TerrainPaletteInternalName; readonly WorldRenderer worldRenderer; readonly TileSet tileset; @@ -93,7 +92,8 @@ namespace OpenRA.Mods.Common.Widgets var u = gridType == MapGridType.Rectangular ? x : (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); - 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); } } }