Damage gets randomness as input

This commit is contained in:
Yair Morgenstern 2023-01-11 12:06:47 +02:00
parent e417c67ced
commit 20f64e2ce5
2 changed files with 12 additions and 13 deletions

View File

@ -242,31 +242,34 @@ object BattleDamage {
fun calculateDamageToAttacker( fun calculateDamageToAttacker(
attacker: ICombatant, attacker: ICombatant,
defender: ICombatant, defender: ICombatant,
ignoreRandomness: Boolean = false, /** Between 0 and 1. */
randomnessFactor: Float = Random(attacker.getCivInfo().gameInfo.turns * attacker.getTile().position.hashCode().toLong()).nextFloat()
): Int { ): Int {
if (attacker.isRanged() && !attacker.isAirUnit()) return 0 if (attacker.isRanged() && !attacker.isAirUnit()) return 0
if (defender.isCivilian()) return 0 if (defender.isCivilian()) return 0
val ratio = getAttackingStrength(attacker, defender) / getDefendingStrength( val ratio = getAttackingStrength(attacker, defender) / getDefendingStrength(
attacker, defender) attacker, defender)
return (damageModifier(ratio, true, attacker, ignoreRandomness) * getHealthDependantDamageRatio(defender)).roundToInt() return (damageModifier(ratio, true, randomnessFactor) * getHealthDependantDamageRatio(defender)).roundToInt()
} }
fun calculateDamageToDefender( fun calculateDamageToDefender(
attacker: ICombatant, attacker: ICombatant,
defender: ICombatant, defender: ICombatant,
ignoreRandomness: Boolean = false, /** Between 0 and 1. Defaults to turn and location-based random to avoid save scumming */
randomnessFactor: Float = Random(attacker.getCivInfo().gameInfo.turns * attacker.getTile().position.hashCode().toLong()).nextFloat()
,
): Int { ): Int {
if (defender.isCivilian()) return 40 if (defender.isCivilian()) return 40
val ratio = getAttackingStrength(attacker, defender) / getDefendingStrength( val ratio = getAttackingStrength(attacker, defender) / getDefendingStrength(
attacker, defender) attacker, defender)
return (damageModifier(ratio, false, attacker, ignoreRandomness) * getHealthDependantDamageRatio(attacker)).roundToInt() return (damageModifier(ratio, false, randomnessFactor) * getHealthDependantDamageRatio(attacker)).roundToInt()
} }
private fun damageModifier( private fun damageModifier(
attackerToDefenderRatio: Float, attackerToDefenderRatio: Float,
damageToAttacker: Boolean, damageToAttacker: Boolean,
attacker: ICombatant, // for the randomness /** Between 0 and 1. */
ignoreRandomness: Boolean = false, randomnessFactor: Float,
): Float { ): Float {
// https://forums.civfanatics.com/threads/getting-the-combat-damage-math.646582/#post-15468029 // https://forums.civfanatics.com/threads/getting-the-combat-damage-math.646582/#post-15468029
val strongerToWeakerRatio = val strongerToWeakerRatio =
@ -274,14 +277,10 @@ object BattleDamage {
var ratioModifier = (((strongerToWeakerRatio + 3) / 4).pow(4) + 1) / 2 var ratioModifier = (((strongerToWeakerRatio + 3) / 4).pow(4) + 1) / 2
if (damageToAttacker && attackerToDefenderRatio > 1 || !damageToAttacker && attackerToDefenderRatio < 1) // damage ratio from the weaker party is inverted if (damageToAttacker && attackerToDefenderRatio > 1 || !damageToAttacker && attackerToDefenderRatio < 1) // damage ratio from the weaker party is inverted
ratioModifier = ratioModifier.pow(-1) ratioModifier = ratioModifier.pow(-1)
val randomSeed = attacker.getCivInfo().gameInfo.turns * attacker.getTile().position.hashCode() // so people don't save-scum to get optimal results val randomCenteredAround30 = 24 + 12 * randomnessFactor
val randomCenteredAround30 = 24 +
if (ignoreRandomness) 6f
else 12 * Random(randomSeed.toLong()).nextFloat()
return randomCenteredAround30 * ratioModifier return randomCenteredAround30 * ratioModifier
} }
} }
enum class CombatAction { enum class CombatAction {
Attack, Attack,
Defend, Defend,

View File

@ -186,8 +186,8 @@ class BattleTable(val worldScreen: WorldScreen): Table() {
row() row()
} }
var damageToDefender = BattleDamage.calculateDamageToDefender(attacker, defender, true) var damageToDefender = BattleDamage.calculateDamageToDefender(attacker, defender, 0.5f)
var damageToAttacker = BattleDamage.calculateDamageToAttacker(attacker, defender, true) var damageToAttacker = BattleDamage.calculateDamageToAttacker(attacker, defender, 0.5f)
if (damageToAttacker > attacker.getHealth() && damageToDefender > defender.getHealth()) { if (damageToAttacker > attacker.getHealth() && damageToDefender > defender.getHealth()) {
// when damage exceeds health, we don't want to show negative health numbers // when damage exceeds health, we don't want to show negative health numbers