mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-14 04:24:05 +09:00
poi wip
This commit is contained in:
@@ -14,12 +14,16 @@ import net.torvald.terrarum.gameactors.*
|
|||||||
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
|
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
|
||||||
import net.torvald.terrarum.gameitems.ItemID
|
import net.torvald.terrarum.gameitems.ItemID
|
||||||
import net.torvald.terrarum.gameparticles.ParticleBase
|
import net.torvald.terrarum.gameparticles.ParticleBase
|
||||||
|
import net.torvald.terrarum.gameworld.BlockLayerI16
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
|
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
|
||||||
import net.torvald.terrarum.gameworld.WorldTime
|
import net.torvald.terrarum.gameworld.WorldTime
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIBuildingMakerBlockChooser
|
import net.torvald.terrarum.modulebasegame.ui.UIBuildingMakerBlockChooser
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIBuildingMakerPenMenu
|
import net.torvald.terrarum.modulebasegame.ui.UIBuildingMakerPenMenu
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIPaletteSelector
|
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.weather.WeatherMixer
|
import net.torvald.terrarum.weather.WeatherMixer
|
||||||
import net.torvald.terrarum.ui.UINSMenu
|
import net.torvald.terrarum.ui.UINSMenu
|
||||||
import net.torvald.terrarum.worlddrawer.WorldCamera
|
import net.torvald.terrarum.worlddrawer.WorldCamera
|
||||||
@@ -34,7 +38,7 @@ class BuildingMaker(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
|||||||
- File
|
- File
|
||||||
- New Flat ter.
|
- New Flat ter.
|
||||||
- New Rand. ter.
|
- New Rand. ter.
|
||||||
- Export…
|
- Export… : net.torvald.terrarum.modulebasegame.YamlCommandToolExportTest
|
||||||
- Import…
|
- Import…
|
||||||
- Save World…
|
- Save World…
|
||||||
- Load World…
|
- Load World…
|
||||||
@@ -698,3 +702,13 @@ class YamlCommandToolToggleMarqueeOverlay : YamlInvokable {
|
|||||||
(args[0] as BuildingMaker).showSelection = !(args[0] as BuildingMaker).showSelection
|
(args[0] as BuildingMaker).showSelection = !(args[0] as BuildingMaker).showSelection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class YamlCommandToolExportTest : YamlInvokable {
|
||||||
|
override fun invoke(args: Array<Any>) {
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
}
|
||||||
119
src/net/torvald/terrarum/serialise/PointOfInterest.kt
Normal file
119
src/net/torvald/terrarum/serialise/PointOfInterest.kt
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
package net.torvald.terrarum.serialise
|
||||||
|
|
||||||
|
import com.badlogic.gdx.utils.Json
|
||||||
|
import com.badlogic.gdx.utils.JsonValue
|
||||||
|
import net.torvald.terrarum.TerrarumAppConfiguration
|
||||||
|
import net.torvald.terrarum.gameitems.ItemID
|
||||||
|
import net.torvald.terrarum.gameworld.BlockLayerI16
|
||||||
|
import net.torvald.terrarum.utils.HashArray
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 2023-10-17.
|
||||||
|
*/
|
||||||
|
class PointOfInterest(
|
||||||
|
identifier: String,
|
||||||
|
width: Int,
|
||||||
|
height: Int
|
||||||
|
) : Json.Serializable {
|
||||||
|
|
||||||
|
constructor() : this("undefined", 0,0)
|
||||||
|
|
||||||
|
@Transient val w = width
|
||||||
|
@Transient val h = height
|
||||||
|
@Transient val layers = ArrayList<POILayer>()
|
||||||
|
@Transient val id = identifier
|
||||||
|
|
||||||
|
override fun write(json: Json) {
|
||||||
|
val tileSymbolToItemId = HashArray<ItemID>() // exported
|
||||||
|
val tilenumToItemID = HashMap<Int, ItemID>() // not exported
|
||||||
|
|
||||||
|
// TODO populate above vars. Block.NULL is always integer -1
|
||||||
|
|
||||||
|
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) }
|
||||||
|
|
||||||
|
json.setTypeName(null)
|
||||||
|
json.writeValue("genver", TerrarumAppConfiguration.VERSION_RAW)
|
||||||
|
json.writeValue("id", id)
|
||||||
|
json.writeValue("wlen", wordSize)
|
||||||
|
json.writeValue("w", w)
|
||||||
|
json.writeValue("h", h)
|
||||||
|
json.writeValue("lut", tileSymbolToItemId)
|
||||||
|
json.writeValue("layers", layers)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun read(json: Json, jsonData: JsonValue) {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class POILayer(
|
||||||
|
name: String
|
||||||
|
) : Json.Serializable {
|
||||||
|
constructor() : this("undefined")
|
||||||
|
|
||||||
|
@Transient val name = name
|
||||||
|
@Transient val blockLayer = ArrayList<BlockLayerI16>()
|
||||||
|
@Transient private lateinit var dat: Array<ByteArray>
|
||||||
|
|
||||||
|
fun getUniqueTiles(): List<Int> {
|
||||||
|
return blockLayer.flatMap { layer ->
|
||||||
|
(0 until layer.height * layer.width).map { layer.unsafeGetTile(it % layer.width, it / layer.width) }
|
||||||
|
}.toSet().toList().sorted()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts `blockLayer` into `dat` internally, the hidden property used for the serialisation
|
||||||
|
*
|
||||||
|
* Tilenum: tile number in the block layer, identical to the any other block layers
|
||||||
|
* TileSymbol: condensed version of the Tilenum, of which the higheset number is equal to the number of unique tiles used in the layer
|
||||||
|
*/
|
||||||
|
fun getReadyForSerialisation(tilenumToItemID: Map<Int, ItemID>, itemIDtoTileSym: Map<ItemID, Long>, 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()
|
||||||
|
}
|
||||||
|
else if (byteLength == 2) {
|
||||||
|
val tileSym = itemIDtoTileSym[tilenumToItemID[layer.unsafeGetTile((i/2) % layer.width, (i/2) / layer.width)]!!]!!
|
||||||
|
if (i % 2 == 0) tileSym.and(255).toByte() else tileSym.ushr(8).and(255).toByte()
|
||||||
|
}
|
||||||
|
else throw IllegalArgumentException()
|
||||||
|
}
|
||||||
|
}.toTypedArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts `dat` into `blockLayer` so the Layer can be actually utilised.
|
||||||
|
*/
|
||||||
|
fun getReadyToBeUsed(tileSymbolToItemId: HashArray<ItemID>, itemIDtoTileNum: Map<ItemID, Int>, width: Int, height: Int, byteLength: Int) {
|
||||||
|
blockLayer.forEach { it.dispose() }
|
||||||
|
blockLayer.clear()
|
||||||
|
|
||||||
|
dat.forEachIndexed { layerIndex, layer ->
|
||||||
|
val currentBlockLayer = BlockLayerI16(width, height).also {
|
||||||
|
blockLayer[layerIndex] = it
|
||||||
|
}
|
||||||
|
for (w in 0 until layer.size / byteLength) {
|
||||||
|
val word = if (byteLength == 1) layer[w].toUint() else if (byteLength == 2) layer.toULittleShort(2*w) else throw IllegalArgumentException()
|
||||||
|
val x = w % width
|
||||||
|
val y = w / width
|
||||||
|
val tile = itemIDtoTileNum[tileSymbolToItemId[word.toLong()]!!]!!
|
||||||
|
currentBlockLayer.unsafeSetTile(x, y, tile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun write(json: Json) {
|
||||||
|
json.setTypeName(null)
|
||||||
|
json.writeValue("name", name)
|
||||||
|
json.writeValue("dat", dat)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun read(json: Json?, jsonData: JsonValue?) {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
35
work_files/DataFormats/poi.md
Normal file
35
work_files/DataFormats/poi.md
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
POI (Point of Interest) is a placement of blocks that can be used by the world generator.
|
||||||
|
|
||||||
|
POIs are serialised as following:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"genver": 1234567890, /* game version in Int64 */
|
||||||
|
"id": "test_struct_with_enumerable_variations",
|
||||||
|
"wlen": 8, /* word length of the tile number. Can be 8 or 16 */
|
||||||
|
"lut": {"0": "basegame:0", "1": "basegame:48"},
|
||||||
|
"w": 7, "h": 4,
|
||||||
|
"layers": [ /* order matters! */
|
||||||
|
{"name": "base", "dat": [
|
||||||
|
"...layer_0.gz.b85", /* each byte matches what's on the LUT, except 0xFF (0xFFFF if wlen=16) always refers to the null tile. Endianness: little */
|
||||||
|
"...layer_1.gz.b85"
|
||||||
|
]},
|
||||||
|
{"name": "varianceA", "dat": [
|
||||||
|
"...layer_0.gz.b85",
|
||||||
|
"...layer_1.gz.b85"
|
||||||
|
]},
|
||||||
|
{"name": "varianceB", "dat": [
|
||||||
|
"...layer_0.gz.b85",
|
||||||
|
"...layer_1.gz.b85"
|
||||||
|
]},
|
||||||
|
{"name": "varianceC", "dat": [
|
||||||
|
"...layer_0.gz.b85",
|
||||||
|
"...layer_1.gz.b85"
|
||||||
|
]},
|
||||||
|
{"name": "overlay", "dat": [
|
||||||
|
"...layer_0.gz.b85",
|
||||||
|
"...layer_1.gz.b85"
|
||||||
|
]}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user