Better generation for all map types

Removed 'smoothed random'
This commit is contained in:
Yair Morgenstern 2023-01-19 18:33:32 +02:00
parent 4a3ef08324
commit 508ce0681d
5 changed files with 10 additions and 48 deletions

View File

@ -353,7 +353,6 @@ Map Generation Type =
Enabled Map Generation Types =
Default =
Pangaea =
Smoothed Random =
Continent and Islands =
Two Continents =
Three Continents =

View File

@ -1,9 +1,9 @@
package com.unciv.logic.map
import com.unciv.logic.IsPartOfGameInfoSerialization
import com.unciv.logic.map.HexMath.getEquivalentHexagonalRadius
import com.unciv.logic.map.HexMath.getEquivalentRectangularSize
import com.unciv.logic.map.HexMath.getNumberOfTilesInHexagon
import com.unciv.logic.IsPartOfGameInfoSerialization
import com.unciv.models.metadata.BaseRuleset
@ -147,9 +147,6 @@ object MapType : IsPartOfGameInfoSerialization {
const val archipelago = "Archipelago"
const val innerSea = "Inner Sea"
// Cellular automata style
const val smoothedRandom = "Smoothed Random"
// All ocean tiles
const val empty = "Empty"
}
@ -230,10 +227,7 @@ class MapParameters : IsPartOfGameInfoSerialization {
vegetationRichness = 0.4f
rareFeaturesRichness = 0.05f
resourceRichness = 0.1f
waterThreshold = if (type == MapType.smoothedRandom)
-0.05f // make world about 55% land
else
0f
waterThreshold = 0f
}
fun getArea() = when {

View File

@ -2,8 +2,8 @@ package com.unciv.logic.map.mapgenerator
import com.unciv.Constants
import com.unciv.UncivGame
import com.unciv.logic.map.HexMath
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.map.HexMath
import com.unciv.logic.map.MapParameters
import com.unciv.logic.map.MapShape
import com.unciv.logic.map.MapType
@ -903,7 +903,7 @@ class MapGenerationRandomness {
nOctaves: Int = 6,
persistence: Double = 0.5,
lacunarity: Double = 2.0,
scale: Double = 10.0
scale: Double = 30.0
): Double {
val worldCoords = HexMath.hex2WorldCoords(tile.position)
return Perlin.noise3d(worldCoords.x.toDouble(), worldCoords.y.toDouble(), seed, nOctaves, persistence, lacunarity, scale)

View File

@ -49,7 +49,6 @@ class MapLandmassGenerator(val ruleset: Ruleset, val randomness: MapGenerationRa
MapType.twoContinents -> createTwoContinents(tileMap)
MapType.threeContinents -> createThreeContinents(tileMap)
MapType.fourCorners -> createFourCorners(tileMap)
MapType.smoothedRandom -> generateLandCellularAutomata(tileMap)
MapType.archipelago -> createArchipelago(tileMap)
MapType.default -> createPerlin(tileMap)
}
@ -89,24 +88,6 @@ class MapLandmassGenerator(val ruleset: Ruleset, val randomness: MapGenerationRa
tile.baseTerrain = if (elevation < waterThreshold) waterTerrainName else landTerrainName
}
/**
* Smoothen the map by clustering landmass and oceans with probability [threshold].
* [TileInfo]s with more than 3 land neighbours are converted to land.
* [TileInfo]s with more than 3 water neighbours are converted to water.
*/
private fun smoothen(tileMap: TileMap, threshold: Double = 1.0) {
for (tileInfo in tileMap.values) {
if (randomness.RNG.nextFloat() > threshold)
continue
val numberOfLandNeighbors = tileInfo.neighbors.count { it.baseTerrain == landTerrainName }
if (numberOfLandNeighbors > 3)
tileInfo.baseTerrain = landTerrainName
else if (numberOfLandNeighbors < 3)
tileInfo.baseTerrain = waterTerrainName
}
}
private fun createPerlin(tileMap: TileMap) {
val elevationSeed = randomness.RNG.nextInt().toDouble()
for (tile in tileMap.values) {
@ -127,7 +108,7 @@ class MapLandmassGenerator(val ruleset: Ruleset, val randomness: MapGenerationRa
private fun createPangaea(tileMap: TileMap) {
val elevationSeed = randomness.RNG.nextInt().toDouble()
for (tile in tileMap.values) {
var elevation = randomness.getPerlinNoise(tile, elevationSeed, scale=30.0)
var elevation = randomness.getPerlinNoise(tile, elevationSeed)
elevation = elevation*(3/4f) + getEllipticContinent(tile, tileMap) / 4
spawnLandOrWater(tile, elevation)
}
@ -190,7 +171,7 @@ class MapLandmassGenerator(val ruleset: Ruleset, val randomness: MapGenerationRa
val elevationSeed = randomness.RNG.nextInt().toDouble()
for (tile in tileMap.values) {
var elevation = randomness.getPerlinNoise(tile, elevationSeed)
elevation = (elevation + getFourCornersTransform(tile, tileMap)) / 2.0
elevation = elevation/2 + getFourCornersTransform(tile, tileMap)/2
spawnLandOrWater(tile, elevation)
}
}
@ -248,7 +229,7 @@ class MapLandmassGenerator(val ruleset: Ruleset, val randomness: MapGenerationRa
// So what we do it create a line of water in the middle - where latitude or longitude is close to 0.
val randomScale = randomness.RNG.nextDouble()
val latitudeFactor = abs(tileInfo.latitude) / tileMap.maxLatitude
var longitudeFactor = abs(tileInfo.longitude) / tileMap.maxLongitude
val longitudeFactor = abs(tileInfo.longitude) / tileMap.maxLongitude
var factor = if (isLatitude) latitudeFactor else longitudeFactor
@ -317,9 +298,11 @@ class MapLandmassGenerator(val ruleset: Ruleset, val randomness: MapGenerationRa
) * 1.5f
}
val shouldBeWater = 1-factor
// there's nothing magical about this, it's just what we got from playing around with a lot of different options -
// the numbers can be changed if you find that something else creates better looking continents
return min(0.2, -1.0 + (5.0 * factor.pow(0.5f) + randomScale) / 3.0)
return 1.0 - (5.0 * shouldBeWater*shouldBeWater + randomScale) / 3.0
}
/**
@ -333,17 +316,4 @@ class MapLandmassGenerator(val ruleset: Ruleset, val randomness: MapGenerationRa
val worldCoords = HexMath.hex2WorldCoords(tile.position)
return Perlin.ridgedNoise3d(worldCoords.x.toDouble(), worldCoords.y.toDouble(), seed, nOctaves, persistence, lacunarity, scale)
}
private fun generateLandCellularAutomata(tileMap: TileMap) {
// Empiric nice looking range: 0.37..0.72 giving ~15%-85% water
// The old code had 0.55 (inverted) hard-coded, so to get the same we need waterThreshold = -0.055 for the MainMenu background.
waterThreshold = 0.545 + 1.75 * waterThreshold
for (tile in tileMap.values) {
spawnLandOrWater(tile, randomness.RNG.nextDouble()) // RNG is [0.0, 1.0]
tile.setTransients()
}
smoothen(tileMap)
}
}

View File

@ -123,7 +123,6 @@ class MapParametersTable(
MapType.twoContinents,
MapType.threeContinents,
MapType.fourCorners,
MapType.smoothedRandom,
MapType.archipelago,
MapType.innerSea,
if (forMapEditor && mapGeneratedMainType != MapGeneratedMainType.randomGenerated) MapType.empty else null