Removed Scenario Maps entirely - was not a well thought-out concept and caused more confusion than actual fun.

Case in point - 0 mods are Scenario mods.
This commit is contained in:
Yair Morgenstern 2021-02-11 22:33:52 +02:00
parent 74cc421b62
commit 8b1778eea3
23 changed files with 147 additions and 430 deletions

View File

@ -234,10 +234,6 @@ Reset to default =
HIGHLY EXPERIMENTAL - YOU HAVE BEEN WARNED! = HIGHLY EXPERIMENTAL - YOU HAVE BEEN WARNED! =
Online Multiplayer = Online Multiplayer =
Scenario Editor =
Scenario file =
Scenario Map =
Scenario =
World Size = World Size =
Tiny = Tiny =
@ -322,8 +318,6 @@ Delete save =
Saved at = Saved at =
Load map = Load map =
Delete map = Delete map =
Load Scenario Map =
Delete Scenario Map =
Are you sure you want to delete this map? = Are you sure you want to delete this map? =
Upload map = Upload map =
Could not upload map! = Could not upload map! =
@ -775,11 +769,8 @@ Improvements =
Clear current map = Clear current map =
Save map = Save map =
Download map = Download map =
Toggle Scenario Map =
Loading... = Loading... =
Filter: = Filter: =
Create scenario map =
Edit scenario parameters =
OK = OK =
Exit map editor = Exit map editor =
[nation] starting location = [nation] starting location =

View File

