This commit is contained in:
Yair Morgenstern
2021-02-06 20:21:41 +02:00
parent 8e900a2503
commit 20cf0c9203
2 changed files with 39 additions and 38 deletions

View File

@ -168,12 +168,10 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
val specialConstructions = ArrayList<Table>() val specialConstructions = ArrayList<Table>()
thread { thread {
// Since this can be a heavy operation and leads to many ANRs on older phones we put the metadata-gathering in another thread.
val constructionButtonDTOList = getConstructionButtonDTOs() // Since this can be a heavy operation and leads to many ANRs on older phones... val constructionButtonDTOList = getConstructionButtonDTOs()
Gdx.app.postRunnable { Gdx.app.postRunnable {
// For some bizarre reason, moving this to another thread messes up the entire construction list?! Haven't figured out why yet
availableConstructionsTable.clear() availableConstructionsTable.clear()
for (dto in constructionButtonDTOList) { for (dto in constructionButtonDTOList) {
val constructionButton = getConstructionButton(dto) val constructionButton = getConstructionButton(dto)
when (dto.construction) { when (dto.construction) {

View File

@ -36,24 +36,24 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap
internal var selectedTile: TileInfo? = null internal var selectedTile: TileInfo? = null
val tileGroups = HashMap<TileInfo, WorldTileGroup>() val tileGroups = HashMap<TileInfo, WorldTileGroup>()
var unitActionOverlay :Actor?=null var unitActionOverlay: Actor? = null
init { init {
if (Gdx.app.type == Application.ApplicationType.Desktop) this.setFlingTime(0f) if (Gdx.app.type == Application.ApplicationType.Desktop) this.setFlingTime(0f)
} }
// Used to transfer data on the "move here" button that should be created, from the side thread to the main thread // Used to transfer data on the "move here" button that should be created, from the side thread to the main thread
class MoveHereButtonDto(val unitToTurnsToDestination: HashMap<MapUnit,Int>, val tileInfo: TileInfo) class MoveHereButtonDto(val unitToTurnsToDestination: HashMap<MapUnit, Int>, val tileInfo: TileInfo)
internal fun addTiles() { internal fun addTiles() {
val tileSetStrings = TileSetStrings() val tileSetStrings = TileSetStrings()
val daTileGroups = tileMap.values.map { WorldTileGroup(worldScreen, it, tileSetStrings) } val daTileGroups = tileMap.values.map { WorldTileGroup(worldScreen, it, tileSetStrings) }
for(tileGroup in daTileGroups) tileGroups[tileGroup.tileInfo]=tileGroup for (tileGroup in daTileGroups) tileGroups[tileGroup.tileInfo] = tileGroup
val allTiles = TileGroupMap(daTileGroups,worldScreen.stage.width) val allTiles = TileGroupMap(daTileGroups, worldScreen.stage.width)
for(tileGroup in tileGroups.values) { for (tileGroup in tileGroups.values) {
tileGroup.cityButtonLayerGroup.onClick(UncivSound.Silent) { tileGroup.cityButtonLayerGroup.onClick(UncivSound.Silent) {
onTileClicked(tileGroup.tileInfo) onTileClicked(tileGroup.tileInfo)
} }
@ -75,7 +75,7 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap
.firstOrNull { it.tileToAttack == tileGroup.tileInfo } .firstOrNull { it.tileToAttack == tileGroup.tileInfo }
if (unit.canAttack() && attackableTile != null) { if (unit.canAttack() && attackableTile != null) {
Battle.moveAndAttack(MapUnitCombatant(unit), attackableTile) Battle.moveAndAttack(MapUnitCombatant(unit), attackableTile)
worldScreen.shouldUpdate=true worldScreen.shouldUpdate = true
return@thread return@thread
} }
@ -92,8 +92,8 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap
actor = allTiles actor = allTiles
setSize(worldScreen.stage.width*2, worldScreen.stage.height*2) setSize(worldScreen.stage.width * 2, worldScreen.stage.height * 2)
setOrigin(width/2,height/2) setOrigin(width / 2, height / 2)
center(worldScreen.stage) center(worldScreen.stage)
layout() // Fit the scroll pane to the contents - otherwise, setScroll won't work! layout() // Fit the scroll pane to the contents - otherwise, setScroll won't work!
@ -112,8 +112,10 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap
if (previousSelectedUnits.isNotEmpty() && previousSelectedUnits.any { it.getTile() != tileInfo } if (previousSelectedUnits.isNotEmpty() && previousSelectedUnits.any { it.getTile() != tileInfo }
&& worldScreen.isPlayersTurn && worldScreen.isPlayersTurn
&& previousSelectedUnits.any { it.movement.canMoveTo(tileInfo) || && previousSelectedUnits.any {
it.movement.isUnknownTileWeShouldAssumeToBePassable(tileInfo)}) { it.movement.canMoveTo(tileInfo) ||
it.movement.isUnknownTileWeShouldAssumeToBePassable(tileInfo)
}) {
// this can take a long time, because of the unit-to-tile calculation needed, so we put it in a different thread // this can take a long time, because of the unit-to-tile calculation needed, so we put it in a different thread
addTileOverlaysWithUnitMovement(previousSelectedUnits, tileInfo) addTileOverlaysWithUnitMovement(previousSelectedUnits, tileInfo)
} else addTileOverlays(tileInfo) // no unit movement but display the units in the tile etc. } else addTileOverlays(tileInfo) // no unit movement but display the units in the tile etc.
@ -134,7 +136,7 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap
} }
fun moveUnitToTargetTile(selectedUnits: List<MapUnit>, targetTile:TileInfo) { fun moveUnitToTargetTile(selectedUnits: List<MapUnit>, targetTile: TileInfo) {
// this can take a long time, because of the unit-to-tile calculation needed, so we put it in a different thread // this can take a long time, because of the unit-to-tile calculation needed, so we put it in a different thread
// THIS PART IS REALLY ANNOYING // THIS PART IS REALLY ANNOYING
// So lets say you have 2 units you want to move in the same direction, right // So lets say you have 2 units you want to move in the same direction, right
@ -189,8 +191,8 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap
* so that and that alone will be relegated to the concurrent thread. * so that and that alone will be relegated to the concurrent thread.
*/ */
val unitToTurnsToTile = HashMap<MapUnit,Int>() val unitToTurnsToTile = HashMap<MapUnit, Int>()
for(unit in selectedUnits) { for (unit in selectedUnits) {
val turnsToGetThere = if (unit.type.isAirUnit()) { val turnsToGetThere = if (unit.type.isAirUnit()) {
if (unit.movement.canReach(tileInfo)) 1 if (unit.movement.canReach(tileInfo)) 1
else 0 else 0
@ -199,8 +201,8 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap
} }
Gdx.app.postRunnable { Gdx.app.postRunnable {
val unitsWhoCanMoveThere = HashMap(unitToTurnsToTile.filter { it.value!=0 }) val unitsWhoCanMoveThere = HashMap(unitToTurnsToTile.filter { it.value != 0 })
if (unitsWhoCanMoveThere.isEmpty()){ // give the regular tile overlays with no unit movement if (unitsWhoCanMoveThere.isEmpty()) { // give the regular tile overlays with no unit movement
addTileOverlays(tileInfo) addTileOverlays(tileInfo)
worldScreen.shouldUpdate = true worldScreen.shouldUpdate = true
return@postRunnable return@postRunnable
@ -211,7 +213,7 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap
if (UncivGame.Current.settings.singleTapMove && turnsToGetThere == 1) { if (UncivGame.Current.settings.singleTapMove && turnsToGetThere == 1) {
// single turn instant move // single turn instant move
val selectedUnit = unitsWhoCanMoveThere.keys.first() val selectedUnit = unitsWhoCanMoveThere.keys.first()
for(unit in unitsWhoCanMoveThere.keys) { for (unit in unitsWhoCanMoveThere.keys) {
unit.movement.headTowards(tileInfo) unit.movement.headTowards(tileInfo)
} }
worldScreen.bottomUnitTable.selectUnit(selectedUnit) // keep moved unit selected worldScreen.bottomUnitTable.selectUnit(selectedUnit) // keep moved unit selected
@ -226,17 +228,17 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap
} }
} }
private fun addTileOverlays(tileInfo: TileInfo, moveHereDto:MoveHereButtonDto?=null){ private fun addTileOverlays(tileInfo: TileInfo, moveHereDto: MoveHereButtonDto? = null) {
val table = Table().apply { defaults().pad(10f) } val table = Table().apply { defaults().pad(10f) }
if(moveHereDto!=null && worldScreen.canChangeState) if (moveHereDto != null && worldScreen.canChangeState)
table.add(getMoveHereButton(moveHereDto)) table.add(getMoveHereButton(moveHereDto))
val unitList = ArrayList<MapUnit>() val unitList = ArrayList<MapUnit>()
if (tileInfo.isCityCenter() if (tileInfo.isCityCenter()
&& (tileInfo.getOwner()==worldScreen.viewingCiv || worldScreen.viewingCiv.isSpectator())) { && (tileInfo.getOwner() == worldScreen.viewingCiv || worldScreen.viewingCiv.isSpectator())) {
unitList.addAll(tileInfo.getCity()!!.getCenterTile().getUnits()) unitList.addAll(tileInfo.getCity()!!.getCenterTile().getUnits())
} else if (tileInfo.airUnits.isNotEmpty() } else if (tileInfo.airUnits.isNotEmpty()
&& (tileInfo.airUnits.first().civInfo==worldScreen.viewingCiv || worldScreen.viewingCiv.isSpectator())) { && (tileInfo.airUnits.first().civInfo == worldScreen.viewingCiv || worldScreen.viewingCiv.isSpectator())) {
unitList.addAll(tileInfo.getUnits()) unitList.addAll(tileInfo.getUnits())
} }
@ -254,7 +256,7 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap
} }
addOverlayOnTileGroup(tileInfo, table) addOverlayOnTileGroup(tileInfo, table)
table.moveBy(0f,60f) table.moveBy(0f, 60f)
} }
private fun getMoveHereButton(dto: MoveHereButtonDto): Group { private fun getMoveHereButton(dto: MoveHereButtonDto): Group {
@ -277,7 +279,7 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap
moveHereButton.addActor(unitIcon) moveHereButton.addActor(unitIcon)
val unitsThatCanMove = dto.unitToTurnsToDestination.keys.filter { it.currentMovement > 0 } val unitsThatCanMove = dto.unitToTurnsToDestination.keys.filter { it.currentMovement > 0 }
if(unitsThatCanMove.isEmpty()) moveHereButton.color.a = 0.5f if (unitsThatCanMove.isEmpty()) moveHereButton.color.a = 0.5f
else { else {
moveHereButton.onClick(UncivSound.Silent) { moveHereButton.onClick(UncivSound.Silent) {
UncivGame.Current.settings.addCompletedTutorialTask("Move unit") UncivGame.Current.settings.addCompletedTutorialTask("Move unit")
@ -295,8 +297,8 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap
val group = tileGroups[tileInfo]!! val group = tileGroups[tileInfo]!!
actor.center(group) actor.center(group)
actor.x+=group.x actor.x += group.x
actor.y+=group.y actor.y += group.y
group.parent.addActor(actor) // Add the overlay to the TileGroupMap - it's what actually displays all the tiles group.parent.addActor(actor) // Add the overlay to the TileGroupMap - it's what actually displays all the tiles
actor.toFront() actor.toFront()
@ -387,19 +389,19 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap
val attackableTiles: List<AttackableTile> = if (unit.type.isCivilian()) listOf() val attackableTiles: List<AttackableTile> = if (unit.type.isCivilian()) listOf()
else { else {
BattleHelper.getAttackableEnemies(unit, unit.movement.getDistanceToTiles()) BattleHelper.getAttackableEnemies(unit, unit.movement.getDistanceToTiles())
.filter { (UncivGame.Current.viewEntireMapForDebug || .filter {
playerViewableTilePositions.contains(it.tileToAttack.position)) } (UncivGame.Current.viewEntireMapForDebug ||
playerViewableTilePositions.contains(it.tileToAttack.position))
}
.distinctBy { it.tileToAttack } .distinctBy { it.tileToAttack }
} }
for (attackableTile in attackableTiles) { for (attackableTile in attackableTiles) {
tileGroups[attackableTile.tileToAttack]!!.showCircle(colorFromRGB(237, 41, 57)) tileGroups[attackableTile.tileToAttack]!!.showCircle(colorFromRGB(237, 41, 57))
tileGroups[attackableTile.tileToAttack]!!.showCrosshair(
tileGroups[attackableTile.tileToAttack]!!.showCrosshair (
// the targets which cannot be attacked without movements shown as orange-ish // the targets which cannot be attacked without movements shown as orange-ish
if (attackableTile.tileToAttackFrom != unit.currentTile) if (attackableTile.tileToAttackFrom != unit.currentTile)
colorFromRGB(255, 75, 0) colorFromRGB(255, 75, 0)
else Color.RED else Color.RED
) )
} }
@ -427,7 +429,7 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap
} }
} }
var blinkAction:Action? = null var blinkAction: Action? = null
fun setCenterPosition(vector: Vector2, immediately: Boolean = false, selectUnit: Boolean = true) { fun setCenterPosition(vector: Vector2, immediately: Boolean = false, selectUnit: Boolean = true) {
val tileGroup = tileGroups.values.firstOrNull { it.tileInfo.position == vector } ?: return val tileGroup = tileGroups.values.firstOrNull { it.tileInfo.position == vector } ?: return
selectedTile = tileGroup.tileInfo selectedTile = tileGroup.tileInfo
@ -472,7 +474,7 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap
worldScreen.shouldUpdate = true worldScreen.shouldUpdate = true
} }
override fun zoom(zoomScale:Float) { override fun zoom(zoomScale: Float) {
super.zoom(zoomScale) super.zoom(zoomScale)
val scale = 1 / scaleX // don't use zoomScale itself, in case it was out of bounds and not applied val scale = 1 / scaleX // don't use zoomScale itself, in case it was out of bounds and not applied
if (scale >= 1) if (scale >= 1)
@ -489,6 +491,7 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap
} }
// For debugging purposes // For debugging purposes
override fun draw(batch: Batch?, parentAlpha: Float) { super.draw(batch, parentAlpha) } override fun draw(batch: Batch?, parentAlpha: Float) = super.draw(batch, parentAlpha)
override fun act(delta: Float) { super.act(delta) }
override fun act(delta: Float) = super.act(delta)
} }