Source-to-GPP mapping - replaces StatMap

This commit is contained in:
Yair Morgenstern 2021-07-23 14:29:31 +03:00
parent e6bac1c5b5
commit 2c050283b0
2 changed files with 45 additions and 58 deletions

View File

@ -12,10 +12,8 @@ import com.unciv.models.ruleset.Unique
import com.unciv.models.ruleset.tile.ResourceSupplyList import com.unciv.models.ruleset.tile.ResourceSupplyList
import com.unciv.models.ruleset.tile.ResourceType import com.unciv.models.ruleset.tile.ResourceType
import com.unciv.models.ruleset.unit.BaseUnit import com.unciv.models.ruleset.unit.BaseUnit
import com.unciv.models.stats.Stat
import com.unciv.models.stats.StatMap
import com.unciv.models.stats.Stats
import java.util.* import java.util.*
import kotlin.collections.HashMap
import kotlin.collections.HashSet import kotlin.collections.HashSet
import kotlin.math.ceil import kotlin.math.ceil
import kotlin.math.min import kotlin.math.min
@ -260,7 +258,8 @@ class CityInfo {
for (unique in getLocalMatchingUniques("Provides [] []")) { // E.G "Provides [1] [Iron]" for (unique in getLocalMatchingUniques("Provides [] []")) { // E.G "Provides [1] [Iron]"
val resource = getRuleset().tileResources[unique.params[1]] val resource = getRuleset().tileResources[unique.params[1]]
if (resource != null) { if (resource != null) {
cityResources.add(resource, unique.params[0].toInt() * civInfo.getResourceModifier(resource), "Tiles") cityResources.add(resource, unique.params[0].toInt()
* civInfo.getResourceModifier(resource), "Tiles")
} }
} }
@ -317,67 +316,59 @@ class CityInfo {
fun containsBuildingUnique(unique: String) = cityConstructions.getBuiltBuildings().any { it.uniques.contains(unique) } fun containsBuildingUnique(unique: String) = cityConstructions.getBuiltBuildings().any { it.uniques.contains(unique) }
fun getGreatPersonPointsForNextTurn(): StatMap { fun getGreatPersonPointsForNextTurn(): HashMap<String, Counter<String>> {
val stats = StatMap() val sourceToGPP = HashMap<String, Counter<String>>()
for ((specialist, amount) in population.getNewSpecialists())
if (getRuleset().specialists.containsKey(specialist)) // To solve problems in total remake mods
stats.add("Specialists", getRuleset().specialists[specialist]!!.greatPersonPoints.times(amount))
val buildingStats = Stats() val specialistsCounter = Counter<String>()
for ((specialistName, amount) in population.getNewSpecialists())
if (getRuleset().specialists.containsKey(specialistName)) { // To solve problems in total remake mods
val specialist = getRuleset().specialists[specialistName]!!
specialistsCounter.add(GreatPersonManager.statsToGreatPersonCounter(specialist.greatPersonPoints)
.times(amount))
}
sourceToGPP["Specialists"] = specialistsCounter
val buildingsCounter = Counter<String>()
for (building in cityConstructions.getBuiltBuildings()) for (building in cityConstructions.getBuiltBuildings())
if (building.greatPersonPoints != null) if (building.greatPersonPoints != null)
buildingStats.add(building.greatPersonPoints!!) buildingsCounter.add(GreatPersonManager.statsToGreatPersonCounter(building.greatPersonPoints!!))
if (!buildingStats.isEmpty()) sourceToGPP["Buildings"] = buildingsCounter
stats["Buildings"] = buildingStats
for (entry in stats) { for ((source, gppCounter) in sourceToGPP) {
for (unique in civInfo.getMatchingUniques("[] is earned []% faster")) { for (unique in civInfo.getMatchingUniques("[] is earned []% faster")) {
val unit = civInfo.gameInfo.ruleSet.units[unique.params[0]] val unitName = unique.params[0]
if (unit == null) continue if (!gppCounter.containsKey(unitName)) continue
val greatUnitUnique = unit.uniqueObjects.firstOrNull { it.placeholderText == "Great Person - []" } gppCounter.add(unitName, gppCounter[unitName]!! * unique.params[1].toInt() / 100)
if (greatUnitUnique == null) continue
val statName = greatUnitUnique.params[0]
val stat = Stat.values().firstOrNull { it.name == statName }
// this is not very efficient, and if it causes problems we can try and think of a way of improving it
if (stat != null) entry.value.add(stat, entry.value.get(stat) * unique.params[1].toFloat() / 100)
} }
var allGppPercentageBonus = 0
for (unique in getMatchingUniques("[]% great person generation []")) { for (unique in getMatchingUniques("[]% great person generation []")) {
if (!matchesFilter(unique.params[1])) continue if (!matchesFilter(unique.params[1])) continue
stats[entry.key]!!.timesInPlace(1 + unique.params[0].toFloat() / 100f) allGppPercentageBonus += unique.params[0].toInt()
} }
// Sweden UP // Sweden UP
var friendshipMultiplier = 0f
for (otherciv in civInfo.getKnownCivs()) { for (otherciv in civInfo.getKnownCivs()) {
if (civInfo.getDiplomacyManager(otherciv).hasFlag(DiplomacyFlags.DeclarationOfFriendship)) { if (!civInfo.getDiplomacyManager(otherciv).hasFlag(DiplomacyFlags.DeclarationOfFriendship)) continue
for(ourunique in civInfo.getMatchingUniques("When declaring friendship, both parties gain a []% boost to great person generation"))
friendshipMultiplier += ourunique.params[0].toFloat() for(ourunique in civInfo.getMatchingUniques("When declaring friendship, both parties gain a []% boost to great person generation"))
for(theirunique in otherciv.getMatchingUniques("When declaring friendship, both parties gain a []% boost to great person generation")) allGppPercentageBonus += ourunique.params[0].toInt()
friendshipMultiplier += theirunique.params[0].toFloat() for(theirunique in otherciv.getMatchingUniques("When declaring friendship, both parties gain a []% boost to great person generation"))
} allGppPercentageBonus += theirunique.params[0].toInt()
} }
if (friendshipMultiplier > 0f)
stats[entry.key]!!.timesInPlace(1 + friendshipMultiplier / 100f)
// Deprecated since 3.15.9
for (unique in getMatchingUniques("+[]% great person generation in this city")
+ getMatchingUniques("+[]% great person generation in all cities")
) {
stats[entry.key]!!.timesInPlace(1 + unique.params[0].toFloat() / 100f)
}
//
for (unitName in gppCounter.keys)
gppCounter.add(unitName, gppCounter[unitName]!! * allGppPercentageBonus / 100)
} }
return stats return sourceToGPP
} }
fun getGreatPersonPoints(): Counter<String> { fun getGreatPersonPoints(): Counter<String> {
val stats = Stats() val gppCounter = Counter<String>()
for (entry in getGreatPersonPointsForNextTurn().values) for (entry in getGreatPersonPointsForNextTurn().values)
stats.add(entry) gppCounter.add(entry)
return GreatPersonManager.statsToGreatPersonCounter(stats) return gppCounter
} }
internal fun getMaxHealth() = 200 + cityConstructions.getBuiltBuildings().sumBy { it.cityHealth } internal fun getMaxHealth() = 200 + cityConstructions.getBuiltBuildings().sumBy { it.cityHealth }

View File

@ -5,7 +5,6 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.utils.Align import com.badlogic.gdx.utils.Align
import com.unciv.UncivGame import com.unciv.UncivGame
import com.unciv.logic.city.CityInfo import com.unciv.logic.city.CityInfo
import com.unciv.logic.civilization.GreatPersonManager
import com.unciv.models.ruleset.Building import com.unciv.models.ruleset.Building
import com.unciv.models.stats.Stat import com.unciv.models.stats.Stat
import com.unciv.models.translations.tr import com.unciv.models.translations.tr
@ -208,19 +207,16 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(CameraStageBaseS
private fun Table.addGreatPersonPointInfo(cityInfo: CityInfo) { private fun Table.addGreatPersonPointInfo(cityInfo: CityInfo) {
val greatPersonPoints = cityInfo.getGreatPersonPointsForNextTurn() val greatPersonPoints = cityInfo.getGreatPersonPointsForNextTurn()
val statToGreatPerson = GreatPersonManager.statToGreatPersonMapping val allGreatPersonNames = greatPersonPoints.asSequence().flatMap { it.value.keys }.distinct()
for (stat in Stat.values()) { for (greatPersonName in allGreatPersonNames) {
if (!statToGreatPerson.containsKey(stat)) continue val expanderName = "[$greatPersonName] points"
if (greatPersonPoints.all { it.value.get(stat) == 0f }) continue
val expanderName = "[" + statToGreatPerson[stat]!! + "] points"
val greatPersonTable = Table() val greatPersonTable = Table()
addCategory(expanderName, greatPersonTable) addCategory(expanderName, greatPersonTable)
for (entry in greatPersonPoints) { for ((source, gppCounter) in greatPersonPoints) {
val value = entry.value.toHashMap()[stat]!! val gppPointsFromSource = gppCounter[greatPersonName]!!
if (value == 0f) continue if (gppPointsFromSource == 0) continue
greatPersonTable.add(entry.key.toLabel()).padRight(10f) greatPersonTable.add(source.toLabel()).padRight(10f)
greatPersonTable.add(value.toOneDecimalLabel()).row() greatPersonTable.add(gppPointsFromSource.toLabel()).row()
} }
} }
} }