mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-26 13:27:22 -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.logic.map.Scenario
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.RulesetCache
|
||||
import com.unciv.ui.newgamescreen.GameOptionsTable
|
||||
import com.unciv.ui.newgamescreen.GameSetupInfo
|
||||
import com.unciv.ui.newgamescreen.PlayerPickerTable
|
||||
@ -17,10 +18,10 @@ import com.unciv.ui.utils.*
|
||||
* @param [mapEditorScreen] previous screen from map editor.
|
||||
*/
|
||||
class GameParametersScreen(var mapEditorScreen: MapEditorScreen): IPreviousScreen, PickerScreen() {
|
||||
override var gameSetupInfo: GameSetupInfo = mapEditorScreen.gameSetupInfo
|
||||
override var ruleset: Ruleset = mapEditorScreen.ruleset
|
||||
var playerPickerTable = PlayerPickerTable(this, this.gameSetupInfo.gameParameters)
|
||||
var gameOptionsTable = GameOptionsTable(mapEditorScreen) { desiredCiv: String -> playerPickerTable.update(desiredCiv) }
|
||||
override var gameSetupInfo = mapEditorScreen.gameSetupInfo.clone()
|
||||
override var ruleset = RulesetCache.getComplexRuleset(gameSetupInfo.gameParameters)
|
||||
var playerPickerTable = PlayerPickerTable(this, gameSetupInfo.gameParameters)
|
||||
var gameOptionsTable = GameOptionsTable(this) { desiredCiv: String -> playerPickerTable.update(desiredCiv) }
|
||||
|
||||
|
||||
init {
|
||||
@ -34,7 +35,8 @@ class GameParametersScreen(var mapEditorScreen: MapEditorScreen): IPreviousScree
|
||||
rightSideButton.onClick {
|
||||
mapEditorScreen.gameSetupInfo = gameSetupInfo
|
||||
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.mapHolder.updateTileGroups()
|
||||
UncivGame.Current.setScreen(mapEditorScreen)
|
||||
|
@ -18,17 +18,14 @@ import com.unciv.ui.newgamescreen.GameSetupInfo
|
||||
import com.unciv.ui.newgamescreen.IPreviousScreen
|
||||
import com.unciv.ui.utils.*
|
||||
|
||||
class MapEditorScreen(): IPreviousScreen, CameraStageBaseScreen() {
|
||||
// need for compatibility with PickerScreen
|
||||
override fun setRightSideButtonEnabled(boolean: Boolean) {}
|
||||
|
||||
class MapEditorScreen(): CameraStageBaseScreen() {
|
||||
var mapName = ""
|
||||
var tileMap = TileMap()
|
||||
var scenarioName = "" // when loading map: mapName is taken as default for scenarioName
|
||||
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 tileEditorOptions: TileEditorOptionsTable
|
||||
@ -63,7 +60,12 @@ class MapEditorScreen(): IPreviousScreen, CameraStageBaseScreen() {
|
||||
mapName = scenarioName
|
||||
this.scenario = scenario
|
||||
this.scenarioName = scenarioName
|
||||
|
||||
gameSetupInfo.gameParameters = scenario.gameParameters
|
||||
|
||||
ruleset = RulesetCache.getComplexRuleset(scenario.gameParameters)
|
||||
ImageGetter.ruleset = ruleset
|
||||
ImageGetter.setTextureRegionDrawables()
|
||||
initialize()
|
||||
}
|
||||
|
||||
|
@ -3,10 +3,8 @@ package com.unciv.ui.mapeditor
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor
|
||||
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.Table
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
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.tile.ResourceType
|
||||
import com.unciv.models.ruleset.tile.TerrainType
|
||||
import com.unciv.models.ruleset.unit.BaseUnit
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.tilegroups.TileGroup
|
||||
import com.unciv.ui.tilegroups.TileSetStrings
|
||||
@ -226,23 +223,26 @@ class TileEditorOptionsTable(val mapEditorScreen: MapEditorScreen): Table(Camera
|
||||
|
||||
val nationsTable = Table()
|
||||
|
||||
// default player - barbarians
|
||||
var currentPlayer = ""
|
||||
var currentNation: Nation? = ruleset.nations.values.firstOrNull{ it.isBarbarian() }
|
||||
|
||||
// default player - first MajorCiv player
|
||||
val defaultPlayer = gameParameters.players.first{
|
||||
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()
|
||||
|
||||
fun setUnitTileAction(){
|
||||
if (currentNation == null) return
|
||||
val unitImage = ImageGetter.getUnitIcon(currentUnit.name, currentNation!!.getInnerColor())
|
||||
.surroundWithCircle(40f).apply { color=currentNation!!.getOuterColor() }
|
||||
setCurrentHex(unitImage, currentUnit.name.tr()+ " - $currentPlayer ("+currentNation!!.name.tr()+")")
|
||||
val unitImage = ImageGetter.getUnitIcon(currentUnit.name, currentNation.getInnerColor())
|
||||
.surroundWithCircle(40f*0.9f).apply { circle.color=currentNation.getOuterColor() }
|
||||
.surroundWithCircle(40f, false).apply { circle.color=currentNation.getInnerColor() }
|
||||
|
||||
setCurrentHex(unitImage, currentUnit.name.tr()+ " - $currentPlayer ("+currentNation.name.tr()+")")
|
||||
tileAction = {
|
||||
val unit = MapUnit()
|
||||
unit.baseUnit = currentUnit
|
||||
unit.name = currentUnit.name
|
||||
unit.owner = currentNation!!.name
|
||||
unit.civInfo = CivilizationInfo(currentNation!!.name).apply { nation=currentNation!! } // needed for the unit icon to render correctly
|
||||
unit.owner = currentNation.name
|
||||
unit.civInfo = CivilizationInfo(currentNation.name).apply { nation=currentNation } // needed for the unit icon to render correctly
|
||||
unit.updateUniques()
|
||||
if (unit.movement.canMoveTo(it)) {
|
||||
when {
|
||||
|
@ -170,7 +170,6 @@ class GameOptionsTable(previousScreen: IPreviousScreen, val updatePlayerPickerTa
|
||||
val modRulesets = RulesetCache.values.filter { it.name != "" }
|
||||
if (modRulesets.isEmpty()) return
|
||||
|
||||
|
||||
add("Mods:".toLabel(fontSize = 24)).padTop(16f).colspan(2).row()
|
||||
val modCheckboxTable = Table().apply { defaults().pad(5f) }
|
||||
for (mod in modRulesets) {
|
||||
|
@ -103,8 +103,12 @@ class MapOptionsTable(val newGameScreen: NewGameScreen): Table() {
|
||||
scenarioFileSelectBox.onChange {
|
||||
mapParameters.name = scenarioFileSelectBox.selected!!
|
||||
val scenario = MapSaver.loadScenario(mapParameters.name)
|
||||
newGameScreen.gameSetupInfo.gameParameters = scenario.gameParameters
|
||||
newGameScreen.updateTables()
|
||||
newGameScreen.apply {
|
||||
gameSetupInfo.gameParameters = scenario.gameParameters
|
||||
newGameOptionsTable.gameParameters = scenario.gameParameters
|
||||
newGameOptionsTable.reloadRuleset()
|
||||
updateTables()
|
||||
}
|
||||
}
|
||||
return scenarioFileSelectBox
|
||||
}
|
||||
|
@ -23,6 +23,14 @@ class GameSetupInfo(var gameId:String, var gameParameters: GameParameters, var m
|
||||
constructor() : this("", GameParameters(), MapParameters())
|
||||
constructor(gameInfo: GameInfo) : this("", gameInfo.gameParameters.clone(), gameInfo.tileMap.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() {
|
||||
|
@ -78,7 +78,7 @@ class PlayerPickerTable(val previousScreen: IPreviousScreen, var gameParameters:
|
||||
val availableCiv = getAvailablePlayerCivs().firstOrNull { !it.isSpectator() }
|
||||
if (availableCiv != null) player = Player(availableCiv.name)
|
||||
// Spectators only Humans
|
||||
else player = Player("Spectator").apply { playerType = PlayerType.Human }
|
||||
else player = Player(Constants.spectator).apply { playerType = PlayerType.Human }
|
||||
}
|
||||
gameParameters.players.add(player)
|
||||
update()
|
||||
@ -89,13 +89,12 @@ class PlayerPickerTable(val previousScreen: IPreviousScreen, var gameParameters:
|
||||
}
|
||||
|
||||
/**
|
||||
* If new mod removes nations already chosen by some player
|
||||
* sets first civilization available in the ruleset
|
||||
* Reassigns removed mod references to random civilization
|
||||
*/
|
||||
private fun reassignRemovedModReferences() {
|
||||
for (player in gameParameters.players) {
|
||||
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
|
||||
if (gameParameters.players.any { it.chosenCiv == desiredCiv }) return
|
||||
// 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 {
|
||||
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) }
|
||||
.surroundWithCircle(36f).apply { circle.color = Color.BLACK }
|
||||
.surroundWithCircle(40f, false).apply { circle.color = Color.WHITE }
|
||||
@ -221,10 +220,10 @@ class PlayerPickerTable(val previousScreen: IPreviousScreen, var gameParameters:
|
||||
.apply { this.setAlignment(Align.center) }
|
||||
.surroundWithCircle(45f).apply { circle.color = Color.BLACK }
|
||||
.surroundWithCircle(50f, false).apply { circle.color = Color.WHITE }).pad(10f)
|
||||
randomPlayerTable.add("Random".toLabel())
|
||||
randomPlayerTable.add(Constants.random.toLabel())
|
||||
randomPlayerTable.touchable = Touchable.enabled
|
||||
randomPlayerTable.onClick {
|
||||
player.chosenCiv = "Random"
|
||||
player.chosenCiv = Constants.random
|
||||
nationsPopup.close()
|
||||
update()
|
||||
}
|
||||
|
@ -297,6 +297,8 @@ open class TileGroup(var tileInfo: TileInfo, var tileSetStrings:TileSetStrings)
|
||||
val tileIsViewable = viewingCiv == null || isViewable(viewingCiv)
|
||||
val showMilitaryUnit = viewingCiv == null || showMilitaryUnit(viewingCiv)
|
||||
|
||||
removeMissingModReferences()
|
||||
|
||||
updateTileImage(viewingCiv)
|
||||
updateRivers(tileInfo.hasBottomRightRiver, tileInfo.hasBottomRiver, tileInfo.hasBottomLeftRiver)
|
||||
updateTerrainBaseImage()
|
||||
@ -318,6 +320,18 @@ open class TileGroup(var tileInfo: TileInfo, var tileSetStrings:TileSetStrings)
|
||||
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() {
|
||||
if (tileInfo.baseTerrain == baseTerrain) return
|
||||
baseTerrain = tileInfo.baseTerrain
|
||||
|
Loading…
x
Reference in New Issue
Block a user