mirror of
https://github.com/yairm210/Unciv.git
synced 2025-01-05 21:11:35 +07:00
Fixed AI unit attack decision making (#10036)
* Limited the impact of a high attacksToKill value * Fixed chooseAttackTarget returning nothing when attackableEnemies only has one element
This commit is contained in:
parent
ac5e51dbea
commit
087c2a0946
@ -9,7 +9,6 @@ import com.unciv.logic.city.City
|
|||||||
import com.unciv.logic.battle.TargetHelper
|
import com.unciv.logic.battle.TargetHelper
|
||||||
import com.unciv.logic.map.mapunit.MapUnit
|
import com.unciv.logic.map.mapunit.MapUnit
|
||||||
import com.unciv.models.ruleset.unique.UniqueType
|
import com.unciv.models.ruleset.unique.UniqueType
|
||||||
import kotlin.math.max
|
|
||||||
|
|
||||||
object BattleHelper {
|
object BattleHelper {
|
||||||
|
|
||||||
@ -59,15 +58,21 @@ object BattleHelper {
|
|||||||
* Choses the best target in attackableEnemies, this could be a city or a unit.
|
* Choses the best target in attackableEnemies, this could be a city or a unit.
|
||||||
*/
|
*/
|
||||||
private fun chooseAttackTarget(unit: MapUnit, attackableEnemies: List<AttackableTile>): AttackableTile? {
|
private fun chooseAttackTarget(unit: MapUnit, attackableEnemies: List<AttackableTile>): AttackableTile? {
|
||||||
|
// Get the highest valued attackableEnemy
|
||||||
var highestAttackValue = 0
|
var highestAttackValue = 0
|
||||||
val attackTile = attackableEnemies.maxByOrNull { attackableEnemy ->
|
var attackTile: AttackableTile? = null
|
||||||
|
// We always have to calculate the attack value even if there is only one attackableEnemy
|
||||||
|
for (attackableEnemy in attackableEnemies) {
|
||||||
val tempAttackValue = if (attackableEnemy.tileToAttack.isCityCenter())
|
val tempAttackValue = if (attackableEnemy.tileToAttack.isCityCenter())
|
||||||
getCityAttackValue(unit, attackableEnemy.tileToAttack.getCity()!!)
|
getCityAttackValue(unit, attackableEnemy.tileToAttack.getCity()!!)
|
||||||
else getUnitAttackValue(unit, attackableEnemy)
|
else getUnitAttackValue(unit, attackableEnemy)
|
||||||
highestAttackValue = max(tempAttackValue, highestAttackValue)
|
if (tempAttackValue > highestAttackValue) {
|
||||||
tempAttackValue
|
highestAttackValue = tempAttackValue
|
||||||
|
attackTile = attackableEnemy
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// todo For air units, prefer to attack tiles with lower intercept chance
|
// todo For air units, prefer to attack tiles with lower intercept chance
|
||||||
|
// Only return that tile if it is actually a good tile to attack
|
||||||
return if (highestAttackValue > 30) attackTile else null
|
return if (highestAttackValue > 30) attackTile else null
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +129,8 @@ object BattleHelper {
|
|||||||
attackValue = 100
|
attackValue = 100
|
||||||
// Associate enemy units with number of hits from this unit to kill them
|
// Associate enemy units with number of hits from this unit to kill them
|
||||||
val attacksToKill = (militaryUnit.health.toFloat() /
|
val attacksToKill = (militaryUnit.health.toFloat() /
|
||||||
BattleDamage.calculateDamageToDefender(MapUnitCombatant(attacker), MapUnitCombatant(militaryUnit))).coerceAtLeast(1f)
|
BattleDamage.calculateDamageToDefender(MapUnitCombatant(attacker), MapUnitCombatant(militaryUnit)))
|
||||||
|
.coerceAtLeast(1f).coerceAtMost(10f)
|
||||||
// We can kill them in this turn
|
// We can kill them in this turn
|
||||||
if (attacksToKill <= 1) attackValue += 30
|
if (attacksToKill <= 1) attackValue += 30
|
||||||
// On average, this should take around 3 turns, so -15
|
// On average, this should take around 3 turns, so -15
|
||||||
|
Loading…
Reference in New Issue
Block a user