diff --git a/core/src/com/unciv/logic/map/HexMath.kt b/core/src/com/unciv/logic/map/HexMath.kt index 31588793dd..1c4cf0c902 100644 --- a/core/src/com/unciv/logic/map/HexMath.kt +++ b/core/src/com/unciv/logic/map/HexMath.kt @@ -126,49 +126,49 @@ object HexMath { // y is 2 o'clock - increases column by 1, x in 10 o'clock - decreases by 1 fun getColumn(hexCoord: Vector2): Int = (hexCoord.y - hexCoord.x).toInt() - fun hex2CubicCoords(hexCoord: Vector2): Vector3 { - return Vector3(hexCoord.y - hexCoord.x, hexCoord.x, -hexCoord.y) - } - - fun cubic2HexCoords(cubicCoord: Vector3): Vector2 { - return Vector2(cubicCoord.y, -cubicCoord.z) - } - - - fun evenQ2CubicCoords(evenQCoord: Vector2): Vector3 { - val x = evenQCoord.x - val z = evenQCoord.y - (evenQCoord.x + (evenQCoord.x.toInt() and 1)) / 2 - val y = -x - z - return Vector3(x, y, z) - } - - fun evenQ2HexCoords(evenQCoord: Vector2): Vector2 { - return if (evenQCoord == Vector2.Zero) - Vector2.Zero - else - cubic2HexCoords(evenQ2CubicCoords(evenQCoord)) - } - - fun roundCubicCoords(cubicCoords: Vector3): Vector3 { - var rx = round(cubicCoords.x) - var ry = round(cubicCoords.y) - var rz = round(cubicCoords.z) - - val deltaX = abs(rx - cubicCoords.x) - val deltaY = abs(ry - cubicCoords.y) - val deltaZ = abs(rz - cubicCoords.z) - - if (deltaX > deltaY && deltaX > deltaZ) - rx = -ry - rz - else if (deltaY > deltaZ) - ry = -rx - rz - else - rz = -rx - ry - - return Vector3(rx, ry, rz) + fun getTileCoordsFromColumnRow(column: Int, row: Int): Vector2 { + // we know that column = y-x in hex coords + // And we know that row = y+x in hex coords + // Therefore, row+column = 2y, row-column=2x + + // However, these row numbers only apear on alternating columns. + // So column 0 will have rows 0,2,4, etc, and column 1 will have rows 1,3,5 etc. + // you'll need to see a hexmap to see it, and then it will be obvious + + val adjustedRow = if (column%2 == 0) row*2f else row*2f + 1 + return Vector2((adjustedRow-column)/2, (adjustedRow+column)/2) } + /** Todo: find a mathematically equivalent way to round hex coords without cubic magic */ fun roundHexCoords(hexCoord: Vector2): Vector2 { + + fun roundCubicCoords(cubicCoords: Vector3): Vector3 { + var rx = round(cubicCoords.x) + var ry = round(cubicCoords.y) + var rz = round(cubicCoords.z) + + val deltaX = abs(rx - cubicCoords.x) + val deltaY = abs(ry - cubicCoords.y) + val deltaZ = abs(rz - cubicCoords.z) + + if (deltaX > deltaY && deltaX > deltaZ) + rx = -ry - rz + else if (deltaY > deltaZ) + ry = -rx - rz + else + rz = -rx - ry + + return Vector3(rx, ry, rz) + } + + fun hex2CubicCoords(hexCoord: Vector2): Vector3 { + return Vector3(hexCoord.y - hexCoord.x, hexCoord.x, -hexCoord.y) + } + + fun cubic2HexCoords(cubicCoord: Vector3): Vector2 { + return Vector2(cubicCoord.y, -cubicCoord.z) + } + return cubic2HexCoords(roundCubicCoords(hex2CubicCoords(hexCoord))) } diff --git a/core/src/com/unciv/logic/map/TileMap.kt b/core/src/com/unciv/logic/map/TileMap.kt index 7727c78769..fb82d674c5 100644 --- a/core/src/com/unciv/logic/map/TileMap.kt +++ b/core/src/com/unciv/logic/map/TileMap.kt @@ -115,10 +115,10 @@ class TileMap : IsPartOfGameInfoSerialization { // Even widths will have coordinates ranging -x..(x-1), not -x..x, which is always an odd-sized range // e.g. w=4 -> -2..1, w=5 -> -2..2, w=6 -> -3..2, w=7 -> -3..3 - for (row in -wrapAdjustedWidth / 2 .. (wrapAdjustedWidth-1) / 2) - for (column in -height / 2 .. (height-1) / 2) + for (column in -wrapAdjustedWidth / 2 .. (wrapAdjustedWidth-1) / 2) + for (row in -height / 2 .. (height-1) / 2) tileList.add(Tile().apply { - position = HexMath.evenQ2HexCoords(Vector2(row.toFloat(), column.toFloat())) + position = HexMath.getTileCoordsFromColumnRow(column, row) baseTerrain = firstAvailableLandTerrain }) @@ -205,8 +205,8 @@ class TileMap : IsPartOfGameInfoSerialization { }.filterNotNull() /** @return all tiles within [rectangle], respecting world edges and wrap. - * If using even Q coordinates the rectangle will be "straight" ie parallel with rectangular map edges. */ - fun getTilesInRectangle(rectangle: Rectangle, evenQ: Boolean = false): Sequence = + * If using row/column coordinates the rectangle will be "straight" ie parallel with rectangular map edges. */ + fun getTilesInRectangle(rectangle: Rectangle, rowsAndColumns: Boolean = false): Sequence = if (rectangle.width <= 0 || rectangle.height <= 0) { val tile = getIfTileExistsOrNull(rectangle.x.toInt(), rectangle.y.toInt()) if (tile == null) sequenceOf() @@ -214,12 +214,13 @@ class TileMap : IsPartOfGameInfoSerialization { } else sequence { - for (x in 0 until rectangle.width.toInt()) { - for (y in 0 until rectangle.height.toInt()) { - val currentX = rectangle.x + x - val currentY = rectangle.y + y - if (evenQ) { - val hexCoords = HexMath.evenQ2HexCoords(Vector2(currentX, currentY)) + for (column in 0 until rectangle.width.toInt()) { + for (row in 0 until rectangle.height.toInt()) { + val currentX = rectangle.x + column + val currentY = rectangle.y + row + + if (rowsAndColumns) { + val hexCoords = HexMath.getTileCoordsFromColumnRow(column, row) yield(getIfTileExistsOrNull(hexCoords.x.toInt(), hexCoords.y.toInt())) } else diff --git a/core/src/com/unciv/logic/map/mapgenerator/MapRegions.kt b/core/src/com/unciv/logic/map/mapgenerator/MapRegions.kt index ef94685ef0..950cba0d6f 100644 --- a/core/src/com/unciv/logic/map/mapgenerator/MapRegions.kt +++ b/core/src/com/unciv/logic/map/mapgenerator/MapRegions.kt @@ -174,12 +174,12 @@ class MapRegions (val ruleset: Ruleset){ splitOffRegion.tileMap.getTilesInRectangle(Rectangle( splitOffRegion.rect.x + splitPoint - 1, splitOffRegion.rect.y, 1f, splitOffRegion.rect.height), - evenQ = true) + rowsAndColumns = true) else splitOffRegion.tileMap.getTilesInRectangle(Rectangle( splitOffRegion.rect.x, splitOffRegion.rect.y + splitPoint - 1, splitOffRegion.rect.width, 1f), - evenQ = true) + rowsAndColumns = true) cumulativeFertility += if (splitOffRegion.continentID == -1) nextRect.sumOf { it.getTileFertility(false) } @@ -408,7 +408,7 @@ class MapRegions (val ruleset: Ruleset){ val fallbackTiles = HashSet() // First check center - val centerTiles = region.tileMap.getTilesInRectangle(centerRect, evenQ = true) + val centerTiles = region.tileMap.getTilesInRectangle(centerRect, rowsAndColumns = true) for (tile in centerTiles) { if (tileData[tile.position]!!.isTwoFromCoast) continue // Don't even consider tiles two from coast @@ -436,7 +436,7 @@ class MapRegions (val ruleset: Ruleset){ } // Now check middle donut - val middleDonut = region.tileMap.getTilesInRectangle(middleRect, evenQ = true).filterNot { it in centerTiles } + val middleDonut = region.tileMap.getTilesInRectangle(middleRect, rowsAndColumns = true).filterNot { it in centerTiles } riverTiles.clear() wetTiles.clear() dryTiles.clear() @@ -467,7 +467,7 @@ class MapRegions (val ruleset: Ruleset){ } // Now check the outer tiles. For these we don't care about rivers, coasts etc - val outerDonut = region.tileMap.getTilesInRectangle(region.rect, evenQ = true).filterNot { it in centerTiles || it in middleDonut} + val outerDonut = region.tileMap.getTilesInRectangle(region.rect, rowsAndColumns = true).filterNot { it in centerTiles || it in middleDonut} dryTiles.clear() for (tile in outerDonut) { if (region.continentID != -1 && region.continentID != tile.getContinent()) @@ -1693,7 +1693,7 @@ class Region (val tileMap: TileMap, val rect: Rectangle, val continentID: Int = val columnHasTile = HashSet() tiles.clear() - for (tile in tileMap.getTilesInRectangle(rect, evenQ = true).filter { + for (tile in tileMap.getTilesInRectangle(rect, rowsAndColumns = true).filter { continentID == -1 || it.getContinent() == continentID } ) { val fertility = tile.getTileFertility(continentID != -1) tiles.add(tile)