mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-29 15:01:09 -04: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:
parent
6f46750c15
commit
f15490d0ac
@ -74,6 +74,10 @@ open class Stats() {
|
|||||||
Stat.Science to science)
|
Stat.Science to science)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun get(stat:Stat):Float{
|
||||||
|
return this.toHashMap()[stat]!!
|
||||||
|
}
|
||||||
|
|
||||||
private fun setStats(hashMap:HashMap<Stat, Float>){
|
private fun setStats(hashMap:HashMap<Stat, Float>){
|
||||||
culture=hashMap[Stat.Culture]!!
|
culture=hashMap[Stat.Culture]!!
|
||||||
gold=hashMap[Stat.Gold]!!
|
gold=hashMap[Stat.Gold]!!
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
package com.unciv.ui.cityscreen
|
package com.unciv.ui.cityscreen
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color
|
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.badlogic.gdx.utils.Align
|
||||||
import com.unciv.logic.city.CityInfo
|
import com.unciv.logic.city.CityInfo
|
||||||
import com.unciv.logic.civilization.GreatPersonManager
|
import com.unciv.logic.civilization.GreatPersonManager
|
||||||
import com.unciv.models.gamebasics.Building
|
import com.unciv.models.gamebasics.Building
|
||||||
import com.unciv.models.gamebasics.tr
|
|
||||||
import com.unciv.models.stats.Stat
|
import com.unciv.models.stats.Stat
|
||||||
import com.unciv.models.stats.Stats
|
import com.unciv.models.stats.Stats
|
||||||
import com.unciv.ui.utils.*
|
import com.unciv.ui.utils.*
|
||||||
@ -15,15 +18,17 @@ import java.util.*
|
|||||||
|
|
||||||
|
|
||||||
class CityInfoTable(private val cityScreen: CityScreen) : Table(CameraStageBaseScreen.skin) {
|
class CityInfoTable(private val cityScreen: CityScreen) : Table(CameraStageBaseScreen.skin) {
|
||||||
|
val pad = 5f
|
||||||
init {
|
init {
|
||||||
defaults().pad(10f)
|
defaults().pad(pad)
|
||||||
|
width = cityScreen.stage.width/4
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun update() {
|
internal fun update() {
|
||||||
clear()
|
clear()
|
||||||
val cityInfo = cityScreen.city
|
val cityInfo = cityScreen.city
|
||||||
|
|
||||||
addBuildingInfo(cityInfo)
|
addBuildingsInfo(cityInfo)
|
||||||
|
|
||||||
addStatInfo()
|
addStatInfo()
|
||||||
|
|
||||||
@ -32,8 +37,36 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(CameraStageBaseS
|
|||||||
pack()
|
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 wonders = mutableListOf<Building>()
|
||||||
val specialistBuildings = mutableListOf<Building>()
|
val specialistBuildings = mutableListOf<Building>()
|
||||||
val otherBuildings = mutableListOf<Building>()
|
val otherBuildings = mutableListOf<Building>()
|
||||||
@ -47,40 +80,32 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(CameraStageBaseS
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!wonders.isEmpty()) {
|
if (!wonders.isEmpty()) {
|
||||||
val wondersExpander = ExpanderTab("Wonders".tr(), skin)
|
addTitle("Wonders")
|
||||||
for (building in wonders) {
|
for (building in wonders) addBuildingInfo(building)
|
||||||
wondersExpander.innerTable.add(ImageGetter.getConstructionImage(building.name).surroundWithCircle(30f))
|
|
||||||
wondersExpander.innerTable.add(building.name.toLabel()).pad(5f).align(Align.left).row()
|
|
||||||
}
|
|
||||||
add(wondersExpander).row()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!specialistBuildings.isEmpty()) {
|
if (!specialistBuildings.isEmpty()) {
|
||||||
val specialistBuildingsExpander = ExpanderTab("Specialist Buildings".tr(), skin)
|
addTitle("Specialist Buildings")
|
||||||
|
|
||||||
for (building in specialistBuildings) {
|
for (building in specialistBuildings) {
|
||||||
specialistBuildingsExpander.innerTable.add(ImageGetter.getConstructionImage(building.name).surroundWithCircle(30f))
|
addBuildingInfo(building)
|
||||||
specialistBuildingsExpander.innerTable.add(building.name.toLabel()).pad(5f)
|
|
||||||
val specialistIcons = Table()
|
val specialistIcons = Table()
|
||||||
specialistIcons.row().size(20f).pad(5f)
|
specialistIcons.row().size(20f).pad(5f)
|
||||||
for (stat in building.specialistSlots!!.toHashMap())
|
for (stat in building.specialistSlots!!.toHashMap())
|
||||||
for (i in 0 until stat.value.toInt())
|
for (i in 0 until stat.value.toInt())
|
||||||
specialistIcons.add(getSpecialistIcon(stat.key)).size(20f)
|
specialistIcons.add(getSpecialistIcon(stat.key)).size(20f)
|
||||||
|
|
||||||
specialistBuildingsExpander.innerTable.add(specialistIcons).row()
|
add(specialistIcons).pad(0f).row()
|
||||||
}
|
}
|
||||||
add(specialistBuildingsExpander).row()
|
|
||||||
|
|
||||||
// specialist allocation
|
// specialist allocation
|
||||||
addSpecialistAllocation(skin, cityInfo)
|
addSpecialistAllocation(skin, cityInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!otherBuildings.isEmpty()) {
|
if (!otherBuildings.isEmpty()) {
|
||||||
val buildingsExpanderTab = ExpanderTab("Buildings".tr(), skin)
|
|
||||||
for (building in otherBuildings) {
|
addTitle("Buildings")
|
||||||
buildingsExpanderTab.innerTable.add(ImageGetter.getConstructionImage(building.name).surroundWithCircle(30f))
|
for (building in wonders) addBuildingInfo(building)
|
||||||
buildingsExpanderTab.innerTable.add(building.name.toLabel()).pad(5f).row()
|
|
||||||
}
|
|
||||||
add(buildingsExpanderTab).row()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +115,6 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(CameraStageBaseS
|
|||||||
|
|
||||||
for(stats in unifiedStatList.values) stats.happiness=0f
|
for(stats in unifiedStatList.values) stats.happiness=0f
|
||||||
|
|
||||||
|
|
||||||
// add happiness to stat list
|
// add happiness to stat list
|
||||||
for(entry in cityStats.getCityHappiness().filter { it.value!=0f }){
|
for(entry in cityStats.getCityHappiness().filter { it.value!=0f }){
|
||||||
if(!unifiedStatList.containsKey(entry.key))
|
if(!unifiedStatList.containsKey(entry.key))
|
||||||
@ -99,41 +123,40 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(CameraStageBaseS
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(stat in Stat.values()){
|
for(stat in Stat.values()){
|
||||||
val expander = ExpanderTab(stat.name.tr(),skin)
|
if(unifiedStatList.all { it.value.get(stat)==0f }) continue
|
||||||
expander.innerTable.defaults().pad(2f)
|
|
||||||
|
|
||||||
|
addTitle(stat.name)
|
||||||
|
val statValuesTable = Table().apply { defaults().pad(2f) }
|
||||||
for(entry in unifiedStatList) {
|
for(entry in unifiedStatList) {
|
||||||
val specificStatValue = entry.value.toHashMap()[stat]!!
|
val specificStatValue = entry.value.get(stat)
|
||||||
if(specificStatValue==0f) continue
|
if(specificStatValue==0f) continue
|
||||||
expander.innerTable.add(entry.key.toLabel())
|
statValuesTable.add(entry.key.toLabel())
|
||||||
expander.innerTable.add(DecimalFormat("0.#").format(specificStatValue).toLabel()).row()
|
statValuesTable.add(DecimalFormat("0.#").format(specificStatValue).toLabel()).row()
|
||||||
}
|
}
|
||||||
for(entry in cityStats.statPercentBonusList){
|
for(entry in cityStats.statPercentBonusList){
|
||||||
val specificStatValue = entry.value.toHashMap()[stat]!!
|
val specificStatValue = entry.value.toHashMap()[stat]!!
|
||||||
if(specificStatValue==0f) continue
|
if(specificStatValue==0f) continue
|
||||||
expander.innerTable.add(entry.key.toLabel())
|
statValuesTable.add(entry.key.toLabel())
|
||||||
val decimal = DecimalFormat("0.#").format(specificStatValue)
|
val decimal = DecimalFormat("0.#").format(specificStatValue)
|
||||||
expander.innerTable.add("+$decimal%".toLabel()).row()
|
statValuesTable.add("+$decimal%".toLabel()).row()
|
||||||
}
|
}
|
||||||
if(stat==Stat.Gold){
|
if(stat==Stat.Gold){
|
||||||
val maintenance = cityStats.cityInfo.cityConstructions.getMaintenanceCosts()
|
val maintenance = cityStats.cityInfo.cityConstructions.getMaintenanceCosts()
|
||||||
if(maintenance>0){
|
if(maintenance>0){
|
||||||
expander.innerTable.add("Maintenance".toLabel())
|
statValuesTable.add("Maintenance".toLabel())
|
||||||
expander.innerTable.add("-$maintenance".toLabel())
|
statValuesTable.add("-$maintenance".toLabel())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(stat==Stat.Food){
|
if(stat==Stat.Food){
|
||||||
expander.innerTable.add("Food eaten".toLabel())
|
statValuesTable.add("Food eaten".toLabel())
|
||||||
expander.innerTable.add(DecimalFormat("0.#").format(cityStats.foodEaten).toLabel()).row()
|
statValuesTable.add(DecimalFormat("0.#").format(cityStats.foodEaten).toLabel()).row()
|
||||||
val growthBonus = cityStats.getGrowthBonusFromPolicies()
|
val growthBonus = cityStats.getGrowthBonusFromPolicies()
|
||||||
if(growthBonus>0){
|
if(growthBonus>0){
|
||||||
expander.innerTable.add("Growth bonus".toLabel())
|
statValuesTable.add("Growth bonus".toLabel())
|
||||||
expander.innerTable.add((growthBonus*100).toInt().toString().toLabel())
|
statValuesTable.add((growthBonus*100).toInt().toString().toLabel())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
add(statValuesTable).row()
|
||||||
if(expander.innerTable.hasChildren())
|
|
||||||
add(expander).row()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,76 +165,74 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(CameraStageBaseS
|
|||||||
val statToGreatPerson = GreatPersonManager().statToGreatPersonMapping
|
val statToGreatPerson = GreatPersonManager().statToGreatPersonMapping
|
||||||
for (stat in Stat.values()) {
|
for (stat in Stat.values()) {
|
||||||
if (!statToGreatPerson.containsKey(stat)) continue
|
if (!statToGreatPerson.containsKey(stat)) continue
|
||||||
|
if(greatPersonPoints.all { it.value.get(stat)==0f }) continue
|
||||||
|
|
||||||
val expanderName = "[" + statToGreatPerson[stat]!! + "] points"
|
val expanderName = "[" + statToGreatPerson[stat]!! + "] points"
|
||||||
val expanderTab = ExpanderTab(expanderName.tr(), skin)
|
addTitle(expanderName)
|
||||||
expanderTab.innerTable.defaults().pad(3f)
|
val greatPersonTable = Table()
|
||||||
for (entry in greatPersonPoints) {
|
for (entry in greatPersonPoints) {
|
||||||
val value = entry.value.toHashMap()[stat]!!
|
val value = entry.value.toHashMap()[stat]!!
|
||||||
if (value == 0f) continue
|
if (value == 0f) continue
|
||||||
expanderTab.innerTable.add(entry.key.toLabel())
|
greatPersonTable.add(entry.key.toLabel()).padRight(10f)
|
||||||
expanderTab.innerTable.add(DecimalFormat("0.#").format(value).toLabel()).row()
|
greatPersonTable.add(DecimalFormat("0.#").format(value).toLabel()).row()
|
||||||
}
|
}
|
||||||
if (expanderTab.innerTable.hasChildren())
|
add(greatPersonTable).row()
|
||||||
add(expanderTab).row()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addSpecialistAllocation(skin: Skin, cityInfo: CityInfo) {
|
private fun addSpecialistAllocation(skin: Skin, cityInfo: CityInfo) {
|
||||||
val specialistAllocationExpander = ExpanderTab("Specialist Allocation".tr(), skin)
|
addTitle("Specialist Allocation")
|
||||||
specialistAllocationExpander.innerTable.defaults().pad(5f)
|
|
||||||
|
|
||||||
|
|
||||||
val currentSpecialists = cityInfo.population.specialists.toHashMap()
|
val currentSpecialists = cityInfo.population.specialists.toHashMap()
|
||||||
val maximumSpecialists = cityInfo.population.getMaxSpecialists()
|
val maximumSpecialists = cityInfo.population.getMaxSpecialists()
|
||||||
|
|
||||||
for (statToMaximumSpecialist in maximumSpecialists.toHashMap()) {
|
for (statToMaximumSpecialist in maximumSpecialists.toHashMap()) {
|
||||||
|
val specialistPickerTable = Table()
|
||||||
if (statToMaximumSpecialist.value == 0f) continue
|
if (statToMaximumSpecialist.value == 0f) continue
|
||||||
val stat = statToMaximumSpecialist.key
|
val stat = statToMaximumSpecialist.key
|
||||||
// these two are conflictingly named compared to above...
|
// these two are conflictingly named compared to above...
|
||||||
val assignedSpecialists = currentSpecialists[statToMaximumSpecialist.key]!!.toInt()
|
val assignedSpecialists = currentSpecialists[stat]!!.toInt()
|
||||||
val maxSpecialists = statToMaximumSpecialist.value.toInt()
|
val maxSpecialists = statToMaximumSpecialist.value.toInt()
|
||||||
if (assignedSpecialists > 0) {
|
if (assignedSpecialists > 0) {
|
||||||
val unassignButton = TextButton("-", skin)
|
val unassignButton = TextButton("-", skin)
|
||||||
unassignButton.label.setFontSize(24)
|
unassignButton.label.setFontSize(24)
|
||||||
unassignButton.onClick {
|
unassignButton.onClick {
|
||||||
cityInfo.population.specialists.add(statToMaximumSpecialist.key, -1f)
|
cityInfo.population.specialists.add(stat, -1f)
|
||||||
cityInfo.cityStats.update()
|
cityInfo.cityStats.update()
|
||||||
cityScreen.update()
|
cityScreen.update()
|
||||||
}
|
}
|
||||||
specialistAllocationExpander.innerTable.add(unassignButton)
|
specialistPickerTable.add(unassignButton)
|
||||||
} else specialistAllocationExpander.innerTable.add()
|
} else specialistPickerTable.add()
|
||||||
|
|
||||||
val specialistTable = Table()
|
val specialistIconTable = Table()
|
||||||
for (i in 1..maxSpecialists) {
|
for (i in 1..maxSpecialists) {
|
||||||
val icon = getSpecialistIcon(stat, i <= assignedSpecialists)
|
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) {
|
if (assignedSpecialists < maxSpecialists) {
|
||||||
val assignButton = TextButton("+", skin)
|
val assignButton = TextButton("+", skin)
|
||||||
assignButton.label.setFontSize(24)
|
assignButton.label.setFontSize(24)
|
||||||
assignButton.onClick {
|
assignButton.onClick {
|
||||||
cityInfo.population.specialists.add(statToMaximumSpecialist.key, +1f)
|
cityInfo.population.specialists.add(statToMaximumSpecialist.key, 1f)
|
||||||
cityInfo.cityStats.update()
|
cityInfo.cityStats.update()
|
||||||
cityScreen.update()
|
cityScreen.update()
|
||||||
}
|
}
|
||||||
if (cityInfo.population.getFreePopulation() == 0) assignButton.disable()
|
if (cityInfo.population.getFreePopulation() == 0)
|
||||||
specialistAllocationExpander.innerTable.add(assignButton)
|
assignButton.disable()
|
||||||
} else specialistAllocationExpander.innerTable.add()
|
specialistPickerTable.add(assignButton)
|
||||||
|
} else specialistPickerTable.add()
|
||||||
specialistAllocationExpander.innerTable.row()
|
add(specialistPickerTable).row()
|
||||||
|
|
||||||
val specialistStatTable = Table().apply { defaults().pad(5f) }
|
val specialistStatTable = Table().apply { defaults().pad(5f) }
|
||||||
val specialistStats = cityInfo.cityStats.getStatsOfSpecialist(stat, cityInfo.civInfo.policies.adoptedPolicies).toHashMap()
|
val specialistStats = cityInfo.cityStats.getStatsOfSpecialist(stat, cityInfo.civInfo.policies.adoptedPolicies).toHashMap()
|
||||||
for (entry in specialistStats) {
|
for (entry in specialistStats) {
|
||||||
if (entry.value == 0f) continue
|
if (entry.value == 0f) continue
|
||||||
specialistStatTable.add(ImageGetter.getStatIcon(entry.key.toString())).size(20f)
|
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()
|
add(specialistStatTable).row()
|
||||||
specialistAllocationExpander.innerTable.add(specialistStatTable).row()
|
|
||||||
}
|
}
|
||||||
add(specialistAllocationExpander).row()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSpecialistIcon(stat: Stat, isFilled: Boolean =true): Image {
|
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
|
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)
|
private var cityInfoTable = CityInfoTable(this)
|
||||||
|
|
||||||
/** Displays tile info, sits on the bottom right */
|
/** Displays tile info, sits on the bottom right */
|
||||||
@ -53,7 +53,7 @@ class CityScreen(internal val city: CityInfo) : CameraStageBaseScreen() {
|
|||||||
cityInfoTable.update()
|
cityInfoTable.update()
|
||||||
val buildingsScroll = ScrollPane(cityInfoTable)
|
val buildingsScroll = ScrollPane(cityInfoTable)
|
||||||
buildingsTableContainer.add(buildingsScroll)
|
buildingsTableContainer.add(buildingsScroll)
|
||||||
.height(stage.height / 2)
|
.size(stage.width/4,stage.height / 2)
|
||||||
|
|
||||||
buildingsTableContainer = buildingsTableContainer.addBorder(2f, Color.WHITE)
|
buildingsTableContainer = buildingsTableContainer.addBorder(2f, Color.WHITE)
|
||||||
buildingsTableContainer.setPosition(stage.width - buildingsTableContainer.width-5,
|
buildingsTableContainer.setPosition(stage.width - buildingsTableContainer.width-5,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user