Added game saves - you can now save and load the game!

This commit is contained in:
Yair Morgenstern 2018-05-06 08:55:20 +03:00
parent 8450d2cf60
commit fc7b6529f0
8 changed files with 180 additions and 39 deletions

View File

@ -20,24 +20,23 @@ class UnCivGame : Game() {
var settings = GameSettings()
var worldScreen: WorldScreen? = null
override fun create() {
setupGameBasics()
Current = this
if (GameSaver.getSave("Autosave").exists()) {
try {
GameSaver.loadGame(this, "Autosave")
gameInfo.getPlayerCivilization().civName="Babylon"
gameInfo.tileMap.values.forEach {
//if (it.getOwner() == "Player") it.getOwner() = "Babylon"
if (it.unit != null && it.unit!!.owner == "Player") it.unit!!.owner = "Babylon"
}
loadGame("Autosave")
} catch (ex: Exception) { // silent fail if we can't read the autosave
startNewGame()
}
}
else startNewGame()
}
fun loadGame(gameName:String){
gameInfo = GameSaver.loadGame( gameName)
worldScreen = WorldScreen()
setWorldScreen()
}

View File

@ -0,0 +1,57 @@
package com.unciv.ui
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
import com.unciv.UnCivGame
import com.unciv.ui.cityscreen.addClickListener
import com.unciv.ui.pickerscreens.PickerScreen
import com.unciv.ui.utils.CameraStageBaseScreen
import com.unciv.ui.utils.GameSaver
import com.unciv.ui.utils.disable
import com.unciv.ui.utils.enable
class LoadScreen : PickerScreen() {
lateinit var selectedSave:String
init {
val saveTable = Table()
val deleteSaveButton = TextButton("Delete save", CameraStageBaseScreen.skin)
deleteSaveButton .addClickListener {
GameSaver.deleteSave(selectedSave)
UnCivGame.Current.screen = LoadScreen()
}
deleteSaveButton.disable()
rightSideGroup.addActor(deleteSaveButton)
topTable.add(saveTable)
val saves = GameSaver.getSaves()
rightSideButton.setText("Load game")
saves.forEach {
val textButton = TextButton(it,skin)
textButton.addClickListener {
selectedSave=it
descriptionLabel.setText(it)
rightSideButton.setText("Load\r\n$it")
rightSideButton.enable()
deleteSaveButton.enable()
deleteSaveButton.color= Color.RED
}
saveTable.add(textButton).pad(5f).row()
}
rightSideButton.addClickListener {
UnCivGame.Current.loadGame(selectedSave)
}
}
}

View File

@ -0,0 +1,53 @@
package com.unciv.ui
import com.badlogic.gdx.scenes.scene2d.ui.Label
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
import com.badlogic.gdx.scenes.scene2d.ui.TextField
import com.unciv.UnCivGame
import com.unciv.ui.cityscreen.addClickListener
import com.unciv.ui.pickerscreens.PickerScreen
import com.unciv.ui.utils.GameSaver
import com.unciv.ui.utils.enable
import java.text.SimpleDateFormat
import java.util.*
class SaveScreen : PickerScreen() {
val textField = TextField("", skin)
init {
val currentSaves = Table()
currentSaves.add(Label("Current saves:",skin)).row()
val saves = GameSaver.getSaves()
saves.forEach {
val textButton = TextButton(it, skin)
textButton.addClickListener {
textField.text = it
}
currentSaves.add(textButton).pad(5f).row()
}
topTable.add(currentSaves)
val newSave = Table()
val defaultSaveName = SimpleDateFormat("dd-MM-yy HH.mm").format(Date())+
" Turn "+ UnCivGame.Current.gameInfo.turns
textField.text = defaultSaveName
newSave.add(Label("Saved game name:",skin)).row()
newSave.add(textField).width(300f)
topTable.add(newSave)
topTable.pack()
rightSideButton.setText("Save game")
rightSideButton.addClickListener {
GameSaver.saveGame(UnCivGame.Current.gameInfo, textField.text)
UnCivGame.Current.setWorldScreen()
}
rightSideButton.enable()
}
}

View File

@ -10,33 +10,34 @@ import com.unciv.ui.utils.disable
open class PickerScreen : CameraStageBaseScreen() {
internal var closeButton: TextButton
internal var closeButton: TextButton = TextButton("Close", CameraStageBaseScreen.skin)
protected var descriptionLabel: Label
protected var rightSideGroup = VerticalGroup()
protected var rightSideButton: TextButton
internal var screenSplit = 0.85f
private var screenSplit = 0.85f
protected var topTable: Table
var bottomTable:Table = Table()
internal var splitPane: SplitPane
init {
val buttonTable = Table()
closeButton = TextButton("Close", CameraStageBaseScreen.skin)
closeButton.addClickListener {
game.setWorldScreen()
dispose()
}
buttonTable.add(closeButton).width(stage.width / 4)
bottomTable.add(closeButton).width(stage.width / 4)
descriptionLabel = Label("", CameraStageBaseScreen.skin)
descriptionLabel.setWrap(true)
descriptionLabel.setFontScale(game.settings.labelScale)
descriptionLabel.width = stage.width / 2
buttonTable.add(descriptionLabel).pad(5f).width(stage.width / 2)
bottomTable.add(descriptionLabel).pad(5f).width(stage.width / 2)
rightSideButton = TextButton("", CameraStageBaseScreen.skin)
buttonTable.add(rightSideButton).width(stage.width / 4)
buttonTable.height = stage.height * (1 - screenSplit)
buttonTable.align(Align.center)
rightSideGroup.addActor(rightSideButton)
bottomTable.add(rightSideGroup).width(stage.width / 4)
bottomTable.height = stage.height * (1 - screenSplit)
bottomTable.align(Align.center)
rightSideButton.disable()
topTable = Table()
@ -44,7 +45,7 @@ open class PickerScreen : CameraStageBaseScreen() {
scrollPane.setSize(stage.width, stage.height * screenSplit)
splitPane = SplitPane(scrollPane, buttonTable, true, CameraStageBaseScreen.skin)
splitPane = SplitPane(scrollPane, bottomTable, true, CameraStageBaseScreen.skin)
splitPane.setSplitAmount(screenSplit)
splitPane.setFillParent(true)
stage.addActor(splitPane)

View File

@ -4,7 +4,6 @@ import com.badlogic.gdx.Gdx
import com.badlogic.gdx.files.FileHandle
import com.badlogic.gdx.utils.Json
import com.unciv.logic.GameInfo
import com.unciv.UnCivGame
object GameSaver {
private const val saveFilesFolder = "SaveFiles"
@ -13,12 +12,21 @@ object GameSaver {
return Gdx.files.local("$saveFilesFolder/$GameName")
}
fun saveGame(game: UnCivGame, GameName: String) {
getSave(GameName).writeString(Json().toJson(game.gameInfo), false)
fun getSaves(): List<String> {
return Gdx.files.local(saveFilesFolder).list().map { it.name() }
}
fun loadGame(game: UnCivGame, GameName: String) {
game.gameInfo = Json().fromJson(GameInfo::class.java, getSave(GameName).readString())
game.gameInfo.setTransients()
fun saveGame(game: GameInfo, GameName: String) {
getSave(GameName).writeString(Json().toJson(game), false)
}
fun loadGame(GameName: String) : GameInfo {
val game = Json().fromJson(GameInfo::class.java, getSave(GameName).readString())
game.setTransients()
return game
}
fun deleteSave(GameName: String){
getSave(GameName).delete()
}
}

View File

@ -1,5 +1,6 @@
package com.unciv.ui.worldscreen
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.ui.Label
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
@ -8,6 +9,7 @@ import com.unciv.logic.map.TileInfo
import com.unciv.logic.map.UnitType
import com.unciv.ui.cityscreen.addClickListener
import com.unciv.ui.utils.CameraStageBaseScreen
import com.unciv.ui.utils.ImageGetter
import com.unciv.ui.utils.disable
import kotlin.math.max
@ -18,10 +20,15 @@ class BattleTable(val worldScreen: WorldScreen): Table() {
skin = CameraStageBaseScreen.skin
}
fun hide(){
clear()
background=null
}
fun update() {
if (worldScreen.unitTable.selectedUnit == null
|| worldScreen.unitTable.selectedUnit!!.getBaseUnit().unitType == UnitType.Civilian){
clear()
hide()
return
} // no attacker
@ -38,16 +45,14 @@ class BattleTable(val worldScreen: WorldScreen): Table() {
&& worldScreen.civInfo.getViewableTiles().contains(selectedTile))
defender = MapUnitCombatant(selectedTile.unit!!)
else {
clear()
hide()
return
}
simulateBattle(attacker, defender)
}
fun simulateBattle(attacker: MapUnitCombatant, defender: ICombatant){
clear()
row().pad(5f)
val attackerLabel = Label(attacker.getName(), skin)
attackerLabel.style= Label.LabelStyle(attackerLabel.style)
@ -81,10 +86,10 @@ class BattleTable(val worldScreen: WorldScreen): Table() {
var damageToAttacker = battle.calculateDamageToAttacker(attacker,defender)
if (damageToAttacker>attacker.getHealth() && damageToDefender>defender.getHealth() // when damage exceeds health, we don't want to show negative health numbers
if (damageToAttacker>attacker.getHealth() && damageToDefender>defender.getHealth()) // when damage exceeds health, we don't want to show negative health numbers
// Also if both parties are supposed to die it's not indicative of who is more likely to win
// So we "normalize" the damages until one dies
) {
{
if(damageToDefender/defender.getHealth().toFloat() > damageToAttacker/attacker.getHealth().toFloat()) // defender dies quicker ie first
{
// Both damages *= (defender.health/damageToDefender)
@ -150,6 +155,13 @@ class BattleTable(val worldScreen: WorldScreen): Table() {
add(attackButton).colspan(2)
pack()
val tileTableBackground = ImageGetter.getDrawable("skin/tileTableBackground.png")
.tint(Color(0x004085bf))
tileTableBackground.minHeight = 0f
tileTableBackground.minWidth = 0f
background = tileTableBackground
setPosition(worldScreen.stage.width/2-width/2, 5f)
}

View File

@ -120,7 +120,7 @@ class WorldScreen : CameraStageBaseScreen() {
game.gameInfo.nextTurn()
unitTable.currentlyExecutingAction = null
GameSaver.saveGame(game, "Autosave")
GameSaver.saveGame(game.gameInfo, "Autosave")
update()
displayTutorials("NextTurn")
}

View File

@ -5,6 +5,8 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.ui.CivilopediaScreen
import com.unciv.ui.LoadScreen
import com.unciv.ui.SaveScreen
import com.unciv.ui.ScienceVictoryScreen
import com.unciv.ui.cityscreen.addClickListener
import com.unciv.ui.pickerscreens.PolicyPickerScreen
@ -17,7 +19,6 @@ class WorldScreenOptionsTable internal constructor(worldScreen: WorldScreen, pri
val tileTableBackground = ImageGetter.getDrawable("skin/tileTableBackground.png")
.tint(Color(0x004085bf))
background = tileTableBackground
isVisible = false
val openCivilopediaButton = TextButton("Civilopedia", CameraStageBaseScreen.skin)
@ -25,32 +26,42 @@ class WorldScreenOptionsTable internal constructor(worldScreen: WorldScreen, pri
worldScreen.game.screen = CivilopediaScreen()
isVisible = false
}
add(openCivilopediaButton).pad(10f)
row()
add(openCivilopediaButton).pad(10f).row()
val LoadGameButton = TextButton("Load game", CameraStageBaseScreen.skin)
LoadGameButton .addClickListener {
worldScreen.game.screen = LoadScreen()
isVisible=false
}
add(LoadGameButton ).pad(10f).row()
val SaveGameButton = TextButton("Save game", CameraStageBaseScreen.skin)
SaveGameButton .addClickListener {
worldScreen.game.screen = SaveScreen()
isVisible=false
}
add(SaveGameButton ).pad(10f).row()
val StartNewGameButton = TextButton("Start new game", CameraStageBaseScreen.skin)
StartNewGameButton.addClickListener { worldScreen.game.startNewGame(true) }
add(StartNewGameButton).pad(10f)
row()
add(StartNewGameButton).pad(10f).row()
val OpenScienceVictoryScreen = TextButton("Science victory status", CameraStageBaseScreen.skin)
OpenScienceVictoryScreen.addClickListener {
worldScreen.game.screen = ScienceVictoryScreen(this@WorldScreenOptionsTable.civInfo)
}
add(OpenScienceVictoryScreen).pad(10f)
row()
add(OpenScienceVictoryScreen).pad(10f).row()
val OpenPolicyPickerScreen = TextButton("Social Policies", CameraStageBaseScreen.skin)
OpenPolicyPickerScreen.addClickListener {
worldScreen.game.screen = PolicyPickerScreen(this@WorldScreenOptionsTable.civInfo)
}
add(OpenPolicyPickerScreen).pad(10f)
row()
add(OpenPolicyPickerScreen).pad(10f).row()
val closeButton = TextButton("Close", CameraStageBaseScreen.skin)
closeButton.addClickListener { isVisible = false }
add(closeButton).pad(10f)
pack() // Needed to show the background.
setPosition(worldScreen.stage.width / 2 - width / 2,
worldScreen.stage.height / 2 - height / 2)