Added promotions mechanism!

This commit is contained in:
Yair Morgenstern 2018-06-16 22:50:11 +03:00
parent 92abe0cf73
commit c6caf0cecd
16 changed files with 203 additions and 151 deletions

View file

@ -71,18 +71,18 @@
{
name:"Scouting I",
effect:"+1 Visibility Range",
unitTypes:["Melee","Mounted"]
unitTypes:["Scout"]
}
{
name:"Scouting II",
prerequisites:["Scouting I"],
effect:"+1 Visibility Range",
unitTypes:["Melee","Mounted"]
unitTypes:["Scout"]
}
{
name:"Scouting III",
prerequisites:["Scouting II"],
effect:"+1 Visibility Range",
unitTypes:["Melee","Mounted"]
unitTypes:["Scout"]
}
]

View file

@ -2,6 +2,7 @@ package com.unciv.logic.automation
import com.unciv.UnCivGame
import com.unciv.logic.battle.Battle
import com.unciv.logic.battle.BattleDamage
import com.unciv.logic.battle.MapUnitCombatant
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.map.MapUnit
@ -90,7 +91,7 @@ class UnitAutomation{
if(setupAction!=null) setupAction.action()
val enemy = Battle().getMapCombatantOfTile(enemyTileToAttack)!!
val damageToAttacker = Battle(unit.civInfo.gameInfo).calculateDamageToAttacker(MapUnitCombatant(unit), enemy)
val damageToAttacker = BattleDamage().calculateDamageToAttacker(MapUnitCombatant(unit), enemy)
if (damageToAttacker < unit.health) { // don't attack if we'll die from the attack
if(MapUnitCombatant(unit).isMelee())

View file

@ -8,116 +8,17 @@ import com.unciv.logic.map.TileInfo
import com.unciv.models.gamebasics.unit.UnitType
import com.unciv.ui.utils.tr
import java.util.*
import kotlin.collections.HashMap
import kotlin.math.max
/**
* Damage calculations according to civ v wiki and https://steamcommunity.com/sharedfiles/filedetails/?id=170194443
*/
class Battle(val gameInfo:GameInfo=UnCivGame.Current.gameInfo) {
private fun getGeneralModifiers(combatant: ICombatant, enemy: ICombatant): HashMap<String, Float> {
val modifiers = HashMap<String, Float>()
if (combatant is MapUnitCombatant) {
val uniques = combatant.unit.getBaseUnit().uniques
if (uniques != null) {
// This beut allows us to have generic unit uniques: "Bonus vs City 75%", "Penatly vs Mounted 25%" etc.
for (unique in uniques) {
val regexResult = Regex("""(Bonus|Penalty) vs (\S*) (\d*)%""").matchEntire(unique)
if (regexResult == null) continue
val vsType = UnitType.valueOf(regexResult.groups[2]!!.value)
val modificationAmount = regexResult.groups[3]!!.value.toFloat() / 100 // if it says 15%, that's 0.15f in modification
if (enemy.getUnitType() == vsType) {
if (regexResult.groups[1]!!.value == "Bonus")
modifiers["Bonus vs $vsType"] = modificationAmount
else modifiers["Penalty vs $vsType"] = -modificationAmount
}
}
}
if(enemy.getCivilization().isBarbarianCivilization())
modifiers["vs Barbarians"] = 0.33f
if(combatant.getCivilization().happiness<0)
modifiers["Unhappiness"] = 0.02f * combatant.getCivilization().happiness //https://www.carlsguides.com/strategy/civilization5/war/combatbonuses.php
}
return modifiers
}
fun getAttackModifiers(attacker: ICombatant, defender: ICombatant): HashMap<String, Float> {
val modifiers = getGeneralModifiers(attacker, defender)
if (attacker.isMelee()) {
val numberOfAttackersSurroundingDefender = defender.getTile().neighbors.count {
it.militaryUnit != null
&& it.militaryUnit!!.owner == attacker.getCivilization().civName
&& MapUnitCombatant(it.militaryUnit!!).isMelee()
}
if (numberOfAttackersSurroundingDefender > 1)
modifiers["Flanking"] = 0.1f * (numberOfAttackersSurroundingDefender-1) //https://www.carlsguides.com/strategy/civilization5/war/combatbonuses.php
}
return modifiers
}
fun getDefenceModifiers(attacker: ICombatant, defender: ICombatant): HashMap<String, Float> {
val modifiers = getGeneralModifiers(defender, attacker)
if (!(defender is MapUnitCombatant && defender.unit.hasUnique("No defensive terrain bonus"))) {
val tileDefenceBonus = defender.getTile().getDefensiveBonus()
if (tileDefenceBonus > 0) modifiers["Terrain"] = tileDefenceBonus
}
if(defender is MapUnitCombatant && defender.unit.isFortified())
modifiers["Fortification"]=0.2f*defender.unit.getFortificationTurns()
return modifiers
}
private fun modifiersToMultiplicationBonus(modifiers: HashMap<String, Float>): Float {
// modifiers are like 0.1 for a 10% bonus, -0.1 for a 10% loss
var modifier = 1f
for (m in modifiers.values) modifier *= (1 + m)
return modifier
}
private fun getHealthDependantDamageRatio(combatant: ICombatant): Float {
if (combatant.getUnitType() == UnitType.City) return 1f
return 1/2f + combatant.getHealth()/200f // Each point of health reduces damage dealt by 0.5%
}
/**
* Includes attack modifiers
*/
fun getAttackingStrength(attacker: ICombatant, defender: ICombatant): Float {
val attackModifier = modifiersToMultiplicationBonus(getAttackModifiers(attacker,defender))
return attacker.getAttackingStrength(defender) * attackModifier
}
/**
* Includes defence modifiers
*/
fun getDefendingStrength(attacker: ICombatant, defender: ICombatant): Float {
val defenceModifier = modifiersToMultiplicationBonus(getDefenceModifiers(attacker,defender))
return defender.getDefendingStrength(attacker) * defenceModifier
}
fun calculateDamageToAttacker(attacker: ICombatant, defender: ICombatant): Int {
if(attacker.isRanged()) return 0
if(defender.getUnitType()== UnitType.Civilian) return 0
val ratio = getDefendingStrength(attacker,defender) / getAttackingStrength(attacker,defender)
return (ratio * 30 * getHealthDependantDamageRatio(defender)).toInt()
}
fun calculateDamageToDefender(attacker: ICombatant, defender: ICombatant): Int {
val ratio = getAttackingStrength(attacker,defender) / getDefendingStrength(attacker,defender)
return (ratio * 30 * getHealthDependantDamageRatio(attacker)).toInt()
}
fun attack(attacker: ICombatant, defender: ICombatant) {
val attackedTile = defender.getTile()
var damageToDefender = calculateDamageToDefender(attacker,defender)
var damageToAttacker = calculateDamageToAttacker(attacker,defender)
var damageToDefender = BattleDamage().calculateDamageToDefender(attacker,defender)
var damageToAttacker = BattleDamage().calculateDamageToAttacker(attacker,defender)
if(defender.getUnitType() == UnitType.Civilian && attacker.isMelee()){
captureCivilianUnit(attacker,defender)
@ -182,6 +83,19 @@ class Battle(val gameInfo:GameInfo=UnCivGame.Current.gameInfo) {
unit.attacksThisTurn+=1
if(unit.isFortified()) attacker.unit.action=null // but not, for instance, if it's Set Up - then it should definitely keep the action!
}
// XP!
if(attacker.isMelee()){
if(defender.getCivilization() != attacker.getCivilization()) // unit was not captured but actually attacked
{
if (attacker is MapUnitCombatant) attacker.unit.promotions.XP += 5
if (defender is MapUnitCombatant) defender.unit.promotions.XP += 4
}
}
else{ // ranged attack
if(attacker is MapUnitCombatant) attacker.unit.promotions.XP += 2
if(defender is MapUnitCombatant) defender.unit.promotions.XP += 2
}
}
private fun conquerCity(city: CityInfo, attacker: ICombatant) {
@ -235,4 +149,5 @@ class Battle(val gameInfo:GameInfo=UnCivGame.Current.gameInfo) {
capturedUnit.civInfo = attacker.getCivilization()
capturedUnit.owner = capturedUnit.civInfo.civName
}
}
}

View file

@ -0,0 +1,104 @@
package com.unciv.logic.battle
import com.unciv.models.gamebasics.unit.UnitType
class BattleDamage{
private fun getGeneralModifiers(combatant: ICombatant, enemy: ICombatant): HashMap<String, Float> {
val modifiers = HashMap<String, Float>()
if (combatant is MapUnitCombatant) {
val uniques = combatant.unit.getBaseUnit().uniques
if (uniques != null) {
// This beut allows us to have generic unit uniques: "Bonus vs City 75%", "Penatly vs Mounted 25%" etc.
for (unique in uniques) {
val regexResult = Regex("""(Bonus|Penalty) vs (\S*) (\d*)%""").matchEntire(unique)
if (regexResult == null) continue
val vsType = UnitType.valueOf(regexResult.groups[2]!!.value)
val modificationAmount = regexResult.groups[3]!!.value.toFloat() / 100 // if it says 15%, that's 0.15f in modification
if (enemy.getUnitType() == vsType) {
if (regexResult.groups[1]!!.value == "Bonus")
modifiers["Bonus vs $vsType"] = modificationAmount
else modifiers["Penalty vs $vsType"] = -modificationAmount
}
}
}
if(enemy.getCivilization().isBarbarianCivilization())
modifiers["vs Barbarians"] = 0.33f
if(combatant.getCivilization().happiness<0)
modifiers["Unhappiness"] = 0.02f * combatant.getCivilization().happiness //https://www.carlsguides.com/strategy/civilization5/war/combatbonuses.php
}
return modifiers
}
fun getAttackModifiers(attacker: ICombatant, defender: ICombatant): HashMap<String, Float> {
val modifiers = getGeneralModifiers(attacker, defender)
if (attacker.isMelee()) {
val numberOfAttackersSurroundingDefender = defender.getTile().neighbors.count {
it.militaryUnit != null
&& it.militaryUnit!!.owner == attacker.getCivilization().civName
&& MapUnitCombatant(it.militaryUnit!!).isMelee()
}
if (numberOfAttackersSurroundingDefender > 1)
modifiers["Flanking"] = 0.1f * (numberOfAttackersSurroundingDefender-1) //https://www.carlsguides.com/strategy/civilization5/war/combatbonuses.php
}
return modifiers
}
fun getDefenceModifiers(attacker: ICombatant, defender: ICombatant): HashMap<String, Float> {
val modifiers = getGeneralModifiers(defender, attacker)
if (!(defender is MapUnitCombatant && defender.unit.hasUnique("No defensive terrain bonus"))) {
val tileDefenceBonus = defender.getTile().getDefensiveBonus()
if (tileDefenceBonus > 0) modifiers["Terrain"] = tileDefenceBonus
}
if(defender is MapUnitCombatant && defender.unit.isFortified())
modifiers["Fortification"]=0.2f*defender.unit.getFortificationTurns()
return modifiers
}
private fun modifiersToMultiplicationBonus(modifiers: HashMap<String, Float>): Float {
// modifiers are like 0.1 for a 10% bonus, -0.1 for a 10% loss
var modifier = 1f
for (m in modifiers.values) modifier *= (1 + m)
return modifier
}
private fun getHealthDependantDamageRatio(combatant: ICombatant): Float {
if (combatant.getUnitType() == UnitType.City) return 1f
return 1/2f + combatant.getHealth()/200f // Each point of health reduces damage dealt by 0.5%
}
/**
* Includes attack modifiers
*/
fun getAttackingStrength(attacker: ICombatant, defender: ICombatant): Float {
val attackModifier = modifiersToMultiplicationBonus(getAttackModifiers(attacker,defender))
return attacker.getAttackingStrength(defender) * attackModifier
}
/**
* Includes defence modifiers
*/
fun getDefendingStrength(attacker: ICombatant, defender: ICombatant): Float {
val defenceModifier = modifiersToMultiplicationBonus(getDefenceModifiers(attacker,defender))
return defender.getDefendingStrength(attacker) * defenceModifier
}
fun calculateDamageToAttacker(attacker: ICombatant, defender: ICombatant): Int {
if(attacker.isRanged()) return 0
if(defender.getUnitType()== UnitType.Civilian) return 0
val ratio = getDefendingStrength(attacker,defender) / getAttackingStrength(attacker,defender)
return (ratio * 30 * getHealthDependantDamageRatio(defender)).toInt()
}
fun calculateDamageToDefender(attacker: ICombatant, defender: ICombatant): Int {
val ratio = getAttackingStrength(attacker,defender) / getDefendingStrength(attacker,defender)
return (ratio * 30 * getHealthDependantDamageRatio(attacker)).toInt()
}
}

View file

@ -17,12 +17,12 @@ class MapUnitCombatant(val unit: MapUnit) : ICombatant {
if(isDefeated()) unit.removeFromTile()
}
override fun getAttackingStrength(defender: ICombatant): Int {
override fun getAttackingStrength(defender: ICombatant): Int { // todo remove defender
if (isRanged()) return unit.getBaseUnit().rangedStrength
else return unit.getBaseUnit().strength
}
override fun getDefendingStrength(attacker: ICombatant): Int {
override fun getDefendingStrength(attacker: ICombatant): Int { // todo remove attacker
return unit.getBaseUnit().strength
}

View file

@ -19,6 +19,7 @@ class MapUnit {
var health:Int = 100
var action: String? = null // work, automation, fortifying, I dunno what.
var attacksThisTurn = 0
var promotions = UnitPromotions()
fun getBaseUnit(): Unit = GameBasics.Units[name]!!
fun getMovementString(): String = DecimalFormat("0.#").format(currentMovement.toDouble()) + "/" + maxMovement

View file

@ -0,0 +1,16 @@
package com.unciv.logic.map
class UnitPromotions{
var XP=0
var promotions = HashSet<String>()
var numberOfPromotions = 0 // The number of times this unit has been promoted - some promotions don't come from being promoted but from other things!
fun xpForNextPromotion() = (numberOfPromotions+1)*10
fun canBePromoted() = XP >= xpForNextPromotion()
fun addPromotion(promotionName:String){
XP -= xpForNextPromotion()
promotions.add(promotionName)
numberOfPromotions++
}
}

View file

@ -6,7 +6,7 @@ import com.unciv.models.gamebasics.tile.Terrain
import com.unciv.models.gamebasics.tile.TileImprovement
import com.unciv.models.gamebasics.tile.TileResource
import com.unciv.models.gamebasics.unit.Unit
import com.unciv.models.gamebasics.unit.UnitPromotion
import com.unciv.models.gamebasics.unit.Promotion
import com.unciv.models.stats.INamed
import kotlin.collections.set
@ -18,7 +18,7 @@ object GameBasics {
val Technologies = LinkedHashMap<String, Technology>()
val Helps = LinkedHashMap<String, BasicHelp>()
val Units = LinkedHashMap<String, Unit>()
val UnitPromotions = LinkedHashMap<String, UnitPromotion>()
val UnitPromotions = LinkedHashMap<String, Promotion>()
val Civilizations = LinkedHashMap<String, Civilization>()
val PolicyBranches = LinkedHashMap<String, PolicyBranch>()
val Tutorials = LinkedHashMap<String, List<String>>()
@ -43,7 +43,7 @@ object GameBasics {
TileImprovements += createHashmap(getFromJson(Array<TileImprovement>::class.java, "TileImprovements"))
Helps += createHashmap(getFromJson(Array<BasicHelp>::class.java, "BasicHelp"))
Units += createHashmap(getFromJson(Array<Unit>::class.java, "Units"))
UnitPromotions += createHashmap(getFromJson(Array<UnitPromotion>::class.java, "UnitPromotions"))
UnitPromotions += createHashmap(getFromJson(Array<Promotion>::class.java, "UnitPromotions"))
PolicyBranches += createHashmap(getFromJson(Array<PolicyBranch>::class.java, "Policies"))
Civilizations += createHashmap(getFromJson(Array<Civilization>::class.java, "Civilizations"))

View file

@ -3,7 +3,7 @@ package com.unciv.models.gamebasics.unit
import com.unciv.models.gamebasics.ICivilopedia
import com.unciv.models.stats.INamed
class UnitPromotion : ICivilopedia, INamed{
class Promotion : ICivilopedia, INamed{
override lateinit var name: String
override val description: String
get(){
@ -11,5 +11,5 @@ class UnitPromotion : ICivilopedia, INamed{
}
var prerequisites = listOf<String>()
lateinit var effect:String;
var unitTypes = listOf<UnitType>()
var unitTypes = listOf<String>() // The json parser woulddn't agree to deserialize this as a list of UnitTypes. =(
}

View file

@ -61,7 +61,7 @@ class CityStatsTable(val cityScreen: CityScreen) : Table(){
!(construction is Building && construction.isWonder)) {
row()
val buildingGoldCost = construction.getGoldCost(city.civInfo.policies.getAdoptedPolicies())
val buildingBuyButton = TextButton("Buy for".tr()+"\r\n$buildingGoldCost gold", CameraStageBaseScreen.skin)
val buildingBuyButton = TextButton("Buy for".tr()+"\r\n$buildingGoldCost "+"Gold".tr(), CameraStageBaseScreen.skin)
buildingBuyButton.addClickListener {
city.cityConstructions.purchaseBuilding(city.cityConstructions.currentConstruction)
update()

View file

@ -1,13 +1,8 @@
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.*
import com.badlogic.gdx.utils.Align
import com.unciv.ui.utils.CameraStageBaseScreen
import com.unciv.ui.utils.addClickListener
import com.unciv.ui.utils.disable
import com.unciv.ui.utils.tr
import com.unciv.ui.utils.*
open class PickerScreen : CameraStageBaseScreen() {
@ -53,9 +48,7 @@ open class PickerScreen : CameraStageBaseScreen() {
}
protected fun pick(rightButtonText: String) {
rightSideButton.touchable = Touchable.enabled
rightSideButton.color = Color.WHITE
rightSideButton.enable()
rightSideButton.setText(rightButtonText)
}
}
}

View file

@ -6,37 +6,44 @@ import com.badlogic.gdx.scenes.scene2d.ui.Label
import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup
import com.unciv.logic.map.MapUnit
import com.unciv.models.gamebasics.GameBasics
import com.unciv.models.gamebasics.unit.UnitPromotion
import com.unciv.ui.utils.ImageGetter
import com.unciv.ui.utils.addClickListener
import com.unciv.ui.utils.setFontColor
import com.unciv.models.gamebasics.unit.Promotion
import com.unciv.ui.utils.*
class PromotionPickerScreen(mapUnit: MapUnit) : PickerScreen() {
private var selectedPromotion: UnitPromotion? = null
private var selectedPromotion: Promotion? = null
init {
rightSideButton.setText("Pick promotion")
rightSideButton.addClickListener {
// todo add promotion to unit and decrease XP
mapUnit.promotions.addPromotion(selectedPromotion!!.name)
game.setWorldScreen()
dispose()
}
val availablePromotions = VerticalGroup()
availablePromotions.space(10f)
val unitType = mapUnit.getBaseUnit().unitType
for (promotion in GameBasics.UnitPromotions.values) {
if (!promotion.unitTypes.contains(mapUnit.getBaseUnit().unitType)) continue
if (!promotion.unitTypes.contains(unitType.toString())) continue
val isPromotionAvailable = promotion.prerequisites.all { mapUnit.promotions.promotions.contains(it) }
val unitHasPromotion = mapUnit.promotions.promotions.contains(promotion.name)
val promotionButton = Button(skin)
if(!isPromotionAvailable) promotionButton.color = Color.GRAY
promotionButton.add(ImageGetter.getPromotionIcon(promotion.name)).size(30f).pad(10f)
promotionButton.add(Label(promotion.name, skin)
.setFontColor(Color.WHITE)).pad(10f)
if(unitHasPromotion) promotionButton.color = Color.GREEN
promotionButton.addClickListener {
selectedPromotion = promotion
pick(promotion.name)
descriptionLabel.setText(promotion.effect)
rightSideButton.setText(promotion.name)
if(isPromotionAvailable && !unitHasPromotion) rightSideButton.enable()
else rightSideButton.disable()
var descriptionText = promotion.effect
if(promotion.prerequisites.isNotEmpty()) descriptionText +="\nRequires: "+promotion.prerequisites.joinToString()
descriptionLabel.setText(descriptionText)
}
availablePromotions.addActor(promotionButton)
}

View file

@ -5,6 +5,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
import com.unciv.logic.automation.UnitAutomation
import com.unciv.logic.battle.Battle
import com.unciv.logic.battle.BattleDamage
import com.unciv.logic.battle.ICombatant
import com.unciv.logic.battle.MapUnitCombatant
import com.unciv.models.gamebasics.unit.UnitType
@ -19,7 +20,7 @@ class BattleTable(val worldScreen: WorldScreen): Table() {
skin = CameraStageBaseScreen.skin
background = ImageGetter.getDrawable(ImageGetter.WhiteDot)
.tint(ImageGetter.getBlue())
pad(10f)
pad(5f)
}
fun hide(){
@ -66,17 +67,17 @@ class BattleTable(val worldScreen: WorldScreen): Table() {
add("Strength: "+defender.getDefendingStrength(attacker))
row().pad(5f)
val attackerModifiers = battle.getAttackModifiers(attacker,defender) .map { it.key+": "+(if(it.value>0)"+" else "")+(it.value*100).toInt()+"%" }
val defenderModifiers = battle.getDefenceModifiers(attacker, defender).map { it.key+": "+(if(it.value>0)"+" else "")+(it.value*100).toInt()+"%" }
val attackerModifiers = BattleDamage().getAttackModifiers(attacker,defender) .map { it.key+": "+(if(it.value>0)"+" else "")+(it.value*100).toInt()+"%" }
val defenderModifiers = BattleDamage().getDefenceModifiers(attacker, defender).map { it.key+": "+(if(it.value>0)"+" else "")+(it.value*100).toInt()+"%" }
for(i in 0..max(attackerModifiers.size,defenderModifiers.size)){
if (attackerModifiers.size > i) add(attackerModifiers[i]) else add()
if (defenderModifiers.size > i) add(defenderModifiers[i]) else add()
row().pad(5f)
row().pad(2f)
}
var damageToDefender = battle.calculateDamageToDefender(attacker,defender)
var damageToAttacker = battle.calculateDamageToAttacker(attacker,defender)
var damageToDefender = BattleDamage().calculateDamageToDefender(attacker,defender)
var damageToAttacker = BattleDamage().calculateDamageToAttacker(attacker,defender)
if (damageToAttacker>attacker.getHealth() && damageToDefender>defender.getHealth()) // when damage exceeds health, we don't want to show negative health numbers

View file

@ -1,11 +1,13 @@
package com.unciv.ui.worldscreen.unit
import com.unciv.UnCivGame
import com.unciv.logic.automation.WorkerAutomation
import com.unciv.logic.map.MapUnit
import com.unciv.models.gamebasics.Building
import com.unciv.models.gamebasics.GameBasics
import com.unciv.models.gamebasics.unit.UnitType
import com.unciv.ui.pickerscreens.ImprovementPickerScreen
import com.unciv.ui.pickerscreens.PromotionPickerScreen
import com.unciv.ui.pickerscreens.TechPickerScreen
import com.unciv.ui.worldscreen.WorldScreen
import java.util.*
@ -34,7 +36,6 @@ class UnitActions {
unitTable.currentlyExecutingAction = "moveTo"
}, unit.currentMovement != 0f )
}
else {
actionList +=
UnitAction("Stop movement", {
@ -43,9 +44,15 @@ class UnitActions {
},true)
}
if(unit.getBaseUnit().unitType!= UnitType.Civilian && !unit.hasUnique("No defensive terrain bonus")){
if(!unit.isFortified())
actionList += UnitAction("Fortify",{unit.action="Fortify 0"}, unit.currentMovement != 0f)
if(unit.getBaseUnit().unitType!= UnitType.Civilian
&& !unit.hasUnique("No defensive terrain bonus") && !unit.isFortified()) {
actionList += UnitAction("Fortify", { unit.action = "Fortify 0" }, unit.currentMovement != 0f)
}
if(unit.promotions.canBePromoted()){
actionList += UnitAction("Promote",
{UnCivGame.Current.screen = PromotionPickerScreen(unit)},
unit.currentMovement != 0f)
}
if(unit.getBaseUnit().upgradesTo!=null) {
@ -158,5 +165,4 @@ class UnitActions {
return actionList
}
}
}

View file

@ -21,6 +21,7 @@ class UnitActionsTable(val worldScreen: WorldScreen) : Table(){
"Move unit" -> return ImageGetter.getStatIcon("Movement")
"Stop movement"-> return ImageGetter.getStatIcon("Movement").apply { color= Color.RED }
"Fortify" -> return ImageGetter.getImage("OtherIcons/Shield.png").apply { color= Color.BLACK }
"Promote" -> return ImageGetter.getImage("OtherIcons/Star.png").apply { color= Color.GOLD }
"Construct improvement" -> return ImageGetter.getUnitIcon("Worker")
"Automate" -> return ImageGetter.getUnitIcon("Great Engineer")
"Stop automation" -> return ImageGetter.getImage("OtherIcons/Stop.png")

View file

@ -6,6 +6,7 @@ import com.unciv.logic.map.MapUnit
import com.unciv.logic.map.TileInfo
import com.unciv.models.gamebasics.unit.UnitType
import com.unciv.ui.utils.CameraStageBaseScreen
import com.unciv.ui.utils.ImageGetter
import com.unciv.ui.utils.addClickListener
import com.unciv.ui.utils.tr
import com.unciv.ui.worldscreen.WorldScreen
@ -14,26 +15,27 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){
private val prevIdleUnitButton = IdleUnitButton(this,worldScreen.tileMapHolder,true)
private val nextIdleUnitButton = IdleUnitButton(this,worldScreen.tileMapHolder,false)
private val unitNameLabel = Label("",CameraStageBaseScreen.skin)
private val promotionsTable = Table()
private val unitDescriptionLabel = Label("",CameraStageBaseScreen.skin)
var selectedUnit : MapUnit? = null
var currentlyExecutingAction : String? = null
init {
pad(20f)
pad(5f)
add(Table().apply {
add(prevIdleUnitButton)
add(unitNameLabel).pad(10f)
add(unitNameLabel).pad(5f)
add(nextIdleUnitButton)
}).colspan(2)
row()
}).colspan(2).row()
add(promotionsTable).row()
add(unitDescriptionLabel)
}
fun update() {
prevIdleUnitButton.update()
nextIdleUnitButton.update()
promotionsTable.clear()
unitDescriptionLabel.clearListeners()
if(selectedUnit!=null)
@ -58,6 +60,9 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){
if(unit.health<100) nameLabelText+=" ("+unit.health+")"
unitNameLabel.setText(nameLabelText)
for(promotion in unit.promotions.promotions)
promotionsTable.add(ImageGetter.getPromotionIcon(promotion)).size(20f)
var unitLabelText = "Movement".tr()+": " + unit.getMovementString()
if (unit.getBaseUnit().unitType != UnitType.Civilian) {
unitLabelText += "\n"+"Strength".tr()+": " + unit.getBaseUnit().strength
@ -65,6 +70,8 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){
if (unit.getBaseUnit().rangedStrength!=0)
unitLabelText += "\n"+"Ranged strength".tr()+": "+unit.getBaseUnit().rangedStrength
unitLabelText += "\n"+"XP".tr()+": "+unit.promotions.XP
if(unit.isFortified() && unit.getFortificationTurns()>0)
unitLabelText+="\n+"+unit.getFortificationTurns()*20+"% fortification"