City Screen improvements (#8598)
* City Screen improvements * Buy icon reverted to Gold icon --------- Co-authored-by: tunerzinc@gmail.com <vfylfhby>
BIN
android/Images/TileIcons/Buy.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
android/Images/TileIcons/CityCenter.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
BIN
android/Images/TileIcons/NotWorked.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
android/Images/TileIcons/Worked.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 456 KiB After Width: | Height: | Size: 469 KiB |
@ -55,6 +55,15 @@ class CityExpansionManager : IsPartOfGameInfoSerialization {
|
|||||||
return cultureToNextTile.roundToInt()
|
return cultureToNextTile.roundToInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun canBuyTile(tile: Tile): Boolean {
|
||||||
|
return when {
|
||||||
|
city.isPuppet -> false
|
||||||
|
tile.getOwner() != null -> false
|
||||||
|
tile !in city.tilesInRange -> false
|
||||||
|
else -> tile.neighbors.any { it.getCity() == city }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun buyTile(tile: Tile) {
|
fun buyTile(tile: Tile) {
|
||||||
val goldCost = getGoldCostOfTile(tile)
|
val goldCost = getGoldCostOfTile(tile)
|
||||||
|
|
||||||
|
@ -697,6 +697,14 @@ class Civilization : IsPartOfGameInfoSerialization {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun hasGoldToBuy(price: Int): Boolean {
|
||||||
|
return when {
|
||||||
|
gameInfo.gameParameters.godMode -> true
|
||||||
|
price == 0 -> true
|
||||||
|
else -> gold >= price
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun addStats(stats: Stats){
|
fun addStats(stats: Stats){
|
||||||
for ((stat, amount) in stats) addStat(stat, amount.toInt())
|
for ((stat, amount) in stats) addStat(stat, amount.toInt())
|
||||||
}
|
}
|
||||||
|
29
core/src/com/unciv/ui/cityscreen/CityMapHolder.kt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package com.unciv.ui.cityscreen
|
||||||
|
|
||||||
|
import com.unciv.ui.UncivStage
|
||||||
|
import com.unciv.ui.tilegroups.TileGroupMap
|
||||||
|
import com.unciv.ui.utils.ZoomableScrollPane
|
||||||
|
|
||||||
|
class CityMapHolder : ZoomableScrollPane(20f, 20f) {
|
||||||
|
|
||||||
|
init {
|
||||||
|
setupZoomPanListeners()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupZoomPanListeners() {
|
||||||
|
|
||||||
|
fun setActHit() {
|
||||||
|
val isEnabled = !isZooming() && !isPanning
|
||||||
|
(stage as UncivStage).performPointerEnterExitEvents = isEnabled
|
||||||
|
val tileGroupMap = actor as TileGroupMap<*>
|
||||||
|
tileGroupMap.shouldAct = isEnabled
|
||||||
|
tileGroupMap.shouldHit = isEnabled
|
||||||
|
}
|
||||||
|
|
||||||
|
onPanStartListener = { setActHit() }
|
||||||
|
onPanStopListener = { setActHit() }
|
||||||
|
onZoomStartListener = { setActHit() }
|
||||||
|
onZoomStopListener = { setActHit() }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -16,9 +16,11 @@ import com.unciv.models.ruleset.tile.TileImprovement
|
|||||||
import com.unciv.models.ruleset.unique.LocalUniqueCache
|
import com.unciv.models.ruleset.unique.LocalUniqueCache
|
||||||
import com.unciv.models.ruleset.unique.UniqueType
|
import com.unciv.models.ruleset.unique.UniqueType
|
||||||
import com.unciv.models.stats.Stat
|
import com.unciv.models.stats.Stat
|
||||||
|
import com.unciv.models.translations.tr
|
||||||
import com.unciv.ui.audio.CityAmbiencePlayer
|
import com.unciv.ui.audio.CityAmbiencePlayer
|
||||||
import com.unciv.ui.audio.SoundPlayer
|
import com.unciv.ui.audio.SoundPlayer
|
||||||
import com.unciv.ui.images.ImageGetter
|
import com.unciv.ui.images.ImageGetter
|
||||||
|
import com.unciv.ui.popup.ConfirmPopup
|
||||||
import com.unciv.ui.tilegroups.TileGroupMap
|
import com.unciv.ui.tilegroups.TileGroupMap
|
||||||
import com.unciv.ui.popup.ToastPopup
|
import com.unciv.ui.popup.ToastPopup
|
||||||
import com.unciv.ui.tilegroups.CityTileGroup
|
import com.unciv.ui.tilegroups.CityTileGroup
|
||||||
@ -26,7 +28,6 @@ import com.unciv.ui.tilegroups.TileSetStrings
|
|||||||
import com.unciv.ui.utils.BaseScreen
|
import com.unciv.ui.utils.BaseScreen
|
||||||
import com.unciv.ui.utils.KeyCharAndCode
|
import com.unciv.ui.utils.KeyCharAndCode
|
||||||
import com.unciv.ui.utils.RecreateOnResize
|
import com.unciv.ui.utils.RecreateOnResize
|
||||||
import com.unciv.ui.utils.ZoomableScrollPane
|
|
||||||
import com.unciv.ui.utils.extensions.disable
|
import com.unciv.ui.utils.extensions.disable
|
||||||
import com.unciv.ui.utils.extensions.keyShortcuts
|
import com.unciv.ui.utils.extensions.keyShortcuts
|
||||||
import com.unciv.ui.utils.extensions.onActivation
|
import com.unciv.ui.utils.extensions.onActivation
|
||||||
@ -88,7 +89,7 @@ class CityScreen(
|
|||||||
private var tileGroups = ArrayList<CityTileGroup>()
|
private var tileGroups = ArrayList<CityTileGroup>()
|
||||||
|
|
||||||
/** The ScrollPane for the background map view of the city surroundings */
|
/** The ScrollPane for the background map view of the city surroundings */
|
||||||
private val mapScrollPane = ZoomableScrollPane()
|
private val mapScrollPane = CityMapHolder()
|
||||||
|
|
||||||
/** Support for [UniqueType.CreatesOneImprovement] - need user to pick a tile */
|
/** Support for [UniqueType.CreatesOneImprovement] - need user to pick a tile */
|
||||||
class PickTileForImprovementData (
|
class PickTileForImprovementData (
|
||||||
@ -302,9 +303,8 @@ class CityScreen(
|
|||||||
.map { CityTileGroup(cityInfo, it, tileSetStrings) }
|
.map { CityTileGroup(cityInfo, it, tileSetStrings) }
|
||||||
|
|
||||||
for (tileGroup in cityTileGroups) {
|
for (tileGroup in cityTileGroups) {
|
||||||
tileGroup.onClick {
|
tileGroup.onClick { tileGroupOnClick(tileGroup, cityInfo) }
|
||||||
tileGroupOnClick(tileGroup, cityInfo)
|
tileGroup.layerMisc.onClick { tileWorkedIconOnClick(tileGroup, cityInfo) }
|
||||||
}
|
|
||||||
tileGroups.add(tileGroup)
|
tileGroups.add(tileGroup)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,6 +330,45 @@ class CityScreen(
|
|||||||
mapScrollPane.updateVisualScroll()
|
mapScrollPane.updateVisualScroll()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun tileWorkedIconOnClick(tileGroup: CityTileGroup, city: City) {
|
||||||
|
|
||||||
|
if (!canChangeState || city.isPuppet) return
|
||||||
|
val tile = tileGroup.tile
|
||||||
|
|
||||||
|
// Cycling as: Not-worked -> Worked -> Locked -> Not-worked
|
||||||
|
if (tileGroup.isWorkable) {
|
||||||
|
if (!tile.providesYield() && city.population.getFreePopulation() > 0) {
|
||||||
|
city.workedTiles.add(tile.position)
|
||||||
|
game.settings.addCompletedTutorialTask("Reassign worked tiles")
|
||||||
|
} else if (tile.isWorked() && !tile.isLocked()) {
|
||||||
|
city.lockedTiles.add(tile.position)
|
||||||
|
} else if (tile.isLocked()) {
|
||||||
|
city.workedTiles.remove(tile.position)
|
||||||
|
city.lockedTiles.remove(tile.position)
|
||||||
|
}
|
||||||
|
city.cityStats.update()
|
||||||
|
update()
|
||||||
|
|
||||||
|
} else if (tileGroup.isPurchasable) {
|
||||||
|
|
||||||
|
val price = city.expansion.getGoldCostOfTile(tile)
|
||||||
|
val purchasePrompt = "Currently you have [${city.civ.gold}] [Gold].".tr() + "\n\n" +
|
||||||
|
"Would you like to purchase [Tile] for [$price] [${Stat.Gold.character}]?".tr()
|
||||||
|
ConfirmPopup(
|
||||||
|
this,
|
||||||
|
purchasePrompt,
|
||||||
|
"Purchase",
|
||||||
|
true,
|
||||||
|
restoreDefault = { update() }
|
||||||
|
) {
|
||||||
|
SoundPlayer.play(UncivSound.Coin)
|
||||||
|
city.expansion.buyTile(tile)
|
||||||
|
// preselect the next tile on city screen rebuild so bulk buying can go faster
|
||||||
|
UncivGame.Current.replaceCurrentScreen(CityScreen(city, initSelectedTile = city.expansion.chooseNewTileToOwn()))
|
||||||
|
}.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun tileGroupOnClick(tileGroup: CityTileGroup, city: City) {
|
private fun tileGroupOnClick(tileGroup: CityTileGroup, city: City) {
|
||||||
if (city.isPuppet) return
|
if (city.isPuppet) return
|
||||||
val tileInfo = tileGroup.tile
|
val tileInfo = tileGroup.tile
|
||||||
@ -356,17 +395,6 @@ class CityScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
selectTile(tileInfo)
|
selectTile(tileInfo)
|
||||||
if (tileGroup.isWorkable && canChangeState) {
|
|
||||||
if (!tileInfo.providesYield() && city.population.getFreePopulation() > 0) {
|
|
||||||
city.workedTiles.add(tileInfo.position)
|
|
||||||
city.lockedTiles.add(tileInfo.position)
|
|
||||||
game.settings.addCompletedTutorialTask("Reassign worked tiles")
|
|
||||||
} else if (tileInfo.isWorked()) {
|
|
||||||
city.workedTiles.remove(tileInfo.position)
|
|
||||||
city.lockedTiles.remove(tileInfo.position)
|
|
||||||
}
|
|
||||||
city.cityStats.update()
|
|
||||||
}
|
|
||||||
update()
|
update()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ class CityScreenTileTable(private val cityScreen: CityScreen): Table() {
|
|||||||
innerTable.row()
|
innerTable.row()
|
||||||
innerTable.add(getTileStatsTable(stats)).row()
|
innerTable.add(getTileStatsTable(stats)).row()
|
||||||
|
|
||||||
if (isTilePurchaseShown(selectedTile)) {
|
if (city.expansion.canBuyTile(selectedTile)) {
|
||||||
val goldCostOfTile = city.expansion.getGoldCostOfTile(selectedTile)
|
val goldCostOfTile = city.expansion.getGoldCostOfTile(selectedTile)
|
||||||
val buyTileButton = "Buy for [$goldCostOfTile] gold".toTextButton()
|
val buyTileButton = "Buy for [$goldCostOfTile] gold".toTextButton()
|
||||||
buyTileButton.onActivation {
|
buyTileButton.onActivation {
|
||||||
@ -67,7 +67,7 @@ class CityScreenTileTable(private val cityScreen: CityScreen): Table() {
|
|||||||
askToBuyTile(selectedTile)
|
askToBuyTile(selectedTile)
|
||||||
}
|
}
|
||||||
buyTileButton.keyShortcuts.add('T')
|
buyTileButton.keyShortcuts.add('T')
|
||||||
buyTileButton.isEnabled = isTilePurchaseAllowed(goldCostOfTile)
|
buyTileButton.isEnabled = cityScreen.canChangeState && city.civ.hasGoldToBuy(goldCostOfTile)
|
||||||
buyTileButton.addTooltip('T') // The key binding is done in CityScreen constructor
|
buyTileButton.addTooltip('T') // The key binding is done in CityScreen constructor
|
||||||
innerTable.add(buyTileButton).padTop(5f).row()
|
innerTable.add(buyTileButton).padTop(5f).row()
|
||||||
}
|
}
|
||||||
@ -113,9 +113,9 @@ class CityScreenTileTable(private val cityScreen: CityScreen): Table() {
|
|||||||
*/
|
*/
|
||||||
private fun askToBuyTile(selectedTile: Tile) {
|
private fun askToBuyTile(selectedTile: Tile) {
|
||||||
// These checks are redundant for the onClick action, but not for the keyboard binding
|
// These checks are redundant for the onClick action, but not for the keyboard binding
|
||||||
if (!isTilePurchaseShown(selectedTile)) return
|
if (!city.expansion.canBuyTile(selectedTile)) return
|
||||||
val goldCostOfTile = city.expansion.getGoldCostOfTile(selectedTile)
|
val goldCostOfTile = city.expansion.getGoldCostOfTile(selectedTile)
|
||||||
if (!isTilePurchaseAllowed(goldCostOfTile)) return
|
if (!city.civ.hasGoldToBuy(goldCostOfTile)) return
|
||||||
|
|
||||||
cityScreen.closeAllPopups()
|
cityScreen.closeAllPopups()
|
||||||
|
|
||||||
@ -135,21 +135,6 @@ class CityScreenTileTable(private val cityScreen: CityScreen): Table() {
|
|||||||
}.open()
|
}.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This tests whether the buy button should be _shown_ */
|
|
||||||
private fun isTilePurchaseShown(selectedTile: Tile) = when {
|
|
||||||
selectedTile.getOwner() != null -> false
|
|
||||||
selectedTile !in city.tilesInRange -> false
|
|
||||||
else -> selectedTile.neighbors.any { it.getCity() == city }
|
|
||||||
}
|
|
||||||
/** This tests whether the buy button should be _enabled_ */
|
|
||||||
private fun isTilePurchaseAllowed(goldCostOfTile: Int) = when {
|
|
||||||
city.isPuppet -> false
|
|
||||||
!cityScreen.canChangeState -> false
|
|
||||||
city.civ.gameInfo.gameParameters.godMode -> true
|
|
||||||
goldCostOfTile == 0 -> true
|
|
||||||
else -> city.civ.gold >= goldCostOfTile
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getTileStatsTable(stats: Stats): Table {
|
private fun getTileStatsTable(stats: Stats): Table {
|
||||||
val statsTable = Table()
|
val statsTable = Table()
|
||||||
statsTable.defaults().pad(2f)
|
statsTable.defaults().pad(2f)
|
||||||
|
@ -1,23 +1,38 @@
|
|||||||
package com.unciv.ui.tilegroups
|
package com.unciv.ui.tilegroups
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Color
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.Actor
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.Touchable
|
||||||
|
import com.badlogic.gdx.utils.Align
|
||||||
import com.unciv.UncivGame
|
import com.unciv.UncivGame
|
||||||
import com.unciv.logic.city.City
|
import com.unciv.logic.city.City
|
||||||
import com.unciv.logic.civilization.Civilization
|
import com.unciv.logic.civilization.Civilization
|
||||||
import com.unciv.logic.map.tile.Tile
|
import com.unciv.logic.map.tile.Tile
|
||||||
import com.unciv.ui.images.ImageGetter
|
import com.unciv.ui.images.ImageGetter
|
||||||
|
import com.unciv.ui.utils.extensions.addToCenter
|
||||||
|
import com.unciv.ui.utils.extensions.darken
|
||||||
|
import com.unciv.ui.utils.extensions.setFontColor
|
||||||
|
import com.unciv.ui.utils.extensions.toGroup
|
||||||
|
import com.unciv.ui.utils.extensions.toLabel
|
||||||
|
|
||||||
class CityTileGroup(private val city: City, tile: Tile, tileSetStrings: TileSetStrings) : TileGroup(tile,tileSetStrings) {
|
class CityTileGroup(private val city: City, tile: Tile, tileSetStrings: TileSetStrings) : TileGroup(tile,tileSetStrings) {
|
||||||
|
|
||||||
var isWorkable = false
|
var isWorkable = false
|
||||||
|
var isPurchasable = false
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (city.location == tile.position)
|
layerMisc.touchable = Touchable.childrenOnly
|
||||||
layerMisc.setNewPopulationIcon(ImageGetter.getImage("OtherIcons/Star"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun update(viewingCiv: Civilization?) {
|
override fun update(viewingCiv: Civilization?) {
|
||||||
super.update(city.civ)
|
super.update(city.civ)
|
||||||
|
|
||||||
|
isWorkable = false
|
||||||
|
isPurchasable = false
|
||||||
|
|
||||||
|
layerMisc.removeWorkedIcon()
|
||||||
|
var icon: Actor? = null
|
||||||
|
|
||||||
when {
|
when {
|
||||||
|
|
||||||
// Does not belong to us
|
// Does not belong to us
|
||||||
@ -25,6 +40,25 @@ class CityTileGroup(private val city: City, tile: Tile, tileSetStrings: TileSetS
|
|||||||
layerTerrain.dim(0.3f)
|
layerTerrain.dim(0.3f)
|
||||||
layerMisc.setYieldVisible(UncivGame.Current.settings.showTileYields)
|
layerMisc.setYieldVisible(UncivGame.Current.settings.showTileYields)
|
||||||
layerMisc.dimYields(true)
|
layerMisc.dimYields(true)
|
||||||
|
|
||||||
|
// Can be purchased in principle? Add icon.
|
||||||
|
if (city.expansion.canBuyTile(tile)) {
|
||||||
|
|
||||||
|
val price = city.expansion.getGoldCostOfTile(tile)
|
||||||
|
val label = price.toString().toLabel(fontSize = 9, alignment = Align.center)
|
||||||
|
val image = ImageGetter.getImage("TileIcons/Buy")
|
||||||
|
icon = image.toGroup(26f).apply { isTransform = false }
|
||||||
|
icon.addToCenter(label)
|
||||||
|
label.y -= 15f
|
||||||
|
|
||||||
|
// Can be purchased now?
|
||||||
|
if (!city.civ.hasGoldToBuy(price)) {
|
||||||
|
image.color = Color.WHITE.darken(0.5f)
|
||||||
|
label.setFontColor(Color.RED)
|
||||||
|
} else {
|
||||||
|
isPurchasable = true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Out of city range
|
// Out of city range
|
||||||
@ -40,34 +74,56 @@ class CityTileGroup(private val city: City, tile: Tile, tileSetStrings: TileSetS
|
|||||||
layerMisc.dimYields(true)
|
layerMisc.dimYields(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Locked
|
// City Center
|
||||||
tile.isLocked() -> {
|
tile.isCityCenter() -> {
|
||||||
layerMisc.setNewPopulationIcon(ImageGetter.getImage("OtherIcons/Lock"))
|
icon = ImageGetter.getImage("TileIcons/CityCenter")
|
||||||
isWorkable = true
|
layerMisc.dimYields(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Workable
|
// Does not provide yields
|
||||||
tile.isWorked() || !tile.providesYield() -> {
|
tile.stats.getTileStats(viewingCiv).isEmpty() -> {
|
||||||
layerMisc.setNewPopulationIcon()
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
// Locked
|
||||||
|
tile.isLocked() -> {
|
||||||
|
icon = ImageGetter.getImage("TileIcons/Locked")
|
||||||
isWorkable = true
|
isWorkable = true
|
||||||
|
layerMisc.dimYields(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Worked
|
||||||
|
tile.isWorked() -> {
|
||||||
|
icon = ImageGetter.getImage("TileIcons/Worked")
|
||||||
|
isWorkable = true
|
||||||
|
layerMisc.dimYields(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not-worked
|
||||||
|
else -> {
|
||||||
|
icon = ImageGetter.getImage("TileIcons/NotWorked")
|
||||||
|
isWorkable = true
|
||||||
|
layerMisc.dimYields(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// No unit flags inside CityScreen
|
if (icon != null) {
|
||||||
layerUnitFlag.isVisible = false
|
icon.setSize(26f, 26f)
|
||||||
|
icon.setPosition(width/2 - icon.width/2,
|
||||||
|
height*0.85f - icon.height/2)
|
||||||
|
layerMisc.addWorkedIcon(icon)
|
||||||
|
}
|
||||||
|
|
||||||
// Pixel art, road, improvements are dimmed inside CityScreen
|
// No unit flags and city-buttons inside CityScreen
|
||||||
|
layerUnitFlag.isVisible = false
|
||||||
|
layerCityButton.isVisible = false
|
||||||
|
|
||||||
|
// Pixel art, roads, improvements are dimmed inside CityScreen
|
||||||
layerUnitArt.dim()
|
layerUnitArt.dim()
|
||||||
layerFeatures.dim()
|
layerFeatures.dim()
|
||||||
layerMisc.dimImprovement(true)
|
layerMisc.dimImprovement(true)
|
||||||
|
|
||||||
// Dim yield icons if tile is not worked
|
// Put whole layer (yield, pop, improvement, res) to front
|
||||||
if (!tile.providesYield())
|
|
||||||
layerMisc.dimYields(true)
|
|
||||||
|
|
||||||
// Update citizen icon and put whole layer (yield, pop, improvement, res) to front
|
|
||||||
layerMisc.updatePopulationIcon()
|
|
||||||
layerMisc.toFront()
|
layerMisc.toFront()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,30 +1,54 @@
|
|||||||
package com.unciv.ui.tilegroups
|
package com.unciv.ui.tilegroups
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Color
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.Touchable
|
||||||
import com.unciv.UncivGame
|
import com.unciv.UncivGame
|
||||||
import com.unciv.logic.civilization.Civilization
|
import com.unciv.logic.civilization.Civilization
|
||||||
import com.unciv.logic.map.tile.Tile
|
import com.unciv.logic.map.tile.Tile
|
||||||
|
import com.unciv.ui.images.ImageGetter
|
||||||
|
import com.unciv.ui.utils.extensions.center
|
||||||
|
import com.unciv.ui.utils.extensions.darken
|
||||||
import com.unciv.ui.worldscreen.WorldScreen
|
import com.unciv.ui.worldscreen.WorldScreen
|
||||||
|
|
||||||
|
|
||||||
class WorldTileGroup(internal val worldScreen: WorldScreen, tile: Tile, tileSetStrings: TileSetStrings)
|
class WorldTileGroup(internal val worldScreen: WorldScreen, tile: Tile, tileSetStrings: TileSetStrings)
|
||||||
: TileGroup(tile,tileSetStrings) {
|
: TileGroup(tile,tileSetStrings) {
|
||||||
|
|
||||||
override fun update(viewingCiv: Civilization?) {
|
init {
|
||||||
|
layerMisc.touchable = Touchable.disabled
|
||||||
layerMisc.removePopulationIcon()
|
|
||||||
|
|
||||||
val city = tile.getCity()
|
|
||||||
val tileIsViewable = isViewable(viewingCiv!!)
|
|
||||||
|
|
||||||
// Show population icon overlay (if option is enabled)
|
|
||||||
if (tileIsViewable && tile.isWorked() && UncivGame.Current.settings.showWorkedTiles
|
|
||||||
&& city!!.civ == viewingCiv) {
|
|
||||||
layerMisc.setNewPopulationIcon()
|
|
||||||
}
|
|
||||||
|
|
||||||
super.update(viewingCiv)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun update(viewingCiv: Civilization?) {
|
||||||
|
super.update(viewingCiv)
|
||||||
|
|
||||||
|
updateWorkedIcon(viewingCiv!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateWorkedIcon(viewingCiv: Civilization) {
|
||||||
|
|
||||||
|
layerMisc.removeWorkedIcon()
|
||||||
|
|
||||||
|
val shouldShowWorkedIcon = UncivGame.Current.settings.showWorkedTiles // Overlay enabled;
|
||||||
|
&& isViewable(viewingCiv) // We see tile;
|
||||||
|
&& tile.getCity()?.civ == viewingCiv // Tile belongs to us;
|
||||||
|
&& tile.isWorked() // Tile is worked;
|
||||||
|
|
||||||
|
if (!shouldShowWorkedIcon)
|
||||||
|
return
|
||||||
|
|
||||||
|
val icon = when {
|
||||||
|
tile.isLocked() -> ImageGetter.getImage("TileIcons/Locked").apply { color = Color.WHITE.darken(0.5f) }
|
||||||
|
tile.isWorked() && tile.providesYield() -> ImageGetter.getImage("TileIcons/Worked").apply { color = Color.WHITE.darken(0.5f) }
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (icon != null) {
|
||||||
|
icon.setSize(20f, 20f)
|
||||||
|
icon.center(this)
|
||||||
|
icon.x += 20f
|
||||||
|
layerMisc.addWorkedIcon(icon)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun clone(): WorldTileGroup = WorldTileGroup(worldScreen, tile , tileSetStrings)
|
override fun clone(): WorldTileGroup = WorldTileGroup(worldScreen, tile , tileSetStrings)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.unciv.ui.tilegroups.layers
|
package com.unciv.ui.tilegroups.layers
|
||||||
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.Group
|
import com.badlogic.gdx.scenes.scene2d.Group
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.Touchable
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Image
|
import com.badlogic.gdx.scenes.scene2d.ui.Image
|
||||||
import com.unciv.logic.civilization.Civilization
|
import com.unciv.logic.civilization.Civilization
|
||||||
import com.unciv.logic.map.tile.Tile
|
import com.unciv.logic.map.tile.Tile
|
||||||
@ -11,6 +12,7 @@ import com.unciv.ui.tilegroups.TileSetStrings
|
|||||||
abstract class TileLayer(val tileGroup: TileGroup, size: Float) : Group() {
|
abstract class TileLayer(val tileGroup: TileGroup, size: Float) : Group() {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
touchable = Touchable.disabled
|
||||||
isTransform = false
|
isTransform = false
|
||||||
@Suppress("LeakingThis")
|
@Suppress("LeakingThis")
|
||||||
setSize(size, size)
|
setSize(size, size)
|
||||||
|
@ -13,14 +13,13 @@ import com.unciv.models.helpers.MapArrowType
|
|||||||
import com.unciv.models.helpers.MiscArrowTypes
|
import com.unciv.models.helpers.MiscArrowTypes
|
||||||
import com.unciv.models.helpers.TintedMapArrow
|
import com.unciv.models.helpers.TintedMapArrow
|
||||||
import com.unciv.models.helpers.UnitMovementMemoryType
|
import com.unciv.models.helpers.UnitMovementMemoryType
|
||||||
import com.unciv.ui.tilegroups.YieldGroup
|
|
||||||
import com.unciv.ui.images.ImageGetter
|
import com.unciv.ui.images.ImageGetter
|
||||||
import com.unciv.ui.tilegroups.TileGroup
|
import com.unciv.ui.tilegroups.TileGroup
|
||||||
import com.unciv.ui.tilegroups.TileSetStrings
|
import com.unciv.ui.tilegroups.TileSetStrings
|
||||||
import com.unciv.ui.tilegroups.WorldTileGroup
|
import com.unciv.ui.tilegroups.WorldTileGroup
|
||||||
|
import com.unciv.ui.tilegroups.YieldGroup
|
||||||
import com.unciv.ui.utils.extensions.center
|
import com.unciv.ui.utils.extensions.center
|
||||||
import com.unciv.ui.utils.extensions.centerX
|
import com.unciv.ui.utils.extensions.centerX
|
||||||
import com.unciv.ui.utils.extensions.darken
|
|
||||||
import com.unciv.ui.utils.extensions.toLabel
|
import com.unciv.ui.utils.extensions.toLabel
|
||||||
import kotlin.math.atan2
|
import kotlin.math.atan2
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
@ -44,7 +43,15 @@ private class MapArrow(val targetTile: Tile, val arrowType: MapArrowType, val st
|
|||||||
class TileLayerMisc(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, size) {
|
class TileLayerMisc(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, size) {
|
||||||
|
|
||||||
override fun act(delta: Float) {}
|
override fun act(delta: Float) {}
|
||||||
override fun hit(x: Float, y: Float, touchable: Boolean): Actor? = null
|
override fun hit(x: Float, y: Float, touchable: Boolean): Actor? {
|
||||||
|
return if (workedIcon == null) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
val coords = Vector2(x, y)
|
||||||
|
workedIcon!!.parentToLocalCoordinates(coords)
|
||||||
|
workedIcon!!.hit(coords.x, coords.y, touchable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private var yieldsInitialized = false
|
private var yieldsInitialized = false
|
||||||
private var yields = YieldGroup().apply { isVisible = false }
|
private var yields = YieldGroup().apply { isVisible = false }
|
||||||
@ -53,10 +60,10 @@ class TileLayerMisc(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, si
|
|||||||
private val arrowsToDraw = ArrayList<MapArrow>()
|
private val arrowsToDraw = ArrayList<MapArrow>()
|
||||||
private val arrows = HashMap<Tile, ArrayList<Actor>>()
|
private val arrows = HashMap<Tile, ArrayList<Actor>>()
|
||||||
|
|
||||||
|
private var resourceName: String? = null
|
||||||
|
private var resourceIcon: Actor? = null
|
||||||
|
private var workedIcon: Actor? = null
|
||||||
var improvementIcon: Actor? = null
|
var improvementIcon: Actor? = null
|
||||||
var populationIcon: Image? = null
|
|
||||||
var resourceIcon: Actor? = null
|
|
||||||
var resourceName: String? = null
|
|
||||||
|
|
||||||
private val startingLocationIcons = mutableListOf<Actor>()
|
private val startingLocationIcons = mutableListOf<Actor>()
|
||||||
|
|
||||||
@ -233,36 +240,16 @@ class TileLayerMisc(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, si
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updatePopulationIcon() {
|
fun removeWorkedIcon() {
|
||||||
val icon = populationIcon
|
workedIcon?.remove()
|
||||||
if (icon != null) {
|
workedIcon = null
|
||||||
icon.setSize(25f, 25f)
|
determineVisibility()
|
||||||
icon.setPosition(width / 2 - icon.width / 2,
|
|
||||||
height * 0.85f - icon.height / 2)
|
|
||||||
icon.color = when {
|
|
||||||
tile().isCityCenter() -> Color.GOLD.cpy()
|
|
||||||
tile().providesYield() -> Color.WHITE.cpy()
|
|
||||||
else -> Color.GRAY.cpy()
|
|
||||||
}
|
|
||||||
icon.toFront()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setNewPopulationIcon(icon: Image = ImageGetter.getStatIcon("Population")
|
fun addWorkedIcon(icon: Actor) {
|
||||||
.apply { color = Color.GREEN.darken(0.5f) }) {
|
workedIcon = icon
|
||||||
populationIcon?.remove()
|
addActor(workedIcon)
|
||||||
populationIcon = icon
|
determineVisibility()
|
||||||
populationIcon!!.run {
|
|
||||||
setSize(20f, 20f)
|
|
||||||
center(tileGroup)
|
|
||||||
x += 20 // right
|
|
||||||
}
|
|
||||||
addActor(populationIcon)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun removePopulationIcon() {
|
|
||||||
populationIcon?.remove()
|
|
||||||
populationIcon = null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -278,7 +265,7 @@ class TileLayerMisc(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, si
|
|||||||
fun dimImprovement(dim: Boolean) { improvementIcon?.color?.a = if (dim) 0.5f else 1f }
|
fun dimImprovement(dim: Boolean) { improvementIcon?.color?.a = if (dim) 0.5f else 1f }
|
||||||
fun dimResource(dim: Boolean) { resourceIcon?.color?.a = if (dim) 0.5f else 1f }
|
fun dimResource(dim: Boolean) { resourceIcon?.color?.a = if (dim) 0.5f else 1f }
|
||||||
fun dimYields(dim: Boolean) { yields.color.a = if (dim) 0.5f else 1f }
|
fun dimYields(dim: Boolean) { yields.color.a = if (dim) 0.5f else 1f }
|
||||||
fun dimPopulation(dim: Boolean) { populationIcon?.color?.a = if (dim) 0.4f else 1f }
|
fun dimPopulation(dim: Boolean) { workedIcon?.color?.a = if (dim) 0.4f else 1f }
|
||||||
|
|
||||||
fun setYieldVisible(isVisible: Boolean) {
|
fun setYieldVisible(isVisible: Boolean) {
|
||||||
yields.isVisible = isVisible
|
yields.isVisible = isVisible
|
||||||
@ -305,7 +292,7 @@ class TileLayerMisc(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, si
|
|||||||
isVisible = yields.isVisible
|
isVisible = yields.isVisible
|
||||||
|| resourceIcon?.isVisible == true
|
|| resourceIcon?.isVisible == true
|
||||||
|| improvementIcon != null
|
|| improvementIcon != null
|
||||||
|| populationIcon != null
|
|| workedIcon != null
|
||||||
|| arrows.isNotEmpty()
|
|| arrows.isNotEmpty()
|
||||||
|| startingLocationIcons.isNotEmpty()
|
|| startingLocationIcons.isNotEmpty()
|
||||||
}
|
}
|
||||||
|
@ -294,6 +294,8 @@ open class ZoomableScrollPane(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun panStop(event: InputEvent?, x: Float, y: Float, pointer: Int, button: Int) {
|
override fun panStop(event: InputEvent?, x: Float, y: Float, pointer: Int, button: Int) {
|
||||||
|
if (zoomListener.isZooming)
|
||||||
|
zoomListener.isZooming = false
|
||||||
isPanning = false
|
isPanning = false
|
||||||
onPanStopListener?.invoke()
|
onPanStopListener?.invoke()
|
||||||
}
|
}
|
||||||
|