Fix random nations pool popup (#8769)

* Fix random nations pool dialog

* Rename randomNations for backwards compat with 4.5.0 or older
This commit is contained in:
SomeTroglodyte 2023-02-27 15:51:04 +01:00 committed by GitHub
parent 51ef8c3ccf
commit 58b3d6eaac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 88 additions and 83 deletions

View File

@ -222,7 +222,7 @@ object GameStarter {
private fun addCivilizations(newGameParameters: GameParameters, gameInfo: GameInfo, ruleset: Ruleset, existingMap: Boolean) {
val availableCivNames = Stack<String>()
if (gameSetupInfo.gameParameters.enableRandomNationsPool) {
availableCivNames.addAll(gameSetupInfo.gameParameters.randomNations.shuffled())
availableCivNames.addAll(gameSetupInfo.gameParameters.randomNationsPool.shuffled())
} else
// CityState or Spectator civs are not available for Random pick
availableCivNames.addAll(ruleset.nations.filter { it.value.isMajorCiv() }.keys.shuffled())

View File

@ -30,7 +30,7 @@ class GameParameters : IsPartOfGameInfoSerialization { // Default values are the
var numberOfCityStates = 6
var enableRandomNationsPool = false
var randomNations = arrayListOf<String>()
var randomNationsPool = arrayListOf<String>()
var noCityRazing = false
var noBarbarians = false
@ -64,7 +64,7 @@ class GameParameters : IsPartOfGameInfoSerialization { // Default values are the
parameters.maxNumberOfCityStates = maxNumberOfCityStates
parameters.numberOfCityStates = numberOfCityStates
parameters.enableRandomNationsPool = enableRandomNationsPool
parameters.randomNations = ArrayList(randomNations)
parameters.randomNationsPool = ArrayList(randomNationsPool)
parameters.noCityRazing = noCityRazing
parameters.noBarbarians = noBarbarians
parameters.ragingBarbarians = ragingBarbarians

View File

@ -3,6 +3,7 @@ package com.unciv.ui.screens.newgamescreen
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.Group
import com.badlogic.gdx.scenes.scene2d.Touchable
import com.badlogic.gdx.scenes.scene2d.ui.CheckBox
import com.badlogic.gdx.scenes.scene2d.ui.ImageButton
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.utils.Align
@ -23,7 +24,6 @@ import com.unciv.ui.screens.basescreen.BaseScreen
import com.unciv.ui.components.ExpanderTab
import com.unciv.ui.components.KeyCharAndCode
import com.unciv.ui.components.UncivSlider
import com.unciv.ui.components.extensions.isNarrowerThan4to3
import com.unciv.ui.components.extensions.keyShortcuts
import com.unciv.ui.components.extensions.onActivation
import com.unciv.ui.components.extensions.onChange
@ -35,15 +35,17 @@ import com.unciv.ui.components.extensions.toLabel
import com.unciv.ui.components.extensions.toTextButton
class GameOptionsTable(
val previousScreen: IPreviousScreen,
val isPortrait: Boolean = false,
val updatePlayerPickerTable: (desiredCiv:String)->Unit
private val previousScreen: IPreviousScreen,
private val isPortrait: Boolean = false,
private val updatePlayerPickerTable: (desiredCiv:String)->Unit
) : Table(BaseScreen.skin) {
var gameParameters = previousScreen.gameSetupInfo.gameParameters
val ruleset = previousScreen.ruleset
var locked = false
var modCheckboxes: ModCheckboxTable? = null
private set
// Remember this so we can unselect it when the pool dialog returns an empty pool
private var randomNationsPoolCheckbox: CheckBox? = null
init {
getGameOptionsTable()
@ -125,11 +127,17 @@ class GameOptionsTable(
pack()
}
private fun Table.addCheckbox(text: String, initialState: Boolean, lockable: Boolean = true, onChange: (newValue: Boolean) -> Unit) {
private fun Table.addCheckbox(
text: String,
initialState: Boolean,
lockable: Boolean = true,
onChange: (newValue: Boolean) -> Unit
): CheckBox {
val checkbox = text.toCheckBox(initialState) { onChange(it) }
checkbox.isDisabled = lockable && locked
checkbox.align(Align.left)
add(checkbox).colspan(2).row()
return checkbox
}
private fun Table.addNoCityRazingCheckbox() =
@ -173,16 +181,25 @@ class GameOptionsTable(
addCheckbox("Enable Espionage", gameParameters.espionageEnabled)
{ gameParameters.espionageEnabled = it }
private fun Table.addRandomNationsPoolCheckbox() =
addCheckbox("Set available nations for random pool", gameParameters.enableRandomNationsPool) {
gameParameters.enableRandomNationsPool = it
update() // To show the button opening the chooser popup
}
private fun Table.addRandomNationsPoolCheckbox() {
randomNationsPoolCheckbox = addCheckbox(
"Set available nations for random pool",
gameParameters.enableRandomNationsPool
) {
gameParameters.enableRandomNationsPool = it
update() // To show the button opening the chooser popup
}
}
private fun Table.addNationsSelectTextButton() {
val button = "Select nations".toTextButton()
button.onClick {
val popup = RandomNationPickerPopup(previousScreen, gameParameters)
val popup = RandomNationPickerPopup(previousScreen, gameParameters) {
if (gameParameters.randomNationsPool.isEmpty()) {
gameParameters.enableRandomNationsPool = false
randomNationsPoolCheckbox?.isChecked = false
}
}
popup.open()
popup.update()
}
@ -391,7 +408,7 @@ class GameOptionsTable(
add(victoryConditionsTable).colspan(2).row()
}
fun reloadRuleset() {
private fun reloadRuleset() {
ruleset.clear()
val newRuleset = RulesetCache.getComplexRuleset(gameParameters)
ruleset.add(newRuleset)
@ -433,7 +450,8 @@ class GameOptionsTable(
private class RandomNationPickerPopup(
previousScreen: IPreviousScreen,
val gameParameters: GameParameters
private val gameParameters: GameParameters,
private val onExit: () -> Unit
) : Popup(previousScreen as BaseScreen) {
companion object {
// These are used for the Close/OK buttons in the lower left/right corners:
@ -443,51 +461,52 @@ private class RandomNationPickerPopup(
val buttonsBackColor: Color = Color.BLACK.cpy().apply { a = 0.67f }
}
val blockWidth: Float = 0f
val civBlocksWidth = if(blockWidth <= 10f) previousScreen.stage.width / 3 - 5f else blockWidth
// This Popup's body has two halves of same size, either side by side or arranged vertically
// depending on screen proportions - determine height for one of those
private val partHeight = stageToShowOn.height * (if (stageToShowOn.isNarrowerThan4to3()) 0.45f else 0.8f)
private val nationListTable = Table()
private val nationListScroll = AutoScrollPane(nationListTable)
private val isPortrait = (previousScreen as BaseScreen).isPortrait()
private val civBlocksWidth = stageToShowOn.width / 3 - 5f
private val partHeight = stageToShowOn.height * (if (isPortrait) 0.45f else 0.8f)
/** Widget offering Nations for the Pool (those that would be excluded) goes on the left/top */
private val availableNationsListTable = Table()
private val availableNationsListScroll = AutoScrollPane(availableNationsListTable)
/** Widget selecting Nations for the Pool (those that could be chosen for a random slot) goes on the right/bottom */
private val selectedNationsListTable = Table()
private val selectedNationsListScroll = AutoScrollPane(selectedNationsListTable)
private var bannedNations = gameParameters.randomNations
var availableNations = arrayListOf<String>()
private val ruleset = previousScreen.ruleset
/** sorted list of all major nations as ready-made button */
private val allNationTables: ArrayList<NationTable>
/** backing for the left side - unchosen Nations */
private var availableNations: MutableSet<String>
/** backing for the right side - chosen Nations */
private var selectedNations: MutableSet<String>
init {
var nationListScrollY = 0f
availableNations += ruleset.nations.values.asSequence()
.filter { it.isMajorCiv() }.map { it.name }
nationListScroll.setOverscroll(false, false)
// +10, because the nation table has a 5f pad, for a total of +10f
if (stageToShowOn.isNarrowerThan4to3()) {
add("Available nations".tr())
val sortedNations = previousScreen.ruleset.nations.values
.filter { it.isMajorCiv() }
.sortedWith(compareBy(UncivGame.Current.settings.getCollatorFromLocale()) { it.name.tr() })
allNationTables = ArrayList(
sortedNations.map { NationTable(it, civBlocksWidth, 0f) } // no need for min height
)
availableNations = sortedNations.map { it.name }.toMutableSet()
selectedNations = gameParameters.randomNationsPool.intersect(availableNations) as MutableSet<String>
availableNations.removeAll(selectedNations)
availableNationsListScroll.setOverscroll(false, false)
// size below uses civBlocksWidth +10, because the nation table has a 5f pad, for a total of +10f
add("Banned nations".tr())
if (isPortrait) {
row()
add(nationListScroll).size( civBlocksWidth + 10f, partHeight )
row()
add("Banned nations".tr()).row()
add(availableNationsListScroll).size( civBlocksWidth + 10f, partHeight ).row()
addSeparator()
add("Available nations".tr()).row()
} else {
add("Available nations".tr())
add("Banned nations".tr()).row()
row()
add(nationListScroll).size( civBlocksWidth + 10f, partHeight )
add("Available nations".tr()).row()
add(availableNationsListScroll).size( civBlocksWidth + 10f, partHeight )
}
selectedNationsListScroll.setOverscroll(false, false)
add(selectedNationsListScroll).size(civBlocksWidth + 10f, partHeight) // Same here, see above
add(selectedNationsListScroll).size(civBlocksWidth + 10f, partHeight)
update()
nationListScroll.layout()
pack()
if (nationListScrollY > 0f) {
// center the selected nation vertically, getRowHeight safe because nationListScrollY > 0f ensures at least 1 row
nationListScrollY -= (nationListScroll.height - nationListTable.getRowHeight(0)) / 2
nationListScroll.scrollY = nationListScrollY.coerceIn(0f, nationListScroll.maxY)
}
val closeButton = "OtherIcons/Close".toImageButton(Color.FIREBRICK)
closeButton.onActivation { close() }
@ -509,24 +528,23 @@ private class RandomNationPickerPopup(
}
fun update() {
nationListTable.clear()
bannedNations = gameParameters.randomNations
availableNations -= bannedNations.toSet()
availableNations = availableNations.sortedWith(compareBy(UncivGame.Current.settings.getCollatorFromLocale()) { it.tr() }).toMutableList() as ArrayList<String>
var currentY = 0f
for (nationName in availableNations) {
val nation = ruleset.nations[nationName] ?: continue
val nationTable = NationTable(nation, civBlocksWidth, 0f) // no need for min height
val cell = nationListTable.add(nationTable)
currentY += cell.padBottom + cell.prefHeight + cell.padTop
cell.row()
nationTable.onClick {
addNationToPool(nation)
}
updateNationListTable(availableNationsListTable, availableNations) {
nation -> { addNationToPool(nation) }
}
updateNationListTable(selectedNationsListTable, selectedNations) {
nation -> { removeNationFromPool(nation) }
}
}
updateNationListTable()
private fun updateNationListTable(table: Table, nations: Set<String>, actionFactory: (Nation)->(()->Unit) ) {
for (child in table.children) { child.listeners.clear() }
table.clear()
for (nationTable in allNationTables) {
if (nationTable.nation.name !in nations) continue
nationTable.onClick(actionFactory(nationTable.nation))
table.add(nationTable).row()
}
}
private fun String.toImageButton(overColor: Color): Group {
@ -540,43 +558,30 @@ private class RandomNationPickerPopup(
return button.surroundWithCircle(buttonsCircleSize, false, buttonsBackColor)
}
private fun updateNationListTable() {
selectedNationsListTable.clear()
for (nationName in bannedNations) {
val currentNation = ruleset.nations[nationName] ?: continue
val nationTable = NationTable(currentNation, civBlocksWidth, 0f)
nationTable.onClick { removeNationFromPool(currentNation) }
selectedNationsListTable.add(nationTable).row()
}
}
private fun addNationToPool(nation: Nation) {
availableNations.remove(nation.name)
bannedNations.add(nation.name)
selectedNations.add(nation.name)
update()
}
private fun removeNationFromPool(nation: Nation) {
availableNations.add(nation.name)
bannedNations.remove(nation.name)
selectedNations.remove(nation.name)
update()
}
private fun returnSelected() {
close()
gameParameters.randomNations = availableNations
gameParameters.randomNationsPool = ArrayList(selectedNations)
onExit()
}
private fun switchAllNations() {
val tempNations = availableNations
availableNations = bannedNations
bannedNations = tempNations
gameParameters.randomNations = bannedNations
availableNations = selectedNations
selectedNations = tempNations
update()
}
}