Tilesets: Added edge tile images!

This commit is contained in:
yairm210
2024-09-21 22:11:18 +03:00
parent c5bf9b387b
commit a91d32874b
5 changed files with 90 additions and 4 deletions

View File

@ -691,6 +691,8 @@ class Tile : IsPartOfGameInfoSerialization, Json.Serializable {
else probability
}
fun isTilemapInitialized() = ::tileMap.isInitialized
//endregion
//region state-changing functions
@ -712,7 +714,7 @@ class Tile : IsPartOfGameInfoSerialization, Json.Serializable {
isOcean = baseTerrain == Constants.ocean
// Resource amounts missing - Old save or bad mapgen?
if (::tileMap.isInitialized && resource != null && tileResource.resourceType == ResourceType.Strategic && resourceAmount == 0) {
if (isTilemapInitialized() && resource != null && tileResource.resourceType == ResourceType.Strategic && resourceAmount == 0) {
// Let's assume it's a small deposit
setTileResource(tileResource, majorDeposit = false)
}
@ -812,7 +814,7 @@ class Tile : IsPartOfGameInfoSerialization, Json.Serializable {
}
private fun updateUniqueMap() {
if (!::tileMap.isInitialized) return // This tile is a fake tile, for visual display only (e.g. map editor, civilopedia)
if (!isTilemapInitialized()) return // This tile is a fake tile, for visual display only (e.g. map editor, civilopedia)
val terrainNameList = allTerrains.map { it.name }.toList()
// List hash is function of all its items, so the same items in the same order will always give the same hash

View File

@ -8,6 +8,8 @@ import com.unciv.models.metadata.GameSettings
import com.unciv.models.ruleset.Ruleset
import com.unciv.models.tilesets.TileSetCache
import com.unciv.models.tilesets.TileSetConfig
import com.unciv.ui.components.tilegroups.layers.EdgeTileImage
import com.unciv.ui.components.tilegroups.layers.NeighborDirection
import com.unciv.ui.images.ImageAttempter
import com.unciv.ui.images.ImageGetter
@ -67,6 +69,26 @@ class TileSetStrings(
val bottomRiver by lazy { orFallback { tilesLocation + "River-Bottom"} }
val bottomLeftRiver by lazy { orFallback { tilesLocation + "River-BottomLeft"} }
val edgeImagesByPosition = ImageGetter.getAllImageNames()
.filter { it.startsWith(tileSetLocation +"Edges/") }
.mapNotNull {
val split = it.split('/').last() // without folder
.split("-")
// Comprised of 3 parts: origin tilefilter, destination tilefilter,
// and edge type: Bottom, BottomLeft or BottomRight
if (split.size != 4) return@mapNotNull null
// split[0] is name and is unused
val originTileFilter = split[1]
val destinationTileFilter = split[2]
val neighborDirection = split[3]
val neighborDirectionEnumValue = NeighborDirection.entries
.firstOrNull { it.name == neighborDirection } ?: return@mapNotNull null
EdgeTileImage(it, originTileFilter, destinationTileFilter, neighborDirectionEnumValue)
}
.groupBy { it.edgeType }
val unitsLocation = unitSetLocation + "Units/"
val bordersLocation = tileSetLocation + "Borders/"

View File

@ -1,6 +1,7 @@
package com.unciv.ui.components.tilegroups.layers
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.math.Vector2
import com.badlogic.gdx.scenes.scene2d.Actor
import com.badlogic.gdx.scenes.scene2d.ui.Image
import com.unciv.UncivGame
@ -86,8 +87,30 @@ class TileLayerTerrain(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup,
}
}
private fun getEdgeTileLocations(): Sequence<String> {
val tile = tile()
if (!tile.isTilemapInitialized()) // fake tile
return emptySequence()
return tile.neighbors
.filter { it.position.x < tile.position.x || it.position.y < tile.position.y }
.flatMap { getMatchingEdges(tile, it) }
}
private fun getMatchingEdges(originTile: Tile, neighborTile: Tile): List<String>{
val vectorToNeighbor = neighborTile.position.cpy().sub(originTile.position)
val direction = NeighborDirection.fromVector(vectorToNeighbor) ?: return emptyList()
val possibleEdgeFiles = strings().edgeImagesByPosition[direction] ?: return emptyList()
return possibleEdgeFiles.filter {
if (!originTile.matchesFilter(it.originTileFilter)) return@filter false
if (!neighborTile.matchesFilter(it.destinationTileFilter)) return@filter false
return@filter true
}.map { it.fileName }
}
private fun updateTileImage(viewingCiv: Civilization?) {
val tileBaseImageLocations = getTileBaseImageLocations(viewingCiv)
val tileBaseImageLocations = getTileBaseImageLocations(viewingCiv) +
getEdgeTileLocations()
if (tileBaseImageLocations.size == tileImageIdentifiers.size) {
if (tileBaseImageLocations.withIndex().all { (i, imageLocation) -> tileImageIdentifiers[i] == imageLocation })
@ -211,3 +234,21 @@ class TileLayerTerrain(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup,
else baseHexagon + strings().orFallback{ getTile(tileGroup.tile.naturalWonder!!) }
}
enum class NeighborDirection {
Top, TopRight, TopLeft, Bottom, BottomLeft, BottomRight;
companion object {
fun fromVector(vector2: Vector2): NeighborDirection? = when {
vector2.x == 1f && vector2.y == 1f -> Top
vector2.x == 0f && vector2.y == 1f -> TopRight
vector2.x == 1f && vector2.y == 0f -> TopLeft
vector2.x == -1f && vector2.y == -1f -> Bottom
vector2.x == 0f && vector2.y == -1f -> BottomLeft
vector2.x == -1f && vector2.y == 0f -> BottomRight
else -> null
}
}
}
data class EdgeTileImage(val fileName:String, val originTileFilter: String, val destinationTileFilter: String, val edgeType: NeighborDirection)

View File

@ -468,6 +468,8 @@ object ImageGetter {
return specialist
}
fun getAllImageNames() = textureRegionDrawables.keys
fun getAvailableSkins() = ninePatchDrawables.keys.asSequence().map { it.split("/")[1] }.distinct()
/** Determines available TileSets from the currently loaded Texture paths.

View File

@ -146,3 +146,22 @@ They can be for unit types (Archery, Seige, Cavalry) or for specific unit names
The files should be in the format of `<unit type/unit name>-attack-<frame number>`.
For example, a 3 frame animation for Sword units would have the files `Sword-attack-1.png`, `Sword-attack-3.png`, `Sword-attack-3.png`
## Edge images
You can add additional images that will be drawn only when a tile is adjacent to another tile in a specific direction.
The images should be placed in the `Images/Tilesets/<tileset name>/Edges` folder, rather than in `/Tiles`.
The name of the tile should be `<tile name>-<origin tile filter>-<destination tile filter>-<neighbor direction>.png`, where direction of one of:
- Bottom
- BottomLeft
- BottomRight
- Top
- TopLeft
- TopRight
For example: `Cliff-Hills-Coast-Top.png`
The initial name has no bearing on the image used, it is just a way to group images together.