mirror of
https://github.com/yairm210/Unciv.git
synced 2025-03-09 20:29:50 +07:00
Readded stats drilldown
This commit is contained in:
parent
f331ac69e4
commit
6104a25d91
@ -2,6 +2,7 @@ package com.unciv.ui.cityscreen
|
||||
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor
|
||||
import com.badlogic.gdx.scenes.scene2d.Touchable
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Cell
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
@ -10,11 +11,15 @@ import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.city.CityFlags
|
||||
import com.unciv.logic.city.CityFocus
|
||||
import com.unciv.logic.city.CityInfo
|
||||
import com.unciv.logic.city.CityStats
|
||||
import com.unciv.logic.city.StatTreeNode
|
||||
import com.unciv.models.ruleset.Building
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.stats.Stat
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.civilopedia.CivilopediaScreen
|
||||
import com.unciv.ui.images.IconCircleGroup
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.ExpanderTab
|
||||
@ -24,6 +29,7 @@ import com.unciv.ui.utils.extensions.colorFromRGB
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.surroundWithCircle
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
import java.text.DecimalFormat
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.round
|
||||
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
|
||||
@ -103,6 +109,9 @@ class CityStatsTable(val cityScreen: CityScreen): Table() {
|
||||
if (cityInfo.religion.getNumberOfFollowers().isNotEmpty() && cityInfo.civInfo.gameInfo.isReligionEnabled())
|
||||
addReligionInfo()
|
||||
|
||||
|
||||
addStatInfo()
|
||||
addGreatPersonPointInfo(cityInfo)
|
||||
addBuildingsInfo()
|
||||
|
||||
upperTable.pack()
|
||||
@ -292,4 +301,151 @@ class CityStatsTable(val cityScreen: CityScreen): Table() {
|
||||
lowerTable.add(expanderTab).growX().row()
|
||||
}
|
||||
|
||||
|
||||
private fun addStatsToHashmap(
|
||||
statTreeNode: StatTreeNode,
|
||||
hashMap: HashMap<String, Float>,
|
||||
stat: Stat,
|
||||
showDetails: Boolean,
|
||||
indentation: Int = 0
|
||||
) {
|
||||
for ((name, child) in statTreeNode.children) {
|
||||
val statAmount = child.totalStats[stat]
|
||||
if (statAmount == 0f) continue
|
||||
hashMap["- ".repeat(indentation) + name.tr()] = statAmount
|
||||
if (showDetails) addStatsToHashmap(child, hashMap, stat, showDetails, indentation + 1)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Table.addStatInfo() {
|
||||
val cityStats = cityScreen.city.cityStats
|
||||
|
||||
val showFaith = cityScreen.city.civInfo.gameInfo.isReligionEnabled()
|
||||
for (stat in Stat.values()) {
|
||||
if (stat == Stat.Faith && !showFaith) continue
|
||||
val statValuesTable = Table()
|
||||
statValuesTable.touchable = Touchable.enabled
|
||||
addCategory(stat.name, statValuesTable)
|
||||
|
||||
updateStatValuesTable(stat, cityStats, statValuesTable)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateStatValuesTable(
|
||||
stat: Stat,
|
||||
cityStats: CityStats,
|
||||
statValuesTable: Table,
|
||||
showDetails:Boolean = false
|
||||
) {
|
||||
statValuesTable.clear()
|
||||
statValuesTable.defaults().pad(2f)
|
||||
statValuesTable.onClick {
|
||||
updateStatValuesTable(
|
||||
stat,
|
||||
cityStats,
|
||||
statValuesTable,
|
||||
!showDetails
|
||||
)
|
||||
onContentResize()
|
||||
}
|
||||
|
||||
val relevantBaseStats = LinkedHashMap<String, Float>()
|
||||
|
||||
if (stat != Stat.Happiness)
|
||||
addStatsToHashmap(cityStats.baseStatTree, relevantBaseStats, stat, showDetails)
|
||||
else relevantBaseStats.putAll(cityStats.happinessList)
|
||||
for (key in relevantBaseStats.keys.toList())
|
||||
if (relevantBaseStats[key] == 0f) relevantBaseStats.remove(key)
|
||||
|
||||
if (relevantBaseStats.isEmpty()) return
|
||||
|
||||
statValuesTable.add("Base values".toLabel(fontSize = FONT_SIZE_STAT_INFO_HEADER)).pad(4f)
|
||||
.colspan(2).row()
|
||||
var sumOfAllBaseValues = 0f
|
||||
for (entry in relevantBaseStats) {
|
||||
val specificStatValue = entry.value
|
||||
if (!entry.key.startsWith('-'))
|
||||
sumOfAllBaseValues += specificStatValue
|
||||
statValuesTable.add(entry.key.toLabel()).left()
|
||||
statValuesTable.add(specificStatValue.toOneDecimalLabel()).row()
|
||||
}
|
||||
statValuesTable.addSeparator()
|
||||
statValuesTable.add("Total".toLabel())
|
||||
statValuesTable.add(sumOfAllBaseValues.toOneDecimalLabel()).row()
|
||||
|
||||
val relevantBonuses = LinkedHashMap<String, Float>()
|
||||
addStatsToHashmap(cityStats.statPercentBonusTree, relevantBonuses, stat, showDetails)
|
||||
|
||||
val totalBonusStats = cityStats.statPercentBonusTree.totalStats
|
||||
if (totalBonusStats[stat] != 0f) {
|
||||
statValuesTable.add("Bonuses".toLabel(fontSize = FONT_SIZE_STAT_INFO_HEADER)).colspan(2)
|
||||
.padTop(20f).row()
|
||||
for ((source, bonusAmount) in relevantBonuses) {
|
||||
statValuesTable.add(source.toLabel()).left()
|
||||
statValuesTable.add(bonusAmount.toPercentLabel()).row() // negative bonus
|
||||
}
|
||||
statValuesTable.addSeparator()
|
||||
statValuesTable.add("Total".toLabel())
|
||||
statValuesTable.add(totalBonusStats[stat].toPercentLabel()).row() // negative bonus
|
||||
|
||||
|
||||
statValuesTable.add("Final".toLabel(fontSize = FONT_SIZE_STAT_INFO_HEADER)).colspan(2)
|
||||
.padTop(20f).row()
|
||||
var finalTotal = 0f
|
||||
for (entry in cityStats.finalStatList) {
|
||||
val specificStatValue = entry.value[stat]
|
||||
finalTotal += specificStatValue
|
||||
if (specificStatValue == 0f) continue
|
||||
statValuesTable.add(entry.key.toLabel())
|
||||
statValuesTable.add(specificStatValue.toOneDecimalLabel()).row()
|
||||
}
|
||||
statValuesTable.addSeparator()
|
||||
statValuesTable.add("Total".toLabel())
|
||||
statValuesTable.add(finalTotal.toOneDecimalLabel()).row()
|
||||
}
|
||||
|
||||
statValuesTable.pack()
|
||||
|
||||
if (stat != Stat.Happiness) {
|
||||
val toggleButton = getToggleButton(showDetails)
|
||||
statValuesTable.addActor(toggleButton)
|
||||
toggleButton.setPosition(0f, statValuesTable.height, Align.topLeft)
|
||||
}
|
||||
|
||||
statValuesTable.padBottom(4f)
|
||||
}
|
||||
|
||||
private fun getToggleButton(showDetails: Boolean): IconCircleGroup {
|
||||
val label = (if (showDetails) "-" else "+").toLabel()
|
||||
label.setAlignment(Align.center)
|
||||
return label
|
||||
.surroundWithCircle(25f, color = BaseScreen.skinStrings.skinConfig.baseColor)
|
||||
.surroundWithCircle(27f, false)
|
||||
}
|
||||
|
||||
private fun Table.addGreatPersonPointInfo(cityInfo: CityInfo) {
|
||||
val greatPersonPoints = cityInfo.getGreatPersonPointsForNextTurn()
|
||||
val allGreatPersonNames = greatPersonPoints.asSequence().flatMap { it.value.keys }.distinct()
|
||||
for (greatPersonName in allGreatPersonNames) {
|
||||
val expanderName = "[$greatPersonName] points"
|
||||
val greatPersonTable = Table()
|
||||
addCategory(expanderName, greatPersonTable)
|
||||
for ((source, gppCounter) in greatPersonPoints) {
|
||||
val gppPointsFromSource = gppCounter[greatPersonName]!!
|
||||
if (gppPointsFromSource == 0) continue
|
||||
greatPersonTable.add(source.toLabel()).padRight(10f)
|
||||
greatPersonTable.add(gppPointsFromSource.toLabel()).row()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val FONT_SIZE_STAT_INFO_HEADER = 22
|
||||
|
||||
private fun Float.toPercentLabel() =
|
||||
"${if (this>0f) "+" else ""}${DecimalFormat("0.#").format(this)}%".toLabel()
|
||||
private fun Float.toOneDecimalLabel() =
|
||||
DecimalFormat("0.#").format(this).toLabel()
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user