@ -22,9 +22,7 @@ object GameStarter {
gameInfo.gameParameters = gameSetupInfo.gameParameters gameInfo.gameParameters = gameSetupInfo.gameParameters
val ruleset = RulesetCache.getComplexRuleset(gameInfo.gameParameters) val ruleset = RulesetCache.getComplexRuleset(gameInfo.gameParameters)
if (gameSetupInfo.mapParameters.type == MapType.scenarioMap) if (gameSetupInfo.mapParameters.name != "") {
gameInfo.tileMap = MapSaver.loadScenario(gameSetupInfo.mapParameters.name).tileMap
else if (gameSetupInfo.mapParameters.name != "") {
gameInfo.tileMap = MapSaver.loadMap(gameSetupInfo.mapFile!!) gameInfo.tileMap = MapSaver.loadMap(gameSetupInfo.mapFile!!)
} else gameInfo.tileMap = MapGenerator(ruleset).generateMap(gameSetupInfo.mapParameters) } else gameInfo.tileMap = MapGenerator(ruleset).generateMap(gameSetupInfo.mapParameters)
gameInfo.tileMap.mapParameters = gameSetupInfo.mapParameters gameInfo.tileMap.mapParameters = gameSetupInfo.mapParameters
@ -51,8 +49,7 @@ object GameStarter {
addCivTechs(gameInfo, ruleset, gameSetupInfo) addCivTechs(gameInfo, ruleset, gameSetupInfo)
// and only now do we add units for everyone, because otherwise both the gameInfo.setTransients() and the placeUnit will both add the unit to the civ's unit list! // and only now do we add units for everyone, because otherwise both the gameInfo.setTransients() and the placeUnit will both add the unit to the civ's unit list!
if (gameSetupInfo.mapParameters.type != MapType.scenarioMap) addCivStartingUnits(gameInfo)
addCivStartingUnits(gameInfo)
// remove starting locations once we're done // remove starting locations once we're done
for (tile in gameInfo.tileMap.values) { for (tile in gameInfo.tileMap.values) {

View File

@ -2,7 +2,6 @@ package com.unciv.logic
import com.badlogic.gdx.Gdx import com.badlogic.gdx.Gdx
import com.badlogic.gdx.files.FileHandle import com.badlogic.gdx.files.FileHandle
import com.unciv.logic.map.ScenarioMap
import com.unciv.logic.map.TileMap import com.unciv.logic.map.TileMap
import com.unciv.ui.saves.Gzip import com.unciv.ui.saves.Gzip
@ -11,42 +10,20 @@ object MapSaver {
fun json() = GameSaver.json() fun json() = GameSaver.json()
private const val mapsFolder = "maps" private const val mapsFolder = "maps"
private const val scenariosFolder = "scenarios"
private fun getMap(mapName:String) = Gdx.files.local("$mapsFolder/$mapName") 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) { fun saveMap(mapName: String,tileMap: TileMap) {
getMap(mapName).writeString(Gzip.zip(json().toJson(tileMap)), false) getMap(mapName).writeString(Gzip.zip(json().toJson(tileMap)), false)
} }
fun saveScenario(scenarioName:String, scenarioMap: ScenarioMap) { fun loadMap(mapFile:FileHandle):TileMap {
getScenario(scenarioName).writeString(Gzip.zip(json().toJson(scenarioMap)), false)
}
fun loadMap(mapName: String) = loadMap(getMap(mapName))
fun loadMap(mapFile:FileHandle):TileMap{
val gzippedString = mapFile.readString() val gzippedString = mapFile.readString()
val unzippedJson = Gzip.unzip(gzippedString) val unzippedJson = Gzip.unzip(gzippedString)
return json().fromJson(TileMap::class.java, unzippedJson) return json().fromJson(TileMap::class.java, unzippedJson)
} }
fun loadScenario(scenarioName: String) = loadScenario(getScenario(scenarioName))
fun loadScenario(scenarioFile: FileHandle): ScenarioMap {
val gzippedString = scenarioFile.readString()
val unzippedJson = Gzip.unzip(gzippedString)
return json().fromJson(ScenarioMap::class.java, unzippedJson)
}
fun deleteMap(mapName: String) = getMap(mapName).delete()
fun deleteScenario(scenarioName: String) = getScenario(scenarioName).delete()
fun getMaps() = Gdx.files.local(mapsFolder).list() fun getMaps() = Gdx.files.local(mapsFolder).list()
fun getScenarios() = Gdx.files.local(scenariosFolder).list()
fun mapFromJson(json:String): TileMap = json().fromJson(TileMap::class.java, json) fun mapFromJson(json:String): TileMap = json().fromJson(TileMap::class.java, json)
} }

View File

@ -192,7 +192,7 @@ object NextTurnAutomation {
VictoryType.Cultural -> listOf("Piety", "Freedom", "Tradition", "Rationalism", "Commerce") VictoryType.Cultural -> listOf("Piety", "Freedom", "Tradition", "Rationalism", "Commerce")
VictoryType.Scientific -> listOf("Rationalism", "Commerce", "Liberty", "Freedom", "Piety") VictoryType.Scientific -> listOf("Rationalism", "Commerce", "Liberty", "Freedom", "Piety")
VictoryType.Domination -> listOf("Autocracy", "Honor", "Liberty", "Rationalism", "Freedom") VictoryType.Domination -> listOf("Autocracy", "Honor", "Liberty", "Rationalism", "Freedom")
VictoryType.Neutral, VictoryType.Scenario -> listOf() VictoryType.Neutral -> listOf()
} }
val policiesByPreference = adoptablePolicies val policiesByPreference = adoptablePolicies
.groupBy { .groupBy {

View File

@ -333,15 +333,11 @@ class CivilizationInfo {
fun isDefeated(): Boolean { fun isDefeated(): Boolean {
// Dirty hack: exploredTiles are empty only before starting units are placed // Dirty hack: exploredTiles are empty only before starting units are placed
if (exploredTiles.isEmpty() || isBarbarian() || isSpectator()) return false if (exploredTiles.isEmpty() || isBarbarian() || isSpectator()) return false
// Scenarios are 'to the death'... for now
if (gameInfo.gameParameters.victoryTypes.contains(VictoryType.Scenario))
return cities.isEmpty() && getCivUnits().none()
else return cities.isEmpty() // No cities else return cities.isEmpty() // No cities
&& (citiesCreated > 0 || !getCivUnits().any { it.hasUnique(Constants.settlerUnique) }) && (citiesCreated > 0 || !getCivUnits().any { it.hasUnique(Constants.settlerUnique) })
} }
fun getEra(): String { fun getEra(): String {
// For scenarios with no techs
if (gameInfo.ruleSet.technologies.isEmpty()) return "None" if (gameInfo.ruleSet.technologies.isEmpty()) return "None"
if (tech.researchedTechnologies.isEmpty()) if (tech.researchedTechnologies.isEmpty())
return gameInfo.ruleSet.getEras().first() return gameInfo.ruleSet.getEras().first()
@ -353,9 +349,7 @@ class CivilizationInfo {
return maxEraOfTech return maxEraOfTech
} }
fun getEraNumber(): Int { fun getEraNumber(): Int = gameInfo.ruleSet.getEraNumber(getEra())
return gameInfo.ruleSet.getEraNumber(getEra())
}
fun isAtWarWith(otherCiv: CivilizationInfo): Boolean { fun isAtWarWith(otherCiv: CivilizationInfo): Boolean {
if (otherCiv.civName == civName) return false // never at war with itself if (otherCiv.civName == civName) return false // never at war with itself

View File

@ -39,8 +39,8 @@ class VictoryManager {
&& civInfo.policies.adoptedPolicies.count { it.endsWith("Complete") } > 4 && civInfo.policies.adoptedPolicies.count { it.endsWith("Complete") } > 4
fun hasWonDominationVictory(): Boolean { fun hasWonDominationVictory(): Boolean {
return (hasVictoryType(VictoryType.Domination) || hasVictoryType(VictoryType.Scenario)) && return hasVictoryType(VictoryType.Domination)
civInfo.gameInfo.civilizations.all { it == civInfo || it.isDefeated() || !it.isMajorCiv() } && civInfo.gameInfo.civilizations.all { it == civInfo || it.isDefeated() || !it.isMajorCiv() }
} }
fun hasWonVictoryType(): VictoryType? { fun hasWonVictoryType(): VictoryType? {

View File

@ -25,11 +25,6 @@ object MapType {
// Non-generated maps // Non-generated maps
const val custom = "Custom" const val custom = "Custom"
// Loaded scenario
const val scenarioMap = "Scenario Map"
const val scenario = "Scenario"
// All ocean tiles // All ocean tiles
const val empty = "Empty" const val empty = "Empty"
} }

View File

@ -1,16 +0,0 @@
package com.unciv.logic.map
import com.unciv.models.metadata.GameParameters
class ScenarioMap {
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
}
}

View File

@ -477,6 +477,35 @@ open class TileInfo {
return lineList.joinToString("\n") return lineList.joinToString("\n")
} }
fun hasEnemyInvisibleUnit(viewingCiv: CivilizationInfo): Boolean {
val unitsInTile = getUnits()
if (unitsInTile.none()) return false
if (unitsInTile.first().civInfo != viewingCiv &&
unitsInTile.firstOrNull { it.isInvisible() } != null) {
return true
}
return false
}
fun hasConnection(civInfo: CivilizationInfo) =
roadStatus != RoadStatus.None || forestOrJungleAreRoads(civInfo)
private fun forestOrJungleAreRoads(civInfo: CivilizationInfo) =
civInfo.nation.forestsAndJunglesAreRoads
&& (terrainFeature == Constants.jungle || terrainFeature == Constants.forest)
&& isFriendlyTerritory(civInfo)
fun isRulesetCompatible(ruleset: Ruleset): Boolean {
if (!ruleset.terrains.containsKey(baseTerrain)) return false
if (terrainFeature != null && !ruleset.terrains.containsKey(terrainFeature)) return false
if (resource != null && !ruleset.tileResources.containsKey(resource)) return false
if (improvement != null && !ruleset.tileImprovements.containsKey(baseTerrain)) return false
return true
}
//endregion //endregion
//region state-changing functions //region state-changing functions
@ -527,23 +556,5 @@ open class TileInfo {
turnsToImprovement = 0 turnsToImprovement = 0
} }
fun hasEnemyInvisibleUnit(viewingCiv: CivilizationInfo): Boolean {
val unitsInTile = getUnits()
if (unitsInTile.none()) return false
if (unitsInTile.first().civInfo != viewingCiv &&
unitsInTile.firstOrNull { it.isInvisible() } != null) {
return true
}
return false
}
fun hasConnection(civInfo: CivilizationInfo) =
roadStatus != RoadStatus.None || forestOrJungleAreRoads(civInfo)
private fun forestOrJungleAreRoads(civInfo: CivilizationInfo) =
civInfo.nation.forestsAndJunglesAreRoads
&& (terrainFeature == Constants.jungle || terrainFeature == Constants.forest)
&& isFriendlyTerritory(civInfo)
//endregion //endregion
} }

View File

@ -14,16 +14,22 @@ class TileMap {
@Transient @Transient
lateinit var gameInfo: GameInfo lateinit var gameInfo: GameInfo
@Transient @Transient
var tileMatrix = ArrayList<ArrayList<TileInfo?>>() // this works several times faster than a hashmap, the performance difference is really astounding var tileMatrix = ArrayList<ArrayList<TileInfo?>>() // this works several times faster than a hashmap, the performance difference is really astounding
@Transient @Transient
var leftX = 0 var leftX = 0
@Transient @Transient
var bottomY = 0 var bottomY = 0
@delegate:Transient @delegate:Transient
val maxLatitude: Float by lazy { if (values.isEmpty()) 0f else values.map { abs(it.latitude) }.max()!! } val maxLatitude: Float by lazy { if (values.isEmpty()) 0f else values.map { abs(it.latitude) }.max()!! }
@delegate:Transient @delegate:Transient
val maxLongitude: Float by lazy { if (values.isEmpty()) 0f else values.map { abs(it.longitude) }.max()!! } val maxLongitude: Float by lazy { if (values.isEmpty()) 0f else values.map { abs(it.longitude) }.max()!! }
@delegate:Transient @delegate:Transient
val naturalWonders: List<String> by lazy { tileList.asSequence().filter { it.isNaturalWonder() }.map { it.naturalWonder!! }.distinct().toList() } val naturalWonders: List<String> by lazy { tileList.asSequence().filter { it.isNaturalWonder() }.map { it.naturalWonder!! }.distinct().toList() }
@ -62,9 +68,7 @@ class TileMap {
return toReturn return toReturn
} }
operator fun contains(vector: Vector2): Boolean { operator fun contains(vector: Vector2) = contains(vector.x.toInt(), vector.y.toInt())
return contains(vector.x.toInt(), vector.y.toInt())
}
fun contains(x: Int, y: Int): Boolean { fun contains(x: Int, y: Int): Boolean {
val arrayXIndex = x - leftX val arrayXIndex = x - leftX
@ -270,10 +274,10 @@ class TileMap {
} }
fun setTransients(ruleset: Ruleset, setUnitCivTransients: Boolean = true) { // In the map editor, no Civs or Game exist, so we won't set the unit transients fun setTransients(ruleset: Ruleset, setUnitCivTransients: Boolean = true) { // In the map editor, no Civs or Game exist, so we won't set the unit transients
val topY = tileList.asSequence().map { it.position.y.toInt() }.max()!! val topY = tileList.asSequence().map { it.position.y.toInt() }.maxOrNull()!!
bottomY = tileList.asSequence().map { it.position.y.toInt() }.min()!! bottomY = tileList.asSequence().map { it.position.y.toInt() }.minOrNull()!!
val rightX = tileList.asSequence().map { it.position.x.toInt() }.max()!! val rightX = tileList.asSequence().map { it.position.x.toInt() }.maxOrNull()!!
leftX = tileList.asSequence().map { it.position.x.toInt() }.min()!! leftX = tileList.asSequence().map { it.position.x.toInt() }.minOrNull()!!
for (x in leftX..rightX) { for (x in leftX..rightX) {
val row = ArrayList<TileInfo?>() val row = ArrayList<TileInfo?>()

View File

@ -21,7 +21,7 @@ class GameSettings {
var soundEffectsVolume = 0.5f var soundEffectsVolume = 0.5f
var musicVolume = 0.5f var musicVolume = 0.5f
var turnsBetweenAutosaves = 1 var turnsBetweenAutosaves = 1
var tileSet:String = "FantasyHex" var tileSet: String = "FantasyHex"
var showTutorials: Boolean = true var showTutorials: Boolean = true
var autoAssignCityProduction: Boolean = true var autoAssignCityProduction: Boolean = true
var autoBuildingRoads: Boolean = true var autoBuildingRoads: Boolean = true
@ -38,7 +38,6 @@ class GameSettings {
var orderTradeOffersByAmount = true var orderTradeOffersByAmount = true
var windowState = WindowState() var windowState = WindowState()
var isFreshlyCreated = false var isFreshlyCreated = false
var extendedMapEditor = false
init { init {
// 26 = Android Oreo. Versions below may display permanent icon in notification bar. // 26 = Android Oreo. Versions below may display permanent icon in notification bar.
@ -47,15 +46,15 @@ class GameSettings {
} }
} }
fun save(){ fun save() {
if (!isFreshlyCreated && Gdx.app?.type == Application.ApplicationType.Desktop) { if (!isFreshlyCreated && Gdx.app?.type == Application.ApplicationType.Desktop) {
windowState = WindowState( Gdx.graphics.width, Gdx.graphics.height) windowState = WindowState(Gdx.graphics.width, Gdx.graphics.height)
} }
GameSaver.setGeneralSettings(this) GameSaver.setGeneralSettings(this)
} }
fun addCompletedTutorialTask(tutorialTask:String){ fun addCompletedTutorialTask(tutorialTask: String) {
tutorialTasksCompleted.add(tutorialTask) tutorialTasksCompleted.add(tutorialTask)
save() save()
} }
} }

View File

@ -13,8 +13,7 @@ enum class VictoryType {
Neutral, Neutral,
Cultural, Cultural,
Domination, Domination,
Scientific, Scientific
Scenario
} }
class Nation : INamed { class Nation : INamed {

View File

@ -1,7 +1,6 @@
package com.unciv.ui.mapeditor package com.unciv.ui.mapeditor
import com.unciv.UncivGame import com.unciv.UncivGame
import com.unciv.logic.map.ScenarioMap
import com.unciv.models.ruleset.RulesetCache import com.unciv.models.ruleset.RulesetCache
import com.unciv.models.translations.tr import com.unciv.models.translations.tr
import com.unciv.ui.newgamescreen.GameOptionsTable import com.unciv.ui.newgamescreen.GameOptionsTable
@ -34,11 +33,10 @@ class GameParametersScreen(var mapEditorScreen: MapEditorScreen): IPreviousScree
rightSideButton.setText("OK".tr()) rightSideButton.setText("OK".tr())
rightSideButton.onClick { rightSideButton.onClick {
mapEditorScreen.gameSetupInfo = gameSetupInfo mapEditorScreen.gameSetupInfo = gameSetupInfo
mapEditorScreen.scenarioMap = ScenarioMap(mapEditorScreen.tileMap, mapEditorScreen.gameSetupInfo.gameParameters)
mapEditorScreen.ruleset.clear() mapEditorScreen.ruleset.clear()
mapEditorScreen.ruleset.add(ruleset) mapEditorScreen.ruleset.add(ruleset)
mapEditorScreen.tileEditorOptions.update() mapEditorScreen.tileEditorOptions.update()
// Remove resources that are not applicable to this scenario // Remove resources that are not applicable to this ruleset
for(tile in mapEditorScreen.tileMap.values) { for(tile in mapEditorScreen.tileMap.values) {
if (tile.resource != null && !ruleset.tileResources.containsKey(tile.resource!!)) if (tile.resource != null && !ruleset.tileResources.containsKey(tile.resource!!))
tile.resource = null tile.resource = null

View File

@ -5,7 +5,6 @@ import com.badlogic.gdx.files.FileHandle
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.scenes.scene2d.ui.TextButton import com.badlogic.gdx.scenes.scene2d.ui.TextButton
import com.badlogic.gdx.utils.Align
import com.unciv.MainMenuScreen import com.unciv.MainMenuScreen
import com.unciv.UncivGame import com.unciv.UncivGame
import com.unciv.logic.MapSaver import com.unciv.logic.MapSaver
@ -17,45 +16,25 @@ import com.unciv.ui.utils.*
import kotlin.concurrent.thread import kotlin.concurrent.thread
import com.unciv.ui.utils.AutoScrollPane as ScrollPane import com.unciv.ui.utils.AutoScrollPane as ScrollPane
class LoadMapScreen(previousMap: TileMap?) : PickerScreen(){ class LoadMapScreen(previousMap: TileMap?) : PickerScreen() {
var chosenMap:FileHandle? = null var chosenMap: FileHandle? = null
val deleteButton = "Delete map".toTextButton() val deleteButton = "Delete map".toTextButton()
var scenarioMap = false
val mapsTable = Table().apply { defaults().pad(10f) } val mapsTable = Table().apply { defaults().pad(10f) }
init { init {
if(UncivGame.Current.settings.extendedMapEditor) {
val toggleButton = "Toggle Scenario Map".toTextButton()
toggleButton.onClick {
scenarioMap = !scenarioMap
update()
}
toggleButton.centerX(stage)
toggleButton.setY(stage.height - 10f, Align.top)
stage.addActor(toggleButton)
}
rightSideButton.setText("Load map".tr()) rightSideButton.setText("Load map".tr())
rightSideButton.onClick { rightSideButton.onClick {
thread { thread {
if (scenarioMap) { Gdx.app.postRunnable {
val scenario = MapSaver.loadScenario(chosenMap!!) val popup = Popup(this)
Gdx.app.postRunnable { popup.addGoodSizedLabel("Loading...")
UncivGame.Current.setScreen(MapEditorScreen(scenario, chosenMap!!.name())) popup.open()
dispose() }
} val map = MapSaver.loadMap(chosenMap!!)
} else { Gdx.app.postRunnable {
Gdx.app.postRunnable { Gdx.input.inputProcessor = null // This is to stop ANRs happening here, until the map editor screen sets up.
val popup = Popup(this) UncivGame.Current.setScreen(MapEditorScreen(map))
popup.addGoodSizedLabel("Loading...") dispose()
popup.open()
}
val map = MapSaver.loadMap(chosenMap!!)
Gdx.app.postRunnable {
Gdx.input.inputProcessor = null // This is to stop ANRs happening here, until the map editor screen sets up.
UncivGame.Current.setScreen(MapEditorScreen(map))
dispose()
}
} }
} }
} }
@ -108,38 +87,22 @@ class LoadMapScreen(previousMap: TileMap?) : PickerScreen(){
deleteButton.disable() deleteButton.disable()
deleteButton.color = Color.RED deleteButton.color = Color.RED
if (scenarioMap) { deleteButton.setText("Delete map".tr())
deleteButton.setText("Delete Scenario Map".tr()) rightSideButton.setText("Load map".tr())
rightSideButton.setText("Load Scenario Map".tr())
mapsTable.clear() mapsTable.clear()
for (scenario in MapSaver.getScenarios()) { for (map in MapSaver.getMaps()) {
val loadScenarioButton = TextButton(scenario.name(), skin) val loadMapButton = TextButton(map.name(), skin)
loadScenarioButton.onClick { loadMapButton.onClick {
rightSideButton.enable() rightSideButton.enable()
chosenMap = scenario chosenMap = map
deleteButton.enable() deleteButton.enable()
deleteButton.color = Color.RED deleteButton.color = Color.RED
}
mapsTable.add(loadScenarioButton).row()
}
} else {
deleteButton.setText("Delete map".tr())
rightSideButton.setText("Load map".tr())
mapsTable.clear()
for (map in MapSaver.getMaps()) {
val loadMapButton = TextButton(map.name(), skin)
loadMapButton.onClick {
rightSideButton.enable()
chosenMap = map
deleteButton.enable()
deleteButton.color = Color.RED
}
mapsTable.add(loadMapButton).row()
} }
mapsTable.add(loadMapButton).row()
} }
} }
} }

View File

@ -9,9 +9,7 @@ import com.unciv.UncivGame
import com.unciv.logic.MapSaver import com.unciv.logic.MapSaver
import com.unciv.logic.map.MapType import com.unciv.logic.map.MapType
import com.unciv.logic.map.RoadStatus import com.unciv.logic.map.RoadStatus
import com.unciv.logic.map.ScenarioMap
import com.unciv.logic.map.TileMap import com.unciv.logic.map.TileMap
import com.unciv.models.translations.tr
import com.unciv.models.metadata.Player import com.unciv.models.metadata.Player
import com.unciv.ui.saves.Gzip import com.unciv.ui.saves.Gzip
import com.unciv.ui.utils.* import com.unciv.ui.utils.*
@ -34,7 +32,6 @@ class MapEditorMenuPopup(var mapEditorScreen: MapEditorScreen): Popup(mapEditorS
addCopyMapAsTextButton() addCopyMapAsTextButton()
addLoadMapButton() addLoadMapButton()
// addUploadMapButton() // addUploadMapButton()
if (UncivGame.Current.settings.extendedMapEditor) addScenarioButton()
addExitMapEditorButton() addExitMapEditorButton()
addCloseOptionsButton() addCloseOptionsButton()
} }
@ -79,18 +76,10 @@ class MapEditorMenuPopup(var mapEditorScreen: MapEditorScreen): Popup(mapEditorS
saveMapButton.onClick { saveMapButton.onClick {
mapEditorScreen.tileMap.mapParameters.name = mapEditorScreen.mapName mapEditorScreen.tileMap.mapParameters.name = mapEditorScreen.mapName
mapEditorScreen.tileMap.mapParameters.type = MapType.custom mapEditorScreen.tileMap.mapParameters.type = MapType.custom
thread(name = "SaveMap") { // this works for both scenarios and non-scenarios thread(name = "SaveMap") {
try { try {
if(mapEditorScreen.hasScenario()) { MapSaver.saveMap(mapEditorScreen.mapName, mapEditorScreen.tileMap)
mapEditorScreen.tileMap.mapParameters.type = MapType.scenarioMap
mapEditorScreen.scenarioMap = ScenarioMap(mapEditorScreen.tileMap, mapEditorScreen.gameSetupInfo.gameParameters)
mapEditorScreen.scenarioMap!!.gameParameters.godMode = true // so we can edit this scenario when loading from the map
mapEditorScreen.scenarioName = mapNameEditor.text
MapSaver.saveScenario(mapNameEditor.text, mapEditorScreen.scenarioMap!!)
}
else {
MapSaver.saveMap(mapEditorScreen.mapName, mapEditorScreen.tileMap)
}
close() close()
Gdx.app.postRunnable { Gdx.app.postRunnable {
ToastPopup("Map saved", mapEditorScreen) // todo - add this text to translations ToastPopup("Map saved", mapEditorScreen) // todo - add this text to translations
@ -162,25 +151,6 @@ class MapEditorMenuPopup(var mapEditorScreen: MapEditorScreen): Popup(mapEditorS
add(uploadMapButton).row() add(uploadMapButton).row()
} }
private fun Popup.addScenarioButton() {
var scenarioButton = "".toTextButton()
if (mapEditorScreen.hasScenario()) {
scenarioButton.setText("Edit scenario parameters".tr())
} else {
scenarioButton.setText("Create scenario map".tr())
// for newly created scenarios read players from tileMap
val players = getPlayersFromMap(mapEditorScreen.tileMap)
mapEditorScreen.gameSetupInfo.gameParameters.players = players
}
add(scenarioButton).row()
scenarioButton.onClick {
close()
UncivGame.Current.setScreen(GameParametersScreen(mapEditorScreen).apply {
playerPickerTable.noRandom = true
})
}
}
private fun Popup.addExitMapEditorButton() { private fun Popup.addExitMapEditorButton() {
val exitMapEditorButton = "Exit map editor".toTextButton() val exitMapEditorButton = "Exit map editor".toTextButton()

View File

@ -5,7 +5,6 @@ import com.badlogic.gdx.math.Vector2
import com.badlogic.gdx.scenes.scene2d.InputEvent import com.badlogic.gdx.scenes.scene2d.InputEvent
import com.badlogic.gdx.scenes.scene2d.InputListener import com.badlogic.gdx.scenes.scene2d.InputListener
import com.badlogic.gdx.scenes.scene2d.actions.Actions import com.badlogic.gdx.scenes.scene2d.actions.Actions
import com.unciv.logic.map.ScenarioMap
import com.unciv.logic.map.TileInfo import com.unciv.logic.map.TileInfo
import com.unciv.logic.map.TileMap import com.unciv.logic.map.TileMap
import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.Ruleset
@ -16,9 +15,7 @@ import com.unciv.ui.utils.*
class MapEditorScreen(): CameraStageBaseScreen() { class MapEditorScreen(): CameraStageBaseScreen() {
var mapName = "" var mapName = ""
var tileMap = TileMap() var tileMap = TileMap()
var scenarioName = "" // when loading map: mapName is taken as default for scenarioName var ruleset = Ruleset().apply { add(RulesetCache.getBaseRuleset()) }
var scenarioMap: ScenarioMap? = null // main indicator whether scenario information is present
var ruleset = Ruleset().apply { add(RulesetCache.getBaseRuleset()) } // Since we change this in scenarios, we can't take the base ruleset directly
var gameSetupInfo = GameSetupInfo() var gameSetupInfo = GameSetupInfo()
lateinit var mapHolder: EditorMapHolder lateinit var mapHolder: EditorMapHolder
@ -33,20 +30,6 @@ class MapEditorScreen(): CameraStageBaseScreen() {
initialize() initialize()
} }
constructor(scenarioMap: ScenarioMap, scenarioName: String = "") : this() {
tileMap = scenarioMap.tileMap
mapName = scenarioName
this.scenarioMap = scenarioMap
this.scenarioName = scenarioName
gameSetupInfo.gameParameters = scenarioMap.gameParameters
// Since the ruleset is referenced directly from other places, we can't just replace it directly
ruleset.clear()
ruleset.add(RulesetCache.getComplexRuleset(scenarioMap.gameParameters))
initialize()
}
fun initialize() { fun initialize() {
ImageGetter.setNewRuleset(ruleset) ImageGetter.setNewRuleset(ruleset)
tileMap.setTransients(ruleset,false) tileMap.setTransients(ruleset,false)
@ -152,8 +135,6 @@ class MapEditorScreen(): CameraStageBaseScreen() {
game.setScreen(MapEditorScreen(mapHolder.tileMap)) game.setScreen(MapEditorScreen(mapHolder.tileMap))
} }
} }
fun hasScenario() = this.scenarioMap != null
} }

View File

@ -56,12 +56,6 @@ class TileEditorOptionsTable(val mapEditorScreen: MapEditorScreen): Table(Camera
.onClick { setImprovements() } .onClick { setImprovements() }
tabPickerTable.add(improvementsButton) tabPickerTable.add(improvementsButton)
// debug Scenario mode
if (UncivGame.Current.settings.extendedMapEditor && mapEditorScreen.hasScenario()) {
val unitsButton = "Units".toTextButton().onClick { setUnits() }
tabPickerTable.add(unitsButton)
}
tabPickerTable.pack() tabPickerTable.pack()
val sliderTab = Table() val sliderTab = Table()
@ -160,59 +154,29 @@ class TileEditorOptionsTable(val mapEditorScreen: MapEditorScreen): Table(Camera
val nationTable = Table() val nationTable = Table()
if (UncivGame.Current.settings.extendedMapEditor) { /** old way improvements for all civs
/** new scenario/improvements functionality * */
* We shouldn't be able to edit random players or spectators for (nation in ruleset.nations.values) {
* */ if (nation.isSpectator()) continue // no improvements for spectator
for (player in gameParameters.players) {
val playerIndex = gameParameters.players.indexOf(player) + 1 val nationImage = getHex(Color.WHITE, ImageGetter.getNationIndicator(nation, 40f))
if (player.chosenCiv == Constants.random || player.chosenCiv == Constants.spectator) nationImage.onClick {
continue val improvementName = "StartingLocation " + nation.name
val nation = ruleset.nations[player.chosenCiv]!! tileAction = {
val nationImage = ImageGetter.getNationIndicator(nation, 40f) it.improvement = improvementName
nationImage.onClick { for (tileGroup in mapEditorScreen.mapHolder.tileGroups.values) {
val improvementName = "StartingLocation " + nation.name val tile = tileGroup.tileInfo
tileAction = { if (tile.improvement == improvementName && tile != it)
it.improvement = improvementName tile.improvement = null
for (tileGroup in mapEditorScreen.mapHolder.tileGroups.values) { tile.setTerrainTransients()
val tile = tileGroup.tileInfo tileGroup.update()
if (tile.improvement == improvementName && tile != it)
tile.improvement = null
tile.setTerrainTransients()
tileGroup.update()
}
} }
val nationIcon = getHex(Color.WHITE, ImageGetter.getNationIndicator(nation, 40f))
setCurrentHex(nationIcon, "Player [$playerIndex] starting location")
} }
nationTable.add(nationImage).row()
}
} else {
/** old way improvements for all civs
* */
for (nation in ruleset.nations.values) {
if (nation.isSpectator()) continue // no improvements for spectator
val nationImage = getHex(Color.WHITE, ImageGetter.getNationIndicator(nation, 40f)) val nationIcon = getHex(Color.WHITE, ImageGetter.getNationIndicator(nation, 40f))
nationImage.onClick { setCurrentHex(nationIcon, "[${nation.name}] starting location")
val improvementName = "StartingLocation " + nation.name
tileAction = {
it.improvement = improvementName
for (tileGroup in mapEditorScreen.mapHolder.tileGroups.values) {
val tile = tileGroup.tileInfo
if (tile.improvement == improvementName && tile != it)
tile.improvement = null
tile.setTerrainTransients()
tileGroup.update()
}
}
val nationIcon = getHex(Color.WHITE, ImageGetter.getNationIndicator(nation, 40f))
setCurrentHex(nationIcon, "[${nation.name}] starting location")
}
nationTable.add(nationImage).row()
} }
nationTable.add(nationImage).row()
} }
editorPickTable.add(AutoScrollPane(nationTable).apply { setScrollingDisabled(true, false) }).height(scrollPanelHeight) editorPickTable.add(AutoScrollPane(nationTable).apply { setScrollingDisabled(true, false) }).height(scrollPanelHeight)

View File

@ -47,8 +47,6 @@ class GameOptionsTable(val previousScreen: IPreviousScreen, val updatePlayerPick
checkboxTable.addBarbariansCheckbox() checkboxTable.addBarbariansCheckbox()
checkboxTable.addOneCityChallengeCheckbox() checkboxTable.addOneCityChallengeCheckbox()
checkboxTable.addNuclearWeaponsCheckbox() checkboxTable.addNuclearWeaponsCheckbox()
if(UncivGame.Current.settings.extendedMapEditor)
checkboxTable.addGodmodeCheckbox()
checkboxTable.addIsOnlineMultiplayerCheckbox() checkboxTable.addIsOnlineMultiplayerCheckbox()
checkboxTable.addModCheckboxes() checkboxTable.addModCheckboxes()
add(checkboxTable).colspan(2).row() add(checkboxTable).colspan(2).row()
@ -76,15 +74,13 @@ class GameOptionsTable(val previousScreen: IPreviousScreen, val updatePlayerPick
addCheckbox("Enable nuclear weapons", gameParameters.nuclearWeaponsEnabled) addCheckbox("Enable nuclear weapons", gameParameters.nuclearWeaponsEnabled)
{ gameParameters.nuclearWeaponsEnabled = it } { gameParameters.nuclearWeaponsEnabled = it }
private fun Table.addGodmodeCheckbox() =
addCheckbox("Scenario Editor", gameParameters.godMode, lockable = false)
{ gameParameters.godMode = it }
private fun Table.addIsOnlineMultiplayerCheckbox() =
private fun Table.addIsOnlineMultiplayerCheckbox() = addCheckbox("Online Multiplayer", gameParameters.isOnlineMultiplayer)
addCheckbox("Online Multiplayer", gameParameters.isOnlineMultiplayer) {
{ gameParameters.isOnlineMultiplayer = it gameParameters.isOnlineMultiplayer = it
updatePlayerPickerTable("") } updatePlayerPickerTable("")
}
private fun addCityStatesSelectBox() { private fun addCityStatesSelectBox() {
add("{Number of City-States}:".toLabel()) add("{Number of City-States}:".toLabel())
@ -132,7 +128,7 @@ class GameOptionsTable(val previousScreen: IPreviousScreen, val updatePlayerPick
} }
private fun Table.addEraSelectBox() { private fun Table.addEraSelectBox() {
if (ruleset.technologies.isEmpty()) return // scenario with no techs if (ruleset.technologies.isEmpty()) return // mod with no techs
val eras = ruleset.technologies.values.filter { !it.uniques.contains("Starting tech") }.map { it.era() }.distinct() val eras = ruleset.technologies.values.filter { !it.uniques.contains("Starting tech") }.map { it.era() }.distinct()
addSelectBox("{Starting Era}:", eras, gameParameters.startingEra) addSelectBox("{Starting Era}:", eras, gameParameters.startingEra)
{ gameParameters.startingEra = it } { gameParameters.startingEra = it }
@ -147,7 +143,6 @@ class GameOptionsTable(val previousScreen: IPreviousScreen, val updatePlayerPick
val victoryConditionsTable = Table().apply { defaults().pad(5f) } val victoryConditionsTable = Table().apply { defaults().pad(5f) }
for (victoryType in VictoryType.values()) { for (victoryType in VictoryType.values()) {
if (victoryType == VictoryType.Neutral) continue if (victoryType == VictoryType.Neutral) continue
if (previousScreen !is GameParametersScreen && victoryType == VictoryType.Scenario) continue // scenario victory is only available for scenarios
val victoryCheckbox = CheckBox(victoryType.name.tr(), CameraStageBaseScreen.skin) val victoryCheckbox = CheckBox(victoryType.name.tr(), CameraStageBaseScreen.skin)
victoryCheckbox.name = victoryType.name victoryCheckbox.name = victoryType.name
victoryCheckbox.isChecked = gameParameters.victoryTypes.contains(victoryType) victoryCheckbox.isChecked = gameParameters.victoryTypes.contains(victoryType)
@ -178,10 +173,7 @@ class GameOptionsTable(val previousScreen: IPreviousScreen, val updatePlayerPick
} }
fun Table.addModCheckboxes() { fun Table.addModCheckboxes() {
val modRulesets = RulesetCache.values.filter { val modRulesets = RulesetCache.values.filter { it.name != "" }
it.name != ""
&& (it.name in gameParameters.mods || !it.modOptions.uniques.contains("Scenario only"))
} // Don't allow scenario mods for a regular 'new game'
val baseRulesetCheckboxes = ArrayList<CheckBox>() val baseRulesetCheckboxes = ArrayList<CheckBox>()
val extentionRulesetModButtons = ArrayList<CheckBox>() val extentionRulesetModButtons = ArrayList<CheckBox>()

View File

@ -5,9 +5,6 @@ import com.badlogic.gdx.files.FileHandle
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox import com.badlogic.gdx.scenes.scene2d.ui.SelectBox
import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.utils.Array import com.badlogic.gdx.utils.Array
import com.unciv.UncivGame
import com.unciv.logic.GameInfo
import com.unciv.logic.GameSaver
import com.unciv.logic.MapSaver import com.unciv.logic.MapSaver
import com.unciv.logic.map.MapType import com.unciv.logic.map.MapType
import com.unciv.ui.utils.CameraStageBaseScreen import com.unciv.ui.utils.CameraStageBaseScreen
@ -20,9 +17,6 @@ class MapOptionsTable(val newGameScreen: NewGameScreen): Table() {
private var mapTypeSpecificTable = Table() private var mapTypeSpecificTable = Table()
private val generatedMapOptionsTable = MapParametersTable(mapParameters) private val generatedMapOptionsTable = MapParametersTable(mapParameters)
private val savedMapOptionsTable = Table() private val savedMapOptionsTable = Table()
private val scenarioMapOptionsTable = Table()
private val scenarioOptionsTable = Table()
var selectedScenarioSaveGame: GameInfo? = null
lateinit var mapTypeSelectBox: TranslatedSelectBox lateinit var mapTypeSelectBox: TranslatedSelectBox
init { init {
@ -31,32 +25,10 @@ class MapOptionsTable(val newGameScreen: NewGameScreen): Table() {
addMapTypeSelection() addMapTypeSelection()
} }
fun selectSavedGameAsScenario(gameFile: FileHandle){
val savedGame = GameSaver.loadGameFromFile(gameFile)
mapParameters.type = MapType.scenario
mapParameters.name = gameFile.name()
newGameScreen.gameSetupInfo.gameParameters = savedGame.gameParameters
newGameScreen.gameSetupInfo.mapParameters = savedGame.tileMap.mapParameters
newGameScreen.updateRuleset()
newGameScreen.updateTables()
selectedScenarioSaveGame = savedGame
}
fun getScenarioFiles(): Sequence<FileHandle> {
val localSaveScenarios = GameSaver.getSaves().filter { it.name().toLowerCase().endsWith("scenario") }
val modScenarios = Gdx.files.local("mods").list().asSequence()
.filter { it.child("scenarios").exists() }.flatMap { it.child("scenarios").list().asSequence() }
return localSaveScenarios + modScenarios
}
private fun addMapTypeSelection() { private fun addMapTypeSelection() {
add("{Map Type}:".toLabel()) add("{Map Type}:".toLabel())
val mapTypes = arrayListOf("Generated") val mapTypes = arrayListOf("Generated")
if (MapSaver.getMaps().isNotEmpty()) mapTypes.add(MapType.custom) if (MapSaver.getMaps().isNotEmpty()) mapTypes.add(MapType.custom)
if (MapSaver.getScenarios().isNotEmpty() && UncivGame.Current.settings.extendedMapEditor)
mapTypes.add(MapType.scenarioMap)
if (getScenarioFiles().any())
mapTypes.add(MapType.scenario)
mapTypeSelectBox = TranslatedSelectBox(mapTypes, "Generated", CameraStageBaseScreen.skin) mapTypeSelectBox = TranslatedSelectBox(mapTypes, "Generated", CameraStageBaseScreen.skin)
val mapFileSelectBox = getMapFileSelectBox() val mapFileSelectBox = getMapFileSelectBox()
@ -67,31 +39,6 @@ class MapOptionsTable(val newGameScreen: NewGameScreen): Table() {
.right().row() .right().row()
val scenarioMapSelectBox = getScenarioFileSelectBox()
scenarioMapOptionsTable.defaults().pad(5f)
scenarioMapOptionsTable.add("{Scenario file}:".toLabel()).left()
// because SOME people gotta give the hugest names to their maps
scenarioMapOptionsTable.add(scenarioMapSelectBox).maxWidth(newGameScreen.stage.width / 2)
.right().row()
val scenarioFiles = getScenarioFiles()
val scenarioSelectBox = SelectBox<FileHandleWrapper>(CameraStageBaseScreen.skin)
if (scenarioFiles.any()) {
for (savedGame in getScenarioFiles()) {
try { // Sometimes, we have scenarios that are dependent on mods that we don't have and so they can't be loaded.
GameSaver.loadGameFromFile(savedGame)
scenarioSelectBox.items.add(FileHandleWrapper(savedGame))
} catch (ex: Exception) {}
}
scenarioSelectBox.items = scenarioSelectBox.items // it doesn't register them until you do this.
scenarioSelectBox.selected = scenarioSelectBox.items.first()
// needs to be after the item change, so it doesn't activate before we choose the Scenario maptype
scenarioSelectBox.onChange { selectSavedGameAsScenario(scenarioSelectBox.selected.fileHandle) }
scenarioOptionsTable.add("{Scenario file}:".toLabel()).left()
scenarioOptionsTable.add(scenarioSelectBox)
}
fun updateOnMapTypeChange() { fun updateOnMapTypeChange() {
mapTypeSpecificTable.clear() mapTypeSpecificTable.clear()
@ -100,20 +47,6 @@ class MapOptionsTable(val newGameScreen: NewGameScreen): Table() {
mapParameters.name = mapFileSelectBox.selected.toString() mapParameters.name = mapFileSelectBox.selected.toString()
mapTypeSpecificTable.add(savedMapOptionsTable) mapTypeSpecificTable.add(savedMapOptionsTable)
newGameScreen.unlockTables() newGameScreen.unlockTables()
} else if (mapTypeSelectBox.selected.value == MapType.scenarioMap) {
mapParameters.type = MapType.scenarioMap
mapParameters.name = scenarioMapSelectBox.selected.toString()
mapTypeSpecificTable.add(scenarioMapOptionsTable)
val scenario = MapSaver.loadScenario(mapParameters.name)
newGameScreen.gameSetupInfo.gameParameters = scenario.gameParameters
newGameScreen.gameSetupInfo.mapParameters = mapParameters
newGameScreen.updateRuleset()
// update PlayerTable and GameOptionsTable
newGameScreen.lockTables()
} else if(mapTypeSelectBox.selected.value == MapType.scenario){
selectSavedGameAsScenario(scenarioSelectBox.selected.fileHandle)
mapTypeSpecificTable.add(scenarioOptionsTable)
newGameScreen.lockTables()
} else { // generated map } else { // generated map
mapParameters.name = "" mapParameters.name = ""
mapParameters.type = generatedMapOptionsTable.mapTypeSelectBox.selected.value mapParameters.type = generatedMapOptionsTable.mapTypeSelectBox.selected.value
@ -138,55 +71,34 @@ class MapOptionsTable(val newGameScreen: NewGameScreen): Table() {
val mapFiles = Array<FileHandleWrapper>() val mapFiles = Array<FileHandleWrapper>()
for (mapFile in MapSaver.getMaps()) for (mapFile in MapSaver.getMaps())
mapFiles.add(FileHandleWrapper(mapFile)) mapFiles.add(FileHandleWrapper(mapFile))
for(mod in Gdx.files.local("mods").list()){ for (mod in Gdx.files.local("mods").list()) {
val mapsFolder = mod.child("maps") val mapsFolder = mod.child("maps")
if(mapsFolder.exists()) if (mapsFolder.exists())
for(map in mapsFolder.list()) for (map in mapsFolder.list())
mapFiles.add(FileHandleWrapper(map)) mapFiles.add(FileHandleWrapper(map))
} }
mapFileSelectBox.items = mapFiles mapFileSelectBox.items = mapFiles
val selectedItem = mapFiles.firstOrNull { it.fileHandle.name()==mapParameters.name } val selectedItem = mapFiles.firstOrNull { it.fileHandle.name() == mapParameters.name }
if (selectedItem != null) { if (selectedItem != null) {
mapFileSelectBox.selected = selectedItem mapFileSelectBox.selected = selectedItem
newGameScreen.gameSetupInfo.mapFile = mapFileSelectBox.selected.fileHandle newGameScreen.gameSetupInfo.mapFile = mapFileSelectBox.selected.fileHandle
} } else if (!mapFiles.isEmpty) {
else if (!mapFiles.isEmpty) {
mapFileSelectBox.selected = mapFiles.first() mapFileSelectBox.selected = mapFiles.first()
newGameScreen.gameSetupInfo.mapFile = mapFileSelectBox.selected.fileHandle newGameScreen.gameSetupInfo.mapFile = mapFileSelectBox.selected.fileHandle
} }
mapFileSelectBox.onChange { mapFileSelectBox.onChange {
val mapFile = mapFileSelectBox.selected.fileHandle val mapFile = mapFileSelectBox.selected.fileHandle
mapParameters.name = mapFile.name() mapParameters.name = mapFile.name()
newGameScreen.gameSetupInfo.mapFile = mapFile newGameScreen.gameSetupInfo.mapFile = mapFile
} }
return mapFileSelectBox return mapFileSelectBox
} }
private fun getScenarioFileSelectBox(): SelectBox<FileHandleWrapper> {
val scenarioFileSelectBox = SelectBox<FileHandleWrapper>(CameraStageBaseScreen.skin)
val scenarioFiles = Array<FileHandleWrapper>()
for (scenarioName in MapSaver.getScenarios()) scenarioFiles.add(FileHandleWrapper(scenarioName))
scenarioFileSelectBox.items = scenarioFiles
val selectedItem = scenarioFiles.firstOrNull { it.fileHandle.name()==mapParameters.name }
if(selectedItem!=null ) scenarioFileSelectBox.selected = selectedItem
scenarioFileSelectBox.onChange {
mapParameters.name = scenarioFileSelectBox.selected!!.fileHandle.name()
val scenario = MapSaver.loadScenario(mapParameters.name)
newGameScreen.apply {
gameSetupInfo.gameParameters = scenario.gameParameters
newGameOptionsTable.gameParameters = scenario.gameParameters
newGameOptionsTable.reloadRuleset()
updateTables()
}
}
return scenarioFileSelectBox
}
// The SelectBox auto displays the text a object.toString(), which on the FileHandle itself includes the folder path. // The SelectBox auto displays the text a object.toString(), which on the FileHandle itself includes the folder path.
// So we wrap it in another object with a custom toString() // So we wrap it in another object with a custom toString()
class FileHandleWrapper(val fileHandle: FileHandle){ class FileHandleWrapper(val fileHandle: FileHandle) {
override fun toString() = fileHandle.name() override fun toString() = fileHandle.name()
} }
} }

View File

@ -1,6 +1,5 @@
package com.unciv.ui.newgamescreen package com.unciv.ui.newgamescreen
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
import com.badlogic.gdx.Gdx import com.badlogic.gdx.Gdx
import com.badlogic.gdx.files.FileHandle import com.badlogic.gdx.files.FileHandle
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox import com.badlogic.gdx.scenes.scene2d.ui.SelectBox
@ -10,7 +9,6 @@ import com.unciv.UncivGame
import com.unciv.logic.* import com.unciv.logic.*
import com.unciv.logic.civilization.PlayerType import com.unciv.logic.civilization.PlayerType
import com.unciv.logic.map.MapParameters import com.unciv.logic.map.MapParameters
import com.unciv.logic.map.MapType
import com.unciv.models.metadata.GameParameters import com.unciv.models.metadata.GameParameters
import com.unciv.models.ruleset.RulesetCache import com.unciv.models.ruleset.RulesetCache
import com.unciv.models.translations.tr import com.unciv.models.translations.tr
@ -19,6 +17,7 @@ import com.unciv.ui.utils.*
import com.unciv.ui.worldscreen.mainmenu.OnlineMultiplayer import com.unciv.ui.worldscreen.mainmenu.OnlineMultiplayer
import java.util.* import java.util.*
import kotlin.concurrent.thread import kotlin.concurrent.thread
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
class GameSetupInfo(var gameId:String, var gameParameters: GameParameters, var mapParameters: MapParameters) { class GameSetupInfo(var gameId:String, var gameParameters: GameParameters, var mapParameters: MapParameters) {
@ -37,9 +36,10 @@ class GameSetupInfo(var gameId:String, var gameParameters: GameParameters, var m
} }
class NewGameScreen(previousScreen:CameraStageBaseScreen, _gameSetupInfo: GameSetupInfo?=null): IPreviousScreen, PickerScreen() { class NewGameScreen(previousScreen:CameraStageBaseScreen, _gameSetupInfo: GameSetupInfo?=null): IPreviousScreen, PickerScreen() {
override val gameSetupInfo = _gameSetupInfo ?: GameSetupInfo() override val gameSetupInfo = _gameSetupInfo ?: GameSetupInfo()
override var ruleset = RulesetCache.getComplexRuleset(gameSetupInfo.gameParameters) // needs to be set because the gameoptionstable etc. depend on this override var ruleset = RulesetCache.getComplexRuleset(gameSetupInfo.gameParameters) // needs to be set because the gameoptionstable etc. depend on this
var newGameOptionsTable = GameOptionsTable(this) { desiredCiv: String -> playerPickerTable.update(desiredCiv) } var newGameOptionsTable = GameOptionsTable(this) { desiredCiv: String -> playerPickerTable.update(desiredCiv) }
// Has to be defined before the mapOptionsTable, since the mapOptionsTable refers to it on init // Has to be defined before the mapOptionsTable, since the mapOptionsTable refers to it on init
var playerPickerTable = PlayerPickerTable(this, gameSetupInfo.gameParameters) var playerPickerTable = PlayerPickerTable(this, gameSetupInfo.gameParameters)
var mapOptionsTable = MapOptionsTable(this) var mapOptionsTable = MapOptionsTable(this)
@ -103,19 +103,7 @@ class NewGameScreen(previousScreen:CameraStageBaseScreen, _gameSetupInfo: GameSe
private fun newGameThread() { private fun newGameThread() {
try { try {
if (mapOptionsTable.mapTypeSelectBox.selected.value == MapType.scenario) { newGame = GameStarter.startNewGame(gameSetupInfo)
newGame = mapOptionsTable.selectedScenarioSaveGame
// to take the definition of which players are human and which are AI
for (player in gameSetupInfo.gameParameters.players) {
newGame!!.getCivilization(player.chosenCiv).playerType = player.playerType
}
if (newGame!!.getCurrentPlayerCivilization().playerType == PlayerType.AI) {
newGame!!.setTransients()
newGame!!.nextTurn() // can't start the game on an AI turn
}
newGame!!.gameParameters.godMode = false
}
else newGame = GameStarter.startNewGame(gameSetupInfo)
} catch (exception: Exception) { } catch (exception: Exception) {
Gdx.app.postRunnable { Gdx.app.postRunnable {
val cantMakeThatMapPopup = Popup(this) val cantMakeThatMapPopup = Popup(this)
@ -155,7 +143,7 @@ class NewGameScreen(previousScreen:CameraStageBaseScreen, _gameSetupInfo: GameSe
Gdx.graphics.requestRendering() Gdx.graphics.requestRendering()
} }
fun updateRuleset(){ fun updateRuleset() {
ruleset.clear() ruleset.clear()
ruleset.add(RulesetCache.getComplexRuleset(gameSetupInfo.gameParameters)) ruleset.add(RulesetCache.getComplexRuleset(gameSetupInfo.gameParameters))
} }

View File

@ -22,7 +22,7 @@ import com.unciv.ui.utils.*
import java.util.* import java.util.*
/** /**
* This [Table] is used to pick or edit players information for new game/scenario creation. * This [Table] is used to pick or edit players information for new game creation.
* Could be inserted to [NewGameScreen], [GameParametersScreen] or any other [Screen] * Could be inserted to [NewGameScreen], [GameParametersScreen] or any other [Screen]
* which provides [GameSetupInfo] and [Ruleset]. * which provides [GameSetupInfo] and [Ruleset].
* Upon player changes updates property [gameParameters]. Also updates available nations when mod changes. * Upon player changes updates property [gameParameters]. Also updates available nations when mod changes.
@ -37,7 +37,7 @@ class PlayerPickerTable(val previousScreen: IPreviousScreen, var gameParameters:
val playerListTable = Table() val playerListTable = Table()
val civBlocksWidth = previousScreen.stage.width / 3 val civBlocksWidth = previousScreen.stage.width / 3
/** Locks player table for editing, used during new game creation with scenario.*/ /** Locks player table for editing, currently unused, was previously used for scenarios and could be useful in the future.*/
var locked = false var locked = false
/** No random civilization is available, used during map editing.*/ /** No random civilization is available, used during map editing.*/

View File

@ -28,7 +28,7 @@ class TechPickerScreen(internal val civInfo: CivilizationInfo, centerOnTech: Tec
/** We need this to be a separate table, and NOT the topTable, because *inhales* /** We need this to be a separate table, and NOT the topTable, because *inhales*
* When call setConnectingLines we need to pack() the table so that the lines will align correctly, BUT * When call setConnectingLines we need to pack() the table so that the lines will align correctly, BUT
* this causes the table to be SMALLER THAN THE SCREEN for small tech trees e.g. scenarios, * this causes the table to be SMALLER THAN THE SCREEN for small tech trees from mods,
* meaning the tech tree is in a crumpled heap at the lower-left corner of the screen * meaning the tech tree is in a crumpled heap at the lower-left corner of the screen
* Having this be a separate table allows us to leave the TopTable as is (that is: auto-width to fit the scrollPane) * Having this be a separate table allows us to leave the TopTable as is (that is: auto-width to fit the scrollPane)
* leaving us the juicy small tech tree right in the center. * leaving us the juicy small tech tree right in the center.

View File

@ -42,7 +42,7 @@ class OptionsPopup(val previousScreen:CameraStageBaseScreen) : Popup(previousScr
add(scrollPane).maxHeight(screen.stage.height * 0.6f).row() add(scrollPane).maxHeight(screen.stage.height * 0.6f).row()
addCloseButton { addCloseButton {
if(previousScreen is WorldScreen) if (previousScreen is WorldScreen)
previousScreen.enableNextTurnButtonAfterOptions() previousScreen.enableNextTurnButtonAfterOptions()
} }
@ -50,11 +50,11 @@ class OptionsPopup(val previousScreen:CameraStageBaseScreen) : Popup(previousScr
center(previousScreen.stage) center(previousScreen.stage)
} }
private fun addHeader (text: String) { private fun addHeader(text: String) {
innerTable2.add(text.toLabel(fontSize = 24)).colspan(2).padTop(if (innerTable2.cells.isEmpty) 0f else 20f).row() innerTable2.add(text.toLabel(fontSize = 24)).colspan(2).padTop(if (innerTable2.cells.isEmpty) 0f else 20f).row()
} }
private fun addYesNoRow (text: String, initialValue: Boolean, updateWorld: Boolean = false, action: ((Boolean) -> Unit)) { private fun addYesNoRow(text: String, initialValue: Boolean, updateWorld: Boolean = false, action: ((Boolean) -> Unit)) {
innerTable2.add(text.toLabel()) innerTable2.add(text.toLabel())
val button = YesNoButton(initialValue, CameraStageBaseScreen.skin) { val button = YesNoButton(initialValue, CameraStageBaseScreen.skin) {
action(it) action(it)
@ -82,13 +82,13 @@ class OptionsPopup(val previousScreen:CameraStageBaseScreen) : Popup(previousScr
addHeader("Display options") addHeader("Display options")
addYesNoRow ("Show worked tiles", settings.showWorkedTiles, true) { settings.showWorkedTiles = it } addYesNoRow("Show worked tiles", settings.showWorkedTiles, true) { settings.showWorkedTiles = it }
addYesNoRow ("Show resources and improvements", settings.showResourcesAndImprovements, true) { settings.showResourcesAndImprovements = it } addYesNoRow("Show resources and improvements", settings.showResourcesAndImprovements, true) { settings.showResourcesAndImprovements = it }
addYesNoRow ("Show tile yields", settings.showTileYields, true) { settings.showTileYields = it } // JN addYesNoRow("Show tile yields", settings.showTileYields, true) { settings.showTileYields = it } // JN
addYesNoRow ("Show tutorials", settings.showTutorials, true) {settings.showTutorials = it } addYesNoRow("Show tutorials", settings.showTutorials, true) { settings.showTutorials = it }
addYesNoRow ("Show minimap", settings.showMinimap, true) { settings.showMinimap = it } addYesNoRow("Show minimap", settings.showMinimap, true) { settings.showMinimap = it }
addYesNoRow ("Show pixel units", settings.showPixelUnits, true) { settings.showPixelUnits = it } addYesNoRow("Show pixel units", settings.showPixelUnits, true) { settings.showPixelUnits = it }
addYesNoRow ("Show pixel improvements", settings.showPixelImprovements, true) { settings.showPixelImprovements = it } addYesNoRow("Show pixel improvements", settings.showPixelImprovements, true) { settings.showPixelImprovements = it }
addLanguageSelectBox() addLanguageSelectBox()
@ -96,7 +96,7 @@ class OptionsPopup(val previousScreen:CameraStageBaseScreen) : Popup(previousScr
addTileSetSelectBox() addTileSetSelectBox()
addYesNoRow ("Continuous rendering", settings.continuousRendering) { addYesNoRow("Continuous rendering", settings.continuousRendering) {
settings.continuousRendering = it settings.continuousRendering = it
Gdx.graphics.isContinuousRendering = it Gdx.graphics.isContinuousRendering = it
} }
@ -106,22 +106,22 @@ class OptionsPopup(val previousScreen:CameraStageBaseScreen) : Popup(previousScr
addHeader("Gameplay options") addHeader("Gameplay options")
addYesNoRow ("Check for idle units", settings.checkForDueUnits, true) { settings.checkForDueUnits = it } addYesNoRow("Check for idle units", settings.checkForDueUnits, true) { settings.checkForDueUnits = it }
addYesNoRow ("Move units with a single tap", settings.singleTapMove) { settings.singleTapMove = it } addYesNoRow("Move units with a single tap", settings.singleTapMove) { settings.singleTapMove = it }
addYesNoRow ("Movement assumes unknown tiles to be passable", settings.unitMovementIncludesImpassibles) addYesNoRow("Movement assumes unknown tiles to be passable", settings.unitMovementIncludesImpassibles)
{ settings.unitMovementIncludesImpassibles = it } { settings.unitMovementIncludesImpassibles = it }
addYesNoRow ("Auto-assign city production", settings.autoAssignCityProduction, true) { addYesNoRow("Auto-assign city production", settings.autoAssignCityProduction, true) {
settings.autoAssignCityProduction = it settings.autoAssignCityProduction = it
if (it && previousScreen is WorldScreen && if (it && previousScreen is WorldScreen &&
previousScreen.viewingCiv.isCurrentPlayer() && previousScreen.viewingCiv.playerType == PlayerType.Human) { previousScreen.viewingCiv.isCurrentPlayer() && previousScreen.viewingCiv.playerType == PlayerType.Human) {
previousScreen.gameInfo.currentPlayerCiv.cities.forEach { city -> previousScreen.gameInfo.currentPlayerCiv.cities.forEach { city ->
city.cityConstructions.chooseNextConstruction() city.cityConstructions.chooseNextConstruction()
} }
} }
} }
addYesNoRow ("Auto-build roads", settings.autoBuildingRoads) { settings.autoBuildingRoads = it } addYesNoRow("Auto-build roads", settings.autoBuildingRoads) { settings.autoBuildingRoads = it }
addYesNoRow ("Automated workers replace improvements", settings.automatedWorkersReplaceImprovements) { settings.automatedWorkersReplaceImprovements = it } addYesNoRow("Automated workers replace improvements", settings.automatedWorkersReplaceImprovements) { settings.automatedWorkersReplaceImprovements = it }
addYesNoRow ("Order trade offers by amount", settings.orderTradeOffersByAmount) { settings.orderTradeOffersByAmount = it } addYesNoRow("Order trade offers by amount", settings.orderTradeOffersByAmount) { settings.orderTradeOffersByAmount = it }
addAutosaveTurnsSelectBox() addAutosaveTurnsSelectBox()
@ -130,8 +130,6 @@ class OptionsPopup(val previousScreen:CameraStageBaseScreen) : Popup(previousScr
addHeader("Other options") addHeader("Other options")
addYesNoRow("Extended map editor", settings.extendedMapEditor) { settings.extendedMapEditor = it }
addSoundEffectsVolumeSlider() addSoundEffectsVolumeSlider()
addMusicVolumeSlider() addMusicVolumeSlider()
addTranslationGeneration() addTranslationGeneration()
@ -206,7 +204,7 @@ class OptionsPopup(val previousScreen:CameraStageBaseScreen) : Popup(previousScr
text += "\n\n" + mod.name + "\n\n" + modLinks text += "\n\n" + mod.name + "\n\n" + modLinks
} }
val popup = Popup(screen) val popup = Popup(screen)
popup.add(ScrollPane(text.toLabel()).apply { setOverscroll(false,false) }) popup.add(ScrollPane(text.toLabel()).apply { setOverscroll(false, false) })
.maxHeight(screen.stage.height / 2).row() .maxHeight(screen.stage.height / 2).row()
popup.addCloseButton() popup.addCloseButton()
popup.open(true) popup.open(true)
@ -399,4 +397,4 @@ private class YesNoButton(initialValue: Boolean, skin: Skin, action: (Boolean) -
action.invoke(value) action.invoke(value)
} }
} }
} }