Fix ai settling on water/Impassible tiles and fix bug with how ai uses puppet city

The bug for puppet city is that it couldn't settle a city if it was a military unit.
This commit is contained in:
Emandac 2025-08-26 01:52:25 +02:00
parent e803030528
commit 965b892912
5 changed files with 13 additions and 10 deletions

View File

@ -66,17 +66,21 @@ object CityLocationTileRanker {
private fun canSettleTile(tile: Tile, unit: MapUnit, nearbyCities: Sequence<City>): Boolean { private fun canSettleTile(tile: Tile, unit: MapUnit, nearbyCities: Sequence<City>): Boolean {
val civ = unit.civ val civ = unit.civ
val unitCanFoundUnique = unit.getMatchingUniques(UniqueType.ConditionalInTiles).firstOrNull()
println(unitCanFoundUnique) val uniques = unit.getMatchingUniques(UniqueType.FoundCity) + unit.getMatchingUniques(UniqueType.FoundPuppetCity)
val unique = uniques.firstOrNull()!!
val uniqueModifier = unique.getModifiers(UniqueType.ConditionalInTiles).firstOrNull()
val modConstants = civ.gameInfo.ruleset.modOptions.constants val modConstants = civ.gameInfo.ruleset.modOptions.constants
if (unitCanFoundUnique == null && (!tile.isLand || tile.isImpassible())) return false if (!unique.hasModifier(UniqueType.ConditionalInTiles) && (!tile.isLand || tile.isImpassible())) return false
if (tile.getOwner() != null && tile.getOwner() != civ) return false if (tile.getOwner() != null && tile.getOwner() != civ) return false
for (city in nearbyCities) { for (city in nearbyCities) {
var addedDistanceBeweenContinents: Int var addedDistanceBeweenContinents: Int
var canSettleInTileWithUnique = false var canSettleInTileWithUnique = false
if (unitCanFoundUnique != null) { if (uniqueModifier != null) {
canSettleInTileWithUnique = (tile.isWater || tile.isImpassible()) && canSettleInTileWithUnique = (tile.isWater || tile.isImpassible()) &&
unitCanFoundUnique.getModifiers(UniqueType.ConditionalInTiles).none{ uniqueModifier.getModifiers(UniqueType.ConditionalInTiles).none{
tile.matchesFilter(it.params[0]) tile.matchesFilter(it.params[0])
} }
} }
@ -99,7 +103,7 @@ object CityLocationTileRanker {
if (distance <= modConstants.minimalCityDistance) return false if (distance <= modConstants.minimalCityDistance) return false
} else { } else {
if (distance <= modConstants.minimalCityDistanceOnDifferentContinents+ if (distance <= modConstants.minimalCityDistanceOnDifferentContinents+
if (unitCanFoundUnique != null) addedDistanceBeweenContinents else 0) return false if (uniqueModifier != null) addedDistanceBeweenContinents else 0) return false
} }
} }
return true return true

View File

@ -32,7 +32,6 @@ object CivilianUnitAutomation {
.any { canUse(unit, it) } .any { canUse(unit, it) }
val hasSettlerUnique = hasSettlerAction(UniqueType.FoundCity) || hasSettlerAction(UniqueType.FoundPuppetCity) val hasSettlerUnique = hasSettlerAction(UniqueType.FoundCity) || hasSettlerAction(UniqueType.FoundPuppetCity)
if (hasSettlerUnique) if (hasSettlerUnique)
return SpecificUnitAutomation.automateSettlerActions(unit, dangerousTiles) return SpecificUnitAutomation.automateSettlerActions(unit, dangerousTiles)

View File

@ -67,7 +67,8 @@ object UnitAutomation {
if (unit.civ.isHuman() && tryUpgradeUnit(unit)) return if (unit.civ.isHuman() && tryUpgradeUnit(unit)) return
//This allows for military units with certain civilian abilities to behave as civilians in peace and soldiers in war //This allows for military units with certain civilian abilities to behave as civilians in peace and soldiers in war
if ((unit.hasUnique(UniqueType.BuildImprovements) || unit.hasUnique(UniqueType.FoundCity) || if ((unit.hasUnique(UniqueType.BuildImprovements) ||
unit.hasUnique(UniqueType.FoundCity) || unit.hasUnique(UniqueType.FoundPuppetCity) ||
unit.hasUnique(UniqueType.ReligiousUnit) || unit.hasUnique(UniqueType.CreateWaterImprovements)) unit.hasUnique(UniqueType.ReligiousUnit) || unit.hasUnique(UniqueType.CreateWaterImprovements))
&& !unit.civ.isAtWar()){ && !unit.civ.isAtWar()){
CivilianUnitAutomation.automateCivilianUnit(unit, getDangerousTiles(unit)) CivilianUnitAutomation.automateCivilianUnit(unit, getDangerousTiles(unit))

View File

@ -633,6 +633,7 @@ class Tile : IsPartOfGameInfoSerialization, Json.Serializable {
return min(distance, wrappedDistance).toInt() return min(distance, wrappedDistance).toInt()
} }
@Readonly
fun canBeSettled(unitCanFoundUnique: Unique?=null): Boolean { fun canBeSettled(unitCanFoundUnique: Unique?=null): Boolean {
val modConstants = tileMap.gameInfo.ruleset.modOptions.constants val modConstants = tileMap.gameInfo.ruleset.modOptions.constants
var addedDistanceBeweenContinents: Int var addedDistanceBeweenContinents: Int
@ -646,7 +647,6 @@ class Tile : IsPartOfGameInfoSerialization, Json.Serializable {
Putting the ! to make sure the player/Ai doesn't place cities too near each other. 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. Because when .none return False when one element has a match.
*/ */
println(canSettleInTileWithUnique)
addedDistanceBeweenContinents = if (!canSettleInTileWithUnique) 1 else 0 addedDistanceBeweenContinents = if (!canSettleInTileWithUnique) 1 else 0

View File

@ -47,7 +47,6 @@ object UnitActionsFromUniques {
UniqueType.FoundPuppetCity).firstOrNull() ?: return null UniqueType.FoundPuppetCity).firstOrNull() ?: return null
val uniqueModifier = unique.getModifiers(UniqueType.ConditionalInTiles).firstOrNull() val uniqueModifier = unique.getModifiers(UniqueType.ConditionalInTiles).firstOrNull()
println(uniqueModifier)
// do this check like that settler unique that don't have ConditionalInTiles does not show the grayed out button on water/moutain // 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 if (!unique.hasModifier(UniqueType.ConditionalInTiles) && (tile.isWater || tile.isImpassible())) return null