diff --git a/core/src/com/unciv/logic/automation/unit/SpecificUnitAutomation.kt b/core/src/com/unciv/logic/automation/unit/SpecificUnitAutomation.kt index ec275db99a..49f6752211 100644 --- a/core/src/com/unciv/logic/automation/unit/SpecificUnitAutomation.kt +++ b/core/src/com/unciv/logic/automation/unit/SpecificUnitAutomation.kt @@ -220,8 +220,14 @@ object SpecificUnitAutomation { if (bestCityLocation == null) { // We got a badass over here, all tiles within 5 are taken? // Try to move towards the frontier - val frontierCity = unit.civInfo.cities.maxByOrNull { it.getFrontierScore() } - if (frontierCity != null && frontierCity.getFrontierScore() > 0 && unit.movement.canReach(frontierCity.getCenterTile())) + + /** @return the number of tiles 4 (un-modded) out from this city that could hold a city, ie how lonely this city is */ + fun getFrontierScore(cityInfo: CityInfo) = cityInfo.getCenterTile() + .getTilesAtDistance(cityInfo.civInfo.gameInfo.ruleSet.modOptions.constants.minimalCityDistance + 1) + .count { it.canBeSettled() && (it.getOwner() == null || it.getOwner() == cityInfo.civInfo ) } + + val frontierCity = unit.civInfo.cities.maxByOrNull { getFrontierScore(it) } + if (frontierCity != null && getFrontierScore(frontierCity) > 0 && unit.movement.canReach(frontierCity.getCenterTile())) unit.movement.headTowards(frontierCity.getCenterTile()) if (UnitAutomation.tryExplore(unit)) return // try to find new areas UnitAutomation.wander(unit) // go around aimlessly diff --git a/core/src/com/unciv/logic/city/CityInfo.kt b/core/src/com/unciv/logic/city/CityInfo.kt index 7587156380..8d1a01ea40 100644 --- a/core/src/com/unciv/logic/city/CityInfo.kt +++ b/core/src/com/unciv/logic/city/CityInfo.kt @@ -2,7 +2,6 @@ package com.unciv.logic.city import com.badlogic.gdx.math.Vector2 import com.unciv.logic.IsPartOfGameInfoSerialization -import com.unciv.logic.battle.CityCombatant import com.unciv.logic.city.managers.CityEspionageManager import com.unciv.logic.city.managers.CityExpansionManager import com.unciv.logic.city.managers.CityInfoConquestFunctions @@ -24,7 +23,6 @@ import com.unciv.models.ruleset.unit.BaseUnit import com.unciv.models.stats.Stat import java.util.* import kotlin.math.ceil -import kotlin.math.pow import kotlin.math.roundToInt enum class CityFlags { @@ -141,6 +139,7 @@ class CityInfo : IsPartOfGameInfoSerialization { fun isCapital(): Boolean = cityConstructions.getBuiltBuildings().any { it.hasUnique(UniqueType.IndicatesCapital) } fun isCoastal(): Boolean = centerTileInfo.isCoastalTile() + fun capitalCityIndicator(): String { val indicatorBuildings = getRuleset().buildings.values .asSequence() @@ -153,7 +152,6 @@ class CityInfo : IsPartOfGameInfoSerialization { fun isConnectedToCapital(connectionTypePredicate: (Set) -> Boolean = { true }): Boolean { val mediumTypes = civInfo.citiesConnectedToCapitalToMediums[this] ?: return false return connectionTypePredicate(mediumTypes) - } fun hasFlag(flag: CityFlags) = flagsCountdown.containsKey(flag.name) @@ -162,10 +160,6 @@ class CityInfo : IsPartOfGameInfoSerialization { fun isWeLoveTheKingDayActive() = hasFlag(CityFlags.WeLoveTheKing) fun isInResistance() = hasFlag(CityFlags.Resistance) - /** @return the number of tiles 4 (un-modded) out from this city that could hold a city, ie how lonely this city is */ - fun getFrontierScore() = getCenterTile() - .getTilesAtDistance(civInfo.gameInfo.ruleSet.modOptions.constants.minimalCityDistance + 1) - .count { it.canBeSettled() && (it.getOwner() == null || it.getOwner() == civInfo ) } fun getRuleset() = civInfo.gameInfo.ruleSet @@ -373,26 +367,6 @@ class CityInfo : IsPartOfGameInfoSerialization { return true } - fun getForceEvaluation(): Int { - // Same as for units, so higher values count more - return CityCombatant(this).getDefendingStrength().toFloat().pow(1.5f).toInt() - } - - fun getNeighbouringCivs(): Set { - val tilesList: HashSet = getTiles().toHashSet() - val cityPositionList: ArrayList = arrayListOf() - - for (tiles in tilesList) - for (tile in tiles.neighbors) - if (!tilesList.contains(tile)) - cityPositionList.add(tile) - - return cityPositionList - .asSequence() - .mapNotNull { it.getOwner()?.civName } - .toSet() - } - //endregion //region state-changing functions diff --git a/core/src/com/unciv/logic/civilization/diplomacy/CityStateFunctions.kt b/core/src/com/unciv/logic/civilization/diplomacy/CityStateFunctions.kt index 3b48004e88..b8937dd9ac 100644 --- a/core/src/com/unciv/logic/civilization/diplomacy/CityStateFunctions.kt +++ b/core/src/com/unciv/logic/civilization/diplomacy/CityStateFunctions.kt @@ -2,6 +2,7 @@ package com.unciv.logic.civilization.diplomacy import com.unciv.Constants import com.unciv.logic.automation.civilization.NextTurnAutomation +import com.unciv.logic.battle.CityCombatant import com.unciv.logic.civilization.AlertType import com.unciv.logic.civilization.CivFlags import com.unciv.logic.civilization.CivilizationInfo @@ -390,7 +391,7 @@ class CityStateFunctions(val civInfo: CivilizationInfo) { it.militaryUnit!!.getForceEvaluation() else 0 } - val csForce = civInfo.getCapital()!!.getForceEvaluation() + inRangeTiles + val csForce = CityCombatant(civInfo.getCapital()!!).getDefendingStrength().toFloat().pow(1.5f).toInt() + inRangeTiles .sumOf { if (it.militaryUnit?.civInfo == civInfo) it.militaryUnit!!.getForceEvaluation() else 0 diff --git a/core/src/com/unciv/logic/trade/TradeEvaluation.kt b/core/src/com/unciv/logic/trade/TradeEvaluation.kt index 72b2cf06c1..1306697ce6 100644 --- a/core/src/com/unciv/logic/trade/TradeEvaluation.kt +++ b/core/src/com/unciv/logic/trade/TradeEvaluation.kt @@ -6,6 +6,7 @@ import com.unciv.logic.automation.ThreatLevel import com.unciv.logic.city.CityInfo import com.unciv.logic.civilization.CivilizationInfo import com.unciv.logic.civilization.diplomacy.RelationshipLevel +import com.unciv.logic.map.TileInfo import com.unciv.models.ruleset.ModOptionsConstants import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.unique.UniqueType @@ -149,8 +150,9 @@ class TradeEvaluation { } } } + private fun surroundedByOurCities(city: CityInfo, civInfo: CivilizationInfo): Int { - val borderingCivs: Set = city.getNeighbouringCivs() + val borderingCivs: Set = getNeighbouringCivs(city) if (borderingCivs.size == 1 && borderingCivs.contains(civInfo.civName)) { return 10 * civInfo.getEraNumber() // if the city is surrounded only by trading civ } @@ -159,6 +161,22 @@ class TradeEvaluation { return 0 } + private fun getNeighbouringCivs(city:CityInfo): Set { + val tilesList: HashSet = city.getTiles().toHashSet() + val cityPositionList: ArrayList = arrayListOf() + + for (tiles in tilesList) + for (tile in tiles.neighbors) + if (!tilesList.contains(tile)) + cityPositionList.add(tile) + + return cityPositionList + .asSequence() + .mapNotNull { it.getOwner()?.civName } + .toSet() + } + + fun evaluateSellCost(offer: TradeOffer, civInfo: CivilizationInfo, tradePartner: CivilizationInfo): Int { when (offer.type) { TradeType.Gold -> return offer.amount