diff --git a/core/src/com/unciv/logic/automation/unit/CityLocationTileRanker.kt b/core/src/com/unciv/logic/automation/unit/CityLocationTileRanker.kt index 48936a6fce..2618faf28b 100644 --- a/core/src/com/unciv/logic/automation/unit/CityLocationTileRanker.kt +++ b/core/src/com/unciv/logic/automation/unit/CityLocationTileRanker.kt @@ -37,7 +37,7 @@ object CityLocationTileRanker { val possibleCityLocations = unit.getTile().getTilesInDistance(range) // Filter out tiles that we can't actually found on .filter { tile -> uniques.any { it.conditionalsApply(GameContext(unit = unit, tile = tile)) } } - .filter { canSettleTile(it, unit.civ, nearbyCities) && (unit.getTile() == it || unit.movement.canMoveTo(it)) } + .filter { canSettleTile(it, unit, nearbyCities) && (unit.getTile() == it || unit.movement.canMoveTo(it)) } val uniqueCache = LocalUniqueCache() val bestTilesToFoundCity = BestTilesToFoundCity() val baseTileMap = HashMap() @@ -63,11 +63,28 @@ object CityLocationTileRanker { return bestTilesToFoundCity } - private fun canSettleTile(tile: Tile, civ: Civilization, nearbyCities: Sequence): Boolean { + private fun canSettleTile(tile: Tile, unit: MapUnit, nearbyCities: Sequence): Boolean { + val civ = unit.civ + val unitCanFoundUnique = unit.getMatchingUniques(UniqueType.ConditionalInTiles).firstOrNull() val modConstants = civ.gameInfo.ruleset.modOptions.constants - if (!tile.isLand || tile.isImpassible()) return false + if ( (!tile.isLand || tile.isImpassible())) return false if (tile.getOwner() != null && tile.getOwner() != civ) return false for (city in nearbyCities) { + var addedDistanceBeweenContinents: Int + var canSettleInTileWithUnique = false + if (unitCanFoundUnique != null) { + canSettleInTileWithUnique = (tile.isWater || tile.isImpassible()) && + unitCanFoundUnique.getModifiers(UniqueType.ConditionalInTiles).none{ + tile.matchesFilter(it.params[0]) + } + } + /* + Putting the ! to make sure the player/Ai doesn't place cities too near each other. + Because when .none return False when one element has a match. + */ + + addedDistanceBeweenContinents = if (!canSettleInTileWithUnique) 1 else 0 + val distance = city.getCenterTile().aerialDistanceTo(tile) // todo: AgreedToNotSettleNearUs is hardcoded for now but it may be better to softcode it below in getDistanceToCityModifier if (distance <= 6 && civ.knows(city.civ) @@ -79,7 +96,8 @@ object CityLocationTileRanker { if (tile.getContinent() == city.getCenterTile().getContinent()) { if (distance <= modConstants.minimalCityDistance) return false } else { - if (distance <= modConstants.minimalCityDistanceOnDifferentContinents) return false + if (distance <= modConstants.minimalCityDistanceOnDifferentContinents+ + if (unitCanFoundUnique != null) addedDistanceBeweenContinents else 0) return false } } return true diff --git a/core/src/com/unciv/logic/map/tile/Tile.kt b/core/src/com/unciv/logic/map/tile/Tile.kt index 8b43ae5525..e4190440fe 100644 --- a/core/src/com/unciv/logic/map/tile/Tile.kt +++ b/core/src/com/unciv/logic/map/tile/Tile.kt @@ -646,7 +646,7 @@ class Tile : IsPartOfGameInfoSerialization, Json.Serializable { /* Putting the ! to make sure the player/Ai doesn't place cities too near each other. Because when .none return False when one element has a match. - */ + */ addedDistanceBeweenContinents = if (!canSettleInTileWithUnique) 1 else 0 diff --git a/core/src/com/unciv/ui/screens/worldscreen/unit/actions/UnitActionsFromUniques.kt b/core/src/com/unciv/ui/screens/worldscreen/unit/actions/UnitActionsFromUniques.kt index 0132990aaa..96227fc70e 100644 --- a/core/src/com/unciv/ui/screens/worldscreen/unit/actions/UnitActionsFromUniques.kt +++ b/core/src/com/unciv/ui/screens/worldscreen/unit/actions/UnitActionsFromUniques.kt @@ -45,12 +45,16 @@ object UnitActionsFromUniques { UniqueType.FoundCity).firstOrNull() ?: UnitActionModifiers.getUsableUnitActionUniques(unit, UniqueType.FoundPuppetCity).firstOrNull() ?: return null - - + + val uniqueModifier = unit.getMatchingUniques(UniqueType.ConditionalInTiles).firstOrNull() + + // do this check like that settler unique that don't have ConditionalInTiles does not show the grayed out button on water/moutain + if (!unique.hasModifier(UniqueType.ConditionalInTiles) && (tile.isWater || tile.isImpassible())) return null + // Spain should still be able to build Conquistadors in a one city challenge - but can't settle them if (unit.civ.isOneCityChallenger() && unit.civ.hasEverOwnedOriginalCapital) return null - if (!unit.hasMovement() || !tile.canBeSettled()) + if (!unit.hasMovement() || !tile.canBeSettled(uniqueModifier)) return UnitAction(UnitActionType.FoundCity, 80f, action = null) val hasActionModifiers = unique.modifiers.any { it.type?.targetTypes?.contains(