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 {
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
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
for (city in nearbyCities) {
var addedDistanceBeweenContinents: Int
var canSettleInTileWithUnique = false
if (unitCanFoundUnique != null) {
if (uniqueModifier != null) {
canSettleInTileWithUnique = (tile.isWater || tile.isImpassible()) &&
unitCanFoundUnique.getModifiers(UniqueType.ConditionalInTiles).none{
uniqueModifier.getModifiers(UniqueType.ConditionalInTiles).none{
tile.matchesFilter(it.params[0])
}
}
@ -99,7 +103,7 @@ object CityLocationTileRanker {
if (distance <= modConstants.minimalCityDistance) return false
} else {
if (distance <= modConstants.minimalCityDistanceOnDifferentContinents+
if (unitCanFoundUnique != null) addedDistanceBeweenContinents else 0) return false
if (uniqueModifier != null) addedDistanceBeweenContinents else 0) return false
}
}
return true

View File

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

View File

@ -67,7 +67,8 @@ object UnitAutomation {
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
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.civ.isAtWar()){
CivilianUnitAutomation.automateCivilianUnit(unit, getDangerousTiles(unit))

View File

@ -633,6 +633,7 @@ class Tile : IsPartOfGameInfoSerialization, Json.Serializable {
return min(distance, wrappedDistance).toInt()
}
@Readonly
fun canBeSettled(unitCanFoundUnique: Unique?=null): Boolean {
val modConstants = tileMap.gameInfo.ruleset.modOptions.constants
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.
Because when .none return False when one element has a match.
*/
println(canSettleInTileWithUnique)
addedDistanceBeweenContinents = if (!canSettleInTileWithUnique) 1 else 0

View File

@ -47,7 +47,6 @@ object UnitActionsFromUniques {
UniqueType.FoundPuppetCity).firstOrNull() ?: return null
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
if (!unique.hasModifier(UniqueType.ConditionalInTiles) && (tile.isWater || tile.isImpassible())) return null