mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-21 10:25:10 -04:00
Added game saves - you can now save and load the game!
This commit is contained in:
parent
8450d2cf60
commit
fc7b6529f0
@ -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()
|
||||
}
|
||||
|
57
core/src/com/unciv/ui/LoadScreen.kt
Normal file
57
core/src/com/unciv/ui/LoadScreen.kt
Normal 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)
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
53
core/src/com/unciv/ui/SaveScreen.kt
Normal file
53
core/src/com/unciv/ui/SaveScreen.kt
Normal 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()
|
||||
}
|
||||
|
||||
}
|
@ -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)
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user