mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-31 15:19:29 +07:00
Slight optimization of getAttackableEnemies (#7353)
This commit is contained in:

committed by
GitHub

parent
716d5d3214
commit
1649b236bb
@ -33,27 +33,12 @@ object BattleHelper {
|
||||
}
|
||||
|
||||
fun getAttackableEnemies(
|
||||
unit: MapUnit,
|
||||
unitDistanceToTiles: PathsToTilesWithinTurn,
|
||||
tilesToCheck: List<TileInfo>? = null,
|
||||
stayOnTile: Boolean = false
|
||||
unit: MapUnit,
|
||||
unitDistanceToTiles: PathsToTilesWithinTurn,
|
||||
tilesToCheck: List<TileInfo>? = null,
|
||||
stayOnTile: Boolean = false
|
||||
): ArrayList<AttackableTile> {
|
||||
val tilesWithEnemies = (tilesToCheck ?: unit.civInfo.viewableTiles)
|
||||
.filter { containsAttackableEnemy(it, MapUnitCombatant(unit)) }
|
||||
// Filter out invalid Civilian Captures
|
||||
.filterNot {
|
||||
val mapCombatant = Battle.getMapCombatantOfTile(it)
|
||||
// IF all of these are true, THEN the action we'll be taking is in fact CAPTURING the civilian.
|
||||
unit.baseUnit.isMelee() && mapCombatant is MapUnitCombatant && mapCombatant.unit.isCivilian()
|
||||
// If we can't pass though that tile, we can't capture the civilian "remotely"
|
||||
// Can use "unit.movement.canPassThrough(it)" now that we can move through
|
||||
// unguarded Civilian tiles. And this catches Naval trying to capture Land
|
||||
// Civilians or Land attacking Water Civilians it can't Embark on
|
||||
&& !unit.movement.canPassThrough(it)
|
||||
}
|
||||
|
||||
val rangeOfAttack = unit.getRange()
|
||||
|
||||
val attackableTiles = ArrayList<AttackableTile>()
|
||||
|
||||
val unitMustBeSetUp = unit.hasUnique(UniqueType.MustSetUp)
|
||||
@ -77,6 +62,8 @@ object BattleHelper {
|
||||
it.first == unit.getTile() || unit.movement.canMoveTo(it.first)
|
||||
}
|
||||
|
||||
val tilesWithEnemies: HashSet<TileInfo> = HashSet()
|
||||
val tilesWithoutEnemies: HashSet<TileInfo> = HashSet()
|
||||
for ((reachableTile, movementLeft) in tilesToAttackFrom) { // tiles we'll still have energy after we reach there
|
||||
val tilesInAttackRange =
|
||||
if (unit.hasUnique(UniqueType.IndirectFire) || unit.baseUnit.movesLikeAirUnits())
|
||||
@ -84,12 +71,27 @@ object BattleHelper {
|
||||
else reachableTile.getViewableTilesList(rangeOfAttack)
|
||||
.asSequence()
|
||||
|
||||
attackableTiles += tilesInAttackRange.filter { it in tilesWithEnemies }
|
||||
.map { AttackableTile(reachableTile, it, movementLeft) }
|
||||
for (tile in tilesInAttackRange) {
|
||||
if (tile in tilesWithEnemies) attackableTiles += AttackableTile(reachableTile, tile, movementLeft)
|
||||
else if (tile in tilesWithoutEnemies) continue // avoid checking the same empty tile multiple times
|
||||
else if (checkTile(unit, tile, tilesToCheck)) {
|
||||
tilesWithEnemies += tile
|
||||
attackableTiles += AttackableTile(reachableTile, tile, movementLeft)
|
||||
} else {
|
||||
tilesWithoutEnemies += tile
|
||||
}
|
||||
}
|
||||
}
|
||||
return attackableTiles
|
||||
}
|
||||
|
||||
private fun checkTile(unit: MapUnit, tile: TileInfo, tilesToCheck: List<TileInfo>?): Boolean {
|
||||
if (!containsAttackableEnemy(tile, MapUnitCombatant(unit))) return false
|
||||
if (tile !in (tilesToCheck ?: unit.civInfo.viewableTiles)) return false
|
||||
val mapCombatant = Battle.getMapCombatantOfTile(tile)
|
||||
return (!unit.baseUnit.isMelee() || mapCombatant !is MapUnitCombatant || !mapCombatant.unit.isCivilian() || unit.movement.canPassThrough(tile))
|
||||
}
|
||||
|
||||
fun containsAttackableEnemy(tile: TileInfo, combatant: ICombatant): Boolean {
|
||||
if (combatant is MapUnitCombatant && combatant.unit.isEmbarked() && !combatant.hasUnique(UniqueType.AttackOnSea)) {
|
||||
// Can't attack water units while embarked, only land
|
||||
|
Reference in New Issue
Block a user