mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-28 06:16:37 -04:00
Merge branch 'master' of https://github.com/yairm210/Unciv
This commit is contained in:
commit
81f88087fe
@ -1,4 +1,11 @@
|
|||||||
[
|
[
|
||||||
|
//Spectator
|
||||||
|
{
|
||||||
|
"name": "Spectator",
|
||||||
|
"outerColor": [255,255,255]
|
||||||
|
// "innerColor": [255,255,255]
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
//nations
|
//nations
|
||||||
"name": "Babylon",
|
"name": "Babylon",
|
||||||
|
@ -77,4 +77,5 @@ object Constants {
|
|||||||
const val informationEra = "Information era"
|
const val informationEra = "Information era"
|
||||||
const val futureEra = "Future era"
|
const val futureEra = "Future era"
|
||||||
const val barbarians = "Barbarians"
|
const val barbarians = "Barbarians"
|
||||||
|
const val spectator = "Spectator"
|
||||||
}
|
}
|
@ -112,6 +112,7 @@ class GameInfo {
|
|||||||
|
|
||||||
currentPlayer = thisPlayer.civName
|
currentPlayer = thisPlayer.civName
|
||||||
currentPlayerCiv = getCivilization(currentPlayer)
|
currentPlayerCiv = getCivilization(currentPlayer)
|
||||||
|
if (currentPlayerCiv.isSpectator()) currentPlayerCiv.popupAlerts.clear() // no popups for spectators
|
||||||
|
|
||||||
|
|
||||||
// Start our turn immediately before the player can made decisions - affects whether our units can commit automated actions and then be attacked immediately etc.
|
// Start our turn immediately before the player can made decisions - affects whether our units can commit automated actions and then be attacked immediately etc.
|
||||||
|
@ -52,6 +52,12 @@ object GameStarter {
|
|||||||
for (tech in gameInfo.getDifficulty().aiFreeTechs)
|
for (tech in gameInfo.getDifficulty().aiFreeTechs)
|
||||||
civInfo.tech.addTechnology(tech)
|
civInfo.tech.addTechnology(tech)
|
||||||
|
|
||||||
|
// add all techs to spectators
|
||||||
|
if (civInfo.isSpectator())
|
||||||
|
for (tech in ruleset.technologies.values)
|
||||||
|
if (!civInfo.tech.isResearched(tech.name))
|
||||||
|
civInfo.tech.addTechnology(tech.name)
|
||||||
|
|
||||||
for (tech in ruleset.technologies.values
|
for (tech in ruleset.technologies.values
|
||||||
.filter { ruleset.getEraNumber(it.era()) < ruleset.getEraNumber(gameSetupInfo.gameParameters.startingEra) })
|
.filter { ruleset.getEraNumber(it.era()) < ruleset.getEraNumber(gameSetupInfo.gameParameters.startingEra) })
|
||||||
if (!civInfo.tech.isResearched(tech.name))
|
if (!civInfo.tech.isResearched(tech.name))
|
||||||
@ -68,7 +74,8 @@ object GameStarter {
|
|||||||
|
|
||||||
private fun addCivilizations(newGameParameters: GameParameters, gameInfo: GameInfo, ruleset: Ruleset) {
|
private fun addCivilizations(newGameParameters: GameParameters, gameInfo: GameInfo, ruleset: Ruleset) {
|
||||||
val availableCivNames = Stack<String>()
|
val availableCivNames = Stack<String>()
|
||||||
availableCivNames.addAll(ruleset.nations.filter { !it.value.isCityState() }.keys.shuffled())
|
// CityState or Spectator civs are not available for Random pick
|
||||||
|
availableCivNames.addAll(ruleset.nations.filter { it.value.isMajorCiv() }.keys.shuffled())
|
||||||
availableCivNames.removeAll(newGameParameters.players.map { it.chosenCiv })
|
availableCivNames.removeAll(newGameParameters.players.map { it.chosenCiv })
|
||||||
availableCivNames.remove(Constants.barbarians)
|
availableCivNames.remove(Constants.barbarians)
|
||||||
|
|
||||||
@ -132,8 +139,8 @@ object GameStarter {
|
|||||||
}
|
}
|
||||||
return availableMilitaryUnits.maxBy { max(it.strength, it.rangedStrength) }!!.name
|
return availableMilitaryUnits.maxBy { max(it.strength, it.rangedStrength) }!!.name
|
||||||
}
|
}
|
||||||
|
// no starting units for Barbarians and Spectators
|
||||||
for (civ in gameInfo.civilizations.filter { !it.isBarbarian() }) {
|
for (civ in gameInfo.civilizations.filter { !it.isBarbarian() && !it.isSpectator() }) {
|
||||||
val startingLocation = startingLocations[civ]!!
|
val startingLocation = startingLocations[civ]!!
|
||||||
for (tile in startingLocation.getTilesInDistance(3))
|
for (tile in startingLocation.getTilesInDistance(3))
|
||||||
tile.improvement = null // Remove ancient ruins in immediate vicinity
|
tile.improvement = null // Remove ancient ruins in immediate vicinity
|
||||||
|
@ -52,6 +52,14 @@ class CivInfoTransientUpdater(val civInfo: CivilizationInfo) {
|
|||||||
private fun setNewViewableTiles() {
|
private fun setNewViewableTiles() {
|
||||||
val newViewableTiles = HashSet<TileInfo>()
|
val newViewableTiles = HashSet<TileInfo>()
|
||||||
|
|
||||||
|
// while spectating all map is visible
|
||||||
|
if (civInfo.isSpectator()) {
|
||||||
|
val allTiles = civInfo.gameInfo.tileMap.values.toSet()
|
||||||
|
civInfo.viewableTiles = allTiles
|
||||||
|
civInfo.viewableInvisibleUnitsTiles = allTiles
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// There are a LOT of tiles usually.
|
// There are a LOT of tiles usually.
|
||||||
// And making large lists of them just as intermediaries before we shove them into the hashset is very space-inefficient.
|
// And making large lists of them just as intermediaries before we shove them into the hashset is very space-inefficient.
|
||||||
// And so, sequences to the rescue!
|
// And so, sequences to the rescue!
|
||||||
|
@ -132,6 +132,7 @@ class CivilizationInfo {
|
|||||||
gameInfo.gameParameters.oneCityChallenge)
|
gameInfo.gameParameters.oneCityChallenge)
|
||||||
fun isCurrentPlayer() = gameInfo.getCurrentPlayerCivilization()==this
|
fun isCurrentPlayer() = gameInfo.getCurrentPlayerCivilization()==this
|
||||||
fun isBarbarian() = nation.isBarbarian()
|
fun isBarbarian() = nation.isBarbarian()
|
||||||
|
fun isSpectator() = nation.isSpectator()
|
||||||
fun isCityState(): Boolean = nation.isCityState()
|
fun isCityState(): Boolean = nation.isCityState()
|
||||||
fun getCityStateType(): CityStateType = nation.cityStateType!!
|
fun getCityStateType(): CityStateType = nation.cityStateType!!
|
||||||
fun isMajorCiv() = nation.isMajorCiv()
|
fun isMajorCiv() = nation.isMajorCiv()
|
||||||
@ -269,6 +270,7 @@ class CivilizationInfo {
|
|||||||
fun isDefeated()= cities.isEmpty() // No cities
|
fun isDefeated()= cities.isEmpty() // No cities
|
||||||
&& exploredTiles.isNotEmpty() // Dirty hack: exploredTiles are empty only before starting units are placed
|
&& exploredTiles.isNotEmpty() // Dirty hack: exploredTiles are empty only before starting units are placed
|
||||||
&& !isBarbarian() // Barbarians can be never defeated
|
&& !isBarbarian() // Barbarians can be never defeated
|
||||||
|
&& !isSpectator() // can't loose in Spectator mode
|
||||||
&& (citiesCreated > 0 || !getCivUnits().any { it.name == Constants.settler })
|
&& (citiesCreated > 0 || !getCivUnits().any { it.name == Constants.settler })
|
||||||
|
|
||||||
fun getEra(): String {
|
fun getEra(): String {
|
||||||
|
@ -47,8 +47,9 @@ class Nation : INamed {
|
|||||||
fun getInnerColor(): Color = innerColorObject
|
fun getInnerColor(): Color = innerColorObject
|
||||||
|
|
||||||
fun isCityState()= cityStateType != null
|
fun isCityState()= cityStateType != null
|
||||||
fun isMajorCiv() = !isBarbarian() && !isCityState()
|
fun isMajorCiv() = !isBarbarian() && !isCityState() &&!isSpectator()
|
||||||
fun isBarbarian() = name== Constants.barbarians
|
fun isBarbarian() = name== Constants.barbarians
|
||||||
|
fun isSpectator() = name == Constants.spectator
|
||||||
|
|
||||||
// This is its own transient because we'll need to check this for every tile-to-tile movement which is harsh
|
// This is its own transient because we'll need to check this for every tile-to-tile movement which is harsh
|
||||||
@Transient var forestsAndJunglesAreRoads = false
|
@Transient var forestsAndJunglesAreRoads = false
|
||||||
|
@ -5,6 +5,7 @@ import com.badlogic.gdx.Gdx
|
|||||||
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox
|
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Skin
|
import com.badlogic.gdx.scenes.scene2d.ui.Skin
|
||||||
import com.badlogic.gdx.utils.Array
|
import com.badlogic.gdx.utils.Array
|
||||||
|
import com.unciv.Constants
|
||||||
import com.unciv.UncivGame
|
import com.unciv.UncivGame
|
||||||
import com.unciv.logic.*
|
import com.unciv.logic.*
|
||||||
import com.unciv.logic.civilization.PlayerType
|
import com.unciv.logic.civilization.PlayerType
|
||||||
@ -60,6 +61,14 @@ class NewGameScreen(previousScreen:CameraStageBaseScreen, _gameSetupInfo: GameSe
|
|||||||
return@onClick
|
return@onClick
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gameSetupInfo.gameParameters.players.count { it.chosenCiv == Constants.spectator } > 1) {
|
||||||
|
val noMoreSpectatorsPopup = Popup(this)
|
||||||
|
noMoreSpectatorsPopup.addGoodSizedLabel("Sorry! No more than one spectator for the moment".tr()).row()
|
||||||
|
noMoreSpectatorsPopup.addCloseButton()
|
||||||
|
noMoreSpectatorsPopup.open()
|
||||||
|
return@onClick
|
||||||
|
}
|
||||||
|
|
||||||
if (gameSetupInfo.gameParameters.isOnlineMultiplayer) {
|
if (gameSetupInfo.gameParameters.isOnlineMultiplayer) {
|
||||||
for (player in gameSetupInfo.gameParameters.players.filter { it.playerType == PlayerType.Human }) {
|
for (player in gameSetupInfo.gameParameters.players.filter { it.playerType == PlayerType.Human }) {
|
||||||
try {
|
try {
|
||||||
|
@ -73,12 +73,19 @@ class PlayerPickerTable(val previousScreen: IPreviousScreen, var gameParameters:
|
|||||||
playerListTable.add("+".toLabel(Color.BLACK, 30).apply { this.setAlignment(Align.center) }
|
playerListTable.add("+".toLabel(Color.BLACK, 30).apply { this.setAlignment(Align.center) }
|
||||||
.surroundWithCircle(50f).onClick {
|
.surroundWithCircle(50f).onClick {
|
||||||
var player = Player()
|
var player = Player()
|
||||||
if (noRandom) { player = Player(getAvailablePlayerCivs().first().name) }
|
// no random mode - add first not spectator civ if still available
|
||||||
|
if (noRandom) {
|
||||||
|
val availableCiv = getAvailablePlayerCivs().firstOrNull { !it.isSpectator() }
|
||||||
|
if (availableCiv != null) player = Player(availableCiv.name)
|
||||||
|
// Spectators only Humans
|
||||||
|
else player = Player("Spectator").apply { playerType = PlayerType.Human }
|
||||||
|
}
|
||||||
gameParameters.players.add(player)
|
gameParameters.players.add(player)
|
||||||
update()
|
update()
|
||||||
}).pad(10f)
|
}).pad(10f)
|
||||||
}
|
}
|
||||||
previousScreen.setRightSideButtonEnabled(gameParameters.players.size > 1)
|
// can enable start game when more than 1 active player
|
||||||
|
previousScreen.setRightSideButtonEnabled(gameParameters.players.count{ it.chosenCiv != Constants.spectator } > 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -122,7 +129,9 @@ class PlayerPickerTable(val previousScreen: IPreviousScreen, var gameParameters:
|
|||||||
playerTypeTextbutton.onClick {
|
playerTypeTextbutton.onClick {
|
||||||
if (player.playerType == PlayerType.AI)
|
if (player.playerType == PlayerType.AI)
|
||||||
player.playerType = PlayerType.Human
|
player.playerType = PlayerType.Human
|
||||||
else player.playerType = PlayerType.AI
|
// we cannot change Spectator player to AI type, robots not allowed to spectate :(
|
||||||
|
else if (player.chosenCiv != Constants.spectator)
|
||||||
|
player.playerType = PlayerType.AI
|
||||||
update()
|
update()
|
||||||
}
|
}
|
||||||
playerTable.add(playerTypeTextbutton).width(100f).pad(5f).right()
|
playerTable.add(playerTypeTextbutton).width(100f).pad(5f).right()
|
||||||
@ -223,8 +232,12 @@ class PlayerPickerTable(val previousScreen: IPreviousScreen, var gameParameters:
|
|||||||
if (!noRandom) { nationListTable.add(randomPlayerTable).pad(10f).width(nationsPopupWidth).row() }
|
if (!noRandom) { nationListTable.add(randomPlayerTable).pad(10f).width(nationsPopupWidth).row() }
|
||||||
|
|
||||||
for (nation in getAvailablePlayerCivs()) {
|
for (nation in getAvailablePlayerCivs()) {
|
||||||
|
// don't show current player civ
|
||||||
if (player.chosenCiv == nation.name)
|
if (player.chosenCiv == nation.name)
|
||||||
continue
|
continue
|
||||||
|
// only humans can spectate, sorry robots
|
||||||
|
if (player.playerType == PlayerType.AI && nation.isSpectator())
|
||||||
|
continue
|
||||||
|
|
||||||
nationListTable.add(NationTable(nation, nationsPopupWidth, previousScreen.ruleset).onClick {
|
nationListTable.add(NationTable(nation, nationsPopupWidth, previousScreen.ruleset).onClick {
|
||||||
if (previousScreen is GameParametersScreen)
|
if (previousScreen is GameParametersScreen)
|
||||||
@ -261,7 +274,7 @@ class PlayerPickerTable(val previousScreen: IPreviousScreen, var gameParameters:
|
|||||||
var nations = ArrayList<Nation>()
|
var nations = ArrayList<Nation>()
|
||||||
for (nation in previousScreen.ruleset.nations.values
|
for (nation in previousScreen.ruleset.nations.values
|
||||||
.filter { it.isMajorCiv() }) {
|
.filter { it.isMajorCiv() }) {
|
||||||
if (gameParameters.players.any { it.chosenCiv == nation.name })
|
if (gameParameters.players.any { it.chosenCiv == nation.name && it.chosenCiv != Constants.spectator})
|
||||||
continue
|
continue
|
||||||
nations.add(nation)
|
nations.add(nation)
|
||||||
}
|
}
|
||||||
|
@ -394,7 +394,7 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||||||
|
|
||||||
private fun updateDiplomacyButton(civInfo: CivilizationInfo) {
|
private fun updateDiplomacyButton(civInfo: CivilizationInfo) {
|
||||||
diplomacyButtonWrapper.clear()
|
diplomacyButtonWrapper.clear()
|
||||||
if(!civInfo.isDefeated() && civInfo.getKnownCivs()
|
if(!civInfo.isDefeated() && !civInfo.isSpectator() && civInfo.getKnownCivs()
|
||||||
.filterNot { it==viewingCiv || it.isBarbarian() }
|
.filterNot { it==viewingCiv || it.isBarbarian() }
|
||||||
.any()) {
|
.any()) {
|
||||||
displayTutorial(Tutorial.OtherCivEncountered)
|
displayTutorial(Tutorial.OtherCivEncountered)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user