It's now much easier to enter a city by clicking on the city button
This commit is contained in:
parent
9590d9890b
commit
fad7df055b
5 changed files with 178 additions and 150 deletions
108
core/src/com/unciv/ui/tilegroups/CityButton.kt
Normal file
108
core/src/com/unciv/ui/tilegroups/CityButton.kt
Normal file
|
@ -0,0 +1,108 @@
|
|||
package com.unciv.ui.tilegroups
|
||||
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.scenes.scene2d.Group
|
||||
import com.badlogic.gdx.scenes.scene2d.Touchable
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Skin
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.UnCivGame
|
||||
import com.unciv.logic.city.CityConstructions
|
||||
import com.unciv.logic.city.CityInfo
|
||||
import com.unciv.logic.city.SpecialConstruction
|
||||
import com.unciv.logic.map.RoadStatus
|
||||
import com.unciv.ui.cityscreen.CityScreen
|
||||
import com.unciv.ui.utils.*
|
||||
|
||||
class CityButton(val city: CityInfo, skin: Skin): Table(skin){
|
||||
init{
|
||||
background = ImageGetter.getDrawable("OtherIcons/civTableBackground.png")
|
||||
.tint(city.civInfo.getNation().getColor())
|
||||
isTransform = true // If this is not set then the city button won't scale!
|
||||
touchable= Touchable.enabled // So you can click anywhere on the button to go to the city
|
||||
}
|
||||
|
||||
fun update(isCityViewable:Boolean) {
|
||||
val cityButtonText = city.population.population.toString() + " | " + city.name
|
||||
val label = Label(cityButtonText, CameraStageBaseScreen.skin)
|
||||
label.setFontColor(city.civInfo.getNation().getSecondaryColor())
|
||||
|
||||
clear()
|
||||
if (city.civInfo.isPlayerCivilization()) {
|
||||
onClick {
|
||||
UnCivGame.Current.screen = CityScreen(city)
|
||||
}
|
||||
}
|
||||
|
||||
if (isCityViewable && city.health < city.getMaxHealth().toFloat()) {
|
||||
val healthBar = ImageGetter.getHealthBar(city.health.toFloat(), city.getMaxHealth().toFloat(), 100f)
|
||||
add(healthBar).colspan(3).row()
|
||||
}
|
||||
|
||||
if (city.isBeingRazed) {
|
||||
val fireImage = ImageGetter.getImage("OtherIcons/Fire.png")
|
||||
add(fireImage).size(20f).pad(2f).padLeft(5f)
|
||||
}
|
||||
if (city.isCapital()) {
|
||||
val starImage = ImageGetter.getImage("OtherIcons/Star.png").apply { color = Color.LIGHT_GRAY }
|
||||
add(starImage).size(20f).pad(2f).padLeft(5f)
|
||||
} else if (city.civInfo.isPlayerCivilization() && city.cityStats.isConnectedToCapital(RoadStatus.Road)) {
|
||||
val connectionImage = ImageGetter.getStatIcon("CityConnection")
|
||||
add(connectionImage).size(20f).pad(2f).padLeft(5f)
|
||||
} else {
|
||||
add()
|
||||
} // this is so the health bar is always 2 columns wide
|
||||
add(label).pad(10f)
|
||||
if (city.civInfo.isPlayerCivilization()) {
|
||||
add(getConstructionGroup(city.cityConstructions)).padRight(5f)
|
||||
}
|
||||
pack()
|
||||
setOrigin(Align.center)
|
||||
toFront()
|
||||
touchable = Touchable.enabled
|
||||
|
||||
}
|
||||
|
||||
|
||||
private fun getConstructionGroup(cityConstructions: CityConstructions): Group {
|
||||
val group= Group()
|
||||
val groupHeight = 25f
|
||||
group.setSize(40f,groupHeight)
|
||||
|
||||
val circle = ImageGetter.getImage("OtherIcons/Circle")
|
||||
circle.setSize(25f,25f)
|
||||
val image = ImageGetter.getConstructionImage(cityConstructions.currentConstruction)
|
||||
image.setSize(18f,18f)
|
||||
image.centerY(group)
|
||||
image.x = group.width-image.width
|
||||
|
||||
// center the circle on thee production image
|
||||
circle.x = image.x + (image.width-circle.width)/2
|
||||
circle.y = image.y + (image.height-circle.height)/2
|
||||
|
||||
group.addActor(circle)
|
||||
group.addActor(image)
|
||||
|
||||
val secondaryColor = cityConstructions.cityInfo.civInfo.getNation().getSecondaryColor()
|
||||
if(cityConstructions.getCurrentConstruction() !is SpecialConstruction) {
|
||||
val turnsToConstruction = cityConstructions.turnsToConstruction(cityConstructions.currentConstruction)
|
||||
val label = Label(turnsToConstruction.toString(), CameraStageBaseScreen.skin)
|
||||
label.setFontColor(secondaryColor)
|
||||
label.setFontSize(10)
|
||||
label.pack()
|
||||
group.addActor(label)
|
||||
|
||||
val adoptedPolicies = cityConstructions.cityInfo.civInfo.policies.adoptedPolicies
|
||||
val constructionPercentage = cityConstructions.getWorkDone(cityConstructions.currentConstruction) /
|
||||
cityConstructions.getCurrentConstruction().getProductionCost(adoptedPolicies).toFloat()
|
||||
val productionBar = ImageGetter.getProgressBarVertical(2f, groupHeight, constructionPercentage
|
||||
, Color.BROWN.cpy().lerp(Color.WHITE, 0.5f), Color.BLACK)
|
||||
productionBar.x = 10f
|
||||
label.x = productionBar.x - label.width - 3
|
||||
group.addActor(productionBar)
|
||||
}
|
||||
return group
|
||||
}
|
||||
|
||||
}
|
|
@ -4,7 +4,6 @@ import com.badlogic.gdx.graphics.Color
|
|||
import com.badlogic.gdx.scenes.scene2d.Actor
|
||||
import com.badlogic.gdx.scenes.scene2d.Group
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Image
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.UnCivGame
|
||||
import com.unciv.logic.HexMath
|
||||
|
@ -356,7 +355,7 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
|
|||
|
||||
|
||||
if (unit.health < 100) { // add health bar
|
||||
group.addActor(getHealthBar(unit.health.toFloat(),100f,size))
|
||||
group.addActor(ImageGetter.getHealthBar(unit.health.toFloat(),100f,size))
|
||||
}
|
||||
|
||||
return group
|
||||
|
@ -375,20 +374,5 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
|
|||
}
|
||||
|
||||
|
||||
protected fun getHealthBar(currentHealth: Float, maxHealth: Float, healthBarSize: Float): Table {
|
||||
val healthPercent = currentHealth / maxHealth
|
||||
val healthBar = Table()
|
||||
val healthPartOfBar = ImageGetter.getWhiteDot()
|
||||
healthPartOfBar.color = when {
|
||||
healthPercent > 2 / 3f -> Color.GREEN
|
||||
healthPercent > 1 / 3f -> Color.ORANGE
|
||||
else -> Color.RED
|
||||
}
|
||||
val emptyPartOfBar = ImageGetter.getWhiteDot().apply { color = Color.BLACK }
|
||||
healthBar.add(healthPartOfBar).width(healthBarSize * healthPercent).height(5f)
|
||||
healthBar.add(emptyPartOfBar).width(healthBarSize * (1 - healthPercent)).height(5f)
|
||||
healthBar.pack()
|
||||
return healthBar
|
||||
|
||||
}
|
||||
}
|
|
@ -1,24 +1,16 @@
|
|||
package com.unciv.ui.tilegroups
|
||||
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.scenes.scene2d.Group
|
||||
import com.badlogic.gdx.scenes.scene2d.Touchable
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.UnCivGame
|
||||
import com.unciv.logic.city.CityConstructions
|
||||
import com.unciv.logic.city.CityInfo
|
||||
import com.unciv.logic.city.SpecialConstruction
|
||||
import com.unciv.logic.map.MapUnit
|
||||
import com.unciv.logic.map.RoadStatus
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.ui.cityscreen.CityScreen
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.CameraStageBaseScreen
|
||||
import com.unciv.ui.utils.ImageGetter
|
||||
import com.unciv.ui.utils.center
|
||||
|
||||
|
||||
class WorldTileGroup(tileInfo: TileInfo) : TileGroup(tileInfo) {
|
||||
var cityButton: Table? = null
|
||||
var cityButton: CityButton? = null
|
||||
|
||||
fun addWhiteHaloAroundUnit(unit: MapUnit) {
|
||||
val whiteHalo = if(unit.isFortified()) ImageGetter.getImage("OtherIcons/Shield.png")
|
||||
|
@ -70,6 +62,7 @@ class WorldTileGroup(tileInfo: TileInfo) : TileGroup(tileInfo) {
|
|||
fogImage.toFront()
|
||||
}
|
||||
|
||||
|
||||
private fun updateCityButton(city: CityInfo?, viewable: Boolean) {
|
||||
if(city==null && cityButton!=null)// there used to be a city here but it was razed
|
||||
{
|
||||
|
@ -78,97 +71,15 @@ class WorldTileGroup(tileInfo: TileInfo) : TileGroup(tileInfo) {
|
|||
}
|
||||
if (city != null && tileInfo.isCityCenter()) {
|
||||
if (cityButton == null) {
|
||||
cityButton = Table()
|
||||
cityButton!!.background = ImageGetter.getDrawable("OtherIcons/civTableBackground.png")
|
||||
.tint(city.civInfo.getNation().getColor())
|
||||
cityButton!!.isTransform = true // If this is not set then the city button won't scale!
|
||||
|
||||
cityButton = CityButton(city,CameraStageBaseScreen.skin)
|
||||
addActor(cityButton)
|
||||
toFront() // so this tile is rendered over neighboring tiles
|
||||
}
|
||||
|
||||
val cityButtonText = city.population.population.toString() +" | " +city.name
|
||||
val label = Label(cityButtonText, CameraStageBaseScreen.skin)
|
||||
label.setFontColor(city.civInfo.getNation().getSecondaryColor())
|
||||
if (city.civInfo.isPlayerCivilization())
|
||||
label.onClick {
|
||||
UnCivGame.Current.screen = CityScreen(city)
|
||||
}
|
||||
|
||||
cityButton!!.run {
|
||||
clear()
|
||||
if(viewable && city.health<city.getMaxHealth().toFloat()) {
|
||||
val healthBar = getHealthBar(city.health.toFloat(),city.getMaxHealth().toFloat(),100f)
|
||||
add(healthBar).colspan(3).row()
|
||||
}
|
||||
|
||||
if(city.isBeingRazed){
|
||||
val fireImage = ImageGetter.getImage("OtherIcons/Fire.png")
|
||||
add(fireImage).size(20f).pad(2f).padLeft(5f)
|
||||
}
|
||||
if(city.isCapital()){
|
||||
val starImage = ImageGetter.getImage("OtherIcons/Star.png").apply { color = Color.LIGHT_GRAY}
|
||||
add(starImage).size(20f).pad(2f).padLeft(5f)
|
||||
}
|
||||
else if (city.civInfo.isPlayerCivilization() && city.cityStats.isConnectedToCapital(RoadStatus.Road)){
|
||||
val connectionImage = ImageGetter.getStatIcon("CityConnection")
|
||||
add(connectionImage).size(20f).pad(2f).padLeft(5f)
|
||||
}
|
||||
|
||||
else{add()} // this is so the health bar is always 2 columns wide
|
||||
add(label).pad(10f)
|
||||
if(city.civInfo.isPlayerCivilization()) {
|
||||
add(getConstructionGroup(city.cityConstructions)).padRight(5f)
|
||||
}
|
||||
pack()
|
||||
setOrigin(Align.center)
|
||||
toFront()
|
||||
touchable = Touchable.enabled
|
||||
}
|
||||
|
||||
cityButton!!.update(viewable)
|
||||
cityButton!!.center(this)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private fun getConstructionGroup(cityConstructions: CityConstructions):Group{
|
||||
val group= Group()
|
||||
val groupHeight = 25f
|
||||
group.setSize(40f,groupHeight)
|
||||
|
||||
val circle = ImageGetter.getImage("OtherIcons/Circle")
|
||||
circle.setSize(25f,25f)
|
||||
val image = ImageGetter.getConstructionImage(cityConstructions.currentConstruction)
|
||||
image.setSize(18f,18f)
|
||||
image.centerY(group)
|
||||
image.x = group.width-image.width
|
||||
|
||||
// center the circle on thee production image
|
||||
circle.x = image.x + (image.width-circle.width)/2
|
||||
circle.y = image.y + (image.height-circle.height)/2
|
||||
|
||||
group.addActor(circle)
|
||||
group.addActor(image)
|
||||
|
||||
val secondaryColor = cityConstructions.cityInfo.civInfo.getNation().getSecondaryColor()
|
||||
if(cityConstructions.getCurrentConstruction() !is SpecialConstruction) {
|
||||
val turnsToConstruction = cityConstructions.turnsToConstruction(cityConstructions.currentConstruction)
|
||||
val label = Label(turnsToConstruction.toString(),CameraStageBaseScreen.skin)
|
||||
label.setFontColor(secondaryColor)
|
||||
label.setFontSize(10)
|
||||
label.pack()
|
||||
group.addActor(label)
|
||||
|
||||
val adoptedPolicies = cityConstructions.cityInfo.civInfo.policies.adoptedPolicies
|
||||
val constructionPercentage = cityConstructions.getWorkDone(cityConstructions.currentConstruction) /
|
||||
cityConstructions.getCurrentConstruction().getProductionCost(adoptedPolicies).toFloat()
|
||||
val productionBar = ImageGetter.getProgressBarVertical(2f, groupHeight, constructionPercentage
|
||||
,Color.BROWN.cpy().lerp(Color.WHITE,0.5f), Color.BLACK )
|
||||
productionBar.x = 10f
|
||||
label.x = productionBar.x - label.width - 3
|
||||
group.addActor(productionBar)
|
||||
}
|
||||
return group
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -140,4 +140,21 @@ object ImageGetter {
|
|||
advancementGroup.pack()
|
||||
return advancementGroup
|
||||
}
|
||||
|
||||
fun getHealthBar(currentHealth: Float, maxHealth: Float, healthBarSize: Float): Table {
|
||||
val healthPercent = currentHealth / maxHealth
|
||||
val healthBar = Table()
|
||||
val healthPartOfBar = ImageGetter.getWhiteDot()
|
||||
healthPartOfBar.color = when {
|
||||
healthPercent > 2 / 3f -> Color.GREEN
|
||||
healthPercent > 1 / 3f -> Color.ORANGE
|
||||
else -> Color.RED
|
||||
}
|
||||
val emptyPartOfBar = ImageGetter.getWhiteDot().apply { color = Color.BLACK }
|
||||
healthBar.add(healthPartOfBar).width(healthBarSize * healthPercent).height(5f)
|
||||
healthBar.add(emptyPartOfBar).width(healthBarSize * (1 - healthPercent)).height(5f)
|
||||
healthBar.pack()
|
||||
return healthBar
|
||||
}
|
||||
|
||||
}
|
|
@ -12,6 +12,7 @@ import com.unciv.UnCivGame
|
|||
import com.unciv.logic.HexMath
|
||||
import com.unciv.logic.automation.UnitAutomation
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.logic.map.MapUnit
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.logic.map.TileMap
|
||||
import com.unciv.ui.tilegroups.TileGroup
|
||||
|
@ -95,42 +96,46 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap:
|
|||
val selectedUnit = worldScreen.bottomBar.unitTable.selectedUnit
|
||||
if (selectedUnit != null && selectedUnit.getTile() != tileInfo
|
||||
&& selectedUnit.canMoveTo(tileInfo) && selectedUnit.movementAlgs().canReach(tileInfo)) {
|
||||
val size = 60f
|
||||
val moveHereButton = Group().apply { width = size;height = size; }
|
||||
moveHereButton.addActor(ImageGetter.getImage("OtherIcons/Circle").apply { width = size; height = size })
|
||||
moveHereButton.addActor(ImageGetter.getStatIcon("Movement").apply { width = size / 2; height = size / 2; center(moveHereButton) })
|
||||
|
||||
val turnsToGetThere = selectedUnit.movementAlgs().getShortestPath(tileInfo).size
|
||||
val numberCircle = ImageGetter.getImage("OtherIcons/Circle").apply { width = size / 2; height = size / 2;color = Color.BLUE }
|
||||
moveHereButton.addActor(numberCircle)
|
||||
moveHereButton.addActor(Label(turnsToGetThere.toString(), CameraStageBaseScreen.skin).apply { center(numberCircle); setFontColor(Color.WHITE) })
|
||||
|
||||
val unitIcon = TileGroup(TileInfo()).getUnitImage(selectedUnit, size / 2)
|
||||
unitIcon.y = size - unitIcon.height
|
||||
moveHereButton.addActor(unitIcon)
|
||||
|
||||
if (selectedUnit.currentMovement > 0)
|
||||
moveHereButton.onClick {
|
||||
if (selectedUnit.movementAlgs().canReach(tileInfo)) {
|
||||
selectedUnit.movementAlgs().headTowards(tileInfo)
|
||||
if (selectedUnit.currentTile != tileInfo)
|
||||
selectedUnit.action = "moveTo " + tileInfo.position.x.toInt() + "," + tileInfo.position.y.toInt()
|
||||
}
|
||||
|
||||
worldScreen.update()
|
||||
moveToOverlay!!.remove()
|
||||
moveToOverlay = null
|
||||
}
|
||||
else moveHereButton.color.a = 0.5f
|
||||
addOverlayOnTileGroup(tileGroup, moveHereButton).apply { width = size; height = size }
|
||||
moveHereButton.y += tileGroup.height
|
||||
moveToOverlay = moveHereButton
|
||||
addMoveHereButtonToTile(selectedUnit, tileInfo, tileGroup)
|
||||
}
|
||||
|
||||
worldScreen.bottomBar.unitTable.tileSelected(tileInfo)
|
||||
worldScreen.update()
|
||||
}
|
||||
|
||||
private fun addMoveHereButtonToTile(selectedUnit: MapUnit, tileInfo: TileInfo, tileGroup: WorldTileGroup) {
|
||||
val size = 60f
|
||||
val moveHereButton = Group().apply { width = size;height = size; }
|
||||
moveHereButton.addActor(ImageGetter.getImage("OtherIcons/Circle").apply { width = size; height = size })
|
||||
moveHereButton.addActor(ImageGetter.getStatIcon("Movement").apply { width = size / 2; height = size / 2; center(moveHereButton) })
|
||||
|
||||
val turnsToGetThere = selectedUnit.movementAlgs().getShortestPath(tileInfo).size
|
||||
val numberCircle = ImageGetter.getImage("OtherIcons/Circle").apply { width = size / 2; height = size / 2;color = Color.BLUE }
|
||||
moveHereButton.addActor(numberCircle)
|
||||
moveHereButton.addActor(Label(turnsToGetThere.toString(), CameraStageBaseScreen.skin).apply { center(numberCircle); setFontColor(Color.WHITE) })
|
||||
|
||||
val unitIcon = TileGroup(TileInfo()).getUnitImage(selectedUnit, size / 2)
|
||||
unitIcon.y = size - unitIcon.height
|
||||
moveHereButton.addActor(unitIcon)
|
||||
|
||||
if (selectedUnit.currentMovement > 0)
|
||||
moveHereButton.onClick {
|
||||
if (selectedUnit.movementAlgs().canReach(tileInfo)) {
|
||||
selectedUnit.movementAlgs().headTowards(tileInfo)
|
||||
if (selectedUnit.currentTile != tileInfo)
|
||||
selectedUnit.action = "moveTo " + tileInfo.position.x.toInt() + "," + tileInfo.position.y.toInt()
|
||||
}
|
||||
|
||||
worldScreen.update()
|
||||
moveToOverlay!!.remove()
|
||||
moveToOverlay = null
|
||||
}
|
||||
else moveHereButton.color.a = 0.5f
|
||||
addOverlayOnTileGroup(tileGroup, moveHereButton).apply { width = size; height = size }
|
||||
moveHereButton.y += tileGroup.height
|
||||
moveToOverlay = moveHereButton
|
||||
}
|
||||
|
||||
private fun addOverlayOnTileGroup(group:WorldTileGroup, actor: Actor) {
|
||||
actor.center(group)
|
||||
actor.x+=group.x
|
||||
|
@ -142,13 +147,16 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap:
|
|||
internal fun updateTiles(civInfo: CivilizationInfo) {
|
||||
val playerViewableTilePositions = civInfo.getViewableTiles().map { it.position }.toHashSet()
|
||||
|
||||
for (WG in tileGroups.values){
|
||||
WG.update(playerViewableTilePositions.contains(WG.tileInfo.position))
|
||||
val unitsInTile = WG.tileInfo.getUnits()
|
||||
if((playerViewableTilePositions.contains(WG.tileInfo.position) || UnCivGame.Current.viewEntireMapForDebug)
|
||||
cityButtonOverlays.forEach{it.remove()}
|
||||
cityButtonOverlays.clear()
|
||||
|
||||
for (tileGroup in tileGroups.values){
|
||||
tileGroup.update(playerViewableTilePositions.contains(tileGroup.tileInfo.position))
|
||||
val unitsInTile = tileGroup.tileInfo.getUnits()
|
||||
if((playerViewableTilePositions.contains(tileGroup.tileInfo.position) || UnCivGame.Current.viewEntireMapForDebug)
|
||||
&& unitsInTile.isNotEmpty() && !unitsInTile.first().civInfo.isPlayerCivilization())
|
||||
WG.showCircle(Color.RED)
|
||||
} // Display ALL viewable enemies with a red circle so that users don't need to go "hunting" for enemy units
|
||||
tileGroup.showCircle(Color.RED) // Display ALL viewable enemies with a red circle so that users don't need to go "hunting" for enemy units
|
||||
}
|
||||
|
||||
if(worldScreen.bottomBar.unitTable.selectedUnit!=null){
|
||||
val unit = worldScreen.bottomBar.unitTable.selectedUnit!!
|
||||
|
|
Loading…
Reference in a new issue