From 08a04d3575b90c16e8490d27b48c226e09efd743 Mon Sep 17 00:00:00 2001 From: SeventhM <127357473+SeventhM@users.noreply.github.com> Date: Sat, 19 Aug 2023 23:18:47 -0700 Subject: [PATCH] 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 --- .../logic/automation/unit/BattleHelper.kt | 131 +---------------- .../automation/unit/SpecificUnitAutomation.kt | 5 +- .../logic/automation/unit/UnitAutomation.kt | 10 +- .../unit => battle}/AttackableTile.kt | 2 +- core/src/com/unciv/logic/battle/Battle.kt | 1 - .../battle/GreatGeneralImplementation.kt | 3 +- .../com/unciv/logic/battle/TargetHelper.kt | 136 ++++++++++++++++++ .../ui/screens/worldscreen/WorldMapHolder.kt | 11 +- .../worldscreen/bottombar/BattleTable.kt | 11 +- 9 files changed, 158 insertions(+), 152 deletions(-) rename core/src/com/unciv/logic/{automation/unit => battle}/AttackableTile.kt (88%) create mode 100644 core/src/com/unciv/logic/battle/TargetHelper.kt diff --git a/core/src/com/unciv/logic/automation/unit/BattleHelper.kt b/core/src/com/unciv/logic/automation/unit/BattleHelper.kt index 063e740023..74e3f63d35 100644 --- a/core/src/com/unciv/logic/automation/unit/BattleHelper.kt +++ b/core/src/com/unciv/logic/automation/unit/BattleHelper.kt @@ -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? = null, - stayOnTile: Boolean = false - ): ArrayList { - val rangeOfAttack = unit.getRange() - val attackableTiles = ArrayList() - - 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 = HashSet() - val tilesWithoutEnemies: HashSet = 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?): 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( diff --git a/core/src/com/unciv/logic/automation/unit/SpecificUnitAutomation.kt b/core/src/com/unciv/logic/automation/unit/SpecificUnitAutomation.kt index 6fa2adae72..a42a851ac1 100644 --- a/core/src/com/unciv/logic/automation/unit/SpecificUnitAutomation.kt +++ b/core/src/com/unciv/logic/automation/unit/SpecificUnitAutomation.kt @@ -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) ) diff --git a/core/src/com/unciv/logic/automation/unit/UnitAutomation.kt b/core/src/com/unciv/logic/automation/unit/UnitAutomation.kt index 1ee1c07480..d738181ac4 100644 --- a/core/src/com/unciv/logic/automation/unit/UnitAutomation.kt +++ b/core/src/com/unciv/logic/automation/unit/UnitAutomation.kt @@ -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 = - 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 diff --git a/core/src/com/unciv/logic/automation/unit/AttackableTile.kt b/core/src/com/unciv/logic/battle/AttackableTile.kt similarity index 88% rename from core/src/com/unciv/logic/automation/unit/AttackableTile.kt rename to core/src/com/unciv/logic/battle/AttackableTile.kt index 563d4917a4..dcdf60d3a7 100644 --- a/core/src/com/unciv/logic/automation/unit/AttackableTile.kt +++ b/core/src/com/unciv/logic/battle/AttackableTile.kt @@ -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 diff --git a/core/src/com/unciv/logic/battle/Battle.kt b/core/src/com/unciv/logic/battle/Battle.kt index e8c0a25b1e..fc6595f994 100644 --- a/core/src/com/unciv/logic/battle/Battle.kt +++ b/core/src/com/unciv/logic/battle/Battle.kt @@ -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 diff --git a/core/src/com/unciv/logic/battle/GreatGeneralImplementation.kt b/core/src/com/unciv/logic/battle/GreatGeneralImplementation.kt index 751d58b30d..4e365f6f1a 100644 --- a/core/src/com/unciv/logic/battle/GreatGeneralImplementation.kt +++ b/core/src/com/unciv/logic/battle/GreatGeneralImplementation.kt @@ -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 diff --git a/core/src/com/unciv/logic/battle/TargetHelper.kt b/core/src/com/unciv/logic/battle/TargetHelper.kt new file mode 100644 index 0000000000..b5baba731e --- /dev/null +++ b/core/src/com/unciv/logic/battle/TargetHelper.kt @@ -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? = null, + stayOnTile: Boolean = false + ): ArrayList { + val rangeOfAttack = unit.getRange() + val attackableTiles = ArrayList() + + 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 = HashSet() + val tilesWithoutEnemies: HashSet = 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?): 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 = + city.getCenterTile().getTilesInDistance(city.range) + .filter { it.isVisible(city.civ) && containsAttackableEnemy(it, CityCombatant(city)) } + +} diff --git a/core/src/com/unciv/ui/screens/worldscreen/WorldMapHolder.kt b/core/src/com/unciv/ui/screens/worldscreen/WorldMapHolder.kt index c5a4721c82..f7965ca077 100644 --- a/core/src/com/unciv/ui/screens/worldscreen/WorldMapHolder.kt +++ b/core/src/com/unciv/ui/screens/worldscreen/WorldMapHolder.kt @@ -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() diff --git a/core/src/com/unciv/ui/screens/worldscreen/bottombar/BattleTable.kt b/core/src/com/unciv/ui/screens/worldscreen/bottombar/BattleTable.kt index 04d9858b54..95248507d6 100644 --- a/core/src/com/unciv/ui/screens/worldscreen/bottombar/BattleTable.kt +++ b/core/src/com/unciv/ui/screens/worldscreen/bottombar/BattleTable.kt @@ -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) }