mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-27 05:46:43 -04:00
Add mod compatibility for extended map editor (#2840)
* Add mod compatibility for extended map editor * fix crashes when loading scenario with mods enabled * update imagegetter ruleset when loading scenario * reload ruleset on new scenrio * Fixed crash when units/improvements from the missing mods present in the map editor. * removeMissingModReferences - better name
This commit is contained in:
parent
4f919b32de
commit
a0daa6be4c
@ -3,6 +3,7 @@ package com.unciv.ui.mapeditor
|
|||||||
import com.unciv.UncivGame
|
import com.unciv.UncivGame
|
||||||
import com.unciv.logic.map.Scenario
|
import com.unciv.logic.map.Scenario
|
||||||
import com.unciv.models.ruleset.Ruleset
|
import com.unciv.models.ruleset.Ruleset
|
||||||
|
import com.unciv.models.ruleset.RulesetCache
|
||||||
import com.unciv.ui.newgamescreen.GameOptionsTable
|
import com.unciv.ui.newgamescreen.GameOptionsTable
|
||||||
import com.unciv.ui.newgamescreen.GameSetupInfo
|
import com.unciv.ui.newgamescreen.GameSetupInfo
|
||||||
import com.unciv.ui.newgamescreen.PlayerPickerTable
|
import com.unciv.ui.newgamescreen.PlayerPickerTable
|
||||||
@ -17,10 +18,10 @@ import com.unciv.ui.utils.*
|
|||||||
* @param [mapEditorScreen] previous screen from map editor.
|
* @param [mapEditorScreen] previous screen from map editor.
|
||||||
*/
|
*/
|
||||||
class GameParametersScreen(var mapEditorScreen: MapEditorScreen): IPreviousScreen, PickerScreen() {
|
class GameParametersScreen(var mapEditorScreen: MapEditorScreen): IPreviousScreen, PickerScreen() {
|
||||||
override var gameSetupInfo: GameSetupInfo = mapEditorScreen.gameSetupInfo
|
override var gameSetupInfo = mapEditorScreen.gameSetupInfo.clone()
|
||||||
override var ruleset: Ruleset = mapEditorScreen.ruleset
|
override var ruleset = RulesetCache.getComplexRuleset(gameSetupInfo.gameParameters)
|
||||||
var playerPickerTable = PlayerPickerTable(this, this.gameSetupInfo.gameParameters)
|
var playerPickerTable = PlayerPickerTable(this, gameSetupInfo.gameParameters)
|
||||||
var gameOptionsTable = GameOptionsTable(mapEditorScreen) { desiredCiv: String -> playerPickerTable.update(desiredCiv) }
|
var gameOptionsTable = GameOptionsTable(this) { desiredCiv: String -> playerPickerTable.update(desiredCiv) }
|
||||||
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -34,7 +35,8 @@ class GameParametersScreen(var mapEditorScreen: MapEditorScreen): IPreviousScree
|
|||||||
rightSideButton.onClick {
|
rightSideButton.onClick {
|
||||||
mapEditorScreen.gameSetupInfo = gameSetupInfo
|
mapEditorScreen.gameSetupInfo = gameSetupInfo
|
||||||
mapEditorScreen.scenario = Scenario(mapEditorScreen.tileMap, mapEditorScreen.gameSetupInfo.gameParameters)
|
mapEditorScreen.scenario = Scenario(mapEditorScreen.tileMap, mapEditorScreen.gameSetupInfo.gameParameters)
|
||||||
mapEditorScreen.ruleset = ruleset //TODO: figure out whether it is necessary
|
mapEditorScreen.ruleset.clear()
|
||||||
|
mapEditorScreen.ruleset.add(ruleset)
|
||||||
mapEditorScreen.tileEditorOptions.update()
|
mapEditorScreen.tileEditorOptions.update()
|
||||||
mapEditorScreen.mapHolder.updateTileGroups()
|
mapEditorScreen.mapHolder.updateTileGroups()
|
||||||
UncivGame.Current.setScreen(mapEditorScreen)
|
UncivGame.Current.setScreen(mapEditorScreen)
|
||||||
|
@ -18,17 +18,14 @@ import com.unciv.ui.newgamescreen.GameSetupInfo
|
|||||||
import com.unciv.ui.newgamescreen.IPreviousScreen
|
import com.unciv.ui.newgamescreen.IPreviousScreen
|
||||||
import com.unciv.ui.utils.*
|
import com.unciv.ui.utils.*
|
||||||
|
|
||||||
class MapEditorScreen(): IPreviousScreen, CameraStageBaseScreen() {
|
class MapEditorScreen(): CameraStageBaseScreen() {
|
||||||
// need for compatibility with PickerScreen
|
|
||||||
override fun setRightSideButtonEnabled(boolean: Boolean) {}
|
|
||||||
|
|
||||||
var mapName = ""
|
var mapName = ""
|
||||||
var tileMap = TileMap()
|
var tileMap = TileMap()
|
||||||
var scenarioName = "" // when loading map: mapName is taken as default for scenarioName
|
var scenarioName = "" // when loading map: mapName is taken as default for scenarioName
|
||||||
var scenario: Scenario? = null // main indicator whether scenario information is present
|
var scenario: Scenario? = null // main indicator whether scenario information is present
|
||||||
override var ruleset = RulesetCache.getBaseRuleset()
|
var ruleset = RulesetCache.getBaseRuleset()
|
||||||
|
|
||||||
override var gameSetupInfo = GameSetupInfo()
|
var gameSetupInfo = GameSetupInfo()
|
||||||
lateinit var mapHolder: EditorMapHolder
|
lateinit var mapHolder: EditorMapHolder
|
||||||
|
|
||||||
lateinit var tileEditorOptions: TileEditorOptionsTable
|
lateinit var tileEditorOptions: TileEditorOptionsTable
|
||||||
@ -63,7 +60,12 @@ class MapEditorScreen(): IPreviousScreen, CameraStageBaseScreen() {
|
|||||||
mapName = scenarioName
|
mapName = scenarioName
|
||||||
this.scenario = scenario
|
this.scenario = scenario
|
||||||
this.scenarioName = scenarioName
|
this.scenarioName = scenarioName
|
||||||
|
|
||||||
gameSetupInfo.gameParameters = scenario.gameParameters
|
gameSetupInfo.gameParameters = scenario.gameParameters
|
||||||
|
|
||||||
|
ruleset = RulesetCache.getComplexRuleset(scenario.gameParameters)
|
||||||
|
ImageGetter.ruleset = ruleset
|
||||||
|
ImageGetter.setTextureRegionDrawables()
|
||||||
initialize()
|
initialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,10 +3,8 @@ package com.unciv.ui.mapeditor
|
|||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.scenes.scene2d.Actor
|
import com.badlogic.gdx.scenes.scene2d.Actor
|
||||||
import com.badlogic.gdx.scenes.scene2d.Group
|
import com.badlogic.gdx.scenes.scene2d.Group
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Slider
|
import com.badlogic.gdx.scenes.scene2d.ui.Slider
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||||
import com.badlogic.gdx.utils.Align
|
|
||||||
import com.unciv.Constants
|
import com.unciv.Constants
|
||||||
import com.unciv.UncivGame
|
import com.unciv.UncivGame
|
||||||
import com.unciv.logic.civilization.CivilizationInfo
|
import com.unciv.logic.civilization.CivilizationInfo
|
||||||
@ -18,7 +16,6 @@ import com.unciv.models.metadata.Player
|
|||||||
import com.unciv.models.ruleset.Nation
|
import com.unciv.models.ruleset.Nation
|
||||||
import com.unciv.models.ruleset.tile.ResourceType
|
import com.unciv.models.ruleset.tile.ResourceType
|
||||||
import com.unciv.models.ruleset.tile.TerrainType
|
import com.unciv.models.ruleset.tile.TerrainType
|
||||||
import com.unciv.models.ruleset.unit.BaseUnit
|
|
||||||
import com.unciv.models.translations.tr
|
import com.unciv.models.translations.tr
|
||||||
import com.unciv.ui.tilegroups.TileGroup
|
import com.unciv.ui.tilegroups.TileGroup
|
||||||
import com.unciv.ui.tilegroups.TileSetStrings
|
import com.unciv.ui.tilegroups.TileSetStrings
|
||||||
@ -226,23 +223,26 @@ class TileEditorOptionsTable(val mapEditorScreen: MapEditorScreen): Table(Camera
|
|||||||
|
|
||||||
val nationsTable = Table()
|
val nationsTable = Table()
|
||||||
|
|
||||||
// default player - barbarians
|
// default player - first MajorCiv player
|
||||||
var currentPlayer = ""
|
val defaultPlayer = gameParameters.players.first{
|
||||||
var currentNation: Nation? = ruleset.nations.values.firstOrNull{ it.isBarbarian() }
|
it.chosenCiv != Constants.spectator && it.chosenCiv != Constants.random
|
||||||
|
}
|
||||||
|
var currentPlayer = getPlayerIndexString(defaultPlayer)
|
||||||
|
var currentNation: Nation = ruleset.nations[defaultPlayer.chosenCiv]!!
|
||||||
var currentUnit = ruleset.units.values.first()
|
var currentUnit = ruleset.units.values.first()
|
||||||
|
|
||||||
fun setUnitTileAction(){
|
fun setUnitTileAction(){
|
||||||
if (currentNation == null) return
|
val unitImage = ImageGetter.getUnitIcon(currentUnit.name, currentNation.getInnerColor())
|
||||||
val unitImage = ImageGetter.getUnitIcon(currentUnit.name, currentNation!!.getInnerColor())
|
.surroundWithCircle(40f*0.9f).apply { circle.color=currentNation.getOuterColor() }
|
||||||
.surroundWithCircle(40f).apply { color=currentNation!!.getOuterColor() }
|
.surroundWithCircle(40f, false).apply { circle.color=currentNation.getInnerColor() }
|
||||||
setCurrentHex(unitImage, currentUnit.name.tr()+ " - $currentPlayer ("+currentNation!!.name.tr()+")")
|
|
||||||
|
setCurrentHex(unitImage, currentUnit.name.tr()+ " - $currentPlayer ("+currentNation.name.tr()+")")
|
||||||
tileAction = {
|
tileAction = {
|
||||||
val unit = MapUnit()
|
val unit = MapUnit()
|
||||||
unit.baseUnit = currentUnit
|
unit.baseUnit = currentUnit
|
||||||
unit.name = currentUnit.name
|
unit.name = currentUnit.name
|
||||||
unit.owner = currentNation!!.name
|
unit.owner = currentNation.name
|
||||||
unit.civInfo = CivilizationInfo(currentNation!!.name).apply { nation=currentNation!! } // needed for the unit icon to render correctly
|
unit.civInfo = CivilizationInfo(currentNation.name).apply { nation=currentNation } // needed for the unit icon to render correctly
|
||||||
unit.updateUniques()
|
unit.updateUniques()
|
||||||
if (unit.movement.canMoveTo(it)) {
|
if (unit.movement.canMoveTo(it)) {
|
||||||
when {
|
when {
|
||||||
|
@ -170,7 +170,6 @@ class GameOptionsTable(previousScreen: IPreviousScreen, val updatePlayerPickerTa
|
|||||||
val modRulesets = RulesetCache.values.filter { it.name != "" }
|
val modRulesets = RulesetCache.values.filter { it.name != "" }
|
||||||
if (modRulesets.isEmpty()) return
|
if (modRulesets.isEmpty()) return
|
||||||
|
|
||||||
|
|
||||||
add("Mods:".toLabel(fontSize = 24)).padTop(16f).colspan(2).row()
|
add("Mods:".toLabel(fontSize = 24)).padTop(16f).colspan(2).row()
|
||||||
val modCheckboxTable = Table().apply { defaults().pad(5f) }
|
val modCheckboxTable = Table().apply { defaults().pad(5f) }
|
||||||
for (mod in modRulesets) {
|
for (mod in modRulesets) {
|
||||||
|
@ -103,8 +103,12 @@ class MapOptionsTable(val newGameScreen: NewGameScreen): Table() {
|
|||||||
scenarioFileSelectBox.onChange {
|
scenarioFileSelectBox.onChange {
|
||||||
mapParameters.name = scenarioFileSelectBox.selected!!
|
mapParameters.name = scenarioFileSelectBox.selected!!
|
||||||
val scenario = MapSaver.loadScenario(mapParameters.name)
|
val scenario = MapSaver.loadScenario(mapParameters.name)
|
||||||
newGameScreen.gameSetupInfo.gameParameters = scenario.gameParameters
|
newGameScreen.apply {
|
||||||
newGameScreen.updateTables()
|
gameSetupInfo.gameParameters = scenario.gameParameters
|
||||||
|
newGameOptionsTable.gameParameters = scenario.gameParameters
|
||||||
|
newGameOptionsTable.reloadRuleset()
|
||||||
|
updateTables()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return scenarioFileSelectBox
|
return scenarioFileSelectBox
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,14 @@ class GameSetupInfo(var gameId:String, var gameParameters: GameParameters, var m
|
|||||||
constructor() : this("", GameParameters(), MapParameters())
|
constructor() : this("", GameParameters(), MapParameters())
|
||||||
constructor(gameInfo: GameInfo) : this("", gameInfo.gameParameters.clone(), gameInfo.tileMap.mapParameters)
|
constructor(gameInfo: GameInfo) : this("", gameInfo.gameParameters.clone(), gameInfo.tileMap.mapParameters)
|
||||||
constructor(gameParameters: GameParameters, mapParameters: MapParameters) : this("", gameParameters, mapParameters)
|
constructor(gameParameters: GameParameters, mapParameters: MapParameters) : this("", gameParameters, mapParameters)
|
||||||
|
|
||||||
|
fun clone(): GameSetupInfo {
|
||||||
|
val toReturn = GameSetupInfo()
|
||||||
|
toReturn.gameId = this.gameId
|
||||||
|
toReturn.gameParameters = this.gameParameters
|
||||||
|
toReturn.mapParameters = this.mapParameters
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NewGameScreen(previousScreen:CameraStageBaseScreen, _gameSetupInfo: GameSetupInfo?=null): IPreviousScreen, PickerScreen() {
|
class NewGameScreen(previousScreen:CameraStageBaseScreen, _gameSetupInfo: GameSetupInfo?=null): IPreviousScreen, PickerScreen() {
|
||||||
|
@ -78,7 +78,7 @@ class PlayerPickerTable(val previousScreen: IPreviousScreen, var gameParameters:
|
|||||||
val availableCiv = getAvailablePlayerCivs().firstOrNull { !it.isSpectator() }
|
val availableCiv = getAvailablePlayerCivs().firstOrNull { !it.isSpectator() }
|
||||||
if (availableCiv != null) player = Player(availableCiv.name)
|
if (availableCiv != null) player = Player(availableCiv.name)
|
||||||
// Spectators only Humans
|
// Spectators only Humans
|
||||||
else player = Player("Spectator").apply { playerType = PlayerType.Human }
|
else player = Player(Constants.spectator).apply { playerType = PlayerType.Human }
|
||||||
}
|
}
|
||||||
gameParameters.players.add(player)
|
gameParameters.players.add(player)
|
||||||
update()
|
update()
|
||||||
@ -89,13 +89,12 @@ class PlayerPickerTable(val previousScreen: IPreviousScreen, var gameParameters:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If new mod removes nations already chosen by some player
|
* Reassigns removed mod references to random civilization
|
||||||
* sets first civilization available in the ruleset
|
|
||||||
*/
|
*/
|
||||||
private fun reassignRemovedModReferences() {
|
private fun reassignRemovedModReferences() {
|
||||||
for (player in gameParameters.players) {
|
for (player in gameParameters.players) {
|
||||||
if (!previousScreen.ruleset.nations.containsKey(player.chosenCiv))
|
if (!previousScreen.ruleset.nations.containsKey(player.chosenCiv))
|
||||||
player.chosenCiv = "Random"
|
player.chosenCiv = Constants.random
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +106,7 @@ class PlayerPickerTable(val previousScreen: IPreviousScreen, var gameParameters:
|
|||||||
// No auto-select if desiredCiv already used
|
// No auto-select if desiredCiv already used
|
||||||
if (gameParameters.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)
|
// Do auto-select, silently no-op if no suitable slot (human with 'random' choice)
|
||||||
gameParameters.players.firstOrNull { it.chosenCiv == "Random" && it.playerType == PlayerType.Human }?.chosenCiv = desiredCiv
|
gameParameters.players.firstOrNull { it.chosenCiv == Constants.random && it.playerType == PlayerType.Human }?.chosenCiv = desiredCiv
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -190,7 +189,7 @@ class PlayerPickerTable(val previousScreen: IPreviousScreen, var gameParameters:
|
|||||||
*/
|
*/
|
||||||
private fun getNationTable(player: Player): Table {
|
private fun getNationTable(player: Player): Table {
|
||||||
val nationTable = Table()
|
val nationTable = Table()
|
||||||
val nationImage = if (player.chosenCiv == "Random") "?".toLabel(Color.WHITE, 25)
|
val nationImage = if (player.chosenCiv == Constants.random) "?".toLabel(Color.WHITE, 25)
|
||||||
.apply { this.setAlignment(Align.center) }
|
.apply { this.setAlignment(Align.center) }
|
||||||
.surroundWithCircle(36f).apply { circle.color = Color.BLACK }
|
.surroundWithCircle(36f).apply { circle.color = Color.BLACK }
|
||||||
.surroundWithCircle(40f, false).apply { circle.color = Color.WHITE }
|
.surroundWithCircle(40f, false).apply { circle.color = Color.WHITE }
|
||||||
@ -221,10 +220,10 @@ class PlayerPickerTable(val previousScreen: IPreviousScreen, var gameParameters:
|
|||||||
.apply { this.setAlignment(Align.center) }
|
.apply { this.setAlignment(Align.center) }
|
||||||
.surroundWithCircle(45f).apply { circle.color = Color.BLACK }
|
.surroundWithCircle(45f).apply { circle.color = Color.BLACK }
|
||||||
.surroundWithCircle(50f, false).apply { circle.color = Color.WHITE }).pad(10f)
|
.surroundWithCircle(50f, false).apply { circle.color = Color.WHITE }).pad(10f)
|
||||||
randomPlayerTable.add("Random".toLabel())
|
randomPlayerTable.add(Constants.random.toLabel())
|
||||||
randomPlayerTable.touchable = Touchable.enabled
|
randomPlayerTable.touchable = Touchable.enabled
|
||||||
randomPlayerTable.onClick {
|
randomPlayerTable.onClick {
|
||||||
player.chosenCiv = "Random"
|
player.chosenCiv = Constants.random
|
||||||
nationsPopup.close()
|
nationsPopup.close()
|
||||||
update()
|
update()
|
||||||
}
|
}
|
||||||
|
@ -297,6 +297,8 @@ open class TileGroup(var tileInfo: TileInfo, var tileSetStrings:TileSetStrings)
|
|||||||
val tileIsViewable = viewingCiv == null || isViewable(viewingCiv)
|
val tileIsViewable = viewingCiv == null || isViewable(viewingCiv)
|
||||||
val showMilitaryUnit = viewingCiv == null || showMilitaryUnit(viewingCiv)
|
val showMilitaryUnit = viewingCiv == null || showMilitaryUnit(viewingCiv)
|
||||||
|
|
||||||
|
removeMissingModReferences()
|
||||||
|
|
||||||
updateTileImage(viewingCiv)
|
updateTileImage(viewingCiv)
|
||||||
updateRivers(tileInfo.hasBottomRightRiver, tileInfo.hasBottomRiver, tileInfo.hasBottomLeftRiver)
|
updateRivers(tileInfo.hasBottomRightRiver, tileInfo.hasBottomRiver, tileInfo.hasBottomLeftRiver)
|
||||||
updateTerrainBaseImage()
|
updateTerrainBaseImage()
|
||||||
@ -318,6 +320,18 @@ open class TileGroup(var tileInfo: TileInfo, var tileSetStrings:TileSetStrings)
|
|||||||
fogImage.isVisible = !(tileIsViewable || showEntireMap)
|
fogImage.isVisible = !(tileIsViewable || showEntireMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun removeMissingModReferences() {
|
||||||
|
val improvementName = tileInfo.improvement
|
||||||
|
if(improvementName != null && improvementName.startsWith("StartingLocation ")){
|
||||||
|
val nationName = improvementName.removePrefix("StartingLocation ")
|
||||||
|
if (!tileInfo.ruleset.nations.containsKey(nationName))
|
||||||
|
tileInfo.improvement = null
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unit in tileInfo.getUnits())
|
||||||
|
if (!tileInfo.ruleset.nations.containsKey(unit.owner)) unit.removeFromTile()
|
||||||
|
}
|
||||||
|
|
||||||
private fun updateTerrainBaseImage() {
|
private fun updateTerrainBaseImage() {
|
||||||
if (tileInfo.baseTerrain == baseTerrain) return
|
if (tileInfo.baseTerrain == baseTerrain) return
|
||||||
baseTerrain = tileInfo.baseTerrain
|
baseTerrain = tileInfo.baseTerrain
|
||||||
|
Loading…
x
Reference in New Issue
Block a user