diff --git a/core/src/com/unciv/ui/tilegroups/TileGroup.kt b/core/src/com/unciv/ui/tilegroups/TileGroup.kt index ae35264a9d..5cc032f508 100644 --- a/core/src/com/unciv/ui/tilegroups/TileGroup.kt +++ b/core/src/com/unciv/ui/tilegroups/TileGroup.kt @@ -53,9 +53,9 @@ open class TileGroup(var tileInfo: TileInfo, var tileSetStrings:TileSetStrings) protected var naturalWonderImage: Image? = null protected var pixelMilitaryUnitImageLocation = "" - protected var pixelMilitaryUnitImage: Image? = null + protected var pixelMilitaryUnitGroup = Group().apply { isTransform = false; setSize(groupSize, groupSize) } protected var pixelCivilianUnitImageLocation = "" - protected var pixelCivilianUnitImage: Image? = null + protected var pixelCivilianUnitGroup = Group().apply { isTransform = false; setSize(groupSize, groupSize) } val miscLayerGroup = Group().apply { isTransform = false; setSize(groupSize, groupSize) } var resourceImage: Actor? = null @@ -93,6 +93,9 @@ open class TileGroup(var tileInfo: TileInfo, var tileSetStrings:TileSetStrings) this.addActor(cityButtonLayerGroup) this.addActor(circleCrosshairFogLayerGroup) + terrainFeatureLayerGroup.addActor(pixelMilitaryUnitGroup) + terrainFeatureLayerGroup.addActor(pixelCivilianUnitGroup) + updateTileImage(null) addCircleImage() @@ -597,15 +600,16 @@ open class TileGroup(var tileInfo: TileInfo, var tileSetStrings:TileSetStrings) } if (pixelMilitaryUnitImageLocation != newImageLocation) { - pixelMilitaryUnitImage?.remove() - pixelMilitaryUnitImage = null + pixelMilitaryUnitGroup.clear() pixelMilitaryUnitImageLocation = newImageLocation if (newImageLocation != "" && ImageGetter.imageExists(newImageLocation)) { - val pixelUnitImage = ImageGetter.getImage(newImageLocation) - terrainFeatureLayerGroup.addActor(pixelUnitImage) - setHexagonImageSize(pixelUnitImage)// Treat this as A TILE, which gets overlayed on the base tile. - pixelMilitaryUnitImage = pixelUnitImage + val nation = militaryUnit!!.civInfo.nation + val pixelUnitImages = ImageGetter.getLayeredImageColored(newImageLocation, null, nation.getInnerColor(), nation.getOuterColor()) + for (pixelUnitImage in pixelUnitImages) { + pixelMilitaryUnitGroup.addActor(pixelUnitImage) + setHexagonImageSize(pixelUnitImage)// Treat this as A TILE, which gets overlayed on the base tile. + } } } } @@ -613,9 +617,10 @@ open class TileGroup(var tileInfo: TileInfo, var tileSetStrings:TileSetStrings) fun updatePixelCivilianUnit(tileIsViewable: Boolean) { var newImageLocation = "" + val civilianUnit = tileInfo.civilianUnit - if (tileInfo.civilianUnit != null && tileIsViewable) { - val specificUnitIconLocation = tileSetStrings.unitsLocation + tileInfo.civilianUnit!!.name + if (civilianUnit != null && tileIsViewable) { + val specificUnitIconLocation = tileSetStrings.unitsLocation + civilianUnit.name newImageLocation = when { !UncivGame.Current.settings.showPixelUnits -> "" ImageGetter.imageExists(specificUnitIconLocation) -> specificUnitIconLocation @@ -624,15 +629,16 @@ open class TileGroup(var tileInfo: TileInfo, var tileSetStrings:TileSetStrings) } if (pixelCivilianUnitImageLocation != newImageLocation) { - pixelCivilianUnitImage?.remove() - pixelCivilianUnitImage = null + pixelCivilianUnitGroup.clear() pixelCivilianUnitImageLocation = newImageLocation if (newImageLocation != "" && ImageGetter.imageExists(newImageLocation)) { - val pixelUnitImage = ImageGetter.getImage(newImageLocation) - terrainFeatureLayerGroup.addActor(pixelUnitImage) - setHexagonImageSize(pixelUnitImage)// Treat this as A TILE, which gets overlayed on the base tile. - pixelCivilianUnitImage = pixelUnitImage + val nation = civilianUnit!!.civInfo.nation + val pixelUnitImages = ImageGetter.getLayeredImageColored(newImageLocation, null, nation.getInnerColor(), nation.getOuterColor()) + for (pixelUnitImage in pixelUnitImages) { + pixelCivilianUnitGroup.addActor(pixelUnitImage) + setHexagonImageSize(pixelUnitImage)// Treat this as A TILE, which gets overlayed on the base tile. + } } } } diff --git a/core/src/com/unciv/ui/utils/ImageGetter.kt b/core/src/com/unciv/ui/utils/ImageGetter.kt index 83950d5e02..3ac4a4996f 100644 --- a/core/src/com/unciv/ui/utils/ImageGetter.kt +++ b/core/src/com/unciv/ui/utils/ImageGetter.kt @@ -67,6 +67,61 @@ object ImageGetter { } } + + /** + * Colors a multilayer image and returns it as a list of layers (Image). + * + * @param baseFileName The filename of the base image. + * For example: TileSets/FantasyHex/Units/Warrior + * + * @param colors The list of colors, one per layer. No coloring is applied to layers + * whose color is null. + * + * @return The list of layers colored. The layers are sorted by NUMBER (see example below) order + * and colors are applied, one per layer, in the same order. If a color is null, no + * coloring is performed on such layer (it stays as it is). If there are less colors + * than layers, the last layers are not colored. Defaults to an empty list if there + * is no layer corresponding to baseFileName. + * + * Example: + * getLayeredImageColored("TileSets/FantasyHex/Units/Warrior", null, Color.GOLD, Color.RED) + * + * All images in the atlas that match the pattern "TileSets/FantasyHex/Units/Warrior" or + * "TileSets/FantasyHex/Units/Warrior-NUMBER" are retrieved. NUMBERs must start from 1 and + * be incremented by 1 per layer. If the n-th NUMBER is missing, the (n-1)-th layer is the + * last one retrieved: + * Given the layer names: + * - TileSets/FantasyHex/Units/Warrior + * - TileSets/FantasyHex/Units/Warrior-1 + * - TileSets/FantasyHex/Units/Warrior-2 + * - TileSets/FantasyHex/Units/Warrior-4 + * Only the base layer and layers 1 and 2 are retrieved. + * The method returns then a list in which first layer has unmodified colors, the second is + * colored in GOLD and the third in RED. + */ + fun getLayeredImageColored(baseFileName: String, vararg colors: Color?): ArrayList { + if (!imageExists(baseFileName)) + return arrayListOf() + + val layerNames = mutableListOf(baseFileName) + val layerList = arrayListOf() + + var i = 1 + while (imageExists("$baseFileName-$i")) { + layerNames.add("$baseFileName-$i") + ++i + } + + for (i in layerNames.indices) { + val image = getImage(layerNames[i]) + if (i < colors.size && colors[i] != null) + image.color = colors[i] + layerList.add(image) + } + + return layerList + } + /*fun refreshAtlas() { atlas.dispose() // To avoid OutOfMemory exceptions atlas = TextureAtlas("game.atlas")