diff --git a/core/src/com/unciv/logic/city/CityStats.kt b/core/src/com/unciv/logic/city/CityStats.kt index b6d724347b..78f22fe648 100644 --- a/core/src/com/unciv/logic/city/CityStats.kt +++ b/core/src/com/unciv/logic/city/CityStats.kt @@ -252,19 +252,14 @@ class CityStats { } fun getStatsOfSpecialist(specialistName:String): Stats { - val stats = cityInfo.getRuleset().specialists[specialistName]!!.clone() + val specialist = cityInfo.getRuleset().specialists[specialistName] + if (specialist == null) return Stats() + val stats = specialist.clone() for (unique in cityInfo.civInfo.getMatchingUniques("[] from every specialist")) stats.add(Stats.parse(unique.params[0])) return stats } - private fun getStatsFromSpecialists(specialists: Stats): Stats { - val stats = Stats() - for (entry in specialists.toHashMap().filter { it.value > 0 }) - stats.add(getStatsOfSpecialist(entry.key) * entry.value) - return stats - } - private fun getStatsFromSpecialists(specialists: HashMap): Stats { val stats = Stats() for (entry in specialists.filter { it.value > 0 }) diff --git a/core/src/com/unciv/logic/city/PopulationManager.kt b/core/src/com/unciv/logic/city/PopulationManager.kt index e92c80af01..94a21e61c4 100644 --- a/core/src/com/unciv/logic/city/PopulationManager.kt +++ b/core/src/com/unciv/logic/city/PopulationManager.kt @@ -7,6 +7,8 @@ import com.unciv.models.stats.Stat import com.unciv.models.stats.Stats import com.unciv.ui.utils.withItem import com.unciv.ui.utils.withoutItem +import kotlin.math.floor +import kotlin.math.pow class PopulationManager { @Transient @@ -18,17 +20,13 @@ class PopulationManager { // Being deprecated out val specialists = Stats() - fun getNewSpecialists(): HashMap { + fun getNewSpecialists() = convertStatsToSpecialistHashmap(specialists) + + fun convertStatsToSpecialistHashmap(stats: Stats):HashMap { val specialistHashmap = HashMap() - for ((stat, amount) in specialists.toHashMap()) { + for ((stat, amount) in stats.toHashMap()) { if (amount == 0f) continue - val specialistName = when (stat) { - Stat.Production -> "Engineer" - Stat.Gold -> "Merchant" - Stat.Science -> "Scientist" - Stat.Culture -> "Artist" - else -> TODO() - } + val specialistName = specialistNameByStat(stat) specialistHashmap[specialistName] = amount.toInt() } return specialistHashmap @@ -43,9 +41,7 @@ class PopulationManager { return toReturn } - fun getNumberOfSpecialists(): Int { - return getNewSpecialists().values.sum() - } + fun getNumberOfSpecialists() = getNewSpecialists().values.sum() fun getFreePopulation(): Int { val workingPopulation = cityInfo.workedTiles.size @@ -54,7 +50,7 @@ class PopulationManager { fun getFoodToNextPopulation(): Int { // civ v math, civilization.wikia - var foodRequired = 15 + 6 * (population - 1) + Math.floor(Math.pow((population - 1).toDouble(), 1.8)) + var foodRequired = 15 + 6 * (population - 1) + floor((population - 1).toDouble().pow(1.8)) if(!cityInfo.civInfo.isPlayerCivilization()) foodRequired *= cityInfo.civInfo.gameInfo.getDifficulty().aiCityGrowthModifier return foodRequired.toInt() @@ -70,7 +66,7 @@ class PopulationManager { if (population > 1) population-- foodStored = 0 } - if (foodStored >= getFoodToNextPopulation()){ // growth! + if (foodStored >= getFoodToNextPopulation()) { // growth! foodStored -= getFoodToNextPopulation() val percentOfFoodCarriedOver = cityInfo.cityConstructions.builtBuildingUniqueMap .getUniques("[]% of food is carried over after population increases") @@ -84,6 +80,16 @@ class PopulationManager { internal fun getStatsOfSpecialist(stat: Stat) = cityInfo.cityStats.getStatsOfSpecialist(stat) + internal fun getStatsOfSpecialist(name:String) = cityInfo.cityStats.getStatsOfSpecialist(name) + + internal fun specialistNameByStat(stat: Stat) = when (stat) { + Stat.Production -> "Engineer" + Stat.Gold -> "Merchant" + Stat.Science -> "Scientist" + Stat.Culture -> "Artist" + else -> TODO() + } + // todo - change tile choice according to city! // if small city, favor production above all, ignore gold! // if larger city, food should be worth less! @@ -118,7 +124,7 @@ class PopulationManager { } fun unassignExtraPopulation() { - for(tile in cityInfo.workedTiles.map { cityInfo.tileMap[it] }) { + for (tile in cityInfo.workedTiles.map { cityInfo.tileMap[it] }) { if (tile.getOwner() != cityInfo.civInfo || tile.getWorkingCity() != cityInfo) cityInfo.workedTiles = cityInfo.workedTiles.withoutItem(tile.position) if (tile.aerialDistanceTo(cityInfo.getCenterTile()) > 3) @@ -128,27 +134,29 @@ class PopulationManager { // unassign specialists that cannot be (e.g. the city was captured and one of the specialist buildings was destroyed) val maxSpecialists = getMaxSpecialists().toHashMap() val specialistsHashmap = specialists.toHashMap() - for(entry in maxSpecialists) - if(specialistsHashmap[entry.key]!! > entry.value) - specialists.add(entry.key,maxSpecialists[entry.key]!! - specialistsHashmap[entry.key]!!) + for (entry in maxSpecialists) + if (specialistsHashmap[entry.key]!! > entry.value) + specialists.add(entry.key, maxSpecialists[entry.key]!! - specialistsHashmap[entry.key]!!) - while (getFreePopulation()<0) { + while (getFreePopulation() < 0) { //evaluate tiles - val worstWorkedTile: TileInfo? = if(cityInfo.workedTiles.isEmpty()) null - else { + val worstWorkedTile: TileInfo? = if (cityInfo.workedTiles.isEmpty()) null + else { cityInfo.workedTiles.asSequence() .map { cityInfo.tileMap[it] } - .minBy { Automation.rankTileForCityWork(it, cityInfo) - + (if(it.isLocked()) 10 else 0) }!! + .minBy { + Automation.rankTileForCityWork(it, cityInfo) + +(if (it.isLocked()) 10 else 0) + }!! } - val valueWorstTile = if(worstWorkedTile==null) 0f + val valueWorstTile = if (worstWorkedTile == null) 0f else Automation.rankTileForCityWork(worstWorkedTile, cityInfo) //evaluate specialists val worstJob: Stat? = specialists.toHashMap() .filter { it.value > 0 } - .map {it.key} + .map { it.key } .minBy { Automation.rankSpecialist(getStatsOfSpecialist(it), cityInfo) } var valueWorstSpecialist = 0f if (worstJob != null) @@ -158,9 +166,7 @@ class PopulationManager { if ((worstWorkedTile != null && valueWorstTile < valueWorstSpecialist) || worstJob == null) { cityInfo.workedTiles = cityInfo.workedTiles.withoutItem(worstWorkedTile!!.position) - } else { - specialists.add(worstJob, -1f) - } + } else specialists.add(worstJob, -1f) } }