More multiple terrain feature changes

This commit is contained in:
Yair Morgenstern 2021-03-11 23:09:05 +02:00
parent 01877fee7c
commit 02cd1a2ef3
3 changed files with 30 additions and 23 deletions

View File

@ -40,8 +40,10 @@ open class TileInfo {
// 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 { matchesUniqueFilter("River") || matchesUniqueFilter("Fresh water")
|| neighbors.any { it.matchesUniqueFilter("Fresh water") } }
val isAdjacentToFreshwater: Boolean by lazy {
matchesUniqueFilter("River") || matchesUniqueFilter("Fresh water")
|| neighbors.any { it.matchesUniqueFilter("Fresh water") }
}
var militaryUnit: MapUnit? = null
var civilianUnit: MapUnit? = null
@ -50,9 +52,11 @@ open class TileInfo {
var position: Vector2 = Vector2.Zero
lateinit var baseTerrain: String
val terrainFeatures: ArrayList<String> = ArrayList()
@Transient // So it won't be serialized from now on
var terrainFeature: String? = null
get() = terrainFeatures.firstOrNull() ?: field //if terrainFeatures contains no terrainFeature maybe one got deserialized to field
get() = terrainFeatures.firstOrNull()
?: field //if terrainFeatures contains no terrainFeature maybe one got deserialized to field
set(value) {
if (terrainFeatures.isNotEmpty()) {
if (value == null) terrainFeatures.removeAt(0)
@ -139,7 +143,7 @@ open class TileInfo {
fun getTileResource(): TileResource =
if (resource == null) throw Exception("No resource exists for this tile!")
else if(!ruleset.tileResources.containsKey(resource!!)) throw Exception("Resource $resource does not exist in this ruleset!")
else if (!ruleset.tileResources.containsKey(resource!!)) throw Exception("Resource $resource does not exist in this ruleset!")
else ruleset.tileResources[resource!!]!!
fun getNaturalWonder(): Terrain =
@ -340,10 +344,10 @@ open class TileInfo {
// Road improvements can change on tiles withh irremovable improvements - nothing else can, though.
improvement.name != RoadStatus.Railroad.name && improvement.name != RoadStatus.Railroad.name
&& improvement.name != "Remove Road" && improvement.name != "Remove Railroad"
&& getTileImprovement().let { it!=null && it.hasUnique("Irremovable") } -> false
&& getTileImprovement().let { it != null && it.hasUnique("Irremovable") } -> false
// 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.uniqueObjects.filter { it.placeholderText == "Must be next to []" }.any {
val filter = it.params[0]
@ -363,7 +367,7 @@ open class TileInfo {
}
}
fun matchesUniqueFilter(filter: String, civInfo: CivilizationInfo?=null): Boolean {
fun matchesUniqueFilter(filter: String, civInfo: CivilizationInfo? = null): Boolean {
return filter == baseTerrain
|| filter == Constants.hill && isHill()
|| filter == "River" && isAdjacentToRiver()
@ -501,7 +505,6 @@ open class TileInfo {
}
fun hasEnemyInvisibleUnit(viewingCiv: CivilizationInfo): Boolean {
val unitsInTile = getUnits()
if (unitsInTile.none()) return false
@ -521,7 +524,7 @@ open class TileInfo {
&& (terrainFeature == Constants.jungle || terrainFeature == Constants.forest)
&& isFriendlyTerritory(civInfo)
fun getRulesetIncompatability(ruleset: Ruleset):String{
fun getRulesetIncompatability(ruleset: Ruleset): String {
if (!ruleset.terrains.containsKey(baseTerrain)) return "Base terrain $baseTerrain does not exist in ruleset!"
if (terrainFeature != null && !ruleset.terrains.containsKey(terrainFeature)) return "Terrain feature $terrainFeature does not exist in ruleset!"
if (resource != null && !ruleset.tileResources.containsKey(resource)) return "Resource $resource does not exist in ruleset!"
@ -586,21 +589,24 @@ open class TileInfo {
turnsToImprovement = 0
}
fun normalizeToRuleset(ruleset: Ruleset){
fun normalizeToRuleset(ruleset: Ruleset) {
if (!ruleset.terrains.containsKey(naturalWonder)) naturalWonder = null
if (naturalWonder != null) {
val naturalWonder = ruleset.terrains[naturalWonder]!!
baseTerrain = naturalWonder.turnsInto!!
terrainFeature = null
terrainFeatures.clear()
resource = null
improvement = null
}
if (!ruleset.terrains.containsKey(terrainFeature)) terrainFeature = null
if (terrainFeature != null) {
for (terrainFeature in terrainFeatures.toList()) {
if (!ruleset.terrains.containsKey(terrainFeature)) {
terrainFeatures.remove(terrainFeature)
continue
}
val terrainFeatureObject = ruleset.terrains[terrainFeature]!!
if (terrainFeatureObject.occursOn.isNotEmpty() && !terrainFeatureObject.occursOn.contains(baseTerrain))
terrainFeature = null
terrainFeatures.remove(terrainFeature)
}
@ -611,16 +617,16 @@ open class TileInfo {
resource = null
}
if (improvement != null) normalizeTileImprovement(ruleset)
// If we're checking this at gameInfo.setTransients, we can't check the top terrain
if (improvement != null && ::baseTerrainObject.isInitialized) normalizeTileImprovement(ruleset)
if (isWater || isImpassible())
roadStatus = RoadStatus.None
}
private fun normalizeTileImprovement(ruleset: Ruleset) {
val topTerrain = getLastTerrain()
if (improvement!!.startsWith("StartingLocation")) {
if (!isLand || topTerrain.impassable) improvement = null
if (!isLand || getLastTerrain().impassable) improvement = null
return
}
val improvementObject = ruleset.tileImprovements[improvement]!!
@ -634,4 +640,4 @@ open class TileInfo {
}
//endregion
}
}

View File

@ -37,7 +37,8 @@ class UnitMovementAlgorithms(val unit:MapUnit) {
if (unit.ignoresTerrainCost) return 1f + extraCost
if (areConnectedByRiver) return 100f // Rivers take the entire turn to cross
if (unit.doubleMovementInForestAndJungle && (to.terrainFeature == Constants.forest || to.terrainFeature == Constants.jungle))
if (unit.doubleMovementInForestAndJungle &&
(to.terrainFeatures.contains(Constants.forest) || to.terrainFeatures.contains(Constants.jungle)))
return 1f + extraCost // usually forest and jungle take 2 movements, so here it is 1
if (civInfo.nation.ignoreHillMovementCost && to.isHill())
return 1f + extraCost // usually hills take 2 movements, so here it is 1
@ -335,7 +336,7 @@ class UnitMovementAlgorithms(val unit:MapUnit) {
if (tile.isImpassible()) {
// special exception - ice tiles are technically impassible, but some units can move through them anyway
// helicopters can pass through impassable tiles like mountains
if (!(tile.terrainFeature == Constants.ice && unit.canEnterIceTiles) && !unit.canPassThroughImpassableTiles)
if (!(tile.terrainFeatures.contains(Constants.ice) && unit.canEnterIceTiles) && !unit.canPassThroughImpassableTiles)
return false
}
if (tile.isLand

View File

@ -270,7 +270,7 @@ class MapGenerator(val ruleset: Ruleset) {
val rareFeatures = ruleset.terrains.values.filter {
it.type == TerrainType.TerrainFeature && it.uniques.contains("Rare feature")
}
for (tile in tileMap.values.asSequence().filter { it.terrainFeature == null }) {
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)) }
@ -287,7 +287,7 @@ class MapGenerator(val ruleset: Ruleset) {
tileMap.setTransients(ruleset)
val temperatureSeed = randomness.RNG.nextInt().toDouble()
for (tile in tileMap.values) {
if (tile.baseTerrain !in Constants.sea || tile.terrainFeature != null)
if (tile.baseTerrain !in Constants.sea || tile.terrainFeatures.any())
continue
val randomTemperature = randomness.getPerlinNoise(tile, temperatureSeed, scale = tileMap.mapParameters.tilesPerBiomeArea.toDouble(), nOctaves = 1)
@ -295,7 +295,7 @@ class MapGenerator(val ruleset: Ruleset) {
var temperature = ((latitudeTemperature + randomTemperature) / 2.0)
temperature = abs(temperature).pow(1.0 - tileMap.mapParameters.temperatureExtremeness) * temperature.sign
if (temperature < -0.8)
tile.terrainFeature = Constants.ice
tile.terrainFeatures.add(Constants.ice)
}
}