world portal gui wip

This commit is contained in:
minjaesong
2023-05-29 02:41:59 +09:00
parent 1646871ddf
commit 98a6c9ae70
8 changed files with 227 additions and 63 deletions

View File

@@ -16,5 +16,7 @@
"GAME_ACTION_QUICKSEL": "Quick Select",
"GAME_ACTION_CRAFT": "Craft",
"GAME_CRAFTING": "Crafting",
"GAME_CRAFTABLE_ITEMS": "Craftable Items"
"GAME_CRAFTABLE_ITEMS": "Craftable Items",
"CONTEXT_WORLD_SEARCH": "World Search",
"CONTEXT_WORLD_LIST": "Worlds List"
}

View File

@@ -136,11 +136,11 @@ class UIItemInventoryCatBar(
private val underlineColour = Color(0xeaeaea_40.toInt())
private val underlineHighlightColour = mainButtons[0].highlightCol
private var highlighterXPos = mainButtons[selectedIndex].posX.toFloat()
private var highlighterXPos = mainButtons[selectedIndex].posX
private var highlighterXStart = highlighterXPos
private var highlighterXEnd = highlighterXPos
private val highlighterYPos = catIcons.tileH + 4f
private val highlighterYPos = catIcons.tileH + 4
private var highlighterMoving = false
private val highlighterMoveDuration: Second = 0.15f
private var highlighterMoveTimer: Second = 0f
@@ -196,11 +196,11 @@ class UIItemInventoryCatBar(
highlighterMoveTimer += delta
highlighterXPos = Movement.moveQuick(
highlighterXStart,
highlighterXEnd,
highlighterXStart.toFloat(),
highlighterXEnd.toFloat(),
highlighterMoveTimer,
highlighterMoveDuration
)
).roundToInt()
if (highlighterMoveTimer > highlighterMoveDuration) {
highlighterMoveTimer = 0f
@@ -224,10 +224,10 @@ class UIItemInventoryCatBar(
// normal stuffs
val oldIndex = selectedIndex
highlighterXStart = mainButtons[selectedIndex].posX.toFloat() // using old selectedIndex
highlighterXStart = mainButtons[selectedIndex].posX // using old selectedIndex
selectedIndex = index
highlighterMoving = true
highlighterXEnd = mainButtons[selectedIndex].posX.toFloat() // using new selectedIndex
highlighterXEnd = mainButtons[selectedIndex].posX // using new selectedIndex
selectionChangeListener?.invoke(oldIndex, index)
}
@@ -290,12 +290,12 @@ class UIItemInventoryCatBar(
if (selectedPanel == 1) {
// indicator
batch.color = underlineHighlightColour
batch.draw(underlineIndTex, (highlighterXPos - buttonGapSize / 2).round(), posY + highlighterYPos)
batch.draw(underlineIndTex, (highlighterXPos - buttonGapSize / 2), posY + highlighterYPos.toFloat())
// label
batch.color = Color.WHITE
catIconsLabels[selectedIcon]().let {
App.fontGame.draw(batch, it, posX + ((width - App.fontGame.getWidth(it)) / 2).toFloat(), posY + highlighterYPos + 4)
App.fontGame.draw(batch, it, posX + ((width - App.fontGame.getWidth(it)) / 2), posY + highlighterYPos + 4)
}
}

View File

@@ -40,8 +40,12 @@ class UIInventoryFull(
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
const val CELLS_HOR = 10
val CELLS_VRT: Int; get() = (App.scr.height - REQUIRED_MARGIN - 134 + UIItemInventoryItemGrid.listGap) / // 134 is another magic number
(UIItemInventoryElemSimple.height + UIItemInventoryItemGrid.listGap)
fun getCellCountVertically(cellHeight: Int, gapHeight: Int = UIItemInventoryItemGrid.listGap): Int {
return (App.scr.height - REQUIRED_MARGIN - 134 + gapHeight) / // 134 is another magic number
(cellHeight + gapHeight)
}
val CELLS_VRT: Int; get() = getCellCountVertically(UIItemInventoryElemSimple.height, UIItemInventoryItemGrid.listGap)
const val itemListToEquipViewGap = UIItemInventoryItemGrid.listGap // used to be 24; figured out that the extra gap does nothig

View File

@@ -532,7 +532,7 @@ class UIItemPlayerCells(
private val litCol = Toolkit.Theme.COL_MOUSE_UP
private val cellCol = CELL_COL
private val defaultCol = Color.WHITE
private val defaultCol = Toolkit.Theme.COL_LIST_DEFAULT
private val hruleCol = Color(1f,1f,1f,0.35f)
private val hruleColLit = litCol.cpy().sub(0f,0f,0f,0.65f)
@@ -734,7 +734,7 @@ class UIItemWorldCells(
private val colourBad = Color(0xFF0011FF.toInt())
private val cellCol = CELL_COL
private var highlightCol: Color = Color.WHITE
private var highlightCol: Color = Toolkit.Theme.COL_LIST_DEFAULT
override var clickOnceListener: ((Int, Int, Int) -> Unit)? = { _: Int, _: Int, _: Int ->
UILoadGovernor.worldDisk = skimmer
@@ -746,7 +746,7 @@ class UIItemWorldCells(
override fun update(delta: Float) {
super.update(delta)
highlightCol = if (mouseUp) Toolkit.Theme.COL_MOUSE_UP else Color.WHITE
highlightCol = if (mouseUp) Toolkit.Theme.COL_MOUSE_UP else Toolkit.Theme.COL_LIST_DEFAULT
}
override fun render(batch: SpriteBatch, camera: Camera) {

View File

@@ -86,8 +86,6 @@ class UINewWorld(val remoCon: UIRemoCon) : UICanvas() {
private val goButton = UIItemTextButton(this, "MENU_LABEL_CONFIRM_BUTTON", drawX + width/2 + (width/2 - goButtonWidth) / 2, drawY + height - 24, goButtonWidth, true, alignment = UIItemTextButton.Companion.Alignment.CENTRE, hasBorder = true)
init {
tex.forEach { it.flip(false, false) }
goButton.touchDownListener = { _, _, _, _ ->
// printdbg(this, "generate! Size=${sizeSelector.selection}, Name=${nameInput.getTextOrPlaceholder()}, Seed=${seedInput.getTextOrPlaceholder()}")

View File

@@ -4,9 +4,15 @@ import com.badlogic.gdx.graphics.Camera
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.*
import net.torvald.terrarum.ui.Toolkit
import net.torvald.terrarum.ui.UICanvas
import net.torvald.terrarum.ui.UIItemHorizontalFadeSlide
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVENTORY_CELLS_OFFSET_Y
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.YPOS_CORRECTION
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.drawBackground
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.internalHeight
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.internalWidth
import net.torvald.terrarum.ui.*
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
import net.torvald.unicode.getKeycapPC
/**
* Structure:
@@ -23,8 +29,8 @@ class UIWorldPortal : UICanvas(
toggleButtonLiteral = App.getConfigInt("control_gamepad_start"),
) {
override var width = App.scr.width
override var height = App.scr.height
override var width: Int = Toolkit.drawWidth
override var height: Int = App.scr.height
@@ -41,23 +47,30 @@ class UIWorldPortal : UICanvas(
fun requestTransition(target: Int) = transitionPanel.requestTransition(target)
val catBar = UIItemInventoryCatBar(
val catBar = UIItemWorldPortalTopBar(
this,
(width - UIInventoryFull.catBarWidth) / 2,
42 - UIInventoryFull.YPOS_CORRECTION + (App.scr.height - UIInventoryFull.internalHeight) / 2,
UIInventoryFull.internalWidth,
UIInventoryFull.catBarWidth,
true
0,
42 - YPOS_CORRECTION + (App.scr.height - internalHeight) / 2,
) { i -> if (!panelTransitionLocked) requestTransition(i) }
private val SP = "\u3000 "
val portalListingControlHelp: String
get() = if (App.environment == RunningEnvironment.PC)
"${getKeycapPC(App.getConfigInt("control_key_inventory"))} ${Lang["GAME_ACTION_CLOSE"]}"
else
"${App.gamepadLabelStart} ${Lang["GAME_ACTION_CLOSE"]}" +
"$SP${App.gamepadLabelLT} ${Lang["GAME_WORLD_SEARCH"]}" +
"$SP${App.gamepadLabelRT} ${Lang["GAME_INVENTORY"]}"
private val transitionalSearch = UIWorldPortalSearch(this)
private val transitionalListing = UIWorldPortalListing(this)
private val transitionalCargo = UIWorldPortalCargo(this)
private val transitionPanel = UIItemHorizontalFadeSlide(
this,
(width - UIInventoryFull.internalWidth) / 2,
UIInventoryFull.INVENTORY_CELLS_OFFSET_Y(),
(width - internalWidth) / 2,
INVENTORY_CELLS_OFFSET_Y(),
width,
App.scr.height,
1f,
@@ -72,7 +85,10 @@ class UIWorldPortal : UICanvas(
}
internal var xEnd = (width + internalWidth).div(2).toFloat()
private set
internal var yEnd = -YPOS_CORRECTION + (App.scr.height + internalHeight).div(2).toFloat()
private set
@@ -82,7 +98,7 @@ class UIWorldPortal : UICanvas(
}
override fun renderUI(batch: SpriteBatch, camera: Camera) {
UIInventoryFull.drawBackground(batch, handler.opacity)
drawBackground(batch, handler.opacity)
// UI items
catBar.render(batch, camera)
@@ -123,4 +139,83 @@ class UIWorldPortal : UICanvas(
INGAME.setTooltipMessage(null) // required!
}
}
class UIItemWorldPortalTopBar(
parentUI: UIWorldPortal,
initialX: Int,
initialY: Int,
val panelTransitionReqFun: (Int) -> Unit = {} // for side buttons; for the selection change, override selectionChangeListener
) : UIItem(parentUI, initialX, initialY) {
override val width = 580
override val height = 25
init {
CommonResourcePool.addToLoadingList("terrarum-basegame-worldportalicons") {
TextureRegionPack(ModMgr.getGdxFile("basegame", "gui/worldportal_catbar.tga"), 20, 20)
}
CommonResourcePool.loadAll()
}
private val genericIcons: TextureRegionPack = CommonResourcePool.getAsTextureRegionPack("inventory_category")
private val icons = CommonResourcePool.getAsTextureRegionPack("terrarum-basegame-worldportalicons")
private val catIconImages = listOf(
icons.get(0, 0),
genericIcons.get(16,0),
icons.get(1, 0),
genericIcons.get(17,0),
icons.get(2, 0),
)
private val catIconLabels = listOf(
"CONTEXT_WORLD_SEARCH",
"",
"CONTEXT_WORLD_LIST",
"GAME_INVENTORY",
"",
)
private val buttonGapSize = 120
private val highlighterYPos = icons.tileH + 4
var selection = 2
private val buttons = Array<UIItemImageButton>(5) {
val xoff = if (it == 1) -32 else if (it == 3) 32 else 0
UIItemImageButton(
parentUI,
catIconImages[it],
activeBackCol = Color(0),
backgroundCol = Color(0),
highlightBackCol = Color(0),
activeBackBlendMode = BlendMode.NORMAL,
initialX = (Toolkit.drawWidth - width) / 2 + it * (buttonGapSize + 20) + xoff,
initialY = posY,
inactiveCol = if (it % 2 == 0) Color.WHITE else Color(0xffffff7f.toInt()),
activeCol = if (it % 2 == 0) Toolkit.Theme.COL_MOUSE_UP else Color(0xffffff7f.toInt()),
highlightable = (it % 2 == 0)
)
}
override fun render(batch: SpriteBatch, camera: Camera) {
super.render(batch, camera)
// button
buttons.forEach { it.render(batch, camera) }
// label
batch.color = Color.WHITE
val text = Lang[catIconLabels[selection]]
App.fontGame.draw(batch, text, buttons[selection].posX + 10 - (App.fontGame.getWidth(text) / 2), posY + highlighterYPos + 4)
blendNormalStraightAlpha(batch)
}
override fun dispose() {
}
}

View File

@@ -2,19 +2,18 @@ package net.torvald.terrarum.modulebasegame.ui
import com.badlogic.gdx.graphics.Camera
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 com.badlogic.gdx.utils.GdxRuntimeException
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.modulebasegame.ui.UIInventoryFull.Companion.getCellCountVertically
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.Common
import net.torvald.terrarum.serialise.ascii85toUUID
import net.torvald.terrarum.ui.Toolkit
import net.torvald.terrarum.ui.UICanvas
@@ -22,8 +21,8 @@ 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 net.torvald.unicode.EMDASH
import java.util.*
import kotlin.math.roundToInt
/**
* Created by minjaesong on 2023-05-19.
@@ -34,27 +33,19 @@ class UIWorldPortalListing(val full: UIWorldPortal) : UICanvas() {
override var width: Int = Toolkit.drawWidth
override var height: Int = App.scr.height
private val cellHeight = 48
private val buttonHeight = 24
private val gridGap = listGap
private val gridGap = 10
private val worldList = ArrayList<WorldInfo>()
private var selectedWorld: DiskSkimmer? = null
private val cellCol = UIInventoryFull.CELL_COL
private var highlightCol: Color = Color.WHITE
private val thumbw = 360
private val thumbh = 240
private val hx = Toolkit.drawWidth.div(2)
private val y = INVENTORY_CELLS_OFFSET_Y()
private val y = INVENTORY_CELLS_OFFSET_Y() + 1
private val listCount = UIInventoryFull.CELLS_VRT
private val listHeight = cellHeight * listCount + gridGap * (listCount - 1)
private val listCount = getCellCountVertically(UIItemWorldCellsSimple.height, gridGap)
private val listHeight = UIItemWorldCellsSimple.height + (listCount - 1) * (UIItemWorldCellsSimple.height + gridGap)
private val memoryGaugeWidth = 360
private val deleteButtonWidth = (memoryGaugeWidth - gridGap) / 2
@@ -80,7 +71,8 @@ class UIWorldPortalListing(val full: UIWorldPortal) : UICanvas() {
data class WorldInfo(
val uuid: UUID,
val diskSkimmer: DiskSkimmer,
val dimensionInChunks: Int
val dimensionInChunks: Int,
val seed: Long
)
init {
@@ -98,30 +90,49 @@ class UIWorldPortalListing(val full: UIWorldPortal) : UICanvas() {
private var chunksUsed = 0
private val chunksMax = 100000
private lateinit var worldCells: Array<UIItemWorldCellsSimple>
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 }.map { (uuid, disk) ->
chunksUsed = worldList.sumOf {
var chunksCount = 0
var seed = 0L
worldList.forEach {
var w = 0
var h = 0
JsonFetcher.readFromJsonString(ByteArray64Reader((disk!!.requestFile(-1)!!.contents.getContent() as EntryFile).bytes, Charsets.UTF_8)).let {
JsonFetcher.readFromJsonString(ByteArray64Reader((disk!!.requestFile(-1)!!.contents.getContent() as EntryFile).bytes, Common.CHARSET)).let {
JsonFetcher.forEachSiblings(it) { name, value ->
if (name == "width") w = value.asInt()
if (name == "height") h = value.asInt()
if (name == "generatorSeed") seed = value.asLong()
}
}
(w / CHUNK_W) * (h / CHUNK_H)
chunksCount = (w / CHUNK_W) * (h / CHUNK_H)
}
WorldInfo(uuid, disk!!, chunksUsed)
WorldInfo(uuid, disk!!, chunksCount, seed)
} as List<WorldInfo>)
chunksUsed = worldList.sumOf { it.dimensionInChunks }
worldCells = Array(maxOf(worldList.size, listCount)) {
UIItemWorldCellsSimple(
this,
hx + gridGap / 2,
y + (gridGap + UIItemWorldCellsSimple.height) * it,
worldList.getOrNull(it),
worldList.getOrNull(it)?.diskSkimmer?.getDiskName(Common.CHARSET)
)
}
uiItems.forEach { it.show() }
worldCells.forEach { it.show() }
}
override fun updateUI(delta: Float) {
uiItems.forEach { it.update(delta) }
worldCells.forEach { it.update(delta) }
}
@@ -132,13 +143,13 @@ class UIWorldPortalListing(val full: UIWorldPortal) : UICanvas() {
// draw background //
// screencap panel
batch.color = cellCol
batch.color = UIInventoryFull.CELL_COL
Toolkit.fillArea(batch, hx - thumbw - gridGap/2, y, thumbw, thumbh)
// draw border //
// screencap panel
batch.color = highlightCol
batch.color = Toolkit.Theme.COL_LIST_DEFAULT
Toolkit.drawBoxBorder(batch, hx - thumbw - gridGap/2 - 1, y - 1, thumbw + 2, thumbh + 2)
@@ -156,27 +167,81 @@ class UIWorldPortalListing(val full: UIWorldPortal) : UICanvas() {
uiItems.forEach { it.render(batch, camera) }
worldCells.forEach { it.render(batch, camera) }
// control hints
batch.color = Color.WHITE
App.fontGame.draw(batch, full.portalListingControlHelp, (hx - thumbw - gridGap/2).toInt(), (full.yEnd - 20).toInt())
}
override fun hide() {
uiItems.forEach { it.hide() }
worldCells.forEach { it.hide() }
worldCells.forEach { try { it.dispose() } catch (_: GdxRuntimeException) {} }
}
override fun dispose() {
uiItems.forEach { it.dispose() }
worldCells.forEach { try { it.dispose() } catch (_: GdxRuntimeException) {} }
}
}
class UIItemWorldCellsSimple(
parent: UILoadDemoSavefiles,
parent: UIWorldPortalListing,
initialX: Int,
initialY: Int,
val skimmer: DiskSkimmer
internal val worldInfo: UIWorldPortalListing.WorldInfo? = null,
internal val worldName: String? = null,
) : UIItem(parent, initialX, initialY) {
companion object {
const val width = 360
const val height = 46
}
override val width: Int = 360
override val height: Int = 46
private val cellCol = UIInventoryFull.CELL_COL
private var highlightCol: Color = Color.WHITE
private val icons = CommonResourcePool.getAsTextureRegionPack("terrarum-basegame-worldportalicons")
override fun show() {
super.show()
}
override fun hide() {
super.hide()
}
override fun update(delta: Float) {
super.update(delta)
}
override fun render(batch: SpriteBatch, camera: Camera) {
super.render(batch, camera)
// draw background
batch.color = UIInventoryFull.CELL_COL
Toolkit.fillArea(batch, posX, posY, width, height)
// draw border
val bcol = if (mouseUp && mousePushed) Toolkit.Theme.COL_SELECTED
else if (mouseUp) Toolkit.Theme.COL_MOUSE_UP else Toolkit.Theme.COL_LIST_DEFAULT
batch.color = bcol
Toolkit.drawBoxBorder(batch, posX - 1, posY - 1, width + 2, height + 2)
// draw texts
batch.draw(icons.get(0, 1), posX + 4f, posY + 1f)
App.fontGame.draw(batch, worldName ?: "$EMDASH", posX + 32, posY + 1)
batch.draw(icons.get(1, 1), posX + 4f, posY + 25f)
App.fontGame.draw(batch, if (worldInfo?.seed == null) "$EMDASH" else "${(if (worldInfo.seed > 0) " + " else "")}${worldInfo.seed}" , posX + 32, posY + 25)
// text separator
batch.color = bcol.cpy().sub(0f,0f,0f,0.65f)
Toolkit.fillArea(batch, posX + 2, posY + 23, width - 4, 1)
}
override fun dispose() {
}

View File

@@ -22,7 +22,7 @@ object Toolkit : Disposable {
val COL_INVENTORY_CELL_BORDER = Color(1f, 1f, 1f, 0.25f)
val COL_CELL_FILL = Color(0x282828C8)
val COL_LIST_DEFAULT = Color.WHITE
val COL_LIST_DEFAULT = Color.WHITE // white
val COL_INACTIVE = Color.LIGHT_GRAY
val COL_SELECTED = Color(0x00f8ff_ff) // cyan, HIGHLY SATURATED
val COL_MOUSE_UP = Color(0xfff066_ff.toInt()) // yellow (all yellows are of low saturation according to the colour science)