diff --git a/core/src/com/unciv/ui/cityscreen/CityScreen.kt b/core/src/com/unciv/ui/cityscreen/CityScreen.kt index 88552b875a..609ad8ddf1 100644 --- a/core/src/com/unciv/ui/cityscreen/CityScreen.kt +++ b/core/src/com/unciv/ui/cityscreen/CityScreen.kt @@ -213,7 +213,7 @@ class CityScreen(internal val city: CityInfo): CameraStageBaseScreen() { stage.removeListener(keyListener) game.setWorldScreen() game.worldScreen.mapHolder.setCenterPosition(city.location) - game.worldScreen.bottomUnitTable.selectUnits() + game.worldScreen.bottomUnitTable.selectUnit() } fun page(delta: Int) { val civInfo = city.civInfo diff --git a/core/src/com/unciv/ui/worldscreen/WorldMapHolder.kt b/core/src/com/unciv/ui/worldscreen/WorldMapHolder.kt index 79f11762c0..b8a97565c3 100644 --- a/core/src/com/unciv/ui/worldscreen/WorldMapHolder.kt +++ b/core/src/com/unciv/ui/worldscreen/WorldMapHolder.kt @@ -9,6 +9,7 @@ import com.badlogic.gdx.scenes.scene2d.* import com.badlogic.gdx.scenes.scene2d.actions.FloatAction import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.utils.ClickListener +import com.badlogic.gdx.utils.Align import com.unciv.Constants import com.unciv.UncivGame import com.unciv.logic.automation.BattleHelper @@ -23,7 +24,6 @@ import com.unciv.ui.map.TileGroupMap import com.unciv.ui.tilegroups.TileSetStrings import com.unciv.ui.tilegroups.WorldTileGroup import com.unciv.ui.utils.* -import java.util.concurrent.ConcurrentHashMap import kotlin.concurrent.thread @@ -93,11 +93,10 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap && previousSelectedUnits.any { it.movement.canMoveTo(tileInfo) }) { // 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) - } - 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. - if(newSelectedUnit==null || newSelectedUnit.type==UnitType.Civilian) { + if (newSelectedUnit == null || newSelectedUnit.type == UnitType.Civilian) { val unitsInTile = selectedTile!!.getUnits() if (previousSelectedCity != null && !previousSelectedCity.attackedThisTurn && selectedTile!!.getTilesInDistance(2).contains(previousSelectedCity.getCenterTile()) @@ -137,7 +136,7 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap Sounds.play(UncivSound.Whoosh) if (selectedUnit.currentTile != targetTile) selectedUnit.action = "moveTo " + targetTile.position.x.toInt() + "," + targetTile.position.y.toInt() - if (selectedUnit.currentMovement > 0) worldScreen.bottomUnitTable.selectUnits(selectedUnit) + if (selectedUnit.currentMovement > 0) worldScreen.bottomUnitTable.selectUnit(selectedUnit) worldScreen.shouldUpdate = true unitActionOverlay?.remove() @@ -165,24 +164,25 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap } Gdx.app.postRunnable { - val unitsWhoCanMoveThere = 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 addTileOverlays(tileInfo) worldScreen.shouldUpdate = true return@postRunnable } - - val turnsToGetThere = unitsWhoCanMoveThere.values.first() - val selectedUnit = unitsWhoCanMoveThere.keys.first() + + val turnsToGetThere = unitsWhoCanMoveThere.values.max()!! +// val selectedUnit = unitsWhoCanMoveThere.keys.first() if (UncivGame.Current.settings.singleTapMove && turnsToGetThere == 1) { // single turn instant move - selectedUnit.movement.headTowards(tileInfo) - worldScreen.bottomUnitTable.selectUnits(selectedUnit) // keep moved unit selected + for(unit in unitsWhoCanMoveThere.keys) { + unit.movement.headTowards(tileInfo) + } +// worldScreen.bottomUnitTable.selectUnit(selectedUnit) // keep moved unit selected } else { // add "move to" button if there is a path to tileInfo - val moveHereButtonDto = if (turnsToGetThere != 0) MoveHereButtonDto(hashMapOf(selectedUnit to turnsToGetThere), tileInfo) - else null + val moveHereButtonDto = MoveHereButtonDto(unitsWhoCanMoveThere, tileInfo) addTileOverlays(tileInfo, moveHereButtonDto) } worldScreen.shouldUpdate = true @@ -211,7 +211,7 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap if (unit.currentMovement == 0f) unitGroup.color.a = 0.5f unitGroup.touchable = Touchable.enabled unitGroup.onClick { - worldScreen.bottomUnitTable.selectUnits(unit) + worldScreen.bottomUnitTable.selectUnit(unit) worldScreen.shouldUpdate = true unitActionOverlay?.remove() } @@ -227,27 +227,30 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap val moveHereButton = Group().apply { width = size;height = size; } moveHereButton.addActor(ImageGetter.getCircle().apply { width = size; height = size }) moveHereButton.addActor(ImageGetter.getStatIcon("Movement") - .apply { color= Color.BLACK; width = size / 2; height = size / 2; center(moveHereButton) }) + .apply { color = Color.BLACK; width = size / 2; height = size / 2; center(moveHereButton) }) val numberCircle = ImageGetter.getCircle().apply { width = size / 2; height = size / 2;color = Color.BLUE } moveHereButton.addActor(numberCircle) - moveHereButton.addActor(dto.unitToTurnsToDestination.values.first().toString().toLabel().apply { center(numberCircle) }) - val unit = dto.unitToTurnsToDestination.keys.first() - val unitIcon = UnitGroup(unit, size / 2) + moveHereButton.addActor(dto.unitToTurnsToDestination.values.max()!!.toLabel().apply { center(numberCircle) }) + val firstUnit = dto.unitToTurnsToDestination.keys.first() + val unitIcon = if (dto.unitToTurnsToDestination.size == 1) UnitGroup(firstUnit, size / 2) + else dto.unitToTurnsToDestination.size.toString().toLabel(fontColor = firstUnit.civInfo.nation.getInnerColor()).apply { setAlignment(Align.center) } + .surroundWithCircle(size / 2).apply { circle.color = firstUnit.civInfo.nation.getOuterColor() } unitIcon.y = size - unitIcon.height moveHereButton.addActor(unitIcon) - if (unit.currentMovement > 0) - moveHereButton.onClick(UncivSound.Silent) { - UncivGame.Current.settings.addCompletedTutorialTask("Move unit") - if(unit.type.isAirUnit()) - UncivGame.Current.settings.addCompletedTutorialTask("Move an air unit") - moveUnitToTargetTile(unit, dto.tileInfo) - } - - else moveHereButton.color.a = 0.5f + for (unit in dto.unitToTurnsToDestination.keys) { + if (unit.currentMovement > 0) + moveHereButton.onClick(UncivSound.Silent) { + UncivGame.Current.settings.addCompletedTutorialTask("Move unit") + if (unit.type.isAirUnit()) + UncivGame.Current.settings.addCompletedTutorialTask("Move an air unit") + moveUnitToTargetTile(unit, dto.tileInfo) + } + else moveHereButton.color.a = 0.5f + } return moveHereButton } diff --git a/core/src/com/unciv/ui/worldscreen/WorldScreen.kt b/core/src/com/unciv/ui/worldscreen/WorldScreen.kt index c1d168541d..19702ef06d 100644 --- a/core/src/com/unciv/ui/worldscreen/WorldScreen.kt +++ b/core/src/com/unciv/ui/worldscreen/WorldScreen.kt @@ -593,7 +593,7 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() { val nextDueUnit = viewingCiv.getNextDueUnit() if (nextDueUnit != null) { mapHolder.setCenterPosition(nextDueUnit.currentTile.position, false, false) - bottomUnitTable.selectUnits(nextDueUnit) + bottomUnitTable.selectUnit(nextDueUnit) shouldUpdate = true } } @@ -686,7 +686,7 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() { // Deselect Unit if (bottomUnitTable.selectedUnit != null) { - bottomUnitTable.selectUnits() + bottomUnitTable.selectUnit() bottomUnitTable.isVisible = false shouldUpdate = true return diff --git a/core/src/com/unciv/ui/worldscreen/unit/IdleUnitButton.kt b/core/src/com/unciv/ui/worldscreen/unit/IdleUnitButton.kt index 4551f032c4..3ba7628af7 100644 --- a/core/src/com/unciv/ui/worldscreen/unit/IdleUnitButton.kt +++ b/core/src/com/unciv/ui/worldscreen/unit/IdleUnitButton.kt @@ -46,7 +46,7 @@ class IdleUnitButton ( unitToSelect.due = false tileMapHolder.setCenterPosition(unitToSelect.currentTile.position) - unitTable.selectUnits(unitToSelect) + unitTable.selectUnit(unitToSelect) unitTable.worldScreen.shouldUpdate = true } } diff --git a/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt b/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt index e5c5e573ad..dc039c88fe 100644 --- a/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt +++ b/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt @@ -285,7 +285,7 @@ object UnitActions { type = UnitActionType.ConstructImprovement, isCurrentAction = unit.currentTile.hasImprovementInProgress(), action = { - worldScreen.game.setScreen(ImprovementPickerScreen(tile) { unitTable.selectUnits() }) + worldScreen.game.setScreen(ImprovementPickerScreen(tile) { unitTable.selectUnit() }) }.takeIf { canConstruct }) } @@ -443,7 +443,7 @@ object UnitActions { uncivSound = UncivSound.Fortify, action = { unit.fortify() - unitTable.selectUnits() + unitTable.selectUnit() }.takeIf { unit.currentMovement > 0 }) if (unit.health < 100) { @@ -452,7 +452,7 @@ object UnitActions { title = UnitActionType.FortifyUntilHealed.value, action = { unit.fortifyUntilHealed() - unitTable.selectUnits() + unitTable.selectUnit() }.takeIf { unit.currentMovement > 0 }) actionList += actionForWounded } @@ -469,7 +469,7 @@ object UnitActions { isCurrentAction = isSleeping, action = { unit.action = Constants.unitActionSleep - unitTable.selectUnits() + unitTable.selectUnit() }.takeIf { !isSleeping }) if (unit.health < 100 && !isSleeping) { @@ -478,7 +478,7 @@ object UnitActions { title = UnitActionType.SleepUntilHealed.value, action = { unit.action = Constants.unitActionSleepUntilHealed - unitTable.selectUnits() + unitTable.selectUnit() }) actionList += actionForWounded } diff --git a/core/src/com/unciv/ui/worldscreen/unit/UnitTable.kt b/core/src/com/unciv/ui/worldscreen/unit/UnitTable.kt index 191398ffec..5adc5d15ea 100644 --- a/core/src/com/unciv/ui/worldscreen/unit/UnitTable.kt +++ b/core/src/com/unciv/ui/worldscreen/unit/UnitTable.kt @@ -1,5 +1,7 @@ package com.unciv.ui.worldscreen.unit +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.Input import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.scenes.scene2d.Touchable import com.badlogic.gdx.scenes.scene2d.ui.Image @@ -28,11 +30,12 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){ /** This is in preparation for multi-select and multi-move */ val selectedUnits = ArrayList() - /** Sending no units clears the selected units entirely */ - fun selectUnits(vararg units:MapUnit) { - selectedUnits.clear() + + /** Sending no unit clears the selected units entirely */ + fun selectUnit(unit:MapUnit?=null, append:Boolean=false) { + if (!append) selectedUnits.clear() selectedCity = null - for (unit in units) selectedUnits.add(unit) + if (unit != null) selectedUnits.add(unit) } var selectedCity : CityInfo? = null @@ -56,7 +59,7 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){ deselectUnitButton.add(ImageGetter.getImage("OtherIcons/Close")).size(20f).pad(10f) deselectUnitButton.pack() deselectUnitButton.touchable = Touchable.enabled - deselectUnitButton.onClick { selectUnits(); worldScreen.shouldUpdate=true; this@UnitTable.isVisible=false } + deselectUnitButton.onClick { selectUnit(); worldScreen.shouldUpdate=true; this@UnitTable.isVisible=false } addActor(deselectUnitButton) }).left() @@ -86,10 +89,10 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){ if(selectedUnit!=null) { isVisible=true if (selectedUnit!!.civInfo != worldScreen.viewingCiv && !worldScreen.viewingCiv.isSpectator()) { // The unit that was selected, was captured. It exists but is no longer ours. - selectUnits() + selectUnit() selectedUnitHasChanged = true } else if (selectedUnit!! !in selectedUnit!!.getTile().getUnits()) { // The unit that was there no longer exists} - selectUnits() + selectUnit() selectedUnitHasChanged = true } } @@ -192,7 +195,7 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){ } fun citySelected(cityInfo: CityInfo) : Boolean { - selectUnits() + selectUnit() if (cityInfo == selectedCity) return false selectedCity = cityInfo selectedUnitHasChanged = true @@ -204,28 +207,28 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){ val previouslySelectedUnit = selectedUnit - if(selectedTile.isCityCenter() - && (selectedTile.getOwner()==worldScreen.viewingCiv || worldScreen.viewingCiv.isSpectator())){ + + if (selectedTile.isCityCenter() + && (selectedTile.getOwner() == worldScreen.viewingCiv || worldScreen.viewingCiv.isSpectator())) { citySelected(selectedTile.getCity()!!) - } - else if(selectedTile.militaryUnit!=null + } else if (selectedTile.militaryUnit != null && (selectedTile.militaryUnit!!.civInfo == worldScreen.viewingCiv || worldScreen.viewingCiv.isSpectator()) - && selectedUnit!=selectedTile.militaryUnit - && (selectedTile.civilianUnit==null || selectedUnit!=selectedTile.civilianUnit)) { - selectUnits(selectedTile.militaryUnit!!) - } - else if (selectedTile.civilianUnit!=null + && selectedTile.militaryUnit!! !in selectedUnits + && (selectedTile.civilianUnit == null || selectedUnit != selectedTile.civilianUnit)) { + if (Gdx.input.isKeyPressed(Input.Keys.SHIFT_LEFT)) selectUnit(selectedTile.militaryUnit!!, true) + else selectUnit(selectedTile.militaryUnit!!) + } else if (selectedTile.civilianUnit != null && (selectedTile.civilianUnit!!.civInfo == worldScreen.viewingCiv || worldScreen.viewingCiv.isSpectator()) - && selectedUnit!=selectedTile.civilianUnit) { - selectUnits(selectedTile.civilianUnit!!) - } else if(selectedTile == previouslySelectedUnit?.currentTile) { + && selectedUnit != selectedTile.civilianUnit) { + selectUnit(selectedTile.civilianUnit!!) + } else if (selectedTile == previouslySelectedUnit?.currentTile) { // tapping the same tile again will deselect a unit. // important for single-tap-move to abort moving easily - selectUnits() + selectUnit() isVisible = false } - if(selectedUnit != previouslySelectedUnit) + if (selectedUnit != previouslySelectedUnit) selectedUnitHasChanged = true }