mirror of
https://github.com/yairm210/Unciv.git
synced 2025-03-10 04:43:29 +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.graphics.Color
|
||||||
import com.badlogic.gdx.scenes.scene2d.Actor
|
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.Cell
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Label
|
import com.badlogic.gdx.scenes.scene2d.ui.Label
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||||
@ -10,11 +11,15 @@ import com.unciv.Constants
|
|||||||
import com.unciv.UncivGame
|
import com.unciv.UncivGame
|
||||||
import com.unciv.logic.city.CityFlags
|
import com.unciv.logic.city.CityFlags
|
||||||
import com.unciv.logic.city.CityFocus
|
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.Building
|
||||||
import com.unciv.models.ruleset.unique.UniqueType
|
import com.unciv.models.ruleset.unique.UniqueType
|
||||||
import com.unciv.models.stats.Stat
|
import com.unciv.models.stats.Stat
|
||||||
import com.unciv.models.translations.tr
|
import com.unciv.models.translations.tr
|
||||||
import com.unciv.ui.civilopedia.CivilopediaScreen
|
import com.unciv.ui.civilopedia.CivilopediaScreen
|
||||||
|
import com.unciv.ui.images.IconCircleGroup
|
||||||
import com.unciv.ui.images.ImageGetter
|
import com.unciv.ui.images.ImageGetter
|
||||||
import com.unciv.ui.utils.BaseScreen
|
import com.unciv.ui.utils.BaseScreen
|
||||||
import com.unciv.ui.utils.ExpanderTab
|
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.onClick
|
||||||
import com.unciv.ui.utils.extensions.surroundWithCircle
|
import com.unciv.ui.utils.extensions.surroundWithCircle
|
||||||
import com.unciv.ui.utils.extensions.toLabel
|
import com.unciv.ui.utils.extensions.toLabel
|
||||||
|
import java.text.DecimalFormat
|
||||||
import kotlin.math.ceil
|
import kotlin.math.ceil
|
||||||
import kotlin.math.round
|
import kotlin.math.round
|
||||||
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
|
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())
|
if (cityInfo.religion.getNumberOfFollowers().isNotEmpty() && cityInfo.civInfo.gameInfo.isReligionEnabled())
|
||||||
addReligionInfo()
|
addReligionInfo()
|
||||||
|
|
||||||
|
|
||||||
|
addStatInfo()
|
||||||
|
addGreatPersonPointInfo(cityInfo)
|
||||||
addBuildingsInfo()
|
addBuildingsInfo()
|
||||||
|
|
||||||
upperTable.pack()
|
upperTable.pack()
|
||||||
@ -292,4 +301,151 @@ class CityStatsTable(val cityScreen: CityScreen): Table() {
|
|||||||
lowerTable.add(expanderTab).growX().row()
|
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