Adding units on map editor. (#2667)
* Adding units to map editor. * loadScenario checkbox Prototype added to MapOptions table. * adds switch for Scenario and Unit editor debug * New Scenario class * Background step1: 1. Create a new class Scenario, containing TileMap, GameParameters and string name (doesn't really matter where, we can move it around later) 2. Create SaveScenario and LoadScenario functions in MapSaver (save to/ load from scenario name) * Prototype of Save/Load scenario implementation. * Add update method to NewGameOptionsTable * First working Save/Load scenario prototype * First working prototype of Load/Save scenario * Added test conditions for the new debug modes * Resolve merge conflict Co-authored-by: Yair Morgenstern <yairm210@hotmail.com>
This commit is contained in:
parent
1961aa7245
commit
c3da044c43
16 changed files with 297 additions and 81 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -137,3 +137,4 @@ android/release/
|
|||
android/assets/mods/
|
||||
android/assets/SaveFiles/
|
||||
android/assets/GameSettingsOld.json
|
||||
android/assets/scenarios/
|
||||
|
|
|
@ -56,6 +56,9 @@ class UncivGame(
|
|||
/** Console log battles
|
||||
*/
|
||||
val alertBattle = true
|
||||
/** Debug new Scenario functionality
|
||||
*/
|
||||
val scenarioDebugSwitch = false
|
||||
|
||||
lateinit var worldScreen: WorldScreen
|
||||
|
||||
|
|
|
@ -21,7 +21,9 @@ object GameStarter {
|
|||
gameInfo.gameParameters = gameSetupInfo.gameParameters
|
||||
val ruleset = RulesetCache.getComplexRuleset(gameInfo.gameParameters.mods)
|
||||
|
||||
if (gameSetupInfo.mapParameters.name != "")
|
||||
if (gameSetupInfo.mapParameters.type == MapType.scenario)
|
||||
gameInfo.tileMap = MapSaver.loadScenario(gameSetupInfo.mapParameters.name).tileMap
|
||||
else if (gameSetupInfo.mapParameters.name != "")
|
||||
gameInfo.tileMap = MapSaver.loadMap(gameSetupInfo.mapParameters.name)
|
||||
else gameInfo.tileMap = MapGenerator(ruleset).generateMap(gameSetupInfo.mapParameters)
|
||||
gameInfo.tileMap.mapParameters = gameSetupInfo.mapParameters
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.unciv.logic
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.unciv.logic.map.Scenario
|
||||
import com.unciv.logic.map.TileMap
|
||||
import com.unciv.ui.saves.Gzip
|
||||
|
||||
|
@ -9,23 +10,36 @@ object MapSaver {
|
|||
fun json() = GameSaver.json()
|
||||
|
||||
private const val mapsFolder = "maps"
|
||||
private const val scenariosFolder = "scenarios"
|
||||
|
||||
private fun getMap(mapName:String) = Gdx.files.local("$mapsFolder/$mapName")
|
||||
|
||||
private fun getScenario(scenarioName:String) = Gdx.files.local("$scenariosFolder/$scenarioName")
|
||||
|
||||
fun saveMap(mapName: String,tileMap: TileMap) {
|
||||
getMap(mapName).writeString(Gzip.zip(json().toJson(tileMap)), false)
|
||||
}
|
||||
|
||||
fun saveScenario(scenarioName:String, scenario: Scenario) {
|
||||
getScenario(scenarioName).writeString(json().toJson(scenario), false)
|
||||
}
|
||||
|
||||
fun loadMap(mapName: String): TileMap {
|
||||
val gzippedString = getMap(mapName).readString()
|
||||
val unzippedJson = Gzip.unzip(gzippedString)
|
||||
return json().fromJson(TileMap::class.java, unzippedJson)
|
||||
}
|
||||
|
||||
fun loadScenario(scenarioName: String): Scenario {
|
||||
val scenarioJson = getScenario(scenarioName).readString()
|
||||
return json().fromJson(Scenario::class.java, scenarioJson)
|
||||
}
|
||||
|
||||
fun deleteMap(mapName: String) = getMap(mapName).delete()
|
||||
|
||||
fun getMaps() = Gdx.files.local(mapsFolder).list().map { it.name() }
|
||||
|
||||
fun getScenarios() = Gdx.files.local(scenariosFolder).list().map { it.name() }
|
||||
|
||||
fun mapFromJson(json:String): TileMap = json().fromJson(TileMap::class.java, json)
|
||||
|
||||
}
|
|
@ -25,6 +25,9 @@ object MapType {
|
|||
// Non-generated maps
|
||||
const val custom = "Custom"
|
||||
|
||||
// Loaded scenario
|
||||
const val scenario = "Scenario"
|
||||
|
||||
// All ocean tiles
|
||||
const val empty = "Empty"
|
||||
}
|
||||
|
|
16
core/src/com/unciv/logic/map/Scenario.kt
Normal file
16
core/src/com/unciv/logic/map/Scenario.kt
Normal file
|
@ -0,0 +1,16 @@
|
|||
package com.unciv.logic.map
|
||||
|
||||
import com.unciv.models.metadata.GameParameters
|
||||
|
||||
class Scenario {
|
||||
lateinit var tileMap: TileMap
|
||||
lateinit var gameParameters: GameParameters
|
||||
|
||||
/** for json parsing, we need to have a default constructor */
|
||||
constructor()
|
||||
|
||||
constructor(tileMap:TileMap, gameParameters: GameParameters) {
|
||||
this.tileMap = tileMap
|
||||
this.gameParameters = gameParameters
|
||||
}
|
||||
}
|
|
@ -9,6 +9,11 @@ import com.unciv.UncivGame
|
|||
import com.unciv.logic.MapSaver
|
||||
import com.unciv.logic.map.MapType
|
||||
import com.unciv.logic.map.RoadStatus
|
||||
import com.unciv.logic.map.Scenario
|
||||
import com.unciv.logic.map.TileMap
|
||||
import com.unciv.models.metadata.Player
|
||||
import com.unciv.ui.newgamescreen.GameOptionsTable
|
||||
import com.unciv.ui.newgamescreen.PlayerPickerTable
|
||||
import com.unciv.ui.saves.Gzip
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.worldscreen.mainmenu.DropBox
|
||||
|
@ -118,6 +123,32 @@ class MapEditorMenuPopup(mapEditorScreen: MapEditorScreen): Popup(mapEditorScree
|
|||
}
|
||||
add(uploadMapButton).row()
|
||||
|
||||
if (UncivGame.Current.scenarioDebugSwitch) {
|
||||
val createScenarioButton = "Create scenario".toTextButton()
|
||||
add(createScenarioButton).row()
|
||||
createScenarioButton.onClick {
|
||||
remove()
|
||||
mapEditorScreen.gameSetupInfo.gameParameters.players = getPlayersFromMap(mapEditorScreen.tileMap) // update players list from tileMap starting locations
|
||||
|
||||
val gameParametersPopup = Popup(screen)
|
||||
val playerPickerTable = PlayerPickerTable(mapEditorScreen, mapEditorScreen.gameSetupInfo.gameParameters)
|
||||
val gameOptionsTable = GameOptionsTable(mapEditorScreen) {desiredCiv: String -> playerPickerTable.update(desiredCiv)}
|
||||
val scenarioNameEditor = TextField(mapEditorScreen.mapName, skin)
|
||||
|
||||
gameParametersPopup.add(playerPickerTable)
|
||||
gameParametersPopup.addSeparatorVertical()
|
||||
gameParametersPopup.add(gameOptionsTable).row()
|
||||
gameParametersPopup.add(scenarioNameEditor)
|
||||
gameParametersPopup.addButton("Save scenario"){
|
||||
mapEditorScreen.tileMap.mapParameters.type=MapType.scenario
|
||||
MapSaver.saveScenario(scenarioNameEditor.text, Scenario(mapEditorScreen.tileMap, mapEditorScreen.gameSetupInfo.gameParameters))
|
||||
ResponsePopup("Scenario saved", mapEditorScreen)
|
||||
gameParametersPopup.close()
|
||||
}.row()
|
||||
gameParametersPopup.addCloseButton().row()
|
||||
gameParametersPopup.open()
|
||||
}
|
||||
}
|
||||
|
||||
val exitMapEditorButton = "Exit map editor".toTextButton()
|
||||
add(exitMapEditorButton ).row()
|
||||
|
@ -128,3 +159,15 @@ class MapEditorMenuPopup(mapEditorScreen: MapEditorScreen): Popup(mapEditorScree
|
|||
add(closeOptionsButton).row()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPlayersFromMap(tileMap: TileMap): ArrayList<Player> {
|
||||
val tilesWithStartingLocations = tileMap.values
|
||||
.filter { it.improvement != null && it.improvement!!.startsWith("StartingLocation ") }
|
||||
var players = ArrayList<Player>()
|
||||
for (tile in tilesWithStartingLocations) {
|
||||
players.add(Player().apply{
|
||||
chosenCiv = tile.improvement!!.removePrefix("StartingLocation ")
|
||||
})
|
||||
}
|
||||
return players
|
||||
}
|
||||
|
|
|
@ -5,17 +5,24 @@ import com.badlogic.gdx.math.Vector2
|
|||
import com.badlogic.gdx.scenes.scene2d.InputEvent
|
||||
import com.badlogic.gdx.scenes.scene2d.InputListener
|
||||
import com.badlogic.gdx.scenes.scene2d.actions.Actions
|
||||
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.logic.MapSaver
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.logic.map.TileMap
|
||||
import com.unciv.models.ruleset.RulesetCache
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.newgamescreen.GameParametersPreviousScreen
|
||||
import com.unciv.ui.newgamescreen.GameSetupInfo
|
||||
import com.unciv.ui.utils.*
|
||||
|
||||
class MapEditorScreen(): CameraStageBaseScreen() {
|
||||
val ruleset = RulesetCache.getBaseRuleset()
|
||||
class MapEditorScreen(): GameParametersPreviousScreen() {
|
||||
override val ruleset = RulesetCache.getBaseRuleset()
|
||||
var mapName = ""
|
||||
|
||||
var tileMap = TileMap()
|
||||
override var gameSetupInfo = GameSetupInfo()
|
||||
lateinit var mapHolder: EditorMapHolder
|
||||
|
||||
val tileEditorOptions = TileEditorOptionsTable(this)
|
||||
|
@ -149,4 +156,19 @@ class MapEditorScreen(): CameraStageBaseScreen() {
|
|||
}
|
||||
}
|
||||
|
||||
class TranslatedSelectBox(values : Collection<String>, default:String, skin: Skin) : SelectBox<TranslatedSelectBox.TranslatedString>(skin) {
|
||||
class TranslatedString(val value: String) {
|
||||
val translation = value.tr()
|
||||
override fun toString() = translation
|
||||
}
|
||||
|
||||
init {
|
||||
val array = Array<TranslatedString>()
|
||||
values.forEach { array.add(TranslatedString(it)) }
|
||||
items = array
|
||||
val defaultItem = array.firstOrNull { it.value == default }
|
||||
selected = if (defaultItem != null) defaultItem else array.first()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@ import com.unciv.logic.civilization.CivilizationInfo
|
|||
import com.unciv.logic.map.MapUnit
|
||||
import com.unciv.logic.map.RoadStatus
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.logic.map.TileMap
|
||||
import com.unciv.models.ruleset.Nation
|
||||
import com.unciv.models.ruleset.tile.ResourceType
|
||||
import com.unciv.models.ruleset.tile.TerrainType
|
||||
import com.unciv.models.translations.tr
|
||||
|
@ -48,8 +50,10 @@ class TileEditorOptionsTable(val mapEditorScreen: MapEditorScreen): Table(Camera
|
|||
.onClick { setImprovements() }
|
||||
tabPickerTable.add(improvementsButton)
|
||||
|
||||
// val unitsButton = "Units".toTextButton().onClick { setUnits() }
|
||||
// tabPickerTable.add(unitsButton)
|
||||
if (UncivGame.Current.scenarioDebugSwitch) {
|
||||
val unitsButton = "Units".toTextButton().onClick { setUnits() }
|
||||
tabPickerTable.add(unitsButton)
|
||||
}
|
||||
|
||||
tabPickerTable.pack()
|
||||
|
||||
|
@ -154,11 +158,15 @@ class TileEditorOptionsTable(val mapEditorScreen: MapEditorScreen): Table(Camera
|
|||
}
|
||||
|
||||
val nationsTable = Table()
|
||||
for(nation in ruleset.nations.values){
|
||||
val nations = nationsFromMap(mapEditorScreen.tileMap)
|
||||
val barbarians = ruleset.nations.values.filter { it.isBarbarian()}
|
||||
|
||||
for(nation in nations + barbarians){
|
||||
val nationImage = ImageGetter.getNationIndicator(nation, 40f)
|
||||
nationsTable.add(nationImage).row()
|
||||
nationImage.onClick { currentNation = nation; setUnitTileAction() }
|
||||
}
|
||||
|
||||
editorPickTable.add(ScrollPane(nationsTable)).height(stage.height*0.8f)
|
||||
|
||||
val unitsTable = Table()
|
||||
|
@ -170,6 +178,18 @@ class TileEditorOptionsTable(val mapEditorScreen: MapEditorScreen): Table(Camera
|
|||
editorPickTable.add(ScrollPane(unitsTable)).height(stage.height*0.8f)
|
||||
}
|
||||
|
||||
private fun nationsFromMap(tileMap: TileMap): ArrayList<Nation> {
|
||||
val tilesWithStartingLocations = tileMap.values
|
||||
.filter { it.improvement != null && it.improvement!!.startsWith("StartingLocation ") }
|
||||
var nations = ArrayList<Nation>()
|
||||
for (tile in tilesWithStartingLocations) {
|
||||
var civName = tile.improvement!!.removePrefix("StartingLocation ")
|
||||
nations.add(ruleset.nations[civName]!!)
|
||||
}
|
||||
return nations
|
||||
}
|
||||
|
||||
|
||||
private fun getRedCross(size: Float, alpha: Float): Actor {
|
||||
val redCross = ImageGetter.getImage("OtherIcons/Close")
|
||||
redCross.setSize( size, size)
|
||||
|
|
|
@ -8,17 +8,24 @@ import com.unciv.models.metadata.GameSpeed
|
|||
import com.unciv.models.ruleset.RulesetCache
|
||||
import com.unciv.models.ruleset.VictoryType
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.utils.CameraStageBaseScreen
|
||||
import com.unciv.ui.utils.ImageGetter
|
||||
import com.unciv.ui.utils.onChange
|
||||
import com.unciv.ui.utils.toLabel
|
||||
import com.unciv.ui.utils.*
|
||||
|
||||
class NewGameOptionsTable(newGameScreen: NewGameScreen, val updatePlayerPickerTable:(desiredCiv:String)->Unit)
|
||||
class GameOptionsTable(previousScreen: GameParametersPreviousScreen, val updatePlayerPickerTable:(desiredCiv:String)->Unit)
|
||||
: Table(CameraStageBaseScreen.skin) {
|
||||
val newGameParameters = newGameScreen.gameSetupInfo.gameParameters
|
||||
val ruleset = newGameScreen.ruleset
|
||||
var gameParameters = previousScreen.gameSetupInfo.gameParameters
|
||||
val ruleset = previousScreen.ruleset
|
||||
var locked = false
|
||||
|
||||
init {
|
||||
getGameOptionsTable()
|
||||
}
|
||||
|
||||
fun update() {
|
||||
clear()
|
||||
getGameOptionsTable()
|
||||
}
|
||||
|
||||
private fun getGameOptionsTable() {
|
||||
top()
|
||||
defaults().pad(5f)
|
||||
|
||||
|
@ -46,26 +53,27 @@ class NewGameOptionsTable(newGameScreen: NewGameScreen, val updatePlayerPickerTa
|
|||
private fun Table.addCheckbox(text: String, initialState: Boolean, onChange: (newValue: Boolean) -> Unit) {
|
||||
val checkbox = CheckBox(text.tr(), CameraStageBaseScreen.skin)
|
||||
checkbox.isChecked = initialState
|
||||
checkbox.isDisabled = locked
|
||||
checkbox.onChange { onChange(checkbox.isChecked) }
|
||||
add(checkbox).colspan(2).left().row()
|
||||
}
|
||||
|
||||
private fun Table.addBarbariansCheckbox() =
|
||||
addCheckbox("No Barbarians", newGameParameters.noBarbarians)
|
||||
{ newGameParameters.noBarbarians = it }
|
||||
addCheckbox("No Barbarians", gameParameters.noBarbarians)
|
||||
{ gameParameters.noBarbarians = it }
|
||||
|
||||
private fun Table.addOneCityChallengeCheckbox() =
|
||||
addCheckbox("One City Challenge", newGameParameters.oneCityChallenge)
|
||||
{ newGameParameters.oneCityChallenge = it }
|
||||
addCheckbox("One City Challenge", gameParameters.oneCityChallenge)
|
||||
{ gameParameters.oneCityChallenge = it }
|
||||
|
||||
private fun Table.addNuclearWeaponsCheckbox() =
|
||||
addCheckbox("Enable nuclear weapons", newGameParameters.nuclearWeaponsEnabled)
|
||||
{ newGameParameters.nuclearWeaponsEnabled = it }
|
||||
addCheckbox("Enable nuclear weapons", gameParameters.nuclearWeaponsEnabled)
|
||||
{ gameParameters.nuclearWeaponsEnabled = it }
|
||||
|
||||
|
||||
private fun Table.addIsOnlineMultiplayerCheckbox() =
|
||||
addCheckbox("Online Multiplayer", newGameParameters.isOnlineMultiplayer)
|
||||
{ newGameParameters.isOnlineMultiplayer = it
|
||||
addCheckbox("Online Multiplayer", gameParameters.isOnlineMultiplayer)
|
||||
{ gameParameters.isOnlineMultiplayer = it
|
||||
updatePlayerPickerTable("") }
|
||||
|
||||
private fun addCityStatesSelectBox() {
|
||||
|
@ -78,34 +86,36 @@ class NewGameOptionsTable(newGameScreen: NewGameScreen, val updatePlayerPickerTa
|
|||
(0..numberOfCityStates).forEach { cityStatesArray.add(it) }
|
||||
|
||||
cityStatesSelectBox.items = cityStatesArray
|
||||
cityStatesSelectBox.selected = newGameParameters.numberOfCityStates
|
||||
cityStatesSelectBox.selected = gameParameters.numberOfCityStates
|
||||
add(cityStatesSelectBox).width(50f).row()
|
||||
cityStatesSelectBox.isDisabled = locked
|
||||
cityStatesSelectBox.onChange {
|
||||
newGameParameters.numberOfCityStates = cityStatesSelectBox.selected
|
||||
gameParameters.numberOfCityStates = cityStatesSelectBox.selected
|
||||
}
|
||||
}
|
||||
|
||||
fun Table.addSelectBox(text: String, values: Collection<String>, initialState: String, onChange: (newValue: String) -> Unit) {
|
||||
add(text.toLabel()).left()
|
||||
val selectBox = TranslatedSelectBox(values, initialState, CameraStageBaseScreen.skin)
|
||||
selectBox.isDisabled = locked
|
||||
selectBox.onChange { onChange(selectBox.selected.value) }
|
||||
add(selectBox).fillX().row()
|
||||
}
|
||||
|
||||
private fun Table.addDifficultySelectBox() {
|
||||
addSelectBox("{Difficulty}:", ruleset.difficulties.keys, newGameParameters.difficulty)
|
||||
{ newGameParameters.difficulty = it }
|
||||
addSelectBox("{Difficulty}:", ruleset.difficulties.keys, gameParameters.difficulty)
|
||||
{ gameParameters.difficulty = it }
|
||||
}
|
||||
|
||||
private fun Table.addGameSpeedSelectBox() {
|
||||
addSelectBox("{Game Speed}:", GameSpeed.values().map { it.name }, newGameParameters.gameSpeed.name)
|
||||
{ newGameParameters.gameSpeed = GameSpeed.valueOf(it) }
|
||||
addSelectBox("{Game Speed}:", GameSpeed.values().map { it.name }, gameParameters.gameSpeed.name)
|
||||
{ gameParameters.gameSpeed = GameSpeed.valueOf(it) }
|
||||
}
|
||||
|
||||
private fun Table.addEraSelectBox() {
|
||||
val eras = ruleset.technologies.values.map { it.era() }.distinct()
|
||||
addSelectBox("{Starting Era}:", eras, newGameParameters.startingEra)
|
||||
{ newGameParameters.startingEra = it }
|
||||
addSelectBox("{Starting Era}:", eras, gameParameters.startingEra)
|
||||
{ gameParameters.startingEra = it }
|
||||
}
|
||||
|
||||
|
||||
|
@ -119,13 +129,14 @@ class NewGameOptionsTable(newGameScreen: NewGameScreen, val updatePlayerPickerTa
|
|||
if (victoryType == VictoryType.Neutral) continue
|
||||
val victoryCheckbox = CheckBox(victoryType.name.tr(), CameraStageBaseScreen.skin)
|
||||
victoryCheckbox.name = victoryType.name
|
||||
victoryCheckbox.isChecked = newGameParameters.victoryTypes.contains(victoryType)
|
||||
victoryCheckbox.isChecked = gameParameters.victoryTypes.contains(victoryType)
|
||||
victoryCheckbox.isDisabled = locked
|
||||
victoryCheckbox.onChange {
|
||||
// If the checkbox is checked, adds the victoryTypes else remove it
|
||||
if (victoryCheckbox.isChecked) {
|
||||
newGameParameters.victoryTypes.add(victoryType)
|
||||
gameParameters.victoryTypes.add(victoryType)
|
||||
} else {
|
||||
newGameParameters.victoryTypes.remove(victoryType)
|
||||
gameParameters.victoryTypes.remove(victoryType)
|
||||
}
|
||||
}
|
||||
victoryConditionsTable.add(victoryCheckbox).left()
|
||||
|
@ -141,9 +152,9 @@ class NewGameOptionsTable(newGameScreen: NewGameScreen, val updatePlayerPickerTa
|
|||
|
||||
fun reloadMods() {
|
||||
ruleset.clear()
|
||||
val newRuleset = RulesetCache.getComplexRuleset(newGameParameters.mods)
|
||||
val newRuleset = RulesetCache.getComplexRuleset(gameParameters.mods)
|
||||
ruleset.add(newRuleset)
|
||||
ruleset.mods += newGameParameters.mods
|
||||
ruleset.mods += gameParameters.mods
|
||||
ruleset.modOptions = newRuleset.modOptions
|
||||
|
||||
ImageGetter.ruleset = ruleset
|
||||
|
@ -154,10 +165,11 @@ class NewGameOptionsTable(newGameScreen: NewGameScreen, val updatePlayerPickerTa
|
|||
val modCheckboxTable = Table().apply { defaults().pad(5f) }
|
||||
for (mod in modRulesets) {
|
||||
val checkBox = CheckBox(mod.name.tr(), CameraStageBaseScreen.skin)
|
||||
if (mod.name in newGameParameters.mods) checkBox.isChecked = true
|
||||
checkBox.isDisabled = locked
|
||||
if (mod.name in gameParameters.mods) checkBox.isChecked = true
|
||||
checkBox.onChange {
|
||||
if (checkBox.isChecked) newGameParameters.mods.add(mod.name)
|
||||
else newGameParameters.mods.remove(mod.name)
|
||||
if (checkBox.isChecked) gameParameters.mods.add(mod.name)
|
||||
else gameParameters.mods.remove(mod.name)
|
||||
reloadMods()
|
||||
var desiredCiv = ""
|
||||
if (checkBox.isChecked) {
|
|
@ -0,0 +1,11 @@
|
|||
package com.unciv.ui.newgamescreen
|
||||
|
||||
import com.badlogic.gdx.scenes.scene2d.Stage
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.ui.pickerscreens.PickerScreen
|
||||
import com.unciv.ui.utils.CameraStageBaseScreen
|
||||
|
||||
abstract class GameParametersPreviousScreen: PickerScreen() {
|
||||
abstract var gameSetupInfo: GameSetupInfo
|
||||
abstract val ruleset: Ruleset
|
||||
}
|
|
@ -15,10 +15,10 @@ class MapOptionsTable(val newGameScreen: NewGameScreen): Table() {
|
|||
private var mapTypeSpecificTable = Table()
|
||||
private val generatedMapOptionsTable = MapParametersTable(mapParameters)
|
||||
private val savedMapOptionsTable = Table()
|
||||
private val savedScenarioOptionsTable = Table()
|
||||
|
||||
init {
|
||||
defaults().pad(5f)
|
||||
|
||||
add("Map Options".toLabel(fontSize = 24)).top().padBottom(20f).colspan(2).row()
|
||||
addMapTypeSelection()
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ class MapOptionsTable(val newGameScreen: NewGameScreen): Table() {
|
|||
add("{Map Type}:".toLabel())
|
||||
val mapTypes = arrayListOf("Generated")
|
||||
if (MapSaver.getMaps().isNotEmpty()) mapTypes.add(MapType.custom)
|
||||
if (MapSaver.getScenarios().isNotEmpty()) mapTypes.add(MapType.scenario)
|
||||
val mapTypeSelectBox = TranslatedSelectBox(mapTypes, "Generated", CameraStageBaseScreen.skin)
|
||||
|
||||
val mapFileSelectBox = getMapFileSelectBox()
|
||||
|
@ -37,16 +38,39 @@ class MapOptionsTable(val newGameScreen: NewGameScreen): Table() {
|
|||
savedMapOptionsTable.add(mapFileSelectBox).maxWidth(newGameScreen.stage.width / 2)
|
||||
.right().row()
|
||||
|
||||
val scenarioFileSelectBox = getScenarioFileSelectBox()
|
||||
savedScenarioOptionsTable.defaults().pad(5f)
|
||||
savedScenarioOptionsTable.add("{Scenario file}:".toLabel()).left()
|
||||
// because SOME people gotta give the hugest names to their maps
|
||||
savedScenarioOptionsTable.add(scenarioFileSelectBox).maxWidth(newGameScreen.stage.width / 2)
|
||||
.right().row()
|
||||
|
||||
fun updateOnMapTypeChange() {
|
||||
mapTypeSpecificTable.clear()
|
||||
if (mapTypeSelectBox.selected.value == MapType.custom) {
|
||||
mapParameters.type = MapType.custom
|
||||
mapParameters.name = mapFileSelectBox.selected
|
||||
mapTypeSpecificTable.add(savedMapOptionsTable)
|
||||
newGameScreen.gameSetupInfo = GameSetupInfo()
|
||||
newGameScreen.unlockTables()
|
||||
newGameScreen.updateTables()
|
||||
} else if (mapTypeSelectBox.selected.value == MapType.scenario) {
|
||||
mapParameters.type = MapType.scenario
|
||||
mapParameters.name = scenarioFileSelectBox.selected
|
||||
mapTypeSpecificTable.add(savedScenarioOptionsTable)
|
||||
val scenario = MapSaver.loadScenario(mapParameters.name)
|
||||
newGameScreen.gameSetupInfo.gameParameters = scenario.gameParameters
|
||||
newGameScreen.gameSetupInfo.mapParameters = mapParameters
|
||||
// update PlayerTable and GameOptionsTable
|
||||
newGameScreen.lockTables()
|
||||
newGameScreen.updateTables()
|
||||
} else {
|
||||
mapParameters.name = ""
|
||||
mapParameters.type = generatedMapOptionsTable.mapTypeSelectBox.selected.value
|
||||
mapTypeSpecificTable.add(generatedMapOptionsTable)
|
||||
newGameScreen.gameSetupInfo = GameSetupInfo()
|
||||
newGameScreen.unlockTables()
|
||||
newGameScreen.updateTables()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,7 +83,6 @@ class MapOptionsTable(val newGameScreen: NewGameScreen): Table() {
|
|||
add(mapTypeSpecificTable).colspan(2).row()
|
||||
}
|
||||
|
||||
|
||||
private fun getMapFileSelectBox(): SelectBox<String> {
|
||||
val mapFileSelectBox = SelectBox<String>(CameraStageBaseScreen.skin)
|
||||
val mapNames = Array<String>()
|
||||
|
@ -71,4 +94,21 @@ class MapOptionsTable(val newGameScreen: NewGameScreen): Table() {
|
|||
return mapFileSelectBox
|
||||
}
|
||||
|
||||
private fun getScenarioFileSelectBox(): SelectBox<String> {
|
||||
val scenarioFileSelectBox = SelectBox<String>(CameraStageBaseScreen.skin)
|
||||
val scenarioNames = Array<String>()
|
||||
for (scenarioName in MapSaver.getScenarios()) scenarioNames.add(scenarioName)
|
||||
scenarioFileSelectBox.items = scenarioNames
|
||||
if (mapParameters.name in scenarioNames) scenarioFileSelectBox.selected = mapParameters.name
|
||||
|
||||
scenarioFileSelectBox.onChange {
|
||||
mapParameters.name = scenarioFileSelectBox.selected!!
|
||||
val scenario = MapSaver.loadScenario(mapParameters.name)
|
||||
newGameScreen.gameSetupInfo.gameParameters = scenario.gameParameters
|
||||
newGameScreen.updateTables()
|
||||
}
|
||||
return scenarioFileSelectBox
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -2,20 +2,18 @@ package com.unciv.ui.newgamescreen
|
|||
|
||||
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.CheckBox
|
||||
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.UncivGame
|
||||
import com.unciv.logic.GameInfo
|
||||
import com.unciv.logic.GameSaver
|
||||
import com.unciv.logic.GameStarter
|
||||
import com.unciv.logic.IdChecker
|
||||
import com.unciv.logic.*
|
||||
import com.unciv.logic.civilization.PlayerType
|
||||
import com.unciv.logic.map.MapParameters
|
||||
import com.unciv.logic.map.MapType
|
||||
import com.unciv.models.metadata.GameParameters
|
||||
import com.unciv.models.ruleset.RulesetCache
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.pickerscreens.PickerScreen
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.worldscreen.mainmenu.OnlineMultiplayer
|
||||
import java.util.*
|
||||
|
@ -27,18 +25,21 @@ class GameSetupInfo(var gameId:String, var gameParameters: GameParameters, var m
|
|||
constructor(gameInfo: GameInfo) : this("", gameInfo.gameParameters.clone(), gameInfo.tileMap.mapParameters)
|
||||
}
|
||||
|
||||
class NewGameScreen(previousScreen:CameraStageBaseScreen, _gameSetupInfo: GameSetupInfo?=null): PickerScreen() {
|
||||
class NewGameScreen(previousScreen:CameraStageBaseScreen, _gameSetupInfo: GameSetupInfo?=null): GameParametersPreviousScreen() {
|
||||
|
||||
var gameSetupInfo: GameSetupInfo = _gameSetupInfo ?: GameSetupInfo()
|
||||
val ruleset = RulesetCache.getComplexRuleset(gameSetupInfo.gameParameters.mods)
|
||||
override var gameSetupInfo: GameSetupInfo = _gameSetupInfo ?: GameSetupInfo()
|
||||
override val ruleset = RulesetCache.getComplexRuleset(gameSetupInfo.gameParameters.mods)
|
||||
var playerPickerTable = PlayerPickerTable(this, gameSetupInfo.gameParameters)
|
||||
var newGameOptionsTable = GameOptionsTable(this) { desiredCiv: String -> playerPickerTable.update(desiredCiv) }
|
||||
var mapOptionsTable = MapOptionsTable(this)
|
||||
|
||||
init {
|
||||
setDefaultCloseAction(previousScreen)
|
||||
scrollPane.setScrollingDisabled(true, true)
|
||||
|
||||
val playerPickerTable = PlayerPickerTable(this, gameSetupInfo.gameParameters)
|
||||
val newGameOptionsTable = NewGameOptionsTable(this) { desiredCiv: String -> playerPickerTable.update(desiredCiv) }
|
||||
topTable.add(ScrollPane(MapOptionsTable(this)).apply { setOverscroll(false, false) })
|
||||
// val playerPickerTable = PlayerPickerTable(this, gameSetupInfo.gameParameters)
|
||||
// val newGameOptionsTable = GameOptionsTable(this) { desiredCiv: String -> playerPickerTable.update(desiredCiv) }
|
||||
topTable.add(ScrollPane(mapOptionsTable).apply { setOverscroll(false, false) })
|
||||
.maxHeight(topTable.parent.height).width(stage.width / 3).padTop(20f).top()
|
||||
topTable.addSeparatorVertical()
|
||||
topTable.add(playerPickerTable).maxHeight(topTable.parent.height).width(stage.width / 3).padTop(20f).top()
|
||||
|
@ -124,11 +125,27 @@ class NewGameScreen(previousScreen:CameraStageBaseScreen, _gameSetupInfo: GameSe
|
|||
Gdx.graphics.requestRendering()
|
||||
}
|
||||
|
||||
fun setNewGameButtonEnabled(bool: Boolean) {
|
||||
if (bool) rightSideButton.enable()
|
||||
else rightSideButton.disable()
|
||||
// fun setNewGameButtonEnabled(bool: Boolean) {
|
||||
// if (bool) rightSideButton.enable()
|
||||
// else rightSideButton.disable()
|
||||
// }
|
||||
|
||||
fun lockTables() {
|
||||
playerPickerTable.locked = true
|
||||
newGameOptionsTable.locked = true
|
||||
}
|
||||
|
||||
fun unlockTables() {
|
||||
playerPickerTable.locked = false
|
||||
newGameOptionsTable.locked = false
|
||||
}
|
||||
|
||||
fun updateTables() {
|
||||
playerPickerTable.gameParameters = gameSetupInfo.gameParameters
|
||||
playerPickerTable.update()
|
||||
newGameOptionsTable.gameParameters = gameSetupInfo.gameParameters
|
||||
newGameOptionsTable.update()
|
||||
}
|
||||
|
||||
var newGame: GameInfo? = null
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ 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.Table
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextField
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.Constants
|
||||
|
@ -20,10 +19,12 @@ import com.unciv.models.translations.tr
|
|||
import com.unciv.ui.utils.*
|
||||
import java.util.*
|
||||
|
||||
class PlayerPickerTable(val newGameScreen: NewGameScreen, val newGameParameters: GameParameters): Table() {
|
||||
class PlayerPickerTable(val previousScreen: GameParametersPreviousScreen, var gameParameters: GameParameters): Table() {
|
||||
val playerListTable = Table()
|
||||
val nationsPopupWidth = newGameScreen.stage.width / 2f
|
||||
val civBlocksWidth = newGameScreen.stage.width / 3
|
||||
val nationsPopupWidth = previousScreen.stage.width / 2f
|
||||
val civBlocksWidth = previousScreen.stage.width / 3
|
||||
var locked = false
|
||||
|
||||
|
||||
init {
|
||||
top()
|
||||
|
@ -34,36 +35,37 @@ class PlayerPickerTable(val newGameScreen: NewGameScreen, val newGameParameters:
|
|||
|
||||
fun update(desiredCiv: String = "") {
|
||||
playerListTable.clear()
|
||||
val gameBasics = newGameScreen.ruleset // the mod picking changes this ruleset
|
||||
val gameBasics = previousScreen.ruleset // the mod picking changes this ruleset
|
||||
|
||||
reassignRemovedModReferences()
|
||||
val newRulesetPlayableCivs = newGameScreen.ruleset.nations.count { it.key != Constants.barbarians }
|
||||
if (newGameParameters.players.size > newRulesetPlayableCivs)
|
||||
newGameParameters.players = ArrayList(newGameParameters.players.subList(0, newRulesetPlayableCivs))
|
||||
val newRulesetPlayableCivs = previousScreen.ruleset.nations.count { it.key != Constants.barbarians }
|
||||
if (gameParameters.players.size > newRulesetPlayableCivs)
|
||||
gameParameters.players = ArrayList(gameParameters.players.subList(0, newRulesetPlayableCivs))
|
||||
if (desiredCiv.isNotEmpty()) assignDesiredCiv(desiredCiv)
|
||||
|
||||
for (player in newGameParameters.players) {
|
||||
for (player in gameParameters.players) {
|
||||
playerListTable.add(getPlayerTable(player, gameBasics)).width(civBlocksWidth).padBottom(20f).row()
|
||||
}
|
||||
if (newGameParameters.players.count() < gameBasics.nations.values.count { it.isMajorCiv() }) {
|
||||
if (gameParameters.players.count() < gameBasics.nations.values.count { it.isMajorCiv() }
|
||||
&& !locked) {
|
||||
playerListTable.add("+".toLabel(Color.BLACK, 30).apply { this.setAlignment(Align.center) }
|
||||
.surroundWithCircle(50f).onClick { newGameParameters.players.add(Player()); update() }).pad(10f)
|
||||
.surroundWithCircle(50f).onClick { gameParameters.players.add(Player()); update() }).pad(10f)
|
||||
}
|
||||
newGameScreen.setNewGameButtonEnabled(newGameParameters.players.size > 1)
|
||||
previousScreen.setRightSideButtonEnabled(gameParameters.players.size > 1)
|
||||
}
|
||||
|
||||
private fun reassignRemovedModReferences() {
|
||||
for (player in newGameParameters.players) {
|
||||
if (!newGameScreen.ruleset.nations.containsKey(player.chosenCiv))
|
||||
for (player in gameParameters.players) {
|
||||
if (!previousScreen.ruleset.nations.containsKey(player.chosenCiv))
|
||||
player.chosenCiv = "Random"
|
||||
}
|
||||
}
|
||||
|
||||
private fun assignDesiredCiv(desiredCiv: String) {
|
||||
// No auto-select if desiredCiv already used
|
||||
if (newGameParameters.players.any { it.chosenCiv == desiredCiv }) return
|
||||
if (gameParameters.players.any { it.chosenCiv == desiredCiv }) return
|
||||
// Do auto-select, silently no-op if no suitable slot (human with 'random' choice)
|
||||
newGameParameters.players.firstOrNull { it.chosenCiv == "Random" && it.playerType == PlayerType.Human }?.chosenCiv = desiredCiv
|
||||
gameParameters.players.firstOrNull { it.chosenCiv == "Random" && it.playerType == PlayerType.Human }?.chosenCiv = desiredCiv
|
||||
}
|
||||
|
||||
fun getPlayerTable(player: Player, ruleset: Ruleset): Table {
|
||||
|
@ -76,16 +78,19 @@ class PlayerPickerTable(val newGameScreen: NewGameScreen, val newGameParameters:
|
|||
|
||||
val playerTypeTextbutton = player.playerType.name.toTextButton()
|
||||
playerTypeTextbutton.onClick {
|
||||
if (locked) return@onClick
|
||||
if (player.playerType == PlayerType.AI)
|
||||
player.playerType = PlayerType.Human
|
||||
else player.playerType = PlayerType.AI
|
||||
update()
|
||||
}
|
||||
playerTable.add(playerTypeTextbutton).width(100f).pad(5f).right()
|
||||
playerTable.add("-".toLabel(Color.BLACK, 30).apply { this.setAlignment(Align.center) }
|
||||
.surroundWithCircle(40f)
|
||||
.onClick { newGameParameters.players.remove(player); update() }).pad(5f).right().row()
|
||||
if (newGameParameters.isOnlineMultiplayer && player.playerType == PlayerType.Human) {
|
||||
if (!locked) {
|
||||
playerTable.add("-".toLabel(Color.BLACK, 30).apply { this.setAlignment(Align.center) }
|
||||
.surroundWithCircle(40f)
|
||||
.onClick { gameParameters.players.remove(player); update() }).pad(5f).right().row()
|
||||
}
|
||||
if (gameParameters.isOnlineMultiplayer && player.playerType == PlayerType.Human) {
|
||||
|
||||
val playerIdTextfield = TextField(player.playerId, CameraStageBaseScreen.skin)
|
||||
playerIdTextfield.messageText = "Please input Player ID!".tr()
|
||||
|
@ -129,7 +134,7 @@ class PlayerPickerTable(val newGameScreen: NewGameScreen, val newGameParameters:
|
|||
.apply { this.setAlignment(Align.center) }
|
||||
.surroundWithCircle(36f).apply { circle.color = Color.BLACK }
|
||||
.surroundWithCircle(40f, false).apply { circle.color = Color.WHITE }
|
||||
else ImageGetter.getNationIndicator(newGameScreen.ruleset.nations[player.chosenCiv]!!, 40f)
|
||||
else ImageGetter.getNationIndicator(previousScreen.ruleset.nations[player.chosenCiv]!!, 40f)
|
||||
nationTable.add(nationImage).pad(5f)
|
||||
nationTable.add(player.chosenCiv.toLabel()).pad(5f)
|
||||
nationTable.touchable = Touchable.enabled
|
||||
|
@ -140,7 +145,7 @@ class PlayerPickerTable(val newGameScreen: NewGameScreen, val newGameParameters:
|
|||
}
|
||||
|
||||
private fun popupNationPicker(player: Player) {
|
||||
val nationsPopup = Popup(newGameScreen)
|
||||
val nationsPopup = Popup(previousScreen)
|
||||
val nationListTable = Table()
|
||||
|
||||
val randomPlayerTable = Table()
|
||||
|
@ -160,18 +165,18 @@ class PlayerPickerTable(val newGameScreen: NewGameScreen, val newGameParameters:
|
|||
nationListTable.add(randomPlayerTable).pad(10f).width(nationsPopupWidth).row()
|
||||
|
||||
|
||||
for (nation in newGameScreen.ruleset.nations.values
|
||||
for (nation in previousScreen.ruleset.nations.values
|
||||
.filter { !it.isCityState() && it.name != Constants.barbarians }) {
|
||||
if (player.chosenCiv != nation.name && newGameParameters.players.any { it.chosenCiv == nation.name })
|
||||
if (player.chosenCiv != nation.name && gameParameters.players.any { it.chosenCiv == nation.name })
|
||||
continue
|
||||
|
||||
nationListTable.add(NationTable(nation, nationsPopupWidth, newGameScreen.ruleset).onClick {
|
||||
nationListTable.add(NationTable(nation, nationsPopupWidth, previousScreen.ruleset).onClick {
|
||||
player.chosenCiv = nation.name
|
||||
nationsPopup.close()
|
||||
update()
|
||||
}).pad(10f).width(nationsPopupWidth).row()
|
||||
}
|
||||
nationsPopup.add(ScrollPane(nationListTable)).height(newGameScreen.stage.height * 0.8f)
|
||||
nationsPopup.add(ScrollPane(nationListTable)).height(previousScreen.stage.height * 0.8f)
|
||||
nationsPopup.pack()
|
||||
|
||||
val closeImage = ImageGetter.getImage("OtherIcons/Close")
|
||||
|
|
|
@ -53,6 +53,11 @@ open class PickerScreen : CameraStageBaseScreen() {
|
|||
}
|
||||
}
|
||||
|
||||
fun setRightSideButtonEnabled(bool: Boolean) {
|
||||
if (bool) rightSideButton.enable()
|
||||
else rightSideButton.disable()
|
||||
}
|
||||
|
||||
protected fun pick(rightButtonText: String) {
|
||||
if(UncivGame.Current.worldScreen.isPlayersTurn) rightSideButton.enable()
|
||||
rightSideButton.setText(rightButtonText)
|
||||
|
|
|
@ -39,7 +39,9 @@ class BasicTests {
|
|||
Assert.assertTrue("This test will only pass if the game is not run with debug modes",
|
||||
!game.superchargedForDebug
|
||||
&& !game.viewEntireMapForDebug
|
||||
&& game.simulateUntilTurnForDebug <= 0)
|
||||
&& game.simulateUntilTurnForDebug <= 0
|
||||
&& game.simulateUntilWinOrLose <= 0
|
||||
&& !game.scenarioDebugSwitch)
|
||||
}
|
||||
|
||||
// If there's a unit that obsoletes with no upgrade then when it obsoletes
|
||||
|
|
Loading…
Reference in a new issue