mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-09 23:39:40 +07:00
Step 1 of resolving #6186 freshwater crisis - unify adjacency to a single function, only rivers are outliers (#6219)
This commit is contained in:
@ -21,12 +21,12 @@ object Constants {
|
|||||||
|
|
||||||
const val forest = "Forest"
|
const val forest = "Forest"
|
||||||
const val jungle = "Jungle"
|
const val jungle = "Jungle"
|
||||||
|
|
||||||
const val ice = "Ice"
|
const val ice = "Ice"
|
||||||
const val floodPlains = "Flood plains"
|
|
||||||
val vegetation = arrayOf(forest, jungle)
|
val vegetation = arrayOf(forest, jungle)
|
||||||
val sea = arrayOf(ocean, coast)
|
val sea = arrayOf(ocean, coast)
|
||||||
|
|
||||||
|
const val freshWater = "Fresh water"
|
||||||
|
|
||||||
const val barbarianEncampment = "Barbarian encampment"
|
const val barbarianEncampment = "Barbarian encampment"
|
||||||
|
|
||||||
const val peaceTreaty = "Peace Treaty"
|
const val peaceTreaty = "Peace Treaty"
|
||||||
|
@ -51,14 +51,6 @@ open class TileInfo {
|
|||||||
@Transient
|
@Transient
|
||||||
var isOcean = false
|
var isOcean = false
|
||||||
|
|
||||||
// This will be called often - farm can be built on Hill and tundra if adjacent to fresh water
|
|
||||||
// and farms on adjacent to fresh water tiles will have +1 additional Food after researching Civil Service
|
|
||||||
@delegate:Transient
|
|
||||||
val isAdjacentToFreshwater: Boolean by lazy {
|
|
||||||
matchesTerrainFilter("River") || matchesTerrainFilter("Fresh water")
|
|
||||||
|| neighbors.any { it.matchesTerrainFilter("Fresh water") }
|
|
||||||
}
|
|
||||||
|
|
||||||
var militaryUnit: MapUnit? = null
|
var militaryUnit: MapUnit? = null
|
||||||
var civilianUnit: MapUnit? = null
|
var civilianUnit: MapUnit? = null
|
||||||
var airUnits = ArrayList<MapUnit>()
|
var airUnits = ArrayList<MapUnit>()
|
||||||
@ -398,7 +390,7 @@ open class TileInfo {
|
|||||||
.sumOf { it.params[0].toInt() }
|
.sumOf { it.params[0].toInt() }
|
||||||
}
|
}
|
||||||
if (isAdjacentToRiver()) fertility += 1
|
if (isAdjacentToRiver()) fertility += 1
|
||||||
if (isAdjacentToFreshwater) fertility += 1 // meaning total +2 for river
|
if (isAdjacentTo(Constants.freshWater)) fertility += 1 // meaning total +2 for river
|
||||||
if (checkCoasts && isCoastalTile()) fertility += 2
|
if (checkCoasts && isCoastalTile()) fertility += 2
|
||||||
return fertility
|
return fertility
|
||||||
}
|
}
|
||||||
@ -435,8 +427,8 @@ open class TileInfo {
|
|||||||
// Freshwater and non-freshwater cannot be moved to matchesUniqueFilter since that creates an endless feedback.
|
// Freshwater and non-freshwater cannot be moved to matchesUniqueFilter since that creates an endless feedback.
|
||||||
// If you're attempting that, check that it works!
|
// If you're attempting that, check that it works!
|
||||||
// Edit: It seems to have been moved?
|
// Edit: It seems to have been moved?
|
||||||
|| unique.params[1] == "Fresh water" && isAdjacentToFreshwater
|
|| unique.params[1] == Constants.freshWater && isAdjacentTo(Constants.freshWater)
|
||||||
|| unique.params[1] == "non-fresh water" && !isAdjacentToFreshwater
|
|| unique.params[1] == "non-fresh water" && !isAdjacentTo(Constants.freshWater)
|
||||||
)
|
)
|
||||||
stats.add(unique.stats)
|
stats.add(unique.stats)
|
||||||
}
|
}
|
||||||
@ -496,10 +488,12 @@ open class TileInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This should be the only adjacency function
|
||||||
fun isAdjacentTo(terrainFilter:String): Boolean {
|
fun isAdjacentTo(terrainFilter:String): Boolean {
|
||||||
if (terrainFilter == "Fresh water" && isAdjacentToFreshwater) return true
|
// Rivers are odd, as they aren't technically part of any specific tile but still count towards adjacency
|
||||||
return if (terrainFilter == "River") isAdjacentToRiver()
|
if (terrainFilter == "River") return isAdjacentToRiver()
|
||||||
else neighbors.any { neighbor -> neighbor.matchesFilter(terrainFilter) }
|
if (terrainFilter == Constants.freshWater && isAdjacentToRiver()) return true
|
||||||
|
return neighbors.any { neighbor -> neighbor.matchesFilter(terrainFilter) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Without regards to what CivInfo it is, a lot of the checks are just for the improvement on the tile.
|
/** Without regards to what CivInfo it is, a lot of the checks are just for the improvement on the tile.
|
||||||
@ -528,14 +522,14 @@ open class TileInfo {
|
|||||||
// Tiles with no terrains, and no turns to build, are like great improvements - they're placeable
|
// Tiles with no terrains, and no turns to build, are like great improvements - they're placeable
|
||||||
improvement.terrainsCanBeBuiltOn.isEmpty() && improvement.turnsToBuild == 0 && isLand -> true
|
improvement.terrainsCanBeBuiltOn.isEmpty() && improvement.turnsToBuild == 0 && isLand -> true
|
||||||
improvement.terrainsCanBeBuiltOn.contains(topTerrain.name) -> true
|
improvement.terrainsCanBeBuiltOn.contains(topTerrain.name) -> true
|
||||||
improvement.uniqueObjects.filter { it.type == UniqueType.MustBeNextTo }.any {
|
improvement.getMatchingUniques(UniqueType.MustBeNextTo).any {
|
||||||
!isAdjacentTo(it.params[0])
|
!isAdjacentTo(it.params[0])
|
||||||
} -> false
|
} -> false
|
||||||
!isWater && RoadStatus.values().any { it.name == improvement.name && it > roadStatus } -> true
|
!isWater && RoadStatus.values().any { it.name == improvement.name && it > roadStatus } -> true
|
||||||
improvement.name == roadStatus.removeAction -> true
|
improvement.name == roadStatus.removeAction -> true
|
||||||
topTerrain.unbuildable && !improvement.isAllowedOnFeature(topTerrain.name) -> false
|
topTerrain.unbuildable && !improvement.isAllowedOnFeature(topTerrain.name) -> false
|
||||||
// DO NOT reverse this &&. isAdjacentToFreshwater() is a lazy which calls a function, and reversing it breaks the tests.
|
// DO NOT reverse this &&. isAdjacentToFreshwater() is a lazy which calls a function, and reversing it breaks the tests.
|
||||||
improvement.hasUnique(UniqueType.ImprovementBuildableByFreshWater) && isAdjacentToFreshwater -> true
|
improvement.hasUnique(UniqueType.ImprovementBuildableByFreshWater) && isAdjacentTo(Constants.freshWater) -> true
|
||||||
|
|
||||||
// If an unique of this type exists, we want all to match (e.g. Hill _and_ Forest would be meaningful).
|
// If an unique of this type exists, we want all to match (e.g. Hill _and_ Forest would be meaningful).
|
||||||
improvement.getMatchingUniques(UniqueType.CanOnlyBeBuiltOnTile).let {
|
improvement.getMatchingUniques(UniqueType.CanOnlyBeBuiltOnTile).let {
|
||||||
@ -574,7 +568,7 @@ open class TileInfo {
|
|||||||
"Water resource" -> isWater && observingCiv != null && hasViewableResource(observingCiv)
|
"Water resource" -> isWater && observingCiv != null && hasViewableResource(observingCiv)
|
||||||
"Natural Wonder" -> naturalWonder != null
|
"Natural Wonder" -> naturalWonder != null
|
||||||
"Featureless" -> terrainFeatures.isEmpty()
|
"Featureless" -> terrainFeatures.isEmpty()
|
||||||
"Fresh Water" -> isAdjacentToFreshwater
|
"Fresh Water" -> isAdjacentTo(Constants.freshWater)
|
||||||
else -> {
|
else -> {
|
||||||
if (terrainFeatures.contains(filter)) return true
|
if (terrainFeatures.contains(filter)) return true
|
||||||
if (getAllTerrains().any { it.hasUnique(filter) }) return true
|
if (getAllTerrains().any { it.hasUnique(filter) }) return true
|
||||||
|
@ -2,6 +2,7 @@ package com.unciv.logic.map.mapgenerator
|
|||||||
|
|
||||||
import com.badlogic.gdx.math.Rectangle
|
import com.badlogic.gdx.math.Rectangle
|
||||||
import com.badlogic.gdx.math.Vector2
|
import com.badlogic.gdx.math.Vector2
|
||||||
|
import com.unciv.Constants
|
||||||
import com.unciv.logic.HexMath
|
import com.unciv.logic.HexMath
|
||||||
import com.unciv.logic.civilization.CivilizationInfo
|
import com.unciv.logic.civilization.CivilizationInfo
|
||||||
import com.unciv.logic.map.*
|
import com.unciv.logic.map.*
|
||||||
@ -391,7 +392,7 @@ class MapRegions (val ruleset: Ruleset){
|
|||||||
evaluateTileForStart(tile)
|
evaluateTileForStart(tile)
|
||||||
if (tile.isAdjacentToRiver())
|
if (tile.isAdjacentToRiver())
|
||||||
riverTiles.add(tile.position)
|
riverTiles.add(tile.position)
|
||||||
else if (tile.isCoastalTile() || tile.isAdjacentToFreshwater)
|
else if (tile.isCoastalTile() || tile.isAdjacentTo(Constants.freshWater))
|
||||||
wetTiles.add(tile.position)
|
wetTiles.add(tile.position)
|
||||||
else
|
else
|
||||||
dryTiles.add(tile.position)
|
dryTiles.add(tile.position)
|
||||||
@ -422,7 +423,7 @@ class MapRegions (val ruleset: Ruleset){
|
|||||||
evaluateTileForStart(tile)
|
evaluateTileForStart(tile)
|
||||||
if (tile.isAdjacentToRiver())
|
if (tile.isAdjacentToRiver())
|
||||||
riverTiles.add(tile.position)
|
riverTiles.add(tile.position)
|
||||||
else if (tile.isCoastalTile() || tile.isAdjacentToFreshwater)
|
else if (tile.isCoastalTile() || tile.isAdjacentTo(Constants.freshWater))
|
||||||
wetTiles.add(tile.position)
|
wetTiles.add(tile.position)
|
||||||
else
|
else
|
||||||
dryTiles.add(tile.position)
|
dryTiles.add(tile.position)
|
||||||
@ -504,7 +505,7 @@ class MapRegions (val ruleset: Ruleset){
|
|||||||
// If terrible, try adding a hill to a dry flat tile
|
// If terrible, try adding a hill to a dry flat tile
|
||||||
if (innerProduction == 0 || (innerProduction < 2 && outerProduction < 8) || (minorCiv && innerProduction < 4)) {
|
if (innerProduction == 0 || (innerProduction < 2 && outerProduction < 8) || (minorCiv && innerProduction < 4)) {
|
||||||
val hillSpot = startTile.neighbors
|
val hillSpot = startTile.neighbors
|
||||||
.filter { it.isLand && it.terrainFeatures.isEmpty() && !it.isAdjacentToFreshwater && !it.isImpassible() }
|
.filter { it.isLand && it.terrainFeatures.isEmpty() && !it.isAdjacentTo(Constants.freshWater) && !it.isImpassible() }
|
||||||
.toList().randomOrNull()
|
.toList().randomOrNull()
|
||||||
val hillEquivalent = ruleset.terrains.values
|
val hillEquivalent = ruleset.terrains.values
|
||||||
.firstOrNull { it.type == TerrainType.TerrainFeature && it.production >= 2 && !it.hasUnique(UniqueType.RareFeature) }?.name
|
.firstOrNull { it.type == TerrainType.TerrainFeature && it.production >= 2 && !it.hasUnique(UniqueType.RareFeature) }?.name
|
||||||
|
@ -170,6 +170,8 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s
|
|||||||
|
|
||||||
UniqueType.ConditionalInTiles ->
|
UniqueType.ConditionalInTiles ->
|
||||||
relevantTile?.matchesFilter(condition.params[0], state.civInfo) == true
|
relevantTile?.matchesFilter(condition.params[0], state.civInfo) == true
|
||||||
|
UniqueType.ConditionalInTilesNot ->
|
||||||
|
relevantTile?.matchesFilter(condition.params[0], state.civInfo) == false
|
||||||
UniqueType.ConditionalFightingInTiles ->
|
UniqueType.ConditionalFightingInTiles ->
|
||||||
state.attackedTile?.matchesFilter(condition.params[0], state.civInfo) == true
|
state.attackedTile?.matchesFilter(condition.params[0], state.civInfo) == true
|
||||||
UniqueType.ConditionalInTilesAnd ->
|
UniqueType.ConditionalInTilesAnd ->
|
||||||
|
@ -3,6 +3,7 @@ package com.unciv.models.translations
|
|||||||
import com.badlogic.gdx.Gdx
|
import com.badlogic.gdx.Gdx
|
||||||
import com.badlogic.gdx.files.FileHandle
|
import com.badlogic.gdx.files.FileHandle
|
||||||
import com.badlogic.gdx.utils.Array
|
import com.badlogic.gdx.utils.Array
|
||||||
|
import com.unciv.Constants
|
||||||
import com.unciv.JsonParser
|
import com.unciv.JsonParser
|
||||||
import com.unciv.models.metadata.BaseRuleset
|
import com.unciv.models.metadata.BaseRuleset
|
||||||
import com.unciv.models.ruleset.*
|
import com.unciv.models.ruleset.*
|
||||||
@ -241,7 +242,7 @@ object TranslationFileWriter {
|
|||||||
val tileFilterMap = ruleset.terrains.keys.toMutableSet().apply { addAll(sequenceOf(
|
val tileFilterMap = ruleset.terrains.keys.toMutableSet().apply { addAll(sequenceOf(
|
||||||
"Friendly Land",
|
"Friendly Land",
|
||||||
"Foreign Land",
|
"Foreign Land",
|
||||||
"Fresh water",
|
Constants.freshWater,
|
||||||
"non-fresh water",
|
"non-fresh water",
|
||||||
"Open Terrain",
|
"Open Terrain",
|
||||||
"Rough Terrain",
|
"Rough Terrain",
|
||||||
|
Reference in New Issue
Block a user