new savegame loader is not quite working yet

This commit is contained in:
minjaesong
2023-06-26 01:09:47 +09:00
parent a497463349
commit f9f49ab63c
7 changed files with 159 additions and 12 deletions

View File

@@ -38,7 +38,8 @@
"MENU_OPTIONS_NOTIFICATION_DISPLAY_DURATION": "Show notification for",
"MENU_LABEL_STREAMING": "Livestreaming",
"MENU_LABEL_EXTRA_JVM_ARGUMENTS": "Extra JVM Arguments",
"GAME_PREV_SAVE_WAS_LOADED": "The most recently saved game was corrupted.\nThe previously saved game was loaded.",
"GAME_PREV_SAVE_WAS_LOADED1": "The most recently saved game was corrupted.",
"GAME_PREV_SAVE_WAS_LOADED2": "The previously saved game was loaded.",
"GAME_MORE_RECENT_AUTOSAVE1": "The Autosave is more recent than the manual save.",
"GAME_MORE_RECENT_AUTOSAVE2": "Please select the saved game you want to load:"
}

View File

@@ -1,5 +1,6 @@
package net.torvald.terrarum
import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.savegame.DiskSkimmer
import java.io.File
@@ -34,4 +35,118 @@ class SavegameCollection(files0: List<DiskSkimmer>) {
return files.first()
}
}
class SavegameCollectionPair(player: SavegameCollection?, world: SavegameCollection?) {
private lateinit var manualPlayer: DiskSkimmer
private lateinit var manualWorld: DiskSkimmer
private lateinit var autoPlayer: DiskSkimmer
private lateinit var autoWorld: DiskSkimmer
var status = 0 // 0: none available, 1: loadable manual save is newer than loadable auto; 2: loadable autosave is newer than loadable manual
private set
var newerSaveIsDamaged = false // only when most recent save is corrupted
private set
init {
printdbg(this, "init ($player, $world)")
if (player != null && world != null) {
printdbg(this, player.files.joinToString { it.diskFile.name })
printdbg(this, world.files.joinToString { it.diskFile.name })
// if a pair of files were saved successfully, they must have identical lastModifiedTime()
var pc = 0; val pt = player.files[0].getLastModifiedTime()
var wc = 0; val wt = world.files[0].getLastModifiedTime()
while (pc < player.files.size && wc < world.files.size) {
val pcf = player.files[pc]
val pcm = pcf.getLastModifiedTime()
val wcf = world.files[wc]
val wcm = wcf.getLastModifiedTime()
if (playerDiskNotDamaged(pcf) && worldDiskNotDamaged(wcf)) {
when (pcf.isAutosaved().toInt(1) or wcf.isAutosaved().toInt()) {
3 -> {
autoPlayer = pcf
autoWorld = wcf
pc += 1
wc += 1
}
0 -> {
manualPlayer = pcf
manualWorld = wcf
pc += 1
wc += 1
}
else -> {
if (pcm > wcm)
pc += 1
else if (pcm == wcm) {
pc += 1
wc += 1
}
else
wc += 1
}
}
}
if (::manualPlayer.isInitialized && ::manualWorld.isInitialized && ::autoPlayer.isInitialized && ::autoWorld.isInitialized)
break
}
if (::manualPlayer.isInitialized && ::manualWorld.isInitialized && ::autoPlayer.isInitialized && ::autoWorld.isInitialized) {
status = if (manualPlayer.getLastModifiedTime() > autoPlayer.getLastModifiedTime()) 1 else 2
printdbg(this, "manualPlayer = ${manualPlayer.diskFile.path}")
printdbg(this, "manualWorld = ${manualWorld.diskFile.path}")
printdbg(this, "autoPlayer = ${autoPlayer.diskFile.path}")
printdbg(this, "autoWorld = ${autoWorld.diskFile.path}")
}
else if (::manualPlayer.isInitialized && ::manualWorld.isInitialized || ::autoPlayer.isInitialized && ::autoWorld.isInitialized) {
status = 1
if (::manualPlayer.isInitialized) {
printdbg(this, "manualPlayer = ${manualPlayer.diskFile.path}")
printdbg(this, "manualWorld = ${manualWorld.diskFile.path}")
}
else {
printdbg(this, "autoPlayer = ${autoPlayer.diskFile.path}")
printdbg(this, "autoWorld = ${autoWorld.diskFile.path}")
}
}
else {
status = 0
}
}
}
private fun DiskSkimmer.isAutosaved() = this.getSaveMode().and(0b0000_0010) != 0
private fun playerDiskNotDamaged(disk: DiskSkimmer): Boolean {
return true
}
private fun worldDiskNotDamaged(disk: DiskSkimmer): Boolean {
return true
}
fun moreRecentAutosaveAvailable() = (status == 2)
fun saveAvaliable() = (status > 0)
fun getManualSave(): Pair<DiskSkimmer, DiskSkimmer>? {
if (status == 0) return null
return manualPlayer to manualWorld
}
fun getAutoSave(): Pair<DiskSkimmer, DiskSkimmer>? {
if (status != 2) return null
return autoPlayer to autoWorld
}
}

View File

