Scenarios editor first part of changes (#2764)
* Unnecessary line. * First part of changes * All features required for basic functionality were implemented. Additional features: - Sync between player adding/deleting and it's unit on map editor - Sync between player's nation change and all it's units Final prototype ready for beta-test. * Second part of commits * Small fix of TileMap.stripAllUnits * Small post fixes. Bring back deleting rivers, accidentally removed during merging. * Fixes by your comments * reverse if statement for "Random" chosenCiv * tileEditorOptions take updated this.gameParameters from constructors * updated unit placement. Check validity by unit.canMoveTo() Correct airunit placement in carriers. * tileMap.stripAllUnits() refactor
This commit is contained in:
parent
e4a5f2af18
commit
de03a727f6
14 changed files with 305 additions and 132 deletions
|
@ -11,6 +11,7 @@ import com.unciv.logic.map.TileMap
|
|||
import com.unciv.logic.trade.TradeOffer
|
||||
import com.unciv.logic.trade.TradeType
|
||||
import com.unciv.models.metadata.GameParameters
|
||||
import com.unciv.models.metadata.Player
|
||||
import com.unciv.models.ruleset.Difficulty
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.RulesetCache
|
||||
|
|
|
@ -114,12 +114,15 @@ object GameStarter {
|
|||
gameInfo.civilizations.filter { !it.isBarbarian() },
|
||||
gameInfo.tileMap)
|
||||
|
||||
// remove starting locations one we're done
|
||||
// remove starting locations once we're done
|
||||
for (tile in gameInfo.tileMap.values) {
|
||||
if (tile.improvement != null && tile.improvement!!.startsWith("StartingLocation "))
|
||||
tile.improvement = null
|
||||
// set max starting movement for units loaded from map
|
||||
for(unit in tile.getUnits()) unit.currentMovement = unit.getMaxMovement().toFloat()
|
||||
}
|
||||
|
||||
|
||||
// For later starting eras, or for civs like Polynesia with a different Warrior, we need different starting units
|
||||
fun getWarriorEquivalent(civ: CivilizationInfo): String {
|
||||
val availableMilitaryUnits = gameInfo.ruleSet.units.values.filter {
|
||||
|
|
|
@ -20,7 +20,7 @@ object MapSaver {
|
|||
}
|
||||
|
||||
fun saveScenario(scenarioName:String, scenario: Scenario) {
|
||||
getScenario(scenarioName).writeString(json().toJson(scenario), false)
|
||||
getScenario(scenarioName).writeString(Gzip.zip(json().toJson(scenario)), false)
|
||||
}
|
||||
|
||||
fun loadMap(mapName: String): TileMap {
|
||||
|
@ -30,8 +30,9 @@ object MapSaver {
|
|||
}
|
||||
|
||||
fun loadScenario(scenarioName: String): Scenario {
|
||||
val scenarioJson = getScenario(scenarioName).readString()
|
||||
return json().fromJson(Scenario::class.java, scenarioJson)
|
||||
val gzippedString = getScenario(scenarioName).readString()
|
||||
val unzippedJson = Gzip.unzip(gzippedString)
|
||||
return json().fromJson(Scenario::class.java, unzippedJson)
|
||||
}
|
||||
|
||||
fun deleteMap(mapName: String) = getMap(mapName).delete()
|
||||
|
|
|
@ -429,6 +429,10 @@ open class TileInfo {
|
|||
}
|
||||
}
|
||||
|
||||
fun stripUnits() {
|
||||
for (unit in this.getUnits()) unit.removeFromTile()
|
||||
}
|
||||
|
||||
fun startWorkingOnImprovement(improvement: TileImprovement, civInfo: CivilizationInfo) {
|
||||
improvementInProgress = improvement.name
|
||||
turnsToImprovement = improvement.getTurnsToBuild(civInfo)
|
||||
|
|
|
@ -5,6 +5,8 @@ import com.unciv.Constants
|
|||
import com.unciv.logic.GameInfo
|
||||
import com.unciv.logic.HexMath
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.models.metadata.Player
|
||||
import com.unciv.models.ruleset.Nation
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import kotlin.math.abs
|
||||
|
||||
|
@ -215,6 +217,39 @@ class TileMap {
|
|||
return viewableTiles
|
||||
}
|
||||
|
||||
/** Strips all units from [TileMap]
|
||||
* @return stripped clone of [TileMap]
|
||||
*/
|
||||
fun stripAllUnits(): TileMap {
|
||||
return clone().apply { tileList.forEach {it.stripUnits()} }
|
||||
}
|
||||
|
||||
/** Strips all units and starting location from [TileMap] for specified [Player]
|
||||
* Operation in place
|
||||
* @param player units of player to be stripped off
|
||||
*/
|
||||
fun stripPlayer(player: Player) {
|
||||
tileList.forEach {
|
||||
if (it.improvement == "StartingLocation " + player.chosenCiv) { it.improvement = null }
|
||||
for (unit in it.getUnits()) if (unit.owner == player.chosenCiv) unit.removeFromTile()
|
||||
}
|
||||
}
|
||||
|
||||
/** Finds all units and starting location of [Player] and changes their [Nation]
|
||||
* Operation in place
|
||||
* @param player player whose all units will be changed
|
||||
* @param newNation new nation to be set up
|
||||
*/
|
||||
fun switchPlayersNation(player: Player, newNation: Nation) {
|
||||
tileList.forEach {
|
||||
if (it.improvement == "StartingLocation " + player.chosenCiv) { it.improvement = "StartingLocation "+newNation.name }
|
||||
for (unit in it.getUnits()) if (unit.owner == player.chosenCiv) {
|
||||
unit.owner = newNation.name
|
||||
unit.civInfo = CivilizationInfo(newNation.name).apply { nation=newNation }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setTransients(ruleset: Ruleset, setUnitCivTransients:Boolean=true) { // In the map editor, no Civs or Game exist, so we won't set the unit transients
|
||||
val topY= tileList.asSequence().map { it.position.y.toInt() }.max()!!
|
||||
bottomY= tileList.asSequence().map { it.position.y.toInt() }.min()!!
|
||||
|
|
|
@ -3,8 +3,7 @@ package com.unciv.models.metadata
|
|||
import com.unciv.Constants
|
||||
import com.unciv.logic.civilization.PlayerType
|
||||
|
||||
class Player {
|
||||
class Player(var chosenCiv: String = Constants.random) {
|
||||
var playerType: PlayerType = PlayerType.AI
|
||||
var chosenCiv = Constants.random
|
||||
var playerId=""
|
||||
}
|
|
@ -1,83 +1,36 @@
|
|||
package com.unciv.ui.mapeditor
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextField
|
||||
import com.unciv.logic.MapSaver
|
||||
import com.unciv.logic.map.MapType
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.map.Scenario
|
||||
import com.unciv.logic.map.TileMap
|
||||
import com.unciv.models.metadata.Player
|
||||
import com.unciv.ui.newgamescreen.GameOptionsTable
|
||||
import com.unciv.ui.newgamescreen.GameSetupInfo
|
||||
import com.unciv.ui.newgamescreen.PlayerPickerTable
|
||||
import com.unciv.ui.newgamescreen.PreviousScreenInterface
|
||||
import com.unciv.ui.newgamescreen.IPreviousScreen
|
||||
import com.unciv.ui.pickerscreens.PickerScreen
|
||||
import com.unciv.ui.utils.*
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
class GameParametersScreen(var mapEditorScreen: MapEditorScreen): PickerScreen() {
|
||||
var playerPickerTable = PlayerPickerTable(mapEditorScreen, mapEditorScreen.gameSetupInfo.gameParameters)
|
||||
class GameParametersScreen(var mapEditorScreen: MapEditorScreen): IPreviousScreen, PickerScreen() {
|
||||
|
||||
override var gameSetupInfo: GameSetupInfo = mapEditorScreen.gameSetupInfo
|
||||
var playerPickerTable = PlayerPickerTable(this, this.gameSetupInfo.gameParameters)
|
||||
var gameOptionsTable = GameOptionsTable(mapEditorScreen.gameSetupInfo) { desiredCiv: String -> playerPickerTable.update(desiredCiv) }
|
||||
|
||||
init {
|
||||
setDefaultCloseAction(mapEditorScreen)
|
||||
scrollPane.setScrollingDisabled(true, true)
|
||||
|
||||
// update players list from tileMap starting locations
|
||||
if (mapEditorScreen.scenario == null) {
|
||||
mapEditorScreen.gameSetupInfo.gameParameters.players = getPlayersFromMap(mapEditorScreen.tileMap)
|
||||
}
|
||||
|
||||
playerPickerTable.apply { locked = true }.update()
|
||||
val scenarioNameEditor = TextField(mapEditorScreen.scenarioName, skin)
|
||||
|
||||
topTable.add(playerPickerTable)
|
||||
topTable.addSeparatorVertical()
|
||||
topTable.add(gameOptionsTable).row()
|
||||
topTable.add(scenarioNameEditor)
|
||||
rightSideButton.setText("Save scenario")
|
||||
rightSideButton.setText("OK")
|
||||
rightSideButton.onClick {
|
||||
thread(name = "SaveScenario") {
|
||||
try {
|
||||
mapEditorScreen.tileMap.mapParameters.type = MapType.scenario
|
||||
mapEditorScreen.scenario = Scenario(mapEditorScreen.tileMap, mapEditorScreen.gameSetupInfo.gameParameters)
|
||||
mapEditorScreen.scenarioName = scenarioNameEditor.text
|
||||
MapSaver.saveScenario(scenarioNameEditor.text, mapEditorScreen.scenario!!)
|
||||
|
||||
game.setScreen(mapEditorScreen)
|
||||
Gdx.app.postRunnable {
|
||||
ResponsePopup("Scenario saved", mapEditorScreen) // todo - add this text to translations
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
ex.printStackTrace()
|
||||
Gdx.app.postRunnable {
|
||||
val cantLoadGamePopup = Popup(mapEditorScreen)
|
||||
cantLoadGamePopup.addGoodSizedLabel("It looks like your scenario can't be saved!").row()
|
||||
cantLoadGamePopup.addCloseButton()
|
||||
cantLoadGamePopup.open(force = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
mapEditorScreen.gameSetupInfo = gameSetupInfo
|
||||
mapEditorScreen.scenario = Scenario(mapEditorScreen.tileMap, mapEditorScreen.gameSetupInfo.gameParameters)
|
||||
mapEditorScreen.tileEditorOptions.update()
|
||||
mapEditorScreen.mapHolder.updateTileGroups()
|
||||
UncivGame.Current.setScreen(mapEditorScreen)
|
||||
dispose()
|
||||
}
|
||||
|
||||
rightSideButton.isEnabled = scenarioNameEditor.text.isNotEmpty()
|
||||
scenarioNameEditor.addListener {
|
||||
mapEditorScreen.scenarioName = scenarioNameEditor.text
|
||||
rightSideButton.isEnabled = scenarioNameEditor.text.isNotEmpty()
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,8 @@ class LoadScenarioScreen(previousMap: TileMap?): PickerScreen(){
|
|||
init {
|
||||
rightSideButton.setText("Load scenario".tr())
|
||||
rightSideButton.onClick {
|
||||
UncivGame.Current.setScreen(MapEditorScreen(MapSaver.loadScenario(chosenScenario)).apply { scenarioName = chosenScenario })
|
||||
val mapEditorScreen = MapEditorScreen(MapSaver.loadScenario(chosenScenario), chosenScenario)
|
||||
UncivGame.Current.setScreen(mapEditorScreen)
|
||||
dispose()
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.unciv.ui.mapeditor
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextField
|
||||
import com.badlogic.gdx.utils.Json
|
||||
import com.unciv.Constants
|
||||
|
@ -34,12 +35,11 @@ class MapEditorMenuPopup(var mapEditorScreen: MapEditorScreen): Popup(mapEditorS
|
|||
addCopyMapAsTextButton()
|
||||
addLoadMapButton()
|
||||
addUploadMapButton()
|
||||
|
||||
if (UncivGame.Current.scenarioDebugSwitch) {
|
||||
addScenarioButton()
|
||||
addSaveScenarioButton()
|
||||
addLoadScenarioButton()
|
||||
}
|
||||
|
||||
addExitMapEditorButton()
|
||||
addCloseOptionsButton()
|
||||
}
|
||||
|
@ -157,15 +157,54 @@ class MapEditorMenuPopup(var mapEditorScreen: MapEditorScreen): Popup(mapEditorS
|
|||
|
||||
private fun Popup.addScenarioButton() {
|
||||
var scenarioButton = "".toTextButton()
|
||||
if (mapEditorScreen.scenario != null) {
|
||||
if (mapEditorScreen.hasScenario()) {
|
||||
scenarioButton.setText("Edit scenario")
|
||||
} else {
|
||||
scenarioButton.setText("Create scenario")
|
||||
// for newly created scenarios read players from tileMap
|
||||
val players = getPlayersFromMap(mapEditorScreen.tileMap)
|
||||
mapEditorScreen.gameSetupInfo.gameParameters.players = players
|
||||
}
|
||||
add(scenarioButton).row()
|
||||
scenarioButton.onClick {
|
||||
remove()
|
||||
UncivGame.Current.setScreen(GameParametersScreen(mapEditorScreen))
|
||||
close()
|
||||
UncivGame.Current.setScreen(GameParametersScreen(mapEditorScreen).apply {
|
||||
playerPickerTable.noRandom = true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun Popup.addSaveScenarioButton() {
|
||||
val saveScenarioButton = "Save scenario".toTextButton()
|
||||
add(saveScenarioButton).row()
|
||||
saveScenarioButton.onClick {
|
||||
thread(name = "SaveScenario") {
|
||||
try {
|
||||
mapEditorScreen.tileMap.mapParameters.type = MapType.scenario
|
||||
mapEditorScreen.scenario = Scenario(mapEditorScreen.tileMap, mapEditorScreen.gameSetupInfo.gameParameters)
|
||||
mapEditorScreen.scenarioName = mapNameEditor.text
|
||||
MapSaver.saveScenario(mapNameEditor.text, mapEditorScreen.scenario!!)
|
||||
|
||||
close()
|
||||
Gdx.app.postRunnable {
|
||||
ResponsePopup("Scenario saved", mapEditorScreen) // todo - add this text to translations
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
ex.printStackTrace()
|
||||
Gdx.app.postRunnable {
|
||||
val cantLoadGamePopup = Popup(mapEditorScreen)
|
||||
cantLoadGamePopup.addGoodSizedLabel("It looks like your scenario can't be saved!").row()
|
||||
cantLoadGamePopup.addCloseButton()
|
||||
cantLoadGamePopup.open(force = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
saveScenarioButton.isEnabled = mapNameEditor.text.isNotEmpty() && mapEditorScreen.hasScenario()
|
||||
mapNameEditor.addListener {
|
||||
mapEditorScreen.scenarioName = mapNameEditor.text
|
||||
saveScenarioButton.isEnabled = mapNameEditor.text.isNotEmpty() && mapEditorScreen.hasScenario()
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,4 +229,16 @@ class MapEditorMenuPopup(var mapEditorScreen: MapEditorScreen): Popup(mapEditorS
|
|||
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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.unciv.ui.mapeditor
|
||||
|
||||
import com.badlogic.gdx.Game
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.math.Vector2
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent
|
||||
|
@ -15,22 +14,22 @@ import com.unciv.logic.map.TileInfo
|
|||
import com.unciv.logic.map.TileMap
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.newgamescreen.GameSetupInfo
|
||||
import com.unciv.ui.newgamescreen.PreviousScreenInterface
|
||||
import com.unciv.ui.newgamescreen.IPreviousScreen
|
||||
import com.unciv.ui.utils.*
|
||||
|
||||
class MapEditorScreen(): PreviousScreenInterface, CameraStageBaseScreen() {
|
||||
// need for compatibility with NewGameScreen: PickerScreen
|
||||
class MapEditorScreen(): IPreviousScreen, CameraStageBaseScreen() {
|
||||
// need for compatibility with PickerScreen
|
||||
override fun setRightSideButtonEnabled(boolean: Boolean) {}
|
||||
|
||||
var mapName = ""
|
||||
var tileMap = TileMap()
|
||||
var scenarioName = ""
|
||||
var scenario: Scenario? = null
|
||||
var scenarioName = "" // when loading map: mapName is taken as default for scenarioName
|
||||
var scenario: Scenario? = null // main indicator whether scenario information is present
|
||||
|
||||
override val gameSetupInfo = GameSetupInfo()
|
||||
override var gameSetupInfo = GameSetupInfo()
|
||||
lateinit var mapHolder: EditorMapHolder
|
||||
|
||||
val tileEditorOptions = TileEditorOptionsTable(this)
|
||||
lateinit var tileEditorOptions: TileEditorOptionsTable
|
||||
|
||||
private val showHideEditorOptionsButton = ">".toTextButton()
|
||||
|
||||
|
@ -45,6 +44,7 @@ class MapEditorScreen(): PreviousScreenInterface, CameraStageBaseScreen() {
|
|||
|
||||
if (mapToLoad != null) {
|
||||
mapName = mapToLoad
|
||||
scenarioName = mapToLoad
|
||||
tileMap = MapSaver.loadMap(mapName)
|
||||
}
|
||||
|
||||
|
@ -56,9 +56,11 @@ class MapEditorScreen(): PreviousScreenInterface, CameraStageBaseScreen() {
|
|||
initialize()
|
||||
}
|
||||
|
||||
constructor(scenario: Scenario) : this() {
|
||||
constructor(scenario: Scenario, scenarioName: String = "") : this() {
|
||||
tileMap = scenario.tileMap
|
||||
mapName = scenarioName
|
||||
this.scenario = scenario
|
||||
this.scenarioName = scenarioName
|
||||
gameSetupInfo.gameParameters = scenario.gameParameters
|
||||
initialize()
|
||||
}
|
||||
|
@ -71,6 +73,7 @@ class MapEditorScreen(): PreviousScreenInterface, CameraStageBaseScreen() {
|
|||
stage.addActor(mapHolder)
|
||||
stage.scrollFocus = mapHolder
|
||||
|
||||
tileEditorOptions = TileEditorOptionsTable(this)
|
||||
stage.addActor(tileEditorOptions)
|
||||
tileEditorOptions.setPosition(stage.width - tileEditorOptions.width, 0f)
|
||||
|
||||
|
@ -166,6 +169,10 @@ class MapEditorScreen(): PreviousScreenInterface, CameraStageBaseScreen() {
|
|||
game.setScreen(MapEditorScreen(mapHolder.tileMap))
|
||||
}
|
||||
}
|
||||
|
||||
fun hasScenario(): Boolean {
|
||||
return this.scenario != null
|
||||
}
|
||||
}
|
||||
|
||||
class TranslatedSelectBox(values : Collection<String>, default:String, skin: Skin) : SelectBox<TranslatedSelectBox.TranslatedString>(skin) {
|
||||
|
|
|
@ -6,6 +6,7 @@ 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
|
||||
|
@ -13,9 +14,11 @@ import com.unciv.logic.map.MapUnit
|
|||
import com.unciv.logic.map.RoadStatus
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.logic.map.TileMap
|
||||
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
|
||||
|
@ -32,10 +35,16 @@ class TileEditorOptionsTable(val mapEditorScreen: MapEditorScreen): Table(Camera
|
|||
private var currentHex: Actor = Group()
|
||||
|
||||
private val ruleset = mapEditorScreen.gameSetupInfo.ruleset
|
||||
private val gameParameters = mapEditorScreen.gameSetupInfo.gameParameters
|
||||
|
||||
private val scrollPanelHeight = mapEditorScreen.stage.height*0.7f - 100f // -100 reserved for currentHex table
|
||||
|
||||
init{
|
||||
update()
|
||||
}
|
||||
|
||||
fun update() {
|
||||
clear()
|
||||
height = mapEditorScreen.stage.height
|
||||
width = mapEditorScreen.stage.width/3
|
||||
|
||||
|
@ -50,7 +59,8 @@ class TileEditorOptionsTable(val mapEditorScreen: MapEditorScreen): Table(Camera
|
|||
.onClick { setImprovements() }
|
||||
tabPickerTable.add(improvementsButton)
|
||||
|
||||
if (UncivGame.Current.scenarioDebugSwitch) {
|
||||
// debug Scenario mode
|
||||
if (UncivGame.Current.scenarioDebugSwitch && mapEditorScreen.hasScenario()) {
|
||||
val unitsButton = "Units".toTextButton().onClick { setUnits() }
|
||||
tabPickerTable.add(unitsButton)
|
||||
}
|
||||
|
@ -125,10 +135,10 @@ class TileEditorOptionsTable(val mapEditorScreen: MapEditorScreen): Table(Camera
|
|||
editorPickTable.clear()
|
||||
|
||||
val improvementsTable = Table()
|
||||
improvementsTable.add(getHex(Color.WHITE).apply {
|
||||
improvementsTable.add(getHex(Color.WHITE, getRedCross(40f, 0.6f)).apply {
|
||||
onClick {
|
||||
tileAction = {it.improvement=null}
|
||||
setCurrentHex(getHex(Color.WHITE), "Clear improvements")
|
||||
setCurrentHex(getHex(Color.WHITE, getRedCross(40f, 0.6f)), "Clear improvements")
|
||||
}
|
||||
}).row()
|
||||
|
||||
|
@ -149,68 +159,138 @@ class TileEditorOptionsTable(val mapEditorScreen: MapEditorScreen): Table(Camera
|
|||
}
|
||||
improvementsTable.add(improvementImage).row()
|
||||
}
|
||||
editorPickTable.add(AutoScrollPane(improvementsTable)).height(scrollPanelHeight)
|
||||
editorPickTable.add(AutoScrollPane(improvementsTable).apply { setScrollingDisabled(true,false) }).height(scrollPanelHeight)
|
||||
|
||||
val nationsTable = Table()
|
||||
for(nation in ruleset.nations.values){
|
||||
val nationImage = getHex(Color.WHITE, ImageGetter.getNationIndicator(nation, 40f))
|
||||
nationImage.onClick {
|
||||
val improvementName = "StartingLocation "+nation.name
|
||||
val nationTable = Table()
|
||||
|
||||
if (UncivGame.Current.scenarioDebugSwitch) {
|
||||
/** new scenario/improvements functionality
|
||||
* There shoudn't be random players in scenario
|
||||
* */
|
||||
for (player in gameParameters.players) {
|
||||
val playerIndex = gameParameters.players.indexOf(player) + 1
|
||||
if (player.chosenCiv != "Random") {
|
||||
val nation = ruleset.nations[player.chosenCiv]!!
|
||||
val nationImage = ImageGetter.getNationIndicator(nation, 40f)
|
||||
nationImage.onClick {
|
||||
val improvementName = "StartingLocation " + nation.name
|
||||
tileAction = {
|
||||
it.improvement = improvementName
|
||||
for (tileGroup in mapEditorScreen.mapHolder.tileGroups.values) {
|
||||
val tile = tileGroup.tileInfo
|
||||
if (tile.improvement == improvementName && tile != it)
|
||||
tile.improvement = null
|
||||
tile.setTerrainTransients()
|
||||
tileGroup.update()
|
||||
}
|
||||
}
|
||||
|
||||
val nationIcon = getHex(Color.WHITE, ImageGetter.getNationIndicator(nation, 40f))
|
||||
setCurrentHex(nationIcon,"Player $playerIndex starting location")
|
||||
}
|
||||
nationTable.add(nationImage).row()
|
||||
|
||||
tileAction = {
|
||||
it.improvement = improvementName
|
||||
for (tileGroup in mapEditorScreen.mapHolder.tileGroups.values) {
|
||||
val tile = tileGroup.tileInfo
|
||||
if (tile.improvement == improvementName && tile != it)
|
||||
tile.improvement = null
|
||||
tile.setTerrainTransients()
|
||||
tileGroup.update()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/** old way improvements for all civs
|
||||
* */
|
||||
for(nation in ruleset.nations.values){
|
||||
val nationImage = getHex(Color.WHITE, ImageGetter.getNationIndicator(nation, 40f))
|
||||
nationImage.onClick {
|
||||
val improvementName = "StartingLocation "+nation.name
|
||||
tileAction = {
|
||||
it.improvement = improvementName
|
||||
for (tileGroup in mapEditorScreen.mapHolder.tileGroups.values) {
|
||||
val tile = tileGroup.tileInfo
|
||||
if (tile.improvement == improvementName && tile != it)
|
||||
tile.improvement = null
|
||||
tile.setTerrainTransients()
|
||||
tileGroup.update()
|
||||
}
|
||||
}
|
||||
|
||||
val nationIcon = getHex(Color.WHITE, ImageGetter.getNationIndicator(nation, 40f))
|
||||
setCurrentHex(nationIcon, "[${nation.name}] starting location")
|
||||
val nationIcon = getHex(Color.WHITE, ImageGetter.getNationIndicator(nation, 40f))
|
||||
setCurrentHex(nationIcon, "[${nation.name}] starting location")
|
||||
}
|
||||
nationTable.add(nationImage).row()
|
||||
}
|
||||
nationsTable.add(nationImage).row()
|
||||
}
|
||||
|
||||
editorPickTable.add(AutoScrollPane(nationsTable)).height(scrollPanelHeight)
|
||||
editorPickTable.add(AutoScrollPane(nationTable).apply { setScrollingDisabled(true,false) }).height(scrollPanelHeight)
|
||||
}
|
||||
|
||||
fun setUnits(){
|
||||
editorPickTable.clear()
|
||||
var currentNation = ruleset.nations.values.first()
|
||||
|
||||
val nationsTable = Table()
|
||||
|
||||
// default player - first non-random player or barbarians
|
||||
var currentPlayer = ""
|
||||
var currentNation: Nation? = ruleset.nations.values.firstOrNull{ it.isBarbarian() }
|
||||
|
||||
var currentUnit = ruleset.units.values.first()
|
||||
|
||||
fun setUnitTileAction(){
|
||||
val unitImage = ImageGetter.getUnitIcon(currentUnit.name, currentNation.getInnerColor())
|
||||
.surroundWithCircle(40f).apply { color=currentNation.getOuterColor() }
|
||||
setCurrentHex(unitImage, currentUnit.name.tr()+" - "+currentNation.name.tr())
|
||||
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()+")")
|
||||
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
|
||||
when {
|
||||
unit.type.isAirUnit() -> it.airUnits.add(unit)
|
||||
unit.type.isCivilian() -> it.civilianUnit=unit
|
||||
else -> it.militaryUnit=unit
|
||||
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 {
|
||||
unit.type.isAirUnit() -> {
|
||||
it.airUnits.add(unit)
|
||||
if (!it.isCityCenter()) unit.isTransported = true // if not city - air unit enters carrier
|
||||
}
|
||||
unit.type.isCivilian() -> { it.civilianUnit = unit }
|
||||
else -> { it.militaryUnit = unit }
|
||||
}
|
||||
unit.currentTile=it // needed for unit icon - unit needs to know if it's embarked or not...
|
||||
}
|
||||
unit.currentTile=it // needed for unit icon - unit needs to know if it's embarked or not...
|
||||
}
|
||||
}
|
||||
|
||||
val nationsTable = Table()
|
||||
val nations = nationsFromMap(mapEditorScreen.tileMap)
|
||||
val barbarians = ruleset.nations.values.filter { it.isBarbarian()}
|
||||
// delete units icon
|
||||
nationsTable.add(getCrossedIcon().onClick {
|
||||
tileAction = { it.stripUnits() }
|
||||
setCurrentHex(getCrossedIcon(), "Remove units")
|
||||
}).row()
|
||||
|
||||
for(nation in nations + barbarians){
|
||||
val nationImage = ImageGetter.getNationIndicator(nation, 40f)
|
||||
nationsTable.add(nationImage).row()
|
||||
nationImage.onClick { currentNation = nation; setUnitTileAction() }
|
||||
// player icons
|
||||
for (player in gameParameters.players) {
|
||||
if (player.chosenCiv != "Random") {
|
||||
val nation = ruleset.nations[player.chosenCiv]!!
|
||||
val nationImage = ImageGetter.getNationIndicator(nation, 40f)
|
||||
nationsTable.add(nationImage).row()
|
||||
nationImage.onClick {
|
||||
currentNation = nation;
|
||||
currentPlayer = getPlayerIndexString(player)
|
||||
setUnitTileAction() }
|
||||
}
|
||||
}
|
||||
|
||||
editorPickTable.add(ScrollPane(nationsTable)).height(stage.height*0.8f)
|
||||
// barbarians icon
|
||||
if (!gameParameters.noBarbarians) {
|
||||
val barbarians = ruleset.nations.values.filter { it.isBarbarian()}
|
||||
for (nation in barbarians) {
|
||||
val nationImage = ImageGetter.getNationIndicator(nation, 40f)
|
||||
nationsTable.add(nationImage).row()
|
||||
nationImage.onClick {
|
||||
currentNation = nation;
|
||||
currentPlayer = ""
|
||||
setUnitTileAction()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editorPickTable.add(AutoScrollPane(nationsTable)).height(scrollPanelHeight)
|
||||
|
||||
val unitsTable = Table()
|
||||
for(unit in ruleset.units.values){
|
||||
|
@ -218,7 +298,7 @@ class TileEditorOptionsTable(val mapEditorScreen: MapEditorScreen): Table(Camera
|
|||
unitsTable.add(unitImage).row()
|
||||
unitImage.onClick { currentUnit = unit; setUnitTileAction() }
|
||||
}
|
||||
editorPickTable.add(ScrollPane(unitsTable)).height(stage.height*0.8f)
|
||||
editorPickTable.add(AutoScrollPane(unitsTable)).height(scrollPanelHeight)
|
||||
}
|
||||
|
||||
private fun nationsFromMap(tileMap: TileMap): ArrayList<Nation> {
|
||||
|
@ -232,6 +312,17 @@ class TileEditorOptionsTable(val mapEditorScreen: MapEditorScreen): Table(Camera
|
|||
return nations
|
||||
}
|
||||
|
||||
private fun getPlayerIndexString(player: Player): String {
|
||||
val index = gameParameters.players.indexOf(player) + 1
|
||||
return "Player $index"
|
||||
}
|
||||
|
||||
private fun getCrossedIcon(): Actor {
|
||||
return getRedCross(20f, 0.6f)
|
||||
.surroundWithCircle(40f, false)
|
||||
.apply { circle.color = Color.WHITE }
|
||||
}
|
||||
|
||||
private fun getRedCross(size: Float, alpha: Float): Actor {
|
||||
val redCross = ImageGetter.getImage("OtherIcons/Close")
|
||||
redCross.setSize( size, size)
|
||||
|
|
|
@ -11,7 +11,7 @@ import com.unciv.ui.utils.CameraStageBaseScreen
|
|||
* or CameraBackStageScreen class for map editing
|
||||
*/
|
||||
|
||||
interface PreviousScreenInterface {
|
||||
interface IPreviousScreen {
|
||||
val gameSetupInfo: GameSetupInfo
|
||||
var stage: Stage
|
||||
|
|
@ -27,7 +27,7 @@ class GameSetupInfo(var gameId:String, var gameParameters: GameParameters, var m
|
|||
constructor(gameParameters: GameParameters, mapParameters: MapParameters) : this("", gameParameters, mapParameters)
|
||||
}
|
||||
|
||||
class NewGameScreen(previousScreen:CameraStageBaseScreen, _gameSetupInfo: GameSetupInfo?=null): PreviousScreenInterface, PickerScreen() {
|
||||
class NewGameScreen(previousScreen:CameraStageBaseScreen, _gameSetupInfo: GameSetupInfo?=null): IPreviousScreen, PickerScreen() {
|
||||
override val gameSetupInfo = _gameSetupInfo ?: GameSetupInfo()
|
||||
var playerPickerTable = PlayerPickerTable(this, gameSetupInfo.gameParameters)
|
||||
var newGameOptionsTable = GameOptionsTable(gameSetupInfo) { desiredCiv: String -> playerPickerTable.update(desiredCiv) }
|
||||
|
|
|
@ -14,15 +14,18 @@ import com.unciv.logic.IdChecker
|
|||
import com.unciv.logic.civilization.PlayerType
|
||||
import com.unciv.models.metadata.GameParameters
|
||||
import com.unciv.models.metadata.Player
|
||||
import com.unciv.models.ruleset.Nation
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.mapeditor.GameParametersScreen
|
||||
import com.unciv.ui.utils.*
|
||||
import java.util.*
|
||||
|
||||
class PlayerPickerTable(val previousScreen: PreviousScreenInterface, var gameParameters: GameParameters): Table() {
|
||||
class PlayerPickerTable(val previousScreen: IPreviousScreen, var gameParameters: GameParameters): Table() {
|
||||
val playerListTable = Table()
|
||||
val nationsPopupWidth = previousScreen.stage.width / 2f
|
||||
val civBlocksWidth = previousScreen.stage.width / 3
|
||||
var locked = false
|
||||
var noRandom = false
|
||||
|
||||
init {
|
||||
top()
|
||||
|
@ -47,7 +50,12 @@ class PlayerPickerTable(val previousScreen: PreviousScreenInterface, var gamePar
|
|||
if (gameParameters.players.count() < ruleset.nations.values.count { it.isMajorCiv() }
|
||||
&& !locked) {
|
||||
playerListTable.add("+".toLabel(Color.BLACK, 30).apply { this.setAlignment(Align.center) }
|
||||
.surroundWithCircle(50f).onClick { gameParameters.players.add(Player()); update() }).pad(10f)
|
||||
.surroundWithCircle(50f).onClick {
|
||||
var player = Player()
|
||||
if (noRandom) { player = Player(getAvailablePlayerCivs().first().name) }
|
||||
gameParameters.players.add(player)
|
||||
update()
|
||||
}).pad(10f)
|
||||
}
|
||||
previousScreen.setRightSideButtonEnabled(gameParameters.players.size > 1)
|
||||
}
|
||||
|
@ -86,7 +94,11 @@ class PlayerPickerTable(val previousScreen: PreviousScreenInterface, var gamePar
|
|||
if (!locked) {
|
||||
playerTable.add("-".toLabel(Color.BLACK, 30).apply { this.setAlignment(Align.center) }
|
||||
.surroundWithCircle(40f)
|
||||
.onClick { gameParameters.players.remove(player); update() }).pad(5f).right().row()
|
||||
.onClick {
|
||||
gameParameters.players.remove(player)
|
||||
if (previousScreen is GameParametersScreen) previousScreen.mapEditorScreen.tileMap.stripPlayer(player)
|
||||
update()
|
||||
}).pad(5f).right().row()
|
||||
}
|
||||
if (gameParameters.isOnlineMultiplayer && player.playerType == PlayerType.Human) {
|
||||
|
||||
|
@ -160,20 +172,23 @@ class PlayerPickerTable(val previousScreen: PreviousScreenInterface, var gamePar
|
|||
nationsPopup.close()
|
||||
update()
|
||||
}
|
||||
nationListTable.add(randomPlayerTable).pad(10f).width(nationsPopupWidth).row()
|
||||
|
||||
if (!noRandom) { nationListTable.add(randomPlayerTable).pad(10f).width(nationsPopupWidth).row() }
|
||||
|
||||
for (nation in previousScreen.gameSetupInfo.ruleset.nations.values
|
||||
.filter { !it.isCityState() && it.name != Constants.barbarians }) {
|
||||
if (player.chosenCiv != nation.name && gameParameters.players.any { it.chosenCiv == nation.name })
|
||||
for (nation in getAvailablePlayerCivs()) {
|
||||
if (player.chosenCiv == nation.name)
|
||||
continue
|
||||
|
||||
nationListTable.add(NationTable(nation, nationsPopupWidth, previousScreen.gameSetupInfo.ruleset).onClick {
|
||||
if (previousScreen is GameParametersScreen) {
|
||||
previousScreen.mapEditorScreen.tileMap.switchPlayersNation(player, nation)
|
||||
}
|
||||
player.chosenCiv = nation.name
|
||||
nationsPopup.close()
|
||||
update()
|
||||
}).pad(10f).width(nationsPopupWidth).row()
|
||||
}
|
||||
|
||||
nationsPopup.add(ScrollPane(nationListTable)).height(previousScreen.stage.height * 0.8f)
|
||||
nationsPopup.pack()
|
||||
|
||||
|
@ -190,4 +205,16 @@ class PlayerPickerTable(val previousScreen: PreviousScreenInterface, var gamePar
|
|||
nationsPopup.open()
|
||||
update()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAvailablePlayerCivs(): ArrayList<Nation> {
|
||||
var nations = ArrayList<Nation>()
|
||||
for (nation in previousScreen.gameSetupInfo.ruleset.nations.values
|
||||
.filter { it.isMajorCiv() }) {
|
||||
if (gameParameters.players.any { it.chosenCiv == nation.name })
|
||||
continue
|
||||
nations.add(nation)
|
||||
}
|
||||
return nations
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue