Move more context-specific functions out of CityInfo

This commit is contained in:
Yair Morgenstern 2023-01-18 21:41:56 +02:00
parent 5ebfcc3a90
commit 6dd0bf51c7
4 changed files with 30 additions and 31 deletions

View File

@ -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

View File

@ -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<String>) -> 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<String> {
val tilesList: HashSet<TileInfo> = getTiles().toHashSet()
val cityPositionList: ArrayList<TileInfo> = 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

View File

@ -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

View File

@ -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<String> = city.getNeighbouringCivs()
val borderingCivs: Set<String> = 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<String> {
val tilesList: HashSet<TileInfo> = city.getTiles().toHashSet()
val cityPositionList: ArrayList<TileInfo> = 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