From 965b8929124b4f1057e0a2eb80cd92aa20cb4c71 Mon Sep 17 00:00:00 2001 From: Emandac <121508218+Emandac@users.noreply.github.com> Date: Tue, 26 Aug 2025 01:52:25 +0200 Subject: [PATCH] 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. --- .../automation/unit/CityLocationTileRanker.kt | 16 ++++++++++------ .../automation/unit/CivilianUnitAutomation.kt | 1 - .../logic/automation/unit/UnitAutomation.kt | 3 ++- core/src/com/unciv/logic/map/tile/Tile.kt | 2 +- .../unit/actions/UnitActionsFromUniques.kt | 1 - 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/core/src/com/unciv/logic/automation/unit/CityLocationTileRanker.kt b/core/src/com/unciv/logic/automation/unit/CityLocationTileRanker.kt index d2821772d5..2822ebfc3a 100644 --- a/core/src/com/unciv/logic/automation/unit/CityLocationTileRanker.kt +++ b/core/src/com/unciv/logic/automation/unit/CityLocationTileRanker.kt @@ -66,17 +66,21 @@ object CityLocationTileRanker { private fun canSettleTile(tile: Tile, unit: MapUnit, nearbyCities: Sequence): 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 diff --git a/core/src/com/unciv/logic/automation/unit/CivilianUnitAutomation.kt b/core/src/com/unciv/logic/automation/unit/CivilianUnitAutomation.kt index b240b64bfa..9a0f7e8e60 100644 --- a/core/src/com/unciv/logic/automation/unit/CivilianUnitAutomation.kt +++ b/core/src/com/unciv/logic/automation/unit/CivilianUnitAutomation.kt @@ -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) diff --git a/core/src/com/unciv/logic/automation/unit/UnitAutomation.kt b/core/src/com/unciv/logic/automation/unit/UnitAutomation.kt index 7eaa131d2f..76b4eae096 100644 --- a/core/src/com/unciv/logic/automation/unit/UnitAutomation.kt +++ b/core/src/com/unciv/logic/automation/unit/UnitAutomation.kt @@ -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)) diff --git a/core/src/com/unciv/logic/map/tile/Tile.kt b/core/src/com/unciv/logic/map/tile/Tile.kt index ea93c98b14..c82dc6a1cb 100644 --- a/core/src/com/unciv/logic/map/tile/Tile.kt +++ b/core/src/com/unciv/logic/map/tile/Tile.kt @@ -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 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 0ee9c1ebcb..50e2ae0d63 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 @@ -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