mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-13 01:08:25 +07:00
Add options to use random number of players and city states. (#8394)
* Add option to use random number of players and city states. * Fix spaces after = * Update clone() and toString() of GameParameters * Make sure at least one AI player when using random players. * Fix typo in random players initial values. * Fix for if user chooses random of 0 or 1 city states. * Move random player and city state toggles to advanced. Move random city state choice to where it will not cache and reveal on next game. Change random city states to use min and max sliders that can be used inverted. * Add random players min and max sliders. * Change random players option to use min and max sliders that can be used inverted.
This commit is contained in:
@ -360,6 +360,12 @@ Three Continents =
|
||||
Four Corners =
|
||||
Archipelago =
|
||||
Inner Sea =
|
||||
Random number of Civilizations =
|
||||
Min number of Civilizations =
|
||||
Max number of Civilizations =
|
||||
Random number of City-States =
|
||||
Min number of City-States =
|
||||
Max number of City-States =
|
||||
Number of City-States =
|
||||
One City Challenge =
|
||||
No City Razing =
|
||||
|
@ -13,6 +13,7 @@ import com.unciv.logic.map.TileMap
|
||||
import com.unciv.logic.map.mapgenerator.MapGenerator
|
||||
import com.unciv.models.metadata.GameParameters
|
||||
import com.unciv.models.metadata.GameSetupInfo
|
||||
import com.unciv.models.metadata.Player
|
||||
import com.unciv.models.ruleset.ModOptionsConstants
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.RulesetCache
|
||||
@ -236,6 +237,33 @@ object GameStarter {
|
||||
val presetMajors = Stack<String>()
|
||||
presetMajors.addAll(availableCivNames.filter { it in civNamesWithStartingLocations })
|
||||
|
||||
if (newGameParameters.randomNumberOfPlayers) {
|
||||
// This swaps min and max if the user accidentally swapped min and max
|
||||
val min = newGameParameters.minNumberOfPlayers.coerceAtMost(newGameParameters.maxNumberOfPlayers)
|
||||
val max = newGameParameters.maxNumberOfPlayers.coerceAtLeast(newGameParameters.minNumberOfPlayers)
|
||||
var playerCount = (min..max).random()
|
||||
|
||||
val humanPlayerCount = newGameParameters.players.filter {
|
||||
it.playerType === PlayerType.Human
|
||||
}.count()
|
||||
val spectatorCount = newGameParameters.players.filter {
|
||||
it.chosenCiv === Constants.spectator
|
||||
}.count()
|
||||
playerCount = playerCount.coerceAtLeast(humanPlayerCount + spectatorCount)
|
||||
|
||||
if (newGameParameters.players.size < playerCount) {
|
||||
val neededPlayers = playerCount - newGameParameters.players.size
|
||||
for (i in 1..neededPlayers) newGameParameters.players.add(Player())
|
||||
} else if (newGameParameters.players.size > playerCount) {
|
||||
val extraPlayers = newGameParameters.players.size - playerCount
|
||||
val playersToRemove = newGameParameters.players.filter {
|
||||
it.playerType === PlayerType.AI
|
||||
}.shuffled().subList(0, extraPlayers)
|
||||
|
||||
newGameParameters.players.removeAll(playersToRemove)
|
||||
}
|
||||
}
|
||||
|
||||
for (player in newGameParameters.players.sortedBy { it.chosenCiv == Constants.random }) {
|
||||
val nationName = when {
|
||||
player.chosenCiv != Constants.random -> player.chosenCiv
|
||||
@ -263,9 +291,17 @@ object GameStarter {
|
||||
.shuffled()
|
||||
.sortedBy { it in civNamesWithStartingLocations } ) // pop() gets the last item, so sort ascending
|
||||
|
||||
val numberOfCityStates = if (newGameParameters.randomNumberOfCityStates) {
|
||||
// This swaps min and max if the user accidentally swapped min and max
|
||||
val min = newGameParameters.minNumberOfCityStates.coerceAtMost(newGameParameters.maxNumberOfCityStates)
|
||||
val max = newGameParameters.maxNumberOfCityStates.coerceAtLeast(newGameParameters.minNumberOfCityStates)
|
||||
(min..max).random()
|
||||
} else {
|
||||
newGameParameters.numberOfCityStates
|
||||
}
|
||||
var addedCityStates = 0
|
||||
// Keep trying to add city states until we reach the target number.
|
||||
while (addedCityStates < newGameParameters.numberOfCityStates) {
|
||||
while (addedCityStates < numberOfCityStates) {
|
||||
if (availableCityStatesNames.isEmpty()) // We ran out of city-states somehow
|
||||
break
|
||||
|
||||
|
@ -15,10 +15,16 @@ class GameParameters : IsPartOfGameInfoSerialization { // Default values are the
|
||||
|
||||
@Deprecated("Since 4.1.11")
|
||||
var gameSpeed = ""
|
||||
var randomNumberOfPlayers = false
|
||||
var minNumberOfPlayers = 3
|
||||
var maxNumberOfPlayers = 3
|
||||
var players = ArrayList<Player>().apply {
|
||||
add(Player().apply { playerType = PlayerType.Human })
|
||||
for (i in 1..3) add(Player())
|
||||
}
|
||||
var randomNumberOfCityStates = false
|
||||
var minNumberOfCityStates = 6
|
||||
var maxNumberOfCityStates = 6
|
||||
var numberOfCityStates = 6
|
||||
|
||||
var noCityRazing = false
|
||||
@ -47,6 +53,12 @@ class GameParameters : IsPartOfGameInfoSerialization { // Default values are the
|
||||
parameters.difficulty = difficulty
|
||||
parameters.speed = speed
|
||||
parameters.players = ArrayList(players)
|
||||
parameters.randomNumberOfPlayers = randomNumberOfPlayers
|
||||
parameters.minNumberOfPlayers = minNumberOfPlayers
|
||||
parameters.maxNumberOfPlayers = maxNumberOfPlayers
|
||||
parameters.randomNumberOfCityStates = randomNumberOfCityStates
|
||||
parameters.minNumberOfCityStates = minNumberOfCityStates
|
||||
parameters.maxNumberOfCityStates = maxNumberOfCityStates
|
||||
parameters.numberOfCityStates = numberOfCityStates
|
||||
parameters.noBarbarians = noBarbarians
|
||||
parameters.ragingBarbarians = ragingBarbarians
|
||||
@ -67,7 +79,11 @@ class GameParameters : IsPartOfGameInfoSerialization { // Default values are the
|
||||
yield("$difficulty $speed $startingEra")
|
||||
yield("${players.count { it.playerType == PlayerType.Human }} ${PlayerType.Human}")
|
||||
yield("${players.count { it.playerType == PlayerType.AI }} ${PlayerType.AI}")
|
||||
yield("$minNumberOfCityStates Min CS")
|
||||
yield("$maxNumberOfCityStates Max CS")
|
||||
yield("$numberOfCityStates CS")
|
||||
if (randomNumberOfPlayers) yield("Random number of Players")
|
||||
if (randomNumberOfCityStates) yield("Random number of City-States")
|
||||
if (isOnlineMultiplayer) yield("Online Multiplayer")
|
||||
if (noBarbarians) yield("No barbs")
|
||||
if (ragingBarbarians) yield("Raging barbs")
|
||||
|
@ -60,7 +60,16 @@ class GameOptionsTable(
|
||||
val turnSlider = addMaxTurnsSlider()
|
||||
if (turnSlider != null)
|
||||
add(turnSlider).padTop(10f).row()
|
||||
addCityStatesSlider()
|
||||
if (gameParameters.randomNumberOfPlayers) {
|
||||
addMinPlayersSlider()
|
||||
addMaxPlayersSlider()
|
||||
}
|
||||
if (gameParameters.randomNumberOfCityStates) {
|
||||
addMinCityStatesSlider()
|
||||
addMaxCityStatesSlider()
|
||||
} else {
|
||||
addCityStatesSlider()
|
||||
}
|
||||
}).colspan(2).fillX().row()
|
||||
}).row()
|
||||
addVictoryTypeCheckboxes()
|
||||
@ -82,6 +91,8 @@ class GameOptionsTable(
|
||||
if (UncivGame.Current.settings.enableEspionageOption)
|
||||
it.addEnableEspionageCheckbox()
|
||||
it.addNoStartBiasCheckbox()
|
||||
it.addRandomPlayersCheckbox()
|
||||
it.addRandomCityStatesCheckbox()
|
||||
}
|
||||
add(expander).pad(10f).padTop(10f).growX().row()
|
||||
|
||||
@ -141,6 +152,10 @@ class GameOptionsTable(
|
||||
{ gameParameters.espionageEnabled = it }
|
||||
|
||||
|
||||
private fun numberOfPlayable() = ruleset.nations.values.count {
|
||||
it.isMajorCiv()
|
||||
}
|
||||
|
||||
private fun numberOfCityStates() = ruleset.nations.values.count {
|
||||
it.isCityState()
|
||||
&& !it.hasUnique(UniqueType.CityStateDeprecated)
|
||||
@ -150,12 +165,78 @@ class GameOptionsTable(
|
||||
addCheckbox("Disable starting bias", gameParameters.noStartBias)
|
||||
{ gameParameters.noStartBias = it }
|
||||
|
||||
private fun Table.addRandomPlayersCheckbox() =
|
||||
addCheckbox("Random number of Civilizations", gameParameters.randomNumberOfPlayers)
|
||||
{
|
||||
gameParameters.randomNumberOfPlayers = it
|
||||
update()
|
||||
}
|
||||
|
||||
private fun Table.addRandomCityStatesCheckbox() =
|
||||
addCheckbox("Random number of City-States", gameParameters.randomNumberOfCityStates)
|
||||
{
|
||||
gameParameters.randomNumberOfCityStates = it
|
||||
update()
|
||||
}
|
||||
|
||||
private fun Table.addMinPlayersSlider() {
|
||||
val playableAvailable = numberOfPlayable()
|
||||
if (playableAvailable == 0) return
|
||||
|
||||
add("{Min number of Civilizations}:".toLabel()).left().expandX()
|
||||
val slider = UncivSlider(2f, playableAvailable.toFloat(), 1f, initial = gameParameters.minNumberOfPlayers.toFloat()) {
|
||||
gameParameters.minNumberOfPlayers = it.toInt()
|
||||
}
|
||||
slider.permanentTip = true
|
||||
slider.isDisabled = locked
|
||||
add(slider).padTop(10f).row()
|
||||
}
|
||||
|
||||
private fun Table.addMaxPlayersSlider() {
|
||||
val playableAvailable = numberOfPlayable()
|
||||
if (playableAvailable == 0) return
|
||||
|
||||
add("{Max number of Civilizations}:".toLabel()).left().expandX()
|
||||
val slider = UncivSlider(2f, playableAvailable.toFloat(), 1f, initial = gameParameters.maxNumberOfPlayers.toFloat()) {
|
||||
gameParameters.maxNumberOfPlayers = it.toInt()
|
||||
}
|
||||
slider.permanentTip = true
|
||||
slider.isDisabled = locked
|
||||
add(slider).padTop(10f).row()
|
||||
}
|
||||
|
||||
private fun Table.addMinCityStatesSlider() {
|
||||
val cityStatesAvailable = numberOfCityStates()
|
||||
if (cityStatesAvailable == 0) return
|
||||
|
||||
add("{Min number of City-States}:".toLabel()).left().expandX()
|
||||
val slider = UncivSlider(0f, cityStatesAvailable.toFloat(), 1f, initial = gameParameters.minNumberOfCityStates.toFloat()) {
|
||||
gameParameters.minNumberOfCityStates = it.toInt()
|
||||
}
|
||||
slider.permanentTip = true
|
||||
slider.isDisabled = locked
|
||||
add(slider).padTop(10f).row()
|
||||
}
|
||||
|
||||
private fun Table.addMaxCityStatesSlider() {
|
||||
val cityStatesAvailable = numberOfCityStates()
|
||||
if (cityStatesAvailable == 0) return
|
||||
|
||||
add("{Max number of City-States}:".toLabel()).left().expandX()
|
||||
val slider = UncivSlider(0f, cityStatesAvailable.toFloat(), 1f, initial = gameParameters.maxNumberOfCityStates.toFloat()) {
|
||||
gameParameters.maxNumberOfCityStates = it.toInt()
|
||||
}
|
||||
slider.permanentTip = true
|
||||
slider.isDisabled = locked
|
||||
add(slider).padTop(10f).row()
|
||||
}
|
||||
|
||||
private fun Table.addCityStatesSlider() {
|
||||
val maxCityStates = numberOfCityStates()
|
||||
if (maxCityStates == 0) return
|
||||
val cityStatesAvailable = numberOfCityStates()
|
||||
if (cityStatesAvailable == 0) return
|
||||
|
||||
add("{Number of City-States}:".toLabel()).left().expandX()
|
||||
val slider = UncivSlider(0f, maxCityStates.toFloat(), 1f, initial = gameParameters.numberOfCityStates.toFloat()) {
|
||||
val slider = UncivSlider(0f, cityStatesAvailable.toFloat(), 1f, initial = gameParameters.numberOfCityStates.toFloat()) {
|
||||
gameParameters.numberOfCityStates = it.toInt()
|
||||
}
|
||||
slider.permanentTip = true
|
||||
|
Reference in New Issue
Block a user