From 42d744e5ce6c4d29610b15e50a6e32b3477870ef Mon Sep 17 00:00:00 2001 From: Starkku Date: Wed, 9 Jul 2025 22:21:33 +0300 Subject: [PATCH] Add custom palette support for TerrainTypes --- src/TSMapEditor/Initialization/Initializer.cs | 9 +----- .../Models/ArtConfig/TerrainArtConfig.cs | 29 +++++++++++++++++++ src/TSMapEditor/Models/TerrainType.cs | 12 ++------ src/TSMapEditor/Rendering/TheaterGraphics.cs | 17 ++++++++--- 4 files changed, 46 insertions(+), 21 deletions(-) create mode 100644 src/TSMapEditor/Models/ArtConfig/TerrainArtConfig.cs diff --git a/src/TSMapEditor/Initialization/Initializer.cs b/src/TSMapEditor/Initialization/Initializer.cs index e440d7844..ecdd6fd51 100644 --- a/src/TSMapEditor/Initialization/Initializer.cs +++ b/src/TSMapEditor/Initialization/Initializer.cs @@ -44,7 +44,7 @@ public Initializer(IMap map) private Dictionary> objectTypeArtInitializers = new Dictionary>() { - { typeof(TerrainType), InitTerrainTypeArt }, + { typeof(TerrainType), InitArtConfigGeneric }, { typeof(SmudgeType), InitSmudgeTypeArt }, { typeof(BuildingType), InitBuildingArtConfig }, { typeof(OverlayType), InitArtConfigGeneric }, @@ -224,13 +224,6 @@ private static void InitTerrainType(INIDefineable obj, IniFile rulesIni, IniSect terrainType.SnowOccupationBits = (TerrainOccupation)section.GetIntValue("SnowOccupationBits", 0); terrainType.TemperateOccupationBits = (TerrainOccupation)section.GetIntValue("TemperateOccupationBits", 0); } - - private static void InitTerrainTypeArt(IMap map, AbstractObject obj, IniFile artIni, IniSection artSection) - { - var terrainType = (TerrainType)obj; - terrainType.Theater = artSection.GetBooleanValue("Theater", terrainType.Theater); - terrainType.Image = artSection.GetStringValue("Image", terrainType.Image); - } private static void InitSmudgeType(INIDefineable obj, IniFile rulesIni, IniSection section) { diff --git a/src/TSMapEditor/Models/ArtConfig/TerrainArtConfig.cs b/src/TSMapEditor/Models/ArtConfig/TerrainArtConfig.cs new file mode 100644 index 000000000..ad9ceec78 --- /dev/null +++ b/src/TSMapEditor/Models/ArtConfig/TerrainArtConfig.cs @@ -0,0 +1,29 @@ +using Rampastring.Tools; + +namespace TSMapEditor.Models.ArtConfig +{ + public class TerrainArtConfig : IArtConfig + { + /// + /// Defined in Art.ini. If set to true, + /// the art for this terrain type is theater-specific; + /// if false, the art is a generic .SHP used for every theater. + /// + public bool Theater { get; set; } + + public string Image { get; set; } + public bool Remapable => false; + + /// + /// Palette override for TerrainTypes in Phobos + /// + public string Palette { get; set; } + + public void ReadFromIniSection(IniSection iniSection) + { + Theater = iniSection.GetBooleanValue(nameof(Theater), Theater); + Image = iniSection.GetStringValue(nameof(Image), Image); + Palette = iniSection.GetStringValue(nameof(Palette), Palette); + } + } +} diff --git a/src/TSMapEditor/Models/TerrainType.cs b/src/TSMapEditor/Models/TerrainType.cs index b9e8643e7..e02969830 100644 --- a/src/TSMapEditor/Models/TerrainType.cs +++ b/src/TSMapEditor/Models/TerrainType.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using TSMapEditor.GameMath; +using TSMapEditor.Models.ArtConfig; using TSMapEditor.Models.Enums; namespace TSMapEditor.Models @@ -12,6 +13,8 @@ public TerrainType(string iniName) : base(iniName) public override RTTIType WhatAmI() => RTTIType.TerrainType; + public TerrainArtConfig ArtConfig { get; } = new TerrainArtConfig(); + public TerrainOccupation TemperateOccupationBits { get; set; } public TerrainOccupation SnowOccupationBits { get; set; } @@ -24,15 +27,6 @@ public TerrainType(string iniName) : base(iniName) public int YDrawFudge { get; set; } - /// - /// Defined in Art.ini. If set to true, - /// the art for this terrain type is theater-specific; - /// if false, the art is a generic .SHP used for every theater. - /// - public bool Theater { get; set; } - - public string Image { get; set; } - /// /// Impassable cell data for automatically placing impassable overlay /// under terrain objects. diff --git a/src/TSMapEditor/Rendering/TheaterGraphics.cs b/src/TSMapEditor/Rendering/TheaterGraphics.cs index 1fc8acaab..ada7f4cba 100644 --- a/src/TSMapEditor/Rendering/TheaterGraphics.cs +++ b/src/TSMapEditor/Rendering/TheaterGraphics.cs @@ -621,17 +621,19 @@ public void ReadTerrainObjectTextures(List terrainTypes) TerrainObjectTextures = new ShapeImage[terrainTypes.Count]; for (int i = 0; i < terrainTypes.Count; i++) { - string shpFileName = terrainTypes[i].Image != null ? terrainTypes[i].Image : terrainTypes[i].ININame; + var terrainType = terrainTypes[i]; + + string shpFileName = terrainType.ArtConfig.Image != null ? terrainType.ArtConfig.Image : terrainType.ININame; string pngFileName = shpFileName + PNG_FILE_EXTENSION; - if (terrainTypes[i].Theater) + if (terrainType.ArtConfig.Theater) shpFileName += Theater.FileExtension; else shpFileName += SHP_FILE_EXTENSION; byte[] data = fileManager.LoadFile(pngFileName); - bool subjectToLighting = !terrainTypes[i].SpawnsTiberium || Constants.TiberiumTreesAffectedByLighting; + bool subjectToLighting = !terrainType.SpawnsTiberium || Constants.TiberiumTreesAffectedByLighting; if (data != null) { @@ -650,8 +652,15 @@ public void ReadTerrainObjectTextures(List terrainTypes) var shpFile = new ShpFile(shpFileName); shpFile.ParseFromBuffer(data); + + var palette = TheaterPalette; + if (terrainType.SpawnsTiberium) + palette = unitPalette; + else if (!string.IsNullOrEmpty(terrainType.ArtConfig.Palette)) + palette = GetPaletteOrDefault(terrainType.ArtConfig.Palette + Theater.FileExtension[1..] + ".pal", palette, true); + TerrainObjectTextures[i] = new ShapeImage(graphicsDevice, shpFile, data, - terrainTypes[i].SpawnsTiberium ? unitPalette : TheaterPalette, subjectToLighting); + palette, subjectToLighting); } }