Better AI targeting (#7359)

This commit is contained in:
OptimizedForDensity
2022-07-04 09:34:33 -04:00
committed by GitHub
parent f0a4922711
commit 8203557633
2 changed files with 38 additions and 5 deletions

View File

@ -166,11 +166,35 @@ object BattleHelper {
enemyTileToAttack = capturableCity // enter it quickly, top priority!
else if (nonCityTilesToAttack.isNotEmpty()) // second priority, units
enemyTileToAttack = nonCityTilesToAttack.minByOrNull {
Battle.getMapCombatantOfTile(it.tileToAttack)!!.getHealth()
}
enemyTileToAttack = chooseUnitToAttack(unit, nonCityTilesToAttack)
else if (cityWithHealthLeft != null) enemyTileToAttack = cityWithHealthLeft // third priority, city
return enemyTileToAttack
}
private fun chooseUnitToAttack(unit: MapUnit, attackableUnits: List<AttackableTile>): AttackableTile {
val militaryUnits = attackableUnits.filter { it.tileToAttack.militaryUnit != null }
// prioritize attacking military
if (militaryUnits.isNotEmpty()) {
// associate enemy units with number of hits from this unit to kill them
val attacksToKill = militaryUnits
.associateWith { it.tileToAttack.militaryUnit!!.health.toFloat() / BattleDamage.calculateDamageToDefender(
MapUnitCombatant(unit),
MapUnitCombatant(it.tileToAttack.militaryUnit!!)
).toFloat().coerceAtLeast(1f) }
// kill a unit if possible, prioritizing by attack strength
val canKill = attacksToKill.filter { it.value <= 1 }.maxByOrNull { MapUnitCombatant(it.key.tileToAttack.militaryUnit!!).getAttackingStrength() }?.key
if (canKill != null) return canKill
// otherwise pick the unit we can kill the fastest
return attacksToKill.minByOrNull { it.value }!!.key
}
// only civilians in attacking range
return attackableUnits.minByOrNull {
Battle.getMapCombatantOfTile(it.tileToAttack)!!.getHealth()
}!!
}
}

View File

@ -528,13 +528,22 @@ object UnitAutomation {
val siegeUnits = targets
.filter { it is MapUnitCombatant && it.unit.baseUnit.isProbablySiegeUnit() }
if (siegeUnits.any()) targets = siegeUnits
val nonEmbarkedSiege = siegeUnits.filter { it is MapUnitCombatant && !it.unit.isEmbarked() }
if (nonEmbarkedSiege.any()) targets = nonEmbarkedSiege
else if (siegeUnits.any()) targets = siegeUnits
else {
val rangedUnits = targets
.filter { it.isRanged() }
if (rangedUnits.any()) targets = rangedUnits
}
return targets.minByOrNull { it.getHealth() }
val hitsToKill = targets.associateWith { it.getHealth().toFloat() / BattleDamage.calculateDamageToDefender(
CityCombatant(city),
it
).toFloat().coerceAtLeast(1f) }
val target = hitsToKill.filter { it.value <= 1 }.maxByOrNull { it.key.getAttackingStrength() }?.key
if (target != null) return target
return hitsToKill.minByOrNull { it.value }?.key
}
private fun tryTakeBackCapturedCity(unit: MapUnit): Boolean {