diff --git a/core/src/com/unciv/ui/cityscreen/CityInfoTable.kt b/core/src/com/unciv/ui/cityscreen/CityInfoTable.kt index 17b971d64e..3947047f94 100644 --- a/core/src/com/unciv/ui/cityscreen/CityInfoTable.kt +++ b/core/src/com/unciv/ui/cityscreen/CityInfoTable.kt @@ -2,7 +2,9 @@ package com.unciv.ui.cityscreen import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.scenes.scene2d.Touchable -import com.badlogic.gdx.scenes.scene2d.ui.* +import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane +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.UncivGame import com.unciv.logic.city.CityInfo @@ -11,7 +13,6 @@ import com.unciv.models.ruleset.Building import com.unciv.models.stats.Stat import com.unciv.models.translations.tr import com.unciv.ui.utils.* -import com.unciv.ui.utils.YesNoPopup import java.text.DecimalFormat class CityInfoTable(private val cityScreen: CityScreen) : Table(CameraStageBaseScreen.skin) { @@ -134,13 +135,13 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(CameraStageBaseS 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) + specialistIcons.add(ImageGetter.getSpecialistIcon(stat.key)).size(20f) specialistBuildingsTable.add(specialistIcons).pad(0f).row() } // specialist allocation - addSpecialistAllocation(skin, cityInfo) +// addCategory("Specialist Allocation", SpecialistAllocationTable(cityScreen)) todo } if (!otherBuildings.isEmpty()) { @@ -226,74 +227,5 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(CameraStageBaseS } } - private fun Table.addSpecialistAllocation(skin: Skin, cityInfo: CityInfo) { - val specialistAllocationTable = Table() - addCategory("Specialist Allocation", specialistAllocationTable) // todo WRONG, BAD - table should contain all the below specialist stuff - - 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[stat]!!.toInt() - val maxSpecialists = statToMaximumSpecialist.value.toInt() - if (assignedSpecialists > 0 && !cityInfo.isPuppet) { - val unassignButton = TextButton("-", skin) - unassignButton.label.setFontSize(24) - unassignButton.onClick { - cityInfo.population.specialists.add(stat, -1f) - cityInfo.cityStats.update() - cityScreen.update() - } - if(!UncivGame.Current.worldScreen.isPlayersTurn) unassignButton.disable() - specialistPickerTable.add(unassignButton) - } else specialistPickerTable.add() - - val specialistIconTable = Table() - for (i in 1..maxSpecialists) { - val icon = getSpecialistIcon(stat, i <= assignedSpecialists) - specialistIconTable.add(icon).size(30f) - } - specialistPickerTable.add(specialistIconTable) - if (assignedSpecialists < maxSpecialists && !cityInfo.isPuppet) { - val assignButton = TextButton("+", skin) - assignButton.label.setFontSize(24) - assignButton.onClick { - cityInfo.population.specialists.add(statToMaximumSpecialist.key, 1f) - cityInfo.cityStats.update() - cityScreen.update() - } - if (cityInfo.population.getFreePopulation() == 0 || !UncivGame.Current.worldScreen.isPlayersTurn) - assignButton.disable() - specialistPickerTable.add(assignButton) - } else specialistPickerTable.add() - specialistAllocationTable.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(entry.value.toInt().toString().toLabel()).padRight(10f) - } - specialistAllocationTable.add(specialistStatTable).row() - } - } - - private fun getSpecialistIcon(stat: Stat, isFilled: Boolean =true): Image { - val specialist = ImageGetter.getImage("StatIcons/Specialist") - if (!isFilled) specialist.color = Color.GRAY - else specialist.color=when(stat){ - Stat.Production -> Color.BROWN - Stat.Gold -> Color.GOLD - Stat.Science -> Color.BLUE - Stat.Culture -> Color.PURPLE - else -> Color.WHITE - } - - return specialist - } } + diff --git a/core/src/com/unciv/ui/cityscreen/CityScreen.kt b/core/src/com/unciv/ui/cityscreen/CityScreen.kt index fb08c51ef4..84b0272c41 100644 --- a/core/src/com/unciv/ui/cityscreen/CityScreen.kt +++ b/core/src/com/unciv/ui/cityscreen/CityScreen.kt @@ -37,6 +37,9 @@ class CityScreen(internal val city: CityInfo): CameraStageBaseScreen() { /** Displays city stats info */ private var cityStatsTable = CityStatsTable(this.city) + /** Displays specialist allocation */ + private var specialistAllocationTable=SpecialistAllocationTable(this) + /** Displays tile info, alternate with selectedConstructionTable - sits on BOTTOM RIGHT */ private var tileTable = CityScreenTileTable(city) @@ -57,6 +60,7 @@ class CityScreen(internal val city: CityInfo): CameraStageBaseScreen() { //stage.setDebugTableUnderMouse(true) stage.addActor(cityStatsTable) + stage.addActor(specialistAllocationTable) stage.addActor(constructionsTable) stage.addActor(tileTable) stage.addActor(selectedConstructionTable) @@ -93,6 +97,8 @@ class CityScreen(internal val city: CityInfo): CameraStageBaseScreen() { cityStatsTable.update() cityStatsTable.setPosition( stage.width - 5f, stage.height - 5f, Align.topRight) + specialistAllocationTable.update() + specialistAllocationTable.setPosition(stage.width-5, cityStatsTable.y, Align.topRight) updateAnnexAndRazeCityButton() updateTileGroups() @@ -155,19 +161,18 @@ class CityScreen(internal val city: CityInfo): CameraStageBaseScreen() { val tileInfo = tileGroup.tileInfo tileGroup.onClick { - if (!city.isPuppet) { - selectedTile = tileInfo - selectedConstruction = null - if (tileGroup.isWorkable && UncivGame.Current.worldScreen.isPlayersTurn) { - if (!tileInfo.isWorked() && city.population.getFreePopulation() > 0) { - city.workedTiles.add(tileInfo.position) - game.settings.addCompletedTutorialTask("Reassign worked tiles") - } - else if (tileInfo.isWorked()) city.workedTiles.remove(tileInfo.position) - city.cityStats.update() - } - update() + if (city.isPuppet) return@onClick + + selectedTile = tileInfo + selectedConstruction = null + if (tileGroup.isWorkable && UncivGame.Current.worldScreen.isPlayersTurn) { + if (!tileInfo.isWorked() && city.population.getFreePopulation() > 0) { + city.workedTiles.add(tileInfo.position) + game.settings.addCompletedTutorialTask("Reassign worked tiles") + } else if (tileInfo.isWorked()) city.workedTiles.remove(tileInfo.position) + city.cityStats.update() } + update() } tileGroups.add(tileGroup) diff --git a/core/src/com/unciv/ui/cityscreen/CityScreenTileTable.kt b/core/src/com/unciv/ui/cityscreen/CityScreenTileTable.kt index 83e2cc44e4..110fe0e69e 100644 --- a/core/src/com/unciv/ui/cityscreen/CityScreenTileTable.kt +++ b/core/src/com/unciv/ui/cityscreen/CityScreenTileTable.kt @@ -7,8 +7,10 @@ import com.unciv.UncivGame import com.unciv.logic.city.CityInfo import com.unciv.logic.map.TileInfo import com.unciv.models.UncivSound +import com.unciv.models.stats.Stats import com.unciv.models.translations.tr import com.unciv.ui.utils.* +import kotlin.math.roundToInt class CityScreenTileTable(val city: CityInfo): Table(){ val innerTable = Table() @@ -32,15 +34,8 @@ class CityScreenTileTable(val city: CityInfo): Table(){ innerTable.add(selectedTile.toString().toLabel()).colspan(2) innerTable.row() + innerTable.add(getTileStatsTable(stats)).row() - val statsTable = Table() - statsTable.defaults().pad(2f) - for (entry in stats.toHashMap().filterNot { it.value==0f }) { - statsTable.add(ImageGetter.getStatIcon(entry.key.toString())).size(20f) - statsTable.add(Math.round(entry.value).toString().toLabel()) - statsTable.row() - } - innerTable.add(statsTable).row() if(selectedTile.getOwner()==null && selectedTile.neighbors.any {it.getCity()==city} && selectedTile in city.tilesInRange){ @@ -67,4 +62,15 @@ class CityScreenTileTable(val city: CityInfo): Table(){ innerTable.pack() pack() } + + private fun getTileStatsTable(stats: Stats): Table { + val statsTable = Table() + statsTable.defaults().pad(2f) + for (entry in stats.toHashMap().filterNot { it.value == 0f }) { + statsTable.add(ImageGetter.getStatIcon(entry.key.toString())).size(20f) + statsTable.add(entry.value.roundToInt().toString().toLabel()) + statsTable.row() + } + return statsTable + } } \ No newline at end of file diff --git a/core/src/com/unciv/ui/cityscreen/SpecialistAllocationTable.kt b/core/src/com/unciv/ui/cityscreen/SpecialistAllocationTable.kt new file mode 100644 index 0000000000..0a4900ddcd --- /dev/null +++ b/core/src/com/unciv/ui/cityscreen/SpecialistAllocationTable.kt @@ -0,0 +1,89 @@ +package com.unciv.ui.cityscreen + +import com.badlogic.gdx.graphics.Color +import com.badlogic.gdx.scenes.scene2d.Actor +import com.badlogic.gdx.scenes.scene2d.ui.Table +import com.badlogic.gdx.scenes.scene2d.ui.TextButton +import com.unciv.UncivGame +import com.unciv.models.stats.Stat +import com.unciv.ui.utils.* + +class SpecialistAllocationTable(val cityScreen: CityScreen): Table(CameraStageBaseScreen.skin){ + val cityInfo = cityScreen.city + + fun update() { + background = ImageGetter.getBackground(Color.BLACK.cpy().apply { a=0.7f }) + clear() + + for (statToMaximumSpecialist in cityInfo.population.getMaxSpecialists().toHashMap()) { + if (statToMaximumSpecialist.value == 0f) continue + + val stat = statToMaximumSpecialist.key + add(getAllocationTable(stat)).pad(10f) + addSeparatorVertical().pad(5f) + add(getSpecialistStatsTable(stat)).row() + } + pack() + } + + + fun getAllocationTable(stat: Stat):Table{ + val specialistPickerTable = Table() + + val assignedSpecialists = cityInfo.population.specialists.get(stat).toInt() + val maxSpecialists = cityInfo.population.getMaxSpecialists().get(stat).toInt() + + specialistPickerTable.add(getUnassignButton(assignedSpecialists, stat)) + + val specialistIconTable = Table() + for (i in 1..maxSpecialists) { + val icon = ImageGetter.getSpecialistIcon(stat, i <= assignedSpecialists) + specialistIconTable.add(icon).size(30f) + } + specialistPickerTable.add(specialistIconTable) + + specialistPickerTable.add(getAssignButton(assignedSpecialists, maxSpecialists, stat)) + + return specialistPickerTable + } + + private fun getAssignButton(assignedSpecialists: Int, maxSpecialists: Int, stat: Stat):Actor { + if (assignedSpecialists >= maxSpecialists || cityInfo.isPuppet) return Table() + val assignButton = TextButton("+", skin) + assignButton.label.setFontSize(24) + assignButton.onClick { + cityInfo.population.specialists.add(stat, 1f) + cityInfo.cityStats.update() + cityScreen.update() + } + if (cityInfo.population.getFreePopulation() == 0 || !UncivGame.Current.worldScreen.isPlayersTurn) + assignButton.disable() + return assignButton + } + + private fun getUnassignButton(assignedSpecialists: Int, stat: Stat):Actor { + if (assignedSpecialists <= 0 || cityInfo.isPuppet) return Table() + + val unassignButton = TextButton("-", skin) + unassignButton.label.setFontSize(24) + unassignButton.onClick { + cityInfo.population.specialists.add(stat, -1f) + cityInfo.cityStats.update() + cityScreen.update() + } + if (!UncivGame.Current.worldScreen.isPlayersTurn) unassignButton.disable() + return unassignButton + } + + + private fun getSpecialistStatsTable(stat: Stat): Table { + 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(entry.value.toInt().toString().toLabel()).padRight(10f) + } + return specialistStatTable + } +} \ No newline at end of file diff --git a/core/src/com/unciv/ui/utils/ImageGetter.kt b/core/src/com/unciv/ui/utils/ImageGetter.kt index bf7c824cfe..afb0371b2e 100644 --- a/core/src/com/unciv/ui/utils/ImageGetter.kt +++ b/core/src/com/unciv/ui/utils/ImageGetter.kt @@ -15,6 +15,7 @@ import com.badlogic.gdx.utils.Align import com.unciv.models.ruleset.Nation import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.tile.ResourceType +import com.unciv.models.stats.Stat object ImageGetter { private const val whiteDotLocation = "OtherIcons/whiteDot" @@ -288,5 +289,19 @@ object ImageGetter { return line } + + fun getSpecialistIcon(stat: Stat, isFilled: Boolean =true): Image { + val specialist = getImage("StatIcons/Specialist") + if (!isFilled) specialist.color = Color.GRAY + else specialist.color=when(stat){ + Stat.Production -> Color.BROWN + Stat.Gold -> Color.GOLD + Stat.Science -> Color.BLUE + Stat.Culture -> Color.PURPLE + else -> Color.WHITE + } + + return specialist + } }