From 036a2e6e9c6ae09fcecac724a6c0aae639c2341b Mon Sep 17 00:00:00 2001 From: yairm210 Date: Sun, 25 Aug 2024 09:44:31 +0300 Subject: [PATCH] Natural wonders uniques generalized to work for terrain feature as well --- .../logic/map/mapgenerator/MapGenerator.kt | 13 ++- .../mapgenerator/NaturalWonderGenerator.kt | 97 +++++++++++-------- 2 files changed, 65 insertions(+), 45 deletions(-) diff --git a/core/src/com/unciv/logic/map/mapgenerator/MapGenerator.kt b/core/src/com/unciv/logic/map/mapgenerator/MapGenerator.kt index bdc2c6a53d..4f11919371 100644 --- a/core/src/com/unciv/logic/map/mapgenerator/MapGenerator.kt +++ b/core/src/com/unciv/logic/map/mapgenerator/MapGenerator.kt @@ -542,6 +542,7 @@ class MapGenerator(val ruleset: Ruleset, private val coroutineScope: CoroutineSc tile.temperature!! < it.params[0].toDouble() || tile.temperature!! > it.params[1].toDouble() || tile.humidity!! < it.params[2].toDouble() || tile.humidity!! > it.params[3].toDouble() } + && NaturalWonderGenerator.fitsTerrainUniques(vegetationTerrain, tile) } if (possibleVegetation.isEmpty()) continue val randomVegetation = possibleVegetation.random(randomness.RNG) @@ -559,8 +560,11 @@ class MapGenerator(val ruleset: Ruleset, private val coroutineScope: CoroutineSc } for (tile in tileMap.values.asSequence().filter { it.terrainFeatures.isEmpty() }) { if (randomness.RNG.nextDouble() <= tileMap.mapParameters.rareFeaturesRichness) { - val possibleFeatures = rareFeatures.filter { it.occursOn.contains(tile.baseTerrain) - && (!tile.isHill() || it.occursOn.contains(Constants.hill)) } + val possibleFeatures = rareFeatures.filter { + it.occursOn.contains(tile.baseTerrain) + && (!tile.isHill() || it.occursOn.contains(Constants.hill)) + && NaturalWonderGenerator.fitsTerrainUniques(it, tile) + } if (possibleFeatures.any()) tile.addTerrainFeature(possibleFeatures.random(randomness.RNG).name) } @@ -609,8 +613,9 @@ class MapGenerator(val ruleset: Ruleset, private val coroutineScope: CoroutineSc val candidates = iceEquivalents .filter { - it.matches(temperature, 1.0) && - tile.lastTerrain.name in it.terrain.occursOn + it.matches(temperature, 1.0) + && tile.lastTerrain.name in it.terrain.occursOn + && NaturalWonderGenerator.fitsTerrainUniques(it.terrain, tile) }.map { it.terrain.name } when (candidates.size) { 1 -> tile.addTerrainFeature(candidates.first()) diff --git a/core/src/com/unciv/logic/map/mapgenerator/NaturalWonderGenerator.kt b/core/src/com/unciv/logic/map/mapgenerator/NaturalWonderGenerator.kt index a1b89082a0..6ed5eba4db 100644 --- a/core/src/com/unciv/logic/map/mapgenerator/NaturalWonderGenerator.kt +++ b/core/src/com/unciv/logic/map/mapgenerator/NaturalWonderGenerator.kt @@ -85,55 +85,19 @@ class NaturalWonderGenerator(val ruleset: Ruleset, val randomness: MapGeneration debug("Natural Wonders for this game: %s", spawned) } - private fun Unique.getIntParam(index: Int) = params[index].toInt() - private fun getCandidateTilesForWonder(tileMap: TileMap, naturalWonder: Terrain, tilesTooCloseToSpawnLocations: Set): Collection { - val continentsRelevant = naturalWonder.hasUnique(UniqueType.NaturalWonderLargerLandmass) || - naturalWonder.hasUnique(UniqueType.NaturalWonderSmallerLandmass) - val sortedContinents = if (continentsRelevant) - tileMap.continentSizes.asSequence() - .sortedByDescending { it.value } - .map { it.key } - .toList() - else listOf() - - val suitableLocations = tileMap.values.filter { tile-> + + val suitableLocations = tileMap.values.filter { tile -> tile.resource == null && tile !in tilesTooCloseToSpawnLocations && - naturalWonder.occursOn.contains(tile.lastTerrain.name) && - naturalWonder.uniqueObjects.all { unique -> - when (unique.type) { - UniqueType.NaturalWonderNeighborCount -> { - val count = tile.neighbors.count { - it.matchesWonderFilter(unique.params[1]) - } - count == unique.getIntParam(0) - } - UniqueType.NaturalWonderNeighborsRange -> { - val count = tile.neighbors.count { - it.matchesWonderFilter(unique.params[2]) - } - count in unique.getIntParam(0)..unique.getIntParam(1) - } - UniqueType.NaturalWonderSmallerLandmass -> { - tile.getContinent() !in sortedContinents.take(unique.getIntParam(0)) - } - UniqueType.NaturalWonderLargerLandmass -> { - tile.getContinent() in sortedContinents.take(unique.getIntParam(0)) - } - UniqueType.NaturalWonderLatitude -> { - val lower = tileMap.maxLatitude * unique.getIntParam(0) * 0.01f - val upper = tileMap.maxLatitude * unique.getIntParam(1) * 0.01f - abs(tile.latitude) in lower..upper - } - else -> true - } - } + naturalWonder.occursOn.contains(tile.lastTerrain.name) && + fitsTerrainUniques(naturalWonder, tile) } return suitableLocations } + private fun trySpawnOnSuitableLocation(suitableLocations: List, wonder: Terrain): Boolean { val minGroupSize: Int val maxGroupSize: Int @@ -216,6 +180,57 @@ class NaturalWonderGenerator(val ruleset: Ruleset, val randomness: MapGeneration } } + + fun fitsTerrainUniques( + naturalWonderOrTerrainFeature: Terrain, + tile: Tile + ): Boolean { + val continentsRelevant = naturalWonderOrTerrainFeature.hasUnique(UniqueType.NaturalWonderLargerLandmass) || + naturalWonderOrTerrainFeature.hasUnique(UniqueType.NaturalWonderSmallerLandmass) + val sortedContinents = if (continentsRelevant) + tile.tileMap.continentSizes.asSequence() + .sortedByDescending { it.value } + .map { it.key } + .toList() + else listOf() + + return naturalWonderOrTerrainFeature.uniqueObjects.all { unique -> + when (unique.type) { + UniqueType.NaturalWonderNeighborCount -> { + val count = tile.neighbors.count { + it.matchesWonderFilter(unique.params[1]) + } + count == unique.getIntParam(0) + } + + UniqueType.NaturalWonderNeighborsRange -> { + val count = tile.neighbors.count { + it.matchesWonderFilter(unique.params[2]) + } + count in unique.getIntParam(0)..unique.getIntParam(1) + } + + UniqueType.NaturalWonderSmallerLandmass -> { + tile.getContinent() !in sortedContinents.take(unique.getIntParam(0)) + } + + UniqueType.NaturalWonderLargerLandmass -> { + tile.getContinent() in sortedContinents.take(unique.getIntParam(0)) + } + + UniqueType.NaturalWonderLatitude -> { + val lower = tile.tileMap.maxLatitude * unique.getIntParam(0) * 0.01f + val upper = tile.tileMap.maxLatitude * unique.getIntParam(1) * 0.01f + abs(tile.latitude) in lower..upper + } + + else -> true + } + } + } + + private fun Unique.getIntParam(index: Int) = params[index].toInt() + // location is being converted to a NW, tile is a neighbor to be converted to coast: Ensure that coast won't show invalid rivers or coast touching lakes private fun removeLakesNextToFutureCoast(location: Tile, tile: Tile) { for (neighbor in tile.neighbors) {