mirror of
https://github.com/yairm210/Unciv.git
synced 2025-03-12 02:50:41 +07:00
Spectator can view other civ stats: Tech, Trades, Cities, Units, Gold (#2877)
* Select units/cities in spectator mode * Can enter EmpireOverviewScreen in spectator mode * keep selectedCiv after nextTurn * Add current civilization Label and Icon * Clickable Civilization label * Victory screen and next turn update
This commit is contained in:
parent
b5a4591955
commit
0f70726c10
@ -8,6 +8,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Label
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.HexMath
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
|
||||
@ -21,7 +22,7 @@ import java.text.DecimalFormat
|
||||
import kotlin.math.*
|
||||
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
|
||||
|
||||
class EmpireOverviewScreen(private val viewingPlayer:CivilizationInfo, defaultPage: String = "Cities") : CameraStageBaseScreen(){
|
||||
class EmpireOverviewScreen(private var viewingPlayer:CivilizationInfo, defaultPage: String = "Cities") : CameraStageBaseScreen(){
|
||||
private val topTable = Table().apply { defaults().pad(10f) }
|
||||
private val centerTable = Table().apply { defaults().pad(20f) }
|
||||
|
||||
|
@ -42,7 +42,7 @@ class PolicyPickerScreen(val worldScreen: WorldScreen, civInfo: CivilizationInfo
|
||||
}
|
||||
else game.setScreen(PolicyPickerScreen(worldScreen)) // update policies
|
||||
}
|
||||
if(!UncivGame.Current.worldScreen.isPlayersTurn)
|
||||
if(!UncivGame.Current.worldScreen.canChangeState)
|
||||
rightSideButton.disable()
|
||||
|
||||
|
||||
|
@ -36,7 +36,8 @@ class PromotionPickerScreen(val unit: MapUnit) : PickerScreen() {
|
||||
acceptPromotion(selectedPromotion)
|
||||
}
|
||||
val canBePromoted = unit.promotions.canBePromoted()
|
||||
if(!canBePromoted)
|
||||
val canChangeState = game.worldScreen.canChangeState
|
||||
if(!canBePromoted || !canChangeState)
|
||||
rightSideButton.disable()
|
||||
|
||||
val availablePromotionsGroup = Table()
|
||||
@ -60,7 +61,7 @@ class PromotionPickerScreen(val unit: MapUnit) : PickerScreen() {
|
||||
selectPromotionButton.onClick {
|
||||
selectedPromotion = promotion
|
||||
rightSideButton.setText(promotion.name.tr())
|
||||
if(canBePromoted && isPromotionAvailable && !unitHasPromotion)
|
||||
if(canBePromoted && isPromotionAvailable && !unitHasPromotion && canChangeState)
|
||||
rightSideButton.enable()
|
||||
else rightSideButton.disable()
|
||||
|
||||
@ -70,7 +71,7 @@ class PromotionPickerScreen(val unit: MapUnit) : PickerScreen() {
|
||||
|
||||
availablePromotionsGroup.add(selectPromotionButton)
|
||||
|
||||
if(canBePromoted && isPromotionAvailable) {
|
||||
if(canBePromoted && isPromotionAvailable && canChangeState) {
|
||||
val pickNow = "Pick now!".toLabel()
|
||||
pickNow.setAlignment(Align.center)
|
||||
pickNow.onClick {
|
||||
|
@ -61,7 +61,6 @@ class TechPickerScreen(internal val civInfo: CivilizationInfo, centerOnTech: Tec
|
||||
dispose()
|
||||
}
|
||||
|
||||
|
||||
// per default show current/recent technology,
|
||||
// and possibly select it to show description,
|
||||
// which is very helpful when just discovered and clicking the notification
|
||||
@ -212,6 +211,13 @@ class TechPickerScreen(internal val civInfo: CivilizationInfo, centerOnTech: Tec
|
||||
return
|
||||
}
|
||||
|
||||
if (!UncivGame.Current.worldScreen.canChangeState) {
|
||||
rightSideButton.disable()
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
|
||||
tempTechsToResearch.clear()
|
||||
tempTechsToResearch.addAll(civTech.getRequiredTechsToDestination(tech))
|
||||
|
||||
|
@ -32,7 +32,7 @@ class VictoryScreen(val worldScreen: WorldScreen) : PickerScreen() {
|
||||
|
||||
val tabsTable = Table().apply { defaults().pad(10f) }
|
||||
val setMyVictoryButton = "Our status".toTextButton().onClick { setMyVictoryTable() }
|
||||
tabsTable.add(setMyVictoryButton)
|
||||
if (!playerCivInfo.isSpectator()) tabsTable.add(setMyVictoryButton)
|
||||
val setGlobalVictoryButton = "Global status".toTextButton().onClick { setGlobalVictoryTable() }
|
||||
tabsTable.add(setGlobalVictoryButton)
|
||||
val setCivRankingsButton = "Rankings".toTextButton().onClick { setCivRankingsTable() }
|
||||
@ -41,7 +41,10 @@ class VictoryScreen(val worldScreen: WorldScreen) : PickerScreen() {
|
||||
topTable.addSeparator()
|
||||
topTable.add(contentsTable)
|
||||
|
||||
setMyVictoryTable()
|
||||
if (playerCivInfo.isSpectator())
|
||||
setGlobalVictoryTable()
|
||||
else
|
||||
setMyVictoryTable()
|
||||
|
||||
rightSideButton.isVisible=false
|
||||
|
||||
|
@ -126,13 +126,15 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap
|
||||
|
||||
private fun addTileOverlays(tileInfo: TileInfo, moveHereDto:MoveHereButtonDto?=null){
|
||||
val table = Table().apply { defaults().pad(10f) }
|
||||
if(moveHereDto!=null)
|
||||
if(moveHereDto!=null && worldScreen.canChangeState)
|
||||
table.add(getMoveHereButton(moveHereDto))
|
||||
|
||||
val unitList = ArrayList<MapUnit>()
|
||||
if (tileInfo.isCityCenter() && tileInfo.getOwner()==worldScreen.viewingCiv) {
|
||||
if (tileInfo.isCityCenter()
|
||||
&& (tileInfo.getOwner()==worldScreen.viewingCiv || worldScreen.viewingCiv.isSpectator())) {
|
||||
unitList.addAll(tileInfo.getCity()!!.getCenterTile().getUnits())
|
||||
} else if (tileInfo.airUnits.isNotEmpty() && tileInfo.airUnits.first().civInfo==worldScreen.viewingCiv) {
|
||||
} else if (tileInfo.airUnits.isNotEmpty()
|
||||
&& (tileInfo.airUnits.first().civInfo==worldScreen.viewingCiv || worldScreen.viewingCiv.isSpectator())) {
|
||||
unitList.addAll(tileInfo.getUnits())
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,7 @@ import kotlin.concurrent.thread
|
||||
class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
||||
val gameInfo = game.gameInfo
|
||||
var isPlayersTurn = viewingCiv == gameInfo.currentPlayerCiv // todo this should be updated when passing turns
|
||||
var selectedCiv = viewingCiv // Selected civilization, used only in spectator mode
|
||||
val canChangeState = isPlayersTurn && !viewingCiv.isSpectator()
|
||||
private var waitingForAutosave = false
|
||||
|
||||
@ -63,6 +64,7 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
||||
private val notificationsScroll: NotificationsScroll
|
||||
var shouldUpdate = false
|
||||
|
||||
|
||||
private var backButtonListener : InputListener
|
||||
|
||||
// An initialized val always turned out to illegally be null...
|
||||
@ -122,7 +124,12 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
||||
viewingCiv.getCivUnits().any() -> viewingCiv.getCivUnits().first().getTile().position
|
||||
else -> Vector2.Zero
|
||||
}
|
||||
mapHolder.setCenterPosition(tileToCenterOn,true)
|
||||
|
||||
// Don't select unit and change selectedCiv when centering as spectator
|
||||
if (viewingCiv.isSpectator())
|
||||
mapHolder.setCenterPosition(tileToCenterOn,true, false)
|
||||
else
|
||||
mapHolder.setCenterPosition(tileToCenterOn,true, true)
|
||||
|
||||
|
||||
if(gameInfo.gameParameters.isOnlineMultiplayer && !gameInfo.isUpToDate)
|
||||
@ -275,6 +282,8 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
||||
bottomTileInfoTable.y = if (game.settings.showMinimap) minimapWrapper.height else 0f
|
||||
battleTable.update()
|
||||
|
||||
updateSelectedCiv()
|
||||
|
||||
tutorialTaskTable.clear()
|
||||
val tutorialTask = getCurrentTutorialTask()
|
||||
if (tutorialTask == "" || !game.settings.showTutorials || viewingCiv.isDefeated()) {
|
||||
@ -298,7 +307,10 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
||||
// it causes a bug when we move a unit to an unexplored tile (for instance a cavalry unit which can move far)
|
||||
mapHolder.updateTiles(viewingCiv)
|
||||
|
||||
topBar.update(viewingCiv)
|
||||
if (viewingCiv.isSpectator())
|
||||
topBar.update(selectedCiv)
|
||||
else
|
||||
topBar.update(viewingCiv)
|
||||
|
||||
updateTechButton()
|
||||
techPolicyAndVictoryHolder.pack()
|
||||
@ -440,6 +452,14 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
||||
techButtonHolder.pack() //setSize(techButtonHolder.prefWidth, techButtonHolder.prefHeight)
|
||||
}
|
||||
|
||||
private fun updateSelectedCiv() {
|
||||
if (bottomUnitTable.selectedUnit != null)
|
||||
selectedCiv = bottomUnitTable.selectedUnit!!.civInfo
|
||||
else if (bottomUnitTable.selectedCity != null)
|
||||
selectedCiv = bottomUnitTable.selectedCity!!.civInfo
|
||||
else viewingCiv
|
||||
}
|
||||
|
||||
private fun createNextTurnButton(): TextButton {
|
||||
|
||||
val nextTurnButton = TextButton("", skin) // text is set in update()
|
||||
@ -500,6 +520,7 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
||||
newWorldScreen.mapHolder.scaleX = mapHolder.scaleX
|
||||
newWorldScreen.mapHolder.scaleY = mapHolder.scaleY
|
||||
newWorldScreen.mapHolder.updateVisualScroll()
|
||||
newWorldScreen.selectedCiv = gameInfoClone.getCivilization(selectedCiv.civName)
|
||||
game.worldScreen = newWorldScreen
|
||||
game.setWorldScreen()
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import com.badlogic.gdx.scenes.scene2d.Group
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Image
|
||||
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.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.models.metadata.GameSpeed
|
||||
import com.unciv.models.ruleset.tile.ResourceType
|
||||
@ -23,6 +24,8 @@ import kotlin.math.roundToInt
|
||||
|
||||
class WorldScreenTopBar(val worldScreen: WorldScreen) : Table() {
|
||||
|
||||
private var selectedCivTable = Table()
|
||||
|
||||
private val turnsLabel = "Turns: 0/400".toLabel()
|
||||
private val goldLabel = "Gold:".toLabel(colorFromRGB(225, 217, 71))
|
||||
private val scienceLabel = "Science:".toLabel(colorFromRGB(78, 140, 151))
|
||||
@ -48,13 +51,9 @@ class WorldScreenTopBar(val worldScreen: WorldScreen) : Table() {
|
||||
pack()
|
||||
addActor(getMenuButton()) // needs to be after pack
|
||||
|
||||
val overviewButton = "Overview".toTextButton()
|
||||
overviewButton.labelCell.pad(10f)
|
||||
overviewButton.pack()
|
||||
overviewButton.onClick { worldScreen.game.setScreen(EmpireOverviewScreen(worldScreen.viewingCiv)) }
|
||||
overviewButton.center(this)
|
||||
overviewButton.x = worldScreen.stage.width - overviewButton.width - 10
|
||||
addActor(overviewButton)
|
||||
addSelectedCivilizationTable()
|
||||
|
||||
addActor(getOverviewButton())
|
||||
}
|
||||
|
||||
private fun getResourceTable(): Table {
|
||||
@ -70,7 +69,9 @@ class WorldScreenTopBar(val worldScreen: WorldScreen) : Table() {
|
||||
val resourceLabel = "0".toLabel()
|
||||
resourceLabels[resource.name] = resourceLabel
|
||||
resourceTable.add(resourceLabel)
|
||||
val invokeResourcesPage = { worldScreen.game.setScreen(EmpireOverviewScreen(worldScreen.viewingCiv, "Resources")) }
|
||||
val invokeResourcesPage = {
|
||||
worldScreen.game.setScreen(EmpireOverviewScreen(worldScreen.selectedCiv, "Resources"))
|
||||
}
|
||||
resourceLabel.onClick(invokeResourcesPage)
|
||||
resourceImage.onClick(invokeResourcesPage)
|
||||
}
|
||||
@ -86,27 +87,35 @@ class WorldScreenTopBar(val worldScreen: WorldScreen) : Table() {
|
||||
statsTable.add(goldLabel)
|
||||
val goldImage = ImageGetter.getStatIcon("Gold")
|
||||
statsTable.add(goldImage).padRight(20f).size(20f)
|
||||
val invokeStatsPage = { worldScreen.game.setScreen(EmpireOverviewScreen(worldScreen.viewingCiv, "Stats")) }
|
||||
val invokeStatsPage = {
|
||||
worldScreen.game.setScreen(EmpireOverviewScreen(worldScreen.selectedCiv, "Stats"))
|
||||
}
|
||||
goldLabel.onClick(invokeStatsPage)
|
||||
goldImage.onClick(invokeStatsPage)
|
||||
|
||||
statsTable.add(scienceLabel) //.apply { setAlignment(Align.center) }).align(Align.top)
|
||||
val scienceImage = ImageGetter.getStatIcon("Science")
|
||||
statsTable.add(scienceImage).padRight(20f).size(20f)
|
||||
val invokeTechScreen = { worldScreen.game.setScreen(TechPickerScreen(worldScreen.viewingCiv)) }
|
||||
val invokeTechScreen = {
|
||||
worldScreen.game.setScreen(TechPickerScreen(worldScreen.selectedCiv))
|
||||
}
|
||||
scienceLabel.onClick(invokeTechScreen)
|
||||
scienceImage.onClick(invokeTechScreen)
|
||||
|
||||
statsTable.add(happinessImage).size(20f)
|
||||
statsTable.add(happinessLabel).padRight(20f)//.apply { setAlignment(Align.center) }).align(Align.top)
|
||||
val invokeResourcesPage = { worldScreen.game.setScreen(EmpireOverviewScreen(worldScreen.viewingCiv, "Resources")) }
|
||||
val invokeResourcesPage = {
|
||||
worldScreen.game.setScreen(EmpireOverviewScreen(worldScreen.selectedCiv, "Resources"))
|
||||
}
|
||||
happinessImage.onClick(invokeResourcesPage)
|
||||
happinessLabel.onClick(invokeResourcesPage)
|
||||
|
||||
statsTable.add(cultureLabel)//.apply { setAlignment(Align.center) }).align(Align.top)
|
||||
val cultureImage = ImageGetter.getStatIcon("Culture")
|
||||
statsTable.add(cultureImage).size(20f)
|
||||
val invokePoliciesPage = { worldScreen.game.setScreen(PolicyPickerScreen(worldScreen)) }
|
||||
val invokePoliciesPage = {
|
||||
worldScreen.game.setScreen(PolicyPickerScreen(worldScreen, worldScreen.selectedCiv))
|
||||
}
|
||||
cultureLabel.onClick(invokePoliciesPage)
|
||||
cultureImage.onClick(invokePoliciesPage)
|
||||
|
||||
@ -130,6 +139,23 @@ class WorldScreenTopBar(val worldScreen: WorldScreen) : Table() {
|
||||
return menuButton
|
||||
}
|
||||
|
||||
private fun getOverviewButton(): TextButton {
|
||||
val overviewButton = "Overview".toTextButton()
|
||||
overviewButton.labelCell.pad(10f)
|
||||
overviewButton.pack()
|
||||
overviewButton.onClick { worldScreen.game.setScreen(EmpireOverviewScreen(worldScreen.selectedCiv)) }
|
||||
overviewButton.center(this)
|
||||
overviewButton.x = worldScreen.stage.width - overviewButton.width - 10
|
||||
return overviewButton
|
||||
}
|
||||
|
||||
private fun addSelectedCivilizationTable() {
|
||||
selectedCivTable.centerY(this)
|
||||
selectedCivTable.left()
|
||||
selectedCivTable.x = getMenuButton().width + 20f
|
||||
updateSelectedCivTabel()
|
||||
addActor(selectedCivTable)
|
||||
}
|
||||
|
||||
internal fun update(civInfo: CivilizationInfo) {
|
||||
val revealedStrategicResources = civInfo.gameInfo.ruleSet.tileResources.values
|
||||
@ -168,6 +194,22 @@ class WorldScreenTopBar(val worldScreen: WorldScreen) : Table() {
|
||||
}
|
||||
|
||||
cultureLabel.setText(getCultureText(civInfo, nextTurnStats))
|
||||
|
||||
updateSelectedCivTabel()
|
||||
}
|
||||
|
||||
private fun updateSelectedCivTabel() {
|
||||
selectedCivTable.clear()
|
||||
|
||||
val selectedCivLabel = worldScreen.selectedCiv.civName.toLabel()
|
||||
selectedCivLabel.setFontSize(25)
|
||||
selectedCivLabel.onClick { worldScreen.game.setScreen(EmpireOverviewScreen(worldScreen.selectedCiv)) }
|
||||
selectedCivTable.add(selectedCivLabel).padRight(10f)
|
||||
|
||||
val nation = worldScreen.gameInfo.ruleSet.nations[worldScreen.selectedCiv.civName]!!
|
||||
selectedCivTable.add(ImageGetter.getNationIndicator(nation, 35f).onClick {
|
||||
worldScreen.game.setScreen(EmpireOverviewScreen(worldScreen.selectedCiv))
|
||||
})
|
||||
}
|
||||
|
||||
private fun getCultureText(civInfo: CivilizationInfo, nextTurnStats: Stats): String {
|
||||
|
@ -42,7 +42,7 @@ class BattleTable(val worldScreen: WorldScreen): Table() {
|
||||
isVisible = true
|
||||
|
||||
val attacker = tryGetAttacker()
|
||||
if(attacker==null){ hide(); return }
|
||||
if(attacker==null || !worldScreen.canChangeState){ hide(); return }
|
||||
|
||||
if (attacker.getUnitType()==UnitType.Missile) {
|
||||
val selectedTile = worldScreen.mapHolder.selectedTile
|
||||
|
@ -62,7 +62,7 @@ class UnitActionsTable(val worldScreen: WorldScreen) : Table() {
|
||||
fun update(unit: MapUnit?) {
|
||||
clear()
|
||||
if (unit == null) return
|
||||
if (!worldScreen.isPlayersTurn) return // No actions when it's not your turn!
|
||||
if (!worldScreen.canChangeState) return // No actions when it's not your turn or spectator!
|
||||
for (button in UnitActions.getUnitActions(unit, worldScreen).map { getUnitActionButton(it) })
|
||||
add(button).left().padBottom(2f).row()
|
||||
pack()
|
||||
|
@ -74,7 +74,7 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){
|
||||
fun update() {
|
||||
if(selectedUnit!=null) {
|
||||
isVisible=true
|
||||
if (selectedUnit!!.civInfo != worldScreen.viewingCiv) { // The unit that was selected, was captured. It exists but is no longer ours.
|
||||
if (selectedUnit!!.civInfo != worldScreen.viewingCiv && !worldScreen.viewingCiv.isSpectator()) { // The unit that was selected, was captured. It exists but is no longer ours.
|
||||
selectedUnit = null
|
||||
selectedCity = null
|
||||
selectedUnitHasChanged = true
|
||||
@ -194,17 +194,21 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){
|
||||
fun tileSelected(selectedTile: TileInfo) {
|
||||
|
||||
val previouslySelectedUnit = selectedUnit
|
||||
if(selectedTile.isCityCenter() && selectedTile.getOwner()==worldScreen.viewingCiv){
|
||||
|
||||
if(selectedTile.isCityCenter()
|
||||
&& (selectedTile.getOwner()==worldScreen.viewingCiv || worldScreen.viewingCiv.isSpectator())){
|
||||
citySelected(selectedTile.getCity()!!)
|
||||
}
|
||||
else if(selectedTile.militaryUnit!=null && selectedTile.militaryUnit!!.civInfo == worldScreen.viewingCiv
|
||||
else if(selectedTile.militaryUnit!=null
|
||||
&& (selectedTile.militaryUnit!!.civInfo == worldScreen.viewingCiv || worldScreen.viewingCiv.isSpectator())
|
||||
&& selectedUnit!=selectedTile.militaryUnit
|
||||
&& (selectedTile.civilianUnit==null || selectedUnit!=selectedTile.civilianUnit)){
|
||||
selectedUnit = selectedTile.militaryUnit
|
||||
selectedCity = null
|
||||
}
|
||||
else if (selectedTile.civilianUnit!=null && selectedTile.civilianUnit!!.civInfo == worldScreen.viewingCiv
|
||||
&& selectedUnit!=selectedTile.civilianUnit){
|
||||
else if (selectedTile.civilianUnit!=null
|
||||
&& (selectedTile.civilianUnit!!.civInfo == worldScreen.viewingCiv || worldScreen.viewingCiv.isSpectator())
|
||||
&& selectedUnit!=selectedTile.civilianUnit){
|
||||
selectedUnit = selectedTile.civilianUnit
|
||||
selectedCity = null
|
||||
} else if(selectedTile == previouslySelectedUnit?.currentTile) {
|
||||
|
Loading…
Reference in New Issue
Block a user