mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-25 21:03:15 -04:00
Slight optimization of getAttackableEnemies (#7353)
This commit is contained in:
parent
716d5d3214
commit
1649b236bb
@ -33,27 +33,12 @@ object BattleHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getAttackableEnemies(
|
fun getAttackableEnemies(
|
||||||
unit: MapUnit,
|
unit: MapUnit,
|
||||||
unitDistanceToTiles: PathsToTilesWithinTurn,
|
unitDistanceToTiles: PathsToTilesWithinTurn,
|
||||||
tilesToCheck: List<TileInfo>? = null,
|
tilesToCheck: List<TileInfo>? = null,
|
||||||
stayOnTile: Boolean = false
|
stayOnTile: Boolean = false
|
||||||
): ArrayList<AttackableTile> {
|
): 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 rangeOfAttack = unit.getRange()
|
||||||
|
|
||||||
val attackableTiles = ArrayList<AttackableTile>()
|
val attackableTiles = ArrayList<AttackableTile>()
|
||||||
|
|
||||||
val unitMustBeSetUp = unit.hasUnique(UniqueType.MustSetUp)
|
val unitMustBeSetUp = unit.hasUnique(UniqueType.MustSetUp)
|
||||||
@ -77,6 +62,8 @@ object BattleHelper {
|
|||||||
it.first == unit.getTile() || unit.movement.canMoveTo(it.first)
|
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
|
for ((reachableTile, movementLeft) in tilesToAttackFrom) { // tiles we'll still have energy after we reach there
|
||||||
val tilesInAttackRange =
|
val tilesInAttackRange =
|
||||||
if (unit.hasUnique(UniqueType.IndirectFire) || unit.baseUnit.movesLikeAirUnits())
|
if (unit.hasUnique(UniqueType.IndirectFire) || unit.baseUnit.movesLikeAirUnits())
|
||||||
@ -84,12 +71,27 @@ object BattleHelper {
|
|||||||
else reachableTile.getViewableTilesList(rangeOfAttack)
|
else reachableTile.getViewableTilesList(rangeOfAttack)
|
||||||
.asSequence()
|
.asSequence()
|
||||||
|
|
||||||
attackableTiles += tilesInAttackRange.filter { it in tilesWithEnemies }
|
for (tile in tilesInAttackRange) {
|
||||||
.map { AttackableTile(reachableTile, it, movementLeft) }
|
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
|
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 {
|
fun containsAttackableEnemy(tile: TileInfo, combatant: ICombatant): Boolean {
|
||||||
if (combatant is MapUnitCombatant && combatant.unit.isEmbarked() && !combatant.hasUnique(UniqueType.AttackOnSea)) {
|
if (combatant is MapUnitCombatant && combatant.unit.isEmbarked() && !combatant.hasUnique(UniqueType.AttackOnSea)) {
|
||||||
// Can't attack water units while embarked, only land
|
// Can't attack water units while embarked, only land
|
||||||
|
Loading…
x
Reference in New Issue
Block a user