mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-27 22:06:05 -04:00
Better AI targeting (#7359)
This commit is contained in:
parent
f0a4922711
commit
8203557633
@ -166,11 +166,35 @@ object BattleHelper {
|
|||||||
enemyTileToAttack = capturableCity // enter it quickly, top priority!
|
enemyTileToAttack = capturableCity // enter it quickly, top priority!
|
||||||
|
|
||||||
else if (nonCityTilesToAttack.isNotEmpty()) // second priority, units
|
else if (nonCityTilesToAttack.isNotEmpty()) // second priority, units
|
||||||
enemyTileToAttack = nonCityTilesToAttack.minByOrNull {
|
enemyTileToAttack = chooseUnitToAttack(unit, nonCityTilesToAttack)
|
||||||
Battle.getMapCombatantOfTile(it.tileToAttack)!!.getHealth()
|
|
||||||
}
|
|
||||||
else if (cityWithHealthLeft != null) enemyTileToAttack = cityWithHealthLeft // third priority, city
|
else if (cityWithHealthLeft != null) enemyTileToAttack = cityWithHealthLeft // third priority, city
|
||||||
|
|
||||||
return enemyTileToAttack
|
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()
|
||||||
|
}!!
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -528,13 +528,22 @@ object UnitAutomation {
|
|||||||
|
|
||||||
val siegeUnits = targets
|
val siegeUnits = targets
|
||||||
.filter { it is MapUnitCombatant && it.unit.baseUnit.isProbablySiegeUnit() }
|
.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 {
|
else {
|
||||||
val rangedUnits = targets
|
val rangedUnits = targets
|
||||||
.filter { it.isRanged() }
|
.filter { it.isRanged() }
|
||||||
if (rangedUnits.any()) targets = rangedUnits
|
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 {
|
private fun tryTakeBackCapturedCity(unit: MapUnit): Boolean {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user