From a9999ad0d7e61a9fc1ab7816d1a14a4bb3ad9d74 Mon Sep 17 00:00:00 2001 From: Emandac <121508218+Emandac@users.noreply.github.com> Date: Sun, 3 Aug 2025 13:01:33 +0200 Subject: [PATCH] Fix the crash for the Ai and rename some variables --- .../civilization/managers/UnitManager.kt | 6 ++-- core/src/com/unciv/logic/map/tile/Tile.kt | 30 +++++++++++++++---- .../com/unciv/models/ruleset/unit/BaseUnit.kt | 2 +- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/core/src/com/unciv/logic/civilization/managers/UnitManager.kt b/core/src/com/unciv/logic/civilization/managers/UnitManager.kt index 4d489d0d2a..c93e55fb1e 100644 --- a/core/src/com/unciv/logic/civilization/managers/UnitManager.kt +++ b/core/src/com/unciv/logic/civilization/managers/UnitManager.kt @@ -55,14 +55,14 @@ class UnitManager(val civInfo: Civilization) { val unit = civInfo.getEquivalentUnit(baseUnit) val citiesNotInResistance = civInfo.cities.filterNot { it.isInResistance() } - var canSpwanUnitOnWater = false + var canSpawnUnitOnWater = false if (city != null) { - canSpwanUnitOnWater = city.getCenterTile().matchesFilter("Water") + canSpawnUnitOnWater = city.getCenterTile().matchesFilter("Water") } val cityToAddTo = when { - unit.isWaterUnit && (city == null || !city.isCoastal()) && !canSpwanUnitOnWater -> + unit.isWaterUnit && (city == null || !city.isCoastal()) && !canSpawnUnitOnWater -> citiesNotInResistance.filter { it.isCoastal() }.randomOrNull() ?: civInfo.cities.filter { it.isCoastal() }.randomOrNull() city != null -> city diff --git a/core/src/com/unciv/logic/map/tile/Tile.kt b/core/src/com/unciv/logic/map/tile/Tile.kt index d5cffa96f2..fefed38205 100644 --- a/core/src/com/unciv/logic/map/tile/Tile.kt +++ b/core/src/com/unciv/logic/map/tile/Tile.kt @@ -19,6 +19,7 @@ import com.unciv.logic.map.mapgenerator.MapResourceSetting import com.unciv.logic.map.mapunit.MapUnit import com.unciv.logic.map.mapunit.UnitTurnManager import com.unciv.logic.map.mapunit.movement.UnitMovement +import com.unciv.models.UnitAction import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.tile.ResourceType import com.unciv.models.ruleset.tile.Terrain @@ -630,13 +631,32 @@ class Tile : IsPartOfGameInfoSerialization, Json.Serializable { return min(distance, wrappedDistance).toInt() } - - @Readonly - fun canBeSettled(): Boolean { + + fun canBeSettled(unitCanFoundUnique: Unique?=null): Boolean { val modConstants = tileMap.gameInfo.ruleset.modOptions.constants + var addedDistanceBeweenContinents: Int + var canSettleInTileWithUnique = false + if (unitCanFoundUnique != null) { + canSettleInTileWithUnique = (isWater || isImpassible()) && + unitCanFoundUnique.getModifiers(UniqueType.ConditionalInTiles).none{ + 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 + return when { - isWater || isImpassible() -> false - getTilesInDistance(modConstants.minimalCityDistanceOnDifferentContinents) + canSettleInTileWithUnique -> false + getTilesInDistance(modConstants.minimalCityDistanceOnDifferentContinents+ + /* + Make sure, settler unit has the unique with condition . + Because this can crash the game in automateSettlerActions in SpecificUnitAutomation.kt. + */ + if (unitCanFoundUnique != null) addedDistanceBeweenContinents else 0) .any { it.isCityCenter() && it.getContinent() != getContinent() } -> false getTilesInDistance(modConstants.minimalCityDistance) .any { it.isCityCenter() && it.getContinent() == getContinent() } -> false diff --git a/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt b/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt index d0dc8a06bc..4e9bdd2943 100644 --- a/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt +++ b/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt @@ -221,7 +221,7 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction { val stateForConditionals = city?.state ?: civ.state - // !city.getCenterTile().matchesFilter("Water") to allow the cities on Water tile to spwan naval units. + // !city.getCenterTile().matchesFilter("Water") to allow the cities on Water tile to spawn naval units. if (city != null && isWaterUnit && !city.isCoastal() && !city.getCenterTile().matchesFilter("Water")) yield(RejectionReasonType.WaterUnitsInCoastalCities.toInstance())