mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-06 08:38:30 +09:00
the file io is cursed
This commit is contained in:
@@ -1,11 +1,19 @@
|
|||||||
package net.torvald.terrarum
|
package net.torvald.terrarum
|
||||||
|
|
||||||
|
import com.badlogic.gdx.utils.JsonWriter
|
||||||
import net.torvald.terrarum.App.printdbg
|
import net.torvald.terrarum.App.printdbg
|
||||||
import net.torvald.terrarum.savegame.DiskSkimmer
|
import net.torvald.terrarum.gameactors.AVKey
|
||||||
|
import net.torvald.terrarum.savegame.*
|
||||||
|
import net.torvald.terrarum.savegame.VDFileID.ROOT
|
||||||
|
import net.torvald.terrarum.savegame.VDFileID.SAVEGAMEINFO
|
||||||
|
import net.torvald.terrarum.serialise.Common
|
||||||
|
import net.torvald.terrarum.utils.JsonFetcher
|
||||||
|
import net.torvald.terrarum.utils.forEachSiblings
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.StandardCopyOption
|
import java.nio.file.StandardCopyOption
|
||||||
|
import java.util.*
|
||||||
import kotlin.io.path.Path
|
import kotlin.io.path.Path
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,6 +65,39 @@ class SavegameCollection(files0: List<DiskSkimmer>) {
|
|||||||
fun getBaseFile(): DiskSkimmer {
|
fun getBaseFile(): DiskSkimmer {
|
||||||
return files.first { it.diskFile.extension.isBlank() }
|
return files.first { it.diskFile.extension.isBlank() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getUUID(): UUID {
|
||||||
|
var uuid: UUID? = null
|
||||||
|
loadable().getFile(SAVEGAMEINFO)!!.let {
|
||||||
|
JsonFetcher.readFromJsonString(ByteArray64Reader(it.bytes, Common.CHARSET)).forEachSiblings { name, value ->
|
||||||
|
if (name == "worldIndex" || name == "uuid") uuid = UUID.fromString(value.asString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return uuid!!
|
||||||
|
}
|
||||||
|
|
||||||
|
fun renamePlayer(name: String) {
|
||||||
|
files.forEach { skimmer ->
|
||||||
|
skimmer.rebuild()
|
||||||
|
skimmer.getFile(SAVEGAMEINFO)!!.let { file ->
|
||||||
|
val json = JsonFetcher.readFromJsonString(ByteArray64Reader(file.bytes, Common.CHARSET))
|
||||||
|
json.getChild("actorValue").getChild(AVKey.NAME).set(name)
|
||||||
|
|
||||||
|
val jsonBytes = json.prettyPrint(JsonWriter.OutputType.json, 0).encodeToByteArray().toByteArray64()
|
||||||
|
val newEntry = DiskEntry(SAVEGAMEINFO, ROOT, skimmer.requestFile(SAVEGAMEINFO)!!.creationDate, App.getTIME_T(), EntryFile(jsonBytes))
|
||||||
|
|
||||||
|
skimmer.appendEntry(newEntry)
|
||||||
|
|
||||||
|
skimmer.setDiskName(name, Common.CHARSET)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun renameWorld(name: String) {
|
||||||
|
files.forEach { skimmer ->
|
||||||
|
skimmer.setDiskName(name, Common.CHARSET)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SavegameCollectionPair(player: SavegameCollection?, world: SavegameCollection?) {
|
class SavegameCollectionPair(player: SavegameCollection?, world: SavegameCollection?) {
|
||||||
|
|||||||
@@ -800,17 +800,20 @@ fun AppUpdateListOfSavegames() {
|
|||||||
}
|
}
|
||||||
}.sortedByDescending { it.getLastModifiedTime() }.forEachIndexed { index, it ->
|
}.sortedByDescending { it.getLastModifiedTime() }.forEachIndexed { index, it ->
|
||||||
println("${index+1}.\t${it.diskFile.absolutePath}")
|
println("${index+1}.\t${it.diskFile.absolutePath}")
|
||||||
it.rebuild()
|
// it.rebuild()
|
||||||
|
|
||||||
val jsonFile = it.getFile(SAVEGAMEINFO)!!
|
// val jsonFile = it.getFile(SAVEGAMEINFO)!!
|
||||||
var worldUUID: UUID? = null
|
// var worldUUID: UUID? = null
|
||||||
JsonFetcher.readFromJsonString(ByteArray64Reader(jsonFile.bytes, Common.CHARSET)).forEachSiblings { name, value ->
|
// JsonFetcher.readFromJsonString(ByteArray64Reader(jsonFile.bytes, Common.CHARSET)).forEachSiblings { name, value ->
|
||||||
if (name == "worldIndex") worldUUID = UUID.fromString(value.asString())
|
// if (name == "worldIndex") worldUUID = UUID.fromString(value.asString())
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
val collection = SavegameCollection.collectFromBaseFilename(File(worldsDir), it.diskFile.name)
|
||||||
|
val worldUUID = collection.getUUID()
|
||||||
|
|
||||||
// if multiple valid savegames with same UUID exist, only the most recent one is retained
|
// if multiple valid savegames with same UUID exist, only the most recent one is retained
|
||||||
if (!App.savegameWorlds.contains(worldUUID)) {
|
if (!App.savegameWorlds.contains(worldUUID)) {
|
||||||
App.savegameWorlds[worldUUID] = SavegameCollection.collectFromBaseFilename(File(worldsDir), it.diskFile.name)
|
App.savegameWorlds[worldUUID] = collection
|
||||||
App.savegameWorldsName[worldUUID] = it.getDiskName(Common.CHARSET)
|
App.savegameWorldsName[worldUUID] = it.getDiskName(Common.CHARSET)
|
||||||
App.sortedSavegameWorlds.add(worldUUID)
|
App.sortedSavegameWorlds.add(worldUUID)
|
||||||
}
|
}
|
||||||
@@ -831,18 +834,21 @@ fun AppUpdateListOfSavegames() {
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
}.sortedByDescending { it.getLastModifiedTime() }.forEachIndexed { index, it ->
|
}.sortedByDescending { it.getLastModifiedTime() }.forEachIndexed { index, it ->
|
||||||
println("${index+1}.\t${it.diskFile.absolutePath}")
|
// println("${index+1}.\t${it.diskFile.absolutePath}")
|
||||||
it.rebuild()
|
// it.rebuild()
|
||||||
|
|
||||||
val jsonFile = it.getFile(SAVEGAMEINFO)!!
|
// val jsonFile = it.getFile(SAVEGAMEINFO)!!
|
||||||
var playerUUID: UUID? = null
|
// var playerUUID: UUID? = null
|
||||||
JsonFetcher.readFromJsonString(ByteArray64Reader(jsonFile.bytes, Common.CHARSET)).forEachSiblings { name, value ->
|
// JsonFetcher.readFromJsonString(ByteArray64Reader(jsonFile.bytes, Common.CHARSET)).forEachSiblings { name, value ->
|
||||||
if (name == "uuid") playerUUID = UUID.fromString(value.asString())
|
// if (name == "uuid") playerUUID = UUID.fromString(value.asString())
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
val collection = SavegameCollection.collectFromBaseFilename(File(playersDir), it.diskFile.name)
|
||||||
|
val playerUUID = collection.getUUID()
|
||||||
|
|
||||||
// if multiple valid savegames with same UUID exist, only the most recent one is retained
|
// if multiple valid savegames with same UUID exist, only the most recent one is retained
|
||||||
if (!App.savegamePlayers.contains(playerUUID)) {
|
if (!App.savegamePlayers.contains(playerUUID)) {
|
||||||
App.savegamePlayers[playerUUID] = SavegameCollection.collectFromBaseFilename(File(playersDir), it.diskFile.name)
|
App.savegamePlayers[playerUUID] = collection
|
||||||
App.savegamePlayersName[playerUUID] = it.getDiskName(Common.CHARSET)
|
App.savegamePlayersName[playerUUID] = it.getDiskName(Common.CHARSET)
|
||||||
App.sortedPlayers.add(playerUUID)
|
App.sortedPlayers.add(playerUUID)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,11 +77,11 @@ class FixtureWorldPortal : Electric {
|
|||||||
// load existing
|
// load existing
|
||||||
val jobAfterSave: () -> Unit
|
val jobAfterSave: () -> Unit
|
||||||
if (it.worldDiskToLoad != null) {
|
if (it.worldDiskToLoad != null) {
|
||||||
UILoadGovernor.worldDisk = it.worldDiskToLoad
|
|
||||||
UILoadGovernor.playerDisk = App.savegamePlayers[player.uuid]!!.files[0]
|
|
||||||
jobAfterSave = {
|
jobAfterSave = {
|
||||||
UILoadGovernor.playerDisk!!.rebuild()
|
LoadSavegame(
|
||||||
LoadSavegame(UILoadGovernor.playerDisk!!, UILoadGovernor.worldDisk!!)
|
App.savegamePlayers[player.uuid]!!.files[0],
|
||||||
|
it.worldDiskToLoad
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// create new
|
// create new
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ class UILoadAutosave(val full: UILoadSavegame) : UICanvas() {
|
|||||||
it.extraDrawOp = getDrawTextualInfoFun(loadables.getManualSave()!!)
|
it.extraDrawOp = getDrawTextualInfoFun(loadables.getManualSave()!!)
|
||||||
it.clickOnceListener = { _,_ ->
|
it.clickOnceListener = { _,_ ->
|
||||||
loadables.getManualSave()!!.let {
|
loadables.getManualSave()!!.let {
|
||||||
UILoadGovernor.playerDisk = it.player
|
// UILoadGovernor.playerDisk = it.player
|
||||||
UILoadGovernor.worldDisk = it.world
|
// UILoadGovernor.worldDisk = it.world
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -81,8 +81,8 @@ class UILoadAutosave(val full: UILoadSavegame) : UICanvas() {
|
|||||||
it.extraDrawOp = getDrawTextualInfoFun(loadables.getAutoSave()!!)
|
it.extraDrawOp = getDrawTextualInfoFun(loadables.getAutoSave()!!)
|
||||||
it.clickOnceListener = { _,_ ->
|
it.clickOnceListener = { _,_ ->
|
||||||
loadables.getAutoSave()!!.let {
|
loadables.getAutoSave()!!.let {
|
||||||
UILoadGovernor.playerDisk = it.player
|
// UILoadGovernor.playerDisk = it.player
|
||||||
UILoadGovernor.worldDisk = it.world
|
// UILoadGovernor.worldDisk = it.world
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ object UILoadGovernor {
|
|||||||
var worldUUID: UUID? = null
|
var worldUUID: UUID? = null
|
||||||
var previousSaveWasLoaded = false
|
var previousSaveWasLoaded = false
|
||||||
// used by the debug save loader
|
// used by the debug save loader
|
||||||
var playerDisk: DiskSkimmer? = null
|
/*var playerDisk: DiskSkimmer? = null
|
||||||
set(value) {
|
set(value) {
|
||||||
printdbg(this, "Player selected: ${value?.diskFile?.name}")
|
printdbg(this, "Player selected: ${value?.diskFile?.name}")
|
||||||
field = value
|
field = value
|
||||||
@@ -72,12 +72,12 @@ object UILoadGovernor {
|
|||||||
set(value) {
|
set(value) {
|
||||||
printdbg(this, "World selected: ${value?.diskFile?.name}")
|
printdbg(this, "World selected: ${value?.diskFile?.name}")
|
||||||
field = value
|
field = value
|
||||||
}
|
}*/
|
||||||
|
|
||||||
fun reset() {
|
fun reset() {
|
||||||
printdbg(this, "Resetting player and world selection")
|
printdbg(this, "Resetting player and world selection")
|
||||||
playerDisk = null
|
// playerDisk = null
|
||||||
worldDisk = null
|
// worldDisk = null
|
||||||
|
|
||||||
playerUUID = null
|
playerUUID = null
|
||||||
worldUUID = null
|
worldUUID = null
|
||||||
@@ -205,15 +205,14 @@ class UILoadDemoSavefiles(val remoCon: UIRemoCon) : Advanceable() {
|
|||||||
|
|
||||||
savegamesCount = 0
|
savegamesCount = 0
|
||||||
App.sortedPlayers.forEach { uuid ->
|
App.sortedPlayers.forEach { uuid ->
|
||||||
val skimmer = App.savegamePlayers[uuid]!!.loadable()
|
|
||||||
val x = uiX
|
val x = uiX
|
||||||
val y = titleTopGradEnd + cellInterval * savegamesCount
|
val y = titleTopGradEnd + cellInterval * savegamesCount
|
||||||
try {
|
try {
|
||||||
playerCells.add(UIItemPlayerCells(this, x, y, skimmer))
|
playerCells.add(UIItemPlayerCells(this, x, y, uuid))
|
||||||
savegamesCount += 1
|
savegamesCount += 1
|
||||||
}
|
}
|
||||||
catch (e: Throwable) {
|
catch (e: Throwable) {
|
||||||
System.err.println("[UILoadDemoSavefiles] Error while loading Player '${skimmer.diskFile.absolutePath}'")
|
System.err.println("[UILoadDemoSavefiles] Error while loading Player with UUID $uuid")
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -321,7 +320,10 @@ class UILoadDemoSavefiles(val remoCon: UIRemoCon) : Advanceable() {
|
|||||||
App.fontGame.draw(batch, txt, (App.scr.width - App.fontGame.getWidth(txt)) / 2f, (App.scr.height - App.fontGame.lineHeight) / 2f)
|
App.fontGame.draw(batch, txt, (App.scr.width - App.fontGame.getWidth(txt)) / 2f, (App.scr.height - App.fontGame.lineHeight) / 2f)
|
||||||
|
|
||||||
if (loadFired == 2) {
|
if (loadFired == 2) {
|
||||||
LoadSavegame(UILoadGovernor.playerDisk!!, UILoadGovernor.worldDisk)
|
LoadSavegame(
|
||||||
|
App.savegamePlayers[UILoadGovernor.playerUUID]!!.loadable(),
|
||||||
|
App.savegameWorlds[UILoadGovernor.worldUUID]?.loadable()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -488,13 +490,13 @@ class UIItemPlayerCells(
|
|||||||
parent: Advanceable,
|
parent: Advanceable,
|
||||||
initialX: Int,
|
initialX: Int,
|
||||||
initialY: Int,
|
initialY: Int,
|
||||||
val skimmer: DiskSkimmer) : UIItem(parent, initialX, initialY) {
|
val playerUUID: UUID) : UIItem(parent, initialX, initialY) {
|
||||||
|
|
||||||
override val width = SAVE_CELL_WIDTH
|
override val width = SAVE_CELL_WIDTH
|
||||||
override val height = SAVE_CELL_HEIGHT
|
override val height = SAVE_CELL_HEIGHT
|
||||||
|
|
||||||
override var clickOnceListener: ((Int, Int) -> Unit) = { _: Int, _: Int ->
|
override var clickOnceListener: ((Int, Int) -> Unit) = { _: Int, _: Int ->
|
||||||
UILoadGovernor.playerDisk = skimmer
|
// UILoadGovernor.playerDisk = App.
|
||||||
UILoadGovernor.playerUUID = playerUUID
|
UILoadGovernor.playerUUID = playerUUID
|
||||||
UILoadGovernor.worldUUID = worldUUID
|
UILoadGovernor.worldUUID = worldUUID
|
||||||
parent.advanceMode(this)
|
parent.advanceMode(this)
|
||||||
@@ -505,15 +507,14 @@ class UIItemPlayerCells(
|
|||||||
private var lastPlayTime: String = "????-??-?? --:--:--"
|
private var lastPlayTime: String = "????-??-?? --:--:--"
|
||||||
private var totalPlayTime: String = "--h--m--s"
|
private var totalPlayTime: String = "--h--m--s"
|
||||||
|
|
||||||
lateinit var playerUUID: UUID; private set
|
// lateinit var playerUUID: UUID; private set
|
||||||
lateinit var worldUUID: UUID; private set
|
lateinit var worldUUID: UUID; private set
|
||||||
|
|
||||||
init {
|
init {
|
||||||
skimmer.getFile(SAVEGAMEINFO)?.bytes?.let {
|
App.savegamePlayers[playerUUID]!!.loadable().getFile(SAVEGAMEINFO)?.bytes?.let {
|
||||||
var lastPlayTime0 = 0L
|
var lastPlayTime0 = 0L
|
||||||
|
|
||||||
JsonFetcher.readFromJsonString(ByteArray64Reader(it, Common.CHARSET)).forEachSiblings { name, value ->
|
JsonFetcher.readFromJsonString(ByteArray64Reader(it, Common.CHARSET)).forEachSiblings { name, value ->
|
||||||
if (name == "uuid") playerUUID = UUID.fromString(value.asString())
|
|
||||||
if (name == "worldCurrentlyPlaying") worldUUID = UUID.fromString(value.asString())
|
if (name == "worldCurrentlyPlaying") worldUUID = UUID.fromString(value.asString())
|
||||||
if (name == "totalPlayTime") totalPlayTime = parseDuration(value.asLong())
|
if (name == "totalPlayTime") totalPlayTime = parseDuration(value.asLong())
|
||||||
if (name == "lastPlayTime") lastPlayTime0 = value.asLong()
|
if (name == "lastPlayTime") lastPlayTime0 = value.asLong()
|
||||||
@@ -565,7 +566,8 @@ class UIItemPlayerCells(
|
|||||||
|
|
||||||
override fun render(batch: SpriteBatch, camera: Camera) {
|
override fun render(batch: SpriteBatch, camera: Camera) {
|
||||||
// try to generate a texture
|
// try to generate a texture
|
||||||
if (skimmer.initialised && !hasTexture) {
|
if (!hasTexture) {
|
||||||
|
val skimmer = App.savegamePlayers[playerUUID]!!.loadable()
|
||||||
skimmer.getFile(SAVEGAMEINFO)?.bytes?.let {
|
skimmer.getFile(SAVEGAMEINFO)?.bytes?.let {
|
||||||
try {
|
try {
|
||||||
printdbg(this, "Generating portrait for $playerName")
|
printdbg(this, "Generating portrait for $playerName")
|
||||||
@@ -757,7 +759,7 @@ class UIItemWorldCells(
|
|||||||
private var highlightCol: Color = Toolkit.Theme.COL_LIST_DEFAULT
|
private var highlightCol: Color = Toolkit.Theme.COL_LIST_DEFAULT
|
||||||
|
|
||||||
override var clickOnceListener: ((Int, Int) -> Unit) = { _: Int, _: Int ->
|
override var clickOnceListener: ((Int, Int) -> Unit) = { _: Int, _: Int ->
|
||||||
UILoadGovernor.worldDisk = skimmer
|
// UILoadGovernor.worldDisk = skimmer
|
||||||
parent.advanceMode(this)
|
parent.advanceMode(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,36 +57,70 @@ class UILoadList(val full: UILoadSavegame) : UICanvas() {
|
|||||||
|
|
||||||
private val mode1Node = Yaml(UITitleRemoConYaml.injectedMenuSingleCharSel).parse()
|
private val mode1Node = Yaml(UITitleRemoConYaml.injectedMenuSingleCharSel).parse()
|
||||||
|
|
||||||
|
private var showSpinner = false
|
||||||
|
|
||||||
|
|
||||||
|
fun advanceMode() {
|
||||||
|
App.printdbg(this, "Load playerUUID: ${UILoadGovernor.playerUUID}, worldUUID: ${UILoadGovernor.worldUUID}")
|
||||||
|
full.loadables = SavegameCollectionPair(App.savegamePlayers[UILoadGovernor.playerUUID], App.savegameWorlds[UILoadGovernor.worldUUID])
|
||||||
|
|
||||||
|
|
||||||
|
if (full.loadables.moreRecentAutosaveAvailable()) {
|
||||||
|
// make choice for load manual or auto, if available
|
||||||
|
full.hasNewerAutosave = true
|
||||||
|
|
||||||
|
full.queueUpManageScr()
|
||||||
|
full.bringAutosaveSelectorUp()
|
||||||
|
}
|
||||||
|
else if (!full.loadables.saveAvaliable()) {
|
||||||
|
// show save is damaged and cannot be loaded
|
||||||
|
full.queueUpDamagedSaveScr()
|
||||||
|
full.takeAutosaveSelectorDown()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// val (p, w) = full.loadables.getLoadableSave()!!
|
||||||
|
// UILoadGovernor.playerDisk = p; UILoadGovernor.worldDisk = w
|
||||||
|
|
||||||
|
if (full.loadables.newerSaveIsDamaged) {
|
||||||
|
UILoadGovernor.previousSaveWasLoaded = true
|
||||||
|
}
|
||||||
|
|
||||||
|
full.queueUpManageScr()
|
||||||
|
full.takeAutosaveSelectorDown()
|
||||||
|
}
|
||||||
|
|
||||||
|
full.changePanelTo(1)
|
||||||
|
}
|
||||||
|
|
||||||
override fun show() {
|
override fun show() {
|
||||||
mode1Node.parent = full.remoCon.treeRoot
|
mode1Node.parent = full.remoCon.treeRoot
|
||||||
mode1Node.data = "MENU_MODE_SINGLEPLAYER : net.torvald.terrarum.modulebasegame.ui.UILoadSavegame"
|
mode1Node.data = "MENU_MODE_SINGLEPLAYER : net.torvald.terrarum.modulebasegame.ui.UILoadSavegame"
|
||||||
full.remoCon.setNewRemoConContents(mode1Node)
|
full.remoCon.setNewRemoConContents(mode1Node)
|
||||||
|
playerCells.clear()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
full.remoCon.handler.lockToggle()
|
full.remoCon.handler.lockToggle()
|
||||||
full.showSpinner = true
|
showSpinner = true
|
||||||
|
|
||||||
Thread {
|
Thread {
|
||||||
// read savegames
|
// read savegames
|
||||||
var savegamesCount = 0
|
var savegamesCount = 0
|
||||||
App.sortedPlayers.forEach { uuid ->
|
App.sortedPlayers.forEach { uuid ->
|
||||||
val skimmer = App.savegamePlayers[uuid]!!.loadable()
|
|
||||||
val x = full.uiX
|
val x = full.uiX
|
||||||
val y = titleTopGradEnd + cellInterval * savegamesCount
|
val y = titleTopGradEnd + cellInterval * savegamesCount
|
||||||
try {
|
try {
|
||||||
playerCells.add(UIItemPlayerCells(full, x, y, skimmer))
|
playerCells.add(UIItemPlayerCells(full, x, y, uuid))
|
||||||
savegamesCount += 1
|
savegamesCount += 1
|
||||||
}
|
}
|
||||||
catch (e: Throwable) {
|
catch (e: Throwable) {
|
||||||
System.err.println("[UILoadSavegame] Error while loading Player '${skimmer.diskFile.absolutePath}'")
|
System.err.println("[UILoadSavegame] Error while loading Player with UUID $uuid")
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
full.remoCon.handler.unlockToggle()
|
full.remoCon.handler.unlockToggle()
|
||||||
full.showSpinner = false
|
showSpinner = false
|
||||||
}.start()
|
}.start()
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -180,9 +214,9 @@ class UILoadList(val full: UILoadSavegame) : UICanvas() {
|
|||||||
full.setCameraPosition(batch, camera, 0f, 0f)
|
full.setCameraPosition(batch, camera, 0f, 0f)
|
||||||
val saveTex = TextureRegion(Texture(savePixmap)); saveTex.flip(false, true)
|
val saveTex = TextureRegion(Texture(savePixmap)); saveTex.flip(false, true)
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
batch.draw(saveTex, (width - uiWidth - 10) / 2f, 0f)
|
batch.draw(saveTex, posX + (width - uiWidth - 10) / 2f, 0f)
|
||||||
// Control help
|
// Control help
|
||||||
App.fontGame.draw(batch, controlHelp, full.uiX.toFloat(), controlHelperY.toFloat())
|
App.fontGame.draw(batch, controlHelp, posX + full.uiX.toFloat(), controlHelperY.toFloat())
|
||||||
}
|
}
|
||||||
|
|
||||||
saveTex.texture.dispose()
|
saveTex.texture.dispose()
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ class UILoadManage(val full: UILoadSavegame) : UICanvas() {
|
|||||||
private val drawX = (Toolkit.drawWidth - 480) / 2
|
private val drawX = (Toolkit.drawWidth - 480) / 2
|
||||||
private val drawY = (App.scr.height - 480) / 2
|
private val drawY = (App.scr.height - 480) / 2
|
||||||
private val buttonRowY = drawY + 480 - 24
|
private val buttonRowY = drawY + 480 - 24
|
||||||
private val corruptedBackButton = UIItemTextButton(this, "MENU_LABEL_BACK", (Toolkit.drawWidth - goButtonWidth) / 2, buttonRowY, goButtonWidth, true, alignment = UIItemTextButton.Companion.Alignment.CENTRE, hasBorder = true)
|
|
||||||
private val confirmCancelButton = UIItemTextButton(this, "MENU_LABEL_CANCEL", drawX + (240 - goButtonWidth) / 2, buttonRowY, goButtonWidth, true, alignment = UIItemTextButton.Companion.Alignment.CENTRE, hasBorder = true)
|
private val confirmCancelButton = UIItemTextButton(this, "MENU_LABEL_CANCEL", drawX + (240 - goButtonWidth) / 2, buttonRowY, goButtonWidth, true, alignment = UIItemTextButton.Companion.Alignment.CENTRE, hasBorder = true)
|
||||||
private val confirmDeleteButton = UIItemTextButton(this, "MENU_LABEL_DELETE", drawX + 240 + (240 - goButtonWidth) / 2, buttonRowY, goButtonWidth, true, alignment = UIItemTextButton.Companion.Alignment.CENTRE, hasBorder = true, inactiveCol = Toolkit.Theme.COL_RED, activeCol = Toolkit.Theme.COL_REDD)
|
private val confirmDeleteButton = UIItemTextButton(this, "MENU_LABEL_DELETE", drawX + 240 + (240 - goButtonWidth) / 2, buttonRowY, goButtonWidth, true, alignment = UIItemTextButton.Companion.Alignment.CENTRE, hasBorder = true, inactiveCol = Toolkit.Theme.COL_RED, activeCol = Toolkit.Theme.COL_REDD)
|
||||||
|
|
||||||
@@ -32,7 +31,6 @@ class UILoadManage(val full: UILoadSavegame) : UICanvas() {
|
|||||||
private val MODE_RENAME = 32 // show rename dialogue
|
private val MODE_RENAME = 32 // show rename dialogue
|
||||||
|
|
||||||
init {
|
init {
|
||||||
corruptedBackButton.clickOnceListener = { _,_ -> full.remoCon.openUI(UILoadSavegame(full.remoCon)) }
|
|
||||||
confirmCancelButton.clickOnceListener = { _,_ -> full.remoCon.openUI(UILoadSavegame(full.remoCon)) }
|
confirmCancelButton.clickOnceListener = { _,_ -> full.remoCon.openUI(UILoadSavegame(full.remoCon)) }
|
||||||
confirmDeleteButton.clickOnceListener = { _,_ ->
|
confirmDeleteButton.clickOnceListener = { _,_ ->
|
||||||
val pu = full.buttonSelectedForDeletion!!.playerUUID
|
val pu = full.buttonSelectedForDeletion!!.playerUUID
|
||||||
@@ -45,17 +43,21 @@ class UILoadManage(val full: UILoadSavegame) : UICanvas() {
|
|||||||
// don't delete the world please
|
// don't delete the world please
|
||||||
full.remoCon.openUI(UILoadSavegame(full.remoCon))
|
full.remoCon.openUI(UILoadSavegame(full.remoCon))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addUIitem(confirmCancelButton)
|
||||||
|
addUIitem(confirmDeleteButton)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun updateUI(delta: Float) {
|
override fun updateUI(delta: Float) {
|
||||||
TODO("Not yet implemented")
|
confirmCancelButton.update(delta)
|
||||||
|
confirmDeleteButton.update(delta)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
||||||
if (mode == MODE_DELETE) {
|
if (mode == MODE_DELETE) {
|
||||||
Toolkit.drawTextCentered(batch, App.fontGame, Lang["MENU_LABEL_SAVE_WILL_BE_DELETED"], Toolkit.drawWidth, 0, titleTopGradEnd + cellInterval - 46)
|
Toolkit.drawTextCentered(batch, App.fontGame, Lang["MENU_LABEL_SAVE_WILL_BE_DELETED"], Toolkit.drawWidth, 0, full.titleTopGradEnd + full.cellInterval - 46)
|
||||||
Toolkit.drawTextCentered(batch, App.fontGame, Lang["MENU_LABEL_ARE_YOU_SURE"], Toolkit.drawWidth, 0, titleTopGradEnd + cellInterval + SAVE_CELL_HEIGHT + 36)
|
Toolkit.drawTextCentered(batch, App.fontGame, Lang["MENU_LABEL_ARE_YOU_SURE"], Toolkit.drawWidth, 0, full.titleTopGradEnd + full.cellInterval + SAVE_CELL_HEIGHT + 36)
|
||||||
|
|
||||||
full.buttonSelectedForDeletion!!.render(batch, camera)
|
full.buttonSelectedForDeletion!!.render(batch, camera)
|
||||||
|
|
||||||
@@ -65,7 +67,20 @@ class UILoadManage(val full: UILoadSavegame) : UICanvas() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
TODO("Not yet implemented")
|
}
|
||||||
|
|
||||||
|
override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
||||||
|
confirmCancelButton.touchDown(screenX, screenY, pointer, button)
|
||||||
|
confirmDeleteButton.touchDown(screenX, screenY, pointer, button)
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
||||||
|
confirmCancelButton.touchUp(screenX, screenY, pointer, button)
|
||||||
|
confirmDeleteButton.touchUp(screenX, screenY, pointer, button)
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package net.torvald.terrarum.modulebasegame.ui
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Camera
|
||||||
|
import com.badlogic.gdx.graphics.Color
|
||||||
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
|
import net.torvald.terrarum.App
|
||||||
|
import net.torvald.terrarum.langpack.Lang
|
||||||
|
import net.torvald.terrarum.ui.Toolkit
|
||||||
|
import net.torvald.terrarum.ui.UICanvas
|
||||||
|
import net.torvald.terrarum.ui.UIItemTextButton
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 2023-07-07.
|
||||||
|
*/
|
||||||
|
class UILoadSaveDamaged(val full: UILoadSavegame) : UICanvas() {
|
||||||
|
|
||||||
|
override var width: Int = Toolkit.drawWidth
|
||||||
|
override var height: Int = App.scr.height
|
||||||
|
|
||||||
|
private val goButtonWidth = 180
|
||||||
|
private val drawX = (Toolkit.drawWidth - 480) / 2
|
||||||
|
private val drawY = (App.scr.height - 480) / 2
|
||||||
|
private val buttonRowY = drawY + 480 - 24
|
||||||
|
private val corruptedBackButton = UIItemTextButton(this, "MENU_LABEL_BACK", (Toolkit.drawWidth - goButtonWidth) / 2, buttonRowY, goButtonWidth, true, alignment = UIItemTextButton.Companion.Alignment.CENTRE, hasBorder = true)
|
||||||
|
|
||||||
|
init {
|
||||||
|
corruptedBackButton.clickOnceListener = { _,_ ->
|
||||||
|
full.changePanelTo(0)
|
||||||
|
println("aaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
|
||||||
|
}
|
||||||
|
|
||||||
|
addUIitem(corruptedBackButton)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateUI(delta: Float) {
|
||||||
|
corruptedBackButton.update(delta)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
||||||
|
Toolkit.drawTextCentered(batch, App.fontGame, Lang["ERROR_SAVE_CORRUPTED"], Toolkit.drawWidth, 0, App.scr.height / 2 - 42)
|
||||||
|
|
||||||
|
corruptedBackButton.render(batch, camera)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dispose() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,31 +1,22 @@
|
|||||||
package net.torvald.terrarum.modulebasegame.ui
|
package net.torvald.terrarum.modulebasegame.ui
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx
|
import com.badlogic.gdx.Gdx
|
||||||
import com.badlogic.gdx.Input
|
|
||||||
import com.badlogic.gdx.graphics.*
|
import com.badlogic.gdx.graphics.*
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||||
import com.badlogic.gdx.utils.Disposable
|
|
||||||
import com.badlogic.gdx.utils.GdxRuntimeException
|
import com.badlogic.gdx.utils.GdxRuntimeException
|
||||||
import net.torvald.unicode.getKeycapConsole
|
import net.torvald.unicode.getKeycapConsole
|
||||||
import net.torvald.unicode.getKeycapPC
|
import net.torvald.unicode.getKeycapPC
|
||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.*
|
||||||
import net.torvald.terrarum.App.printdbg
|
import net.torvald.terrarum.App.printdbg
|
||||||
import net.torvald.terrarum.langpack.Lang
|
import net.torvald.terrarum.langpack.Lang
|
||||||
import net.torvald.terrarum.savegame.ByteArray64InputStream
|
|
||||||
import net.torvald.terrarum.savegame.EntryFile
|
|
||||||
import net.torvald.terrarum.modulebasegame.serialise.LoadSavegame
|
import net.torvald.terrarum.modulebasegame.serialise.LoadSavegame
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVENTORY_CELLS_OFFSET_Y
|
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVENTORY_CELLS_OFFSET_Y
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.internalWidth
|
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.internalWidth
|
||||||
import net.torvald.terrarum.savegame.VDFileID.PLAYER_SCREENSHOT
|
|
||||||
import net.torvald.terrarum.ui.*
|
import net.torvald.terrarum.ui.*
|
||||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||||
import java.time.Instant
|
|
||||||
import java.time.format.DateTimeFormatter
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.zip.GZIPInputStream
|
|
||||||
import kotlin.collections.ArrayList
|
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
|
|
||||||
@@ -74,15 +65,6 @@ class UILoadSavegame(val remoCon: UIRemoCon) : Advanceable() {
|
|||||||
internal val titleTopGradEnd: Int = titleTopGradStart + gradAreaHeight
|
internal val titleTopGradEnd: Int = titleTopGradStart + gradAreaHeight
|
||||||
internal val titleBottomGradStart: Int = height - App.scr.tvSafeGraphicsHeight - gradAreaHeight
|
internal val titleBottomGradStart: Int = height - App.scr.tvSafeGraphicsHeight - gradAreaHeight
|
||||||
internal val titleBottomGradEnd: Int = titleBottomGradStart + gradAreaHeight
|
internal val titleBottomGradEnd: Int = titleBottomGradStart + gradAreaHeight
|
||||||
internal val controlHelperY: Int = titleBottomGradStart + gradAreaHeight - textH
|
|
||||||
|
|
||||||
|
|
||||||
private val controlHelp: String
|
|
||||||
get() = if (App.environment == RunningEnvironment.PC)
|
|
||||||
"${getKeycapPC(App.getConfigInt("control_key_up"))}${getKeycapPC(App.getConfigInt("control_key_down"))}" +
|
|
||||||
" ${Lang["MENU_CONTROLS_SCROLL"]}"
|
|
||||||
else
|
|
||||||
"${getKeycapConsole('R')} ${Lang["MENU_CONTROLS_SCROLL"]}"
|
|
||||||
|
|
||||||
|
|
||||||
private var scrollAreaHeight = height - 2 * App.scr.tvSafeGraphicsHeight - 64
|
private var scrollAreaHeight = height - 2 * App.scr.tvSafeGraphicsHeight - 64
|
||||||
@@ -95,8 +77,6 @@ class UILoadSavegame(val remoCon: UIRemoCon) : Advanceable() {
|
|||||||
private val scrollAnimLen = 0.1f
|
private val scrollAnimLen = 0.1f
|
||||||
private var sliderFBO = FrameBuffer(Pixmap.Format.RGBA8888, uiWidth + 10, height, false)
|
private var sliderFBO = FrameBuffer(Pixmap.Format.RGBA8888, uiWidth + 10, height, false)
|
||||||
|
|
||||||
internal var showSpinner = false
|
|
||||||
|
|
||||||
internal var buttonSelectedForDeletion: UIItemPlayerCells? = null
|
internal var buttonSelectedForDeletion: UIItemPlayerCells? = null
|
||||||
|
|
||||||
private val goButtonWidth = 180
|
private val goButtonWidth = 180
|
||||||
@@ -104,7 +84,7 @@ class UILoadSavegame(val remoCon: UIRemoCon) : Advanceable() {
|
|||||||
private val drawY = (App.scr.height - 480) / 2
|
private val drawY = (App.scr.height - 480) / 2
|
||||||
private val buttonRowY = drawY + 480 - 24
|
private val buttonRowY = drawY + 480 - 24
|
||||||
|
|
||||||
private lateinit var loadables: SavegameCollectionPair
|
internal lateinit var loadables: SavegameCollectionPair // will be used and modified by subUIs
|
||||||
|
|
||||||
/*private val altSelDrawW = 640
|
/*private val altSelDrawW = 640
|
||||||
private val altSelHdrawW = altSelDrawW / 2
|
private val altSelHdrawW = altSelDrawW / 2
|
||||||
@@ -115,10 +95,13 @@ class UILoadSavegame(val remoCon: UIRemoCon) : Advanceable() {
|
|||||||
private val altSelQdrawW = altSelDrawW / 4
|
private val altSelQdrawW = altSelDrawW / 4
|
||||||
private val altSelQQQdrawW = altSelDrawW * 3 / 4*/
|
private val altSelQQQdrawW = altSelDrawW * 3 / 4*/
|
||||||
|
|
||||||
|
internal var hasNewerAutosave = false
|
||||||
|
|
||||||
private val transitionalListing = UILoadList(this)
|
private val transitionalListing = UILoadList(this)
|
||||||
private val transitionalAutosave = UILoadAutosave(this)
|
private val transitionalAutosave = UILoadAutosave(this)
|
||||||
private val transitionalManage = UILoadManage(this)
|
private val transitionalManage = UILoadManage(this)
|
||||||
private val transitionalNewCharacter = UINewCharacter(remoCon)
|
private val transitionalNewCharacter = UINewCharacter(remoCon)
|
||||||
|
private val transitionalSaveDamaged = UILoadSaveDamaged(this)
|
||||||
private val transitionPanel = UIItemHorizontalFadeSlide(
|
private val transitionPanel = UIItemHorizontalFadeSlide(
|
||||||
this,
|
this,
|
||||||
(width - internalWidth) / 2,
|
(width - internalWidth) / 2,
|
||||||
@@ -127,118 +110,34 @@ class UILoadSavegame(val remoCon: UIRemoCon) : Advanceable() {
|
|||||||
App.scr.height,
|
App.scr.height,
|
||||||
0f,
|
0f,
|
||||||
listOf(transitionalListing),
|
listOf(transitionalListing),
|
||||||
listOf(transitionalManage, transitionalAutosave, transitionalNewCharacter)
|
listOf(transitionalManage, transitionalNewCharacter, transitionalSaveDamaged),
|
||||||
|
listOf(NullUI, transitionalAutosave)
|
||||||
)
|
)
|
||||||
|
|
||||||
init {
|
internal fun queueUpManageScr() { transitionPanel.setCentreUIto(0) }
|
||||||
|
internal fun queueUpNewCharScr() { transitionPanel.setCentreUIto(1) }
|
||||||
|
internal fun queueUpDamagedSaveScr() { transitionPanel.setCentreUIto(2) }
|
||||||
|
|
||||||
}
|
internal fun bringAutosaveSelectorUp() { transitionPanel.setRightUIto(1) }
|
||||||
|
internal fun takeAutosaveSelectorDown() { transitionPanel.setRightUIto(0) }
|
||||||
|
|
||||||
init {
|
|
||||||
|
|
||||||
|
internal fun changePanelTo(index: Int) {
|
||||||
|
transitionPanel.requestTransition(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun advanceMode(button: UIItem) {
|
override fun advanceMode(button: UIItem) {
|
||||||
printdbg(this, "advanceMode ${button.javaClass.canonicalName}")
|
printdbg(this, "advanceMode ${button.javaClass.canonicalName}")
|
||||||
|
|
||||||
mode += 1
|
if (button.javaClass.simpleName == "UIItemPlayerCells") {
|
||||||
uiScroll = 0f
|
transitionalListing.advanceMode()
|
||||||
scrollFrom = 0
|
|
||||||
scrollTarget = 0
|
|
||||||
scrollAnimCounter = 0f
|
|
||||||
loadFired = 0
|
|
||||||
|
|
||||||
printdbg(this, "savelist mode: $mode")
|
|
||||||
|
|
||||||
// look for recently played world
|
|
||||||
if (mode == MODE_SELECT_AFTER) {
|
|
||||||
|
|
||||||
// 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}")
|
|
||||||
loadables = SavegameCollectionPair(App.savegamePlayers[UILoadGovernor.playerUUID], App.savegameWorlds[UILoadGovernor.worldUUID])
|
|
||||||
|
|
||||||
mode = if (loadables.moreRecentAutosaveAvailable()) {
|
|
||||||
// make choice for load manual or auto, if available
|
|
||||||
|
|
||||||
MODE_SAVE_MULTIPLE_CHOICES
|
|
||||||
}
|
|
||||||
else if (!loadables.saveAvaliable()) {
|
|
||||||
// show save is damaged and cannot be loaded
|
|
||||||
MODE_SAVE_DAMAGED
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
val (p, w) = loadables.getLoadableSave()!!
|
|
||||||
UILoadGovernor.playerDisk = p; UILoadGovernor.worldDisk = w
|
|
||||||
|
|
||||||
if (loadables.newerSaveIsDamaged) {
|
|
||||||
UILoadGovernor.previousSaveWasLoaded = true
|
|
||||||
}
|
|
||||||
|
|
||||||
MODE_LOAD_DA_SHIT_ALREADY
|
|
||||||
|
|
||||||
|
|
||||||
// test codes //
|
|
||||||
|
|
||||||
/*val autoThumb = loadables.getManualSave()!!.getThumbnail()
|
|
||||||
val manualThumb = loadables.getManualSave()!!.getThumbnail()
|
|
||||||
|
|
||||||
loadManualThumbButton = UIItemImageButton(this, manualThumb,
|
|
||||||
initialX = (Toolkit.drawWidth - altSelDrawW)/2 + altSelQdrawW - imageButtonW/2,
|
|
||||||
initialY = altSelDrawY + 120,
|
|
||||||
width = imageButtonW,
|
|
||||||
height = imageButtonH,
|
|
||||||
imageDrawWidth = imageButtonW,
|
|
||||||
imageDrawHeight = imageButtonH,
|
|
||||||
highlightable = false,
|
|
||||||
useBorder = true,
|
|
||||||
).also {
|
|
||||||
it.extraDrawOp = getDrawTextualInfoFun(loadables.getManualSave()!!)
|
|
||||||
it.clickOnceListener = { _,_ ->
|
|
||||||
loadables.getManualSave()!!.let {
|
|
||||||
UILoadGovernor.playerDisk = it.player
|
|
||||||
UILoadGovernor.worldDisk = it.world
|
|
||||||
}
|
|
||||||
mode = MODE_LOAD_DA_SHIT_ALREADY
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loadAutoThumbButton = UIItemImageButton(this, autoThumb,
|
|
||||||
initialX = (Toolkit.drawWidth - altSelDrawW)/2 + altSelQQQdrawW - imageButtonW/2,
|
|
||||||
initialY = altSelDrawY + 120,
|
|
||||||
width = imageButtonW,
|
|
||||||
height = imageButtonH,
|
|
||||||
imageDrawWidth = imageButtonW,
|
|
||||||
imageDrawHeight = imageButtonH,
|
|
||||||
highlightable = false,
|
|
||||||
useBorder = true,
|
|
||||||
).also {
|
|
||||||
it.extraDrawOp = getDrawTextualInfoFun(loadables.getManualSave()!!)
|
|
||||||
it.clickOnceListener = { _,_ ->
|
|
||||||
loadables.getManualSave()!!.let {
|
|
||||||
UILoadGovernor.playerDisk = it.player
|
|
||||||
UILoadGovernor.worldDisk = it.world
|
|
||||||
}
|
|
||||||
mode = MODE_LOAD_DA_SHIT_ALREADY
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MODE_SAVE_MULTIPLE_CHOICES*/
|
|
||||||
}
|
|
||||||
|
|
||||||
printdbg(this, "mode = $mode")
|
|
||||||
}
|
|
||||||
else if (mode == MODE_SAVE_DELETE_CONFIRM) {
|
|
||||||
// confirm deletion of selected player
|
|
||||||
buttonSelectedForDeletion = (button as UIItemPlayerCells).also {
|
|
||||||
deleteCellPosYstart = it.posY.toFloat()
|
|
||||||
it.forceMouseDown = true
|
|
||||||
it.update(0.01f)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun show() {
|
override fun show() {
|
||||||
|
takeAutosaveSelectorDown()
|
||||||
transitionPanel.show()
|
transitionPanel.show()
|
||||||
|
hasNewerAutosave = false
|
||||||
/*try {
|
/*try {
|
||||||
remoCon.handler.lockToggle()
|
remoCon.handler.lockToggle()
|
||||||
showSpinner = true
|
showSpinner = true
|
||||||
@@ -366,13 +265,13 @@ class UILoadSavegame(val remoCon: UIRemoCon) : Advanceable() {
|
|||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
if (mode == MODE_SAVE_DELETE_CONFIRM && deleteCellAnimCounter <= scrollAnimLen) {
|
/*if (mode == MODE_SAVE_DELETE_CONFIRM && deleteCellAnimCounter <= scrollAnimLen) {
|
||||||
// do transitional moving stuff
|
// do transitional moving stuff
|
||||||
buttonSelectedForDeletion?.posY = Movement.fastPullOut(deleteCellAnimCounter / scrollAnimLen, deleteCellPosYstart, (titleTopGradEnd + cellInterval).toFloat()).roundToInt()
|
buttonSelectedForDeletion?.posY = Movement.fastPullOut(deleteCellAnimCounter / scrollAnimLen, deleteCellPosYstart, (titleTopGradEnd + cellInterval).toFloat()).roundToInt()
|
||||||
|
|
||||||
deleteCellAnimCounter += delta
|
deleteCellAnimCounter += delta
|
||||||
if (deleteCellAnimCounter > scrollAnimLen) deleteCellAnimCounter = scrollAnimLen
|
if (deleteCellAnimCounter > scrollAnimLen) deleteCellAnimCounter = scrollAnimLen
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
private var deleteCellAnimCounter = 0f
|
private var deleteCellAnimCounter = 0f
|
||||||
@@ -381,7 +280,7 @@ class UILoadSavegame(val remoCon: UIRemoCon) : Advanceable() {
|
|||||||
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
||||||
transitionPanel.render(batch, camera)
|
transitionPanel.render(batch, camera)
|
||||||
|
|
||||||
if (mode == MODE_LOAD_DA_SHIT_ALREADY) {
|
/*if (mode == MODE_LOAD_DA_SHIT_ALREADY) {
|
||||||
loadFired += 1
|
loadFired += 1
|
||||||
// to hide the "flipped skybox" artefact
|
// to hide the "flipped skybox" artefact
|
||||||
batch.end()
|
batch.end()
|
||||||
@@ -398,167 +297,31 @@ class UILoadSavegame(val remoCon: UIRemoCon) : Advanceable() {
|
|||||||
LoadSavegame(UILoadGovernor.playerDisk!!, UILoadGovernor.worldDisk)
|
LoadSavegame(UILoadGovernor.playerDisk!!, UILoadGovernor.worldDisk)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mode == MODE_SELECT || mode == MODE_SAVE_DELETE) {
|
|
||||||
/*batch.end()
|
|
||||||
|
|
||||||
val cells = getCells()
|
|
||||||
|
|
||||||
lateinit var savePixmap: Pixmap
|
|
||||||
sliderFBO.inAction(camera as OrthographicCamera, batch) {
|
|
||||||
gdxClearAndEnableBlend(0f, 0f, 0f, 0f)
|
|
||||||
|
|
||||||
setCameraPosition(batch, camera, 0f, 0f)
|
|
||||||
batch.color = Color.WHITE
|
|
||||||
batch.inUse {
|
|
||||||
for (index in 0 until cells.size) {
|
|
||||||
val it = cells[index]
|
|
||||||
|
|
||||||
if (App.getConfigBoolean("fx_streamerslayout"))
|
|
||||||
it.posX += uiXdiffChatOverlay
|
|
||||||
|
|
||||||
if (index in listScroll - 2 until listScroll + savesVisible + 2)
|
|
||||||
it.render(batch, camera)
|
|
||||||
|
|
||||||
if (App.getConfigBoolean("fx_streamerslayout"))
|
|
||||||
it.posX -= uiXdiffChatOverlay
|
|
||||||
}
|
|
||||||
}
|
|
||||||
savePixmap = Pixmap.createFromFrameBuffer(0, 0, sliderFBO.width, sliderFBO.height)
|
|
||||||
savePixmap.blending = Pixmap.Blending.None
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// implement "wipe-out" by CPU-rendering (*deep exhale*)
|
|
||||||
//savePixmap.setColor(1f,1f,1f,0f)
|
|
||||||
savePixmap.setColor(0f, 0f, 0f, 0f)
|
|
||||||
savePixmap.fillRectangle(0, savePixmap.height - titleTopGradStart, savePixmap.width, titleTopGradStart)
|
|
||||||
// top grad
|
|
||||||
for (y in titleTopGradStart until titleTopGradEnd) {
|
|
||||||
val alpha = (y - titleTopGradStart).toFloat() / gradAreaHeight
|
|
||||||
for (x in 0 until savePixmap.width) {
|
|
||||||
val col = savePixmap.getPixel(x, savePixmap.height - y)
|
|
||||||
val blendAlpha = (col.and(0xFF) * alpha).roundToInt()
|
|
||||||
savePixmap.drawPixel(x, savePixmap.height - y, col.and(0xFFFFFF00.toInt()) or blendAlpha)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// bottom grad
|
|
||||||
for (y in titleBottomGradStart until titleBottomGradEnd) {
|
|
||||||
val alpha = 1f - ((y - titleBottomGradStart).toFloat() / gradAreaHeight)
|
|
||||||
for (x in 0 until savePixmap.width) {
|
|
||||||
val col = savePixmap.getPixel(x, savePixmap.height - y)
|
|
||||||
val blendAlpha = (col.and(0xFF) * alpha).roundToInt()
|
|
||||||
savePixmap.drawPixel(x, savePixmap.height - y, col.and(0xFFFFFF00.toInt()) or blendAlpha)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
savePixmap.setColor(0f, 0f, 0f, 0f)
|
|
||||||
savePixmap.fillRectangle(0, 0, savePixmap.width, height - titleBottomGradEnd + 1)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
setCameraPosition(batch, camera, 0f, 0f)
|
|
||||||
val saveTex = TextureRegion(Texture(savePixmap)); saveTex.flip(false, true)
|
|
||||||
batch.inUse {
|
|
||||||
batch.draw(saveTex, (width - uiWidth - 10) / 2f, 0f)
|
|
||||||
// Control help
|
|
||||||
App.fontGame.draw(batch, controlHelp, uiX.toFloat(), controlHelperY.toFloat())
|
|
||||||
}
|
|
||||||
|
|
||||||
saveTex.texture.dispose()
|
|
||||||
savePixmap.dispose()
|
|
||||||
|
|
||||||
batch.begin()*/
|
|
||||||
}
|
|
||||||
else if (mode == MODE_SAVE_MULTIPLE_CHOICES) {
|
|
||||||
// "The Autosave is more recent than the manual save"
|
|
||||||
Toolkit.drawTextCentered(batch, App.fontGame, Lang["GAME_MORE_RECENT_AUTOSAVE1"], Toolkit.drawWidth, 0, altSelDrawY)
|
|
||||||
Toolkit.drawTextCentered(batch, App.fontGame, Lang["GAME_MORE_RECENT_AUTOSAVE2"], Toolkit.drawWidth, 0, altSelDrawY + 24)
|
|
||||||
// Manual Save Autosave
|
|
||||||
Toolkit.drawTextCentered(batch, App.fontGame, Lang["MENU_IO_MANUAL_SAVE"], altSelHdrawW, (Toolkit.drawWidth - altSelDrawW)/2, altSelDrawY + 80)
|
|
||||||
Toolkit.drawTextCentered(batch, App.fontGame, Lang["MENU_IO_AUTOSAVE"], altSelHdrawW, Toolkit.drawWidth/2, altSelDrawY + 80)
|
|
||||||
|
|
||||||
|
|
||||||
// draw thumbnail-buttons
|
|
||||||
loadAutoThumbButton.render(batch, camera)
|
|
||||||
loadManualThumbButton.render(batch, camera)
|
|
||||||
}
|
|
||||||
else if (mode == MODE_SAVE_DAMAGED) {
|
|
||||||
Toolkit.drawTextCentered(batch, App.fontGame, Lang["ERROR_SAVE_CORRUPTED"], Toolkit.drawWidth, 0, App.scr.height / 2 - 42)
|
|
||||||
|
|
||||||
corruptedBackButton.render(batch, camera)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (mode == MODE_SELECT || mode == MODE_SAVE_DELETE || mode == MODE_SAVE_DELETE_CONFIRM) {
|
|
||||||
// deleteCharacterButton.render(batch, camera)
|
|
||||||
}
|
|
||||||
if (mode == MODE_SAVE_DELETE_CONFIRM) {
|
if (mode == MODE_SAVE_DELETE_CONFIRM) {
|
||||||
buttonSelectedForDeletion?.render(batch, camera)
|
buttonSelectedForDeletion?.render(batch, camera)
|
||||||
confirmCancelButton.render(batch, camera)
|
confirmCancelButton.render(batch, camera)
|
||||||
confirmDeleteButton.render(batch, camera)
|
confirmDeleteButton.render(batch, camera)
|
||||||
}
|
|
||||||
|
|
||||||
if (mode == MODE_SAVE_DELETE_CONFIRM) {
|
|
||||||
batch.color = Color.WHITE
|
batch.color = Color.WHITE
|
||||||
Toolkit.drawTextCentered(batch, App.fontGame, Lang["MENU_LABEL_SAVE_WILL_BE_DELETED"], Toolkit.drawWidth, 0, titleTopGradEnd + cellInterval - 46)
|
Toolkit.drawTextCentered(batch, App.fontGame, Lang["MENU_LABEL_SAVE_WILL_BE_DELETED"], Toolkit.drawWidth, 0, titleTopGradEnd + cellInterval - 46)
|
||||||
Toolkit.drawTextCentered(batch, App.fontGame, Lang["MENU_LABEL_ARE_YOU_SURE"], Toolkit.drawWidth, 0, titleTopGradEnd + cellInterval + SAVE_CELL_HEIGHT + 36)
|
Toolkit.drawTextCentered(batch, App.fontGame, Lang["MENU_LABEL_ARE_YOU_SURE"], Toolkit.drawWidth, 0, titleTopGradEnd + cellInterval + SAVE_CELL_HEIGHT + 36)
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun keyDown(keycode: Int): Boolean {
|
override fun keyDown(keycode: Int): Boolean {
|
||||||
/*if (this.isVisible && (mode == MODE_SELECT || mode == MODE_SAVE_DELETE)) {
|
|
||||||
val cells = getCells()
|
|
||||||
|
|
||||||
if ((keycode == Input.Keys.UP || keycode == App.getConfigInt("control_key_up")) && scrollTarget > 0) {
|
|
||||||
scrollFrom = listScroll
|
|
||||||
scrollTarget -= 1
|
|
||||||
scrollAnimCounter = 0f
|
|
||||||
}
|
|
||||||
else if ((keycode == Input.Keys.DOWN || keycode == App.getConfigInt("control_key_down")) && scrollTarget < cells.size - savesVisible) {
|
|
||||||
scrollFrom = listScroll
|
|
||||||
scrollTarget += 1
|
|
||||||
scrollAnimCounter = 0f
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
transitionPanel.keyDown(keycode)
|
transitionPanel.keyDown(keycode)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
||||||
printdbg(this, "touchDown mode=$mode")
|
|
||||||
|
|
||||||
if (mode == MODE_SAVE_MULTIPLE_CHOICES) {
|
|
||||||
if (::loadAutoThumbButton.isInitialized) loadAutoThumbButton.touchDown(screenX, screenY, pointer, button)
|
|
||||||
if (::loadManualThumbButton.isInitialized) loadManualThumbButton.touchDown(screenX, screenY, pointer, button)
|
|
||||||
}
|
|
||||||
else if (mode == MODE_SELECT || mode == MODE_SAVE_DELETE) {
|
|
||||||
// getCells().forEach { it.touchDown(screenX, screenY, pointer, button) }
|
|
||||||
// deleteCharacterButton.touchDown(screenX, screenY, pointer, button)
|
|
||||||
}
|
|
||||||
else if (mode == MODE_SAVE_DELETE_CONFIRM) {
|
|
||||||
confirmCancelButton.touchDown(screenX, screenY, pointer, button)
|
|
||||||
confirmDeleteButton.touchDown(screenX, screenY, pointer, button)
|
|
||||||
}
|
|
||||||
else if (mode == MODE_SAVE_DAMAGED) corruptedBackButton.touchDown(screenX, screenY, pointer, button)
|
|
||||||
transitionPanel.touchDown(screenX, screenY, pointer, button)
|
transitionPanel.touchDown(screenX, screenY, pointer, button)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
override fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
||||||
if (mode == MODE_SAVE_MULTIPLE_CHOICES) {
|
|
||||||
if (::loadAutoThumbButton.isInitialized) loadAutoThumbButton.touchUp(screenX, screenY, pointer, button)
|
|
||||||
if (::loadManualThumbButton.isInitialized) loadManualThumbButton.touchUp(screenX, screenY, pointer, button)
|
|
||||||
}
|
|
||||||
else if (mode == MODE_SELECT || mode == MODE_SAVE_DELETE) {
|
|
||||||
// getCells().forEach { it.touchUp(screenX, screenY, pointer, button) }
|
|
||||||
// deleteCharacterButton.touchUp(screenX, screenY, pointer, button)
|
|
||||||
}
|
|
||||||
else if (mode == MODE_SAVE_DELETE_CONFIRM) {
|
|
||||||
confirmCancelButton.touchUp(screenX, screenY, pointer, button)
|
|
||||||
confirmDeleteButton.touchUp(screenX, screenY, pointer, button)
|
|
||||||
}
|
|
||||||
else if (mode == MODE_SAVE_DAMAGED) corruptedBackButton.touchUp(screenX, screenY, pointer, button)
|
|
||||||
transitionPanel.touchUp(screenX, screenY, pointer, button)
|
transitionPanel.touchUp(screenX, screenY, pointer, button)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -592,9 +355,7 @@ class UILoadSavegame(val remoCon: UIRemoCon) : Advanceable() {
|
|||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
try { shapeRenderer.dispose() } catch (e: IllegalArgumentException) {}
|
try { shapeRenderer.dispose() } catch (e: IllegalArgumentException) {}
|
||||||
try { sliderFBO.dispose() } catch (e: IllegalArgumentException) {}
|
try { sliderFBO.dispose() } catch (e: IllegalArgumentException) {}
|
||||||
disposablePool.forEach {
|
try { transitionPanel.dispose() } catch (e: IllegalArgumentException) {}
|
||||||
try { it.dispose() } catch (e: GdxRuntimeException) {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun resize(width: Int, height: Int) {
|
override fun resize(width: Int, height: Int) {
|
||||||
|
|||||||
@@ -78,10 +78,10 @@ class UINewCharacter(val remoCon: UIRemoCon) : UICanvas() {
|
|||||||
|
|
||||||
|
|
||||||
// comment below if chargen must send gamers back to the charcters list
|
// comment below if chargen must send gamers back to the charcters list
|
||||||
UILoadGovernor.playerDisk = DiskSkimmer(outFile)
|
// UILoadGovernor.playerDisk = DiskSkimmer(outFile)
|
||||||
// comment above if chargen must send gamers back to the charcters list
|
// comment above if chargen must send gamers back to the charcters list
|
||||||
|
|
||||||
printdbg(this, "playerdisk: ${UILoadGovernor.playerDisk?.diskFile?.path}")
|
// printdbg(this, "playerdisk: ${UILoadGovernor.playerDisk?.diskFile?.path}")
|
||||||
|
|
||||||
}, "TerrarumBasegameNewCharcterSaveThread")
|
}, "TerrarumBasegameNewCharcterSaveThread")
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,8 @@ class UINewWorld(val remoCon: UIRemoCon) : UICanvas() {
|
|||||||
printdbg(this, "generate! Size=${sizeSelector.selection}, Name=${nameInput.getTextOrPlaceholder()}, Seed=${seedInput.getTextOrPlaceholder()}")
|
printdbg(this, "generate! Size=${sizeSelector.selection}, Name=${nameInput.getTextOrPlaceholder()}, Seed=${seedInput.getTextOrPlaceholder()}")
|
||||||
|
|
||||||
val ingame = TerrarumIngame(App.batch)
|
val ingame = TerrarumIngame(App.batch)
|
||||||
val player = ReadActor.invoke(UILoadGovernor.playerDisk!!, ByteArray64Reader(UILoadGovernor.playerDisk!!.getFile(SAVEGAMEINFO)!!.bytes, Common.CHARSET)) as IngamePlayer
|
val playerDisk = App.savegamePlayers[UILoadGovernor.playerUUID]!!.loadable()
|
||||||
|
val player = ReadActor.invoke(playerDisk, ByteArray64Reader(playerDisk.getFile(SAVEGAMEINFO)!!.bytes, Common.CHARSET)) as IngamePlayer
|
||||||
val seed = try {
|
val seed = try {
|
||||||
seedInput.getTextOrPlaceholder().toLong()
|
seedInput.getTextOrPlaceholder().toLong()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package net.torvald.terrarum.savegame
|
package net.torvald.terrarum.savegame
|
||||||
|
|
||||||
|
import net.torvald.terrarum.App.printdbg
|
||||||
import net.torvald.terrarum.serialise.toUint
|
import net.torvald.terrarum.serialise.toUint
|
||||||
import net.torvald.terrarum.serialise.toUlong
|
import net.torvald.terrarum.serialise.toUlong
|
||||||
import java.io.*
|
import java.io.*
|
||||||
@@ -72,7 +73,6 @@ removefile:
|
|||||||
*/
|
*/
|
||||||
private var entryToOffsetTable = HashMap<EntryID, Long>()
|
private var entryToOffsetTable = HashMap<EntryID, Long>()
|
||||||
|
|
||||||
val fa: RandomAccessFile = RandomAccessFile(diskFile, "rw")
|
|
||||||
|
|
||||||
private fun debugPrintln(s: Any) {
|
private fun debugPrintln(s: Any) {
|
||||||
if (false) println(s.toString())
|
if (false) println(s.toString())
|
||||||
@@ -87,84 +87,125 @@ removefile:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun FileInputStream.readBytes(buffer: ByteArray): Int {
|
||||||
|
val readStatus = this.read(buffer)
|
||||||
|
return readStatus
|
||||||
|
}
|
||||||
|
private fun FileInputStream.readInt16(): Int {
|
||||||
|
val buffer = ByteArray(2)
|
||||||
|
val readStatus = readBytes(buffer)
|
||||||
|
if (readStatus != 2) throw InternalError("Unexpected error -- EOF reached? (expected 2, got $readStatus)")
|
||||||
|
return buffer.toInt16()
|
||||||
|
}
|
||||||
|
private fun FileInputStream.readInt32(): Int {
|
||||||
|
val buffer = ByteArray(4)
|
||||||
|
val readStatus = readBytes(buffer)
|
||||||
|
if (readStatus != 4) throw InternalError("Unexpected error -- EOF reached? (expected 4, got $readStatus)")
|
||||||
|
return buffer.toInt32()
|
||||||
|
}
|
||||||
|
private fun FileInputStream.readInt48(): Long {
|
||||||
|
val buffer = ByteArray(6)
|
||||||
|
val readStatus = readBytes(buffer)
|
||||||
|
if (readStatus != 6) throw InternalError("Unexpected error -- EOF reached? (expected 6, got $readStatus)")
|
||||||
|
return buffer.toInt48()
|
||||||
|
}
|
||||||
|
private fun FileInputStream.readInt24(): Int {
|
||||||
|
val buffer = ByteArray(3)
|
||||||
|
val readStatus = readBytes(buffer)
|
||||||
|
if (readStatus != 3) throw InternalError("Unexpected error -- EOF reached? (expected 3, got $readStatus)")
|
||||||
|
return buffer.toInt24()
|
||||||
|
}
|
||||||
|
private fun FileInputStream.readInt64(): Long {
|
||||||
|
val buffer = ByteArray(8)
|
||||||
|
val readStatus = readBytes(buffer)
|
||||||
|
if (readStatus != 8) throw InternalError("Unexpected error -- EOF reached? (expected 8, got $readStatus)")
|
||||||
|
return buffer.toInt64()
|
||||||
|
}
|
||||||
|
private fun ByteArray.toInt16(offset: Int = 0): Int {
|
||||||
|
return this[0 + offset].toUint().shl(8) or
|
||||||
|
this[1 + offset].toUint()
|
||||||
|
}
|
||||||
|
private fun ByteArray.toInt24(offset: Int = 0): Int {
|
||||||
|
return this[0 + offset].toUint().shl(16) or
|
||||||
|
this[1 + offset].toUint().shl(8) or
|
||||||
|
this[2 + offset].toUint()
|
||||||
|
}
|
||||||
|
private fun ByteArray.toInt32(offset: Int = 0): Int {
|
||||||
|
return this[0 + offset].toUint().shl(24) or
|
||||||
|
this[1 + offset].toUint().shl(16) or
|
||||||
|
this[2 + offset].toUint().shl(8) or
|
||||||
|
this[3 + offset].toUint()
|
||||||
|
}
|
||||||
|
private fun ByteArray.toInt48(offset: Int = 0): Long {
|
||||||
|
return this[0 + offset].toUlong().shl(40) or
|
||||||
|
this[1 + offset].toUlong().shl(32) or
|
||||||
|
this[2 + offset].toUlong().shl(24) or
|
||||||
|
this[3 + offset].toUlong().shl(16) or
|
||||||
|
this[4 + offset].toUlong().shl(8) or
|
||||||
|
this[5 + offset].toUlong()
|
||||||
|
}
|
||||||
|
private fun ByteArray.toInt64(offset: Int = 0): Long {
|
||||||
|
return this[0 + offset].toUlong().shl(56) or
|
||||||
|
this[1 + offset].toUlong().shl(48) or
|
||||||
|
this[2 + offset].toUlong().shl(40) or
|
||||||
|
this[3 + offset].toUlong().shl(32) or
|
||||||
|
this[4 + offset].toUlong().shl(24) or
|
||||||
|
this[5 + offset].toUlong().shl(16) or
|
||||||
|
this[6 + offset].toUlong().shl(8) or
|
||||||
|
this[7 + offset].toUlong()
|
||||||
|
}
|
||||||
|
|
||||||
fun rebuild() {
|
fun rebuild() {
|
||||||
checkFileSanity() // state of the file may have been changed (e.g. file deleted) so we check again
|
checkFileSanity() // state of the file may have been changed (e.g. file deleted) so we check again
|
||||||
|
|
||||||
|
entryToOffsetTable.clear()
|
||||||
|
|
||||||
// fa = RandomAccessFile(diskFile, "rw")
|
// fa = RandomAccessFile(diskFile, "rw")
|
||||||
|
|
||||||
val fis = FileInputStream(diskFile)
|
val fis = FileInputStream(diskFile)
|
||||||
var currentPosition = fis.skip(VirtualDisk.HEADER_SIZE) // skip disk header
|
var currentPosition = VirtualDisk.HEADER_SIZE
|
||||||
|
fis.skipNBytes(VirtualDisk.HEADER_SIZE) // skip disk header
|
||||||
|
|
||||||
// println("[DiskSkimmer] loading the diskfile ${diskFile.canonicalPath}")
|
println("[DiskSkimmer] rebuild ${diskFile.canonicalPath}")
|
||||||
|
|
||||||
fun skipRead(bytes: Long) {
|
|
||||||
currentPosition += fis.skip(bytes)
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Reads a byte and adds up the position var
|
|
||||||
*/
|
|
||||||
fun readByte(): Byte {
|
|
||||||
currentPosition++
|
|
||||||
val read = fis.read()
|
|
||||||
|
|
||||||
if (read < 0) throw InternalError("Unexpectedly reached EOF")
|
|
||||||
return read.toByte()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads specific bytes to the buffer and adds up the position var
|
|
||||||
*/
|
|
||||||
fun readBytes(buffer: ByteArray): Int {
|
|
||||||
val readStatus = fis.read(buffer)
|
|
||||||
currentPosition += readStatus
|
|
||||||
return readStatus
|
|
||||||
}
|
|
||||||
fun readUshortBig(): Int {
|
|
||||||
val buffer = ByteArray(2)
|
|
||||||
val readStatus = readBytes(buffer)
|
|
||||||
if (readStatus != 2) throw InternalError("Unexpected error -- EOF reached? (expected 2, got $readStatus)")
|
|
||||||
return buffer.toShortBig()
|
|
||||||
}
|
|
||||||
fun readIntBig(): Int {
|
|
||||||
val buffer = ByteArray(4)
|
|
||||||
val readStatus = readBytes(buffer)
|
|
||||||
if (readStatus != 4) throw InternalError("Unexpected error -- EOF reached? (expected 4, got $readStatus)")
|
|
||||||
return buffer.toIntBig()
|
|
||||||
}
|
|
||||||
fun readInt48(): Long {
|
|
||||||
val buffer = ByteArray(6)
|
|
||||||
val readStatus = readBytes(buffer)
|
|
||||||
if (readStatus != 6) throw InternalError("Unexpected error -- EOF reached? (expected 6, got $readStatus)")
|
|
||||||
return buffer.toInt48()
|
|
||||||
}
|
|
||||||
fun readLongBig(): Long {
|
|
||||||
val buffer = ByteArray(8)
|
|
||||||
val readStatus = readBytes(buffer)
|
|
||||||
if (readStatus != 8) throw InternalError("Unexpected error -- EOF reached? (expected 8, got $readStatus)")
|
|
||||||
return buffer.toLongBig()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
val currentLength = diskFile.length()
|
val currentLength = diskFile.length()
|
||||||
|
var ccc = 0
|
||||||
while (currentPosition < currentLength) {
|
while (currentPosition < currentLength) {
|
||||||
|
|
||||||
val entryID = readLongBig() // at this point, cursor is 8 bytes past to the entry head
|
val entryID = fis.readInt64() // at this point, cursor is 8 bytes past to the entry head
|
||||||
|
currentPosition += 8
|
||||||
|
|
||||||
// fill up the offset table
|
// fill up the offset table/
|
||||||
val offset = currentPosition
|
val offset = currentPosition
|
||||||
|
|
||||||
skipRead(8) // parent ID
|
// printdbg(this, "Offset $offset, entryID $entryID")
|
||||||
val typeFlag = readByte()
|
|
||||||
skipRead(3)
|
fis.readInt64() // parentID
|
||||||
skipRead(16) // skip rest of the header
|
val typeFlag = fis.read().toByte()
|
||||||
|
fis.readInt24()
|
||||||
|
fis.read(16)
|
||||||
|
|
||||||
|
currentPosition += 8+4+16
|
||||||
|
|
||||||
|
// printdbg(this, " $currentPosition")
|
||||||
|
|
||||||
val entrySize = when (typeFlag and 127) {
|
val entrySize = when (typeFlag and 127) {
|
||||||
DiskEntry.NORMAL_FILE -> readInt48()
|
DiskEntry.NORMAL_FILE -> {
|
||||||
DiskEntry.DIRECTORY -> readIntBig().toLong() * 8L
|
currentPosition += 6
|
||||||
|
fis.readInt48()
|
||||||
|
}
|
||||||
|
DiskEntry.DIRECTORY -> {
|
||||||
|
currentPosition += 4
|
||||||
|
fis.readInt32().toLong() * 8L
|
||||||
|
}
|
||||||
else -> 0
|
else -> 0
|
||||||
}
|
}
|
||||||
|
|
||||||
skipRead(entrySize) // skips rest of the entry's actual contents
|
// printdbg(this, " type $typeFlag entrySize = $entrySize")
|
||||||
|
|
||||||
|
currentPosition += entrySize // skips rest of the entry's actual contents
|
||||||
|
fis.skipNBytes(entrySize)
|
||||||
|
|
||||||
if (typeFlag > 0) {
|
if (typeFlag > 0) {
|
||||||
if (entryToOffsetTable[entryID] != null)
|
if (entryToOffsetTable[entryID] != null)
|
||||||
@@ -177,6 +218,12 @@ removefile:
|
|||||||
else {
|
else {
|
||||||
debugPrintln("[DiskSkimmer] ... discarding entry $entryID at offset:$offset (name: ${diskIDtoReadableFilename(entryID, getSaveKind())})")
|
debugPrintln("[DiskSkimmer] ... discarding entry $entryID at offset:$offset (name: ${diskIDtoReadableFilename(entryID, getSaveKind())})")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// printdbg(this, " currentPosition = $currentPosition / $currentLength")
|
||||||
|
|
||||||
|
ccc++
|
||||||
|
// if (ccc == 13) System.exit(1)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fis.close()
|
fis.close()
|
||||||
@@ -199,38 +246,42 @@ removefile:
|
|||||||
|
|
||||||
if (!initialised) throw IllegalStateException("File entries not built! Initialise the Skimmer by executing rebuild()")
|
if (!initialised) throw IllegalStateException("File entries not built! Initialise the Skimmer by executing rebuild()")
|
||||||
|
|
||||||
|
// rebuild()
|
||||||
|
|
||||||
entryToOffsetTable[entryID].let { offset ->
|
entryToOffsetTable[entryID].let { offset ->
|
||||||
if (offset == null) {
|
if (offset == null) {
|
||||||
debugPrintln("[DiskSkimmer.requestFile] entry $entryID does not exist on the table")
|
debugPrintln("[DiskSkimmer.requestFile] entry $entryID does not exist on the table")
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fa.seek(offset)
|
val fis = FileInputStream(diskFile)
|
||||||
val parent = fa.read(8).toLongBig()
|
fis.skipNBytes(offset)
|
||||||
val fileFlag = fa.read(4)[0]
|
val parent = fis.readInt64()
|
||||||
val creationTime = fa.read(6).toInt48()
|
val fileFlag = fis.read().toByte()
|
||||||
val modifyTime = fa.read(6).toInt48()
|
fis.readInt24()
|
||||||
val skip_crc = fa.read(4)
|
val creationTime = fis.readInt48()
|
||||||
|
val modifyTime = fis.readInt48()
|
||||||
|
fis.readInt32()
|
||||||
|
|
||||||
|
|
||||||
// get entry size // TODO future me, is this kind of comment helpful or redundant?
|
// get entry size // TODO future me, is this kind of comment helpful or redundant?
|
||||||
val entrySize = when (fileFlag) {
|
val entrySize = when (fileFlag) {
|
||||||
DiskEntry.NORMAL_FILE -> {
|
DiskEntry.NORMAL_FILE -> {
|
||||||
fa.read(6).toInt48()
|
fis.readInt48()
|
||||||
}
|
}
|
||||||
DiskEntry.DIRECTORY -> {
|
DiskEntry.DIRECTORY -> {
|
||||||
fa.read(4).toIntBig().toLong()
|
fis.readInt32().toLong() and 0xFFFFFFFFL
|
||||||
}
|
}
|
||||||
DiskEntry.SYMLINK -> 8L
|
DiskEntry.SYMLINK -> 8L
|
||||||
else -> throw UnsupportedOperationException("Unsupported entry type: $fileFlag for entryID $entryID at offset $offset") // FIXME no support for compressed file
|
else -> throw UnsupportedOperationException("Unsupported entry type: $fileFlag for entryID $entryID at offset ${offset+8}") // FIXME no support for compressed file
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val entryContent = when (fileFlag) {
|
val entryContent = when (fileFlag) {
|
||||||
DiskEntry.NORMAL_FILE -> {
|
DiskEntry.NORMAL_FILE -> {
|
||||||
val byteArray = ByteArray64(entrySize)
|
val byteArray = ByteArray64(entrySize)
|
||||||
// read one byte at a time
|
// read one byte at a time
|
||||||
for (c in 0L until entrySize) {
|
for (c in 0L until entrySize) {
|
||||||
byteArray[c] = fa.read().toByte()
|
byteArray[c] = fis.read().toByte()
|
||||||
}
|
}
|
||||||
|
|
||||||
EntryFile(byteArray)
|
EntryFile(byteArray)
|
||||||
@@ -240,20 +291,21 @@ removefile:
|
|||||||
// read 8 bytes at a time
|
// read 8 bytes at a time
|
||||||
val bytesBuffer8 = ByteArray(8)
|
val bytesBuffer8 = ByteArray(8)
|
||||||
for (c in 0L until entrySize) {
|
for (c in 0L until entrySize) {
|
||||||
fa.read(bytesBuffer8)
|
fis.read(bytesBuffer8)
|
||||||
dirContents.add(bytesBuffer8.toLongBig())
|
dirContents.add(bytesBuffer8.toLongBig())
|
||||||
}
|
}
|
||||||
|
|
||||||
EntryDirectory(dirContents)
|
EntryDirectory(dirContents)
|
||||||
}
|
}
|
||||||
DiskEntry.SYMLINK -> {
|
DiskEntry.SYMLINK -> {
|
||||||
val target = fa.read(8).toLongBig()
|
val target = fis.readInt64()
|
||||||
|
|
||||||
EntrySymlink(target)
|
EntrySymlink(target)
|
||||||
}
|
}
|
||||||
else -> throw UnsupportedOperationException("Unsupported entry type: $fileFlag for entryID $entryID at offset $offset") // FIXME no support for compressed file
|
else -> throw UnsupportedOperationException("Unsupported entry type: $fileFlag for entryID $entryID at offset ${offset+8}") // FIXME no support for compressed file
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fis.close()
|
||||||
return DiskEntry(entryID, parent, creationTime, modifyTime, entryContent)
|
return DiskEntry(entryID, parent, creationTime, modifyTime, entryContent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -313,6 +365,7 @@ removefile:
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
fun invalidateEntry(id: EntryID) {
|
fun invalidateEntry(id: EntryID) {
|
||||||
|
val fa = RandomAccessFile(diskFile, "rwd")
|
||||||
entryToOffsetTable[id]?.let {
|
entryToOffsetTable[id]?.let {
|
||||||
fa.seek(it + 8)
|
fa.seek(it + 8)
|
||||||
val type = fa.read()
|
val type = fa.read()
|
||||||
@@ -320,12 +373,15 @@ removefile:
|
|||||||
fa.write(type or 128)
|
fa.write(type or 128)
|
||||||
entryToOffsetTable.remove(id)
|
entryToOffsetTable.remove(id)
|
||||||
}
|
}
|
||||||
|
fa.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun injectDiskCRC(crc: Int) {
|
fun injectDiskCRC(crc: Int) {
|
||||||
|
val fa = RandomAccessFile(diskFile, "rwd")
|
||||||
fa.seek(42L)
|
fa.seek(42L)
|
||||||
fa.write(crc.toBigEndian())
|
fa.write(crc.toBigEndian())
|
||||||
|
fa.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
//private val modifiedDirectories = TreeSet<DiskEntry>()
|
//private val modifiedDirectories = TreeSet<DiskEntry>()
|
||||||
@@ -344,33 +400,41 @@ removefile:
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
fun setSaveMode(bits: Int) {
|
fun setSaveMode(bits: Int) {
|
||||||
|
val fa = RandomAccessFile(diskFile, "rwd")
|
||||||
fa.seek(49L)
|
fa.seek(49L)
|
||||||
fa.writeByte(bits)
|
fa.writeByte(bits)
|
||||||
|
fa.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setSaveKind(bits: Int) {
|
fun setSaveKind(bits: Int) {
|
||||||
|
val fa = RandomAccessFile(diskFile, "rwd")
|
||||||
fa.seek(50L)
|
fa.seek(50L)
|
||||||
fa.writeByte(bits)
|
fa.writeByte(bits)
|
||||||
|
fa.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getSaveMode(): Int {
|
fun getSaveMode(): Int {
|
||||||
|
val fa = RandomAccessFile(diskFile, "rwd")
|
||||||
fa.seek(49L)
|
fa.seek(49L)
|
||||||
return fa.read()
|
return fa.read().also { fa.close() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getSaveKind(): Int {
|
fun getSaveKind(): Int {
|
||||||
|
val fa = RandomAccessFile(diskFile, "rwd")
|
||||||
fa.seek(50L)
|
fa.seek(50L)
|
||||||
return fa.read()
|
return fa.read().also { fa.close() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
override fun getDiskName(charset: Charset): String {
|
override fun getDiskName(charset: Charset): String {
|
||||||
|
val fa = RandomAccessFile(diskFile, "rwd")
|
||||||
val bytes = ByteArray(268)
|
val bytes = ByteArray(268)
|
||||||
fa.seek(10L)
|
fa.seek(10)
|
||||||
fa.read(bytes, 0, 32)
|
fa.read(bytes, 0, 32)
|
||||||
fa.seek(60L)
|
fa.seek(60L)
|
||||||
fa.read(bytes, 32, 236)
|
fa.read(bytes, 32, 236)
|
||||||
|
fa.close()
|
||||||
return bytes.toCanonicalString(charset)
|
return bytes.toCanonicalString(charset)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,9 +442,11 @@ removefile:
|
|||||||
* @return creation time of the root directory
|
* @return creation time of the root directory
|
||||||
*/
|
*/
|
||||||
fun getCreationTime(): Long {
|
fun getCreationTime(): Long {
|
||||||
|
val fa = RandomAccessFile(diskFile, "rwd")
|
||||||
val bytes = ByteArray(6)
|
val bytes = ByteArray(6)
|
||||||
fa.seek(320L)
|
fa.seek(320L)
|
||||||
fa.read(bytes)
|
fa.read(bytes)
|
||||||
|
fa.close()
|
||||||
return bytes.toInt48()
|
return bytes.toInt48()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -388,9 +454,11 @@ removefile:
|
|||||||
* @return last modified time of the root directory
|
* @return last modified time of the root directory
|
||||||
*/
|
*/
|
||||||
fun getLastModifiedTime(): Long {
|
fun getLastModifiedTime(): Long {
|
||||||
|
val fa = RandomAccessFile(diskFile, "rwd")
|
||||||
val bytes = ByteArray(6)
|
val bytes = ByteArray(6)
|
||||||
fa.seek(326L)
|
fa.seek(326L)
|
||||||
fa.read(bytes)
|
fa.read(bytes)
|
||||||
|
fa.close()
|
||||||
return bytes.toInt48()
|
return bytes.toInt48()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,18 +466,22 @@ removefile:
|
|||||||
* redefines creation time of the root directory
|
* redefines creation time of the root directory
|
||||||
*/
|
*/
|
||||||
fun setCreationTime(time_t: Long) {
|
fun setCreationTime(time_t: Long) {
|
||||||
|
val fa = RandomAccessFile(diskFile, "rwd")
|
||||||
val bytes = ByteArray(6)
|
val bytes = ByteArray(6)
|
||||||
fa.seek(320L)
|
fa.seek(320L)
|
||||||
fa.write(time_t.toInt48())
|
fa.write(time_t.toInt48())
|
||||||
|
fa.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* redefines last modified time of the root directory
|
* redefines last modified time of the root directory
|
||||||
*/
|
*/
|
||||||
fun setLastModifiedTime(time_t: Long) {
|
fun setLastModifiedTime(time_t: Long) {
|
||||||
|
val fa = RandomAccessFile(diskFile, "rwd")
|
||||||
val bytes = ByteArray(6)
|
val bytes = ByteArray(6)
|
||||||
fa.seek(326L)
|
fa.seek(326L)
|
||||||
fa.write(time_t.toInt48())
|
fa.write(time_t.toInt48())
|
||||||
|
fa.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
@@ -436,6 +508,9 @@ removefile:
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
fun appendEntry(entry: DiskEntry) {
|
fun appendEntry(entry: DiskEntry) {
|
||||||
|
val fa = RandomAccessFile(diskFile, "rwd")
|
||||||
|
|
||||||
|
|
||||||
// val parentDir = requestFile(entry.parentEntryID)!!
|
// val parentDir = requestFile(entry.parentEntryID)!!
|
||||||
val id = entry.entryID
|
val id = entry.entryID
|
||||||
// val parent = entry.parentEntryID
|
// val parent = entry.parentEntryID
|
||||||
@@ -456,9 +531,14 @@ removefile:
|
|||||||
// append modified directory
|
// append modified directory
|
||||||
// entryToOffsetTable[parent] = fa.filePointer + 8
|
// entryToOffsetTable[parent] = fa.filePointer + 8
|
||||||
// parentDir.serialize().forEach { fa.writeByte(it.toInt()) }
|
// parentDir.serialize().forEach { fa.writeByte(it.toInt()) }
|
||||||
|
|
||||||
|
fa.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deleteEntry(id: EntryID) {
|
fun deleteEntry(id: EntryID) {
|
||||||
|
val fa = RandomAccessFile(diskFile, "rwd")
|
||||||
|
|
||||||
|
|
||||||
val entry = requestFile(id)!!
|
val entry = requestFile(id)!!
|
||||||
// val parentDir = requestFile(entry.parentEntryID)!!
|
// val parentDir = requestFile(entry.parentEntryID)!!
|
||||||
// val parent = entry.parentEntryID
|
// val parent = entry.parentEntryID
|
||||||
@@ -476,6 +556,8 @@ removefile:
|
|||||||
// append modified directory
|
// append modified directory
|
||||||
// entryToOffsetTable[id] = appendAt + 8
|
// entryToOffsetTable[id] = appendAt + 8
|
||||||
// parentDir.serialize().forEach { fa.writeByte(it.toInt()) }
|
// parentDir.serialize().forEach { fa.writeByte(it.toInt()) }
|
||||||
|
|
||||||
|
fa.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun appendEntries(entries: List<DiskEntry>) = entries.forEach { appendEntry(it) }
|
fun appendEntries(entries: List<DiskEntry>) = entries.forEach { appendEntry(it) }
|
||||||
@@ -523,9 +605,9 @@ removefile:
|
|||||||
debugPrintln("[DiskSkimmer.getEntryBlockSize] offset for entry $id = $offset")
|
debugPrintln("[DiskSkimmer.getEntryBlockSize] offset for entry $id = $offset")
|
||||||
|
|
||||||
val fis = FileInputStream(diskFile)
|
val fis = FileInputStream(diskFile)
|
||||||
fis.skip(offset + 8)
|
fis.skipNBytes(offset + 8)
|
||||||
val type = fis.read().toByte()
|
val type = fis.read().toByte()
|
||||||
fis.skip(272) // skip name, timestamp and CRC
|
fis.skipNBytes(272) // skip name, timestamp and CRC
|
||||||
|
|
||||||
|
|
||||||
val ret: Long
|
val ret: Long
|
||||||
@@ -582,4 +664,14 @@ removefile:
|
|||||||
this[6].toUlong().shl(8) or
|
this[6].toUlong().shl(8) or
|
||||||
this[7].toUlong()
|
this[7].toUlong()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setDiskName(name: String, charset: Charset) {
|
||||||
|
val fa = RandomAccessFile(diskFile, "rwd")
|
||||||
|
val bytes = name.toEntryName(268, charset)
|
||||||
|
fa.seek(10L)
|
||||||
|
fa.write(bytes, 0, 32)
|
||||||
|
fa.seek(60L)
|
||||||
|
fa.write(bytes, 32, 236)
|
||||||
|
fa.close()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -254,6 +254,7 @@ object VDSaveKind {
|
|||||||
object VDFileID {
|
object VDFileID {
|
||||||
const val ROOT = 0L
|
const val ROOT = 0L
|
||||||
const val SAVEGAMEINFO = -1L
|
const val SAVEGAMEINFO = -1L
|
||||||
|
const val PLAYER_JSON = -1L
|
||||||
const val THUMBNAIL = -2L
|
const val THUMBNAIL = -2L
|
||||||
const val SPRITEDEF = -2L
|
const val SPRITEDEF = -2L
|
||||||
const val SPRITEDEF_GLOW = -3L
|
const val SPRITEDEF_GLOW = -3L
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package net.torvald.terrarum.ui
|
package net.torvald.terrarum.ui
|
||||||
|
|
||||||
import com.jme3.math.FastMath
|
import net.torvald.terrarum.App.printdbg
|
||||||
import net.torvald.terrarum.INGAME
|
import net.torvald.terrarum.INGAME
|
||||||
import net.torvald.terrarum.modulebasegame.ui.NullUI
|
import net.torvald.terrarum.modulebasegame.ui.NullUI
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
@@ -36,13 +36,13 @@ class UIItemHorizontalFadeSlide(
|
|||||||
|
|
||||||
override val uis: List<UICanvas>; get() = listOf(leftUI, centreUI, rightUI)
|
override val uis: List<UICanvas>; get() = listOf(leftUI, centreUI, rightUI)
|
||||||
|
|
||||||
fun setLeftUI(index: Int) {
|
fun setLeftUIto(index: Int) {
|
||||||
leftUI = uisOnLeft[index]
|
leftUI = uisOnLeft[index]
|
||||||
}
|
}
|
||||||
fun setCentreUI(index: Int) {
|
fun setCentreUIto(index: Int) {
|
||||||
centreUI = uisOnCentre[index]
|
centreUI = uisOnCentre[index]
|
||||||
}
|
}
|
||||||
fun setRightUI(index: Int) {
|
fun setRightUIto(index: Int) {
|
||||||
rightUI = uisOnRight[index]
|
rightUI = uisOnRight[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,4 +79,31 @@ class UIItemHorizontalFadeSlide(
|
|||||||
}
|
}
|
||||||
INGAME.setTooltipMessage(null)
|
INGAME.setTooltipMessage(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun dispose() {
|
||||||
|
uisOnLeft.forEach { try { it.dispose() } catch (e: IllegalArgumentException) {} }
|
||||||
|
uisOnCentre.forEach { try { it.dispose() } catch (e: IllegalArgumentException) {} }
|
||||||
|
uisOnRight.forEach { try { it.dispose() } catch (e: IllegalArgumentException) {} }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun keyDown(keycode: Int): Boolean {
|
||||||
|
return super.keyDown(keycode)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun keyUp(keycode: Int): Boolean {
|
||||||
|
return super.keyUp(keycode)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
||||||
|
printdbg(this, "touchDown UIs: ${uis.joinToString { it.javaClass.simpleName }}")
|
||||||
|
return super.touchDown(screenX, screenY, pointer, button)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
||||||
|
return super.touchUp(screenX, screenY, pointer, button)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun scrolled(amountX: Float, amountY: Float): Boolean {
|
||||||
|
return super.scrolled(amountX, amountY)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user