Withdraw chances can stack

This commit is contained in:
Yair Morgenstern 2022-02-09 12:15:10 +02:00
parent 967b70a4b9
commit 644c61a851

View File

@ -77,8 +77,8 @@ object Battle {
// Withdraw from melee ability // Withdraw from melee ability
if (attacker is MapUnitCombatant && attacker.isMelee() && defender is MapUnitCombatant) { if (attacker is MapUnitCombatant && attacker.isMelee() && defender is MapUnitCombatant) {
val withdraw = defender.unit.getMatchingUniques(UniqueType.MayWithdraw) val withdraw = defender.unit.getMatchingUniques(UniqueType.MayWithdraw)
.maxByOrNull{ it.params[0] } // If a mod allows multiple withdraw properties, ensure the best is used .sumOf{ it.params[0].toInt() } // If a mod allows multiple withdraw properties, ensure the best is used
if (withdraw != null && doWithdrawFromMeleeAbility(attacker, defender, withdraw)) return if (withdraw != 0 && doWithdrawFromMeleeAbility(attacker, defender, withdraw)) return
} }
val isAlreadyDefeatedCity = defender is CityCombatant && defender.isDefeated() val isAlreadyDefeatedCity = defender is CityCombatant && defender.isDefeated()
@ -811,7 +811,7 @@ object Battle {
} }
} }
private fun doWithdrawFromMeleeAbility(attacker: ICombatant, defender: ICombatant, withdrawUnique: Unique): Boolean { private fun doWithdrawFromMeleeAbility(attacker: ICombatant, defender: ICombatant, baseWithdrawChance: Int): Boolean {
// Some notes... // Some notes...
// unit.getUniques() is a union of BaseUnit uniques and Promotion effects. // unit.getUniques() is a union of BaseUnit uniques and Promotion effects.
// according to some strategy guide the Slinger's withdraw ability is inherited on upgrade, // according to some strategy guide the Slinger's withdraw ability is inherited on upgrade,
@ -830,8 +830,6 @@ object Battle {
|| defendBaseUnit.isLandUnit() && !tile.isLand // forbid retreat from land to sea - embarked already excluded || defendBaseUnit.isLandUnit() && !tile.isLand // forbid retreat from land to sea - embarked already excluded
|| tile.isCityCenter() && tile.getOwner() != defender.getCivInfo() // forbid retreat into the city which doesn't belong to the defender || tile.isCityCenter() && tile.getOwner() != defender.getCivInfo() // forbid retreat into the city which doesn't belong to the defender
} }
// base chance for all units is set to 80%
val baseChance = withdrawUnique.params[0].toFloat()
/* Calculate success chance: Base chance from json, calculation method from https://www.bilibili.com/read/cv2216728 /* Calculate success chance: Base chance from json, calculation method from https://www.bilibili.com/read/cv2216728
In general, except attacker's tile, 5 tiles neighbors the defender : In general, except attacker's tile, 5 tiles neighbors the defender :
2 of which are also attacker's neighbors ( we call them 2-Tiles) and the other 3 aren't (we call them 3-Tiles). 2 of which are also attacker's neighbors ( we call them 2-Tiles) and the other 3 aren't (we call them 3-Tiles).
@ -840,7 +838,7 @@ object Battle {
If 3-Tiles the defender can withdraw to is null, we choose this from 2-Tiles the defender can withdraw to. If 3-Tiles the defender can withdraw to is null, we choose this from 2-Tiles the defender can withdraw to.
If 2-Tiles the defender can withdraw to is also null, we return false. If 2-Tiles the defender can withdraw to is also null, we return false.
*/ */
val percentChance = baseChance - max(0, (attackBaseUnit.movement-2)) * 20 - val percentChance = baseWithdrawChance - max(0, (attackBaseUnit.movement-2)) * 20 -
fromTile.neighbors.filterNot { it == attTile || it in attTile.neighbors }.count { canNotWithdrawTo(it) } * 20 fromTile.neighbors.filterNot { it == attTile || it in attTile.neighbors }.count { canNotWithdrawTo(it) } * 20
// Get a random number in [0,100) : if the number <= percentChance, defender will withdraw from melee // Get a random number in [0,100) : if the number <= percentChance, defender will withdraw from melee
if (Random().nextInt(100) > percentChance) return false if (Random().nextInt(100) > percentChance) return false