From d1d75b88ca8465c61bf376d9d3cacc61572b2364 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Mon, 23 Oct 2023 22:25:33 +0900 Subject: [PATCH] export poi to file --- .../terrarum/modulebasegame/BuildingMaker.kt | 126 +++++++++----- .../UIBuildingMakerGetFilename.kt | 155 ++++++++++++++++++ .../terrarum/serialise/PointOfInterest.kt | 6 +- .../terrarum/ui/UIItemTextButtonList.kt | 2 +- src/net/torvald/terrarum/ui/UINSMenu.kt | 6 +- 5 files changed, 251 insertions(+), 44 deletions(-) create mode 100644 src/net/torvald/terrarum/modulebasegame/UIBuildingMakerGetFilename.kt diff --git a/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt b/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt index 0b0ef9ef4..5a9a47f00 100644 --- a/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt +++ b/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt @@ -5,7 +5,6 @@ import com.badlogic.gdx.InputAdapter import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.TextureRegion -import net.torvald.gdx.graphics.Cvec import net.torvald.terrarum.* import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE @@ -32,6 +31,7 @@ import net.torvald.terrarum.weather.WeatherMixer import net.torvald.terrarum.ui.UINSMenu import net.torvald.terrarum.worlddrawer.WorldCamera import net.torvald.util.CircularArray +import java.io.File /** * Created by minjaesong on 2018-07-06. @@ -81,9 +81,13 @@ class BuildingMaker(batch: FlippingSpriteBatch) : IngameInstance(batch) { val uiPalette = UIBuildingMakerBlockChooser(this) val uiPenMenu = UIBuildingMakerPenMenu(this) + val uiGetPoiName = UIBuildingMakerGetFilename() // used for both import and export val uiContainer = UIContainer() + val keyboardUsedByTextInput: Boolean + get() = uiGetPoiName.textInput.isEnabled + private val pensMustShowSelection = arrayOf( PENMODE_MARQUEE, PENMODE_MARQUEE_ERASE ) @@ -254,6 +258,7 @@ class BuildingMaker(batch: FlippingSpriteBatch) : IngameInstance(batch) { uiContainer.add(notifier) uiContainer.add(uiPalette) uiContainer.add(uiPenMenu) + uiContainer.add(uiGetPoiName) @@ -314,7 +319,11 @@ class BuildingMaker(batch: FlippingSpriteBatch) : IngameInstance(batch) { WeatherMixer.update(delta, actorNowPlaying, gameWorld) blockPointingCursor.update(delta) - actorNowPlaying?.update(delta) + + if (!keyboardUsedByTextInput) { + actorNowPlaying?.update(delta) + } + var overwriteMouseOnUI = false uiContainer.forEach { it?.update(delta) @@ -323,7 +332,7 @@ class BuildingMaker(batch: FlippingSpriteBatch) : IngameInstance(batch) { } } - mouseOnUI = (overwriteMouseOnUI || uiPenMenu.isVisible) + mouseOnUI = (overwriteMouseOnUI || uiPenMenu.isVisible || uiPalette.isVisible || uiGetPoiName.isVisible) WorldCamera.update(world, actorNowPlaying) @@ -403,10 +412,37 @@ class BuildingMaker(batch: FlippingSpriteBatch) : IngameInstance(batch) { override fun dispose() { // blockMarkings.dispose() uiPenMenu.dispose() + uiGetPoiName.dispose() musicGovernor.dispose() } - override fun inputStrobed(e: TerrarumKeyboardEvent) { + fun getPoiNameForExport(w: Int, h: Int, callback: (String) -> Unit) { + uiGetPoiName.let { + it.title = "Export" + it.labelDo = "Export" + it.text = listOf("WH: $w\u00D7$h", "Name of the POI:") + it.confirmCallback = callback + it.setPosition( + 240, + 32 + ) + it.reset() + it.setAsOpen() + } + } + + fun getPoiNameForImport(callback: (String) -> Unit) { + uiGetPoiName.let { + it.title = "Import" + it.labelDo = "Import" + it.text = listOf("Name of the POI:") + it.confirmCallback = callback + it.setPosition( + 240, + 32 + ) + it.setAsOpen() + } } private fun makePenWork(x: Int, y: Int) { @@ -486,6 +522,12 @@ class BuildingMaker(batch: FlippingSpriteBatch) : IngameInstance(batch) { fos.write(FILE_FOOTER) fos.close() }*/ + + override fun inputStrobed(e: TerrarumKeyboardEvent) { + uiContainer.forEach { + it?.inputStrobed(e) + } + } } class BuildingMakerController(val screen: BuildingMaker) : InputAdapter() { @@ -676,7 +718,7 @@ class YamlCommandToolMarqueeErase : YamlInvokable { class YamlCommandToolMarqueeClear : YamlInvokable { override fun invoke(args: Array) { (args[0] as BuildingMaker).selection.toList().forEach { - val (x, y) = (it % 4294967296L).toInt() to (it / 4294967296).toInt() + val (x, y) = (it % 4294967296).toInt() to (it / 4294967296).toInt() (args[0] as BuildingMaker).removeBlockMarker(x, y) } } @@ -703,9 +745,7 @@ class YamlCommandToolExportTest : YamlInvokable { var maxX = -1 var maxY = -1 ui.selection.forEach { - val (x, y) = (it % 4294967296L).toInt() to (it / 4294967296).toInt() - - printdbg(this, "Selection: ($x,$y)") + val (x, y) = (it % 4294967296).toInt() to (it / 4294967296).toInt() if (x < minX) minX = x if (y < minY) minY = y @@ -715,48 +755,60 @@ class YamlCommandToolExportTest : YamlInvokable { marked.add(it) } - printdbg(this, "POI Area: ($minX,$minY)..($maxX,$maxY), WH=(${maxX - minX},${maxY - minY})") + ui.getPoiNameForExport(maxX - minX + 1, maxY - minY + 1) { name -> + // prepare POI + val poi = PointOfInterest( + name, + maxX - minX + 1, + maxY - minY + 1, + ui.world.tileNumberToNameMap, + ui.world.tileNameToNumberMap + ) + val layer = POILayer(name) + val terr = BlockLayerI16(poi.w, poi.h) + val wall = BlockLayerI16(poi.w, poi.h) + layer.blockLayer = arrayListOf(terr, wall) + poi.layers.add(layer) - var name = "test" - - // prepare POI - val poi = PointOfInterest(name, maxX - minX + 1, maxY - minY + 1, ui.world.tileNumberToNameMap, ui.world.tileNameToNumberMap) - val layer = POILayer(name) - val terr = BlockLayerI16(poi.w, poi.h) - val wall = BlockLayerI16(poi.w, poi.h) - layer.blockLayer = arrayListOf(terr, wall) - poi.layers.add(layer) - - for (x in minX..maxX) { - for (y in minY..maxY) { - if (isMarked(x, y)) { - terr.unsafeSetTile(x - minX, y - minY, ui.world.getTileFromTerrainRaw(x, y)) - wall.unsafeSetTile(x - minX, y - minY, ui.world.getTileFromWallRaw(x, y)) - } - else { - terr.unsafeSetTile(x - minX, y - minY, -1) - wall.unsafeSetTile(x - minX, y - minY, -1) + for (x in minX..maxX) { + for (y in minY..maxY) { + if (isMarked(x, y)) { + terr.unsafeSetTile(x - minX, y - minY, ui.world.getTileFromTerrainRaw(x, y)) + wall.unsafeSetTile(x - minX, y - minY, ui.world.getTileFromWallRaw(x, y)) + } + else { + terr.unsafeSetTile(x - minX, y - minY, -1) + wall.unsafeSetTile(x - minX, y - minY, -1) + } } } + + + // process POI for export + val json = Common.jsoner + val jsonStr = json.toJson(poi) + + + val dir = App.defaultDir + "/Exports/" + val dirAsFile = File(dir) + if (!dirAsFile.exists()) { + dirAsFile.mkdir() + } + + File(dirAsFile, "$name.poi").writeText(jsonStr) } - - - // process POI for export - val json = Common.jsoner - val jsonStr = json.toJson(poi) - printdbg(this, "Json:\n$jsonStr") } } private fun Point2i.toAddr() = toAddr(this.x, this.y) -private fun toAddr(x: Int, y: Int) = (x.toLong().shl(32) or y.toLong().and(0xFFFFFFFFL)) +private fun toAddr(x: Int, y: Int) = (y.toLong().shl(32) or x.toLong().and(0xFFFFFFFFL)) class YamlCommandClearSelection : YamlInvokable { override fun invoke(args: Array) { val ui = (args[0] as BuildingMaker) try { - (ui.selection.clone() as ArrayList).forEach { (x, y) -> - ui.removeBlockMarker(x, y) + (ui.selection.clone() as ArrayList).forEach { i -> + ui.removeBlockMarker((i % 4294967296).toInt(), (i / 4294967296).toInt()) } } catch (e: NullPointerException) {} diff --git a/src/net/torvald/terrarum/modulebasegame/UIBuildingMakerGetFilename.kt b/src/net/torvald/terrarum/modulebasegame/UIBuildingMakerGetFilename.kt new file mode 100644 index 000000000..bb668559c --- /dev/null +++ b/src/net/torvald/terrarum/modulebasegame/UIBuildingMakerGetFilename.kt @@ -0,0 +1,155 @@ +package net.torvald.terrarum.modulebasegame + +import com.badlogic.gdx.graphics.Color +import com.badlogic.gdx.graphics.OrthographicCamera +import com.badlogic.gdx.graphics.g2d.SpriteBatch +import net.torvald.terrarum.* +import net.torvald.terrarum.ui.* +import net.torvald.terrarum.ui.UIItemTextButtonList.Companion.DEFAULT_BACKGROUNDCOL +import net.torvald.terrarum.ui.UINSMenu.Companion.LINE_HEIGHT +import kotlin.math.roundToInt + +class UIBuildingMakerGetFilename : UICanvas() { + + var confirmCallback: (String) -> Unit = {} + var title = "Export" + var text = listOf("") + + var labelDo = "OK" + var labelDont = "Cancel" + + override var width = 280 + override var height = 160 + + private val textWidth = width - LINE_HEIGHT + private val buttonWidth = 101 + private val buttonGap = (width - buttonWidth*2) / 3 + + override var openCloseTime = OPENCLOSE_GENERIC + + val textInput = UIItemTextLineInput( + this, + (width - textWidth) / 2, + LINE_HEIGHT * (text.size + 2), + textWidth, + { "The Yucky Panopticon" }, + InputLenCap(250, InputLenCap.CharLenUnit.UTF8_BYTES) + ) + + val buttonOk = UIItemTextButton( + this, + { labelDo }, + buttonGap, + height - LINE_HEIGHT - LINE_HEIGHT/2, + buttonWidth + ).also { + it.clickOnceListener = { _, _ -> + + textInput.getTextOrPlaceholder().let { name -> + if (name.isNotBlank()) + confirmCallback(name.trim()) + } + + this.setAsClose() + } + } + + val buttonCancel = UIItemTextButton( + this, + { labelDont }, + width - buttonWidth - buttonGap, + height - LINE_HEIGHT - LINE_HEIGHT/2, + buttonWidth + ).also { + it.clickOnceListener = { _, _ -> + reset() + this.setAsClose() + } + } + + fun reset() { + textInput.clearText() + } + + init { + addUIitem(textInput) + addUIitem(buttonOk) + addUIitem(buttonCancel) + } + + override fun updateUI(delta: Float) { + uiItems.forEach { it.update(delta) } + } + + + override fun renderUI(batch: SpriteBatch, camera: OrthographicCamera) { + blendNormalStraightAlpha(batch) + + // draw border + batch.color = Toolkit.Theme.COL_INACTIVE + Toolkit.drawBoxBorder(batch, -1, -1 - LINE_HEIGHT, width + 2, height + LINE_HEIGHT + 2) + + // draw title bar + batch.color = UINSMenu.DEFAULT_TITLEBACKCOL + Toolkit.fillArea(batch, 0, 0 - LINE_HEIGHT, width, LINE_HEIGHT) + + batch.color = UINSMenu.DEFAULT_TITLETEXTCOL + App.fontGame.draw(batch, title, UINSMenu.TEXT_OFFSETX + 0, UINSMenu.TEXT_OFFSETY + 0 - LINE_HEIGHT) + + // draw the back + batch.color = DEFAULT_BACKGROUNDCOL + Toolkit.fillArea(batch, 0, 0, width, height) + + + // draw the list + batch.color = Color.WHITE + val textWidth: Int = text.maxOf { App.fontGame.getWidth(it) } + + text.forEachIndexed { index, str -> + App.fontGame.draw(batch, str, 0 + LINE_HEIGHT / 2, 0 + LINE_HEIGHT / 2 + LINE_HEIGHT * index) + } + + uiItems.forEach { it.render(batch, camera) } + } + + private var dragOriginX = 0 // relative mousepos + private var dragOriginY = 0 // relative mousepos + private var dragForReal = false + + override fun touchDragged(screenX: Int, screenY: Int, pointer: Int): Boolean { + if (mouseInScreen(screenX, screenY)) { + if (dragForReal) { + handler.setPosition( + (screenX / App.scr.magn - dragOriginX).roundToInt(), + (screenY / App.scr.magn - dragOriginY).roundToInt() + ) + } + } + + uiItems.forEach { it.touchDragged(screenX, screenY, pointer) } + + return true + } + + fun mouseOnTitleBar() = + relativeMouseX in 0 until width && relativeMouseY in -LINE_HEIGHT until 0 + + override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean { + if (mouseOnTitleBar()) { + dragOriginX = relativeMouseX + dragOriginY = relativeMouseY + dragForReal = true + } + else { + dragForReal = false + } + + uiItems.forEach { it.touchDown(screenX, screenY, pointer, button) } + + return true + } + + override fun dispose() { + uiItems.forEach { it.tryDispose() } + } +} diff --git a/src/net/torvald/terrarum/serialise/PointOfInterest.kt b/src/net/torvald/terrarum/serialise/PointOfInterest.kt index ab3bbaf38..6d704d949 100644 --- a/src/net/torvald/terrarum/serialise/PointOfInterest.kt +++ b/src/net/torvald/terrarum/serialise/PointOfInterest.kt @@ -58,9 +58,9 @@ class PointOfInterest( - printdbg(this, "unique tiles: ${tileSymbolToItemId.size}") - printdbg(this, "tileSymbolToItemId=$tileSymbolToItemId") - printdbg(this, "itemIDtoTileSym=$itemIDtoTileSym") +// printdbg(this, "unique tiles: ${tileSymbolToItemId.size}") +// printdbg(this, "tileSymbolToItemId=$tileSymbolToItemId") +// printdbg(this, "itemIDtoTileSym=$itemIDtoTileSym") diff --git a/src/net/torvald/terrarum/ui/UIItemTextButtonList.kt b/src/net/torvald/terrarum/ui/UIItemTextButtonList.kt index 4fe7c3d70..22ce89500 100644 --- a/src/net/torvald/terrarum/ui/UIItemTextButtonList.kt +++ b/src/net/torvald/terrarum/ui/UIItemTextButtonList.kt @@ -240,7 +240,7 @@ class UIItemTextButtonList( batch.color = backgroundCol blendNormalStraightAlpha(batch) - Toolkit.fillArea(batch, posX.toFloat(), posY.toFloat(), width.toFloat(), height.toFloat()) + Toolkit.fillArea(batch, posX, posY, width, height) buttons.forEach { it.render(batch, camera) } diff --git a/src/net/torvald/terrarum/ui/UINSMenu.kt b/src/net/torvald/terrarum/ui/UINSMenu.kt index b427b43df..0855400e4 100644 --- a/src/net/torvald/terrarum/ui/UINSMenu.kt +++ b/src/net/torvald/terrarum/ui/UINSMenu.kt @@ -30,12 +30,12 @@ class UINSMenu( companion object { val DEFAULT_TITLEBACKCOL = Color(0f, 0f, 0f, .77f) val DEFAULT_TITLETEXTCOL = Color.WHITE + val LINE_HEIGHT = 24 + val TEXT_OFFSETX = 3f + val TEXT_OFFSETY = (LINE_HEIGHT - App.fontGame.lineHeight) / 2f } override var openCloseTime: Second = 0f - val LINE_HEIGHT = 24 - val TEXT_OFFSETX = 3f - val TEXT_OFFSETY = (LINE_HEIGHT - App.fontGame.lineHeight) / 2f val CHILD_ARROW = "${0x2023.toChar()}"