Specialist information is now hybrid

This commit is contained in:
Yair Morgenstern
2020-09-30 18:03:26 +03:00
parent 9f9d89af9d
commit 43f5799578
2 changed files with 37 additions and 36 deletions

View File

@ -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<String, Int>): Stats {
val stats = Stats()
for (entry in specialists.filter { it.value > 0 })

View File

@ -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<String, Int> {
fun getNewSpecialists() = convertStatsToSpecialistHashmap(specialists)
fun convertStatsToSpecialistHashmap(stats: Stats):HashMap<String,Int> {
val specialistHashmap = HashMap<String, Int>()
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)
}
}