Minimum city distance across continents (#5404)

This commit is contained in:
SomeTroglodyte 2021-10-06 21:51:52 +02:00 committed by GitHub
parent 22ebe2b9af
commit d25adacec7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 66 additions and 51 deletions

View File

@ -2,10 +2,7 @@ package com.unciv
object Constants { object Constants {
const val worker = "Worker" const val worker = "Worker"
const val canBuildImprovements = "Can build [] improvements on tiles"
const val workBoatsUnique = "May create improvements on water resources"
const val settler = "Settler" const val settler = "Settler"
const val settlerUnique = "Founds a new city"
const val eraSpecificUnit = "Era Starting Unit" const val eraSpecificUnit = "Era Starting Unit"
const val spreadReligionAbilityCount = "Spread Religion" const val spreadReligionAbilityCount = "Spread Religion"
const val removeHeresyAbilityCount = "Remove Foreign religions from your own cities" const val removeHeresyAbilityCount = "Remove Foreign religions from your own cities"

View File

@ -262,7 +262,7 @@ object GameStarter {
val startingLocations = getStartingLocations(allCivs, tileMap, landTilesInBigEnoughGroup, startScores) val startingLocations = getStartingLocations(allCivs, tileMap, landTilesInBigEnoughGroup, startScores)
val settlerLikeUnits = ruleSet.units.filter { val settlerLikeUnits = ruleSet.units.filter {
it.value.uniqueObjects.any { unique -> unique.placeholderText == Constants.settlerUnique } it.value.hasUnique(UniqueType.FoundCity)
} }
// no starting units for Barbarians and Spectators // no starting units for Barbarians and Spectators
@ -315,9 +315,8 @@ object GameStarter {
} }
if (unit == "Worker" && "Worker" !in ruleSet.units) { if (unit == "Worker" && "Worker" !in ruleSet.units) {
val buildableWorkerLikeUnits = ruleSet.units.filter { val buildableWorkerLikeUnits = ruleSet.units.filter {
it.value.uniqueObjects.any { unique -> unique.placeholderText == Constants.canBuildImprovements } it.value.hasUnique(UniqueType.BuildImprovements) &&
&& it.value.isBuildable(civ) it.value.isBuildable(civ) && it.value.isCivilian()
&& it.value.isCivilian()
} }
if (buildableWorkerLikeUnits.isEmpty()) return null // No workers in this mod if (buildableWorkerLikeUnits.isEmpty()) return null // No workers in this mod
return civ.getEquivalentUnit(buildableWorkerLikeUnits.keys.random()).name return civ.getEquivalentUnit(buildableWorkerLikeUnits.keys.random()).name

View File

@ -1,6 +1,5 @@
package com.unciv.logic.automation package com.unciv.logic.automation
import com.unciv.Constants
import com.unciv.UncivGame import com.unciv.UncivGame
import com.unciv.logic.city.CityConstructions import com.unciv.logic.city.CityConstructions
import com.unciv.logic.city.PerpetualConstruction import com.unciv.logic.city.PerpetualConstruction
@ -10,8 +9,8 @@ import com.unciv.logic.civilization.PlayerType
import com.unciv.logic.map.BFS import com.unciv.logic.map.BFS
import com.unciv.models.ruleset.Building import com.unciv.models.ruleset.Building
import com.unciv.models.ruleset.VictoryType import com.unciv.models.ruleset.VictoryType
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.stats.Stat import com.unciv.models.stats.Stat
import com.unciv.models.translations.equalsPlaceholderText
import kotlin.math.min import kotlin.math.min
import kotlin.math.sqrt import kotlin.math.sqrt
@ -105,7 +104,7 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
if (!cityIsOverAverageProduction) modifier /= 5 // higher production cities will deal with this if (!cityIsOverAverageProduction) modifier /= 5 // higher production cities will deal with this
val civilianUnit = cityInfo.getCenterTile().civilianUnit val civilianUnit = cityInfo.getCenterTile().civilianUnit
if (civilianUnit != null && civilianUnit.hasUnique(Constants.settlerUnique) if (civilianUnit != null && civilianUnit.hasUnique(UniqueType.FoundCity)
&& cityInfo.getCenterTile().getTilesInDistance(5).none { it.militaryUnit?.civInfo == civInfo }) && cityInfo.getCenterTile().getTilesInDistance(5).none { it.militaryUnit?.civInfo == civInfo })
modifier = 5f // there's a settler just sitting here, doing nothing - BAD modifier = 5f // there's a settler just sitting here, doing nothing - BAD
@ -115,10 +114,10 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
private fun addWorkBoatChoice() { private fun addWorkBoatChoice() {
val buildableWorkboatUnits = cityInfo.cityConstructions.getConstructableUnits() val buildableWorkboatUnits = cityInfo.cityConstructions.getConstructableUnits()
.filter { it.uniques.contains(Constants.workBoatsUnique) .filter { it.hasUnique(UniqueType.CreateWaterImprovements)
&& Automation.allowSpendingResource(civInfo, it) } && Automation.allowSpendingResource(civInfo, it) }
val canBuildWorkboat = buildableWorkboatUnits.any() val canBuildWorkboat = buildableWorkboatUnits.any()
&& !cityInfo.getTiles().any { it.civilianUnit?.hasUnique(Constants.workBoatsUnique) == true } && !cityInfo.getTiles().any { it.civilianUnit?.hasUnique(UniqueType.CreateWaterImprovements) == true }
if (!canBuildWorkboat) return if (!canBuildWorkboat) return
val tilesThatNeedWorkboat = cityInfo.getTiles() val tilesThatNeedWorkboat = cityInfo.getTiles()
.filter { it.isWater && it.hasViewableResource(civInfo) && it.improvement == null }.toList() .filter { it.isWater && it.hasViewableResource(civInfo) && it.improvement == null }.toList()
@ -139,9 +138,9 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
private fun addWorkerChoice() { private fun addWorkerChoice() {
val workerEquivalents = civInfo.gameInfo.ruleSet.units.values val workerEquivalents = civInfo.gameInfo.ruleSet.units.values
.filter { it.uniques.any { .filter {
unique -> unique.equalsPlaceholderText(Constants.canBuildImprovements) it.hasUnique(UniqueType.BuildImprovements)
} && it.isBuildable(cityConstructions) && it.isBuildable(cityConstructions)
&& Automation.allowSpendingResource(civInfo, it) } && Automation.allowSpendingResource(civInfo, it) }
if (workerEquivalents.isEmpty()) return // for mods with no worker units if (workerEquivalents.isEmpty()) return // for mods with no worker units
if (civInfo.getIdleUnits().any { it.isAutomated() && it.hasUniqueToBuildImprovements }) if (civInfo.getIdleUnits().any { it.isAutomated() && it.hasUniqueToBuildImprovements })

View File

@ -689,12 +689,12 @@ object NextTurnAutomation {
if (civInfo.cities.none() || civInfo.getHappiness() <= civInfo.cities.size + 5) return if (civInfo.cities.none() || civInfo.getHappiness() <= civInfo.cities.size + 5) return
val settlerUnits = civInfo.gameInfo.ruleSet.units.values val settlerUnits = civInfo.gameInfo.ruleSet.units.values
.filter { it.uniques.contains(Constants.settlerUnique) && it.isBuildable(civInfo) } .filter { it.hasUnique(UniqueType.FoundCity) && it.isBuildable(civInfo) }
if (settlerUnits.isEmpty()) return if (settlerUnits.isEmpty()) return
if (civInfo.getCivUnits().none { it.hasUnique(Constants.settlerUnique) } if (civInfo.getCivUnits().none { it.hasUnique(UniqueType.FoundCity) }
&& civInfo.cities.none { && civInfo.cities.none {
val currentConstruction = it.cityConstructions.getCurrentConstruction() val currentConstruction = it.cityConstructions.getCurrentConstruction()
currentConstruction is BaseUnit && currentConstruction.uniques.contains(Constants.settlerUnique) currentConstruction is BaseUnit && currentConstruction.hasUnique(UniqueType.FoundCity)
}) { }) {
val bestCity = civInfo.cities.maxByOrNull { it.cityStats.currentCityStats.production }!! val bestCity = civInfo.cities.maxByOrNull { it.cityStats.currentCityStats.production }!!

View File

@ -159,17 +159,23 @@ object SpecificUnitAutomation {
&& !unit.civInfo.isCityState() // ..unless you're a city state that was unable to settle its city on turn 1 && !unit.civInfo.isCityState() // ..unless you're a city state that was unable to settle its city on turn 1
&& unit.getDamageFromTerrain() < unit.health) return // Also make sure we won't die waiting && unit.getDamageFromTerrain() < unit.health) return // Also make sure we won't die waiting
val tilesNearCities = unit.civInfo.gameInfo.getCities().asSequence() val tilesNearCities = sequence {
.flatMap { for (city in unit.civInfo.gameInfo.getCities()) {
val distanceAwayFromCity = val center = city.getCenterTile()
if (unit.civInfo.knows(it.civInfo) if (unit.civInfo.knows(city.civInfo) &&
// If the CITY OWNER knows that the UNIT OWNER agreed not to settle near them // If the CITY OWNER knows that the UNIT OWNER agreed not to settle near them
&& it.civInfo.getDiplomacyManager(unit.civInfo).hasFlag(DiplomacyFlags.AgreedToNotSettleNearUs)) city.civInfo.getDiplomacyManager(unit.civInfo).hasFlag(DiplomacyFlags.AgreedToNotSettleNearUs)
6 ) {
else 3 yieldAll(center.getTilesInDistance(6))
it.getCenterTile().getTilesInDistance(distanceAwayFromCity) continue
} }
.toSet() for (tile in center.getTilesAtDistance(3)) {
if (tile.getContinent() == center.getContinent())
yield(tile)
}
yieldAll(center.getTilesInDistance(2))
}
}.toSet()
// This is to improve performance - instead of ranking each tile in the area up to 19 times, do it once. // This is to improve performance - instead of ranking each tile in the area up to 19 times, do it once.
val nearbyTileRankings = unit.getTile().getTilesInDistance(7) val nearbyTileRankings = unit.getTile().getTilesInDistance(7)

View File

@ -101,7 +101,7 @@ object UnitAutomation {
if (unit.isCivilian()) { if (unit.isCivilian()) {
if (tryRunAwayIfNeccessary(unit)) return if (tryRunAwayIfNeccessary(unit)) return
if (unit.hasUnique(Constants.settlerUnique)) if (unit.hasUnique(UniqueType.FoundCity))
return SpecificUnitAutomation.automateSettlerActions(unit) return SpecificUnitAutomation.automateSettlerActions(unit)
if (unit.hasUniqueToBuildImprovements) if (unit.hasUniqueToBuildImprovements)
@ -119,7 +119,7 @@ object UnitAutomation {
) )
return SpecificUnitAutomation.enhanceReligion(unit) return SpecificUnitAutomation.enhanceReligion(unit)
if (unit.hasUnique(Constants.workBoatsUnique)) if (unit.hasUnique(UniqueType.CreateWaterImprovements))
return SpecificUnitAutomation.automateWorkBoats(unit) return SpecificUnitAutomation.automateWorkBoats(unit)
if (unit.hasUnique("Bonus for units in 2 tile radius 15%")) if (unit.hasUnique("Bonus for units in 2 tile radius 15%"))
@ -311,7 +311,7 @@ object UnitAutomation {
.firstOrNull { .firstOrNull {
val tile = it.currentTile val tile = it.currentTile
it.isCivilian() && it.isCivilian() &&
(it.hasUnique(Constants.settlerUnique) || unit.isGreatPerson()) (it.hasUnique(UniqueType.FoundCity) || unit.isGreatPerson())
&& tile.militaryUnit == null && unit.movement.canMoveTo(tile) && unit.movement.canReach(tile) && tile.militaryUnit == null && unit.movement.canMoveTo(tile) && unit.movement.canReach(tile)
} ?: return false } ?: return false
unit.movement.headTowards(settlerOrGreatPersonToAccompany.currentTile) unit.movement.headTowards(settlerOrGreatPersonToAccompany.currentTile)

View File

@ -1,6 +1,5 @@
package com.unciv.logic.civilization package com.unciv.logic.civilization
import com.unciv.Constants
import com.unciv.logic.automation.NextTurnAutomation import com.unciv.logic.automation.NextTurnAutomation
import com.unciv.logic.civilization.diplomacy.* import com.unciv.logic.civilization.diplomacy.*
import com.unciv.models.metadata.GameSpeed import com.unciv.models.metadata.GameSpeed
@ -23,7 +22,7 @@ class CityStateFunctions(val civInfo: CivilizationInfo) {
/** Attempts to initialize the city state, returning true if successful. */ /** Attempts to initialize the city state, returning true if successful. */
fun initCityState(ruleset: Ruleset, startingEra: String, unusedMajorCivs: Collection<String>): Boolean { fun initCityState(ruleset: Ruleset, startingEra: String, unusedMajorCivs: Collection<String>): Boolean {
val cityStateType = ruleset.nations[civInfo.civName]?.cityStateType val cityStateType = ruleset.nations[civInfo.civName]?.cityStateType
if (cityStateType == null) return false ?: return false
val startingTechs = ruleset.technologies.values.filter { it.uniques.contains("Starting tech") } val startingTechs = ruleset.technologies.values.filter { it.uniques.contains("Starting tech") }
for (tech in startingTechs) for (tech in startingTechs)
@ -406,9 +405,8 @@ class CityStateFunctions(val civInfo: CivilizationInfo) {
if (!civInfo.isCityState()) throw Exception("You can only demand workers from City-States!") if (!civInfo.isCityState()) throw Exception("You can only demand workers from City-States!")
val buildableWorkerLikeUnits = civInfo.gameInfo.ruleSet.units.filter { val buildableWorkerLikeUnits = civInfo.gameInfo.ruleSet.units.filter {
it.value.uniqueObjects.any { unique -> unique.placeholderText == Constants.canBuildImprovements } it.value.hasUnique(UniqueType.BuildImprovements) &&
&& it.value.isCivilian() it.value.isCivilian() && it.value.isBuildable(civInfo)
&& it.value.isBuildable(civInfo)
} }
if (buildableWorkerLikeUnits.isEmpty()) return // Bad luck? if (buildableWorkerLikeUnits.isEmpty()) return // Bad luck?
demandingCiv.placeUnitNearTile(civInfo.getCapital().location, buildableWorkerLikeUnits.keys.random()) demandingCiv.placeUnitNearTile(civInfo.getCapital().location, buildableWorkerLikeUnits.keys.random())

View File

@ -72,9 +72,9 @@ class CivInfoTransientUpdater(val civInfo: CivilizationInfo) {
// And so, sequences to the rescue! // And so, sequences to the rescue!
val ownedTiles = civInfo.cities.asSequence().flatMap { it.getTiles() } val ownedTiles = civInfo.cities.asSequence().flatMap { it.getTiles() }
newViewableTiles.addAll(ownedTiles) newViewableTiles.addAll(ownedTiles)
val neighboringUnownedTiles = ownedTiles.flatMap { it.neighbors.filter { it.getOwner() != civInfo } } val neighboringUnownedTiles = ownedTiles.flatMap { tile -> tile.neighbors.filter { it.getOwner() != civInfo } }
newViewableTiles.addAll(neighboringUnownedTiles) newViewableTiles.addAll(neighboringUnownedTiles)
newViewableTiles.addAll(civInfo.getCivUnits().flatMap { it.viewableTiles.asSequence().filter { it.getOwner() != civInfo } }) newViewableTiles.addAll(civInfo.getCivUnits().flatMap { unit -> unit.viewableTiles.asSequence().filter { it.getOwner() != civInfo } })
if (!civInfo.isCityState()) { if (!civInfo.isCityState()) {
for (otherCiv in civInfo.getKnownCivs()) { for (otherCiv in civInfo.getKnownCivs()) {
@ -110,9 +110,7 @@ class CivInfoTransientUpdater(val civInfo: CivilizationInfo) {
} }
if (civInfo.hasUnique("100 Gold for discovering a Natural Wonder (bonus enhanced to 500 Gold if first to discover it)")) { if (civInfo.hasUnique("100 Gold for discovering a Natural Wonder (bonus enhanced to 500 Gold if first to discover it)")) {
if (!discoveredNaturalWonders.contains(tile.naturalWonder!!)) goldGained += if (discoveredNaturalWonders.contains(tile.naturalWonder!!)) 100 else 500
goldGained += 500
else goldGained += 100
} }
if (goldGained > 0) { if (goldGained > 0) {

View File

@ -277,7 +277,7 @@ class MapUnit {
cannotEnterOceanTiles = hasUnique(UniqueType.CannotEnterOcean) cannotEnterOceanTiles = hasUnique(UniqueType.CannotEnterOcean)
cannotEnterOceanTilesUntilAstronomy = hasUnique(UniqueType.CannotEnterOceanUntilAstronomy) cannotEnterOceanTilesUntilAstronomy = hasUnique(UniqueType.CannotEnterOceanUntilAstronomy)
hasUniqueToBuildImprovements = hasUnique(Constants.canBuildImprovements) hasUniqueToBuildImprovements = hasUnique(UniqueType.BuildImprovements)
canEnterForeignTerrain = canEnterForeignTerrain =
hasUnique("May enter foreign tiles without open borders, but loses [] religious strength each turn it ends there") hasUnique("May enter foreign tiles without open borders, but loses [] religious strength each turn it ends there")
|| hasUnique("May enter foreign tiles without open borders") || hasUnique("May enter foreign tiles without open borders")
@ -1051,7 +1051,7 @@ class MapUnit {
} }
fun canBuildImprovement(improvement: TileImprovement, tile: TileInfo = currentTile): Boolean { fun canBuildImprovement(improvement: TileImprovement, tile: TileInfo = currentTile): Boolean {
val matchingUniques = getMatchingUniques(Constants.canBuildImprovements) val matchingUniques = getMatchingUniques(UniqueType.BuildImprovements)
return matchingUniques.any { improvement.matchesFilter(it.params[0]) || tile.matchesTerrainFilter(it.params[0]) } return matchingUniques.any { improvement.matchesFilter(it.params[0]) || tile.matchesTerrainFilter(it.params[0]) }
} }

View File

@ -8,6 +8,7 @@ import com.unciv.models.stats.Stat
// parameterName values should be compliant with autogenerated values in TranslationFileWriter.generateStringsFromJSONs // parameterName values should be compliant with autogenerated values in TranslationFileWriter.generateStringsFromJSONs
// Eventually we'll merge the translation generation to take this as the source of that // Eventually we'll merge the translation generation to take this as the source of that
@Suppress("unused") // Some are used only via enumerating the enum matching on parameterName
enum class UniqueParameterType(val parameterName:String) { enum class UniqueParameterType(val parameterName:String) {
Number("amount") { Number("amount") {
override fun getErrorSeverity(parameterText: String, ruleset: Ruleset): override fun getErrorSeverity(parameterText: String, ruleset: Ruleset):
@ -145,6 +146,16 @@ enum class UniqueParameterType(val parameterName:String) {
else -> UniqueType.UniqueComplianceErrorSeverity.RulesetSpecific else -> UniqueType.UniqueComplianceErrorSeverity.RulesetSpecific
} }
}, },
/** should mirror TileImprovement.matchesFilter exactly */
ImprovementFilter("improvementFilter") {
private val knownValues = setOf("All", "All Road", "Great Improvement", "Great")
override fun getErrorSeverity(parameterText: String, ruleset: Ruleset):
UniqueType.UniqueComplianceErrorSeverity? {
if (parameterText in knownValues) return null
if (ruleset.tileImprovements.containsKey(parameterText)) return null
return UniqueType.UniqueComplianceErrorSeverity.RulesetSpecific
}
},
Resource("resource") { Resource("resource") {
override fun getErrorSeverity(parameterText: String, ruleset: Ruleset): override fun getErrorSeverity(parameterText: String, ruleset: Ruleset):
UniqueType.UniqueComplianceErrorSeverity? = when (parameterText) { UniqueType.UniqueComplianceErrorSeverity? = when (parameterText) {

View File

@ -1,6 +1,7 @@
package com.unciv.models.ruleset.unique package com.unciv.models.ruleset.unique
import com.badlogic.gdx.math.Vector2 import com.badlogic.gdx.math.Vector2
import com.unciv.Constants
import com.unciv.logic.city.CityInfo import com.unciv.logic.city.CityInfo
import com.unciv.logic.civilization.* import com.unciv.logic.civilization.*
import com.unciv.logic.map.MapUnit import com.unciv.logic.map.MapUnit
@ -33,7 +34,7 @@ object UniqueTriggerActivation {
OneTimeFreeUnit -> { OneTimeFreeUnit -> {
val unitName = unique.params[0] val unitName = unique.params[0]
val unit = civInfo.gameInfo.ruleSet.units[unitName] val unit = civInfo.gameInfo.ruleSet.units[unitName]
if (chosenCity == null || unit == null || (unit.uniques.contains("Founds a new city") && civInfo.isOneCityChallenger())) if (chosenCity == null || unit == null || (unit.hasUnique(UniqueType.FoundCity) && civInfo.isOneCityChallenger()))
return false return false
val placedUnit = civInfo.addUnit(unitName, chosenCity) val placedUnit = civInfo.addUnit(unitName, chosenCity)
@ -49,7 +50,7 @@ object UniqueTriggerActivation {
OneTimeAmountFreeUnits -> { OneTimeAmountFreeUnits -> {
val unitName = unique.params[1] val unitName = unique.params[1]
val unit = civInfo.gameInfo.ruleSet.units[unitName] val unit = civInfo.gameInfo.ruleSet.units[unitName]
if (chosenCity == null || unit == null || (unit.uniques.contains("Founds a new city") && civInfo.isOneCityChallenger())) if (chosenCity == null || unit == null || (unit.hasUnique(UniqueType.FoundCity) && civInfo.isOneCityChallenger()))
return false return false
val tilesUnitsWerePlacedOn: MutableList<Vector2> = mutableListOf() val tilesUnitsWerePlacedOn: MutableList<Vector2> = mutableListOf()

View File

@ -124,6 +124,9 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget) {
///////////////////////////////////////// UNIT UNIQUES ///////////////////////////////////////// ///////////////////////////////////////// UNIT UNIQUES /////////////////////////////////////////
FoundCity("Founds a new city", UniqueTarget.Unit),
BuildImprovements("Can build [improvementFilter/terrainFilter] improvements on tiles", UniqueTarget.Unit),
CreateWaterImprovements("May create improvements on water resources", UniqueTarget.Unit),
Strength("[amount]% Strength", UniqueTarget.Unit, UniqueTarget.Global), Strength("[amount]% Strength", UniqueTarget.Unit, UniqueTarget.Global),
StrengthNearCapital("[amount]% Strength decreasing with distance from the capital", UniqueTarget.Unit), StrengthNearCapital("[amount]% Strength decreasing with distance from the capital", UniqueTarget.Unit),

View File

@ -403,7 +403,7 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
}) })
} }
if (uniques.contains(Constants.settlerUnique) && if (hasUnique(UniqueType.FoundCity) &&
(civInfo.isCityState() || civInfo.isOneCityChallenger()) (civInfo.isCityState() || civInfo.isOneCityChallenger())
) )
rejectionReasons.add(RejectionReason.NoSettlerForOneCityPlayers) rejectionReasons.add(RejectionReason.NoSettlerForOneCityPlayers)

View File

@ -128,7 +128,7 @@ object UnitActions {
fun getWaterImprovementAction(unit: MapUnit): UnitAction? { fun getWaterImprovementAction(unit: MapUnit): UnitAction? {
val tile = unit.currentTile val tile = unit.currentTile
if (!tile.isWater || !unit.hasUnique(Constants.workBoatsUnique) || tile.resource == null) return null if (!tile.isWater || !unit.hasUnique(UniqueType.CreateWaterImprovements) || tile.resource == null) return null
val improvementName = tile.getTileResource().improvement ?: return null val improvementName = tile.getTileResource().improvement ?: return null
val improvement = tile.ruleset.tileImprovements[improvementName] ?: return null val improvement = tile.ruleset.tileImprovements[improvementName] ?: return null
@ -161,9 +161,11 @@ object UnitActions {
* (no movement left, too close to another city). * (no movement left, too close to another city).
*/ */
fun getFoundCityAction(unit: MapUnit, tile: TileInfo): UnitAction? { fun getFoundCityAction(unit: MapUnit, tile: TileInfo): UnitAction? {
if (!unit.hasUnique("Founds a new city") || tile.isWater || tile.isImpassible()) return null if (!unit.hasUnique(UniqueType.FoundCity) || tile.isWater || tile.isImpassible()) return null
if (unit.currentMovement <= 0 || tile.getTilesInDistance(3).any { it.isCityCenter() }) if (unit.currentMovement <= 0 ||
tile.getTilesInDistance(2).any { it.isCityCenter() } ||
tile.getTilesAtDistance(3).any { it.isCityCenter() && it.getContinent() == tile.getContinent() })
return UnitAction(UnitActionType.FoundCity, action = null) return UnitAction(UnitActionType.FoundCity, action = null)
val foundAction = { val foundAction = {

View File

@ -14,6 +14,7 @@ import com.unciv.models.metadata.GameSettings
import com.unciv.models.metadata.Player import com.unciv.models.metadata.Player
import com.unciv.models.ruleset.RulesetCache import com.unciv.models.ruleset.RulesetCache
import com.unciv.models.metadata.GameSetupInfo import com.unciv.models.metadata.GameSetupInfo
import com.unciv.models.ruleset.unique.UniqueType
import org.junit.After import org.junit.After
import org.junit.Assert import org.junit.Assert
import org.junit.Before import org.junit.Before
@ -68,7 +69,7 @@ class SerializationTests {
// Found a city otherwise too many classes have no instance and are not tested // Found a city otherwise too many classes have no instance and are not tested
val civ = game.getCurrentPlayerCivilization() val civ = game.getCurrentPlayerCivilization()
val unit = civ.getCivUnits().first { it.hasUnique(Constants.settlerUnique) } val unit = civ.getCivUnits().first { it.hasUnique(UniqueType.FoundCity) }
val tile = unit.getTile() val tile = unit.getTile()
unit.civInfo.addCity(tile.position) unit.civInfo.addCity(tile.position)
if (tile.ruleset.tileImprovements.containsKey("City center")) if (tile.ruleset.tileImprovements.containsKey("City center"))