diff --git a/core/src/com/unciv/UnCivGame.kt b/core/src/com/unciv/UnCivGame.kt index 6fdec59f94..0f865d6d29 100644 --- a/core/src/com/unciv/UnCivGame.kt +++ b/core/src/com/unciv/UnCivGame.kt @@ -16,7 +16,7 @@ class UnCivGame : Game() { * This exists so that when debugging we can see the entire map. * Remember to turn this to false before commit and upload! */ - val viewEntireMapForDebug = false + val viewEntireMapForDebug = true diff --git a/core/src/com/unciv/logic/automation/UnitAutomation.kt b/core/src/com/unciv/logic/automation/UnitAutomation.kt index b41df7e3c1..5fb86c421f 100644 --- a/core/src/com/unciv/logic/automation/UnitAutomation.kt +++ b/core/src/com/unciv/logic/automation/UnitAutomation.kt @@ -39,29 +39,23 @@ class UnitAutomation{ return tileCombatant.getCivilization()!=civInfo } - fun getAttackableEnemies(unit: MapUnit): List { - val attackableTiles = unit.civInfo.getViewableTiles() + class AttackableTile(val tileToAttackFrom:TileInfo, val tileToAttack:TileInfo) + + fun getAttackableEnemies(unit: MapUnit): ArrayList { + val tilesWithEnemies = unit.civInfo.getViewableTiles() .filter { containsAttackableEnemy(it,unit.civInfo) } - if(MapUnitCombatant(unit).isMelee()) { - val distanceToTiles = unit.getDistanceToTiles() - // If we're conducting a melee attack, - // then there needs to be a tile adjacent to the enemy that we can get to, - // AND STILL HAVE MOVEMENT POINTS REMAINING, - return attackableTiles.filter { - it.neighbors.any { - unit.getTile()==it || // We're already right nearby - unit.canMoveTo(it) - && distanceToTiles.containsKey(it) - && distanceToTiles[it]!! < unit.currentMovement // We can get there - } - } - } + val distanceToTiles = unit.getDistanceToTiles() + val rangeOfAttack = if(MapUnitCombatant(unit).isMelee()) 1 else unit.getBaseUnit().range - else { // Range attack, so enemy needs to be in range - return attackableTiles.filter { unit.getTile().getTilesInDistance(unit.getBaseUnit().range).contains(it) } + val attackableTiles = ArrayList() + val tilesToAttackFrom = distanceToTiles.filter { it.value!=unit.currentMovement }.map { it.key } + .filter { unit.canMoveTo(it) || it==unit.getTile() } + for(reachableTile in tilesToAttackFrom){ // tiles we'll still have energy after we reach there + attackableTiles += reachableTile.getTilesInDistance(rangeOfAttack).filter { it in tilesWithEnemies } + .map { AttackableTile(reachableTile,it) } } - + return attackableTiles } fun automateUnitMoves(unit: MapUnit) { @@ -93,21 +87,20 @@ class UnitAutomation{ } // do nothing but heal // if there is an attackable unit in the vicinity, attack! - val enemyTileToAttack = getAttackableEnemies(unit).firstOrNull() + val enemyTileToAttack = getAttackableEnemies(unit) + // Only take enemies we can fight without dying + .filter { BattleDamage().calculateDamageToAttacker(MapUnitCombatant(unit), + Battle().getMapCombatantOfTile(it.tileToAttack)!!) < unit.health } + .firstOrNull() if (enemyTileToAttack != null) { + val enemy = Battle().getMapCombatantOfTile(enemyTileToAttack.tileToAttack)!! + unit.moveToTile(enemyTileToAttack.tileToAttackFrom) val setupAction = UnitActions().getUnitActions(unit, UnCivGame.Current.worldScreen).firstOrNull{ it.name == "Set up" } if(setupAction!=null) setupAction.action() - - val enemy = Battle().getMapCombatantOfTile(enemyTileToAttack)!! - val damageToAttacker = BattleDamage().calculateDamageToAttacker(MapUnitCombatant(unit), enemy) - - if (damageToAttacker < unit.health) { // don't attack if we'll die from the attack - if(MapUnitCombatant(unit).isMelee()) - unit.movementAlgs().headTowards(enemyTileToAttack) + if(unit.currentMovement>0) // This can be 0, if the set up action took away what action points we had left... Battle(unit.civInfo.gameInfo).attack(MapUnitCombatant(unit), enemy) - return - } + return } if(unit.getTile().isCityCenter()) return // It's always good to have a unit in the city center, so if you havn't found annyonw aroud to attack, forget it. diff --git a/core/src/com/unciv/logic/map/TileInfo.kt b/core/src/com/unciv/logic/map/TileInfo.kt index 393be4b0f7..246a80db66 100644 --- a/core/src/com/unciv/logic/map/TileInfo.kt +++ b/core/src/com/unciv/logic/map/TileInfo.kt @@ -159,6 +159,7 @@ open class TileInfo { if (improvement != null) SB.appendln(improvement!!.tr()) if (improvementInProgress != null) SB.appendln("{$improvementInProgress} in ${this.turnsToImprovement} {turns}".tr()) val isViewableToPlayer = UnCivGame.Current.gameInfo.getPlayerCivilization().getViewableTiles().contains(this) + || UnCivGame.Current.viewEntireMapForDebug if (civilianUnit != null && isViewableToPlayer) SB.appendln(civilianUnit!!.name) if(militaryUnit!=null && isViewableToPlayer){ var milUnitString = militaryUnit!!.name diff --git a/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt b/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt index 7b5c098dd0..a9f190835f 100644 --- a/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt +++ b/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt @@ -25,7 +25,7 @@ class UnitMovementAlgorithms(val unit:MapUnit) { fun getDistanceToTilesWithinTurn(origin: Vector2, unitMovement: Float): HashMap { if(unitMovement==0f) return hashMapOf() - val distanceToTiles = HashMap() + val distanceToTiles = LinkedHashMap() val unitTile = tileMap[origin] distanceToTiles[unitTile] = 0f var tilesToCheck = listOf(unitTile) diff --git a/core/src/com/unciv/ui/tilegroups/WorldTileGroup.kt b/core/src/com/unciv/ui/tilegroups/WorldTileGroup.kt index 31be829313..c324f97990 100644 --- a/core/src/com/unciv/ui/tilegroups/WorldTileGroup.kt +++ b/core/src/com/unciv/ui/tilegroups/WorldTileGroup.kt @@ -44,7 +44,8 @@ class WorldTileGroup(tileInfo: TileInfo) : TileGroup(tileInfo) { addPopulationIcon() if (tileInfo.tileMap.gameInfo.getPlayerCivilization().exploredTiles.contains(tileInfo.position) - || UnCivGame.Current.viewEntireMapForDebug) updateCityButton(city, isViewable) // needs to be before the update so the units will be above the city button + || UnCivGame.Current.viewEntireMapForDebug) + updateCityButton(city, isViewable || UnCivGame.Current.viewEntireMapForDebug) // needs to be before the update so the units will be above the city button super.update(isViewable || UnCivGame.Current.viewEntireMapForDebug) diff --git a/core/src/com/unciv/ui/worldscreen/TileMapHolder.kt b/core/src/com/unciv/ui/worldscreen/TileMapHolder.kt index 81ce39f10c..12ae28a6af 100644 --- a/core/src/com/unciv/ui/worldscreen/TileMapHolder.kt +++ b/core/src/com/unciv/ui/worldscreen/TileMapHolder.kt @@ -6,7 +6,9 @@ import com.badlogic.gdx.scenes.scene2d.Group import com.badlogic.gdx.scenes.scene2d.InputEvent import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane import com.badlogic.gdx.scenes.scene2d.utils.ActorGestureListener +import com.unciv.UnCivGame import com.unciv.logic.HexMath +import com.unciv.logic.automation.UnitAutomation import com.unciv.logic.civilization.CivilizationInfo import com.unciv.logic.map.TileInfo import com.unciv.logic.map.TileMap @@ -33,7 +35,6 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap: group.addClickListener { worldScreen.displayTutorials("TileClicked") - selectedTile = tileInfo worldScreen.bottomBar.unitTable.tileSelected(tileInfo) worldScreen.update() @@ -92,7 +93,7 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap: for (WG in tileGroups.values){ WG.update(playerViewableTiles.contains(WG.tileInfo)) val unitsInTile = WG.tileInfo.getUnits() - if(playerViewableTiles.contains(WG.tileInfo) + if((playerViewableTiles.contains(WG.tileInfo) || UnCivGame.Current.viewEntireMapForDebug) && unitsInTile.isNotEmpty() && unitsInTile.first().civInfo!=civInfo) WG.showCircle(Color.RED) } // Display ALL viewable enemies ewith a red circle so that users don't need to go "hunting" for enemy units @@ -107,16 +108,14 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap: val unitType = unit.getBaseUnit().unitType val attackableTiles: List = when{ unitType==UnitType.Civilian -> unit.getDistanceToTiles().keys.toList() - unit.getBaseUnit().unitType.isMelee() -> unit.getDistanceToTiles().keys.toList() - unitType.isRanged() -> unit.getTile().getTilesInDistance(2) - else -> throw Exception("UnitType isn't Civilian, Melee or Ranged???") + else -> UnitAutomation().getAttackableEnemies(unit).map { it.tileToAttack } } for (tile in attackableTiles.filter { it.getUnits().isNotEmpty() && it.getUnits().first().owner != unit.owner - && playerViewableTiles.contains(it)}) { + && (playerViewableTiles.contains(it) || UnCivGame.Current.viewEntireMapForDebug)}) { if(unit.getBaseUnit().unitType== UnitType.Civilian) tileGroups[tile]!!.hideCircle() else tileGroups[tile]!!.showCircle(colorFromRGB(237, 41, 57)) } diff --git a/core/src/com/unciv/ui/worldscreen/bottombar/BattleTable.kt b/core/src/com/unciv/ui/worldscreen/bottombar/BattleTable.kt index 349a5222b6..81a7072ba0 100644 --- a/core/src/com/unciv/ui/worldscreen/bottombar/BattleTable.kt +++ b/core/src/com/unciv/ui/worldscreen/bottombar/BattleTable.kt @@ -3,6 +3,7 @@ package com.unciv.ui.worldscreen.bottombar import com.badlogic.gdx.scenes.scene2d.ui.Label import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.TextButton +import com.unciv.UnCivGame import com.unciv.logic.automation.UnitAutomation import com.unciv.logic.battle.Battle import com.unciv.logic.battle.BattleDamage @@ -43,7 +44,7 @@ class BattleTable(val worldScreen: WorldScreen): Table() { val defender: ICombatant? = Battle().getMapCombatantOfTile(selectedTile) if(defender==null || defender.getCivilization()==worldScreen.civInfo - || !attacker.getCivilization().exploredTiles.contains(selectedTile.position)) { + || !(attacker.getCivilization().exploredTiles.contains(selectedTile.position) || UnCivGame.Current.viewEntireMapForDebug)) { hide() return } @@ -120,14 +121,13 @@ class BattleTable(val worldScreen: WorldScreen): Table() { attacker.unit.getDistanceToTiles() - val attackerCanReachDefender = UnitAutomation().getAttackableEnemies(attacker.unit) - .contains(defender.getTile()) + val attackableEnemy = UnitAutomation().getAttackableEnemies(attacker.unit) + .firstOrNull{ it.tileToAttack == defender.getTile()} - if(!attackerCanReachDefender || !attacker.unit.canAttack()) attackButton.disable() + if(attackableEnemy==null || !attacker.unit.canAttack()) attackButton.disable() else { attackButton.addClickListener { - if(attacker.isMelee()) - attacker.unit.movementAlgs().headTowards(defender.getTile()) + attacker.unit.moveToTile(attackableEnemy.tileToAttackFrom) battle.attack(attacker, defender) worldScreen.update() }