@@ -26,6 +26,7 @@ import net.torvald.terrarum.gameitems.mouseInInteractableRange
import net.torvald.terrarum.gameparticles.ParticleBase
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.gameworld.WorldSimulator
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.modulebasegame.gameactors.*
import net.torvald.terrarum.modulebasegame.gameactors.physicssolver.CollisionSolver
import net.torvald.terrarum.modulebasegame.gameitems.PickaxeCore
@@ -716,6 +717,10 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
gameUpdateGovernor.reset()
if (UILoadGovernor.previousSaveWasLoaded) {
sendNotification(listOf(Lang["GAME_PREV_SAVE_WAS_LOADED1"], Lang["GAME_PREV_SAVE_WAS_LOADED2"]))
}
gameFullyLoaded = true
}

View File

@@ -24,6 +24,7 @@ import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.gameworld.WorldTime
import net.torvald.terrarum.gameworld.fmod
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.modulebasegame.ui.UILoadGovernor
import net.torvald.terrarum.modulebasegame.ui.UIRemoCon
import net.torvald.terrarum.modulebasegame.ui.UITitleRemoConYaml
import net.torvald.terrarum.realestate.LandUtil
@@ -237,6 +238,7 @@ class TitleScreen(batch: FlippingSpriteBatch) : IngameInstance(batch) {
printdbg(this, "update list of savegames")
// to show "Continue" and "Load" on the titlescreen, uncomment this line
App.updateListOfSavegames()
UILoadGovernor.reset()
loadThingsWhileIntroIsVisible()

View File

@@ -7,6 +7,7 @@ import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.App
import net.torvald.terrarum.CommonResourcePool
import net.torvald.terrarum.INGAME
import net.torvald.terrarum.ceilInt
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.CELL_COL

View File

@@ -57,6 +57,11 @@ val SAVE_CELL_HEIGHT = 120
* WARNING: the values are not guaranteed to reset when the selector UI is closed!
*/
object UILoadGovernor {
// used by the default save loader
var playerUUID: UUID? = null
var worldUUID: UUID? = null
var previousSaveWasLoaded = false
// used by the debug save loader
var playerDisk: DiskSkimmer? = null
set(value) {
printdbg(this, "Player selected: ${value?.diskFile?.name}")
@@ -73,6 +78,10 @@ object UILoadGovernor {
printdbg(this, "Resetting player and world selection")
playerDisk = null
worldDisk = null
playerUUID = null
worldUUID = null
previousSaveWasLoaded = false
}
}
@@ -486,6 +495,8 @@ class UIItemPlayerCells(
override var clickOnceListener: ((Int, Int) -> Unit)? = { _: Int, _: Int ->
UILoadGovernor.playerDisk = skimmer
UILoadGovernor.playerUUID = playerUUID
UILoadGovernor.worldUUID = worldUUID
parent.advanceMode()
}
@@ -494,12 +505,11 @@ class UIItemPlayerCells(
private var lastPlayTime: String = "????-??-?? --:--:--"
private var totalPlayTime: String = "--h--m--s"
private var playerUUID: UUID? = null
private lateinit var playerUUID: UUID
private lateinit var worldUUID: UUID
init {
skimmer.getFile(SAVEGAMEINFO)?.bytes?.let {
var playerUUID: UUID? = null
var worldUUID: UUID? = null
var lastPlayTime0 = 0L
JsonFetcher.readFromJsonString(ByteArray64Reader(it, Common.CHARSET)).forEachSiblings { name, value ->

View File

@@ -134,17 +134,30 @@ class UILoadSavegame(val remoCon: UIRemoCon) : Advanceable() {
// look for recently played world
if (mode == 1) {
UILoadGovernor.playerDisk!!.getFile(SAVEGAMEINFO)?.bytes?.let {
var worldUUID: UUID? = null
JsonFetcher.readFromJsonString(ByteArray64Reader(it, Common.CHARSET)).forEachSiblings { name, value ->
if (name == "worldCurrentlyPlaying") worldUUID = UUID.fromString(value.asString())
}
// TODO select the most recent loadable save by comparing manual and autosaves, NOT JUST going with loadable()
UILoadGovernor.worldDisk = App.savegameWorlds[worldUUID!!]!!.loadable()
// select the most recent loadable save by comparing manual and autosaves, NOT JUST going with loadable()
printdbg(this, "Load playerUUID: ${UILoadGovernor.playerUUID}, worldUUID: ${UILoadGovernor.worldUUID}")
val loadables = SavegameCollectionPair(App.savegamePlayers[UILoadGovernor.playerUUID], App.savegameWorlds[UILoadGovernor.worldUUID])
var loadAuto = false
if (loadables.moreRecentAutosaveAvailable()) {
// TODO make choice for load manual or auto, if available
mode += 1
}
else if (!loadables.saveAvaliable()) {
// TODO show save is damaged and cannot be loaded
return
}
val (p, w) = if (loadAuto) loadables.getAutoSave()!! else loadables.getManualSave()!!
UILoadGovernor.playerDisk = p; UILoadGovernor.worldDisk = w
if (loadables.newerSaveIsDamaged) {
// TODO queue message: GAME_PREV_SAVE_WAS_LOADED
}
mode += 1
}
}