diff --git a/core/src/com/unciv/logic/map/MapParameters.kt b/core/src/com/unciv/logic/map/MapParameters.kt index 75a0eccaae..464edd0558 100644 --- a/core/src/com/unciv/logic/map/MapParameters.kt +++ b/core/src/com/unciv/logic/map/MapParameters.kt @@ -131,6 +131,7 @@ object MapType : IsPartOfGameInfoSerialization { const val default = "Default" const val pangaea = "Pangaea" const val twoContinents = "Two Continents" + const val threeContinents = "Three Continents" const val fourCorners = "Four Corners" const val archipelago = "Archipelago" const val innerSea = "Inner Sea" diff --git a/core/src/com/unciv/logic/map/mapgenerator/MapLandmassGenerator.kt b/core/src/com/unciv/logic/map/mapgenerator/MapLandmassGenerator.kt index bfdee3aadf..1b146c4b47 100644 --- a/core/src/com/unciv/logic/map/mapgenerator/MapLandmassGenerator.kt +++ b/core/src/com/unciv/logic/map/mapgenerator/MapLandmassGenerator.kt @@ -5,6 +5,7 @@ import com.unciv.logic.map.* import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.tile.TerrainType import kotlin.math.abs +import kotlin.math.max import kotlin.math.min import kotlin.math.pow @@ -41,6 +42,7 @@ class MapLandmassGenerator(val ruleset: Ruleset, val randomness: MapGenerationRa MapType.pangaea -> createPangaea(tileMap) MapType.innerSea -> createInnerSea(tileMap) MapType.twoContinents -> createTwoContinents(tileMap) + MapType.threeContinents -> createThreeContinents(tileMap) MapType.fourCorners -> createFourCorners(tileMap) MapType.smoothedRandom -> generateLandCellularAutomata(tileMap) MapType.archipelago -> createArchipelago(tileMap) @@ -120,6 +122,17 @@ class MapLandmassGenerator(val ruleset: Ruleset, val randomness: MapGenerationRa } } + private fun createThreeContinents(tileMap: TileMap) { + val isNorth = randomness.RNG.nextDouble() < 0.5f + + val elevationSeed = randomness.RNG.nextInt().toDouble() + for (tile in tileMap.values) { + var elevation = randomness.getPerlinNoise(tile, elevationSeed) + elevation = (elevation + getThreeContinentsTransform(tile, tileMap, isNorth)) / 2.0 + spawnLandOrWater(tile, elevation) + } + } + private fun createFourCorners(tileMap: TileMap) { val elevationSeed = randomness.RNG.nextInt().toDouble() for (tile in tileMap.values) { @@ -167,6 +180,37 @@ class MapLandmassGenerator(val ruleset: Ruleset, val randomness: MapGenerationRa return min(0.2, -1.0 + (5.0 * factor.pow(0.6f) + randomScale) / 3.0) } + private fun getThreeContinentsTransform(tileInfo: TileInfo, tileMap: TileMap, isNorth: Boolean): Double { + // The idea here is to create a water area separating the two four areas. + // So what we do it create a line of water in the middle - where longitude is close to 0. + val randomScale = randomness.RNG.nextDouble() + var longitudeFactor = abs(tileInfo.longitude) / tileMap.maxLongitude + var latitudeFactor = abs(tileInfo.latitude) / tileMap.maxLatitude + + // We then pick one side to be merged into one centered continent instead of two cornered. + if (isNorth && tileInfo.latitude < 0 || !isNorth && tileInfo.latitude > 0) + longitudeFactor = max(0f, tileMap.maxLongitude - abs(tileInfo.longitude * 2f)) / tileMap.maxLongitude + + // If this is a world wrap, we want it to be separated on both sides - + // so we make the actual strip of water thinner, but we put it both in the middle of the map and on the edges of the map + if (tileMap.mapParameters.worldWrap) { + longitudeFactor = min( + longitudeFactor, + (tileMap.maxLongitude - abs(tileInfo.longitude)) / tileMap.maxLongitude + ) * 1.5f + latitudeFactor = min( + latitudeFactor, + (tileMap.maxLatitude - abs(tileInfo.latitude)) / tileMap.maxLatitude + ) * 1.5f + } + // 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 + + val landFactor = min(longitudeFactor, latitudeFactor) + + return min(0.2, -1.0 + (5.0 * landFactor.pow(0.5f) + randomScale) / 3.0) + } + private fun getFourCornersTransform(tileInfo: TileInfo, tileMap: TileMap): Double { // The idea here is to create a water area separating the two four areas. // So what we do it create a line of water in the middle - where longitude is close to 0. diff --git a/core/src/com/unciv/ui/newgamescreen/MapParametersTable.kt b/core/src/com/unciv/ui/newgamescreen/MapParametersTable.kt index c570d529b6..1c6ad444fd 100644 --- a/core/src/com/unciv/ui/newgamescreen/MapParametersTable.kt +++ b/core/src/com/unciv/ui/newgamescreen/MapParametersTable.kt @@ -95,6 +95,7 @@ class MapParametersTable( MapType.default, MapType.pangaea, MapType.twoContinents, + MapType.threeContinents, MapType.fourCorners, MapType.smoothedRandom, MapType.archipelago,