diff --git a/src/net/torvald/terrarum/IngameInstance.kt b/src/net/torvald/terrarum/IngameInstance.kt index 58464f918..359aadfa9 100644 --- a/src/net/torvald/terrarum/IngameInstance.kt +++ b/src/net/torvald/terrarum/IngameInstance.kt @@ -22,6 +22,7 @@ import net.torvald.terrarum.modulebasegame.ui.UITooltip import net.torvald.terrarum.realestate.LandUtil import net.torvald.terrarum.savegame.VirtualDisk import net.torvald.terrarum.ui.ConsoleWindow +import net.torvald.terrarum.ui.Toolkit import net.torvald.util.CircularArray import net.torvald.util.SortedArrayList import org.khelekore.prtree.* @@ -90,7 +91,7 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo init { consoleHandler.setPosition(0, 0) notifier.setPosition( - (App.scr.width - notifier.width) / 2, + (Toolkit.drawWidth - notifier.width) / 2, App.scr.height - notifier.height - App.scr.tvSafeGraphicsHeight ) diff --git a/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt b/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt index a2765dca2..b89d01ffd 100644 --- a/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt +++ b/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt @@ -7,6 +7,7 @@ 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 import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.blockproperties.BlockPropUtil @@ -16,6 +17,8 @@ import net.torvald.terrarum.gameitems.ItemID import net.torvald.terrarum.gameparticles.ParticleBase import net.torvald.terrarum.gameworld.BlockLayerI16 import net.torvald.terrarum.gameworld.GameWorld +import net.torvald.terrarum.gameworld.GameWorld.Companion.TERRAIN +import net.torvald.terrarum.gameworld.GameWorld.Companion.WALL import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid import net.torvald.terrarum.gameworld.WorldTime import net.torvald.terrarum.modulebasegame.ui.UIBuildingMakerBlockChooser @@ -24,6 +27,7 @@ import net.torvald.terrarum.modulebasegame.ui.UIPaletteSelector import net.torvald.terrarum.serialise.Common import net.torvald.terrarum.serialise.PointOfInterest import net.torvald.terrarum.serialise.POILayer +import net.torvald.terrarum.ui.Toolkit import net.torvald.terrarum.weather.WeatherMixer import net.torvald.terrarum.ui.UINSMenu import net.torvald.terrarum.worlddrawer.WorldCamera @@ -62,6 +66,8 @@ class BuildingMaker(batch: FlippingSpriteBatch) : IngameInstance(batch) { val gameWorld = GameWorld(90*12, 90*4, timeNow, timeNow) + override val musicGovernor = TerrarumMusicGovernor() + init { // ghetto world for building @@ -286,7 +292,9 @@ class BuildingMaker(batch: FlippingSpriteBatch) : IngameInstance(batch) { uiPaletteSelector.isVisible = true notifier.setPosition( - (App.scr.width - notifier.width) / 2, App.scr.height - notifier.height) + (Toolkit.drawWidth - notifier.width) / 2, + App.scr.height - notifier.height - App.scr.tvSafeGraphicsHeight + ) actorNowPlaying?.setPosition(512 * 16.0, 149 * 16.0) @@ -376,6 +384,9 @@ class BuildingMaker(batch: FlippingSpriteBatch) : IngameInstance(batch) { BlockPropUtil.dynamicLumFuncTickClock() + + + musicGovernor.update(this, delta) } private val particles = CircularArray(16, true) @@ -399,9 +410,13 @@ class BuildingMaker(batch: FlippingSpriteBatch) : IngameInstance(batch) { override fun resize(width: Int, height: Int) { IngameRenderer.resize(App.scr.width, App.scr.height) + val drawWidth = Toolkit.drawWidth + uiToolbox.setPosition(0, 0) notifier.setPosition( - (App.scr.width - notifier.width) / 2, App.scr.height - notifier.height) + (Toolkit.drawWidth - notifier.width) / 2, + App.scr.height - notifier.height - App.scr.tvSafeGraphicsHeight + ) println("[BuildingMaker] Resize event") } @@ -415,6 +430,7 @@ class BuildingMaker(batch: FlippingSpriteBatch) : IngameInstance(batch) { override fun dispose() { // blockMarkings.dispose() uiPenMenu.dispose() + musicGovernor.dispose() } override fun inputStrobed(e: TerrarumKeyboardEvent) { @@ -705,10 +721,57 @@ class YamlCommandToolToggleMarqueeOverlay : YamlInvokable { class YamlCommandToolExportTest : YamlInvokable { override fun invoke(args: Array) { - val a = PointOfInterest("test", 10, 10) - val dat = BlockLayerI16(10, 10) - a.layers.add(POILayer("layerr1").also { it.blockLayer.add(BlockLayerI16(10, 10)) }) - a.layers.add(POILayer("layerr2").also { it.blockLayer.add(BlockLayerI16(10, 10)) }) - println(Common.jsoner.toJson(a)) + val ui = (args[0] as BuildingMaker) + if (ui.selection.isEmpty()) return + + val marked = HashSet() + fun isMarked(x: Int, y: Int) = marked.contains(toAddr(x, y)) + + + // get the bounding box + var minX = 2147483647 + var minY = 2147483647 + var maxX = -1 + var maxY = -1 + ui.selection.forEach { + if (it.x < minX) minX = it.x + if (it.y < minY) minY = it.y + if (it.x > maxX) maxX = it.x + if (it.y > maxY) maxY = it.y + + marked.add(it.toAddr()) + } + + var name = "test" + + // prepare POI + val poi = PointOfInterest(name, maxX - minX + 1, maxY - minY + 1, ui.world.tileNumberToNameMap) + 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[0] = 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) + } + } + } + + + // process POI for export + val json = Common.jsoner + val jsonStr = json.toJson(poi) + printdbg(this, "Json:\n$jsonStr") } -} \ No newline at end of file +} + +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)) diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index fcab3bc4b..d5bcf6afd 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -1477,7 +1477,9 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) { // resize UIs notifier.setPosition( - (drawWidth - notifier.width) / 2, App.scr.height - notifier.height) + (Toolkit.drawWidth - notifier.width) / 2, + App.scr.height - notifier.height - App.scr.tvSafeGraphicsHeight + ) uiQuickBar.setPosition((drawWidth - uiQuickBar.width) / 2, App.scr.tvSafeGraphicsHeight) // inventory diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumMusicGovernor.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumMusicGovernor.kt index 1fcefb39f..476164730 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumMusicGovernor.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumMusicGovernor.kt @@ -82,7 +82,7 @@ class TerrarumMusicGovernor : MusicGovernor() { return } - val ingame = ingame as TerrarumIngame +// val ingame = ingame as TerrarumIngame if (state == 0) state = 2 diff --git a/src/net/torvald/terrarum/serialise/PointOfInterest.kt b/src/net/torvald/terrarum/serialise/PointOfInterest.kt index 21f3e9285..2e95942de 100644 --- a/src/net/torvald/terrarum/serialise/PointOfInterest.kt +++ b/src/net/torvald/terrarum/serialise/PointOfInterest.kt @@ -2,7 +2,9 @@ package net.torvald.terrarum.serialise import com.badlogic.gdx.utils.Json import com.badlogic.gdx.utils.JsonValue +import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.TerrarumAppConfiguration +import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.gameitems.ItemID import net.torvald.terrarum.gameworld.BlockLayerI16 import net.torvald.terrarum.gameworld.GameWorld @@ -15,26 +17,49 @@ import net.torvald.terrarum.utils.HashArray class PointOfInterest( identifier: String, width: Int, - height: Int + height: Int, + tileNumberToNameMap0: HashArray ) : Json.Serializable { - constructor() : this("undefined", 0,0) + constructor() : this("undefined", 0,0, HashArray()) @Transient val w = width @Transient val h = height @Transient val layers = ArrayList() @Transient val id = identifier + @Transient val tileNumberToNameMap: HashArray = tileNumberToNameMap0 + + override fun write(json: Json) { val tileSymbolToItemId = HashArray() // exported - val tilenumToItemID = HashMap() // not exported - // TODO populate above vars. Block.NULL is always integer -1 + val uniqueTiles = ArrayList(layers.flatMap { it.getUniqueTiles() }.toSet().toList().sorted()) + // swap if non-air tile is occupying the index 0 + if (tileNumberToNameMap[uniqueTiles[0].toLong()] != Block.AIR) { + val otherTileIndex = uniqueTiles.linearSearchBy { tileNumberToNameMap[it.toLong()] == Block.AIR }!! + val t = uniqueTiles[otherTileIndex] + uniqueTiles[otherTileIndex] = uniqueTiles[0] + uniqueTiles[0] = t + } + + // build tileSymbolToItemId + uniqueTiles.forEachIndexed { index, tilenum -> + tileSymbolToItemId[index.toLong()] = tileNumberToNameMap[tilenum.toLong()]!! + } + tileSymbolToItemId[-1] = Block.NULL val itemIDtoTileSym = tileSymbolToItemId.map { it.value to it.key }.toMap() val wordSize = if (tileSymbolToItemId.size >= 255) 16 else 8 - layers.forEach { it.getReadyForSerialisation(tilenumToItemID, itemIDtoTileSym, wordSize / 8) } + + + + printdbg(this, "lut=$tileSymbolToItemId") + + + + layers.forEach { it.getReadyForSerialisation(tileNumberToNameMap, itemIDtoTileSym, wordSize / 8) } json.setTypeName(null) json.writeValue("genver", TerrarumAppConfiguration.VERSION_RAW) @@ -75,6 +100,9 @@ class POILayer( @Transient internal lateinit var blockLayer: ArrayList @Transient internal lateinit var dat: Array + /** + * @return list of unique tiles, in the form of TileNums + */ fun getUniqueTiles(): List { return blockLayer.flatMap { layer -> (0 until layer.height * layer.width).map { layer.unsafeGetTile(it % layer.width, it / layer.width) } @@ -90,14 +118,19 @@ class POILayer( * `tilenumToItemID[-1]` should return `Block.NULL` * `itemIDtoTileSym[Block.NULL]` should return -1, so that it would return 0xFF on any length of the word */ - fun getReadyForSerialisation(tilenumToItemID: Map, itemIDtoTileSym: Map, byteLength: Int) { + fun getReadyForSerialisation(tilenumToItemID: HashArray, itemIDtoTileSym: Map, byteLength: Int) { dat = blockLayer.map { layer -> ByteArray(layer.width * layer.height * byteLength) { i -> if (byteLength == 1) { - itemIDtoTileSym[tilenumToItemID[layer.unsafeGetTile(i % layer.width, i / layer.width)]!!]!!.toByte() + val tilenum = layer.unsafeGetTile(i % layer.width, i / layer.width).toLong() + val itemID = if (tilenum == 255L) Block.NULL else tilenumToItemID[tilenum]!! + val tileSym = itemIDtoTileSym[itemID]!! + tileSym.toByte() } else if (byteLength == 2) { - val tileSym = itemIDtoTileSym[tilenumToItemID[layer.unsafeGetTile((i/2) % layer.width, (i/2) / layer.width)]!!]!! + val tilenum = layer.unsafeGetTile((i/2) % layer.width, (i/2) / layer.width).toLong() + val itemID = if (tilenum == 65535L) Block.NULL else tilenumToItemID[tilenum]!! + val tileSym = itemIDtoTileSym[itemID]!! if (i % 2 == 0) tileSym.and(255).toByte() else tileSym.ushr(8).and(255).toByte() } else throw IllegalArgumentException()