Code organization - separated TechButton and IconCircleGroup to separate files &c

Tech with special abilities now displayed with a star icon
This commit is contained in:
Yair Morgenstern
2018-11-04 18:42:55 +02:00
parent 937687a0f4
commit 02b0f6e9fe
14 changed files with 475 additions and 447 deletions

View File

@ -8,7 +8,6 @@ import com.unciv.models.stats.Stats
import com.unciv.ui.utils.tr
class Building : NamedStats(), IConstruction{
private var baseDescription: String? = null
override val description: String
get() = getDescription(false, hashSetOf())

View File

@ -12,7 +12,6 @@ class Technology : ICivilopedia {
val SB=StringBuilder()
if(baseDescription!=null) SB.appendln(baseDescription!!.tr())
val improvedImprovements = GameBasics.TileImprovements.values.filter { it.improvingTech==name }.groupBy { it.improvingTechStats.toString() }
for (improvement in improvedImprovements) {
val impimpString = improvement.value.joinToString { it.name.tr() } +" {provide" + (if(improvement.value.size==1) "s" else "") +"} "+improvement.key

View File

@ -0,0 +1,63 @@
package com.unciv.ui.pickerscreens
import com.badlogic.gdx.graphics.Color
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.logic.civilization.TechManager
import com.unciv.models.gamebasics.GameBasics
import com.unciv.ui.utils.CameraStageBaseScreen
import com.unciv.ui.utils.ImageGetter
import com.unciv.ui.utils.setFontColor
import com.unciv.ui.utils.surroundWithCircle
class TechButton(techName:String, val techManager: TechManager) : Table(CameraStageBaseScreen.skin) {
val text= Label("", skin).setFontColor(Color.WHITE).apply { setAlignment(Align.center) }
init {
touchable = Touchable.enabled
defaults().pad(10f)
background = ImageGetter.getDrawable("OtherIcons/civTableBackground.png")
if(ImageGetter.techIconExists(techName))
add(ImageGetter.getTechIconGroup(techName)) // this is 60*60
val rightSide = Table()
val techCost = techManager.costOfTech(techName)
val remainingTech = techManager.remainingScienceToTech(techName)
if(techCost!=remainingTech){
val percentComplete = (techCost-remainingTech)/techCost.toFloat()
add(ImageGetter.getProgressBarVertical(2f, 50f, percentComplete, Color.BLUE, Color.WHITE))
}
rightSide.add(text).row()
// here we add little images of what the tech gives you
val techEnabledIcons = Table()
techEnabledIcons.defaults().pad(5f)
for(unit in GameBasics.Units.values.filter { it.requiredTech==techName
&& (it.uniqueTo==null || it.uniqueTo==techManager.civInfo.civName) })
techEnabledIcons.add(ImageGetter.getConstructionImage(unit.name).surroundWithCircle(30f))
for(building in GameBasics.Buildings.values.filter { it.requiredTech==techName
&& (it.uniqueTo==null || it.uniqueTo==techManager.civInfo.civName)})
techEnabledIcons.add(ImageGetter.getConstructionImage(building.name).surroundWithCircle(30f))
for(improvement in GameBasics.TileImprovements.values.filter { it.techRequired==techName || it.improvingTech==techName }) {
if(improvement.name.startsWith("Remove"))
techEnabledIcons.add(ImageGetter.getImage("OtherIcons/Stop")).size(30f)
else techEnabledIcons.add(ImageGetter.getImprovementIcon(improvement.name, 30f))
}
for(resource in GameBasics.TileResources.values.filter { it.revealedBy==techName })
techEnabledIcons.add(ImageGetter.getResourceImage(resource.name, 30f))
val tech = GameBasics.Technologies[techName]!!
if(tech.baseDescription!=null)
techEnabledIcons.add(ImageGetter.getImage("OtherIcons/Star").apply { color= Color.BLACK }.surroundWithCircle(30f))
rightSide.add(techEnabledIcons)
add(rightSide)
pack()
}
}

View File

@ -1,10 +1,7 @@
package com.unciv.ui.pickerscreens
import com.badlogic.gdx.graphics.Color
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.civilization.CivilizationInfo
import com.unciv.logic.civilization.TechManager
@ -13,6 +10,7 @@ import com.unciv.models.gamebasics.tech.Technology
import com.unciv.ui.utils.*
import java.util.*
class TechPickerScreen(internal val civInfo: CivilizationInfo) : PickerScreen() {
private var techNameToButton = HashMap<String, TechButton>()
@ -37,52 +35,6 @@ class TechPickerScreen(internal val civInfo: CivilizationInfo) : PickerScreen()
isFreeTechPick = freeTechPick
}
class TechButton(techName:String, val techManager:TechManager) : Table(skin) {
val text=Label("",skin).setFontColor(Color.WHITE).apply { setAlignment(Align.center) }
init {
touchable = Touchable.enabled
defaults().pad(10f)
background = ImageGetter.getDrawable("OtherIcons/civTableBackground.png")
if(ImageGetter.techIconExists(techName))
add(ImageGetter.getTechIconGroup(techName)) // this is 60*60
val rightSide = Table()
val techCost = techManager.costOfTech(techName)
val remainingTech = techManager.remainingScienceToTech(techName)
if(techCost!=remainingTech){
val percentComplete = (techCost-remainingTech)/techCost.toFloat()
add(ImageGetter.getProgressBarVertical(2f,50f,percentComplete, Color.BLUE, Color.WHITE))
}
rightSide.add(text).row()
// here we add little images of what the tech gives you
val techEnabledIcons = Table()
techEnabledIcons.defaults().pad(5f)
for(unit in GameBasics.Units.values.filter { it.requiredTech==techName
&& (it.uniqueTo==null || it.uniqueTo==techManager.civInfo.civName) })
techEnabledIcons.add(ImageGetter.IconCircleGroup(30f,ImageGetter.getConstructionImage(unit.name)))
for(building in GameBasics.Buildings.values.filter { it.requiredTech==techName
&& (it.uniqueTo==null || it.uniqueTo==techManager.civInfo.civName)})
techEnabledIcons.add(ImageGetter.IconCircleGroup(30f,ImageGetter.getConstructionImage(building.name)))
for(improvement in GameBasics.TileImprovements.values.filter { it.techRequired==techName || it.improvingTech==techName }) {
if(improvement.name.startsWith("Remove"))
techEnabledIcons.add(ImageGetter.getImage("OtherIcons/Stop")).size(30f)
else techEnabledIcons.add(ImageGetter.getImprovementIcon(improvement.name, 30f))
}
for(resource in GameBasics.TileResources.values.filter { it.revealedBy==techName })
techEnabledIcons.add(ImageGetter.getResourceImage(resource.name,30f))
rightSide.add(techEnabledIcons)
add(rightSide)
pack()
}
}
init {
onBackButtonClicked { UnCivGame.Current.setWorldScreen(); dispose() }

View File

@ -228,7 +228,7 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
}
if (roadStatus == RoadStatus.None) continue // no road image
val image = if (roadStatus == RoadStatus.Road) ImageGetter.getImage(ImageGetter.WhiteDot).apply { color = Color.BROWN }
val image = if (roadStatus == RoadStatus.Road) ImageGetter.getWhiteDot().apply { color = Color.BROWN }
else ImageGetter.getImage("OtherIcons/Railroad.png")
roadImage.image = image
@ -378,13 +378,13 @@ 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.getImage(ImageGetter.WhiteDot)
val healthPartOfBar = ImageGetter.getWhiteDot()
healthPartOfBar.color = when {
healthPercent > 2 / 3f -> Color.GREEN
healthPercent > 1 / 3f -> Color.ORANGE
else -> Color.RED
}
val emptyPartOfBar = ImageGetter.getImage(ImageGetter.WhiteDot).apply { color = Color.BLACK }
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()

View File

@ -190,3 +190,6 @@ fun Actor.onClick(function: () -> Unit) {
} )
}
fun Image.surroundWithCircle(size:Float): IconCircleGroup {
return IconCircleGroup(size,this)
}

View File

@ -0,0 +1,15 @@
package com.unciv.ui.utils
import com.badlogic.gdx.scenes.scene2d.Group
import com.badlogic.gdx.scenes.scene2d.ui.Image
class IconCircleGroup(size:Float, val image: Image): Group(){
val circle = ImageGetter.getImage("OtherIcons/Circle").apply { setSize(size, size) }
init {
setSize(size, size)
addActor(circle)
image.setSize(size * 0.75f, size * 0.75f)
image.center(this)
addActor(image)
}
}

View File

@ -14,7 +14,7 @@ import com.unciv.models.gamebasics.GameBasics
import com.unciv.models.gamebasics.tile.ResourceType
object ImageGetter {
const val WhiteDot = "OtherIcons/whiteDot.png"
const private val whiteDotLocation = "OtherIcons/whiteDot.png"
// When we used to load images directly from different files, without using a texture atlas,
// The draw() phase of the main screen would take a really long time because the BatchRenderer would
@ -22,9 +22,8 @@ object ImageGetter {
// So, we now use TexturePacker in the DesktopLauncher class to pack all the different images into single images,
// and the atlas is what tells us what was packed where.
var atlas = TextureAtlas("game.atlas")
fun getWhiteDot() = getImage(whiteDotLocation)
init{
}
fun getExternalImage(fileName:String): Image {
return Image(TextureRegion(Texture("ExtraImages/$fileName.png")))
@ -49,7 +48,7 @@ object ImageGetter {
throw Exception("Could not find $fileName")
return region
} catch (ex: Exception) {
return getTextureRegion(WhiteDot)
return getTextureRegion(whiteDotLocation)
}
}
@ -66,16 +65,19 @@ object ImageGetter {
return getImage("UnitIcons/$unitName").apply { this.color=color }
}
val foodCircleColor = Color.GREEN.cpy().lerp(Color.WHITE,0.5f)
val productionCircleColor = Color.BROWN.cpy().lerp(Color.WHITE,0.5f)
val goldCircleColor = Color.GOLD.cpy().lerp(Color.WHITE,0.5f)
fun getImprovementIcon(improvementName:String, size:Float=20f):Actor{
val iconGroup = IconCircleGroup(size, getImage("ImprovementIcons/$improvementName"))
val iconGroup = getImage("ImprovementIcons/$improvementName").surroundWithCircle(size)
val improvement = GameBasics.TileImprovements[improvementName]!!
when {
improvement.food>0 -> iconGroup.circle.color= Color.GREEN.cpy().lerp(Color.WHITE,0.5f)
improvement.production>0 -> iconGroup.circle.color= Color.BROWN.cpy().lerp(Color.WHITE,0.5f)
improvement.gold>0 -> iconGroup.circle.color= Color.GOLD.cpy().lerp(Color.WHITE,0.5f)
improvement.science>0 -> iconGroup.circle.color= Color.GOLD.cpy().lerp(Color.BLUE,0.5f)
improvement.culture>0 -> iconGroup.circle.color= Color.GOLD.cpy().lerp(Color.PURPLE,0.5f)
improvement.food>0 -> iconGroup.circle.color= foodCircleColor
improvement.production>0 -> iconGroup.circle.color= productionCircleColor
improvement.gold>0 -> iconGroup.circle.color= goldCircleColor
improvement.science>0 -> iconGroup.circle.color= Color.BLUE.cpy().lerp(Color.WHITE,0.5f)
improvement.culture>0 -> iconGroup.circle.color= Color.PURPLE.cpy().lerp(Color.WHITE,0.5f)
}
return iconGroup
@ -95,7 +97,7 @@ object ImageGetter {
fun getBlue() = Color(0x004085bf)
fun getBackground(color:Color): Drawable {
return getDrawable(WhiteDot).tint(color)
return getDrawable(whiteDotLocation).tint(color)
}
fun refreshAltas() {
@ -103,11 +105,13 @@ object ImageGetter {
}
fun getResourceImage(resourceName: String, size:Float): Actor {
val iconGroup = IconCircleGroup(size,getImage("ResourceIcons/$resourceName"))
val iconGroup = getImage("ResourceIcons/$resourceName").surroundWithCircle(size)
val resource = GameBasics.TileResources[resourceName]!!
if(resource.food>0) iconGroup.circle.color= Color.GREEN.cpy().lerp(Color.WHITE,0.5f)
else if(resource.production>0) iconGroup.circle.color= Color.BROWN.cpy().lerp(Color.WHITE,0.5f)
else if(resource.gold>0) iconGroup.circle.color= Color.GOLD.cpy().lerp(Color.WHITE,0.5f)
when {
resource.food>0 -> iconGroup.circle.color= foodCircleColor
resource.production>0 -> iconGroup.circle.color= productionCircleColor
resource.gold>0 -> iconGroup.circle.color= goldCircleColor
}
if(resource.resourceType==ResourceType.Luxury){
val happiness = getStatIcon("Happiness")
@ -125,27 +129,15 @@ object ImageGetter {
}
fun getTechIconGroup(techName: String): Group {
return IconCircleGroup(60f,getImage("TechIcons/$techName"))
return getImage("TechIcons/$techName").surroundWithCircle(60f)
}
fun getProgressBarVertical(width:Float,height:Float,percentComplete:Float,progressColor:Color,backgroundColor:Color): Table {
val advancementGroup = Table()
val completionHeight = height * percentComplete
advancementGroup.add(ImageGetter.getImage(ImageGetter.WhiteDot).apply { color = backgroundColor }).width(width).height(height-completionHeight).row()
advancementGroup.add(ImageGetter.getImage(ImageGetter.WhiteDot).apply { color= progressColor}).width(width).height(completionHeight)
advancementGroup.add(getImage(whiteDotLocation).apply { color = backgroundColor }).width(width).height(height-completionHeight).row()
advancementGroup.add(getImage(whiteDotLocation).apply { color= progressColor}).width(width).height(completionHeight)
advancementGroup.pack()
return advancementGroup
}
class IconCircleGroup(size:Float, val image:Image):Group(){
val circle = getImage("OtherIcons/Circle").apply { setSize(size, size) }
init {
setSize(size, size)
addActor(circle)
image.setSize(size * 0.75f, size * 0.75f)
image.center(this)
addActor(image)
}
}
}
}

View File

@ -14,6 +14,7 @@ import com.unciv.logic.civilization.DiplomaticStatus
import com.unciv.models.gamebasics.tile.ResourceType
import com.unciv.ui.pickerscreens.GreatPersonPickerScreen
import com.unciv.ui.pickerscreens.PolicyPickerScreen
import com.unciv.ui.pickerscreens.TechButton
import com.unciv.ui.pickerscreens.TechPickerScreen
import com.unciv.ui.trade.DiplomacyScreen
import com.unciv.ui.utils.*
@ -32,7 +33,7 @@ class WorldScreen : CameraStageBaseScreen() {
val unitActionsTable = UnitActionsTable(this)
private val techButton = Table()
val diplomacyButtonWrapper = Table()
private val diplomacyButtonWrapper = Table()
private val nextTurnButton = createNextTurnButton()
private val notificationsScroll: NotificationsScroll
@ -178,7 +179,7 @@ class WorldScreen : CameraStageBaseScreen() {
}
else {
val currentTech = civInfo.tech.currentTechnology()!!
val innerButton = TechPickerScreen.TechButton(currentTech,civInfo.tech)
val innerButton = TechButton(currentTech,civInfo.tech)
innerButton.color = colorFromRGB(7, 46, 43)
techButton.add(innerButton)
val turnsToTech = civInfo.tech.turnsToTech(currentTech)
@ -254,7 +255,7 @@ class WorldScreen : CameraStageBaseScreen() {
}
}
var shouldUpdate=false
private var shouldUpdate=false
override fun render(delta: Float) {
if(shouldUpdate){ // This is so that updates happen in the MAIN THREAD, where there is a GL Context,
// otherwise images will not load properly!
@ -271,7 +272,7 @@ class WorldScreen : CameraStageBaseScreen() {
val resources = civInfo.getCivResources()
if(resources.keys.any { it.resourceType==ResourceType.Luxury }) displayTutorials("LuxuryResource")
if(resources.keys.any { it.resourceType==ResourceType.Strategic}) displayTutorials("StrategicResource")
if(civInfo.exploredTiles.map { gameInfo.tileMap[it] }.any { it.isCityCenter() && it.getOwner()!=civInfo })
if(civInfo.exploredTiles.asSequence().map { gameInfo.tileMap[it] }.any { it.isCityCenter() && it.getOwner()!=civInfo })
displayTutorials("EnemyCity")
if("Enables construction of Spaceship parts" in civInfo.getBuildingUniques())
displayTutorials("ApolloProgram")