mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-27 05:46:43 -04:00
Spectators can enter and view other player cities (#2856)
* Spectators can enter and view other player cities * Spectators not shown on diplomacy screen * master merge fix * Spectators can enter and view other player cities * Spectators not shown on diplomacy screen * Fix barbarians spawn in spectator mode * small post fixes * remove excessive spectator check * Remove spectators from diplomacy screen * Spectators cannot reallocate specialists in cities * Refactor using canChangeState value for CityScreen and WorldScreen. * Continue refactor using canChangeState value
This commit is contained in:
parent
bd422fdb16
commit
00983dd00e
@ -182,7 +182,7 @@ class GameInfo {
|
|||||||
|
|
||||||
fun placeBarbarianEncampment(existingEncampments: List<TileInfo>): TileInfo? {
|
fun placeBarbarianEncampment(existingEncampments: List<TileInfo>): TileInfo? {
|
||||||
// Barbarians will only spawn in places that no one can see
|
// Barbarians will only spawn in places that no one can see
|
||||||
val allViewableTiles = civilizations.filterNot { it.isBarbarian() }
|
val allViewableTiles = civilizations.filterNot { it.isBarbarian() || it.isSpectator() }
|
||||||
.flatMap { it.viewableTiles }.toHashSet()
|
.flatMap { it.viewableTiles }.toHashSet()
|
||||||
val tilesWithin3ofExistingEncampment = existingEncampments.asSequence()
|
val tilesWithin3ofExistingEncampment = existingEncampments.asSequence()
|
||||||
.flatMap { it.getTilesInDistance(3) }.toSet()
|
.flatMap { it.getTilesInDistance(3) }.toSet()
|
||||||
|
@ -22,6 +22,9 @@ class CityScreen(internal val city: CityInfo): CameraStageBaseScreen() {
|
|||||||
var selectedConstruction: IConstruction? = null
|
var selectedConstruction: IConstruction? = null
|
||||||
var keyListener: InputListener? = null
|
var keyListener: InputListener? = null
|
||||||
|
|
||||||
|
/** Toggles or adds/removes all state changing buttons */
|
||||||
|
val canChangeState = UncivGame.Current.worldScreen.canChangeState
|
||||||
|
|
||||||
/** Toggle between Constructions and cityInfo (buildings, specialists etc. */
|
/** Toggle between Constructions and cityInfo (buildings, specialists etc. */
|
||||||
var showConstructionsTable = true
|
var showConstructionsTable = true
|
||||||
|
|
||||||
@ -134,12 +137,13 @@ class CityScreen(internal val city: CityInfo): CameraStageBaseScreen() {
|
|||||||
city.annexCity()
|
city.annexCity()
|
||||||
update()
|
update()
|
||||||
}
|
}
|
||||||
|
if (!canChangeState) annexCityButton.disable()
|
||||||
razeCityButtonHolder.add(annexCityButton).colspan(cityPickerTable.columns)
|
razeCityButtonHolder.add(annexCityButton).colspan(cityPickerTable.columns)
|
||||||
} else if(!city.isBeingRazed) {
|
} else if(!city.isBeingRazed) {
|
||||||
val razeCityButton = "Raze city".toTextButton()
|
val razeCityButton = "Raze city".toTextButton()
|
||||||
razeCityButton.labelCell.pad(10f)
|
razeCityButton.labelCell.pad(10f)
|
||||||
razeCityButton.onClick { city.isBeingRazed=true; update() }
|
razeCityButton.onClick { city.isBeingRazed=true; update() }
|
||||||
if(!UncivGame.Current.worldScreen.isPlayersTurn || city.isOriginalCapital)
|
if(!canChangeState || city.isOriginalCapital)
|
||||||
razeCityButton.disable()
|
razeCityButton.disable()
|
||||||
|
|
||||||
razeCityButtonHolder.add(razeCityButton).colspan(cityPickerTable.columns)
|
razeCityButtonHolder.add(razeCityButton).colspan(cityPickerTable.columns)
|
||||||
@ -147,7 +151,7 @@ class CityScreen(internal val city: CityInfo): CameraStageBaseScreen() {
|
|||||||
val stopRazingCityButton = "Stop razing city".toTextButton()
|
val stopRazingCityButton = "Stop razing city".toTextButton()
|
||||||
stopRazingCityButton.labelCell.pad(10f)
|
stopRazingCityButton.labelCell.pad(10f)
|
||||||
stopRazingCityButton.onClick { city.isBeingRazed=false; update() }
|
stopRazingCityButton.onClick { city.isBeingRazed=false; update() }
|
||||||
if(!UncivGame.Current.worldScreen.isPlayersTurn) stopRazingCityButton.disable()
|
if(!canChangeState) stopRazingCityButton.disable()
|
||||||
razeCityButtonHolder.add(stopRazingCityButton).colspan(cityPickerTable.columns)
|
razeCityButtonHolder.add(stopRazingCityButton).colspan(cityPickerTable.columns)
|
||||||
}
|
}
|
||||||
razeCityButtonHolder.pack()
|
razeCityButtonHolder.pack()
|
||||||
@ -173,7 +177,7 @@ class CityScreen(internal val city: CityInfo): CameraStageBaseScreen() {
|
|||||||
|
|
||||||
selectedTile = tileInfo
|
selectedTile = tileInfo
|
||||||
selectedConstruction = null
|
selectedConstruction = null
|
||||||
if (tileGroup.isWorkable && UncivGame.Current.worldScreen.isPlayersTurn) {
|
if (tileGroup.isWorkable && canChangeState) {
|
||||||
if (!tileInfo.isWorked() && city.population.getFreePopulation() > 0) {
|
if (!tileInfo.isWorked() && city.population.getFreePopulation() > 0) {
|
||||||
city.workedTiles.add(tileInfo.position)
|
city.workedTiles.add(tileInfo.position)
|
||||||
game.settings.addCompletedTutorialTask("Reassign worked tiles")
|
game.settings.addCompletedTutorialTask("Reassign worked tiles")
|
||||||
|
@ -34,7 +34,6 @@ class CityScreenTileTable(val cityScreen: CityScreen): Table(){
|
|||||||
innerTable.row()
|
innerTable.row()
|
||||||
innerTable.add(getTileStatsTable(stats)).row()
|
innerTable.add(getTileStatsTable(stats)).row()
|
||||||
|
|
||||||
|
|
||||||
if(selectedTile.getOwner()==null && selectedTile.neighbors.any {it.getCity()==city}
|
if(selectedTile.getOwner()==null && selectedTile.neighbors.any {it.getCity()==city}
|
||||||
&& selectedTile in city.tilesInRange){
|
&& selectedTile in city.tilesInRange){
|
||||||
val goldCostOfTile = city.expansion.getGoldCostOfTile(selectedTile)
|
val goldCostOfTile = city.expansion.getGoldCostOfTile(selectedTile)
|
||||||
@ -44,7 +43,9 @@ class CityScreenTileTable(val cityScreen: CityScreen): Table(){
|
|||||||
city.expansion.buyTile(selectedTile)
|
city.expansion.buyTile(selectedTile)
|
||||||
UncivGame.Current.setScreen(CityScreen(city))
|
UncivGame.Current.setScreen(CityScreen(city))
|
||||||
}
|
}
|
||||||
if(goldCostOfTile>city.civInfo.gold || city.isPuppet || !UncivGame.Current.worldScreen.isPlayersTurn)
|
if(goldCostOfTile>city.civInfo.gold
|
||||||
|
|| city.isPuppet
|
||||||
|
|| !cityScreen.canChangeState)
|
||||||
buyTileButton.disable()
|
buyTileButton.disable()
|
||||||
|
|
||||||
innerTable.add(buyTileButton).row()
|
innerTable.add(buyTileButton).row()
|
||||||
@ -64,6 +65,7 @@ class CityScreenTileTable(val cityScreen: CityScreen): Table(){
|
|||||||
update(selectedTile)
|
update(selectedTile)
|
||||||
cityScreen.update()
|
cityScreen.update()
|
||||||
}
|
}
|
||||||
|
if (!cityScreen.canChangeState) unlockButton.disable()
|
||||||
innerTable.add(unlockButton).row()
|
innerTable.add(unlockButton).row()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -73,6 +75,7 @@ class CityScreenTileTable(val cityScreen: CityScreen): Table(){
|
|||||||
update(selectedTile)
|
update(selectedTile)
|
||||||
cityScreen.update()
|
cityScreen.update()
|
||||||
}
|
}
|
||||||
|
if (!cityScreen.canChangeState) lockButton.disable()
|
||||||
innerTable.add(lockButton).row()
|
innerTable.add(lockButton).row()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -270,7 +270,8 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
|
|||||||
|
|
||||||
if (isSelectedQueueEntry()) {
|
if (isSelectedQueueEntry()) {
|
||||||
button = "Remove from queue".toTextButton()
|
button = "Remove from queue".toTextButton()
|
||||||
if (!UncivGame.Current.worldScreen.isPlayersTurn || city.isPuppet) button.disable()
|
if (!cityScreen.canChangeState || city.isPuppet)
|
||||||
|
button.disable()
|
||||||
else {
|
else {
|
||||||
button.onClick {
|
button.onClick {
|
||||||
cityConstructions.removeFromQueue(selectedQueueEntry,false)
|
cityConstructions.removeFromQueue(selectedQueueEntry,false)
|
||||||
@ -284,7 +285,7 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
|
|||||||
if (construction == null
|
if (construction == null
|
||||||
|| cityConstructions.isQueueFull()
|
|| cityConstructions.isQueueFull()
|
||||||
|| !cityConstructions.getConstruction(construction.name).isBuildable(cityConstructions)
|
|| !cityConstructions.getConstruction(construction.name).isBuildable(cityConstructions)
|
||||||
|| !UncivGame.Current.worldScreen.isPlayersTurn
|
|| !cityScreen.canChangeState
|
||||||
|| construction is PerpetualConstruction && cityConstructions.isBeingConstructedOrEnqueued(construction.name)
|
|| construction is PerpetualConstruction && cityConstructions.isBeingConstructedOrEnqueued(construction.name)
|
||||||
|| city.isPuppet) {
|
|| city.isPuppet) {
|
||||||
button.disable()
|
button.disable()
|
||||||
@ -347,7 +348,7 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( !construction.isBuildable(cityConstructions)
|
if ( !construction.isBuildable(cityConstructions)
|
||||||
|| !UncivGame.Current.worldScreen.isPlayersTurn
|
|| !cityScreen.canChangeState
|
||||||
|| city.isPuppet || city.isInResistance()
|
|| city.isPuppet || city.isInResistance()
|
||||||
|| !city.canPurchase(construction)
|
|| !city.canPurchase(construction)
|
||||||
|| constructionGoldCost > city.civInfo.gold )
|
|| constructionGoldCost > city.civInfo.gold )
|
||||||
@ -362,7 +363,7 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
|
|||||||
private fun getRaisePriorityButton(constructionQueueIndex: Int, name: String, city: CityInfo): Table {
|
private fun getRaisePriorityButton(constructionQueueIndex: Int, name: String, city: CityInfo): Table {
|
||||||
val tab = Table()
|
val tab = Table()
|
||||||
tab.add(ImageGetter.getImage("OtherIcons/Up").surroundWithCircle(40f))
|
tab.add(ImageGetter.getImage("OtherIcons/Up").surroundWithCircle(40f))
|
||||||
if (UncivGame.Current.worldScreen.isPlayersTurn && !city.isPuppet) {
|
if (cityScreen.canChangeState && !city.isPuppet) {
|
||||||
tab.touchable = Touchable.enabled
|
tab.touchable = Touchable.enabled
|
||||||
tab.onClick {
|
tab.onClick {
|
||||||
tab.touchable = Touchable.disabled
|
tab.touchable = Touchable.disabled
|
||||||
@ -379,7 +380,7 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
|
|||||||
private fun getLowerPriorityButton(constructionQueueIndex: Int, name: String, city: CityInfo): Table {
|
private fun getLowerPriorityButton(constructionQueueIndex: Int, name: String, city: CityInfo): Table {
|
||||||
val tab = Table()
|
val tab = Table()
|
||||||
tab.add(ImageGetter.getImage("OtherIcons/Down").surroundWithCircle(40f))
|
tab.add(ImageGetter.getImage("OtherIcons/Down").surroundWithCircle(40f))
|
||||||
if (UncivGame.Current.worldScreen.isPlayersTurn && !city.isPuppet) {
|
if (cityScreen.canChangeState && !city.isPuppet) {
|
||||||
tab.touchable = Touchable.enabled
|
tab.touchable = Touchable.enabled
|
||||||
tab.onClick {
|
tab.onClick {
|
||||||
tab.touchable = Touchable.disabled
|
tab.touchable = Touchable.disabled
|
||||||
@ -396,7 +397,7 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
|
|||||||
private fun getRemoveFromQueueButton(constructionQueueIndex: Int, city: CityInfo): Table {
|
private fun getRemoveFromQueueButton(constructionQueueIndex: Int, city: CityInfo): Table {
|
||||||
val tab = Table()
|
val tab = Table()
|
||||||
tab.add(ImageGetter.getImage("OtherIcons/Stop").surroundWithCircle(40f))
|
tab.add(ImageGetter.getImage("OtherIcons/Stop").surroundWithCircle(40f))
|
||||||
if (UncivGame.Current.worldScreen.isPlayersTurn && !city.isPuppet) {
|
if (cityScreen.canChangeState && !city.isPuppet) {
|
||||||
tab.touchable = Touchable.enabled
|
tab.touchable = Touchable.enabled
|
||||||
tab.onClick {
|
tab.onClick {
|
||||||
tab.touchable = Touchable.disabled
|
tab.touchable = Touchable.disabled
|
||||||
|
@ -22,9 +22,9 @@ class SpecialistAllocationTable(val cityScreen: CityScreen): Table(CameraStageBa
|
|||||||
val assignedSpecialists = cityInfo.population.specialists.get(stat).toInt()
|
val assignedSpecialists = cityInfo.population.specialists.get(stat).toInt()
|
||||||
val maxSpecialists = cityInfo.population.getMaxSpecialists().get(stat).toInt()
|
val maxSpecialists = cityInfo.population.getMaxSpecialists().get(stat).toInt()
|
||||||
|
|
||||||
add(getUnassignButton(assignedSpecialists,stat))
|
if (cityScreen.canChangeState) add(getUnassignButton(assignedSpecialists,stat))
|
||||||
add(getAllocationTable(assignedSpecialists, maxSpecialists, stat)).pad(10f)
|
add(getAllocationTable(assignedSpecialists, maxSpecialists, stat)).pad(10f)
|
||||||
add(getAssignButton(assignedSpecialists,maxSpecialists,stat))
|
if (cityScreen.canChangeState) add(getAssignButton(assignedSpecialists,maxSpecialists,stat))
|
||||||
addSeparatorVertical().pad(10f)
|
addSeparatorVertical().pad(10f)
|
||||||
add(getSpecialistStatsTable(stat)).row()
|
add(getSpecialistStatsTable(stat)).row()
|
||||||
}
|
}
|
||||||
|
@ -308,7 +308,7 @@ class EmpireOverviewScreen(private val viewingPlayer:CivilizationInfo, defaultPa
|
|||||||
viewingPlayer.diplomacy.containsKey(civ.civName)
|
viewingPlayer.diplomacy.containsKey(civ.civName)
|
||||||
|
|
||||||
private fun getDiplomacyGroup(): Group {
|
private fun getDiplomacyGroup(): Group {
|
||||||
val relevantCivs = viewingPlayer.gameInfo.civilizations.filter { !it.isBarbarian() && !it.isCityState() }
|
val relevantCivs = viewingPlayer.gameInfo.civilizations.filter { it.isMajorCiv() }
|
||||||
val freeWidth = stage.width
|
val freeWidth = stage.width
|
||||||
val freeHeight = stage.height - topTable.height
|
val freeHeight = stage.height - topTable.height
|
||||||
val group = Group()
|
val group = Group()
|
||||||
@ -334,8 +334,8 @@ class EmpireOverviewScreen(private val viewingPlayer:CivilizationInfo, defaultPa
|
|||||||
|
|
||||||
for(civ in relevantCivs.filter { playerKnows(it) && !it.isDefeated() })
|
for(civ in relevantCivs.filter { playerKnows(it) && !it.isDefeated() })
|
||||||
for(diplomacy in civ.diplomacy.values.
|
for(diplomacy in civ.diplomacy.values.
|
||||||
filter { !it.otherCiv().isBarbarian() && !it.otherCiv().isCityState()
|
filter { it.otherCiv().isMajorCiv()
|
||||||
&& playerKnows(it.otherCiv()) && !it.otherCiv().isDefeated()}){
|
&& playerKnows(it.otherCiv()) && !it.otherCiv().isDefeated() }){
|
||||||
val civGroup = civGroups[civ.civName]!!
|
val civGroup = civGroups[civ.civName]!!
|
||||||
val otherCivGroup = civGroups[diplomacy.otherCivName]!!
|
val otherCivGroup = civGroups[diplomacy.otherCivName]!!
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ class CityButton(val city: CityInfo, private val tileGroup: WorldTileGroup): Tab
|
|||||||
val viewingCiv = worldScreen.viewingCiv
|
val viewingCiv = worldScreen.viewingCiv
|
||||||
// second tap on the button will go to the city screen
|
// second tap on the button will go to the city screen
|
||||||
// if this city belongs to you
|
// if this city belongs to you
|
||||||
if (uncivGame.viewEntireMapForDebug || belongsToViewingCiv()) {
|
if (uncivGame.viewEntireMapForDebug || belongsToViewingCiv() || viewingCiv.isSpectator()) {
|
||||||
uncivGame.setScreen(CityScreen(city))
|
uncivGame.setScreen(CityScreen(city))
|
||||||
} else if (viewingCiv.knows(city.civInfo)) {
|
} else if (viewingCiv.knows(city.civInfo)) {
|
||||||
// If city doesn't belong to you, go directly to its owner's diplomacy screen.
|
// If city doesn't belong to you, go directly to its owner's diplomacy screen.
|
||||||
@ -203,15 +203,16 @@ class CityButton(val city: CityInfo, private val tileGroup: WorldTileGroup): Tab
|
|||||||
iconTable.add(connectionImage).size(20f).pad(2f).padLeft(5f)
|
iconTable.add(connectionImage).size(20f).pad(2f).padLeft(5f)
|
||||||
}
|
}
|
||||||
|
|
||||||
iconTable.add(getPopulationGroup(uncivGame.viewEntireMapForDebug || belongsToViewingCiv()))
|
iconTable.add(getPopulationGroup(uncivGame.viewEntireMapForDebug
|
||||||
.padLeft(10f)
|
|| belongsToViewingCiv()
|
||||||
|
|| worldScreen.viewingCiv.isSpectator())).padLeft(10f)
|
||||||
|
|
||||||
val cityButtonText = city.name
|
val cityButtonText = city.name
|
||||||
val label = cityButtonText.toLabel(secondaryColor)
|
val label = cityButtonText.toLabel(secondaryColor)
|
||||||
iconTable.add(label).pad(10f) // sufficient horizontal padding
|
iconTable.add(label).pad(10f) // sufficient horizontal padding
|
||||||
.fillY() // provide full-height clicking area
|
.fillY() // provide full-height clicking area
|
||||||
|
|
||||||
if (uncivGame.viewEntireMapForDebug || belongsToViewingCiv())
|
if (uncivGame.viewEntireMapForDebug || belongsToViewingCiv() || worldScreen.viewingCiv.isSpectator())
|
||||||
iconTable.add(getConstructionGroup(city.cityConstructions)).padRight(10f).padLeft(10f)
|
iconTable.add(getConstructionGroup(city.cityConstructions)).padRight(10f).padLeft(10f)
|
||||||
else if (city.civInfo.isMajorCiv()) {
|
else if (city.civInfo.isMajorCiv()) {
|
||||||
val nationIcon = ImageGetter.getNationIcon(city.civInfo.nation.name)
|
val nationIcon = ImageGetter.getNationIcon(city.civInfo.nation.name)
|
||||||
|
@ -53,7 +53,7 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo):CameraStageBaseScreen() {
|
|||||||
private fun updateLeftSideTable() {
|
private fun updateLeftSideTable() {
|
||||||
leftSideTable.clear()
|
leftSideTable.clear()
|
||||||
for (civ in UncivGame.Current.gameInfo.civilizations
|
for (civ in UncivGame.Current.gameInfo.civilizations
|
||||||
.filterNot { it.isDefeated() || it == viewingCiv || it.isBarbarian() }) {
|
.filterNot { it.isDefeated() || it == viewingCiv || it.isBarbarian() || it.isSpectator() }) {
|
||||||
if (!viewingCiv.knows(civ)) continue
|
if (!viewingCiv.knows(civ)) continue
|
||||||
|
|
||||||
val civIndicator = ImageGetter.getNationIndicator(civ.nation,100f)
|
val civIndicator = ImageGetter.getNationIndicator(civ.nation,100f)
|
||||||
|
@ -41,6 +41,7 @@ import kotlin.concurrent.thread
|
|||||||
class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
||||||
val gameInfo = game.gameInfo
|
val gameInfo = game.gameInfo
|
||||||
var isPlayersTurn = viewingCiv == gameInfo.currentPlayerCiv // todo this should be updated when passing turns
|
var isPlayersTurn = viewingCiv == gameInfo.currentPlayerCiv // todo this should be updated when passing turns
|
||||||
|
val canChangeState = isPlayersTurn && !viewingCiv.isSpectator()
|
||||||
private var waitingForAutosave = false
|
private var waitingForAutosave = false
|
||||||
|
|
||||||
val mapHolder = WorldMapHolder(this, gameInfo.tileMap)
|
val mapHolder = WorldMapHolder(this, gameInfo.tileMap)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user