mirror of
https://github.com/yairm210/Unciv.git
synced 2025-01-05 21:11:35 +07:00
Refactor: Move checking targets from automation to logic (#9945)
* Move checking targets from automation to logic * Ending newline, move attackable tile * move getBombardableTiles for similar reasons * fix package name * remove import
This commit is contained in:
parent
7cb39dcecf
commit
08a04d3575
@ -1,21 +1,18 @@
|
||||
package com.unciv.logic.automation.unit
|
||||
|
||||
import com.unciv.Constants
|
||||
import com.unciv.logic.battle.AttackableTile
|
||||
import com.unciv.logic.battle.Battle
|
||||
import com.unciv.logic.battle.BattleDamage
|
||||
import com.unciv.logic.battle.CityCombatant
|
||||
import com.unciv.logic.battle.ICombatant
|
||||
import com.unciv.logic.battle.MapUnitCombatant
|
||||
import com.unciv.logic.battle.TargetHelper
|
||||
import com.unciv.logic.map.mapunit.MapUnit
|
||||
import com.unciv.logic.map.mapunit.PathsToTilesWithinTurn
|
||||
import com.unciv.logic.map.tile.Tile
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
|
||||
object BattleHelper {
|
||||
|
||||
fun tryAttackNearbyEnemy(unit: MapUnit, stayOnTile: Boolean = false): Boolean {
|
||||
if (unit.hasUnique(UniqueType.CannotAttack)) return false
|
||||
val attackableEnemies = getAttackableEnemies(unit, unit.movement.getDistanceToTiles(), stayOnTile=stayOnTile)
|
||||
val attackableEnemies = TargetHelper.getAttackableEnemies(unit, unit.movement.getDistanceToTiles(), stayOnTile=stayOnTile)
|
||||
// Only take enemies we can fight without dying
|
||||
.filter {
|
||||
BattleDamage.calculateDamageToAttacker(
|
||||
@ -32,131 +29,11 @@ object BattleHelper {
|
||||
return unit.currentMovement == 0f
|
||||
}
|
||||
|
||||
fun getAttackableEnemies(
|
||||
unit: MapUnit,
|
||||
unitDistanceToTiles: PathsToTilesWithinTurn,
|
||||
tilesToCheck: List<Tile>? = null,
|
||||
stayOnTile: Boolean = false
|
||||
): ArrayList<AttackableTile> {
|
||||
val rangeOfAttack = unit.getRange()
|
||||
val attackableTiles = ArrayList<AttackableTile>()
|
||||
|
||||
val unitMustBeSetUp = unit.hasUnique(UniqueType.MustSetUp)
|
||||
val tilesToAttackFrom = if (stayOnTile || unit.baseUnit.movesLikeAirUnits())
|
||||
sequenceOf(Pair(unit.currentTile, unit.currentMovement))
|
||||
else
|
||||
unitDistanceToTiles.asSequence()
|
||||
.map { (tile, distance) ->
|
||||
val movementPointsToExpendAfterMovement = if (unitMustBeSetUp) 1 else 0
|
||||
val movementPointsToExpendHere =
|
||||
if (unitMustBeSetUp && !unit.isSetUpForSiege()) 1 else 0
|
||||
val movementPointsToExpendBeforeAttack =
|
||||
if (tile == unit.currentTile) movementPointsToExpendHere else movementPointsToExpendAfterMovement
|
||||
val movementLeft =
|
||||
unit.currentMovement - distance.totalDistance - movementPointsToExpendBeforeAttack
|
||||
Pair(tile, movementLeft)
|
||||
}
|
||||
// still got leftover movement points after all that, to attack
|
||||
.filter { it.second > Constants.minimumMovementEpsilon }
|
||||
.filter {
|
||||
it.first == unit.getTile() || unit.movement.canMoveTo(it.first)
|
||||
}
|
||||
|
||||
val tilesWithEnemies: HashSet<Tile> = HashSet()
|
||||
val tilesWithoutEnemies: HashSet<Tile> = 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())
|
||||
reachableTile.getTilesInDistance(rangeOfAttack)
|
||||
else reachableTile.tileMap.getViewableTiles(reachableTile.position, rangeOfAttack, true).asSequence()
|
||||
|
||||
for (tile in tilesInAttackRange) {
|
||||
// Since military units can technically enter tiles with enemy civilians,
|
||||
// some try to move to to the tile and then attack the unit it contains, which is silly
|
||||
if (tile == reachableTile) continue
|
||||
if (tile in tilesWithEnemies) attackableTiles += AttackableTile(
|
||||
reachableTile,
|
||||
tile,
|
||||
movementLeft,
|
||||
Battle.getMapCombatantOfTile(tile)
|
||||
)
|
||||
else if (tile in tilesWithoutEnemies) continue // avoid checking the same empty tile multiple times
|
||||
else if (tileContainsAttackableEnemy(unit, tile, tilesToCheck)) {
|
||||
tilesWithEnemies += tile
|
||||
attackableTiles += AttackableTile(
|
||||
reachableTile, tile, movementLeft,
|
||||
Battle.getMapCombatantOfTile(tile)
|
||||
)
|
||||
} else if (unit.isPreparingAirSweep()) {
|
||||
tilesWithEnemies += tile
|
||||
attackableTiles += AttackableTile(
|
||||
reachableTile, tile, movementLeft,
|
||||
Battle.getMapCombatantOfTile(tile)
|
||||
)
|
||||
} else tilesWithoutEnemies += tile
|
||||
}
|
||||
}
|
||||
return attackableTiles
|
||||
}
|
||||
|
||||
private fun tileContainsAttackableEnemy(unit: MapUnit, tile: Tile, tilesToCheck: List<Tile>?): Boolean {
|
||||
if (!containsAttackableEnemy(tile, MapUnitCombatant(unit))) return false
|
||||
if (tile !in (tilesToCheck ?: unit.civ.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: Tile, combatant: ICombatant): Boolean {
|
||||
if (combatant is MapUnitCombatant && combatant.unit.isEmbarked() && !combatant.hasUnique(UniqueType.AttackOnSea)) {
|
||||
// Can't attack water units while embarked, only land
|
||||
if (tile.isWater || combatant.isRanged())
|
||||
return false
|
||||
}
|
||||
|
||||
val tileCombatant = Battle.getMapCombatantOfTile(tile) ?: return false
|
||||
if (tileCombatant.getCivInfo() == combatant.getCivInfo()) return false
|
||||
// If the user automates units, one may capture the city before the user had a chance to decide what to do with it,
|
||||
// and then the next unit should not attack that city
|
||||
if (tileCombatant is CityCombatant && tileCombatant.city.hasJustBeenConquered) return false
|
||||
if (!combatant.getCivInfo().isAtWarWith(tileCombatant.getCivInfo())) return false
|
||||
|
||||
if (combatant is MapUnitCombatant && combatant.isLandUnit() && combatant.isMelee() && tile.isWater &&
|
||||
!combatant.getCivInfo().tech.unitsCanEmbark && !combatant.unit.cache.canMoveOnWater
|
||||
)
|
||||
return false
|
||||
|
||||
if (combatant is MapUnitCombatant && combatant.hasUnique(UniqueType.CannotAttack))
|
||||
return false
|
||||
|
||||
if (combatant is MapUnitCombatant &&
|
||||
combatant.unit.getMatchingUniques(UniqueType.CanOnlyAttackUnits).run {
|
||||
any() && none { tileCombatant.matchesCategory(it.params[0]) }
|
||||
}
|
||||
)
|
||||
return false
|
||||
|
||||
if (combatant is MapUnitCombatant &&
|
||||
combatant.unit.getMatchingUniques(UniqueType.CanOnlyAttackTiles).run {
|
||||
any() && none { tile.matchesFilter(it.params[0]) }
|
||||
}
|
||||
)
|
||||
return false
|
||||
|
||||
// Only units with the right unique can view submarines (or other invisible units) from more then one tile away.
|
||||
// Garrisoned invisible units can be attacked by anyone, as else the city will be in invincible.
|
||||
if (tileCombatant.isInvisible(combatant.getCivInfo()) && !tile.isCityCenter()) {
|
||||
return combatant is MapUnitCombatant
|
||||
&& combatant.getCivInfo().viewableInvisibleUnitsTiles.map { it.position }.contains(tile.position)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun tryDisembarkUnitToAttackPosition(unit: MapUnit): Boolean {
|
||||
if (!unit.baseUnit.isMelee() || !unit.baseUnit.isLandUnit() || !unit.isEmbarked()) return false
|
||||
val unitDistanceToTiles = unit.movement.getDistanceToTiles()
|
||||
|
||||
val attackableEnemiesNextTurn = getAttackableEnemies(unit, unitDistanceToTiles)
|
||||
val attackableEnemiesNextTurn = TargetHelper.getAttackableEnemies(unit, unitDistanceToTiles)
|
||||
// Only take enemies we can fight without dying
|
||||
.filter {
|
||||
BattleDamage.calculateDamageToAttacker(
|
||||
|
@ -5,6 +5,7 @@ import com.unciv.logic.automation.Automation
|
||||
import com.unciv.logic.battle.Battle
|
||||
import com.unciv.logic.battle.GreatGeneralImplementation
|
||||
import com.unciv.logic.battle.MapUnitCombatant
|
||||
import com.unciv.logic.battle.TargetHelper
|
||||
import com.unciv.logic.city.City
|
||||
import com.unciv.logic.civilization.diplomacy.DiplomaticModifiers
|
||||
import com.unciv.logic.map.mapunit.MapUnit
|
||||
@ -480,7 +481,7 @@ object SpecificUnitAutomation {
|
||||
.filter { destinationCity ->
|
||||
destinationCity != airUnit.currentTile
|
||||
&& destinationCity.getTilesInDistance(airUnit.getRange())
|
||||
.any { BattleHelper.containsAttackableEnemy(it, MapUnitCombatant(airUnit)) }
|
||||
.any { TargetHelper.containsAttackableEnemy(it, MapUnitCombatant(airUnit)) }
|
||||
}
|
||||
if (citiesThatCanAttackFrom.isEmpty()) return
|
||||
|
||||
@ -547,7 +548,7 @@ object SpecificUnitAutomation {
|
||||
if (city.getTilesInDistance(unit.getRange())
|
||||
.any {
|
||||
it.isVisible(unit.civ) &&
|
||||
BattleHelper.containsAttackableEnemy(
|
||||
TargetHelper.containsAttackableEnemy(
|
||||
it,
|
||||
MapUnitCombatant(unit)
|
||||
)
|
||||
|
@ -8,6 +8,7 @@ import com.unciv.logic.battle.BattleDamage
|
||||
import com.unciv.logic.battle.CityCombatant
|
||||
import com.unciv.logic.battle.ICombatant
|
||||
import com.unciv.logic.battle.MapUnitCombatant
|
||||
import com.unciv.logic.battle.TargetHelper
|
||||
import com.unciv.logic.city.City
|
||||
import com.unciv.logic.civilization.Civilization
|
||||
import com.unciv.logic.civilization.NotificationCategory
|
||||
@ -467,11 +468,6 @@ object UnitAutomation {
|
||||
return unit.currentMovement == 0f
|
||||
}
|
||||
|
||||
/** Get a list of visible tiles which have something attackable */
|
||||
fun getBombardableTiles(city: City): Sequence<Tile> =
|
||||
city.getCenterTile().getTilesInDistance(city.range)
|
||||
.filter { it.isVisible(city.civ) && BattleHelper.containsAttackableEnemy(it, CityCombatant(city)) }
|
||||
|
||||
/** Move towards the closest attackable enemy of the [unit].
|
||||
*
|
||||
* Limited by [CLOSE_ENEMY_TURNS_AWAY_LIMIT] and [CLOSE_ENEMY_TILES_AWAY_LIMIT].
|
||||
@ -482,7 +478,7 @@ object UnitAutomation {
|
||||
unit.getTile().position,
|
||||
unit.getMaxMovement() * CLOSE_ENEMY_TURNS_AWAY_LIMIT
|
||||
)
|
||||
var closeEnemies = BattleHelper.getAttackableEnemies(
|
||||
var closeEnemies = TargetHelper.getAttackableEnemies(
|
||||
unit,
|
||||
unitDistanceToTiles,
|
||||
tilesToCheck = unit.getTile().getTilesInDistance(CLOSE_ENEMY_TILES_AWAY_LIMIT).toList()
|
||||
@ -674,7 +670,7 @@ object UnitAutomation {
|
||||
}
|
||||
|
||||
private fun chooseBombardTarget(city: City): ICombatant? {
|
||||
var targets = getBombardableTiles(city).map { Battle.getMapCombatantOfTile(it)!! }
|
||||
var targets = TargetHelper.getBombardableTiles(city).map { Battle.getMapCombatantOfTile(it)!! }
|
||||
if (targets.none()) return null
|
||||
|
||||
val siegeUnits = targets
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.unciv.logic.automation.unit
|
||||
package com.unciv.logic.battle
|
||||
|
||||
import com.unciv.logic.battle.ICombatant
|
||||
import com.unciv.logic.map.tile.Tile
|
@ -4,7 +4,6 @@ import com.badlogic.gdx.math.Vector2
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.automation.civilization.NextTurnAutomation
|
||||
import com.unciv.logic.automation.unit.AttackableTile
|
||||
import com.unciv.logic.automation.unit.SpecificUnitAutomation
|
||||
import com.unciv.logic.city.City
|
||||
import com.unciv.logic.civilization.AlertType
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.unciv.logic.battle
|
||||
|
||||
import com.unciv.logic.automation.unit.BattleHelper
|
||||
import com.unciv.logic.automation.unit.SpecificUnitAutomation
|
||||
import com.unciv.logic.map.mapunit.MapUnit
|
||||
import com.unciv.logic.map.tile.Tile
|
||||
@ -95,7 +94,7 @@ object GreatGeneralImplementation {
|
||||
unitTile.getTilesInDistance(unitBonusRadius).sumOf { auraTile ->
|
||||
val militaryUnit = auraTile.militaryUnit
|
||||
if (militaryUnit == null || militaryUnit.civ != general.civ || militaryUnit.isEmbarked()) 0
|
||||
else if (BattleHelper.getAttackableEnemies(militaryUnit, militaryUnit.movement.getDistanceToTiles()).isEmpty()) 0
|
||||
else if (TargetHelper.getAttackableEnemies(militaryUnit, militaryUnit.movement.getDistanceToTiles()).isEmpty()) 0
|
||||
else generalBonusData.firstOrNull {
|
||||
// "Military" as commented above only a small optimization
|
||||
auraTile.aerialDistanceTo(unitTile) <= it.radius
|
||||
|
136
core/src/com/unciv/logic/battle/TargetHelper.kt
Normal file
136
core/src/com/unciv/logic/battle/TargetHelper.kt
Normal file
@ -0,0 +1,136 @@
|
||||
package com.unciv.logic.battle
|
||||
|
||||
import com.unciv.Constants
|
||||
import com.unciv.logic.city.City
|
||||
import com.unciv.logic.map.mapunit.MapUnit
|
||||
import com.unciv.logic.map.mapunit.PathsToTilesWithinTurn
|
||||
import com.unciv.logic.map.tile.Tile
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
|
||||
object TargetHelper {
|
||||
fun getAttackableEnemies(
|
||||
unit: MapUnit,
|
||||
unitDistanceToTiles: PathsToTilesWithinTurn,
|
||||
tilesToCheck: List<Tile>? = null,
|
||||
stayOnTile: Boolean = false
|
||||
): ArrayList<AttackableTile> {
|
||||
val rangeOfAttack = unit.getRange()
|
||||
val attackableTiles = ArrayList<AttackableTile>()
|
||||
|
||||
val unitMustBeSetUp = unit.hasUnique(UniqueType.MustSetUp)
|
||||
val tilesToAttackFrom = if (stayOnTile || unit.baseUnit.movesLikeAirUnits())
|
||||
sequenceOf(Pair(unit.currentTile, unit.currentMovement))
|
||||
else
|
||||
unitDistanceToTiles.asSequence()
|
||||
.map { (tile, distance) ->
|
||||
val movementPointsToExpendAfterMovement = if (unitMustBeSetUp) 1 else 0
|
||||
val movementPointsToExpendHere =
|
||||
if (unitMustBeSetUp && !unit.isSetUpForSiege()) 1 else 0
|
||||
val movementPointsToExpendBeforeAttack =
|
||||
if (tile == unit.currentTile) movementPointsToExpendHere else movementPointsToExpendAfterMovement
|
||||
val movementLeft =
|
||||
unit.currentMovement - distance.totalDistance - movementPointsToExpendBeforeAttack
|
||||
Pair(tile, movementLeft)
|
||||
}
|
||||
// still got leftover movement points after all that, to attack
|
||||
.filter { it.second > Constants.minimumMovementEpsilon }
|
||||
.filter {
|
||||
it.first == unit.getTile() || unit.movement.canMoveTo(it.first)
|
||||
}
|
||||
|
||||
val tilesWithEnemies: HashSet<Tile> = HashSet()
|
||||
val tilesWithoutEnemies: HashSet<Tile> = 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())
|
||||
reachableTile.getTilesInDistance(rangeOfAttack)
|
||||
else reachableTile.tileMap.getViewableTiles(reachableTile.position, rangeOfAttack, true).asSequence()
|
||||
|
||||
for (tile in tilesInAttackRange) {
|
||||
// Since military units can technically enter tiles with enemy civilians,
|
||||
// some try to move to to the tile and then attack the unit it contains, which is silly
|
||||
if (tile == reachableTile) continue
|
||||
if (tile in tilesWithEnemies) attackableTiles += AttackableTile(
|
||||
reachableTile,
|
||||
tile,
|
||||
movementLeft,
|
||||
Battle.getMapCombatantOfTile(tile)
|
||||
)
|
||||
else if (tile in tilesWithoutEnemies) continue // avoid checking the same empty tile multiple times
|
||||
else if (tileContainsAttackableEnemy(unit, tile, tilesToCheck)) {
|
||||
tilesWithEnemies += tile
|
||||
attackableTiles += AttackableTile(
|
||||
reachableTile, tile, movementLeft,
|
||||
Battle.getMapCombatantOfTile(tile)
|
||||
)
|
||||
} else if (unit.isPreparingAirSweep()) {
|
||||
tilesWithEnemies += tile
|
||||
attackableTiles += AttackableTile(
|
||||
reachableTile, tile, movementLeft,
|
||||
Battle.getMapCombatantOfTile(tile)
|
||||
)
|
||||
} else tilesWithoutEnemies += tile
|
||||
}
|
||||
}
|
||||
return attackableTiles
|
||||
}
|
||||
|
||||
private fun tileContainsAttackableEnemy(unit: MapUnit, tile: Tile, tilesToCheck: List<Tile>?): Boolean {
|
||||
if (!containsAttackableEnemy(tile, MapUnitCombatant(unit))) return false
|
||||
if (tile !in (tilesToCheck ?: unit.civ.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: Tile, combatant: ICombatant): Boolean {
|
||||
if (combatant is MapUnitCombatant && combatant.unit.isEmbarked() && !combatant.hasUnique(UniqueType.AttackOnSea)) {
|
||||
// Can't attack water units while embarked, only land
|
||||
if (tile.isWater || combatant.isRanged())
|
||||
return false
|
||||
}
|
||||
|
||||
val tileCombatant = Battle.getMapCombatantOfTile(tile) ?: return false
|
||||
if (tileCombatant.getCivInfo() == combatant.getCivInfo()) return false
|
||||
// If the user automates units, one may capture the city before the user had a chance to decide what to do with it,
|
||||
// and then the next unit should not attack that city
|
||||
if (tileCombatant is CityCombatant && tileCombatant.city.hasJustBeenConquered) return false
|
||||
if (!combatant.getCivInfo().isAtWarWith(tileCombatant.getCivInfo())) return false
|
||||
|
||||
if (combatant is MapUnitCombatant && combatant.isLandUnit() && combatant.isMelee() && tile.isWater &&
|
||||
!combatant.getCivInfo().tech.unitsCanEmbark && !combatant.unit.cache.canMoveOnWater
|
||||
)
|
||||
return false
|
||||
|
||||
if (combatant is MapUnitCombatant && combatant.hasUnique(UniqueType.CannotAttack))
|
||||
return false
|
||||
|
||||
if (combatant is MapUnitCombatant &&
|
||||
combatant.unit.getMatchingUniques(UniqueType.CanOnlyAttackUnits).run {
|
||||
any() && none { tileCombatant.matchesCategory(it.params[0]) }
|
||||
}
|
||||
)
|
||||
return false
|
||||
|
||||
if (combatant is MapUnitCombatant &&
|
||||
combatant.unit.getMatchingUniques(UniqueType.CanOnlyAttackTiles).run {
|
||||
any() && none { tile.matchesFilter(it.params[0]) }
|
||||
}
|
||||
)
|
||||
return false
|
||||
|
||||
// Only units with the right unique can view submarines (or other invisible units) from more then one tile away.
|
||||
// Garrisoned invisible units can be attacked by anyone, as else the city will be in invincible.
|
||||
if (tileCombatant.isInvisible(combatant.getCivInfo()) && !tile.isCityCenter()) {
|
||||
return combatant is MapUnitCombatant
|
||||
&& combatant.getCivInfo().viewableInvisibleUnitsTiles.map { it.position }.contains(tile.position)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/** Get a list of visible tiles which have something attackable */
|
||||
fun getBombardableTiles(city: City): Sequence<Tile> =
|
||||
city.getCenterTile().getTilesInDistance(city.range)
|
||||
.filter { it.isVisible(city.civ) && containsAttackableEnemy(it, CityCombatant(city)) }
|
||||
|
||||
}
|
@ -15,12 +15,11 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.automation.unit.AttackableTile
|
||||
import com.unciv.logic.automation.unit.BattleHelper
|
||||
import com.unciv.logic.automation.unit.CityLocationTileRanker
|
||||
import com.unciv.logic.automation.unit.UnitAutomation
|
||||
import com.unciv.logic.battle.AttackableTile
|
||||
import com.unciv.logic.battle.Battle
|
||||
import com.unciv.logic.battle.MapUnitCombatant
|
||||
import com.unciv.logic.battle.TargetHelper
|
||||
import com.unciv.logic.city.City
|
||||
import com.unciv.logic.civilization.Civilization
|
||||
import com.unciv.logic.map.TileMap
|
||||
@ -224,7 +223,7 @@ class WorldMapHolder(
|
||||
/** If we are in unit-swapping mode and didn't find a swap partner, we don't want to move or attack */
|
||||
} else {
|
||||
// This seems inefficient as the tileToAttack is already known - but the method also calculates tileToAttackFrom
|
||||
val attackableTile = BattleHelper
|
||||
val attackableTile = TargetHelper
|
||||
.getAttackableEnemies(unit, unit.movement.getDistanceToTiles())
|
||||
.firstOrNull { it.tileToAttack == tile }
|
||||
if (unit.canAttack() && attackableTile != null) {
|
||||
@ -700,7 +699,7 @@ class WorldMapHolder(
|
||||
|| (targetTile.isCityCenter() && unit.civ.hasExplored(targetTile)) }
|
||||
.map { AttackableTile(unit.getTile(), it, 1f, null) }
|
||||
.toList()
|
||||
else BattleHelper.getAttackableEnemies(unit, unit.movement.getDistanceToTiles())
|
||||
else TargetHelper.getAttackableEnemies(unit, unit.movement.getDistanceToTiles())
|
||||
.filter { it.tileToAttack.isVisible(unit.civ) }
|
||||
.distinctBy { it.tileToAttack }
|
||||
|
||||
@ -730,7 +729,7 @@ class WorldMapHolder(
|
||||
|
||||
private fun updateBombardableTilesForSelectedCity(city: City) {
|
||||
if (!city.canBombard()) return
|
||||
for (attackableTile in UnitAutomation.getBombardableTiles(city)) {
|
||||
for (attackableTile in TargetHelper.getBombardableTiles(city)) {
|
||||
val group = tileGroups[attackableTile]!!
|
||||
group.layerOverlay.showHighlight(colorFromRGB(237, 41, 57))
|
||||
group.layerOverlay.showCrosshair()
|
||||
|
@ -4,14 +4,13 @@ import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.scenes.scene2d.Touchable
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.unciv.logic.automation.unit.AttackableTile
|
||||
import com.unciv.logic.automation.unit.BattleHelper
|
||||
import com.unciv.logic.automation.unit.UnitAutomation
|
||||
import com.unciv.logic.battle.AttackableTile
|
||||
import com.unciv.logic.battle.Battle
|
||||
import com.unciv.logic.battle.BattleDamage
|
||||
import com.unciv.logic.battle.CityCombatant
|
||||
import com.unciv.logic.battle.ICombatant
|
||||
import com.unciv.logic.battle.MapUnitCombatant
|
||||
import com.unciv.logic.battle.TargetHelper
|
||||
import com.unciv.logic.map.tile.Tile
|
||||
import com.unciv.models.UncivSound
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
@ -73,7 +72,7 @@ class BattleTable(val worldScreen: WorldScreen): Table() {
|
||||
val defender = tryGetDefender() ?: return hide()
|
||||
if (attacker is CityCombatant && defender is CityCombatant) return hide()
|
||||
val tileToAttackFrom = if (attacker is MapUnitCombatant)
|
||||
BattleHelper.getAttackableEnemies(
|
||||
TargetHelper.getAttackableEnemies(
|
||||
attacker.unit,
|
||||
attacker.unit.movement.getDistanceToTiles()
|
||||
)
|
||||
@ -247,11 +246,11 @@ class BattleTable(val worldScreen: WorldScreen): Table() {
|
||||
|
||||
if (attacker.canAttack()) {
|
||||
if (attacker is MapUnitCombatant) {
|
||||
attackableTile = BattleHelper
|
||||
attackableTile = TargetHelper
|
||||
.getAttackableEnemies(attacker.unit, attacker.unit.movement.getDistanceToTiles())
|
||||
.firstOrNull{ it.tileToAttack == defender.getTile()}
|
||||
} else if (attacker is CityCombatant) {
|
||||
val canBombard = UnitAutomation.getBombardableTiles(attacker.city).contains(defender.getTile())
|
||||
val canBombard = TargetHelper.getBombardableTiles(attacker.city).contains(defender.getTile())
|
||||
if (canBombard) {
|
||||
attackableTile = AttackableTile(attacker.getTile(), defender.getTile(), 0f, defender)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user