mirror of
https://github.com/yairm210/Unciv.git
synced 2025-03-03 22:22:51 +07:00
chore: Simplified hex coord math - part 2
This commit is contained in:
parent
e390a4f579
commit
a9903ad0f5
@ -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)))
|
||||
}
|
||||
|
||||
|
@ -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<Tile> =
|
||||
* If using row/column coordinates the rectangle will be "straight" ie parallel with rectangular map edges. */
|
||||
fun getTilesInRectangle(rectangle: Rectangle, rowsAndColumns: Boolean = false): Sequence<Tile> =
|
||||
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
|
||||
|
@ -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<Vector2>()
|
||||
|
||||
// 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<Int>()
|
||||
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user