mirror of
https://github.com/yairm210/Unciv.git
synced 2025-02-22 20:49:36 +07:00
units support single-tap move (#750)
* implemented single tap move - units stay selected after move (to go on moving) - and they are de-selectable by taping them again (to abort moving) * unit movement: mark the reachable spots clearly to avoid accidental movement * unit action: when an exclusive decision is made, deselect unit * clicking on the unit information in the UnitTable will show that unit + minor fixes * siege units won't show movement hints when set up, while packing up does not cost any movement points * workers: highlight button when constructing an improvement, won't sleep then * fixed units not being de-selected when clicking the UnitTable or "next unit" button * zooming forwards clicks on to the map, so we need to deselect units in that case * clean up branch * added "Move units with a single tap" to options menu
This commit is contained in:
parent
3cfe3a7f73
commit
fdf95317f0
@ -151,7 +151,7 @@
|
||||
Russian:"Бомбардная сила"
|
||||
French:"Force de bombardement"
|
||||
Romanian:"Puterea bombardamentului"
|
||||
German:"Bombardieren Sie die Stärke"
|
||||
German:"Stärke Bombardierung"
|
||||
Dutch:"Bombard sterkte"
|
||||
Spanish:"Fuerza de bombardeo"
|
||||
Simplified_Chinese:"远程轰击"
|
||||
@ -803,9 +803,15 @@
|
||||
"Check for idle units":{
|
||||
Italian:"Controlla unità inutilizzate"
|
||||
Simplified_Chinese:"查看未行动单位"
|
||||
Portuguese:"Cheque por unidades sem ordens"
|
||||
Portuguese:"Cheque por unidades sem ordens",
|
||||
German: "Untätige Einheiten anzeigen bei Rundenende"
|
||||
}
|
||||
|
||||
"Move units with a single tap":{
|
||||
German: "Einheiten mit einem Klick bewegen"
|
||||
},
|
||||
|
||||
|
||||
"Close":{
|
||||
Italian:"Chiudi"
|
||||
Russian:"Закрыть"
|
||||
|
@ -6,6 +6,7 @@ class GameSettings {
|
||||
var showWorkedTiles: Boolean = false
|
||||
var showResourcesAndImprovements: Boolean = true
|
||||
var checkForDueUnits: Boolean = true
|
||||
var singleTapMove: Boolean = false
|
||||
var language: String = "English"
|
||||
var resolution: String = "1050x700"
|
||||
var tutorialsShown = ArrayList<String>()
|
||||
|
@ -445,11 +445,9 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
fun showCircle(color: Color) {
|
||||
fun showCircle(color: Color, alpha: Float = 0.3f) {
|
||||
circleImage.isVisible = true
|
||||
circleImage.color = color.cpy().apply { a=0.3f }
|
||||
circleImage.color = color.cpy().apply { a=alpha }
|
||||
}
|
||||
|
||||
fun hideCircle() {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.unciv.ui.worldscreen
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.math.Interpolation
|
||||
import com.badlogic.gdx.math.Vector2
|
||||
@ -30,7 +31,6 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap:
|
||||
|
||||
// Used to transfer data on the "move here" button that should be created, from the side thread to the main thread
|
||||
class MoveHereButtonDto(val unit: MapUnit, val tileInfo: TileInfo, val turnsToGetThere: Int)
|
||||
var moveHereButtonDto :MoveHereButtonDto?=null
|
||||
|
||||
internal fun addTiles() {
|
||||
|
||||
@ -59,6 +59,8 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap:
|
||||
var lastInitialDistance = 0f
|
||||
|
||||
override fun zoom(event: InputEvent?, initialDistance: Float, distance: Float) {
|
||||
// deselect any unit, as zooming occasionally forwards clicks on to the map
|
||||
worldScreen.bottomBar.unitTable.selectedUnit = null
|
||||
if (lastInitialDistance != initialDistance) {
|
||||
lastInitialDistance = initialDistance
|
||||
lastScale = scaleX
|
||||
@ -79,10 +81,14 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap:
|
||||
selectedTile = tileInfo
|
||||
|
||||
val selectedUnit = worldScreen.bottomBar.unitTable.selectedUnit
|
||||
worldScreen.bottomBar.unitTable.tileSelected(tileInfo)
|
||||
|
||||
if (selectedUnit != null && selectedUnit.getTile() != tileInfo
|
||||
&& selectedUnit.canMoveTo(tileInfo) && selectedUnit.movementAlgs().canReach(tileInfo)) {
|
||||
&& selectedUnit.canMoveTo(tileInfo) && selectedUnit.movementAlgs().canReach(tileInfo)
|
||||
&& selectedUnit.action!="Set Up") {
|
||||
// this can take a long time, because of the unit-to-tile calculation needed, so we put it in a different thread
|
||||
queueAddMoveHereButton(selectedUnit, tileInfo)
|
||||
moveHere(selectedUnit, tileInfo)
|
||||
worldScreen.bottomBar.unitTable.selectedUnit = selectedUnit // keep moved unit selected
|
||||
}
|
||||
|
||||
if(selectedUnit==null || selectedUnit.type==UnitType.Civilian){
|
||||
@ -98,10 +104,11 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap:
|
||||
}
|
||||
|
||||
worldScreen.bottomBar.unitTable.tileSelected(tileInfo)
|
||||
|
||||
worldScreen.shouldUpdate = true
|
||||
}
|
||||
|
||||
private fun queueAddMoveHereButton(selectedUnit: MapUnit, tileInfo: TileInfo) {
|
||||
private fun moveHere(selectedUnit: MapUnit, tileInfo: TileInfo) {
|
||||
thread {
|
||||
/** LibGdx sometimes has these weird errors when you try to edit the UI layout from 2 separate threads.
|
||||
* And so, all UI editing will be done on the main thread.
|
||||
@ -109,9 +116,19 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap:
|
||||
* so that and that alone will be relegated to the concurrent thread.
|
||||
*/
|
||||
val turnsToGetThere = selectedUnit.movementAlgs().getShortestPath(tileInfo).size // this is what takes the most time, tbh
|
||||
moveHereButtonDto = MoveHereButtonDto(selectedUnit, tileInfo, turnsToGetThere)
|
||||
worldScreen.shouldUpdate = true // when the world screen updates, is calls our updateTiles,
|
||||
// which will add the move here button *on the main thread*! Problem solved!
|
||||
|
||||
Gdx.app.postRunnable {
|
||||
if(UnCivGame.Current.settings.singleTapMove && turnsToGetThere==1) {
|
||||
// single turn instant move
|
||||
selectedUnit.movementAlgs().headTowards(tileInfo)
|
||||
} else {
|
||||
// add "move to" button
|
||||
val moveHereButtonDto = MoveHereButtonDto(selectedUnit, tileInfo, turnsToGetThere)
|
||||
addMoveHereButtonToTile(moveHereButtonDto, tileGroups[moveHereButtonDto.tileInfo]!!)
|
||||
}
|
||||
worldScreen.shouldUpdate = true
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -202,11 +219,6 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap:
|
||||
tileGroup.showCircle(Color.RED) // Display ALL viewable enemies with a red circle so that users don't need to go "hunting" for enemy units
|
||||
}
|
||||
|
||||
if(moveHereButtonDto!=null) {
|
||||
addMoveHereButtonToTile(moveHereButtonDto!!, tileGroups[moveHereButtonDto!!.tileInfo]!!)
|
||||
moveHereButtonDto=null
|
||||
}
|
||||
|
||||
if (worldScreen.bottomBar.unitTable.selectedCity!=null){
|
||||
val city = worldScreen.bottomBar.unitTable.selectedCity!!
|
||||
updateTilegroupsForSelectedCity(city, playerViewableTilePositions)
|
||||
@ -224,11 +236,12 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap:
|
||||
}
|
||||
|
||||
private fun updateTilegroupsForSelectedUnit(unit: MapUnit, playerViewableTilePositions: HashSet<Vector2>) {
|
||||
|
||||
tileGroups[unit.getTile()]!!.selectUnit(unit)
|
||||
|
||||
for (tile: TileInfo in unit.getDistanceToTiles().keys)
|
||||
if (unit.canMoveTo(tile))
|
||||
tileGroups[tile]!!.showCircle(colorFromRGB(0, 120, 215))
|
||||
tileGroups[tile]!!.showCircle(Color.WHITE, if (UnCivGame.Current.settings.singleTapMove) 0.7f else 0.3f)
|
||||
|
||||
val unitType = unit.type
|
||||
val attackableTiles: List<TileInfo> = when {
|
||||
@ -260,10 +273,11 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap:
|
||||
}
|
||||
}
|
||||
|
||||
fun setCenterPosition(vector: Vector2, immediately: Boolean =false) {
|
||||
fun setCenterPosition(vector: Vector2, immediately: Boolean = false, selectUnit: Boolean = true) {
|
||||
val tileGroup = tileGroups.values.first { it.tileInfo.position == vector }
|
||||
selectedTile = tileGroup.tileInfo
|
||||
worldScreen.bottomBar.unitTable.tileSelected(selectedTile!!)
|
||||
if(selectUnit)
|
||||
worldScreen.bottomBar.unitTable.tileSelected(selectedTile!!)
|
||||
|
||||
val originalScrollX = scrollX
|
||||
val originalScrollY = scrollY
|
||||
|
@ -230,7 +230,8 @@ class WorldScreen : CameraStageBaseScreen() {
|
||||
if (currentPlayerCiv.shouldGoToDueUnit()) {
|
||||
val nextDueUnit = currentPlayerCiv.getNextDueUnit()
|
||||
if(nextDueUnit!=null) {
|
||||
tileMapHolder.setCenterPosition(nextDueUnit.currentTile.position)
|
||||
tileMapHolder.setCenterPosition(nextDueUnit.currentTile.position, false, false)
|
||||
bottomBar.unitTable.selectedUnit = nextDueUnit
|
||||
shouldUpdate=true
|
||||
}
|
||||
return@onClick
|
||||
|
@ -56,6 +56,12 @@ class WorldScreenOptionsTable(screen:WorldScreen) : PopupTable(screen){
|
||||
update()
|
||||
}
|
||||
|
||||
add("Move units with a single tap".toLabel())
|
||||
addButton(if(settings.singleTapMove) "Yes".tr() else "No".tr()) {
|
||||
settings.singleTapMove = !settings.singleTapMove
|
||||
update()
|
||||
}
|
||||
|
||||
addLanguageSelectBox()
|
||||
|
||||
addResolutionSelectBox()
|
||||
|
@ -74,7 +74,7 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){
|
||||
touchable = Touchable.enabled
|
||||
onClick {
|
||||
selectedUnit?.currentTile?.position?.let {
|
||||
worldScreen.tileMapHolder.setCenterPosition(it)
|
||||
worldScreen.tileMapHolder.setCenterPosition(it, false, false)
|
||||
}
|
||||
}
|
||||
}).expand()
|
||||
@ -172,7 +172,6 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){
|
||||
for(promotion in selectedUnit!!.promotions.promotions)
|
||||
promotionsTable.add(ImageGetter.getPromotionIcon(promotion)).size(20f)
|
||||
|
||||
unitDescriptionTable.onClick { worldScreen.tileMapHolder.setCenterPosition(selectedUnit!!.getTile().position) }
|
||||
}
|
||||
|
||||
pack()
|
||||
@ -205,7 +204,8 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){
|
||||
}
|
||||
|
||||
else if(selectedTile.militaryUnit!=null && selectedTile.militaryUnit!!.civInfo == worldScreen.currentPlayerCiv
|
||||
&& selectedUnit!=selectedTile.militaryUnit){
|
||||
&& selectedUnit!=selectedTile.militaryUnit
|
||||
&& (selectedTile.civilianUnit==null || selectedUnit!=selectedTile.civilianUnit)){
|
||||
selectedUnit = selectedTile.militaryUnit
|
||||
selectedCity = null
|
||||
}
|
||||
@ -213,6 +213,10 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){
|
||||
&& selectedUnit!=selectedTile.civilianUnit){
|
||||
selectedUnit = selectedTile.civilianUnit
|
||||
selectedCity = null
|
||||
} else if(selectedTile == previouslySelectedUnit?.currentTile) {
|
||||
// tapping the same tile again will deselect a unit.
|
||||
// important for single-tap-move to abort moving easily
|
||||
selectedUnit = null
|
||||
}
|
||||
|
||||
if(selectedUnit != previouslySelectedUnit)
|
||||
|
Loading…
Reference in New Issue
Block a user