mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-16 16:46:07 +09:00
new load wip
This commit is contained in:
@@ -7,7 +7,6 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import net.torvald.EMDASH
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.App.*
|
||||
import net.torvald.terrarum.Terrarum.PLAYER_REF_ID
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED
|
||||
import net.torvald.terrarum.blockproperties.BlockPropUtil
|
||||
@@ -24,7 +23,6 @@ import net.torvald.terrarum.gameitem.inInteractableRange
|
||||
import net.torvald.terrarum.gameparticles.ParticleBase
|
||||
import net.torvald.terrarum.gameworld.GameWorld
|
||||
import net.torvald.terrarum.gameworld.WorldSimulator
|
||||
import net.torvald.terrarum.itemproperties.ItemCodex
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.*
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.physicssolver.CollisionSolver
|
||||
import net.torvald.terrarum.modulebasegame.gameitems.PickaxeCore
|
||||
@@ -34,9 +32,12 @@ import net.torvald.terrarum.modulebasegame.worldgenerator.RoguelikeRandomiser
|
||||
import net.torvald.terrarum.modulebasegame.worldgenerator.Worldgen
|
||||
import net.torvald.terrarum.modulebasegame.worldgenerator.WorldgenParams
|
||||
import net.torvald.terrarum.realestate.LandUtil
|
||||
import net.torvald.terrarum.serialise.*
|
||||
import net.torvald.terrarum.serialise.Common
|
||||
import net.torvald.terrarum.serialise.LoadSavegame
|
||||
import net.torvald.terrarum.serialise.ReadActor
|
||||
import net.torvald.terrarum.serialise.WriteSavegame
|
||||
import net.torvald.terrarum.tvda.DiskSkimmer
|
||||
import net.torvald.terrarum.tvda.VDUtil
|
||||
import net.torvald.terrarum.tvda.VirtualDisk
|
||||
import net.torvald.terrarum.ui.Toolkit
|
||||
import net.torvald.terrarum.ui.UIAutosaveNotifier
|
||||
import net.torvald.terrarum.ui.UICanvas
|
||||
@@ -249,15 +250,17 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
}
|
||||
|
||||
data class Codices(
|
||||
val disk: VirtualDisk,
|
||||
val meta: WriteMeta.WorldMeta,
|
||||
val disk: DiskSkimmer, // WORLD disk
|
||||
val world: GameWorld,
|
||||
// val meta: WriteMeta.WorldMeta,
|
||||
// val block: BlockCodex,
|
||||
val item: ItemCodex,
|
||||
// val item: ItemCodex,
|
||||
// val wire: WireCodex,
|
||||
// val material: MaterialCodex,
|
||||
// val faction: FactionCodex,
|
||||
val apocryphas: Map<String, Any>,
|
||||
val actors: List<ActorID>
|
||||
// val apocryphas: Map<String, Any>,
|
||||
val actors: List<ActorID>,
|
||||
val player: IngamePlayer
|
||||
)
|
||||
|
||||
|
||||
@@ -272,13 +275,13 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
else {
|
||||
printdbg(this, "Ingame setting things up from the savegame")
|
||||
|
||||
RoguelikeRandomiser.loadFromSave(codices.meta.randseed0, codices.meta.randseed1)
|
||||
WeatherMixer.loadFromSave(codices.meta.weatseed0, codices.meta.weatseed1)
|
||||
RoguelikeRandomiser.loadFromSave(codices.world.randSeeds[0], codices.world.randSeeds[1])
|
||||
WeatherMixer.loadFromSave(codices.world.randSeeds[2], codices.world.randSeeds[3])
|
||||
|
||||
Terrarum.itemCodex.loadFromSave(codices.item)
|
||||
Terrarum.apocryphas = HashMap(codices.apocryphas)
|
||||
// Terrarum.itemCodex.loadFromSave(codices.item)
|
||||
// Terrarum.apocryphas = HashMap(codices.apocryphas)
|
||||
|
||||
savegameNickname = codices.disk.getDiskNameString(Common.CHARSET)
|
||||
savegameNickname = codices.disk.getDiskName(Common.CHARSET)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,18 +290,36 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
codices.actors.forEach {
|
||||
try {
|
||||
val actor = ReadActor(codices.disk, LoadSavegame.getFileReader(codices.disk, it.toLong()))
|
||||
addNewActor(actor)
|
||||
if (actor !is IngamePlayer) { // actor list should not contain IngamePlayers (see WriteWorld.preWrite) but just in case...
|
||||
addNewActor(actor)
|
||||
}
|
||||
}
|
||||
catch (e: NullPointerException) {
|
||||
System.err.println("Could not read the actor ${it} from the disk")
|
||||
e.printStackTrace()
|
||||
if (it == PLAYER_REF_ID) throw e
|
||||
// throw e // if not player, don't rethrow -- let players play the corrupted world if it loads, they'll be able to cope with their losses even though there will be buncha lone actorblocks lying around...
|
||||
}
|
||||
}
|
||||
|
||||
// assign new random referenceID for player
|
||||
codices.player.referenceID = Terrarum.generateUniqueReferenceID(Actor.RenderOrder.MIDDLE)
|
||||
addNewActor(codices.player)
|
||||
|
||||
|
||||
// overwrite player's props with world's for multiplayer
|
||||
// see comments on IngamePlayer.unauthorisedPlayerProps to know why this is necessary.
|
||||
codices.player.backupPlayerProps(isMultiplayer) // backup first!
|
||||
world.playersLastStatus[codices.player.uuid]?.let { // if nothing was saved, nothing would happen and we still keep the backup, which WriteActor looks for it
|
||||
codices.player.setPosition(it.physics.position)
|
||||
if (isMultiplayer) {
|
||||
codices.player.actorValue = it.actorValue!!
|
||||
codices.player.inventory = it.inventory!!
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// by doing this, whatever the "possession" the player had will be broken by the game load
|
||||
actorNowPlaying = getActorByID(Terrarum.PLAYER_REF_ID) as IngamePlayer
|
||||
actorNowPlaying = codices.player
|
||||
actorGamer = codices.player
|
||||
|
||||
makeSavegameBackupCopy() // don't put it on the postInit() or render(); postInitForNewGame calls this function on the savegamewriter's callback
|
||||
}
|
||||
@@ -332,10 +353,11 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
// 1. lighten the IO burden
|
||||
// 2. cannot sync up the "counter" to determine whether both are finished
|
||||
uiAutosaveNotifier.setAsOpen()
|
||||
WriteSavegame.immediate(WriteSavegame.SaveMode.PLAYER, playerDisk, getPlayerSaveFiledesc(playerSavefileName), this, false, true) {
|
||||
val saveTime_t = App.getTIME_T()
|
||||
WriteSavegame.immediate(saveTime_t, WriteSavegame.SaveMode.PLAYER, playerDisk, getPlayerSaveFiledesc(playerSavefileName), this, false, true) {
|
||||
makeSavegameBackupCopy(getPlayerSaveFiledesc(playerSavefileName))
|
||||
|
||||
WriteSavegame.immediate(WriteSavegame.SaveMode.WORLD, worldDisk, getWorldSaveFiledesc(worldSavefileName), this, false, true) {
|
||||
WriteSavegame.immediate(saveTime_t, WriteSavegame.SaveMode.WORLD, worldDisk, getWorldSaveFiledesc(worldSavefileName), this, false, true) {
|
||||
makeSavegameBackupCopy(getWorldSaveFiledesc(worldSavefileName)) // don't put it on the postInit() or render(); must be called using callback
|
||||
uiAutosaveNotifier.setAsClose()
|
||||
}
|
||||
|
||||
@@ -8,17 +8,16 @@ import net.torvald.terrarum.console.Echo
|
||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
|
||||
import net.torvald.terrarum.serialise.WriteActor
|
||||
import net.torvald.terrarum.serialise.WriteMeta
|
||||
import net.torvald.terrarum.serialise.WriteWorld
|
||||
import java.io.IOException
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2017-07-18.
|
||||
*/
|
||||
object ExportMeta : ConsoleCommand {
|
||||
/*object ExportMeta : ConsoleCommand {
|
||||
override fun execute(args: Array<String>) {
|
||||
try {
|
||||
val str = WriteMeta(ingame!! as TerrarumIngame, App.getTIME_T())
|
||||
val str = net.torvald.terrarum.serialise.WriteMeta(ingame!! as TerrarumIngame, App.getTIME_T())
|
||||
val writer = java.io.FileWriter(App.defaultDir + "/Exports/savegame.json", false)
|
||||
writer.write(str)
|
||||
writer.close()
|
||||
@@ -33,7 +32,7 @@ object ExportMeta : ConsoleCommand {
|
||||
override fun printUsage() {
|
||||
Echo("Usage: Exportmeta")
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
object ExportWorld : ConsoleCommand {
|
||||
override fun execute(args: Array<String>) {
|
||||
|
||||
@@ -2,13 +2,14 @@ package net.torvald.terrarum.modulebasegame.gameactors
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.graphics.Texture
|
||||
import net.torvald.spriteanimation.HasAssembledSprite
|
||||
import net.torvald.spriteanimation.SpriteAnimation
|
||||
import net.torvald.spriteassembler.ADProperties
|
||||
import net.torvald.spriteassembler.AssembleSheetPixmap
|
||||
import net.torvald.terrarum.App
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.tvda.SimpleFileSystem
|
||||
import net.torvald.terrarum.utils.PlayerLastStatus
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
import java.util.*
|
||||
|
||||
@@ -21,7 +22,11 @@ import java.util.*
|
||||
|
||||
class IngamePlayer : ActorHumanoid {
|
||||
|
||||
var uuid = UUID.randomUUID(); private set
|
||||
val creationTime = App.getTIME_T()
|
||||
var lastPlayTime = App.getTIME_T() // cumulative value for the savegame
|
||||
var totalPlayTime = 0L // cumulative value for the savegame
|
||||
|
||||
val uuid = UUID.randomUUID()
|
||||
var worldCurrentlyPlaying: UUID = UUID(0L,0L) // only filled up on save and load; DO NOT USE THIS
|
||||
|
||||
/** ADL for main sprite. Necessary. */
|
||||
@@ -50,6 +55,17 @@ class IngamePlayer : ActorHumanoid {
|
||||
}
|
||||
|
||||
|
||||
/** Copy of some of the player's props before get overwritten by the props saved in the world.
|
||||
*
|
||||
* This field is only there for loading multiplayer map on singleplayer instances where the world loader would
|
||||
* permanently changing player's props into multiplayer world's.
|
||||
*/
|
||||
@Transient internal lateinit var unauthorisedPlayerProps: PlayerLastStatus
|
||||
|
||||
fun backupPlayerProps(isMultiplayer: Boolean) {
|
||||
unauthorisedPlayerProps = PlayerLastStatus(this, isMultiplayer)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer
|
||||
import com.badlogic.gdx.utils.JsonReader
|
||||
import net.torvald.getKeycapConsole
|
||||
import net.torvald.getKeycapPC
|
||||
import net.torvald.terrarum.*
|
||||
@@ -14,8 +15,6 @@ import net.torvald.terrarum.App.printdbg
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.serialise.Common
|
||||
import net.torvald.terrarum.serialise.LoadSavegame
|
||||
import net.torvald.terrarum.serialise.ReadMeta
|
||||
import net.torvald.terrarum.serialise.WriteMeta
|
||||
import net.torvald.terrarum.tvda.*
|
||||
import net.torvald.terrarum.ui.*
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
@@ -26,6 +25,9 @@ import java.util.logging.Level
|
||||
import java.util.zip.GZIPInputStream
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
val SAVE_CELL_WIDTH = 480
|
||||
val SAVE_CELL_HEIGHT = 120
|
||||
|
||||
/**
|
||||
* Only works if current screen set by the App is [TitleScreen]
|
||||
*
|
||||
@@ -55,13 +57,13 @@ class UILoadDemoSavefiles : UICanvas() {
|
||||
private val shapeRenderer = ShapeRenderer()
|
||||
|
||||
|
||||
internal val uiWidth = UIItemDemoSaveCells.WIDTH // 480
|
||||
internal val uiWidth = SAVE_CELL_WIDTH
|
||||
internal val uiX = (width - uiWidth) / 2
|
||||
|
||||
internal val textH = App.fontGame.lineHeight.toInt()
|
||||
|
||||
internal val cellGap = 20
|
||||
internal val cellInterval = cellGap + UIItemDemoSaveCells.HEIGHT
|
||||
internal val cellInterval = cellGap + SAVE_CELL_HEIGHT
|
||||
internal val gradAreaHeight = 32
|
||||
|
||||
internal val titleTextPosY: Int = App.scr.tvSafeGraphicsHeight + 10
|
||||
@@ -106,15 +108,15 @@ class UILoadDemoSavefiles : UICanvas() {
|
||||
Thread {
|
||||
// read savegames
|
||||
var savegamesCount = 0
|
||||
App.savegames.forEach { skimmer ->
|
||||
App.savegameWorlds.forEach { (uuid, skimmer) ->
|
||||
val x = uiX + if (App.getConfigBoolean("fx_streamerslayout")) App.scr.chatWidth / 2 else 0
|
||||
val y = titleTopGradEnd + cellInterval * savegamesCount
|
||||
try {
|
||||
addUIitem(UIItemDemoSaveCells(this, x, y, skimmer))
|
||||
addUIitem(UIItemWorldCells(this, x, y, skimmer))
|
||||
savegamesCount += 1
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
System.err.println("[UILoadDemoSavefiles] Savefile '${skimmer.diskFile.absolutePath}' cannot be loaded")
|
||||
System.err.println("[UILoadDemoSavefiles] Error while loading World '${skimmer.diskFile.absolutePath}'")
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
@@ -290,7 +292,7 @@ class UILoadDemoSavefiles : UICanvas() {
|
||||
override fun resize(width: Int, height: Int) {
|
||||
super.resize(width, height)
|
||||
scrollAreaHeight = height - 2 * App.scr.tvSafeGraphicsHeight - 64
|
||||
savesVisible = (scrollAreaHeight + cellInterval) / (cellInterval + UIItemDemoSaveCells.HEIGHT)
|
||||
savesVisible = (scrollAreaHeight + cellInterval) / (cellInterval + SAVE_CELL_HEIGHT)
|
||||
|
||||
listScroll = 0
|
||||
scrollTarget = 0
|
||||
@@ -311,49 +313,66 @@ class UILoadDemoSavefiles : UICanvas() {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class UIItemDemoSaveCells(
|
||||
class UIItemPlayerCells(
|
||||
parent: UILoadDemoSavefiles,
|
||||
initialX: Int,
|
||||
initialY: Int,
|
||||
val skimmer: DiskSkimmer) : UIItem(parent, initialX, initialY) {
|
||||
|
||||
companion object {
|
||||
const val WIDTH = 480
|
||||
const val HEIGHT = 120
|
||||
override val width = SAVE_CELL_WIDTH
|
||||
override val height = SAVE_CELL_HEIGHT
|
||||
|
||||
|
||||
|
||||
override fun dispose() {
|
||||
}
|
||||
|
||||
|
||||
private val metaFile: DiskEntry?
|
||||
}
|
||||
|
||||
|
||||
class UIItemWorldCells(
|
||||
parent: UILoadDemoSavefiles,
|
||||
initialX: Int,
|
||||
initialY: Int,
|
||||
val skimmer: DiskSkimmer) : UIItem(parent, initialX, initialY) {
|
||||
|
||||
|
||||
private val metaFile: EntryFile?
|
||||
private val saveName: String
|
||||
private val saveMode: Int
|
||||
private val isQuick: Boolean
|
||||
private val isAuto: Boolean
|
||||
private val meta: WriteMeta.WorldMeta?
|
||||
private val saveDamaged: Boolean
|
||||
private var saveDamaged: Boolean = false
|
||||
private val lastPlayedTimestamp: String
|
||||
|
||||
init {
|
||||
printdbg(this, "Rebuilding skimmer for savefile ${skimmer.diskFile.absolutePath}")
|
||||
skimmer.rebuild()
|
||||
|
||||
metaFile = skimmer.requestFile(-1)
|
||||
metaFile = skimmer.getFile(-1)
|
||||
if (metaFile == null) saveDamaged = true
|
||||
|
||||
saveName = skimmer.getDiskName(Common.CHARSET)
|
||||
saveMode = skimmer.getSaveMode()
|
||||
isQuick = (saveMode % 2 == 1)
|
||||
isAuto = (saveMode.ushr(1) != 0)
|
||||
meta = if (metaFile != null) ReadMeta.fromDiskEntry(metaFile) else null
|
||||
|
||||
saveDamaged = checkForSavegameDamage(skimmer)
|
||||
saveDamaged = saveDamaged or checkForSavegameDamage(skimmer)
|
||||
|
||||
lastPlayedTimestamp = if (meta != null)
|
||||
Instant.ofEpochSecond(meta.lastplay_t)
|
||||
.atZone(TimeZone.getDefault().toZoneId())
|
||||
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) +
|
||||
"/${parseDuration(meta.playtime_t)}"
|
||||
else "--:--:--/--h--m--s"
|
||||
if (metaFile != null) {
|
||||
val worldJson = JsonReader().parse(ByteArray64Reader(metaFile.bytes, Common.CHARSET))
|
||||
val lastplay_t = worldJson["lastPlayTime"].asLong()
|
||||
val playtime_t = worldJson["totalPlayTime"].asLong()
|
||||
lastPlayedTimestamp =
|
||||
Instant.ofEpochSecond(lastplay_t)
|
||||
.atZone(TimeZone.getDefault().toZoneId())
|
||||
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) +
|
||||
"/${parseDuration(playtime_t)}"
|
||||
}
|
||||
else {
|
||||
lastPlayedTimestamp = "--:--:--/--h--m--s"
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseDuration(seconds: Long): String {
|
||||
@@ -367,8 +386,8 @@ class UIItemDemoSaveCells(
|
||||
"${d}d${h.toString().padStart(2,'0')}h${m.toString().padStart(2,'0')}m${s.toString().padStart(2,'0')}s"
|
||||
}
|
||||
|
||||
override val width: Int = WIDTH
|
||||
override val height: Int = HEIGHT
|
||||
override val width: Int = SAVE_CELL_WIDTH
|
||||
override val height: Int = SAVE_CELL_HEIGHT
|
||||
|
||||
private var thumbPixmap: Pixmap? = null
|
||||
private var thumb: TextureRegion? = null
|
||||
|
||||
@@ -2,12 +2,8 @@ package net.torvald.terrarum.modulebasegame.ui
|
||||
|
||||
import com.badlogic.gdx.graphics.Camera
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import net.torvald.terrarum.App
|
||||
import net.torvald.terrarum.Second
|
||||
import net.torvald.terrarum.serialise.LoadSavegame
|
||||
import net.torvald.terrarum.tvda.VDUtil
|
||||
import net.torvald.terrarum.ui.UICanvas
|
||||
import java.util.logging.Level
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2021-09-13.
|
||||
@@ -31,11 +27,11 @@ class UIProxyLoadLatestSave : UICanvas() {
|
||||
}
|
||||
|
||||
override fun endOpening(delta: Float) {
|
||||
if (App.savegames.size > 0) {
|
||||
LoadSavegame(VDUtil.readDiskArchive(App.savegames[0].diskFile, Level.INFO) {
|
||||
System.err.println("Possibly damaged savefile ${App.savegames[0].diskFile.absolutePath}:\n$it")
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// do something!
|
||||
|
||||
|
||||
}
|
||||
|
||||
override fun endClosing(delta: Float) {
|
||||
|
||||
@@ -12,6 +12,7 @@ object UITitleRemoConYaml {
|
||||
* The class must be the UICanvas
|
||||
*/
|
||||
private val menuBase = """
|
||||
- MENU_LABEL_NEW_GAME : net.torvald.terrarum.modulebasegame.ui.UIProxyNewRandomGame
|
||||
- MENU_OPTIONS
|
||||
- MENU_LABEL_GRAPHICS : net.torvald.terrarum.modulebasegame.ui.GraphicsControlPanel
|
||||
- MENU_OPTIONS_CONTROLS : net.torvald.terrarum.modulebasegame.ui.UIKeyboardControlPanel
|
||||
@@ -27,17 +28,15 @@ object UITitleRemoConYaml {
|
||||
|
||||
private val menuWithSavefile = """
|
||||
- MENU_LABEL_CONTINUE : net.torvald.terrarum.modulebasegame.ui.UIProxyLoadLatestSave
|
||||
- MENU_LABEL_NEW_GAME : net.torvald.terrarum.modulebasegame.ui.UIProxyNewRandomGame
|
||||
- MENU_IO_LOAD : net.torvald.terrarum.modulebasegame.ui.UILoadDemoSavefiles
|
||||
- MENU_LABEL_RETURN
|
||||
"""
|
||||
- MENU_LABEL_NEW_WORLD
|
||||
- MENU_LABEL_RETURN"""
|
||||
|
||||
private val menuNewGame = """
|
||||
- MENU_LABEL_NEW_GAME : net.torvald.terrarum.modulebasegame.ui.UIProxyNewRandomGame
|
||||
"""
|
||||
|
||||
|
||||
operator fun invoke(hasSave: Boolean) =
|
||||
Yaml((if (hasSave) menuWithSavefile else menuNewGame) + menuBase).parse()
|
||||
Yaml((if (!hasSave) menuWithSavefile else menuNewGame) + menuBase).parse()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user