mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-19 20:28:56 +07:00
Merge branch 'master' of https://github.com/yairm210/Unciv
This commit is contained in:
@ -1,4 +1,11 @@
|
||||
[
|
||||
//Spectator
|
||||
{
|
||||
"name": "Spectator",
|
||||
"outerColor": [255,255,255]
|
||||
// "innerColor": [255,255,255]
|
||||
},
|
||||
|
||||
{
|
||||
//nations
|
||||
"name": "Babylon",
|
||||
@ -1015,5 +1022,5 @@
|
||||
"outerColor": [0,0,0],
|
||||
"innerColor": [182,0,0]
|
||||
}
|
||||
|
||||
|
||||
]
|
||||
|
@ -77,4 +77,5 @@ object Constants {
|
||||
const val informationEra = "Information era"
|
||||
const val futureEra = "Future era"
|
||||
const val barbarians = "Barbarians"
|
||||
const val spectator = "Spectator"
|
||||
}
|
@ -112,6 +112,7 @@ class GameInfo {
|
||||
|
||||
currentPlayer = thisPlayer.civName
|
||||
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.
|
||||
|
@ -52,6 +52,12 @@ object GameStarter {
|
||||
for (tech in gameInfo.getDifficulty().aiFreeTechs)
|
||||
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
|
||||
.filter { ruleset.getEraNumber(it.era()) < ruleset.getEraNumber(gameSetupInfo.gameParameters.startingEra) })
|
||||
if (!civInfo.tech.isResearched(tech.name))
|
||||
@ -68,7 +74,8 @@ object GameStarter {
|
||||
|
||||
private fun addCivilizations(newGameParameters: GameParameters, gameInfo: GameInfo, ruleset: Ruleset) {
|
||||
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.remove(Constants.barbarians)
|
||||
|
||||
@ -132,8 +139,8 @@ object GameStarter {
|
||||
}
|
||||
return availableMilitaryUnits.maxBy { max(it.strength, it.rangedStrength) }!!.name
|
||||
}
|
||||
|
||||
for (civ in gameInfo.civilizations.filter { !it.isBarbarian() }) {
|
||||
// no starting units for Barbarians and Spectators
|
||||
for (civ in gameInfo.civilizations.filter { !it.isBarbarian() && !it.isSpectator() }) {
|
||||
val startingLocation = startingLocations[civ]!!
|
||||
for (tile in startingLocation.getTilesInDistance(3))
|
||||
tile.improvement = null // Remove ancient ruins in immediate vicinity
|
||||
|
@ -52,6 +52,14 @@ class CivInfoTransientUpdater(val civInfo: CivilizationInfo) {
|
||||
private fun setNewViewableTiles() {
|
||||
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.
|
||||
// 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!
|
||||
|
@ -132,6 +132,7 @@ class CivilizationInfo {
|
||||
gameInfo.gameParameters.oneCityChallenge)
|
||||
fun isCurrentPlayer() = gameInfo.getCurrentPlayerCivilization()==this
|
||||
fun isBarbarian() = nation.isBarbarian()
|
||||
fun isSpectator() = nation.isSpectator()
|
||||
fun isCityState(): Boolean = nation.isCityState()
|
||||
fun getCityStateType(): CityStateType = nation.cityStateType!!
|
||||
fun isMajorCiv() = nation.isMajorCiv()
|
||||
@ -269,6 +270,7 @@ class CivilizationInfo {
|
||||
fun isDefeated()= cities.isEmpty() // No cities
|
||||
&& exploredTiles.isNotEmpty() // Dirty hack: exploredTiles are empty only before starting units are placed
|
||||
&& !isBarbarian() // Barbarians can be never defeated
|
||||
&& !isSpectator() // can't loose in Spectator mode
|
||||
&& (citiesCreated > 0 || !getCivUnits().any { it.name == Constants.settler })
|
||||
|
||||
fun getEra(): String {
|
||||
|
@ -47,8 +47,9 @@ class Nation : INamed {
|
||||
fun getInnerColor(): Color = innerColorObject
|
||||
|
||||
fun isCityState()= cityStateType != null
|
||||
fun isMajorCiv() = !isBarbarian() && !isCityState()
|
||||
fun isMajorCiv() = !isBarbarian() && !isCityState() &&!isSpectator()
|
||||
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
|
||||
@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.Skin
|
||||
import com.badlogic.gdx.utils.Array
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.*
|
||||
import com.unciv.logic.civilization.PlayerType
|
||||
@ -60,6 +61,14 @@ class NewGameScreen(previousScreen:CameraStageBaseScreen, _gameSetupInfo: GameSe
|
||||
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) {
|
||||
for (player in gameSetupInfo.gameParameters.players.filter { it.playerType == PlayerType.Human }) {
|
||||
try {
|
||||
|
@ -73,12 +73,19 @@ class PlayerPickerTable(val previousScreen: IPreviousScreen, var gameParameters:
|
||||
playerListTable.add("+".toLabel(Color.BLACK, 30).apply { this.setAlignment(Align.center) }
|
||||
.surroundWithCircle(50f).onClick {
|
||||
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)
|
||||
update()
|
||||
}).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 {
|
||||
if (player.playerType == PlayerType.AI)
|
||||
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()
|
||||
}
|
||||
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() }
|
||||
|
||||
for (nation in getAvailablePlayerCivs()) {
|
||||
// don't show current player civ
|
||||
if (player.chosenCiv == nation.name)
|
||||
continue
|
||||
// only humans can spectate, sorry robots
|
||||
if (player.playerType == PlayerType.AI && nation.isSpectator())
|
||||
continue
|
||||
|
||||
nationListTable.add(NationTable(nation, nationsPopupWidth, previousScreen.ruleset).onClick {
|
||||
if (previousScreen is GameParametersScreen)
|
||||
@ -261,7 +274,7 @@ class PlayerPickerTable(val previousScreen: IPreviousScreen, var gameParameters:
|
||||
var nations = ArrayList<Nation>()
|
||||
for (nation in previousScreen.ruleset.nations.values
|
||||
.filter { it.isMajorCiv() }) {
|
||||
if (gameParameters.players.any { it.chosenCiv == nation.name })
|
||||
if (gameParameters.players.any { it.chosenCiv == nation.name && it.chosenCiv != Constants.spectator})
|
||||
continue
|
||||
nations.add(nation)
|
||||
}
|
||||
|
@ -394,7 +394,7 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
||||
|
||||
private fun updateDiplomacyButton(civInfo: CivilizationInfo) {
|
||||
diplomacyButtonWrapper.clear()
|
||||
if(!civInfo.isDefeated() && civInfo.getKnownCivs()
|
||||
if(!civInfo.isDefeated() && !civInfo.isSpectator() && civInfo.getKnownCivs()
|
||||
.filterNot { it==viewingCiv || it.isBarbarian() }
|
||||
.any()) {
|
||||
displayTutorial(Tutorial.OtherCivEncountered)
|
||||
|
Reference in New Issue
Block a user