From 7ddcc5895563a662331c6ed703925200a1326414 Mon Sep 17 00:00:00 2001 From: Yair Morgenstern Date: Sun, 7 Mar 2021 10:02:19 +0200 Subject: [PATCH] Can convert maps between different rulesets! --- core/src/com/unciv/logic/map/TileInfo.kt | 47 +++++++ .../unciv/ui/mapeditor/MapEditorMenuPopup.kt | 116 +++++++++--------- .../ui/mapeditor/TileEditorOptionsTable.kt | 46 +------ 3 files changed, 108 insertions(+), 101 deletions(-) diff --git a/core/src/com/unciv/logic/map/TileInfo.kt b/core/src/com/unciv/logic/map/TileInfo.kt index 436f217171..11d533126d 100644 --- a/core/src/com/unciv/logic/map/TileInfo.kt +++ b/core/src/com/unciv/logic/map/TileInfo.kt @@ -571,5 +571,52 @@ open class TileInfo { turnsToImprovement = 0 } + fun normalizeToRuleset(ruleset: Ruleset){ + if (!ruleset.terrains.containsKey(naturalWonder)) naturalWonder = null + if (naturalWonder != null) { + val naturalWonder = ruleset.terrains[naturalWonder]!! + baseTerrain = naturalWonder.turnsInto!! + terrainFeature = null + resource = null + improvement = null + } + + if (!ruleset.terrains.containsKey(terrainFeature)) terrainFeature = null + if (terrainFeature != null) { + val terrainFeatureObject = ruleset.terrains[terrainFeature]!! + if (terrainFeatureObject.occursOn.isNotEmpty() && !terrainFeatureObject.occursOn.contains(baseTerrain)) + terrainFeature = null + } + + + if (resource != null && !ruleset.tileResources.containsKey(resource)) resource = null + if (resource != null) { + val resourceObject = ruleset.tileResources[resource]!! + if (resourceObject.terrainsCanBeFoundOn.none { it == baseTerrain || it == terrainFeature }) + resource = null + } + + if (improvement != null) normalizeTileImprovement(ruleset) + if (isWater || isImpassible()) + roadStatus = RoadStatus.None + } + + + private fun normalizeTileImprovement(ruleset: Ruleset) { + val topTerrain = getLastTerrain() + if (improvement!!.startsWith("StartingLocation")) { + if (!isLand || topTerrain.impassable) improvement = null + return + } + val improvementObject = ruleset.tileImprovements[improvement]!! + improvement = null // Unset, and check if it can be reset. If so, do it, if not, invalid. + if (canImprovementBeBuiltHere(improvementObject) + // Allow building 'other' improvements like city ruins, barb encampments, Great Improvements etc + || (improvementObject.terrainsCanBeBuiltOn.isEmpty() + && ruleset.tileResources.values.none { it.improvement == improvementObject.name } + && !isImpassible() && isLand)) + improvement = improvementObject.name + } + //endregion } diff --git a/core/src/com/unciv/ui/mapeditor/MapEditorMenuPopup.kt b/core/src/com/unciv/ui/mapeditor/MapEditorMenuPopup.kt index adbd2b7ec9..2abdd0c547 100644 --- a/core/src/com/unciv/ui/mapeditor/MapEditorMenuPopup.kt +++ b/core/src/com/unciv/ui/mapeditor/MapEditorMenuPopup.kt @@ -1,71 +1,75 @@ package com.unciv.ui.mapeditor +import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane +import com.badlogic.gdx.scenes.scene2d.ui.Table import com.unciv.Constants import com.unciv.MainMenuScreen import com.unciv.UncivGame import com.unciv.logic.map.TileMap import com.unciv.models.metadata.Player -import com.unciv.ui.utils.Popup -import com.unciv.ui.utils.onClick -import com.unciv.ui.utils.toTextButton +import com.unciv.models.ruleset.RulesetCache +import com.unciv.ui.newgamescreen.ModCheckboxTable +import com.unciv.ui.utils.* -class MapEditorMenuPopup(var mapEditorScreen: MapEditorScreen): Popup(mapEditorScreen){ +class MapEditorMenuPopup(var mapEditorScreen: MapEditorScreen): Popup(mapEditorScreen) { init { - addNewMapButton() - addSaveMapButton() - addLoadMapButton() - addExitMapEditorButton() - addCloseOptionsButton() + addButton("New map") { UncivGame.Current.setScreen(NewMapScreen()) } + addButton("Save map") { mapEditorScreen.game.setScreen(SaveAndLoadMapScreen(mapEditorScreen.tileMap, true)) } + addButton("Load map") { mapEditorScreen.game.setScreen(SaveAndLoadMapScreen(mapEditorScreen.tileMap)) } + addButton("Exit map editor") { mapEditorScreen.game.setScreen(MainMenuScreen()); mapEditorScreen.dispose() } + addButton("Change ruleset") { MapEditorRulesetPopup(mapEditorScreen).open(); close() } + addButton(Constants.close) { close() } } - private fun Popup.addNewMapButton() { - val newMapButton = "New map".toTextButton() - newMapButton.onClick { - UncivGame.Current.setScreen(NewMapScreen()) + class MapEditorRulesetPopup(mapEditorScreen: MapEditorScreen) : Popup(mapEditorScreen) { + var ruleset = mapEditorScreen.ruleset.clone() // don't take the actual one, so w can decide to not make changes + + init { + val mods = mapEditorScreen.tileMap.mapParameters.mods + + val checkboxTable = ModCheckboxTable(mods, mapEditorScreen) { + ruleset.clear() + val newRuleset = RulesetCache.getComplexRuleset(mods) + ruleset.add(newRuleset) + ruleset.mods += mods + ruleset.modOptions = newRuleset.modOptions + + ImageGetter.setNewRuleset(ruleset) + } + + add(ScrollPane(checkboxTable)).maxHeight(mapEditorScreen.stage.height * 0.8f).row() + + addButton("Save") { + val incompatibilities = mapEditorScreen.tileMap.values.map { it.getRulesetIncompatability(ruleset) }.toHashSet() + incompatibilities.remove("") + + if (incompatibilities.isEmpty()) { + mapEditorScreen.tileMap.mapParameters.mods = mods; + mapEditorScreen.game.setScreen(MapEditorScreen(mapEditorScreen.tileMap)) // reset all images etc. + return@addButton + } + + val incompatTable = Table() + for (inc in incompatibilities) + incompatTable.add(inc.toLabel()).row() + val incompatPopup = Popup(screen) + incompatPopup.add(ScrollPane(incompatTable)).maxHeight(stage.height * 0.8f).row() + incompatPopup.add("Change map to fit selected ruleset?").row() + incompatPopup.addButton("Yes") { + for (tile in mapEditorScreen.tileMap.values) + tile.normalizeToRuleset(ruleset) + mapEditorScreen.tileMap.mapParameters.mods = mods + mapEditorScreen.game.setScreen(MapEditorScreen(mapEditorScreen.tileMap)) // reset all images etc. + } + incompatPopup.addButton("No") { incompatPopup.close() } + incompatPopup.open(true) + + } + + // Reset - no changes + addCloseButton { ImageGetter.setNewRuleset(mapEditorScreen.ruleset) } } - add(newMapButton).row() } - private fun Popup.addSaveMapButton() { - val saveMapButton = "Save map".toTextButton() - saveMapButton.onClick { - mapEditorScreen.game.setScreen(SaveAndLoadMapScreen(mapEditorScreen.tileMap, true)) - } - add(saveMapButton).row() - } - - private fun Popup.addLoadMapButton() { - val loadMapButton = "Load map".toTextButton() - loadMapButton.onClick { - UncivGame.Current.setScreen(SaveAndLoadMapScreen(mapEditorScreen.tileMap)) - } - add(loadMapButton).row() - } - - - private fun Popup.addExitMapEditorButton() { - val exitMapEditorButton = "Exit map editor".toTextButton() - add(exitMapEditorButton).row() - exitMapEditorButton.onClick { mapEditorScreen.game.setScreen(MainMenuScreen()); mapEditorScreen.dispose() } - } - - private fun Popup.addCloseOptionsButton() { - val closeOptionsButton = Constants.close.toTextButton() - closeOptionsButton.onClick { close() } - add(closeOptionsButton).row() - } - - private fun getPlayersFromMap(tileMap: TileMap): ArrayList { - val tilesWithStartingLocations = tileMap.values - .filter { it.improvement != null && it.improvement!!.startsWith("StartingLocation ") } - var players = ArrayList() - for (tile in tilesWithStartingLocations) { - players.add(Player().apply{ - chosenCiv = tile.improvement!!.removePrefix("StartingLocation ") - }) - } - return players - } - -} +} \ No newline at end of file diff --git a/core/src/com/unciv/ui/mapeditor/TileEditorOptionsTable.kt b/core/src/com/unciv/ui/mapeditor/TileEditorOptionsTable.kt index c7c38c8d25..7791871fbf 100644 --- a/core/src/com/unciv/ui/mapeditor/TileEditorOptionsTable.kt +++ b/core/src/com/unciv/ui/mapeditor/TileEditorOptionsTable.kt @@ -443,53 +443,9 @@ class TileEditorOptionsTable(val mapEditorScreen: MapEditorScreen): Table(Camera fun updateTileWhenClicked(tileInfo: TileInfo) { tileAction(tileInfo) - normalizeTile(tileInfo) + tileInfo.normalizeToRuleset(ruleset) } - fun normalizeTile(tileInfo: TileInfo) { - /*Natural Wonder superpowers! */ - if (tileInfo.naturalWonder != null) { - val naturalWonder = tileInfo.getNaturalWonder() - tileInfo.baseTerrain = naturalWonder.turnsInto!! - tileInfo.terrainFeature = null - tileInfo.resource = null - tileInfo.improvement = null - } - - if (tileInfo.terrainFeature != null) { - val terrainFeature = tileInfo.getTerrainFeature() - if (terrainFeature == null || terrainFeature.occursOn.isNotEmpty() && !terrainFeature.occursOn.contains(tileInfo.baseTerrain)) - tileInfo.terrainFeature = null - } - if (tileInfo.resource != null && !ruleset.tileResources.containsKey(tileInfo.resource)) - tileInfo.resource = null - if (tileInfo.resource != null) { - val resource = tileInfo.getTileResource() - if (resource.terrainsCanBeFoundOn.none { it == tileInfo.baseTerrain || it == tileInfo.terrainFeature }) - tileInfo.resource = null - } - if (tileInfo.improvement != null) { - normalizeTileImprovement(tileInfo) - } - if (tileInfo.isWater || tileInfo.isImpassible()) - tileInfo.roadStatus = RoadStatus.None - } - - private fun normalizeTileImprovement(tileInfo: TileInfo) { - val topTerrain = tileInfo.getLastTerrain() - if (tileInfo.improvement!!.startsWith("StartingLocation")) { - if (!tileInfo.isLand || topTerrain.impassable) - tileInfo.improvement = null - return - } - val improvement = tileInfo.getTileImprovement()!! - tileInfo.improvement = null // Unset, and check if it can be reset. If so, do it, if not, invalid. - if (tileInfo.canImprovementBeBuiltHere(improvement) - // Allow building 'other' improvements like city ruins, barb encampments, Great Improvements etc - || (improvement.terrainsCanBeBuiltOn.isEmpty() && ruleset.tileResources.values.none { it.improvement == improvement.name } - && !tileInfo.isImpassible() && tileInfo.isLand)) - tileInfo.improvement = improvement.name - } private fun setCurrentHex(tileInfo: TileInfo, text: String) { val tileGroup = TileGroup(tileInfo, TileSetStrings())