mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
player load ui
This commit is contained in:
@@ -16,6 +16,7 @@ The main game directory is composed of following directories:
|
||||
}
|
||||
*if file -1025 is not there, read bodyparts from assets directory
|
||||
*optionally encrypt the files other than -1
|
||||
*disk name is player's name encoded in UTF-8
|
||||
+ Shared
|
||||
- <e.g. Disk GUID>, TEVD { * }
|
||||
- <this directory can have anything>
|
||||
@@ -26,6 +27,7 @@ The main game directory is composed of following directories:
|
||||
[0x1_0000_0000L or (layerNumber shl 24) or chunkNumber] chunk data,
|
||||
[-2] screenshot.tga.gz taken by the last player
|
||||
}
|
||||
*disk name is world's name encoded in UTF-8
|
||||
```
|
||||
|
||||
(TEVD stands for Terrarum Virtual Disk spec version 3, TVDA stands for spec version 254; both have MAGIC header of `TEVd`)
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package net.torvald.spriteanimation
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.graphics.Texture
|
||||
import net.torvald.spriteassembler.ADProperties
|
||||
import net.torvald.spriteassembler.AssembleSheetPixmap
|
||||
import net.torvald.terrarum.tvda.DiskSkimmer
|
||||
import net.torvald.terrarum.tvda.SimpleFileSystem
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
|
||||
@@ -71,7 +69,7 @@ interface HasAssembledSprite {
|
||||
private fun _rebuild(disk: SimpleFileSystem, ad: ADProperties, sprite: SpriteAnimation) {
|
||||
// TODO injecting held item/armour pictures? Would it be AssembleSheetPixmap's job?
|
||||
|
||||
val pixmap = AssembleSheetPixmap.fromVirtualDisk(disk, ad)
|
||||
val pixmap = if (disk.getEntry(-1025) != null) AssembleSheetPixmap.fromVirtualDisk(disk, ad) else AssembleSheetPixmap.fromAssetsDir(ad)
|
||||
val texture = Texture(pixmap)
|
||||
texture.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
|
||||
pixmap.dispose()
|
||||
|
||||
@@ -5,6 +5,7 @@ import net.torvald.terrarum.linearSearchBy
|
||||
import net.torvald.terrarum.serialise.Common
|
||||
import java.io.InputStream
|
||||
import java.io.Reader
|
||||
import java.io.StringReader
|
||||
import java.util.*
|
||||
|
||||
internal data class Joint(val name: String, val position: ADPropertyObject.Vector2i) {
|
||||
@@ -79,30 +80,29 @@ class ADProperties {
|
||||
constructor(gdxFile: FileHandle) {
|
||||
fileFrom = gdxFile.path()
|
||||
adlString = gdxFile.readString(Common.CHARSET.name())
|
||||
javaProp.load(gdxFile.read())
|
||||
continueLoad()
|
||||
}
|
||||
|
||||
constructor(reader: Reader) {
|
||||
adlString = reader.readText()
|
||||
javaProp.load(reader)
|
||||
continueLoad()
|
||||
}
|
||||
|
||||
constructor(inputStream: InputStream) {
|
||||
adlString = inputStream.readAllBytes().toString(Common.CHARSET)
|
||||
javaProp.load(inputStream)
|
||||
continueLoad()
|
||||
}
|
||||
|
||||
private fun continueLoad() {
|
||||
javaProp.load(StringReader(adlString))
|
||||
|
||||
// sanity check
|
||||
reservedProps.forEach {
|
||||
try {
|
||||
javaProp[it]!!
|
||||
}
|
||||
catch (e: NullPointerException) {
|
||||
throw IllegalArgumentException("Prop '$it' not found from ${fileFrom.ifBlank { "(path unavailable)" }}", e)
|
||||
throw IllegalArgumentException("Prop '$it' not found from ${fileFrom.ifBlank { "'${adlString.substring(0, 1024)}'" }}", e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ class ADProperties {
|
||||
if (it.name.isBlank())
|
||||
throw IllegalArgumentException("Empty Bodypart name on BODYPARTS; try removing trailing semicolon (';')?")
|
||||
else
|
||||
throw IllegalArgumentException("Bodyparts definition for '${it.name}' not found from ${fileFrom.ifBlank { "(path unavailable)" }}", e)
|
||||
throw IllegalArgumentException("Bodyparts definition for '${it.name}' not found from ${fileFrom.ifBlank { "'${adlString.substring(0, 1024)}'" }}", e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -189,7 +189,9 @@ public class App implements ApplicationListener {
|
||||
* Sorted by the lastplaytime, in reverse order (index 0 is the most recent game played)
|
||||
*/
|
||||
public static TreeMap<UUID, DiskSkimmer> savegameWorlds = new TreeMap<>();
|
||||
public static TreeMap<UUID, String> savegameWorldsName = new TreeMap<>();
|
||||
public static TreeMap<UUID, DiskSkimmer> savegamePlayers = new TreeMap<>();
|
||||
public static TreeMap<UUID, String> savegamePlayersName = new TreeMap<>();
|
||||
|
||||
public static void updateListOfSavegames() {
|
||||
AppUpdateListOfSavegames();
|
||||
|
||||
@@ -19,6 +19,7 @@ import net.torvald.terrarum.App.*
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||
import net.torvald.terrarum.blockproperties.BlockCodex
|
||||
import net.torvald.terrarum.blockproperties.WireCodex
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.gameactors.Actor
|
||||
import net.torvald.terrarum.gameactors.ActorID
|
||||
import net.torvald.terrarum.gameactors.faction.FactionCodex
|
||||
@@ -682,7 +683,9 @@ class Codex : KVHashMap() {
|
||||
|
||||
fun AppUpdateListOfSavegames() {
|
||||
App.savegamePlayers.clear()
|
||||
App.savegamePlayersName.clear()
|
||||
App.savegameWorlds.clear()
|
||||
App.savegameWorldsName.clear()
|
||||
|
||||
println("listing savegames...")
|
||||
|
||||
@@ -692,7 +695,7 @@ fun AppUpdateListOfSavegames() {
|
||||
DiskSkimmer(file, Common.CHARSET, true)
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
System.err.println("Unable to load a savefile ${file.absolutePath}")
|
||||
System.err.println("Unable to load a world file ${file.absolutePath}")
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
@@ -705,9 +708,33 @@ fun AppUpdateListOfSavegames() {
|
||||
val json = JsonReader().parse(ByteArray64Reader(jsonFile.bytes, Common.CHARSET).readText())
|
||||
val worldUUID = UUID.fromString(json.get("worldIndex")!!.asString())
|
||||
App.savegameWorlds[worldUUID] = it
|
||||
App.savegameWorldsName[worldUUID] = it.getDiskName(Common.CHARSET)
|
||||
}
|
||||
|
||||
|
||||
// create list of players
|
||||
(File(App.playersDir).listFiles().filter { !it.isDirectory && !it.name.contains('.') }.map { file ->
|
||||
try {
|
||||
DiskSkimmer(file, Common.CHARSET, true)
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
System.err.println("Unable to load a player file ${file.absolutePath}")
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
}.filter { it != null }.sortedByDescending { it!!.diskFile.lastModified() } as List<DiskSkimmer>).forEach {
|
||||
println(it.diskFile.absolutePath)
|
||||
it.rebuild() // disk skimmer was created without initialisation, so do it now
|
||||
|
||||
// TODO write simple and dumb SAX parser for JSON
|
||||
val jsonFile = it.getFile(-1L)!!
|
||||
val json = JsonReader().parse(ByteArray64Reader(jsonFile.bytes, Common.CHARSET).readText())
|
||||
val playerUUID = UUID.fromString(json.get("uuid")!!.asString())
|
||||
App.savegamePlayers[playerUUID] = it
|
||||
// App.savegamePlayersName[playerUUID] = it.getDiskName(Common.CHARSET)
|
||||
App.savegamePlayersName[playerUUID] = json.get("actorValue")?.getChild(AVKey.NAME)?.asString() ?: ""
|
||||
}
|
||||
|
||||
// TODO: savegamePlayers
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -333,13 +333,13 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
|
||||
worldDisk = VDUtil.createNewDisk(
|
||||
1L shl 60,
|
||||
worldSavefileName,
|
||||
savegameNickname,
|
||||
Common.CHARSET
|
||||
)
|
||||
|
||||
playerDisk = VDUtil.createNewDisk(
|
||||
1L shl 60,
|
||||
playerSavefileName,
|
||||
actorGamer.actorValue.getAsString(AVKey.NAME) ?: "",
|
||||
Common.CHARSET
|
||||
)
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ class IngamePlayer : ActorHumanoid {
|
||||
private fun _rebuild(disk: SimpleFileSystem, ad: ADProperties, sprite: SpriteAnimation) {
|
||||
// TODO injecting held item/armour pictures? Would it be AssembleSheetPixmap's job?
|
||||
|
||||
val pixmap = AssembleSheetPixmap.fromVirtualDisk(disk, ad)
|
||||
val pixmap = if (disk.getEntry(-1025) != null) AssembleSheetPixmap.fromVirtualDisk(disk, ad) else AssembleSheetPixmap.fromAssetsDir(ad)
|
||||
val texture = Texture(pixmap)
|
||||
texture.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
|
||||
pixmap.dispose()
|
||||
|
||||
@@ -5,9 +5,8 @@ import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import net.torvald.TIMES
|
||||
import net.torvald.terrarum.App
|
||||
import net.torvald.terrarum.CommonResourcePool
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.ui.ItemSlotImageFactory.CELLCOLOUR_BLACK
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.CELL_COL
|
||||
import net.torvald.terrarum.ui.Toolkit
|
||||
import net.torvald.terrarum.ui.UICanvas
|
||||
import net.torvald.terrarum.ui.UIItemTextButton
|
||||
@@ -63,7 +62,7 @@ class GraphicsControlPanel : UICanvas() {
|
||||
batch.color = Color.WHITE
|
||||
Toolkit.drawBoxBorder(batch, drawX, drawY, width, height)
|
||||
|
||||
batch.color = CELLCOLOUR_BLACK
|
||||
batch.color = CELL_COL
|
||||
Toolkit.fillArea(batch, drawX, drawY, width, height)
|
||||
|
||||
batch.color = Color.WHITE
|
||||
|
||||
@@ -34,6 +34,8 @@ class UIInventoryFull(
|
||||
override var openCloseTime: Second = 0.0f
|
||||
|
||||
companion object {
|
||||
val CELL_COL = Color(0x28282888)
|
||||
|
||||
const val INVEN_DEBUG_MODE = false
|
||||
|
||||
const val REQUIRED_MARGIN: Int = 138 // hard-coded value. Don't know the details. Range: [91-146]. I chose MAX-8 because cell gap is 8
|
||||
|
||||
@@ -5,8 +5,8 @@ import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.gameitem.GameItem
|
||||
import net.torvald.terrarum.modulebasegame.ui.ItemSlotImageFactory.CELLCOLOUR_BLACK
|
||||
import net.torvald.terrarum.modulebasegame.ui.ItemSlotImageFactory.CELLCOLOUR_BLACK_ACTIVE
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.CELL_COL
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.itemListHeight
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryItemGrid.Companion.createInvCellGenericKeyDownFun
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryItemGrid.Companion.createInvCellGenericTouchDownFun
|
||||
@@ -43,7 +43,7 @@ class UIItemInventoryEquippedView(
|
||||
lateinit var inventorySortList: Array<GameItem?>
|
||||
private var rebuildList = true
|
||||
|
||||
val spriteViewBackCol: Color = CELLCOLOUR_BLACK
|
||||
val spriteViewBackCol: Color = CELL_COL
|
||||
|
||||
private val equipPosIcon = CommonResourcePool.getAsTextureRegionPack("inventory_category")
|
||||
private val cellToIcon = intArrayOf(0,1,2,3,4,5,6,7,6,7,6,7)
|
||||
@@ -59,7 +59,7 @@ class UIItemInventoryEquippedView(
|
||||
itemImage = null,
|
||||
mouseoverBackCol = Color(CELLCOLOUR_BLACK_ACTIVE),
|
||||
mouseoverBackBlendMode = BlendMode.SCREEN,
|
||||
backCol = CELLCOLOUR_BLACK,
|
||||
backCol = CELL_COL,
|
||||
backBlendMode = BlendMode.NORMAL,
|
||||
drawBackOnNull = true,
|
||||
keyDownFun = createInvCellGenericKeyDownFun(),
|
||||
|
||||
@@ -13,8 +13,8 @@ import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.ActorInventory
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureInventory
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.InventoryPair
|
||||
import net.torvald.terrarum.modulebasegame.ui.ItemSlotImageFactory.CELLCOLOUR_BLACK
|
||||
import net.torvald.terrarum.modulebasegame.ui.ItemSlotImageFactory.CELLCOLOUR_BLACK_ACTIVE
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.CELL_COL
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVEN_DEBUG_MODE
|
||||
import net.torvald.terrarum.ui.UICanvas
|
||||
import net.torvald.terrarum.ui.UIItem
|
||||
@@ -55,7 +55,7 @@ class UIItemInventoryItemGrid(
|
||||
override val width = horizontalCells * UIItemInventoryElemSimple.height + (horizontalCells - 1) * listGap
|
||||
override val height = verticalCells * UIItemInventoryElemSimple.height + (verticalCells - 1) * listGap
|
||||
|
||||
val backColour = CELLCOLOUR_BLACK
|
||||
val backColour = CELL_COL
|
||||
|
||||
init {
|
||||
CommonResourcePool.addToLoadingList("inventory_walletnumberfont") {
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
package net.torvald.terrarum.modulebasegame.ui
|
||||
|
||||
import com.badlogic.gdx.graphics.Camera
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import com.badlogic.gdx.utils.JsonValue
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
|
||||
import net.torvald.terrarum.ui.UICanvas
|
||||
import net.torvald.terrarum.ui.UIItem
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2019-02-05.
|
||||
*
|
||||
* If ingamePlayer is specified, sprite of current ingamePlayer will be drawn, instead of the SaveMetaData's thumbnail.
|
||||
*/
|
||||
class UIItemPlayerInfoCell(
|
||||
parent: UICanvas,
|
||||
val saveInfo: JsonValue,
|
||||
override val width: Int,
|
||||
initialX: Int,
|
||||
initialY: Int,
|
||||
var highlightable: Boolean,
|
||||
var ingamePlayer: IngamePlayer? = null
|
||||
) : UIItem(parent, initialX, initialY) {
|
||||
|
||||
override val height = HEIGHT
|
||||
|
||||
companion object {
|
||||
const val HEIGHT = 64
|
||||
}
|
||||
|
||||
private val spriteAreaWidth = 56
|
||||
private val spriteToNameAreaGap = 8
|
||||
private val edgeGap = 8
|
||||
|
||||
private val backColInactive = ItemSlotImageFactory.CELLCOLOUR_BLACK
|
||||
private val backColActive = ItemSlotImageFactory.CELLCOLOUR_BLACK_ACTIVE
|
||||
|
||||
private val textRow1 = (((height / 2) - App.fontGame.lineHeight) / 2).toFloat()
|
||||
private val textRow2 = textRow1 + (height / 2)
|
||||
|
||||
private val creationTimeStr: String
|
||||
private val modificationTimeStr: String
|
||||
|
||||
private val worldCountStr: String
|
||||
private val worldCountStrWidth: Int
|
||||
|
||||
init {
|
||||
val cal = Calendar.getInstance()
|
||||
|
||||
cal.timeInMillis = saveInfo.getLong("creation_t") * 1000
|
||||
creationTimeStr = "${cal[Calendar.YEAR]}-" +
|
||||
"${cal[Calendar.MONTH].toString().padStart(2,'0')}-" +
|
||||
"${cal[Calendar.DATE].toString().padStart(2,'0')}"
|
||||
|
||||
cal.timeInMillis = saveInfo.getLong("lastplay_t") * 1000
|
||||
modificationTimeStr = "${cal[Calendar.YEAR]}-" +
|
||||
"${cal[Calendar.MONTH].toString().padStart(2,'0')}-" +
|
||||
"${cal[Calendar.DATE].toString().padStart(2,'0')}"
|
||||
|
||||
|
||||
worldCountStr = Lang["CONTEXT_WORLD_COUNT"] + saveInfo.get("worlds").asIntArray().size
|
||||
worldCountStrWidth = App.fontGame.getWidth(worldCountStr)
|
||||
}
|
||||
|
||||
override fun render(batch: SpriteBatch, camera: Camera) {
|
||||
// background
|
||||
if (highlightable && mouseUp) {
|
||||
batch.color = backColActive
|
||||
blendScreen(batch)
|
||||
}
|
||||
else {
|
||||
batch.color = backColInactive
|
||||
blendNormal(batch)
|
||||
}
|
||||
|
||||
batch.fillRect(posX.toFloat(), posY.toFloat(), width.toFloat(), height.toFloat())
|
||||
|
||||
|
||||
blendNormal(batch)
|
||||
/*batch.color = SPRITE_DRAW_COL
|
||||
|
||||
// character sprite image
|
||||
if (ingamePlayer != null) {
|
||||
val spriteImage = ingamePlayer?.sprite?.textureRegion?.get(0,0)
|
||||
batch.draw(spriteImage,
|
||||
((spriteImage?.regionWidth ?: 2) - spriteAreaWidth).div(2).toFloat(),
|
||||
((spriteImage?.regionHeight ?: 2) - height).div(2).toFloat()
|
||||
)
|
||||
}
|
||||
else {
|
||||
val spriteImage = saveInfo.thumbnail
|
||||
batch.draw(spriteImage,
|
||||
(spriteImage.width - spriteAreaWidth).div(2).toFloat(),
|
||||
(spriteImage.height - height).div(2).toFloat()
|
||||
)
|
||||
}
|
||||
|
||||
// texts //
|
||||
|
||||
// name
|
||||
batch.color = Color.WHITE
|
||||
AppLoader.fontGame.draw(batch, saveInfo.playerName, spriteAreaWidth + spriteToNameAreaGap.toFloat(), textRow1)
|
||||
// creation and modification time
|
||||
AppLoader.fontGame.draw(batch, "$creationTimeStr/$modificationTimeStr", spriteAreaWidth + spriteToNameAreaGap.toFloat(), textRow2)
|
||||
// world count
|
||||
AppLoader.fontGame.draw(batch, worldCountStr, width - (edgeGap + worldCountStrWidth).toFloat(), textRow1)
|
||||
// wallet
|
||||
val walletStr = "¤ " + (ingamePlayer?.inventory?.wallet ?: saveInfo.playerWallet)
|
||||
val walletStrWidth = AppLoader.fontGame.getWidth(walletStr)
|
||||
AppLoader.fontGame.draw(batch, walletStr, width - (edgeGap + walletStrWidth).toFloat(), textRow2)
|
||||
*/
|
||||
}
|
||||
|
||||
override fun update(delta: Float) {
|
||||
super.update(delta)
|
||||
|
||||
|
||||
|
||||
oldPosX = posX
|
||||
oldPosY = posY
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
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.ui.UICanvas
|
||||
import net.torvald.terrarum.ui.UIItem
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* @param savefile TEVd file
|
||||
*
|
||||
* Created by minjaesong on 2018-09-15.
|
||||
*/
|
||||
class UIItemSavegameInfoCell(
|
||||
parent: UICanvas,
|
||||
savefile: File,
|
||||
override val width: Int,
|
||||
initialX: Int,
|
||||
initialY: Int
|
||||
) : UIItem(parent, initialX, initialY) {
|
||||
|
||||
override val height: Int = App.fontGame.lineHeight.toInt() * 2
|
||||
|
||||
override fun render(batch: SpriteBatch, camera: Camera) {
|
||||
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -8,12 +8,18 @@ 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 com.jme3.math.FastMath
|
||||
import net.torvald.EMDASH
|
||||
import net.torvald.getKeycapConsole
|
||||
import net.torvald.getKeycapPC
|
||||
import net.torvald.spriteanimation.SpriteAnimation
|
||||
import net.torvald.spriteassembler.ADProperties
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.App.printdbg
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.CELL_COL
|
||||
import net.torvald.terrarum.serialise.Common
|
||||
import net.torvald.terrarum.serialise.ReadPlayer
|
||||
import net.torvald.terrarum.tvda.ByteArray64InputStream
|
||||
import net.torvald.terrarum.tvda.ByteArray64Reader
|
||||
import net.torvald.terrarum.tvda.DiskSkimmer
|
||||
@@ -97,6 +103,15 @@ class UILoadDemoSavefiles : UICanvas() {
|
||||
|
||||
private var showSpinner = false
|
||||
|
||||
// used by UIItem*Cells
|
||||
internal var playerDisk: DiskSkimmer? = null
|
||||
internal var worldDisk: DiskSkimmer? = null
|
||||
|
||||
private val worldCells = ArrayList<UIItemWorldCells>()
|
||||
private val playerCells = ArrayList<UIItemPlayerCells>()
|
||||
|
||||
var mode = 0 // 0: show players, 1: show worlds
|
||||
|
||||
override fun show() {
|
||||
printdbg(this, "savefiles show()")
|
||||
|
||||
@@ -109,19 +124,31 @@ class UILoadDemoSavefiles : UICanvas() {
|
||||
Thread {
|
||||
// read savegames
|
||||
var savegamesCount = 0
|
||||
App.savegameWorlds.forEach { (uuid, skimmer) ->
|
||||
App.savegameWorlds.forEach { (_, skimmer) ->
|
||||
val x = uiX + if (App.getConfigBoolean("fx_streamerslayout")) App.scr.chatWidth / 2 else 0
|
||||
val y = titleTopGradEnd + cellInterval * savegamesCount
|
||||
try {
|
||||
addUIitem(UIItemWorldCells(this, x, y, skimmer))
|
||||
worldCells.add(UIItemWorldCells(this, x, y, skimmer))
|
||||
savegamesCount += 1
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
System.err.println("[UILoadDemoSavefiles] Error while loading World '${skimmer.diskFile.absolutePath}'")
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
savegamesCount = 0
|
||||
App.savegamePlayers.forEach { (_, skimmer) ->
|
||||
val x = uiX + if (App.getConfigBoolean("fx_streamerslayout")) App.scr.chatWidth / 2 else 0
|
||||
val y = titleTopGradEnd + cellInterval * savegamesCount
|
||||
try {
|
||||
playerCells.add(UIItemPlayerCells(this, x, y, skimmer))
|
||||
savegamesCount += 1
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
System.err.println("[UILoadDemoSavefiles] Error while loading Player '${skimmer.diskFile.absolutePath}'")
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -134,10 +161,14 @@ class UILoadDemoSavefiles : UICanvas() {
|
||||
}
|
||||
|
||||
override fun hide() {
|
||||
uiItems.forEach { it.dispose() }
|
||||
uiItems.clear()
|
||||
worldCells.forEach { it.dispose() }
|
||||
worldCells.clear()
|
||||
playerCells.forEach { it.dispose() }
|
||||
playerCells.clear()
|
||||
}
|
||||
|
||||
private fun getCells() = if (mode == 0) playerCells else worldCells
|
||||
|
||||
override fun updateUI(delta: Float) {
|
||||
|
||||
if (scrollTarget != listScroll) {
|
||||
@@ -156,8 +187,10 @@ class UILoadDemoSavefiles : UICanvas() {
|
||||
}
|
||||
}
|
||||
|
||||
for (index in 0 until uiItems.size) {
|
||||
val it = uiItems[index]
|
||||
val cells = getCells()
|
||||
|
||||
for (index in 0 until cells.size) {
|
||||
val it = cells[index]
|
||||
if (index in listScroll - 2 until listScroll + savesVisible + 2) {
|
||||
// re-position
|
||||
it.posY = (it.initialY - uiScroll).roundToInt()
|
||||
@@ -172,6 +205,8 @@ class UILoadDemoSavefiles : UICanvas() {
|
||||
|
||||
batch.end()
|
||||
|
||||
val cells = getCells()
|
||||
|
||||
lateinit var savePixmap: Pixmap
|
||||
sliderFBO.inAction(camera as OrthographicCamera, batch) {
|
||||
gdxClearAndSetBlend(0f,0f,0f,0f)
|
||||
@@ -179,8 +214,8 @@ class UILoadDemoSavefiles : UICanvas() {
|
||||
setCameraPosition(batch, camera, 0f, 0f)
|
||||
batch.color = Color.WHITE
|
||||
batch.inUse {
|
||||
for (index in 0 until uiItems.size) {
|
||||
val it = uiItems[index]
|
||||
for (index in 0 until cells.size) {
|
||||
val it = cells[index]
|
||||
if (index in listScroll - 2 until listScroll + savesVisible + 2) {
|
||||
it.render(batch, camera)
|
||||
}
|
||||
@@ -240,12 +275,14 @@ class UILoadDemoSavefiles : UICanvas() {
|
||||
|
||||
override fun keyDown(keycode: Int): Boolean {
|
||||
if (this.isVisible) {
|
||||
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 < uiItems.size - savesVisible) {
|
||||
else if ((keycode == Input.Keys.DOWN || keycode == App.getConfigInt("control_key_down")) && scrollTarget < cells.size - savesVisible) {
|
||||
scrollFrom = listScroll
|
||||
scrollTarget += 1
|
||||
scrollAnimCounter = 0f
|
||||
@@ -256,12 +293,14 @@ class UILoadDemoSavefiles : UICanvas() {
|
||||
|
||||
override fun scrolled(amountX: Float, amountY: Float): Boolean {
|
||||
if (this.isVisible) {
|
||||
val cells = getCells()
|
||||
|
||||
if (amountY <= -1f && scrollTarget > 0) {
|
||||
scrollFrom = listScroll
|
||||
scrollTarget -= 1
|
||||
scrollAnimCounter = 0f
|
||||
}
|
||||
else if (amountY >= 1f && scrollTarget < uiItems.size - savesVisible) {
|
||||
else if (amountY >= 1f && scrollTarget < cells.size - savesVisible) {
|
||||
scrollFrom = listScroll
|
||||
scrollTarget += 1
|
||||
scrollAnimCounter = 0f
|
||||
@@ -323,9 +362,109 @@ class UIItemPlayerCells(
|
||||
override val width = SAVE_CELL_WIDTH
|
||||
override val height = SAVE_CELL_HEIGHT
|
||||
|
||||
private var thumbPixmap: Pixmap? = null
|
||||
private var thumb: TextureRegion? = null
|
||||
|
||||
override var clickOnceListener: ((Int, Int, Int) -> Unit)? = { _: Int, _: Int, _: Int ->
|
||||
parent.playerDisk = skimmer
|
||||
}
|
||||
|
||||
private var playerName: String = "$EMDASH"
|
||||
private var worldName: String = "$EMDASH"
|
||||
private var lastPlayTime: String = "--h--m--s"
|
||||
private var totalPlayTime: String = "--:--:--"
|
||||
|
||||
init {
|
||||
skimmer.getFile(-1L)?.bytes?.let {
|
||||
val json = JsonReader().parse(ByteArray64Reader(it, Common.CHARSET))
|
||||
|
||||
val playerUUID = UUID.fromString(json["uuid"]?.asString())
|
||||
val worldUUID = UUID.fromString(json["worldCurrentlyPlaying"]?.asString())
|
||||
|
||||
App.savegamePlayersName[playerUUID]?.let { if (it.isNotBlank()) playerName = it }
|
||||
App.savegameWorldsName[worldUUID]?.let { if (it.isNotBlank()) worldName = it }
|
||||
json["lastPlayTime"]?.asString()?.let {
|
||||
lastPlayTime = Instant.ofEpochSecond(it.toLong())
|
||||
.atZone(TimeZone.getDefault().toZoneId())
|
||||
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
|
||||
}
|
||||
json["totalPlayTime"]?.asString()?.let {
|
||||
totalPlayTime = parseDuration(it.toLong())
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseDuration(seconds: Long): String {
|
||||
val s = seconds % 60
|
||||
val m = (seconds / 60) % 60
|
||||
val h = (seconds / 3600) % 24
|
||||
val d = seconds / 86400
|
||||
return if (d == 0L)
|
||||
"${h.toString().padStart(2,'0')}h${m.toString().padStart(2,'0')}m${s.toString().padStart(2,'0')}s"
|
||||
else
|
||||
"${d}d${h.toString().padStart(2,'0')}h${m.toString().padStart(2,'0')}m${s.toString().padStart(2,'0')}s"
|
||||
}
|
||||
|
||||
private var sprite: SpriteAnimation? = null
|
||||
|
||||
internal var hasTexture = false
|
||||
private set
|
||||
|
||||
private val cellCol = CELL_COL
|
||||
|
||||
override fun render(batch: SpriteBatch, camera: Camera) {
|
||||
// try to generate a texture
|
||||
if (skimmer.initialised && !hasTexture) {
|
||||
skimmer.getFile(-1L)?.bytes?.let {
|
||||
val animFile = skimmer.getFile(-2L)!!
|
||||
val p = ReadPlayer(skimmer, ByteArray64Reader(it, Common.CHARSET))
|
||||
val sprite = SpriteAnimation(p)
|
||||
val animDesc = ADProperties(ByteArray64Reader(animFile.bytes, Common.CHARSET))
|
||||
p.reassembleSprite(skimmer, sprite, animDesc)
|
||||
sprite.textureRegion.get(0,0).let {
|
||||
thumb = it
|
||||
}
|
||||
this.sprite = sprite
|
||||
}
|
||||
|
||||
hasTexture = true
|
||||
}
|
||||
|
||||
val highlightCol = if (mouseUp) UIItemTextButton.defaultActiveCol else Color.WHITE
|
||||
val x = posX.toFloat()
|
||||
val y = posY.toFloat()
|
||||
|
||||
// draw box backgrounds
|
||||
batch.color = cellCol
|
||||
Toolkit.fillArea(batch, posX, posY, 106, height)
|
||||
Toolkit.fillArea(batch, posX + 116, posY + 63, width - 116, 57)
|
||||
|
||||
// draw borders
|
||||
batch.color = highlightCol
|
||||
// avatar border
|
||||
Toolkit.drawBoxBorder(batch, posX - 1, posY - 1, 106 + 2, height + 2)
|
||||
// infocell border
|
||||
Toolkit.drawBoxBorder(batch, posX + 115, posY + 62, width - 114, 59)
|
||||
// infocell divider
|
||||
Toolkit.fillArea(batch, posX + 118, posY + 90, width - 120, 1)
|
||||
|
||||
// player avatar
|
||||
batch.color = Color.WHITE
|
||||
thumb?.let {
|
||||
batch.draw(it, x + FastMath.ceil((106f - it.regionWidth) / 2f), y + FastMath.ceil((height - it.regionHeight) / 2f))
|
||||
}
|
||||
// texts
|
||||
App.fontGame.draw(batch, playerName, x + 120f, y + height - 54f)
|
||||
App.fontGame.draw(batch, worldName, x + 120f, y + height - 24f)
|
||||
App.fontGame.draw(batch, lastPlayTime, x + width - 4f - App.fontGame.getWidth(lastPlayTime), y + height - 54f)
|
||||
App.fontGame.draw(batch, totalPlayTime, x + width - 4f - App.fontGame.getWidth(totalPlayTime), y + height - 24f)
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
thumb?.texture?.dispose()
|
||||
thumbPixmap?.dispose()
|
||||
sprite?.dispose()
|
||||
}
|
||||
|
||||
|
||||
@@ -398,6 +537,7 @@ class UIItemWorldCells(
|
||||
|
||||
|
||||
private val colourBad = Color(0xFF0011FF.toInt())
|
||||
private val cellCol = CELL_COL
|
||||
|
||||
|
||||
init {
|
||||
@@ -405,6 +545,7 @@ class UIItemWorldCells(
|
||||
}
|
||||
|
||||
override var clickOnceListener: ((Int, Int, Int) -> Unit)? = { _: Int, _: Int, _: Int ->
|
||||
parent.worldDisk = skimmer
|
||||
TODO()
|
||||
}
|
||||
|
||||
@@ -435,8 +576,10 @@ class UIItemWorldCells(
|
||||
val x = posX.toFloat()
|
||||
val y = posY.toFloat()
|
||||
|
||||
|
||||
// TODO draw border
|
||||
// draw background
|
||||
batch.color = cellCol
|
||||
Toolkit.fillArea(batch, posX, posY, width, height)
|
||||
// draw border
|
||||
batch.color = highlightCol
|
||||
Toolkit.drawBoxBorder(batch, posX-1, posY-1, width+2, height+2)
|
||||
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
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.Second
|
||||
import net.torvald.terrarum.blendNormal
|
||||
import net.torvald.terrarum.ui.UICanvas
|
||||
import net.torvald.terrarum.ui.UIItemList
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2018-09-15.
|
||||
*/
|
||||
class UITitleCharactersList : UICanvas() {
|
||||
|
||||
override var openCloseTime: Second = 0f
|
||||
|
||||
private val moduleAreaHMargin = 48
|
||||
private val moduleAreaBorder = 8
|
||||
|
||||
override var width = App.scr.width - UIRemoCon.remoConWidth - moduleAreaHMargin
|
||||
override var height = App.scr.height - moduleAreaHMargin * 2
|
||||
|
||||
private val moduleInfoCells = ArrayList<UIItemSavegameInfoCell>()
|
||||
// build characters list
|
||||
init {
|
||||
//SavegameLedger.getSavefileList()?.forEachIndexed { index, file ->
|
||||
//
|
||||
//}
|
||||
}
|
||||
|
||||
private val mouduleArea = UIItemList<UIItemSavegameInfoCell>(
|
||||
this,
|
||||
moduleInfoCells,
|
||||
UIRemoCon.remoConWidth, moduleAreaHMargin,
|
||||
width,
|
||||
height,
|
||||
inactiveCol = Color.WHITE,
|
||||
border = moduleAreaBorder
|
||||
)
|
||||
|
||||
|
||||
init {
|
||||
uiItems.add(mouduleArea)
|
||||
}
|
||||
|
||||
override fun updateUI(delta: Float) {
|
||||
mouduleArea.update(delta)
|
||||
}
|
||||
|
||||
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
||||
batch.color = Color.WHITE
|
||||
blendNormal(batch)
|
||||
mouduleArea.render(batch, camera)
|
||||
}
|
||||
|
||||
override fun doOpening(delta: Float) {
|
||||
}
|
||||
|
||||
override fun doClosing(delta: Float) {
|
||||
}
|
||||
|
||||
override fun endOpening(delta: Float) {
|
||||
}
|
||||
|
||||
override fun endClosing(delta: Float) {
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -101,6 +101,9 @@ object WritePlayer {
|
||||
/**
|
||||
* Player-specific [ReadActor].
|
||||
*
|
||||
* @param disk disk
|
||||
* @param dataStream Reader containing JSON file
|
||||
*
|
||||
* Created by minjaesong on 2021-10-07.
|
||||
*/
|
||||
object ReadPlayer {
|
||||
|
||||
BIN
work_files/UI/character_cell.kra
LFS
BIN
work_files/UI/character_cell.kra
LFS
Binary file not shown.
Reference in New Issue
Block a user