Mod-specific maps are go! :D

Resolves #3517
This commit is contained in:
Yair Morgenstern
2021-02-12 11:16:54 +02:00
parent 9db073ff25
commit fff22e66cd
9 changed files with 53 additions and 9 deletions

View File

@ -37,6 +37,9 @@ class MapParameters {
var noRuins = false var noRuins = false
var noNaturalWonders = false var noNaturalWonders = false
/** This is used mainly for the map editor, so you can continue editing a map under the ame ruleset you started with */
var mods = LinkedHashSet<String>()
var seed: Long = 0 var seed: Long = 0
var tilesPerBiomeArea = 6 var tilesPerBiomeArea = 6
var maxCoastExtension = 2 var maxCoastExtension = 2

View File

@ -502,7 +502,7 @@ open class TileInfo {
if (!ruleset.terrains.containsKey(baseTerrain)) return "Base terrain $baseTerrain does not exist in ruleset!" if (!ruleset.terrains.containsKey(baseTerrain)) return "Base terrain $baseTerrain does not exist in ruleset!"
if (terrainFeature != null && !ruleset.terrains.containsKey(terrainFeature)) return "Terrain feature $terrainFeature does not exist in ruleset!" if (terrainFeature != null && !ruleset.terrains.containsKey(terrainFeature)) return "Terrain feature $terrainFeature does not exist in ruleset!"
if (resource != null && !ruleset.tileResources.containsKey(resource)) return "Resource $resource does not exist in ruleset!" if (resource != null && !ruleset.tileResources.containsKey(resource)) return "Resource $resource does not exist in ruleset!"
if (improvement != null && !ruleset.tileImprovements.containsKey(baseTerrain)) return "Improvement $improvement does not exist in ruleset!" if (improvement != null && !ruleset.tileImprovements.containsKey(improvement)) return "Improvement $improvement does not exist in ruleset!"
return "" return ""
} }

View File

