Can convert maps between different rulesets!

This commit is contained in:
Yair Morgenstern 2021-03-07 10:02:19 +02:00
parent a654937ad3
commit 7ddcc58955
3 changed files with 108 additions and 101 deletions

View File

@ -571,5 +571,52 @@ open class TileInfo {
turnsToImprovement = 0 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 //endregion
} }

View File

@ -1,71 +1,75 @@
package com.unciv.ui.mapeditor 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.Constants
import com.unciv.MainMenuScreen import com.unciv.MainMenuScreen
import com.unciv.UncivGame import com.unciv.UncivGame
import com.unciv.logic.map.TileMap import com.unciv.logic.map.TileMap
import com.unciv.models.metadata.Player import com.unciv.models.metadata.Player
import com.unciv.ui.utils.Popup import com.unciv.models.ruleset.RulesetCache
import com.unciv.ui.utils.onClick import com.unciv.ui.newgamescreen.ModCheckboxTable
import com.unciv.ui.utils.toTextButton import com.unciv.ui.utils.*
class MapEditorMenuPopup(var mapEditorScreen: MapEditorScreen): Popup(mapEditorScreen){ class MapEditorMenuPopup(var mapEditorScreen: MapEditorScreen): Popup(mapEditorScreen) {
init { init {
addNewMapButton() addButton("New map") { UncivGame.Current.setScreen(NewMapScreen()) }
addSaveMapButton() addButton("Save map") { mapEditorScreen.game.setScreen(SaveAndLoadMapScreen(mapEditorScreen.tileMap, true)) }
addLoadMapButton() addButton("Load map") { mapEditorScreen.game.setScreen(SaveAndLoadMapScreen(mapEditorScreen.tileMap)) }
addExitMapEditorButton() addButton("Exit map editor") { mapEditorScreen.game.setScreen(MainMenuScreen()); mapEditorScreen.dispose() }
addCloseOptionsButton() addButton("Change ruleset") { MapEditorRulesetPopup(mapEditorScreen).open(); close() }
addButton(Constants.close) { close() }
} }
private fun Popup.addNewMapButton() { class MapEditorRulesetPopup(mapEditorScreen: MapEditorScreen) : Popup(mapEditorScreen) {
val newMapButton = "New map".toTextButton() var ruleset = mapEditorScreen.ruleset.clone() // don't take the actual one, so w can decide to not make changes
newMapButton.onClick {
UncivGame.Current.setScreen(NewMapScreen()) 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<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
}
}

View File

@ -443,53 +443,9 @@ class TileEditorOptionsTable(val mapEditorScreen: MapEditorScreen): Table(Camera
fun updateTileWhenClicked(tileInfo: TileInfo) { fun updateTileWhenClicked(tileInfo: TileInfo) {
tileAction(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) { private fun setCurrentHex(tileInfo: TileInfo, text: String) {
val tileGroup = TileGroup(tileInfo, TileSetStrings()) val tileGroup = TileGroup(tileInfo, TileSetStrings())