diff --git a/core/src/com/unciv/models/stats/Stats.kt b/core/src/com/unciv/models/stats/Stats.kt index 5911fe1847..bc3083e04e 100644 --- a/core/src/com/unciv/models/stats/Stats.kt +++ b/core/src/com/unciv/models/stats/Stats.kt @@ -74,6 +74,10 @@ open class Stats() { Stat.Science to science) } + fun get(stat:Stat):Float{ + return this.toHashMap()[stat]!! + } + private fun setStats(hashMap:HashMap){ culture=hashMap[Stat.Culture]!! gold=hashMap[Stat.Gold]!! diff --git a/core/src/com/unciv/ui/cityscreen/CityInfoTable.kt b/core/src/com/unciv/ui/cityscreen/CityInfoTable.kt index 319beedfba..ab4a70b358 100644 --- a/core/src/com/unciv/ui/cityscreen/CityInfoTable.kt +++ b/core/src/com/unciv/ui/cityscreen/CityInfoTable.kt @@ -1,12 +1,15 @@ package com.unciv.ui.cityscreen import com.badlogic.gdx.graphics.Color -import com.badlogic.gdx.scenes.scene2d.ui.* +import com.badlogic.gdx.scenes.scene2d.Touchable +import com.badlogic.gdx.scenes.scene2d.ui.Image +import com.badlogic.gdx.scenes.scene2d.ui.Skin +import com.badlogic.gdx.scenes.scene2d.ui.Table +import com.badlogic.gdx.scenes.scene2d.ui.TextButton import com.badlogic.gdx.utils.Align import com.unciv.logic.city.CityInfo import com.unciv.logic.civilization.GreatPersonManager import com.unciv.models.gamebasics.Building -import com.unciv.models.gamebasics.tr import com.unciv.models.stats.Stat import com.unciv.models.stats.Stats import com.unciv.ui.utils.* @@ -15,15 +18,17 @@ import java.util.* class CityInfoTable(private val cityScreen: CityScreen) : Table(CameraStageBaseScreen.skin) { + val pad = 5f init { - defaults().pad(10f) + defaults().pad(pad) + width = cityScreen.stage.width/4 } internal fun update() { clear() val cityInfo = cityScreen.city - addBuildingInfo(cityInfo) + addBuildingsInfo(cityInfo) addStatInfo() @@ -32,8 +37,36 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(CameraStageBaseS pack() } + private fun addTitle(str:String) { + val titleTable = Table().background(ImageGetter.getBackground(ImageGetter.getBlue())) + titleTable.add(str.toLabel().setFontSize(22)) + add(titleTable).width(cityScreen.stage.width/4 - 2*pad).row() + } - private fun addBuildingInfo(cityInfo: CityInfo) { + fun addBuildingInfo(building: Building){ + val wonderNameAndIconTable = Table() + wonderNameAndIconTable.touchable = Touchable.enabled + wonderNameAndIconTable.add(ImageGetter.getConstructionImage(building.name).surroundWithCircle(30f)) + wonderNameAndIconTable.add(building.name.toLabel()).pad(5f) + add(wonderNameAndIconTable).pad(5f).fillX().row() + + val wonderDetailsTable = Table() + add(wonderDetailsTable).pad(5f).align(Align.left).row() + + wonderNameAndIconTable.onClick { + if(wonderDetailsTable.hasChildren()) + wonderDetailsTable.clear() + else{ + val detailsString = building.getDescription(true, + cityScreen.city.civInfo.policies.adoptedPolicies) + wonderDetailsTable.add(detailsString.toLabel().apply { setWrap(true)}) + .width(cityScreen.stage.width/4 - 2*pad ) // when you set wrap, then you need to manually set the size of the label + wonderDetailsTable.addSeparator() + } + } + } + + private fun addBuildingsInfo(cityInfo: CityInfo) { val wonders = mutableListOf() val specialistBuildings = mutableListOf() val otherBuildings = mutableListOf() @@ -47,40 +80,32 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(CameraStageBaseS } if (!wonders.isEmpty()) { - val wondersExpander = ExpanderTab("Wonders".tr(), skin) - for (building in wonders) { - wondersExpander.innerTable.add(ImageGetter.getConstructionImage(building.name).surroundWithCircle(30f)) - wondersExpander.innerTable.add(building.name.toLabel()).pad(5f).align(Align.left).row() - } - add(wondersExpander).row() + addTitle("Wonders") + for (building in wonders) addBuildingInfo(building) } if (!specialistBuildings.isEmpty()) { - val specialistBuildingsExpander = ExpanderTab("Specialist Buildings".tr(), skin) + addTitle("Specialist Buildings") + for (building in specialistBuildings) { - specialistBuildingsExpander.innerTable.add(ImageGetter.getConstructionImage(building.name).surroundWithCircle(30f)) - specialistBuildingsExpander.innerTable.add(building.name.toLabel()).pad(5f) + addBuildingInfo(building) val specialistIcons = Table() specialistIcons.row().size(20f).pad(5f) for (stat in building.specialistSlots!!.toHashMap()) for (i in 0 until stat.value.toInt()) specialistIcons.add(getSpecialistIcon(stat.key)).size(20f) - specialistBuildingsExpander.innerTable.add(specialistIcons).row() + add(specialistIcons).pad(0f).row() } - add(specialistBuildingsExpander).row() // specialist allocation addSpecialistAllocation(skin, cityInfo) } if (!otherBuildings.isEmpty()) { - val buildingsExpanderTab = ExpanderTab("Buildings".tr(), skin) - for (building in otherBuildings) { - buildingsExpanderTab.innerTable.add(ImageGetter.getConstructionImage(building.name).surroundWithCircle(30f)) - buildingsExpanderTab.innerTable.add(building.name.toLabel()).pad(5f).row() - } - add(buildingsExpanderTab).row() + + addTitle("Buildings") + for (building in wonders) addBuildingInfo(building) } } @@ -90,7 +115,6 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(CameraStageBaseS for(stats in unifiedStatList.values) stats.happiness=0f - // add happiness to stat list for(entry in cityStats.getCityHappiness().filter { it.value!=0f }){ if(!unifiedStatList.containsKey(entry.key)) @@ -99,41 +123,40 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(CameraStageBaseS } for(stat in Stat.values()){ - val expander = ExpanderTab(stat.name.tr(),skin) - expander.innerTable.defaults().pad(2f) + if(unifiedStatList.all { it.value.get(stat)==0f }) continue + addTitle(stat.name) + val statValuesTable = Table().apply { defaults().pad(2f) } for(entry in unifiedStatList) { - val specificStatValue = entry.value.toHashMap()[stat]!! + val specificStatValue = entry.value.get(stat) if(specificStatValue==0f) continue - expander.innerTable.add(entry.key.toLabel()) - expander.innerTable.add(DecimalFormat("0.#").format(specificStatValue).toLabel()).row() + statValuesTable.add(entry.key.toLabel()) + statValuesTable.add(DecimalFormat("0.#").format(specificStatValue).toLabel()).row() } for(entry in cityStats.statPercentBonusList){ val specificStatValue = entry.value.toHashMap()[stat]!! if(specificStatValue==0f) continue - expander.innerTable.add(entry.key.toLabel()) + statValuesTable.add(entry.key.toLabel()) val decimal = DecimalFormat("0.#").format(specificStatValue) - expander.innerTable.add("+$decimal%".toLabel()).row() + statValuesTable.add("+$decimal%".toLabel()).row() } if(stat==Stat.Gold){ val maintenance = cityStats.cityInfo.cityConstructions.getMaintenanceCosts() if(maintenance>0){ - expander.innerTable.add("Maintenance".toLabel()) - expander.innerTable.add("-$maintenance".toLabel()) + statValuesTable.add("Maintenance".toLabel()) + statValuesTable.add("-$maintenance".toLabel()) } } if(stat==Stat.Food){ - expander.innerTable.add("Food eaten".toLabel()) - expander.innerTable.add(DecimalFormat("0.#").format(cityStats.foodEaten).toLabel()).row() + statValuesTable.add("Food eaten".toLabel()) + statValuesTable.add(DecimalFormat("0.#").format(cityStats.foodEaten).toLabel()).row() val growthBonus = cityStats.getGrowthBonusFromPolicies() if(growthBonus>0){ - expander.innerTable.add("Growth bonus".toLabel()) - expander.innerTable.add((growthBonus*100).toInt().toString().toLabel()) + statValuesTable.add("Growth bonus".toLabel()) + statValuesTable.add((growthBonus*100).toInt().toString().toLabel()) } } - - if(expander.innerTable.hasChildren()) - add(expander).row() + add(statValuesTable).row() } } @@ -142,76 +165,74 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(CameraStageBaseS val statToGreatPerson = GreatPersonManager().statToGreatPersonMapping for (stat in Stat.values()) { if (!statToGreatPerson.containsKey(stat)) continue + if(greatPersonPoints.all { it.value.get(stat)==0f }) continue + val expanderName = "[" + statToGreatPerson[stat]!! + "] points" - val expanderTab = ExpanderTab(expanderName.tr(), skin) - expanderTab.innerTable.defaults().pad(3f) + addTitle(expanderName) + val greatPersonTable = Table() for (entry in greatPersonPoints) { val value = entry.value.toHashMap()[stat]!! if (value == 0f) continue - expanderTab.innerTable.add(entry.key.toLabel()) - expanderTab.innerTable.add(DecimalFormat("0.#").format(value).toLabel()).row() + greatPersonTable.add(entry.key.toLabel()).padRight(10f) + greatPersonTable.add(DecimalFormat("0.#").format(value).toLabel()).row() } - if (expanderTab.innerTable.hasChildren()) - add(expanderTab).row() + add(greatPersonTable).row() } } private fun addSpecialistAllocation(skin: Skin, cityInfo: CityInfo) { - val specialistAllocationExpander = ExpanderTab("Specialist Allocation".tr(), skin) - specialistAllocationExpander.innerTable.defaults().pad(5f) - + addTitle("Specialist Allocation") val currentSpecialists = cityInfo.population.specialists.toHashMap() val maximumSpecialists = cityInfo.population.getMaxSpecialists() for (statToMaximumSpecialist in maximumSpecialists.toHashMap()) { + val specialistPickerTable = Table() if (statToMaximumSpecialist.value == 0f) continue val stat = statToMaximumSpecialist.key // these two are conflictingly named compared to above... - val assignedSpecialists = currentSpecialists[statToMaximumSpecialist.key]!!.toInt() + val assignedSpecialists = currentSpecialists[stat]!!.toInt() val maxSpecialists = statToMaximumSpecialist.value.toInt() if (assignedSpecialists > 0) { val unassignButton = TextButton("-", skin) unassignButton.label.setFontSize(24) unassignButton.onClick { - cityInfo.population.specialists.add(statToMaximumSpecialist.key, -1f) + cityInfo.population.specialists.add(stat, -1f) cityInfo.cityStats.update() cityScreen.update() } - specialistAllocationExpander.innerTable.add(unassignButton) - } else specialistAllocationExpander.innerTable.add() + specialistPickerTable.add(unassignButton) + } else specialistPickerTable.add() - val specialistTable = Table() + val specialistIconTable = Table() for (i in 1..maxSpecialists) { val icon = getSpecialistIcon(stat, i <= assignedSpecialists) - specialistTable.add(icon).size(30f) + specialistIconTable.add(icon).size(30f) } - specialistAllocationExpander.innerTable.add(specialistTable) + specialistPickerTable.add(specialistIconTable) if (assignedSpecialists < maxSpecialists) { val assignButton = TextButton("+", skin) assignButton.label.setFontSize(24) assignButton.onClick { - cityInfo.population.specialists.add(statToMaximumSpecialist.key, +1f) + cityInfo.population.specialists.add(statToMaximumSpecialist.key, 1f) cityInfo.cityStats.update() cityScreen.update() } - if (cityInfo.population.getFreePopulation() == 0) assignButton.disable() - specialistAllocationExpander.innerTable.add(assignButton) - } else specialistAllocationExpander.innerTable.add() - - specialistAllocationExpander.innerTable.row() + if (cityInfo.population.getFreePopulation() == 0) + assignButton.disable() + specialistPickerTable.add(assignButton) + } else specialistPickerTable.add() + add(specialistPickerTable).row() val specialistStatTable = Table().apply { defaults().pad(5f) } val specialistStats = cityInfo.cityStats.getStatsOfSpecialist(stat, cityInfo.civInfo.policies.adoptedPolicies).toHashMap() for (entry in specialistStats) { if (entry.value == 0f) continue specialistStatTable.add(ImageGetter.getStatIcon(entry.key.toString())).size(20f) - specialistStatTable.add(Label(entry.value.toInt().toString(), skin)).padRight(10f) + specialistStatTable.add(entry.value.toInt().toString().toLabel()).padRight(10f) } - specialistAllocationExpander.innerTable.add() - specialistAllocationExpander.innerTable.add(specialistStatTable).row() + add(specialistStatTable).row() } - add(specialistAllocationExpander).row() } private fun getSpecialistIcon(stat: Stat, isFilled: Boolean =true): Image { diff --git a/core/src/com/unciv/ui/cityscreen/CityScreen.kt b/core/src/com/unciv/ui/cityscreen/CityScreen.kt index 7143abc8a6..a758aef033 100644 --- a/core/src/com/unciv/ui/cityscreen/CityScreen.kt +++ b/core/src/com/unciv/ui/cityscreen/CityScreen.kt @@ -27,7 +27,7 @@ class CityScreen(internal val city: CityInfo) : CameraStageBaseScreen() { private var razeCityButtonHolder = Table() // sits on the top - /** Displays buildings, specialists and stats drilldown - sits on the top left of the city screen */ + /** Displays buildings, specialists and stats drilldown - sits on the top right of the city screen */ private var cityInfoTable = CityInfoTable(this) /** Displays tile info, sits on the bottom right */ @@ -53,7 +53,7 @@ class CityScreen(internal val city: CityInfo) : CameraStageBaseScreen() { cityInfoTable.update() val buildingsScroll = ScrollPane(cityInfoTable) buildingsTableContainer.add(buildingsScroll) - .height(stage.height / 2) + .size(stage.width/4,stage.height / 2) buildingsTableContainer = buildingsTableContainer.addBorder(2f, Color.WHITE) buildingsTableContainer.setPosition(stage.width - buildingsTableContainer.width-5,