Natural wonders uniques generalized to work for terrain feature as well

This commit is contained in:
yairm210 2024-08-25 09:44:31 +03:00
parent ebc5c8c315
commit 036a2e6e9c
2 changed files with 65 additions and 45 deletions

View File

@ -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())

View File

@ -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<Tile>): Collection<Tile> {
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<Tile>, 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) {