Unit control transferred to UnitTable

This commit is contained in:
Yair Morgenstern 2018-03-07 18:37:16 +02:00
parent 07c011143d
commit 1a4a9d416c
13 changed files with 247 additions and 182 deletions

View File

View File

@ -9,7 +9,7 @@ import java.text.DecimalFormat
class MapUnit {
@Transient
@JvmField var civInfo: CivilizationInfo? = null
lateinit var civInfo: CivilizationInfo
@JvmField var owner: String? = null
@JvmField var name: String? = null
@ -55,7 +55,7 @@ class MapUnit {
private fun getPriority(tileInfo: TileInfo): Int {
var priority = 0
if (tileInfo.workingCity != null) priority += 2
if (tileInfo.hasViewableResource(civInfo!!)) priority += 1
if (tileInfo.hasViewableResource(civInfo)) priority += 1
if (tileInfo.owner == owner) priority += 2
else if (tileInfo.neighbors.any { it.owner != null }) priority += 1
return priority
@ -64,15 +64,15 @@ class MapUnit {
private fun findTileToWork(currentTile: TileInfo): TileInfo {
var selectedTile = currentTile
var selectedTilePriority =
if (currentTile.improvement == null && currentTile.canBuildImprovement(chooseImprovement(currentTile), civInfo!!))
if (currentTile.improvement == null && currentTile.canBuildImprovement(chooseImprovement(currentTile), civInfo))
getPriority(currentTile)
else
1 // min rank to get selected is 2
for (i in 1..4)
for (tile in civInfo!!.gameInfo.tileMap.getTilesAtDistance(currentTile.position, i))
for (tile in civInfo.gameInfo.tileMap.getTilesAtDistance(currentTile.position, i))
if (tile.unit == null && tile.improvement == null && getPriority(tile) > selectedTilePriority
&& tile.canBuildImprovement(chooseImprovement(tile), civInfo!!)) {
&& tile.canBuildImprovement(chooseImprovement(tile), civInfo)) {
selectedTile = tile
selectedTilePriority = getPriority(tile)
}
@ -90,9 +90,9 @@ class MapUnit {
}
if (tile.improvementInProgress == null) {
val improvement = chooseImprovement(tile)
if (tile.canBuildImprovement(improvement, civInfo!!))
if (tile.canBuildImprovement(improvement, civInfo))
// What if we're stuck on this tile but can't build there?
tile.startWorkingOnImprovement(improvement, civInfo!!)
tile.startWorkingOnImprovement(improvement, civInfo)
}
}
@ -121,16 +121,23 @@ class MapUnit {
* @param destination
* @return The tile that we reached this turn
*/
private fun headTowards(origin: Vector2, destination: Vector2): TileInfo {
val tileMap = civInfo!!.gameInfo.tileMap
val isMachineryResearched = civInfo!!.tech.isResearched("Machinery")
val path = tileMap.getShortestPath(origin, destination, currentMovement, maxMovement, isMachineryResearched)
fun headTowards(origin: Vector2, destination: Vector2): TileInfo {
val tileMap = civInfo.gameInfo.tileMap
val isMachineryResearched = civInfo.tech.isResearched("Machinery")
val distanceToTiles = tileMap.getDistanceToTilesWithinTurn(origin, currentMovement, isMachineryResearched)
val destinationThisTurn = path.first()
if (destinationThisTurn.unit != null) return tileMap[origin] // Someone is blocking tohe path to the final tile...
val distanceToTile = tileMap.getDistanceToTilesWithinTurn(origin, currentMovement, isMachineryResearched)[destinationThisTurn]!!
tileMap[origin].moveUnitToTile(destinationThisTurn, distanceToTile)
return destinationThisTurn
val destinationTileThisTurn:TileInfo
if (distanceToTiles.containsKey(tileMap.get(destination)))
destinationTileThisTurn = tileMap.get(destination)
else { // If the tile is far away, we need to build a path how to get there, and then take the first step
val path = tileMap.getShortestPath(origin, destination, currentMovement, maxMovement, isMachineryResearched)
destinationTileThisTurn = path.first()
}
if (destinationTileThisTurn.unit != null) return tileMap[origin] // Someone is blocking tohe path to the final tile...
val distanceToTile: Float = distanceToTiles[destinationTileThisTurn]!!
tileMap[origin].moveUnitToTile(destinationTileThisTurn, distanceToTile)
return destinationTileThisTurn
}
fun nextTurn(tileInfo: TileInfo) {

View File

@ -3,11 +3,11 @@ package com.unciv.logic.map
import com.badlogic.gdx.math.Vector2
import com.unciv.logic.city.CityInfo
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.models.linq.Linq
import com.unciv.models.gamebasics.GameBasics
import com.unciv.models.gamebasics.Terrain
import com.unciv.models.gamebasics.TileImprovement
import com.unciv.models.gamebasics.TileResource
import com.unciv.models.linq.Linq
import com.unciv.models.stats.Stats
class TileInfo {

View File

@ -1,11 +1,11 @@
package com.unciv.logic.map
import com.badlogic.gdx.math.Vector2
import com.unciv.logic.GameInfo
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.models.gamebasics.GameBasics
import com.unciv.models.linq.Linq
import com.unciv.models.linq.LinqHashMap
import com.unciv.logic.GameInfo
import com.unciv.ui.utils.HexMath
class TileMap {
@ -74,7 +74,7 @@ class TileMap {
return distanceToTiles
}
fun getShortestPath(origin: Vector2, destination: Vector2, currentMovement: Float, maxMovement: Int, isMachineryResearched: Boolean): Linq<TileInfo> {
fun getShortestPath(origin: Vector2, destination: Vector2, currentMovement: Float, maxMovement: Int, isMachineryResearched: Boolean): List<TileInfo> {
var tilesToCheck: Linq<TileInfo> = Linq(get(origin))
val movementTreeParents = LinqHashMap<TileInfo, TileInfo>() // contains a map of "you can get from X to Y in that turn"
movementTreeParents[get(origin)] = null
@ -82,24 +82,32 @@ class TileMap {
var distance = 1
while (true) {
val newTilesToCheck = Linq<TileInfo>()
val distanceToDestination = HashMap<TileInfo, Float>()
val movementThisTurn = if (distance == 1) currentMovement else maxMovement.toFloat()
for (tileToCheck in tilesToCheck) {
val movementThisTurn = if (distance == 1) currentMovement else maxMovement.toFloat()
for (reachableTile in getDistanceToTilesWithinTurn(tileToCheck.position, movementThisTurn, isMachineryResearched).keys) {
if (movementTreeParents.containsKey(reachableTile)) continue // We cannot be faster than anything existing...
if (reachableTile.position != destination && reachableTile.unit != null) continue // This is an intermediary tile that contains a unit - we can't go there!
movementTreeParents[reachableTile] = tileToCheck
if (reachableTile.position == destination) {
val path = Linq<TileInfo>() // Traverse the tree upwards to get the list of tiles leading to the destination,
var current = reachableTile
while (movementTreeParents[current] != null) {
path.add(current)
current = movementTreeParents[current]
}
return path.reverse() // and reverse in order to get the list in chronological order
val distanceToTilesThisTurn = getDistanceToTilesWithinTurn(tileToCheck.position, movementThisTurn, isMachineryResearched)
for (reachableTile in distanceToTilesThisTurn.keys) {
if(reachableTile.position == destination)
distanceToDestination.put(tileToCheck, distanceToTilesThisTurn[reachableTile]!!)
else {
if (movementTreeParents.containsKey(reachableTile)) continue // We cannot be faster than anything existing...
if (reachableTile.position != destination && reachableTile.unit != null) continue // This is an intermediary tile that contains a unit - we can't go there!
movementTreeParents[reachableTile] = tileToCheck
newTilesToCheck.add(reachableTile)
}
newTilesToCheck.add(reachableTile)
}
}
if (distanceToDestination.isNotEmpty()) {
val path = Linq<TileInfo>() // Traverse the tree upwards to get the list of tiles leading to the destination,
var currentTile = distanceToDestination.minBy { it.value }!!.key
while (currentTile.position != origin) {
path.add(currentTile)
currentTile = movementTreeParents[currentTile]!!
}
return path.reversed() // and reverse in order to get the list in chronological order
}
tilesToCheck = newTilesToCheck
distance++
}

View File

@ -2,13 +2,13 @@ package com.unciv.models.gamebasics
import com.unciv.logic.city.CityConstructions
import com.unciv.logic.city.IConstruction
import com.unciv.models.linq.Linq
import com.unciv.models.stats.NamedStats
import com.unciv.models.stats.Stats
import com.unciv.ui.ScienceVictoryScreen
import com.unciv.ui.UnCivGame
import com.unciv.ui.VictoryScreen
import com.unciv.ui.pickerscreens.PolicyPickerScreen
import com.unciv.models.linq.Linq
import com.unciv.models.stats.Stats
import com.unciv.models.stats.NamedStats
class Building : NamedStats(), IConstruction, ICivilopedia {
private lateinit var baseDescription: String
@ -146,7 +146,7 @@ class Building : NamedStats(), IConstruction, ICivilopedia {
if ("MustBeNextToDesert" == unique && !civInfo.gameInfo.tileMap.getTilesInDistance(construction.cityInfo.cityLocation, 1).any { it.baseTerrain == "Desert" })
return false
if (requiredResource != null && !civInfo.getCivResources().containsKey(GameBasics.TileResources[requiredResource]))
return false // Only checks if exists, doesn't check amount - todo
return false
if (requiredNearbyImprovedResources != null) {

View File

@ -5,7 +5,6 @@ import com.badlogic.gdx.utils.Predicate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
/**
@ -71,12 +70,6 @@ public class Linq<T> extends ArrayList<T> {
return newCollection;
}
public Linq<T> reverse(){
Linq<T> newCol = clone();
Collections.reverse(newCol);
return newCol;
}
public Linq<T> clone(){
return new Linq<T>(this);
}

View File

@ -88,7 +88,6 @@ class PolicyPickerScreen(internal val civInfo: CivilizationInfo) : PickerScreen(
private fun pickPolicy(policy: Policy) {
if (civInfo.policies.isAdopted(policy.name)
|| policy.name.endsWith("Complete")
|| !civInfo.policies.getAdoptedPolicies().containsAll(policy.requires!!)
|| !civInfo.policies.canAdoptPolicy()) {
rightSideButton.touchable = Touchable.disabled
@ -112,12 +111,13 @@ class PolicyPickerScreen(internal val civInfo: CivilizationInfo) : PickerScreen(
} else
toReturn = TextButton(policy.name, CameraStageBaseScreen.skin)
when {
civInfo.policies.isAdopted(policy.name) -> toReturn.color = Color.GREEN
policy.name.endsWith("Complete") || !civInfo.policies.getAdoptedPolicies().containsAll(policy.requires!!)
-> toReturn.color = Color.GRAY
if (civInfo.policies.isAdopted(policy.name)) { // existing
toReturn.color = Color.GREEN
} else if (!civInfo.policies.getAdoptedPolicies().containsAll(policy.requires!!))
// non-available
{
toReturn.color = Color.GRAY
}
toReturn.addClickListener { pickPolicy(policy) }
toReturn.pack()
return toReturn

View File

@ -1,14 +1,11 @@
package com.unciv.ui.worldscreen
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.Touchable
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.badlogic.gdx.utils.Align
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.map.TileInfo
import com.unciv.ui.cityscreen.addClickListener
import com.unciv.ui.utils.CameraStageBaseScreen
import com.unciv.ui.utils.ImageGetter
@ -43,49 +40,15 @@ class TileInfoTable(private val worldScreen: WorldScreen, internal val civInfo:
}
if (tile.unit != null) {
val tileMapHolder = worldScreen.tileMapHolder
val buttonText = if (tileMapHolder.unitTile == tile)"Stop movement" else "Move to"
var moveUnitButton = TextButton(buttonText, skin)
moveUnitButton.label.setFontScale(worldScreen.buttonScale)
if (tile.unit!!.currentMovement == 0f) {
moveUnitButton.color = Color.GRAY
moveUnitButton.touchable = Touchable.disabled
}
moveUnitButton.addClickListener {
if (tileMapHolder.unitTile != null) {
tileMapHolder.unitTile = null
tileMapHolder.updateTiles()
return@addClickListener
}
tileMapHolder.unitTile = tile
// if (tile.unit != null) {
// for (button in UnitActions().getUnitActions(tile))
// add(button).colspan(2)
// .size(button.width * worldScreen.buttonScale, button.height * worldScreen.buttonScale).row()
// }
// Set all tiles transparent except those in unit range
for (TG in tileMapHolder.tileGroups.linqValues()) TG.setColor(0f, 0f, 0f, 0.3f)
pack()
val distanceToTiles = civInfo.gameInfo.tileMap.getDistanceToTilesWithinTurn(
tileMapHolder.unitTile!!.position,
tileMapHolder.unitTile!!.unit!!.currentMovement,
civInfo.tech.isResearched("Machinery"))
for (tile in distanceToTiles.keys) {
tileMapHolder.tileGroups[tile.position.toString()]!!.color = Color.WHITE
}
worldScreen.update()
}
add(moveUnitButton).colspan(2)
.size(moveUnitButton.width * worldScreen.buttonScale, moveUnitButton.height * worldScreen.buttonScale).row()
for (button in UnitActions().getUnitActions(tile.unit!!,tile,civInfo))
add(button).colspan(2)
.size(button.width * worldScreen.buttonScale, button.height * worldScreen.buttonScale).row()
pack()
setPosition(worldScreen.stage.width - 10f - width, 10f)
}
setPosition(worldScreen.stage.width - 10f - width, 10f)
}
}

View File

@ -13,11 +13,10 @@ import com.unciv.models.linq.LinqHashMap
import com.unciv.ui.cityscreen.addClickListener
import com.unciv.ui.tilegroups.WorldTileGroup
import com.unciv.ui.utils.HexMath
import java.util.*
class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap: TileMap, internal val civInfo: CivilizationInfo) : ScrollPane(null) {
internal var selectedTile: TileInfo? = null
internal var unitTile: TileInfo? = null
//internal var unitTile: TileInfo? = null
val tileGroups = LinqHashMap<String, WorldTileGroup>()
internal fun addTiles() {
@ -39,19 +38,7 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap:
worldScreen.displayTutorials("TileClicked", tutorial)
selectedTile = tileInfo
if (unitTile != null && group.tileInfo.unit == null) {
val distanceToTiles = tileMap.getDistanceToTilesWithinTurn(unitTile!!.position, unitTile!!.unit!!.currentMovement, civInfo.tech.isResearched("Machinery"))
if (distanceToTiles.containsKey(selectedTile)) {
unitTile!!.moveUnitToTile(group.tileInfo, distanceToTiles[selectedTile]!!)
} else {
unitTile!!.unit!!.action = "moveTo " + selectedTile!!.position.x.toInt() + "," + selectedTile!!.position.y.toInt()
unitTile!!.unit!!.doPreTurnAction(unitTile!!)
}
unitTile = null
selectedTile = group.tileInfo
}
worldScreen.unitTable.tileSelected(tileInfo)
worldScreen.update()
}
@ -102,35 +89,28 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap:
internal fun updateTiles() {
for (WG in tileGroups.linqValues()) WG.update(worldScreen)
if (unitTile != null)
return // While we're in "unit move" mode, no tiles but the tiles the unit can move to will be "visible"
// YES A TRIPLE FOR, GOT PROBLEMS WITH THAT?
// Seriously though, there is probably a more efficient way of doing this, probably?
// The original implementation caused serious lag on android, so efficiency is key, here
for (WG in tileGroups.linqValues()) WG.setIsViewable(false)
val veiwableVectorStrings = HashSet<String>()
var viewablePositions = emptyList<Vector2>()
if(worldScreen.unitTable.currentlyExecutingAction == null) {
viewablePositions += tileMap.values.where { it.owner == civInfo.civName }
.flatMap { HexMath.GetAdjacentVectors(it.position) } // tiles adjacent to city tiles
viewablePositions += tileMap.values.where { it.unit != null }
.flatMap { tileMap.getViewableTiles(it.position, 2).select { it.position } } // Tiles within 2 tiles of units
}
// tiles adjacent to city tiles
for (tileInfo in tileMap.values)
if (civInfo.civName == tileInfo.owner)
for (adjacentLocation in HexMath.GetAdjacentVectors(tileInfo.position))
veiwableVectorStrings.add(adjacentLocation.toString())
else
viewablePositions += worldScreen.unitTable.getViewablePositionsForExecutingAction()
// Tiles within 2 tiles of units
for (tile in tileMap.values
.where { arg0 -> arg0.unit != null })
for (tileInfo in tileMap.getViewableTiles(tile.position, 2))
veiwableVectorStrings.add(tileInfo.position.toString())
for (string in viewablePositions.map { it.toString() }.filter { tileGroups.containsKey(it) })
tileGroups[string]!!.setIsViewable(true)
for (string in veiwableVectorStrings)
if (tileGroups.containsKey(string))
tileGroups[string]!!.setIsViewable(true)
}
fun setCenterPosition(vector: Vector2) {
val tileGroup = tileGroups.linqValues().first { it.tileInfo.position == vector }
selectedTile = tileGroup.tileInfo
if(selectedTile!!.unit!=null) worldScreen.unitTable.selectedUnitTile = selectedTile
layout() // Fit the scroll pane to the contents - otherwise, setScroll won't work!
// We want to center on the middle of TG (TG.getX()+TG.getWidth()/2)
// and so the scroll position (== where the screen starts) needs to be half a screen away
@ -138,6 +118,7 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap:
// Here it's the same, only the Y axis is inverted - when at 0 we're at the top, not bottom - so we invert it back.
scrollY = maxY - (tileGroup.y + tileGroup.width / 2 - worldScreen.stage.height / 2)
updateVisualScroll()
worldScreen.update()
}

View File

@ -10,6 +10,7 @@ import com.unciv.ui.pickerscreens.PolicyPickerScreen
import com.unciv.ui.pickerscreens.TechPickerScreen
import com.unciv.ui.utils.CameraStageBaseScreen
import com.unciv.ui.utils.GameSaver
import com.unciv.ui.worldscreen.unit.UnitTable
class WorldScreen : CameraStageBaseScreen() {
internal val civInfo: CivilizationInfo
@ -24,7 +25,7 @@ class WorldScreen : CameraStageBaseScreen() {
internal val optionsTable: WorldScreenOptionsTable
private val notificationsScroll: NotificationsScroll
internal val idleUnitButton = IdleUnitButton(this)
internal val unitTable = UnitTable(this)
init {
val gameInfo = game.gameInfo
@ -41,7 +42,7 @@ class WorldScreen : CameraStageBaseScreen() {
stage.addActor(civTable)
stage.addActor(techButton)
stage.addActor(notificationsScroll)
stage.addActor(idleUnitButton)
stage.addActor(unitTable)
update()
tileMapHolder.setCenterPosition(Vector2.Zero)
@ -80,7 +81,7 @@ class WorldScreen : CameraStageBaseScreen() {
tileMapHolder.updateTiles()
civTable.update(this)
notificationsScroll.update()
idleUnitButton.update()
unitTable.update()
if (civInfo.tech.freeTechs != 0) {
game.screen = TechPickerScreen(true, civInfo)
} else if (civInfo.policies.shouldOpenPolicyPicker) {
@ -93,8 +94,8 @@ class WorldScreen : CameraStageBaseScreen() {
techButton.isVisible = civInfo.cities.size != 0
techButton.clearListeners()
techButton.addClickListener {
game.screen = TechPickerScreen(civInfo)
}
game.screen = TechPickerScreen(civInfo)
}
if (civInfo.tech.currentTechnology() == null)
techButton.setText("Choose a tech!")
@ -109,22 +110,23 @@ class WorldScreen : CameraStageBaseScreen() {
private fun createNextTurnButton() {
val nextTurnButton = TextButton("Next turn", CameraStageBaseScreen.skin)
nextTurnButton.addClickListener {
if (civInfo.tech.currentTechnology() == null && civInfo.cities.size != 0) {
game.screen = TechPickerScreen(civInfo)
return@addClickListener
}
game.gameInfo.nextTurn()
tileMapHolder.unitTile = null
GameSaver.SaveGame(game, "Autosave")
update()
val tutorial = Linq<String>()
tutorial.add("In your first couple of turns," +
"\r\n you will have very little options," +
"\r\n but as your civilization grows, so do the " +
"\r\n number of things requiring your attention")
displayTutorials("NextTurn", tutorial)
if (civInfo.tech.currentTechnology() == null && civInfo.cities.size != 0) {
game.screen = TechPickerScreen(civInfo)
return@addClickListener
}
game.gameInfo.nextTurn()
unitTable.selectedUnitTile = null
unitTable.currentlyExecutingAction = null
GameSaver.SaveGame(game, "Autosave")
update()
val tutorial = Linq<String>()
tutorial.add("In your first couple of turns," +
"\r\n you will have very little options," +
"\r\n but as your civilization grows, so do the " +
"\r\n number of things requiring your attention")
displayTutorials("NextTurn", tutorial)
}
nextTurnButton.setPosition(stage.width - nextTurnButton.width - 10f,
civTable.y - nextTurnButton.height - 10f)

View File

@ -1,4 +1,4 @@
package com.unciv.ui.worldscreen
package com.unciv.ui.worldscreen.unit
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.Touchable
@ -6,12 +6,12 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextButton
import com.unciv.logic.map.TileInfo
import com.unciv.ui.cityscreen.addClickListener
import com.unciv.ui.utils.CameraStageBaseScreen
import com.unciv.ui.worldscreen.WorldScreen
class IdleUnitButton internal constructor(internal val worldScreen: WorldScreen) : TextButton("Select next idle unit", CameraStageBaseScreen.skin) {
init {
setPosition(worldScreen.stage.width / 2 - width / 2, 5f)
addClickListener {
val tilesWithIdleUnits = worldScreen.civInfo.gameInfo.tileMap.values.where { arg0 -> arg0.hasIdleUnit() }
val tilesWithIdleUnits = worldScreen.civInfo.gameInfo.tileMap.values.where { it.hasIdleUnit() }
val tileToSelect: TileInfo
if (!tilesWithIdleUnits.contains(worldScreen.tileMapHolder.selectedTile))
@ -22,18 +22,18 @@ class IdleUnitButton internal constructor(internal val worldScreen: WorldScreen)
tileToSelect = tilesWithIdleUnits[index]
}
worldScreen.tileMapHolder.setCenterPosition(tileToSelect.position)
worldScreen.tileMapHolder.selectedTile = tileToSelect
worldScreen.update()
}
}
internal fun update() {
if (worldScreen.civInfo.gameInfo.tileMap.values.any { arg0 -> arg0.hasIdleUnit() }) {
worldScreen.idleUnitButton.color = Color.WHITE
worldScreen.idleUnitButton.touchable = Touchable.enabled
if (worldScreen.civInfo.gameInfo.tileMap.values.any { it.hasIdleUnit() }) {
color = Color.WHITE
touchable = Touchable.enabled
} else {
worldScreen.idleUnitButton.color = Color.GRAY
worldScreen.idleUnitButton.touchable = Touchable.disabled
color = Color.GRAY
touchable = Touchable.disabled
}
}
}

View File

@ -1,9 +1,8 @@
package com.unciv.ui.worldscreen
package com.unciv.ui.worldscreen.unit
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.Touchable
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.map.MapUnit
import com.unciv.logic.map.TileInfo
import com.unciv.models.gamebasics.Building
@ -11,11 +10,12 @@ import com.unciv.models.gamebasics.GameBasics
import com.unciv.models.linq.Linq
import com.unciv.ui.UnCivGame
import com.unciv.ui.cityscreen.addClickListener
import com.unciv.ui.pickerscreens.ImprovementPickerScreen
import com.unciv.ui.pickerscreens.TechPickerScreen
import com.unciv.ui.utils.CameraStageBaseScreen
import java.util.ArrayList
import java.util.*
public class UnitActions {
class UnitActions {
private fun constructImprovementAndDestroyUnit(tileInfo: TileInfo, improvementName: String): () -> Unit {
return {
@ -24,15 +24,42 @@ public class UnitActions {
}
}
fun getUnitActions(unit: MapUnit, tile: TileInfo, civInfo: CivilizationInfo): List<TextButton> {
fun getUnitActions(tile: TileInfo): List<TextButton> {
val unit = tile.unit!!
val worldScreen = UnCivGame.Current.worldScreen!!
val tileMapHolder = worldScreen.tileMapHolder
val unitTable = worldScreen.unitTable
val actionList = ArrayList<TextButton>()
if (unitTable.currentlyExecutingAction != "moveTo"){
actionList += getUnitActionButton(unit, "Move unit", true, {
unitTable.currentlyExecutingAction = "moveTo"
// Set all tiles transparent except those in unit range
for (TG in tileMapHolder.tileGroups.linqValues()) TG.setColor(0f, 0f, 0f, 0.3f)
val distanceToTiles = tileMapHolder.tileMap.getDistanceToTilesWithinTurn(
unitTable.selectedUnitTile!!.position,
unitTable.getSelectedUnit().currentMovement,
unit.civInfo.tech.isResearched("Machinery"))
for (tileInRange in distanceToTiles.keys) {
tileMapHolder.tileGroups[tileInRange.position.toString()]!!.color = Color.WHITE
}
})
}
else {
actionList += getUnitActionButton(unit, "Stop movement", true, {
unitTable.currentlyExecutingAction = null
tileMapHolder.updateTiles()
})
}
if (unit.name == "Settler") {
actionList += getUnitActionButton(unit, "Found City",
!civInfo.gameInfo.tileMap.getTilesInDistance(tile.position, 2).any { it.isCityCenter },
!tileMapHolder.tileMap.getTilesInDistance(tile.position, 2).any { it.isCityCenter },
{
val tutorial = Linq<String>()
tutorial.add("You have founded a city!" +
@ -48,9 +75,8 @@ public class UnitActions {
worldScreen.displayTutorials("CityFounded", tutorial)
civInfo.addCity(tile.position)
if (worldScreen.tileMapHolder.unitTile == tile)
worldScreen.tileMapHolder.unitTile = null // The settler was in the middle of moving and we then founded a city with it
unit.civInfo.addCity(tile.position)
unitTable.currentlyExecutingAction = null // In case the settler was in the middle of doing something and we then founded a city with it
tile.unit = null // Remove settler!
worldScreen.update()
})
@ -60,25 +86,30 @@ public class UnitActions {
val improvementButtonText =
if (tile.improvementInProgress == null) "Construct\r\nimprovement"
else tile.improvementInProgress!! + "\r\nin progress"
actionList += getUnitActionButton(unit, improvementButtonText, !tile.isCityCenter || GameBasics.TileImprovements.linqValues().any { arg0 -> tile.canBuildImprovement(arg0, civInfo) },
{ worldScreen.game.screen = com.unciv.ui.pickerscreens.ImprovementPickerScreen(tile) })
actionList += getUnitActionButton(unit, if ("automation" == tile.unit!!.action) "Stop automation" else "Automate", true, {
if ("automation" == tile.unit!!.action)
tile.unit!!.action = null
else {
tile.unit!!.action = "automation"
tile.unit!!.doAutomatedAction(tile)
}
worldScreen.update()
})
actionList += getUnitActionButton(unit, improvementButtonText,
!tile.isCityCenter || GameBasics.TileImprovements.linqValues().any { tile.canBuildImprovement(it, unit.civInfo) },
{ worldScreen.game.screen = ImprovementPickerScreen(tile) })
if("automation" == tile.unit!!.action){
actionList += getUnitActionButton(unit,"Stop automation",true,
{tile.unit!!.action = null})
}
else {
actionList += getUnitActionButton(unit, "Automate", true,
{
tile.unit!!.action = "automation"
tile.unit!!.doAutomatedAction(tile)
}
)
}
}
if (unit.name == "Great Scientist") {
actionList += getUnitActionButton(unit, "Discover Technology", true,
{
civInfo.tech.freeTechs += 1
unit.civInfo.tech.freeTechs += 1
tile.unit = null// destroy!
worldScreen.game.screen = TechPickerScreen(true, civInfo)
worldScreen.game.screen = TechPickerScreen(true, unit.civInfo)
})
actionList += getUnitActionButton(unit, "Construct Academy", true,
@ -88,7 +119,7 @@ public class UnitActions {
if (unit.name == "Great Artist") {
actionList += getUnitActionButton(unit, "Start Golden Age", true,
{
civInfo.goldenAges.enterGoldenAge()
unit.civInfo.goldenAges.enterGoldenAge()
tile.unit = null// destroy!
worldScreen.update()
}
@ -112,7 +143,7 @@ public class UnitActions {
if (unit.name == "Great Merchant") {
actionList += getUnitActionButton(unit, "Conduct Trade Mission", true,
{
civInfo.gold += 350 // + 50 * era_number - todo!
unit.civInfo.gold += 350 // + 50 * era_number - todo!
tile.unit = null // destroy!
})
actionList += getUnitActionButton(unit, "Construct Customs House", true,

View File

@ -0,0 +1,80 @@
package com.unciv.ui.worldscreen.unit
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.math.Vector2
import com.badlogic.gdx.scenes.scene2d.ui.Label
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.unciv.logic.map.MapUnit
import com.unciv.logic.map.TileInfo
import com.unciv.models.linq.LinqHashMap
import com.unciv.ui.utils.CameraStageBaseScreen
import com.unciv.ui.utils.ImageGetter
import com.unciv.ui.worldscreen.WorldScreen
class UnitTable(val worldScreen: WorldScreen) : Table(){
private val idleUnitButton = IdleUnitButton(worldScreen)
private val unitLabel = Label("",CameraStageBaseScreen.skin)
var selectedUnitTile : TileInfo? = null
var currentlyExecutingAction : String? = null
private val unitActionsTable = Table()
fun getSelectedUnit(): MapUnit {
if(selectedUnitTile==null) throw Exception("getSelectedUnit was called when no unit was selected!")
else return selectedUnitTile!!.unit!!
}
init {
val tileTableBackground = ImageGetter.getDrawable("skin/tileTableBackground.png")
.tint(Color(0x004085bf))
pad(20f)
setBackground(tileTableBackground)
add(unitLabel)
add(unitActionsTable)
row()
add(idleUnitButton).colspan(2)
}
fun update() {
idleUnitButton.update()
unitActionsTable.clear()
if(selectedUnitTile!=null && selectedUnitTile!!.unit==null) selectedUnitTile=null // The unit that was there no longer exists
if(selectedUnitTile!=null) {
unitLabel.setText(getSelectedUnit().name+" "+getSelectedUnit().movementString)
for (button in UnitActions().getUnitActions(selectedUnitTile!!))
unitActionsTable.add(button).colspan(2).pad(5f)
.size(button.width * worldScreen.buttonScale, button.height * worldScreen.buttonScale).row()
}
unitActionsTable.pack()
pack()
setPosition(worldScreen.stage.width / 2 - width / 2, 5f)
}
fun tileSelected(selectedTile: TileInfo) {
if(currentlyExecutingAction=="moveTo"){
val reachedTile = getSelectedUnit().headTowards(selectedUnitTile!!.position, selectedTile.position)
selectedUnitTile = reachedTile
if(reachedTile!=selectedTile) // Didn't get all the way there
getSelectedUnit().action = "moveTo " + selectedTile.position.x.toInt() + "," + selectedTile.position.y.toInt()
currentlyExecutingAction = null
}
if(selectedTile.unit!=null) selectedUnitTile = selectedTile
}
private fun getDistanceToTiles(): LinqHashMap<TileInfo, Float> {
return worldScreen.tileMapHolder.tileMap.getDistanceToTilesWithinTurn(selectedUnitTile!!.position,
getSelectedUnit().currentMovement,
getSelectedUnit().civInfo.tech.isResearched("Machinery"))
}
fun getViewablePositionsForExecutingAction(): List<Vector2>
{
if(currentlyExecutingAction == "moveTo")
return getDistanceToTiles().keys.map { it.position }
return emptyList()
}
}