@ -27,6 +27,7 @@ class MapEditorScreen(): CameraStageBaseScreen() {
constructor(map: TileMap) : this() { constructor(map: TileMap) : this() {
tileMap = map tileMap = map
ruleset = RulesetCache.getComplexRuleset(map.mapParameters.mods)
initialize() initialize()
} }

View File

@ -7,9 +7,11 @@ import com.unciv.UncivGame
import com.unciv.logic.map.mapgenerator.MapGenerator import com.unciv.logic.map.mapgenerator.MapGenerator
import com.unciv.logic.map.MapParameters import com.unciv.logic.map.MapParameters
import com.unciv.logic.map.TileMap import com.unciv.logic.map.TileMap
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
import com.unciv.ui.newgamescreen.MapParametersTable import com.unciv.ui.newgamescreen.MapParametersTable
import com.unciv.ui.newgamescreen.ModCheckboxTable
import com.unciv.ui.pickerscreens.PickerScreen import com.unciv.ui.pickerscreens.PickerScreen
import com.unciv.ui.utils.* import com.unciv.ui.utils.*
import kotlin.concurrent.thread import kotlin.concurrent.thread
@ -19,6 +21,7 @@ import com.unciv.ui.utils.AutoScrollPane as ScrollPane
class NewMapScreen : PickerScreen() { class NewMapScreen : PickerScreen() {
private val mapParameters = MapParameters() private val mapParameters = MapParameters()
private val ruleset = RulesetCache.getBaseRuleset()
private var generatedMap: TileMap? = null private var generatedMap: TileMap? = null
init { init {
@ -28,12 +31,22 @@ class NewMapScreen : PickerScreen() {
pad(10f) pad(10f)
add("Map Options".toLabel(fontSize = 24)).row() add("Map Options".toLabel(fontSize = 24)).row()
add(MapParametersTable(mapParameters, isEmptyMapAllowed = true)).row() add(MapParametersTable(mapParameters, isEmptyMapAllowed = true)).row()
add(ModCheckboxTable(mapParameters.mods, this@NewMapScreen) {
ruleset.clear()
val newRuleset = RulesetCache.getComplexRuleset(mapParameters.mods)
ruleset.add(newRuleset)
ruleset.mods += mapParameters.mods
ruleset.modOptions = newRuleset.modOptions
ImageGetter.ruleset = ruleset
ImageGetter.reload()
})
pack() pack()
} }
topTable.apply { topTable.apply {
add(ScrollPane(newMapScreenOptionsTable).apply { setOverscroll(false,false) }) add(ScrollPane(newMapScreenOptionsTable).apply { setOverscroll(false, false) })
.height(topTable.parent.height) .height(topTable.parent.height)
pack() pack()
setFillParent(true) setFillParent(true)
@ -47,11 +60,12 @@ class NewMapScreen : PickerScreen() {
thread(name = "MapGenerator") { thread(name = "MapGenerator") {
try { try {
// Map generation can take a while and we don't want ANRs // Map generation can take a while and we don't want ANRs
val ruleset = RulesetCache.getBaseRuleset()
generatedMap = MapGenerator(ruleset).generateMap(mapParameters) generatedMap = MapGenerator(ruleset).generateMap(mapParameters)
Gdx.app.postRunnable { Gdx.app.postRunnable {
UncivGame.Current.setScreen(MapEditorScreen(generatedMap!!)) val mapEditorScreen = MapEditorScreen(generatedMap!!)
mapEditorScreen.ruleset = ruleset
UncivGame.Current.setScreen(mapEditorScreen)
} }
} catch (exception: Exception) { } catch (exception: Exception) {

View File

@ -174,7 +174,7 @@ class GameOptionsTable(val previousScreen: IPreviousScreen, val updatePlayerPick
} }
fun Table.addModCheckboxes() { fun Table.addModCheckboxes() {
val table = ModCheckboxTable(gameParameters, previousScreen as CameraStageBaseScreen) { val table = ModCheckboxTable(gameParameters.mods, previousScreen as CameraStageBaseScreen) {
reloadRuleset() reloadRuleset()
update() update()

View File

@ -91,6 +91,10 @@ class MapOptionsTable(val newGameScreen: NewGameScreen): Table() {
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
val map = MapSaver.loadMap(mapFile)
newGameScreen.gameSetupInfo.gameParameters.mods = map.mapParameters.mods
newGameScreen.updateRuleset()
newGameScreen.updateTables()
} }
return mapFileSelectBox return mapFileSelectBox
} }

View File

@ -10,10 +10,9 @@ import com.unciv.ui.utils.ToastPopup
import com.unciv.ui.utils.onChange import com.unciv.ui.utils.onChange
import com.unciv.ui.utils.toLabel import com.unciv.ui.utils.toLabel
class ModCheckboxTable(val gameParameters: GameParameters, val screen: CameraStageBaseScreen, onUpdate: (String) -> Unit): Table(){ class ModCheckboxTable(val mods:LinkedHashSet<String>, val screen: CameraStageBaseScreen, onUpdate: (String) -> Unit): Table(){
init { init {
val modRulesets = RulesetCache.values.filter { it.name != "" } val modRulesets = RulesetCache.values.filter { it.name != "" }
val mods = gameParameters.mods
val baseRulesetCheckboxes = ArrayList<CheckBox>() val baseRulesetCheckboxes = ArrayList<CheckBox>()
val extentionRulesetModButtons = ArrayList<CheckBox>() val extentionRulesetModButtons = ArrayList<CheckBox>()
@ -41,7 +40,7 @@ class ModCheckboxTable(val gameParameters: GameParameters, val screen: CameraSta
var isCompatibleWithCurrentRuleset = true var isCompatibleWithCurrentRuleset = true
var complexModLinkErrors = "" var complexModLinkErrors = ""
try { try {
val newRuleset = RulesetCache.getComplexRuleset(gameParameters.mods) val newRuleset = RulesetCache.getComplexRuleset(mods)
newRuleset.modOptions.isBaseRuleset = true // This is so the checkModLinks finds all connections newRuleset.modOptions.isBaseRuleset = true // This is so the checkModLinks finds all connections
complexModLinkErrors = newRuleset.checkModLinks() complexModLinkErrors = newRuleset.checkModLinks()
if (complexModLinkErrors != "") isCompatibleWithCurrentRuleset = false if (complexModLinkErrors != "") isCompatibleWithCurrentRuleset = false

View File

@ -16,6 +16,7 @@ import com.unciv.ui.pickerscreens.PickerScreen
import com.unciv.ui.utils.* 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.collections.HashSet
import kotlin.concurrent.thread import kotlin.concurrent.thread
import com.unciv.ui.utils.AutoScrollPane as ScrollPane import com.unciv.ui.utils.AutoScrollPane as ScrollPane
@ -91,6 +92,28 @@ class NewGameScreen(previousScreen:CameraStageBaseScreen, _gameSetupInfo: GameSe
} }
Gdx.input.inputProcessor = null // remove input processing - nothing will be clicked! Gdx.input.inputProcessor = null // remove input processing - nothing will be clicked!
if (gameSetupInfo.mapFile != null){
val map = MapSaver.loadMap(gameSetupInfo.mapFile!!)
val rulesetIncompatabilities = HashSet<String>()
for(tile in map.values) {
val rulesetIncompat = tile.getRulesetIncompatability(ruleset)
if (rulesetIncompat != "") rulesetIncompatabilities.add(rulesetIncompat)
}
if (rulesetIncompatabilities.isNotEmpty()) {
val incompatibleMap = Popup(this)
incompatibleMap.addGoodSizedLabel("Map is incompatible with the chosen ruleset!".tr()).row()
for(incompat in rulesetIncompatabilities)
incompatibleMap.addGoodSizedLabel(incompat).row()
incompatibleMap.addCloseButton()
incompatibleMap.open()
game.setScreen(this) // to get the input back
return@onClick
}
}
rightSideButton.disable() rightSideButton.disable()
rightSideButton.setText("Working...".tr()) rightSideButton.setText("Working...".tr())
@ -146,6 +169,7 @@ class NewGameScreen(previousScreen:CameraStageBaseScreen, _gameSetupInfo: GameSe
fun updateRuleset() { fun updateRuleset() {
ruleset.clear() ruleset.clear()
ruleset.add(RulesetCache.getComplexRuleset(gameSetupInfo.gameParameters.mods)) ruleset.add(RulesetCache.getComplexRuleset(gameSetupInfo.gameParameters.mods))
ImageGetter.setNewRuleset(ruleset)
} }
fun lockTables() { fun lockTables() {

View File

@ -43,7 +43,6 @@ object ImageGetter {
} }
fun setNewRuleset(ruleset: Ruleset) { fun setNewRuleset(ruleset: Ruleset) {
if (this.ruleset == ruleset) return
this.ruleset = ruleset this.ruleset = ruleset
reload() reload()
} }