diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryCellBase.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryCellBase.kt index c344eeb08..4208d3931 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryCellBase.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryCellBase.kt @@ -67,7 +67,7 @@ abstract class UIItemInventoryCellBase( object UIItemInventoryCellCommonRes { val meterColourMap = GdxColorMap(Gdx.files.internal("./assets/clut/health_bar_colouring_4096.tga")) - val meterBackDarkening = Color(0x828282ff.toInt()) + val meterBackDarkening = Color(0x666666ff.toInt()) fun getHealthMeterColour(value: Float, start: Float, end: Float): Color { if (start > end) throw IllegalArgumentException("Start value is greater than end value: $start..$end") diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIWorldPortalListing.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIWorldPortalListing.kt index 96ef8634e..c4e5c3456 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIWorldPortalListing.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIWorldPortalListing.kt @@ -5,17 +5,25 @@ import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Texture import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.TextureRegion +import com.badlogic.gdx.utils.Json import net.torvald.terrarum.* import net.torvald.terrarum.gameactors.AVKey import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVENTORY_CELLS_OFFSET_Y import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryItemGrid.Companion.listGap +import net.torvald.terrarum.realestate.LandUtil.CHUNK_H +import net.torvald.terrarum.realestate.LandUtil.CHUNK_W +import net.torvald.terrarum.savegame.ByteArray64Reader import net.torvald.terrarum.savegame.DiskSkimmer +import net.torvald.terrarum.savegame.EntryFile import net.torvald.terrarum.serialise.ascii85toUUID import net.torvald.terrarum.ui.Toolkit import net.torvald.terrarum.ui.UICanvas import net.torvald.terrarum.ui.UIItem import net.torvald.terrarum.ui.UIItemTextButton +import net.torvald.terrarum.utils.JsonFetcher +import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack import java.util.* +import kotlin.math.roundToInt /** * Created by minjaesong on 2023-05-19. @@ -30,7 +38,7 @@ class UIWorldPortalListing(val full: UIWorldPortal) : UICanvas() { private val buttonHeight = 24 private val gridGap = listGap - private val worldList = ArrayList>() + private val worldList = ArrayList() private var selectedWorld: DiskSkimmer? = null @@ -48,8 +56,9 @@ class UIWorldPortalListing(val full: UIWorldPortal) : UICanvas() { private val listCount = UIInventoryFull.CELLS_VRT private val listHeight = cellHeight * listCount + gridGap * (listCount - 1) - private val deleteButtonWidth = 80 - private val buttonReset = UIItemTextButton(this, + private val memoryGaugeWidth = 360 + private val deleteButtonWidth = (memoryGaugeWidth - gridGap) / 2 + private val buttonDeleteWorld = UIItemTextButton(this, "MENU_LABEL_DELETE_WORLD", hx - gridGap/2 - deleteButtonWidth, y + listHeight - buttonHeight, @@ -58,34 +67,68 @@ class UIWorldPortalListing(val full: UIWorldPortal) : UICanvas() { hasBorder = true, alignment = UIItemTextButton.Companion.Alignment.CENTRE ) + private val buttonRenameWorld = UIItemTextButton(this, + "MENU_LABEL_RENAME", + buttonDeleteWorld.posX - gridGap - deleteButtonWidth, + y + listHeight - buttonHeight, + deleteButtonWidth, + readFromLang = true, + hasBorder = true, + alignment = UIItemTextButton.Companion.Alignment.CENTRE + ) + + data class WorldInfo( + val uuid: UUID, + val diskSkimmer: DiskSkimmer, + val dimensionInChunks: Int + ) init { CommonResourcePool.addToLoadingList("terrarum-basegame-worldportalicons") { - TextureRegion(Texture(ModMgr.getGdxFile("basegame", "gui/worldportal_catbar.tga")), 20, 20).also { - it.flip(false, false) - } + TextureRegionPack(ModMgr.getGdxFile("basegame", "gui/worldportal_catbar.tga"), 20, 20) } CommonResourcePool.loadAll() - addUIitem(buttonReset) + addUIitem(buttonRenameWorld) + addUIitem(buttonDeleteWorld) } + private var chunksUsed = 0 + private val chunksMax = 100000 + override fun show() { worldList.clear() worldList.addAll((INGAME.actorGamer.actorValue.getAsString(AVKey.WORLD_PORTAL_DICT) ?: "").split(",").filter { it.isNotBlank() }.map { it.ascii85toUUID().let { it to App.savegameWorlds[it] } - }.filter { it.second != null } as List>) + }.filter { it.second != null }.map { (uuid, disk) -> + chunksUsed = worldList.sumOf { + var w = 0 + var h = 0 + JsonFetcher.readFromJsonString(ByteArray64Reader((disk!!.requestFile(-1)!!.contents.getContent() as EntryFile).bytes, Charsets.UTF_8)).let { + JsonFetcher.forEachSiblings(it) { name, value -> + if (name == "width") w = value.asInt() + if (name == "height") h = value.asInt() + } + } + (w / CHUNK_W) * (h / CHUNK_H) + } + WorldInfo(uuid, disk!!, chunksUsed) + } as List) + chunksUsed = worldList.sumOf { it.dimensionInChunks } } override fun updateUI(delta: Float) { } - override fun renderUI(batch: SpriteBatch, camera: Camera) { + override fun renderUI(batch: SpriteBatch, camera: Camera) { + val memoryGaugeXpos = hx - memoryGaugeWidth - gridGap/2 + val memoryGaugeYpos = y + listHeight - buttonHeight - gridGap - buttonHeight + val icons = CommonResourcePool.getAsTextureRegionPack("terrarum-basegame-worldportalicons") // draw background // // screencap panel @@ -97,8 +140,19 @@ class UIWorldPortalListing(val full: UIWorldPortal) : UICanvas() { // screencap panel batch.color = highlightCol Toolkit.drawBoxBorder(batch, hx - thumbw - gridGap/2 - 1, y - 1, thumbw + 2, thumbh + 2) + + // memory gauge - Toolkit.drawBoxBorder(batch, hx - 330 - gridGap/2 - 1, y + listHeight - 1, 240 + 2, buttonHeight + 2) + val barCol = UIItemInventoryCellCommonRes.getHealthMeterColour(chunksMax - chunksUsed, 0, chunksMax) + val barBack = barCol mul UIItemInventoryCellCommonRes.meterBackDarkening + batch.color = Color.WHITE + batch.draw(icons.get(2, 2), memoryGaugeXpos - 32f, memoryGaugeYpos + 2f) + Toolkit.drawBoxBorder(batch, memoryGaugeXpos - 1, memoryGaugeYpos - 1, memoryGaugeWidth + 2, buttonHeight + 2) + batch.color = barBack + Toolkit.fillArea(batch, memoryGaugeXpos, memoryGaugeYpos, memoryGaugeWidth, buttonHeight) + batch.color = barCol + Toolkit.fillArea(batch, memoryGaugeXpos, memoryGaugeYpos, (memoryGaugeWidth * (chunksUsed / chunksMax.toFloat())).ceilInt(), buttonHeight) + uiItems.forEach { it.render(batch, camera) } diff --git a/src/net/torvald/terrarum/savegame/DiskSkimmer.kt b/src/net/torvald/terrarum/savegame/DiskSkimmer.kt index 0619ab323..34b38e4b2 100644 --- a/src/net/torvald/terrarum/savegame/DiskSkimmer.kt +++ b/src/net/torvald/terrarum/savegame/DiskSkimmer.kt @@ -363,6 +363,8 @@ removefile: return fa.read() } + + override fun getDiskName(charset: Charset): String { val bytes = ByteArray(268) fa.seek(10L) diff --git a/src/net/torvald/terrarum/ui/UIItemTextButton.kt b/src/net/torvald/terrarum/ui/UIItemTextButton.kt index 4b7a90c3b..41b6861d6 100644 --- a/src/net/torvald/terrarum/ui/UIItemTextButton.kt +++ b/src/net/torvald/terrarum/ui/UIItemTextButton.kt @@ -81,7 +81,7 @@ open class UIItemTextButton( Alignment.LEFT -> posX + paddingLeft Alignment.RIGHT -> width - paddingRight - textW } - val fontY = posY + (hitboxSize - font.lineHeight.toInt()) / 2 + val fontY = posY + 2 + (hitboxSize - font.lineHeight.toInt()) / 2 // draw background diff --git a/src/net/torvald/terrarum/utils/JsonFetcher.kt b/src/net/torvald/terrarum/utils/JsonFetcher.kt index 3f770f281..60c85f52c 100644 --- a/src/net/torvald/terrarum/utils/JsonFetcher.kt +++ b/src/net/torvald/terrarum/utils/JsonFetcher.kt @@ -3,6 +3,7 @@ package net.torvald.terrarum.utils import com.badlogic.gdx.utils.JsonReader import com.badlogic.gdx.utils.JsonValue import net.torvald.terrarum.App.printdbg +import java.io.Reader /** * Created by minjaesong on 2016-02-15. @@ -18,9 +19,7 @@ object JsonFetcher { printdbg(this, "Reading JSON $jsonFilePath") - if (jsonString == null) { - throw Error("[JsonFetcher] jsonString is null!") - } + if (jsonString == null) throw Error("[JsonFetcher] jsonString is null!") return JsonReader().parse(jsonString.toString()) } @@ -32,13 +31,15 @@ object JsonFetcher { printdbg(this, "Reading JSON ${jsonFile.path}") - if (jsonString == null) { - throw Error("[JsonFetcher] jsonString is null!") - } + if (jsonString == null) throw Error("[JsonFetcher] jsonString is null!") return JsonReader().parse(jsonString.toString()) } + fun readFromJsonString(stringReader: Reader): JsonValue { + return JsonReader().parse(stringReader.readText()) + } + @Throws(java.io.IOException::class) private fun readJsonFileAsString(path: String) { java.nio.file.Files.lines(java.nio.file.FileSystems.getDefault().getPath(path)).forEach( diff --git a/work_files/DataFormats/SAVE_FORMAT.md b/work_files/DataFormats/SAVE_FORMAT.md index f9c8d8b79..c461beb81 100644 --- a/work_files/DataFormats/SAVE_FORMAT.md +++ b/work_files/DataFormats/SAVE_FORMAT.md @@ -7,7 +7,7 @@ The main game directory is composed of following directories: ``` .Terrarum + Players - - "${PlayerName}-${UUID}", TVDA { + - "${UUID}", TVDA { [-1] player JSON, [-2] spritedef, [-3] !optional! spritedef-glow, @@ -23,7 +23,7 @@ The main game directory is composed of following directories: - , TEVD { * } - + Worlds - - "${WorldName}-${UUID}", TVDA { + - "${UUID}", TVDA { [-1] world JSON with Player Data, [actorID] actors (mainly fixtures) JSON, [0x1_0000_0000L or (layerNumber shl 24) or chunkNumber] chunk data,