mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-09 18:14:06 +09:00
redeem code input wip
This commit is contained in:
BIN
assets/graphics/code_input_cells.tga
LFS
Normal file
BIN
assets/graphics/code_input_cells.tga
LFS
Normal file
Binary file not shown.
@@ -1044,7 +1044,7 @@ fun distBetween(a: ActorWithBody, bpos: Vector2): Double {
|
|||||||
val dist = min(min(bpos.distanceSquared(apos1), bpos.distanceSquared(apos2)), bpos.distanceSquared(apos3))
|
val dist = min(min(bpos.distanceSquared(apos1), bpos.distanceSquared(apos2)), bpos.distanceSquared(apos3))
|
||||||
return dist.sqrt()
|
return dist.sqrt()
|
||||||
}
|
}
|
||||||
const val hashStrMap = "YBNDRFG8EJKMCPQXOTLVWIS2A345H769"
|
const val hashStrMap = "YBNDRFGWEJKMCPQXOTLVUIS2A345H769"
|
||||||
fun getHashStr(length: Int = 5) = (0 until length).map { hashStrMap[Math.random().times(32).toInt()] }.joinToString("")
|
fun getHashStr(length: Int = 5) = (0 until length).map { hashStrMap[Math.random().times(32).toInt()] }.joinToString("")
|
||||||
|
|
||||||
fun <S, T> List<S>.cartesianProduct(other: List<T>) = this.flatMap { thisIt ->
|
fun <S, T> List<S>.cartesianProduct(other: List<T>) = this.flatMap { thisIt ->
|
||||||
|
|||||||
133
src/net/torvald/terrarum/ui/UIItemRedeemCodeArea.kt
Normal file
133
src/net/torvald/terrarum/ui/UIItemRedeemCodeArea.kt
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
package net.torvald.terrarum.ui
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx
|
||||||
|
import com.badlogic.gdx.graphics.Color
|
||||||
|
import com.badlogic.gdx.graphics.OrthographicCamera
|
||||||
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
|
import net.torvald.terrarum.CommonResourcePool
|
||||||
|
import net.torvald.terrarum.imagefont.BigAlphNum
|
||||||
|
import net.torvald.terrarum.utils.PasswordBase32
|
||||||
|
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 2025-01-15.
|
||||||
|
*/
|
||||||
|
class UIItemRedeemCodeArea(
|
||||||
|
parentUI: UICanvas,
|
||||||
|
initialX: Int,
|
||||||
|
initialY: Int,
|
||||||
|
val textCols: Int,
|
||||||
|
val textRows: Int,
|
||||||
|
|
||||||
|
) : UIItem(parentUI, initialX, initialY) {
|
||||||
|
|
||||||
|
private val CELL_W = 16
|
||||||
|
private val CELL_H = 22
|
||||||
|
|
||||||
|
override val width = textCols * CELL_W
|
||||||
|
override val height = textRows * CELL_H
|
||||||
|
|
||||||
|
init {
|
||||||
|
CommonResourcePool.addToLoadingList("spritesheet:terrarum_redeem_code_form") {
|
||||||
|
TextureRegionPack(Gdx.files.internal("assets/graphics/code_input_cells.tga"), CELL_W, CELL_H)
|
||||||
|
}
|
||||||
|
CommonResourcePool.loadAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
private var inputFormTiles = CommonResourcePool.getAsTextureRegionPack("spritesheet:terrarum_redeem_code_form")
|
||||||
|
|
||||||
|
|
||||||
|
private val inputText = StringBuilder(textCols * textRows)
|
||||||
|
private var textCaret = 0
|
||||||
|
fun clearInput() { inputText.clear(); textCaret = 0 }
|
||||||
|
fun acceptChar(char: Char): Boolean {
|
||||||
|
if (textCaret in 0 until textCols * textRows) {
|
||||||
|
inputText.insert(textCaret, char)
|
||||||
|
textCaret++
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
else return false
|
||||||
|
}
|
||||||
|
fun backspace(): Boolean {
|
||||||
|
if (textCaret in 1 until textCols * textRows) {
|
||||||
|
inputText.deleteCharAt(textCaret - 1)
|
||||||
|
textCaret--
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
else return false
|
||||||
|
}
|
||||||
|
fun reverseBackspace(): Boolean {
|
||||||
|
if (textCaret in 0 until (textCols * textRows - 1)) {
|
||||||
|
inputText.deleteCharAt(textCaret)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
else return false
|
||||||
|
}
|
||||||
|
fun __moveCursorBackward(delta: Int = 1) {
|
||||||
|
textCaret = (textCaret - 1).coerceIn(0, textCols * textRows)
|
||||||
|
}
|
||||||
|
fun __moveCursorForward(delta: Int = 1) {
|
||||||
|
textCaret = (textCaret + 1).coerceIn(0, textCols * textRows)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getInputAsString() = inputText.toString()
|
||||||
|
fun getInputAsBinary(codebook: RedeemCodebook) = codebook.toBinary(inputText.toString())
|
||||||
|
|
||||||
|
private val caretCol = Toolkit.Theme.COL_SELECTED
|
||||||
|
|
||||||
|
override fun render(frameDelta: Float, batch: SpriteBatch, camera: OrthographicCamera) {
|
||||||
|
super.render(frameDelta, batch, camera)
|
||||||
|
|
||||||
|
val lineCol = if (isActive) Toolkit.Theme.COL_MOUSE_UP else Toolkit.Theme.COL_INACTIVE
|
||||||
|
|
||||||
|
// draw border
|
||||||
|
batch.color = lineCol
|
||||||
|
Toolkit.drawBoxBorder(batch, posX, posY, width, height)
|
||||||
|
|
||||||
|
// draw cells
|
||||||
|
for (y in 0 until textRows) {
|
||||||
|
for (x in 0 until textCols) {
|
||||||
|
batch.draw(inputFormTiles.get(if (x == 0) 0 else if (x == textCols - 1) 2 else 1, 0),
|
||||||
|
posX.toFloat() + CELL_W * x, posY.toFloat() + CELL_H * y
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw texts
|
||||||
|
batch.color = Color.WHITE
|
||||||
|
for (y in 0 until textRows) {
|
||||||
|
for (x in 0 until textCols) {
|
||||||
|
BigAlphNum.draw(
|
||||||
|
batch,
|
||||||
|
"${inputText[y * textRows + x]}",
|
||||||
|
posX + CELL_W * x + 2f,
|
||||||
|
posY + CELL_H * y + 3f
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw caret
|
||||||
|
batch.color = caretCol
|
||||||
|
val cx = textCaret % textCols
|
||||||
|
val cy = textCaret / textCols
|
||||||
|
Toolkit.drawStraightLine(batch,
|
||||||
|
posX + CELL_W * cx - 1,
|
||||||
|
posY + CELL_H * cy + 1,
|
||||||
|
posY + CELL_H * cy + 1 + 20, 2, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dispose() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RedeemCodebook {
|
||||||
|
fun toBinary(inputString: String): ByteArray
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
object Base32RedeemCodebook : RedeemCodebook {
|
||||||
|
override fun toBinary(inputString: String): ByteArray {
|
||||||
|
return PasswordBase32.decode(inputString, inputString.length)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@ import kotlin.experimental.xor
|
|||||||
object PasswordBase32 {
|
object PasswordBase32 {
|
||||||
|
|
||||||
private val si = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567="
|
private val si = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567="
|
||||||
private val so = "YBNDRFG8EJKMCPQXOTLVUIS2A345H769 "
|
private val so = "YBNDRFGWEJKMCPQXOTLVUIS2A345H769 "
|
||||||
|
|
||||||
private val standardToModified = HashMap<Char, Char>(32)
|
private val standardToModified = HashMap<Char, Char>(32)
|
||||||
private val modifiedToStandard = HashMap<Char, Char>(32)
|
private val modifiedToStandard = HashMap<Char, Char>(32)
|
||||||
@@ -26,6 +26,7 @@ object PasswordBase32 {
|
|||||||
modifiedToStandard['0'] = modifiedToStandard['O']!!
|
modifiedToStandard['0'] = modifiedToStandard['O']!!
|
||||||
modifiedToStandard['1'] = modifiedToStandard['I']!!
|
modifiedToStandard['1'] = modifiedToStandard['I']!!
|
||||||
modifiedToStandard['Z'] = modifiedToStandard['2']!!
|
modifiedToStandard['Z'] = modifiedToStandard['2']!!
|
||||||
|
modifiedToStandard['8'] = modifiedToStandard['B']!!
|
||||||
}
|
}
|
||||||
|
|
||||||
private val nullPw = byteArrayOf(0.toByte())
|
private val nullPw = byteArrayOf(0.toByte())
|
||||||
|
|||||||
Reference in New Issue
Block a user