mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-15 16:16:10 +09:00
300 lines
10 KiB
Kotlin
300 lines
10 KiB
Kotlin
package net.torvald.terrarum.modulebasegame.ui
|
|
|
|
import com.badlogic.gdx.Input.Keys
|
|
import com.badlogic.gdx.graphics.Color
|
|
import com.badlogic.gdx.graphics.OrthographicCamera
|
|
import com.badlogic.gdx.graphics.Pixmap
|
|
import com.badlogic.gdx.graphics.Texture
|
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
|
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
|
import net.torvald.terrarum.*
|
|
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
|
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF
|
|
import net.torvald.terrarum.blockproperties.Block
|
|
import net.torvald.terrarum.itemproperties.Item
|
|
import net.torvald.terrarum.langpack.Lang
|
|
import net.torvald.terrarum.modulebasegame.gameactors.ActorInventory
|
|
import net.torvald.terrarum.modulebasegame.gameactors.FixtureInventory
|
|
import net.torvald.terrarum.modulebasegame.gameitems.ItemTextSignCopper
|
|
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellCommonRes.tooltipShowing
|
|
import net.torvald.terrarum.ui.*
|
|
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
|
import net.torvald.unicode.TIMES
|
|
import net.torvald.unicode.getKeycapPC
|
|
import kotlin.math.roundToInt
|
|
|
|
/**
|
|
* Created by minjaesong on 2024-03-22.
|
|
*/
|
|
class UIEngravingTextSign : UICanvas(
|
|
toggleKeyLiteral = "control_key_inventory",
|
|
toggleButtonLiteral = "control_gamepad_start"
|
|
) {
|
|
|
|
private var panelZoom = 4f
|
|
init {
|
|
CommonResourcePool.addToLoadingList("spritesheet:copper_sign") {
|
|
TextureRegionPack(ModMgr.getGdxFile("basegame", "sprites/fixtures/text_sign_glass_copper.tga"), TILE_SIZE, 2*TILE_SIZE)
|
|
}
|
|
CommonResourcePool.loadAll()
|
|
}
|
|
|
|
private val signSheet = CommonResourcePool.getAsTextureRegionPack("spritesheet:copper_sign")
|
|
|
|
override var width = Toolkit.drawWidth
|
|
override var height = App.scr.height
|
|
|
|
fun getPlayerInventory(): ActorInventory = INGAME.actorNowPlaying!!.inventory
|
|
|
|
private val row0 = App.scr.halfh + 48
|
|
private val row1 = row0 + 60
|
|
private val row2 = row1 + 40
|
|
|
|
private val row3 = maxOf(UIInventoryFull.yEnd.toInt() - 20 - 36, row2 + 64)
|
|
|
|
private val goButtonWidth = 180
|
|
|
|
private val internalWidth = 480
|
|
private val drawX = (Toolkit.drawWidth - internalWidth) / 2
|
|
private val inputWidth = 350
|
|
private val spinnerWidth = ControlPanelCommon.CONFIG_SPINNER_WIDTH
|
|
private val ingredientsWidth = UIItemInventoryElemSimple.height * 3 + 16
|
|
private val inputX = drawX + internalWidth - inputWidth
|
|
|
|
private val textInput = UIItemTextLineInput(this, inputX - 1, row0, inputWidth).also {
|
|
it.textCommitListener = { text ->
|
|
val textLen = App.fontGame.getWidth(text) + 4
|
|
val panelCountMin = (textLen / TILE_SIZEF).ceilToInt()
|
|
|
|
updateMinimumLen(panelCountMin)
|
|
panelCount = panelCountSpinner.value.toInt()
|
|
|
|
updatePanelText(text, panelCount)
|
|
}
|
|
}
|
|
|
|
private val COPPER_BULB = "item@basegame:35"
|
|
private val ROCK_TILE = Block.STONE_TILE_WHITE
|
|
private val GLASS = Block.GLASS_CRUDE
|
|
|
|
|
|
private val backdropColour = Color(0xffffff_c8.toInt())
|
|
|
|
private var fboText = FrameBuffer(Pixmap.Format.RGBA8888, 1, 1, false)
|
|
private var fboBatch = SpriteBatch()
|
|
private var fboCamera = OrthographicCamera(1f, 1f)
|
|
|
|
private fun updateMinimumLen(mlen0: Int) {
|
|
val mlen = mlen0.coerceAtLeast(2).toDouble()
|
|
val delta = maxOf(panelCount.toDouble(), mlen) - panelCount.toDouble()
|
|
panelCountSpinner.changeValueBy(delta.toInt())
|
|
setIngredient(panelCountSpinner.value.toInt())
|
|
}
|
|
|
|
private fun updatePanelText(text: String, panelCount: Int) {
|
|
fboText.dispose()
|
|
fboText = FrameBuffer(Pixmap.Format.RGBA8888, panelCount*TILE_SIZE, 2*TILE_SIZE, false)
|
|
fboText.colorBufferTexture.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
|
|
fboCamera.setToOrtho(true, panelCount*TILE_SIZEF, 2*TILE_SIZEF)
|
|
|
|
fboText.inAction(fboCamera, fboBatch) {
|
|
gdxClearAndEnableBlend(Color.CLEAR)
|
|
fboBatch.color = Color.WHITE
|
|
fboBatch.inUse { batch ->
|
|
blendNormalStraightAlpha(batch)
|
|
val tw = App.fontGame.getWidth(text)
|
|
App.fontGame.draw(batch, text, 1 + (it.width - tw) / 2, 2)
|
|
|
|
|
|
blendAlphaMask(batch)
|
|
for (p in 0 until panelCount) {
|
|
batch.draw(signSheet.get(3, 0), TILE_SIZEF * p, 0f)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun drawPanels(batch: SpriteBatch, xStart: Float, yStart: Float, panelCount: Int) {
|
|
blendNormalStraightAlpha(batch)
|
|
|
|
// panels
|
|
batch.color = backdropColour
|
|
for (p in 0 until panelCount) {
|
|
val sprite = signSheet.get(if (p == 0) 0 else if (p == panelCount - 1) 2 else 1, 0)
|
|
batch.draw(sprite, xStart + p * sprite.regionWidth * panelZoom, yStart, sprite.regionWidth * panelZoom, sprite.regionHeight * panelZoom)
|
|
}
|
|
|
|
// text
|
|
batch.draw(fboText.colorBufferTexture, xStart, yStart, fboText.width * panelZoom, fboText.height * panelZoom)
|
|
}
|
|
|
|
private fun setIngredient(num: Int) {
|
|
ingredients.clear()
|
|
ingredients.add(GLASS, num * 2L)
|
|
ingredients.add(ROCK_TILE, num * 1L)
|
|
ingredients.add(COPPER_BULB, num * 1L)
|
|
ingredientsPanel.rebuild(UIItemCatBar.FILTER_CAT_ALL)
|
|
}
|
|
|
|
private fun refreshCraftButtonStatus() {
|
|
val player = getPlayerInventory()
|
|
val canCraft = ingredients.all {
|
|
(player.searchByID(it.itm)?.qty ?: 0L) >= it.qty
|
|
}
|
|
goButton.isEnabled = canCraft
|
|
}
|
|
|
|
private val ingredients = FixtureInventory() // this one is definitely not to be changed
|
|
private val ingredientsPanel = UIItemInventoryItemGrid(
|
|
this,
|
|
{ ingredients },
|
|
drawX,
|
|
row2,
|
|
3, 1,
|
|
drawScrollOnRightside = false,
|
|
drawWallet = false,
|
|
hideSidebar = true,
|
|
colourTheme = UIItemInventoryCellCommonRes.defaultInventoryCellTheme.copy(
|
|
cellHighlightSubCol = Toolkit.Theme.COL_INACTIVE
|
|
),
|
|
keyDownFun = { _, _, _, _, _ -> },
|
|
wheelFun = { _, _, _, _, _, _ -> },
|
|
touchDownFun = { _, _, _, _, _ -> },
|
|
).also {
|
|
it.isCompactMode = true
|
|
}
|
|
|
|
private val panelCountSpinner = UIItemSpinner(
|
|
this,
|
|
inputX + inputWidth - ingredientsWidth + 19,
|
|
row2 - 1,
|
|
2, 2, 32, 1,
|
|
spinnerWidth,
|
|
numberToTextFunction = { "${it.toDouble().roundToInt()}" }
|
|
).also {
|
|
it.selectionChangeListener = { num0 ->
|
|
val num = num0.toInt()
|
|
setIngredient(num)
|
|
refreshCraftButtonStatus()
|
|
}
|
|
}
|
|
|
|
|
|
private val resetButton = UIItemTextButton(this,
|
|
{ Lang["MENU_LABEL_RESET"] }, width / 2 - 24 - goButtonWidth, row3, goButtonWidth, alignment = UIItemTextButton.Companion.Alignment.CENTRE, hasBorder = true).also {
|
|
|
|
it.clickOnceListener = { _, _ ->
|
|
resetUI()
|
|
}
|
|
}
|
|
|
|
private val goButton = UIItemTextButton(this,
|
|
{ Lang["GAME_ACTION_CRAFT"] }, width / 2 + 24, row3, goButtonWidth, alignment = UIItemTextButton.Companion.Alignment.CENTRE, hasBorder = true).also {
|
|
|
|
it.clickOnceListener = { _, _ ->
|
|
val actorInventory = getPlayerInventory()
|
|
val text = textInput.getText()
|
|
val item = ItemTextSignCopper(Item.COPPER_SIGN).makeDynamic(actorInventory).also {
|
|
it.extra["signContent"] = text
|
|
it.extra["signPanelCount"] = panelCount
|
|
it.nameSecondary = "[$panelCount${TIMES}2] $text"
|
|
}
|
|
|
|
actorInventory.add(item)
|
|
|
|
resetUI()
|
|
}
|
|
}
|
|
|
|
private fun resetUI() {
|
|
panelCountSpinner.resetToSmallest()
|
|
textInput.clearText()
|
|
setIngredient(panelCountSpinner.value.toInt())
|
|
refreshCraftButtonStatus()
|
|
}
|
|
|
|
override fun show() {
|
|
super.show()
|
|
tooltipShowing.clear()
|
|
INGAME.setTooltipMessage(null)
|
|
resetUI()
|
|
}
|
|
|
|
init {
|
|
addUIitem(textInput)
|
|
addUIitem(panelCountSpinner)
|
|
addUIitem(ingredientsPanel)
|
|
addUIitem(goButton)
|
|
addUIitem(resetButton)
|
|
}
|
|
|
|
private var panelCount = panelCountSpinner.value.toInt()
|
|
override fun updateImpl(delta: Float) {
|
|
panelCount = panelCountSpinner.value.toInt()
|
|
|
|
uiItems.forEach { it.update(delta) }
|
|
}
|
|
|
|
private val halfSlotOffset = (UIItemInventoryElemSimple.height + UIItemInventoryItemGrid.listGap) / 2
|
|
private val thisOffsetX = UIInventoryFull.INVENTORY_CELLS_OFFSET_X() + UIItemInventoryElemSimple.height + UIItemInventoryItemGrid.listGap - halfSlotOffset
|
|
|
|
private val controlHelp: String
|
|
get() = if (App.environment == RunningEnvironment.PC)
|
|
"${getKeycapPC(ControlPresets.getKey("control_key_inventory"))} ${Lang["GAME_ACTION_CLOSE"]}"
|
|
else
|
|
"${App.gamepadLabelStart} ${Lang["GAME_ACTION_CLOSE"]}"
|
|
|
|
override fun renderImpl(frameDelta: Float, batch: SpriteBatch, camera: OrthographicCamera) {
|
|
UIInventoryFull.drawBackground(batch, opacity)
|
|
|
|
// paint preview
|
|
drawPanels(batch, (width - panelCount * panelZoom * TILE_SIZE).toInt().div(2).toFloat(), height / 4f - 8, panelCount)
|
|
|
|
// paint UI elements
|
|
uiItems.forEach { it.render(frameDelta, batch, camera) }
|
|
|
|
// paint labels
|
|
batch.color = Color.WHITE
|
|
|
|
val controlHintXPos = thisOffsetX + 2f
|
|
blendNormalStraightAlpha(batch)
|
|
App.fontGame.draw(batch, controlHelp, controlHintXPos, UIInventoryFull.yEnd - 20)
|
|
|
|
App.fontGame.draw(batch, Lang["CONTEXT_ENGRAVER_TEXT"], drawX, row0)
|
|
Toolkit.drawTextCentered(batch, App.fontGame, Lang["MENU_OPTIONS_SIZE"], spinnerWidth, panelCountSpinner.posX, row1)
|
|
Toolkit.drawTextCentered(batch, App.fontGame, Lang["GAME_INVENTORY_INGREDIENTS"], ingredientsWidth, ingredientsPanel.posX, row1)
|
|
|
|
}
|
|
|
|
override fun dispose() {
|
|
fboText.tryDispose()
|
|
fboBatch.tryDispose()
|
|
}
|
|
|
|
|
|
override fun doOpening(delta: Float) {
|
|
super.doOpening(delta)
|
|
INGAME.setTooltipMessage(null)
|
|
INGAME.pause()
|
|
}
|
|
|
|
override fun doClosing(delta: Float) {
|
|
super.doClosing(delta)
|
|
INGAME.setTooltipMessage(null)
|
|
INGAME.resume()
|
|
}
|
|
|
|
override fun endOpening(delta: Float) {
|
|
super.endOpening(delta)
|
|
tooltipShowing.clear()
|
|
INGAME.setTooltipMessage(null) // required!
|
|
}
|
|
|
|
override fun endClosing(delta: Float) {
|
|
super.endClosing(delta)
|
|
resetUI()
|
|
tooltipShowing.clear()
|
|
INGAME.setTooltipMessage(null) // required!
|
|
}
|
|
|
|
} |