mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-23 11:34:54 -04:00
Separate tile update functions from the rest of WorldMapHolder, it's too big
This commit is contained in:
parent
f021fb692d
commit
b58570294b
@ -12,11 +12,8 @@ import com.badlogic.gdx.scenes.scene2d.Touchable
|
||||
import com.badlogic.gdx.scenes.scene2d.actions.Actions
|
||||
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.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
|
||||
@ -30,25 +27,11 @@ import com.unciv.logic.map.tile.Tile
|
||||
import com.unciv.models.Spy
|
||||
import com.unciv.models.UncivSound
|
||||
import com.unciv.models.UnitActionType
|
||||
import com.unciv.models.ruleset.unique.LocalUniqueCache
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.ui.audio.SoundPlayer
|
||||
import com.unciv.ui.components.MapArrowType
|
||||
import com.unciv.ui.components.MiscArrowTypes
|
||||
import com.unciv.ui.components.extensions.center
|
||||
import com.unciv.ui.components.extensions.colorFromRGB
|
||||
import com.unciv.ui.components.extensions.darken
|
||||
import com.unciv.ui.components.extensions.isShiftKeyPressed
|
||||
import com.unciv.ui.components.extensions.setSize
|
||||
import com.unciv.ui.components.extensions.surroundWithCircle
|
||||
import com.unciv.ui.components.extensions.toLabel
|
||||
import com.unciv.ui.components.input.ActivationTypes
|
||||
import com.unciv.ui.components.input.ClickableCircle
|
||||
import com.unciv.ui.components.input.KeyCharAndCode
|
||||
import com.unciv.ui.components.input.KeyboardBinding
|
||||
import com.unciv.ui.components.input.keyShortcuts
|
||||
import com.unciv.ui.components.input.onActivation
|
||||
import com.unciv.ui.components.input.onClick
|
||||
import com.unciv.ui.components.extensions.*
|
||||
import com.unciv.ui.components.input.*
|
||||
import com.unciv.ui.components.tilegroups.TileGroup
|
||||
import com.unciv.ui.components.tilegroups.TileGroupMap
|
||||
import com.unciv.ui.components.tilegroups.TileSetStrings
|
||||
@ -74,11 +57,11 @@ class WorldMapHolder(
|
||||
internal var selectedTile: Tile? = null
|
||||
val tileGroups = HashMap<Tile, WorldTileGroup>()
|
||||
|
||||
private val unitActionOverlays: ArrayList<Actor> = ArrayList()
|
||||
internal val unitActionOverlays: ArrayList<Actor> = ArrayList()
|
||||
|
||||
private val unitMovementPaths: HashMap<MapUnit, ArrayList<Tile>> = HashMap()
|
||||
internal val unitMovementPaths: HashMap<MapUnit, ArrayList<Tile>> = HashMap()
|
||||
|
||||
private val unitConnectRoadPaths: HashMap<MapUnit, List<Tile>> = HashMap()
|
||||
internal val unitConnectRoadPaths: HashMap<MapUnit, List<Tile>> = HashMap()
|
||||
|
||||
private lateinit var tileGroupMap: TileGroupMap<WorldTileGroup>
|
||||
|
||||
@ -707,7 +690,7 @@ class WorldMapHolder(
|
||||
}
|
||||
|
||||
/** Returns true when the civ is a human player defeated in singleplayer game */
|
||||
private fun isMapRevealEnabled(viewingCiv: Civilization) = !viewingCiv.gameInfo.gameParameters.isOnlineMultiplayer
|
||||
fun isMapRevealEnabled(viewingCiv: Civilization) = !viewingCiv.gameInfo.gameParameters.isOnlineMultiplayer
|
||||
&& viewingCiv.isCurrentPlayer()
|
||||
&& viewingCiv.isDefeated()
|
||||
|
||||
@ -752,249 +735,6 @@ class WorldMapHolder(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun updateTiles(viewingCiv: Civilization) {
|
||||
|
||||
if (isMapRevealEnabled(viewingCiv)) {
|
||||
// Only needs to be done once - this is so the minimap will also be revealed
|
||||
tileGroups.values.forEach {
|
||||
it.tile.setExplored(viewingCiv, true)
|
||||
it.isForceVisible = true } // So we can see all resources, regardless of tech
|
||||
}
|
||||
|
||||
// General update of all tiles
|
||||
val uniqueCache = LocalUniqueCache(true)
|
||||
for (tileGroup in tileGroups.values)
|
||||
tileGroup.update(viewingCiv, uniqueCache)
|
||||
|
||||
// Update tiles according to selected unit/city
|
||||
val unitTable = worldScreen.bottomUnitTable
|
||||
when {
|
||||
unitTable.selectedSpy != null -> {
|
||||
updateTilesForSelectedSpy(unitTable.selectedSpy!!)
|
||||
}
|
||||
unitTable.selectedCity != null -> {
|
||||
val city = unitTable.selectedCity!!
|
||||
updateBombardableTilesForSelectedCity(city)
|
||||
// We still want to show road paths to the selected city if they are present
|
||||
if (unitTable.selectedUnitIsConnectingRoad) {
|
||||
updateTilesForSelectedUnit(unitTable.selectedUnits[0])
|
||||
}
|
||||
}
|
||||
unitTable.selectedUnit != null -> {
|
||||
for (unit in unitTable.selectedUnits) {
|
||||
updateTilesForSelectedUnit(unit)
|
||||
}
|
||||
}
|
||||
unitActionOverlays.isNotEmpty() -> {
|
||||
removeUnitActionOverlay()
|
||||
}
|
||||
}
|
||||
|
||||
// Same as below - randomly, tileGroups doesn't seem to contain the selected tile, and this doesn't seem reproducible
|
||||
tileGroups[selectedTile]?.layerOverlay?.showHighlight(Color.WHITE)
|
||||
|
||||
zoom(scaleX) // zoom to current scale, to set the size of the city buttons after "next turn"
|
||||
}
|
||||
|
||||
private fun updateTilesForSelectedUnit(unit: MapUnit) {
|
||||
|
||||
val tileGroup = tileGroups[unit.getTile()] ?: return
|
||||
|
||||
// Update flags for units which have them
|
||||
if (!unit.baseUnit.movesLikeAirUnits) {
|
||||
tileGroup.layerUnitFlag.selectFlag(unit)
|
||||
}
|
||||
|
||||
// Fade out less relevant images if a military unit is selected
|
||||
if (unit.isMilitary()) {
|
||||
for (group in tileGroups.values) {
|
||||
|
||||
// Fade out population icons
|
||||
group.layerMisc.dimPopulation(true)
|
||||
|
||||
val shownImprovement = group.tile.getShownImprovement(unit.civ)
|
||||
|
||||
// Fade out improvement icons (but not barb camps or ruins)
|
||||
if (shownImprovement != null && shownImprovement != Constants.barbarianEncampment
|
||||
&& !unit.civ.gameInfo.ruleset.tileImprovements[shownImprovement]!!.isAncientRuinsEquivalent())
|
||||
group.layerMisc.dimImprovement(true)
|
||||
}
|
||||
}
|
||||
|
||||
// Z-Layer: 0
|
||||
// Highlight suitable tiles in swapping-mode
|
||||
if (worldScreen.bottomUnitTable.selectedUnitIsSwapping) {
|
||||
val unitSwappableTiles = unit.movement.getUnitSwappableTiles()
|
||||
val swapUnitsTileOverlayColor = Color.PURPLE
|
||||
for (tile in unitSwappableTiles) {
|
||||
tileGroups[tile]!!.layerOverlay.showHighlight(swapUnitsTileOverlayColor,
|
||||
if (UncivGame.Current.settings.singleTapMove) 0.7f else 0.3f)
|
||||
}
|
||||
// In swapping-mode we don't want to show other overlays
|
||||
return
|
||||
}
|
||||
|
||||
// Z-Layer: 0
|
||||
// Highlight suitable tiles in road connecting mode
|
||||
if (worldScreen.bottomUnitTable.selectedUnitIsConnectingRoad) {
|
||||
if (unit.currentTile.ruleset.roadImprovement == null) return
|
||||
val validTiles = unit.civ.gameInfo.tileMap.tileList.filter {
|
||||
MapPathing.isValidRoadPathTile(unit, it)
|
||||
}
|
||||
val connectRoadTileOverlayColor = Color.RED
|
||||
for (tile in validTiles) {
|
||||
tileGroups[tile]!!.layerOverlay.showHighlight(connectRoadTileOverlayColor, 0.3f)
|
||||
}
|
||||
|
||||
if (unitConnectRoadPaths.containsKey(unit)) {
|
||||
for (tile in unitConnectRoadPaths[unit]!!) {
|
||||
tileGroups[tile]!!.layerOverlay.showHighlight(Color.ORANGE, 0.8f)
|
||||
}
|
||||
}
|
||||
|
||||
// In road connecting mode we don't want to show other overlays
|
||||
return
|
||||
}
|
||||
|
||||
val isAirUnit = unit.baseUnit.movesLikeAirUnits
|
||||
val moveTileOverlayColor = if (unit.isPreparingParadrop()) Color.BLUE else Color.WHITE
|
||||
val tilesInMoveRange = unit.movement.getReachableTilesInCurrentTurn()
|
||||
// Prepare special Nuke blast radius display
|
||||
val nukeBlastRadius = if (unit.isNuclearWeapon() && selectedTile != null && selectedTile != unit.getTile())
|
||||
unit.getNukeBlastRadius() else -1
|
||||
|
||||
// Z-Layer: 1
|
||||
// Highlight tiles within movement range
|
||||
for (tile in tilesInMoveRange) {
|
||||
val group = tileGroups[tile]!!
|
||||
|
||||
// Air-units have additional highlights
|
||||
if (isAirUnit && !unit.isPreparingAirSweep()) {
|
||||
if (nukeBlastRadius >= 0 && tile.aerialDistanceTo(selectedTile!!) <= nukeBlastRadius) {
|
||||
// The tile is within the nuke blast radius
|
||||
group.layerMisc.overlayTerrain(Color.FIREBRICK, 0.6f)
|
||||
} else if (tile.aerialDistanceTo(unit.getTile()) <= unit.getRange()) {
|
||||
// The tile is within attack range
|
||||
group.layerMisc.overlayTerrain(Color.RED)
|
||||
} else if (tile.isExplored(worldScreen.viewingCiv) && tile.aerialDistanceTo(unit.getTile()) <= unit.getRange()*2) {
|
||||
// The tile is within move range
|
||||
group.layerMisc.overlayTerrain(if (unit.movement.canMoveTo(tile)) Color.WHITE else Color.BLUE)
|
||||
}
|
||||
}
|
||||
|
||||
// Highlight tile unit can move to
|
||||
if (unit.movement.canMoveTo(tile) ||
|
||||
unit.movement.isUnknownTileWeShouldAssumeToBePassable(tile) && !unit.baseUnit.movesLikeAirUnits
|
||||
) {
|
||||
val alpha = if (UncivGame.Current.settings.singleTapMove) 0.7f else 0.3f
|
||||
group.layerOverlay.showHighlight(moveTileOverlayColor, alpha)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Z-Layer: 2
|
||||
// Add back in the red markers for Air Unit Attack range since they can't move, but can still attack
|
||||
if (unit.cache.cannotMove && isAirUnit && !unit.isPreparingAirSweep()) {
|
||||
val tilesInAttackRange = unit.getTile().getTilesInDistanceRange(IntRange(1, unit.getRange()))
|
||||
for (tile in tilesInAttackRange) {
|
||||
// The tile is within attack range
|
||||
tileGroups[tile]!!.layerOverlay.showHighlight(Color.RED, 0.3f)
|
||||
}
|
||||
}
|
||||
|
||||
// Z-Layer: 3
|
||||
// Movement paths
|
||||
if (unitMovementPaths.containsKey(unit)) {
|
||||
for (tile in unitMovementPaths[unit]!!) {
|
||||
tileGroups[tile]!!.layerOverlay.showHighlight(Color.SKY, 0.8f)
|
||||
}
|
||||
}
|
||||
|
||||
// Z-Layer: 4
|
||||
// Highlight road path for workers currently connecting roads
|
||||
if (unit.isAutomatingRoadConnection()) {
|
||||
if (unit.automatedRoadConnectionPath == null) return
|
||||
val currTileIndex = unit.automatedRoadConnectionPath!!.indexOf(unit.currentTile.position)
|
||||
if (currTileIndex != -1) {
|
||||
val futureTiles = unit.automatedRoadConnectionPath!!.filterIndexed { index, _ ->
|
||||
index > currTileIndex
|
||||
}.map { tilePos ->
|
||||
tileMap[tilePos]
|
||||
}
|
||||
for (tile in futureTiles) {
|
||||
tileGroups[tile]!!.layerOverlay.showHighlight(Color.ORANGE, if (UncivGame.Current.settings.singleTapMove) 0.7f else 0.3f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Z-Layer: 5
|
||||
// Highlight movement destination tile
|
||||
if (unit.isMoving()) {
|
||||
tileGroups[unit.getMovementDestination()]!!.layerOverlay.showHighlight(Color.WHITE, 0.7f)
|
||||
}
|
||||
|
||||
// Z-Layer: 6
|
||||
// Highlight attackable tiles
|
||||
if (unit.isMilitary()) {
|
||||
|
||||
val attackableTiles: List<AttackableTile> =
|
||||
if (nukeBlastRadius >= 0)
|
||||
selectedTile!!.getTilesInDistance(nukeBlastRadius)
|
||||
// Should not display invisible submarine units even if the tile is visible.
|
||||
.filter { targetTile -> (targetTile.isVisible(unit.civ) && targetTile.getUnits().any { !it.isInvisible(unit.civ) })
|
||||
|| (targetTile.isCityCenter() && unit.civ.hasExplored(targetTile)) }
|
||||
.map { AttackableTile(unit.getTile(), it, 1f, null) }
|
||||
.toList()
|
||||
else TargetHelper.getAttackableEnemies(unit, unit.movement.getDistanceToTiles())
|
||||
.filter { it.tileToAttack.isVisible(unit.civ) }
|
||||
.distinctBy { it.tileToAttack }
|
||||
|
||||
for (attackableTile in attackableTiles) {
|
||||
val tileGroupToAttack = tileGroups[attackableTile.tileToAttack]!!
|
||||
tileGroupToAttack.layerOverlay.showHighlight(colorFromRGB(237, 41, 57))
|
||||
tileGroupToAttack.layerOverlay.showCrosshair(
|
||||
// the targets which cannot be attacked without movements shown as orange-ish
|
||||
if (attackableTile.tileToAttackFrom != unit.currentTile)
|
||||
0.5f
|
||||
else 1f
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Z-Layer: 7
|
||||
// Highlight best tiles for city founding
|
||||
if (unit.hasUnique(UniqueType.FoundCity)
|
||||
&& UncivGame.Current.settings.showSettlersSuggestedCityLocations) {
|
||||
CityLocationTileRanker.getBestTilesToFoundCity(unit, minimumValue = 50f).tileRankMap.asSequence()
|
||||
.filter { it.key.isExplored(unit.civ) }.sortedByDescending { it.value }.take(3).forEach {
|
||||
tileGroups[it.key]!!.layerOverlay.showGoodCityLocationIndicator()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateTilesForSelectedSpy(spy: Spy) {
|
||||
for (group in tileGroups.values) {
|
||||
group.layerOverlay.reset()
|
||||
if (!group.tile.isCityCenter())
|
||||
group.layerMisc.dimImprovement(true)
|
||||
group.layerCityButton.moveDown()
|
||||
}
|
||||
for (city in worldScreen.gameInfo.getCities()) {
|
||||
if (spy.canMoveTo(city)) {
|
||||
tileGroups[city.getCenterTile()]!!.layerOverlay.showHighlight(Color.CYAN, .7f)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateBombardableTilesForSelectedCity(city: City) {
|
||||
if (!city.canBombard()) return
|
||||
for (attackableTile in TargetHelper.getBombardableTiles(city)) {
|
||||
val group = tileGroups[attackableTile]!!
|
||||
group.layerOverlay.showHighlight(colorFromRGB(237, 41, 57))
|
||||
group.layerOverlay.showCrosshair()
|
||||
}
|
||||
}
|
||||
|
||||
var blinkAction: Action? = null
|
||||
|
||||
|
262
core/src/com/unciv/ui/screens/worldscreen/WorldMapTileUpdater.kt
Normal file
262
core/src/com/unciv/ui/screens/worldscreen/WorldMapTileUpdater.kt
Normal file
@ -0,0 +1,262 @@
|
||||
package com.unciv.ui.screens.worldscreen
|
||||
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.automation.unit.CityLocationTileRanker
|
||||
import com.unciv.logic.battle.AttackableTile
|
||||
import com.unciv.logic.battle.TargetHelper
|
||||
import com.unciv.logic.city.City
|
||||
import com.unciv.logic.civilization.Civilization
|
||||
import com.unciv.logic.map.MapPathing
|
||||
import com.unciv.logic.map.mapunit.MapUnit
|
||||
import com.unciv.models.Spy
|
||||
import com.unciv.models.ruleset.unique.LocalUniqueCache
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.ui.components.extensions.colorFromRGB
|
||||
|
||||
object WorldMapTileUpdater {
|
||||
|
||||
fun WorldMapHolder.updateTiles(viewingCiv: Civilization) {
|
||||
|
||||
if (isMapRevealEnabled(viewingCiv)) {
|
||||
// Only needs to be done once - this is so the minimap will also be revealed
|
||||
tileGroups.values.forEach {
|
||||
it.tile.setExplored(viewingCiv, true)
|
||||
it.isForceVisible = true } // So we can see all resources, regardless of tech
|
||||
}
|
||||
|
||||
// General update of all tiles
|
||||
val uniqueCache = LocalUniqueCache(true)
|
||||
for (tileGroup in tileGroups.values)
|
||||
tileGroup.update(viewingCiv, uniqueCache)
|
||||
|
||||
// Update tiles according to selected unit/city
|
||||
val unitTable = worldScreen.bottomUnitTable
|
||||
when {
|
||||
unitTable.selectedSpy != null -> {
|
||||
updateTilesForSelectedSpy(unitTable.selectedSpy!!)
|
||||
}
|
||||
unitTable.selectedCity != null -> {
|
||||
val city = unitTable.selectedCity!!
|
||||
updateBombardableTilesForSelectedCity(city)
|
||||
// We still want to show road paths to the selected city if they are present
|
||||
if (unitTable.selectedUnitIsConnectingRoad) {
|
||||
updateTilesForSelectedUnit(unitTable.selectedUnits[0])
|
||||
}
|
||||
}
|
||||
unitTable.selectedUnit != null -> {
|
||||
for (unit in unitTable.selectedUnits) {
|
||||
updateTilesForSelectedUnit(unit)
|
||||
}
|
||||
}
|
||||
unitActionOverlays.isNotEmpty() -> {
|
||||
removeUnitActionOverlay()
|
||||
}
|
||||
}
|
||||
|
||||
// Same as below - randomly, tileGroups doesn't seem to contain the selected tile, and this doesn't seem reproducible
|
||||
tileGroups[selectedTile]?.layerOverlay?.showHighlight(Color.WHITE)
|
||||
|
||||
zoom(scaleX) // zoom to current scale, to set the size of the city buttons after "next turn"
|
||||
}
|
||||
|
||||
private fun WorldMapHolder.updateTilesForSelectedUnit(unit: MapUnit) {
|
||||
|
||||
val tileGroup = tileGroups[unit.getTile()] ?: return
|
||||
|
||||
// Update flags for units which have them
|
||||
if (!unit.baseUnit.movesLikeAirUnits) {
|
||||
tileGroup.layerUnitFlag.selectFlag(unit)
|
||||
}
|
||||
|
||||
// Fade out less relevant images if a military unit is selected
|
||||
if (unit.isMilitary()) {
|
||||
for (group in tileGroups.values) {
|
||||
|
||||
// Fade out population icons
|
||||
group.layerMisc.dimPopulation(true)
|
||||
|
||||
val shownImprovement = group.tile.getShownImprovement(unit.civ)
|
||||
|
||||
// Fade out improvement icons (but not barb camps or ruins)
|
||||
if (shownImprovement != null && shownImprovement != Constants.barbarianEncampment
|
||||
&& !unit.civ.gameInfo.ruleset.tileImprovements[shownImprovement]!!.isAncientRuinsEquivalent())
|
||||
group.layerMisc.dimImprovement(true)
|
||||
}
|
||||
}
|
||||
|
||||
// Z-Layer: 0
|
||||
// Highlight suitable tiles in swapping-mode
|
||||
if (worldScreen.bottomUnitTable.selectedUnitIsSwapping) {
|
||||
val unitSwappableTiles = unit.movement.getUnitSwappableTiles()
|
||||
val swapUnitsTileOverlayColor = Color.PURPLE
|
||||
for (tile in unitSwappableTiles) {
|
||||
tileGroups[tile]!!.layerOverlay.showHighlight(swapUnitsTileOverlayColor,
|
||||
if (UncivGame.Current.settings.singleTapMove) 0.7f else 0.3f)
|
||||
}
|
||||
// In swapping-mode we don't want to show other overlays
|
||||
return
|
||||
}
|
||||
|
||||
// Z-Layer: 0
|
||||
// Highlight suitable tiles in road connecting mode
|
||||
if (worldScreen.bottomUnitTable.selectedUnitIsConnectingRoad) {
|
||||
if (unit.currentTile.ruleset.roadImprovement == null) return
|
||||
val validTiles = unit.civ.gameInfo.tileMap.tileList.filter {
|
||||
MapPathing.isValidRoadPathTile(unit, it)
|
||||
}
|
||||
val connectRoadTileOverlayColor = Color.RED
|
||||
for (tile in validTiles) {
|
||||
tileGroups[tile]!!.layerOverlay.showHighlight(connectRoadTileOverlayColor, 0.3f)
|
||||
}
|
||||
|
||||
if (unitConnectRoadPaths.containsKey(unit)) {
|
||||
for (tile in unitConnectRoadPaths[unit]!!) {
|
||||
tileGroups[tile]!!.layerOverlay.showHighlight(Color.ORANGE, 0.8f)
|
||||
}
|
||||
}
|
||||
|
||||
// In road connecting mode we don't want to show other overlays
|
||||
return
|
||||
}
|
||||
|
||||
val isAirUnit = unit.baseUnit.movesLikeAirUnits
|
||||
val moveTileOverlayColor = if (unit.isPreparingParadrop()) Color.BLUE else Color.WHITE
|
||||
val tilesInMoveRange = unit.movement.getReachableTilesInCurrentTurn()
|
||||
// Prepare special Nuke blast radius display
|
||||
val nukeBlastRadius = if (unit.isNuclearWeapon() && selectedTile != null && selectedTile != unit.getTile())
|
||||
unit.getNukeBlastRadius() else -1
|
||||
|
||||
// Z-Layer: 1
|
||||
// Highlight tiles within movement range
|
||||
for (tile in tilesInMoveRange) {
|
||||
val group = tileGroups[tile]!!
|
||||
|
||||
// Air-units have additional highlights
|
||||
if (isAirUnit && !unit.isPreparingAirSweep()) {
|
||||
if (nukeBlastRadius >= 0 && tile.aerialDistanceTo(selectedTile!!) <= nukeBlastRadius) {
|
||||
// The tile is within the nuke blast radius
|
||||
group.layerMisc.overlayTerrain(Color.FIREBRICK, 0.6f)
|
||||
} else if (tile.aerialDistanceTo(unit.getTile()) <= unit.getRange()) {
|
||||
// The tile is within attack range
|
||||
group.layerMisc.overlayTerrain(Color.RED)
|
||||
} else if (tile.isExplored(worldScreen.viewingCiv) && tile.aerialDistanceTo(unit.getTile()) <= unit.getRange()*2) {
|
||||
// The tile is within move range
|
||||
group.layerMisc.overlayTerrain(if (unit.movement.canMoveTo(tile)) Color.WHITE else Color.BLUE)
|
||||
}
|
||||
}
|
||||
|
||||
// Highlight tile unit can move to
|
||||
if (unit.movement.canMoveTo(tile) ||
|
||||
unit.movement.isUnknownTileWeShouldAssumeToBePassable(tile) && !unit.baseUnit.movesLikeAirUnits
|
||||
) {
|
||||
val alpha = if (UncivGame.Current.settings.singleTapMove) 0.7f else 0.3f
|
||||
group.layerOverlay.showHighlight(moveTileOverlayColor, alpha)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Z-Layer: 2
|
||||
// Add back in the red markers for Air Unit Attack range since they can't move, but can still attack
|
||||
if (unit.cache.cannotMove && isAirUnit && !unit.isPreparingAirSweep()) {
|
||||
val tilesInAttackRange = unit.getTile().getTilesInDistanceRange(IntRange(1, unit.getRange()))
|
||||
for (tile in tilesInAttackRange) {
|
||||
// The tile is within attack range
|
||||
tileGroups[tile]!!.layerOverlay.showHighlight(Color.RED, 0.3f)
|
||||
}
|
||||
}
|
||||
|
||||
// Z-Layer: 3
|
||||
// Movement paths
|
||||
if (unitMovementPaths.containsKey(unit)) {
|
||||
for (tile in unitMovementPaths[unit]!!) {
|
||||
tileGroups[tile]!!.layerOverlay.showHighlight(Color.SKY, 0.8f)
|
||||
}
|
||||
}
|
||||
|
||||
// Z-Layer: 4
|
||||
// Highlight road path for workers currently connecting roads
|
||||
if (unit.isAutomatingRoadConnection()) {
|
||||
if (unit.automatedRoadConnectionPath == null) return
|
||||
val currTileIndex = unit.automatedRoadConnectionPath!!.indexOf(unit.currentTile.position)
|
||||
if (currTileIndex != -1) {
|
||||
val futureTiles = unit.automatedRoadConnectionPath!!.filterIndexed { index, _ ->
|
||||
index > currTileIndex
|
||||
}.map { tilePos ->
|
||||
tileMap[tilePos]
|
||||
}
|
||||
for (tile in futureTiles) {
|
||||
tileGroups[tile]!!.layerOverlay.showHighlight(Color.ORANGE, if (UncivGame.Current.settings.singleTapMove) 0.7f else 0.3f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Z-Layer: 5
|
||||
// Highlight movement destination tile
|
||||
if (unit.isMoving()) {
|
||||
tileGroups[unit.getMovementDestination()]!!.layerOverlay.showHighlight(Color.WHITE, 0.7f)
|
||||
}
|
||||
|
||||
// Z-Layer: 6
|
||||
// Highlight attackable tiles
|
||||
if (unit.isMilitary()) {
|
||||
|
||||
val attackableTiles: List<AttackableTile> =
|
||||
if (nukeBlastRadius >= 0)
|
||||
selectedTile!!.getTilesInDistance(nukeBlastRadius)
|
||||
// Should not display invisible submarine units even if the tile is visible.
|
||||
.filter { targetTile -> (targetTile.isVisible(unit.civ) && targetTile.getUnits().any { !it.isInvisible(unit.civ) })
|
||||
|| (targetTile.isCityCenter() && unit.civ.hasExplored(targetTile)) }
|
||||
.map { AttackableTile(unit.getTile(), it, 1f, null) }
|
||||
.toList()
|
||||
else TargetHelper.getAttackableEnemies(unit, unit.movement.getDistanceToTiles())
|
||||
.filter { it.tileToAttack.isVisible(unit.civ) }
|
||||
.distinctBy { it.tileToAttack }
|
||||
|
||||
for (attackableTile in attackableTiles) {
|
||||
val tileGroupToAttack = tileGroups[attackableTile.tileToAttack]!!
|
||||
tileGroupToAttack.layerOverlay.showHighlight(colorFromRGB(237, 41, 57))
|
||||
tileGroupToAttack.layerOverlay.showCrosshair(
|
||||
// the targets which cannot be attacked without movements shown as orange-ish
|
||||
if (attackableTile.tileToAttackFrom != unit.currentTile)
|
||||
0.5f
|
||||
else 1f
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Z-Layer: 7
|
||||
// Highlight best tiles for city founding
|
||||
if (unit.hasUnique(UniqueType.FoundCity)
|
||||
&& UncivGame.Current.settings.showSettlersSuggestedCityLocations) {
|
||||
CityLocationTileRanker.getBestTilesToFoundCity(unit, minimumValue = 50f).tileRankMap.asSequence()
|
||||
.filter { it.key.isExplored(unit.civ) }.sortedByDescending { it.value }.take(3).forEach {
|
||||
tileGroups[it.key]!!.layerOverlay.showGoodCityLocationIndicator()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun WorldMapHolder.updateTilesForSelectedSpy(spy: Spy) {
|
||||
for (group in tileGroups.values) {
|
||||
group.layerOverlay.reset()
|
||||
if (!group.tile.isCityCenter())
|
||||
group.layerMisc.dimImprovement(true)
|
||||
group.layerCityButton.moveDown()
|
||||
}
|
||||
for (city in worldScreen.gameInfo.getCities()) {
|
||||
if (spy.canMoveTo(city)) {
|
||||
tileGroups[city.getCenterTile()]!!.layerOverlay.showHighlight(Color.CYAN, .7f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun WorldMapHolder.updateBombardableTilesForSelectedCity(city: City) {
|
||||
if (!city.canBombard()) return
|
||||
for (attackableTile in TargetHelper.getBombardableTiles(city)) {
|
||||
val group = tileGroups[attackableTile]!!
|
||||
group.layerOverlay.showHighlight(colorFromRGB(237, 41, 57))
|
||||
group.layerOverlay.showCrosshair()
|
||||
}
|
||||
}
|
||||
}
|
@ -49,6 +49,7 @@ import com.unciv.ui.screens.savescreens.LoadGameScreen
|
||||
import com.unciv.ui.screens.savescreens.QuickSave
|
||||
import com.unciv.ui.screens.savescreens.SaveGameScreen
|
||||
import com.unciv.ui.screens.victoryscreen.VictoryScreen
|
||||
import com.unciv.ui.screens.worldscreen.WorldMapTileUpdater.updateTiles
|
||||
import com.unciv.ui.screens.worldscreen.bottombar.BattleTable
|
||||
import com.unciv.ui.screens.worldscreen.bottombar.TileInfoTable
|
||||
import com.unciv.ui.screens.worldscreen.mainmenu.WorldScreenMusicPopup
|
||||
|
Loading…
x
Reference in New Issue
Block a user