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:
Alexander Korolyov 2020-06-24 22:47:34 +02:00 committed by GitHub
parent e4a5f2af18
commit de03a727f6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 305 additions and 132 deletions

View file

@ -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

View file

@ -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 {

View file

@ -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()

View file

@ -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)

View file

@ -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()!!

View file

@ -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=""
}

View file

@ -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
}
}

View file

@ -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()
}

View file

@ -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
}
}

View file

@ -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) {

View file

@ -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)

View file

@ -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

View file

@ -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) }

View file

@ -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
}
}