mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-22 22:00:24 +07:00
Resolved #470 - can now click on a building in the city info table to display its effect
Organized city info table
This commit is contained in:
@ -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<Stat, Float>){
|
||||
culture=hashMap[Stat.Culture]!!
|
||||
gold=hashMap[Stat.Gold]!!
|
||||
|
@ -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<Building>()
|
||||
val specialistBuildings = mutableListOf<Building>()
|
||||
val otherBuildings = mutableListOf<Building>()
|
||||
@ -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 {
|
||||
|
@ -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,
|
||||
|
Reference in New Issue
Block a user