Merge 2c5ada9871d1af9abd745e1836aea0f373126b01 into d51ef24c205b6b05330b3c4d7ce79c402db44447

This commit is contained in:
ahpakar 2025-09-18 13:09:14 +00:00 committed by GitHub
commit 751d7311a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 91 additions and 39 deletions

View File

@ -137,10 +137,11 @@ class BattleTable(val worldScreen: WorldScreen) : Table() {
} }
private fun getIcon(combatant: ICombatant) = private fun getIcon(combatant: ICombatant) =
if (combatant is MapUnitCombatant) UnitIconGroup(combatant.unit,25f) if (combatant is MapUnitCombatant) UnitIconGroup(combatant.unit, 25f)
else ImageGetter.getNationPortrait(combatant.getCivInfo().nation, 25f) else ImageGetter.getNationPortrait(combatant.getCivInfo().nation, 25f)
private val quarterScreen = worldScreen.stage.width / 4 private val quarterScreen = worldScreen.stage.width / 4
private val viewportWidthSixth = worldScreen.stage.width / 6
private fun getModifierTable(key: String, value: Int) = Table().apply { private fun getModifierTable(key: String, value: Int) = Table().apply {
val description = if (key.startsWith("vs ")) val description = if (key.startsWith("vs "))
@ -150,36 +151,47 @@ class BattleTable(val worldScreen: WorldScreen) : Table() {
val upOrDownLabel = if (value > 0f) "".toLabel(Color.GREEN) val upOrDownLabel = if (value > 0f) "".toLabel(Color.GREEN)
else "".toLabel(Color.RED) else "".toLabel(Color.RED)
add(upOrDownLabel) add(upOrDownLabel).padRight(16f)
val modifierLabel = "$percentage $description".toLabel(fontSize = 14).apply { wrap = true } val modifierLabel = "$percentage $description".toLabel(fontSize = 12, alignment = Align.right).apply { wrap = true }
add(modifierLabel).width(quarterScreen - upOrDownLabel.minWidth) add(modifierLabel).width(viewportWidthSixth - upOrDownLabel.minWidth)
} }
private fun getAttackerNameWrapper(combatant: ICombatant) = Table().apply {
add(combatant.getName().toLabel(
fontSize = 28, // 16 * 1.75
alignment = Align.right,
hideIcons = true));
add(getIcon(combatant)).padLeft(8f)
};
private fun getDefenderNameWrapper(combatant: ICombatant) = Table().apply {
add(getIcon(combatant)).padRight(8f)
add(combatant.getName().toLabel(
fontSize = 28,
alignment = Align.left,
hideIcons = true))
};
private fun simulateBattle(attacker: ICombatant, defender: ICombatant, tileToAttackFrom: Tile) { private fun simulateBattle(attacker: ICombatant, defender: ICombatant, tileToAttackFrom: Tile) {
clear() clear()
val attackerNameWrapper = Table() add(getAttackerNameWrapper(attacker)).right().padBottom(8f)
val attackerLabel = attacker.getName().toLabel(hideIcons = true) add(getDefenderNameWrapper(defender)).left().padBottom(8f)
attackerNameWrapper.add(getIcon(attacker)).padRight(5f) row()
attackerNameWrapper.add(attackerLabel)
add(attackerNameWrapper)
val defenderNameWrapper = Table()
val defenderLabel = Label(defender.getName().tr(hideIcons = true), skin)
defenderNameWrapper.add(getIcon(defender)).padRight(5f)
defenderNameWrapper.add(defenderLabel)
add(defenderNameWrapper).row()
addSeparator().pad(0f)
val attackIcon = if (attacker.isRanged()) Fonts.rangedStrength else Fonts.strength val attackIcon = if (attacker.isRanged()) Fonts.rangedStrength else Fonts.strength
val defenceIcon = val defenceIcon =
if (attacker.isRanged() && defender.isRanged() && !defender.isCity() && !(defender is MapUnitCombatant && defender.unit.isEmbarked())) if (attacker.isRanged() && defender.isRanged() && !defender.isCity() && !(defender is MapUnitCombatant && defender.unit.isEmbarked()))
Fonts.rangedStrength Fonts.rangedStrength
else Fonts.strength // use strength icon if attacker is melee, defender is melee, defender is a city, or defender is embarked else Fonts.strength // use strength icon if attacker is melee, defender is melee, defender is a city, or defender is embarked
add(attacker.getAttackingStrength().tr() + attackIcon)
add(defender.getDefendingStrength(attacker.isRanged()).tr() + defenceIcon).row() val attackerTrueStrengthString =
BattleDamage.getAttackingStrength(attacker, defender, tileToAttackFrom).roundToInt().toString() + attackIcon;
val defenderTrueStrengthString =
defenceIcon + BattleDamage.getDefendingStrength(attacker, defender, tileToAttackFrom).roundToInt().toString();
add(attackerTrueStrengthString.toLabel(fontSize = 24, alignment = Align.right)).right().padBottom(16f)
add(defenderTrueStrengthString.toLabel(fontSize = 24, alignment = Align.left)).left().padBottom(16f)
row()
val attackerModifiers = val attackerModifiers =
BattleDamage.getAttackModifiers(attacker, defender, tileToAttackFrom).map { BattleDamage.getAttackModifiers(attacker, defender, tileToAttackFrom).map {
@ -192,18 +204,42 @@ class BattleTable(val worldScreen: WorldScreen) : Table() {
} }
else listOf() else listOf()
for (i in 0..max(attackerModifiers.size, defenderModifiers.size)) {
if (i < attackerModifiers.size) add(attackerModifiers[i]) else add().width(quarterScreen)
if (i < defenderModifiers.size) add(defenderModifiers[i]) else add().width(quarterScreen)
row().pad(2f)
}
if (attackerModifiers.any() || defenderModifiers.any()) { if (attackerModifiers.any() || defenderModifiers.any()) {
addSeparator() val attackerModifiersTable = Table()
val attackerStrength = BattleDamage.getAttackingStrength(attacker, defender, tileToAttackFrom).roundToInt() val defenderModifiersTable = Table()
val defenderStrength = BattleDamage.getDefendingStrength(attacker, defender, tileToAttackFrom).roundToInt()
add(attackerStrength.tr() + attackIcon) val attackerBaseStrengthLabel =
add(defenderStrength.tr() + attackIcon).row() ("Base value".tr() + " " + attacker.getAttackingStrength().toString() + attackIcon).toLabel(
fontSize = 12,
alignment = Align.right);
val defenderBaseStrengthLabel =
("Base value".tr() + " " + defender.getDefendingStrength(attacker.isRanged()).toString() + defenceIcon).toLabel(
fontSize = 12,
alignment = Align.right);
attackerModifiersTable.add(attackerBaseStrengthLabel).top().right().row()
defenderModifiersTable.add(defenderBaseStrengthLabel).top().right().row()
val maxModifierArraySize = max(attackerModifiers.size, defenderModifiers.size);
for (i in 0..maxModifierArraySize) {
attackerModifiersTable.run {
if (i < attackerModifiers.size) add(attackerModifiers[i]).right() else add()
if (i != maxModifierArraySize) {
row().padBottom(3f)
}
}
defenderModifiersTable.run {
if (i < defenderModifiers.size) add(defenderModifiers[i]).right() else add()
if (i != maxModifierArraySize) {
row().padBottom(3f)
}
}
}
add(attackerModifiersTable).top().padBottom(16f)
add(defenderModifiersTable).top().padBottom(16f)
row();
} }
// from Battle.addXp(), check for can't gain more XP from Barbarians // from Battle.addXp(), check for can't gain more XP from Barbarians
@ -239,21 +275,37 @@ class BattleTable(val worldScreen: WorldScreen) : Table() {
val minRemainingLifeDefender = max(defenderHealth-maxDamageToDefender, 0) val minRemainingLifeDefender = max(defenderHealth-maxDamageToDefender, 0)
val maxRemainingLifeDefender = max(defenderHealth-minDamageToDefender, 0) val maxRemainingLifeDefender = max(defenderHealth-minDamageToDefender, 0)
add(getHealthBar(attacker.getMaxHealth(), attacker.getHealth(), maxRemainingLifeAttacker, minRemainingLifeAttacker)) add(getHealthBar(attacker.getMaxHealth(), attacker.getHealth(), maxRemainingLifeAttacker, minRemainingLifeAttacker)).right()
add(getHealthBar(defender.getMaxHealth(), defender.getHealth(), maxRemainingLifeDefender, minRemainingLifeDefender, true)).row() add(getHealthBar(defender.getMaxHealth(), defender.getHealth(), maxRemainingLifeDefender, minRemainingLifeDefender, true)).left()
row()
fun avg(vararg values: Int) = values.average().roundToInt() fun avg(vararg values: Int) = values.average().roundToInt()
// Don't use original damage estimates - they're raw, before clamping to 0..max // Don't use original damage estimates - they're raw, before clamping to 0..max
val avgDamageToDefender = avg(defenderHealth - minRemainingLifeDefender, defenderHealth - maxRemainingLifeDefender) val avgDamageToDefender = avg(defenderHealth - minRemainingLifeDefender, defenderHealth - maxRemainingLifeDefender)
val avgDamageToAttacker = avg(attackerHealth - minRemainingLifeAttacker, attackerHealth - maxRemainingLifeAttacker) val avgDamageToAttacker = avg(attackerHealth - minRemainingLifeAttacker, attackerHealth - maxRemainingLifeAttacker)
if (minRemainingLifeAttacker == attackerHealth) add(attackerHealth.toLabel()) val attackerHealthString: String
else if (maxRemainingLifeAttacker == minRemainingLifeAttacker) add("$attackerHealth$maxRemainingLifeAttacker ($avgDamageToAttacker)".toLabel()) val defenderHealthString: String
else add("$attackerHealth$minRemainingLifeAttacker-$maxRemainingLifeAttacker (~$avgDamageToAttacker)".toLabel()) val showAttackerExact = (minRemainingLifeAttacker == maxRemainingLifeAttacker)
val showDefenderExact = (minRemainingLifeDefender == maxRemainingLifeDefender)
if (minRemainingLifeAttacker == attackerHealth) attackerHealthString = attackerHealth.toString()
else if (showAttackerExact)
attackerHealthString = "$attackerHealth$maxRemainingLifeAttacker"
else
attackerHealthString = "$attackerHealth$minRemainingLifeAttacker$maxRemainingLifeAttacker"
if (minRemainingLifeDefender == maxRemainingLifeDefender) add("$defenderHealth$maxRemainingLifeDefender ($avgDamageToDefender)".toLabel()) add(attackerHealthString.toLabel(alignment = Align.right)).right().padBottom(0f)
else add("$defenderHealth$minRemainingLifeDefender-$maxRemainingLifeDefender (~$avgDamageToDefender)".toLabel())
if (showDefenderExact)
defenderHealthString = "$defenderHealth$maxRemainingLifeDefender"
else
defenderHealthString = "$defenderHealth$minRemainingLifeDefender$maxRemainingLifeDefender"
add(defenderHealthString.toLabel()).left().padBottom(0f).row()
add(("Average".tr() + ": $avgDamageToAttacker").toLabel(fontSize = 12, alignment = Align.right)).right()
add(("Average".tr() + ": $avgDamageToDefender").toLabel(fontSize = 12, alignment = Align.left)).left()
} }
row().pad(5f) row().pad(5f)

View File

@ -231,7 +231,7 @@ object BattleTableHelpers {
val totalWidth = 120f val totalWidth = 120f
fun addHealthToBar(image: Image, amount: Int) { fun addHealthToBar(image: Image, amount: Int) {
val width = totalWidth * amount / maxHealth val width = totalWidth * amount / maxHealth
healthBar.add(image).size(width.coerceIn(0f, totalWidth),4f) healthBar.add(image).size(width.coerceIn(0f, totalWidth), 8f)
} }
fun animateHealth(health: Image, healthDecreaseWidth: Float, move: Float) { fun animateHealth(health: Image, healthDecreaseWidth: Float, move: Float) {