Generalised BlockLayer

This commit is contained in:
minjaesong
2023-10-10 03:56:02 +09:00
parent 8f1ca485f6
commit e76ff58b3e
12 changed files with 330 additions and 148 deletions

View File

@@ -423,3 +423,4 @@ fun ItemID.isVirtual() = this.startsWith("$PREFIX_VIRTUALTILE@")
fun ItemID.isBlock() = !this.contains('@') && !this.isDynamic()
fun ItemID.isWall() = this.startsWith("wall@")
fun ItemID.isFluid() = this.startsWith("fluid@")
fun ItemID.isOre() = this.startsWith("ores@")

View File

@@ -1,110 +1,14 @@
package net.torvald.terrarum.gameworld
import com.badlogic.gdx.utils.Disposable
import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.serialise.toUint
import net.torvald.unsafe.UnsafeHelper
import net.torvald.unsafe.UnsafePtr
/**
* Memory layout:
* ```
* a7 a6 a5 a4 a3 a2 a1 a0 | aF aE aD aC aB aA a9 a8 ||
* ```
* where a_n is a tile number
*
* Original version Created by minjaesong on 2016-01-17.
* Unsafe version Created by minjaesong on 2019-06-08.
*
* Note to self: refrain from using shorts--just do away with two bytes: different system have different endianness
* Created by minjaesong on 2023-10-10.
*/
open class BlockLayer(val width: Int, val height: Int) : Disposable {
// for some reason, all the efforts of saving the memory space were futile.
interface BlockLayer : Disposable {
// using unsafe pointer gets you 100 fps, whereas using directbytebuffer gets you 90
internal val ptr: UnsafePtr = UnsafeHelper.allocate(width * height * BYTES_PER_BLOCK)
val bytesPerBlock: Long
fun unsafeToBytes(x: Int, y: Int): ByteArray
fun unsafeSetTile(x: Int, y: Int, bytes: ByteArray)
val ptrDestroyed: Boolean
get() = ptr.destroyed
init {
ptr.fillWith(0)
}
/**
* @param data Byte array representation of the layer
*/
constructor(width: Int, height: Int, data: ByteArray) : this(width, height) {
TODO()
data.forEachIndexed { index, byte -> UnsafeHelper.unsafe.putByte(ptr.ptr + index, byte) }
}
/**
* Returns an iterator over stored bytes.
*
* @return an Iterator.
*/
fun bytesIterator(): Iterator<Byte> {
return object : Iterator<Byte> {
private var iteratorCount = 0L
override fun hasNext(): Boolean {
return iteratorCount < width * height * BYTES_PER_BLOCK
}
override fun next(): Byte {
iteratorCount += 1
return ptr[iteratorCount - 1]
}
}
}
internal fun unsafeGetTile(x: Int, y: Int): Int {
val offset = BYTES_PER_BLOCK * (y * width + x)
val lsb = ptr[offset]
val msb = ptr[offset + 1]
return lsb.toUint() + msb.toUint().shl(8)
}
internal fun unsafeSetTile(x: Int, y: Int, tile: Int) {
val offset = BYTES_PER_BLOCK * (y * width + x)
val lsb = tile.and(0xff).toByte()
val msb = tile.ushr(8).and(0xff).toByte()
// try {
ptr[offset] = lsb
ptr[offset + 1] = msb
// }
// catch (e: IndexOutOfBoundsException) {
// printdbgerr(this, "IndexOutOfBoundsException: x = $x, y = $y; offset = $offset")
// throw e
// }
}
/**
* @param blockOffset Offset in blocks. BlockOffset of 0x100 is equal to ```layerPtr + 0x200```
*/
/*internal fun unsafeSetTile(blockOffset: Long, tile: Int) {
val offset = BYTES_PER_BLOCK * blockOffset
val lsb = tile.and(0xff).toByte()
val msb = tile.ushr(8).and(0xff).toByte()
unsafe.putByte(layerPtr + offset, lsb)
unsafe.putByte(layerPtr + offset + 1, msb)
}*/
fun isInBound(x: Int, y: Int) = (x >= 0 && y >= 0 && x < width && y < height)
override fun dispose() {
ptr.destroy()
printdbg(this, "BlockLayer with ptr ($ptr) successfully freed")
}
override fun toString(): String = ptr.toString()
companion object {
@Transient val BYTES_PER_BLOCK = 2L
}
}
}

View File

@@ -0,0 +1,126 @@
package net.torvald.terrarum.gameworld
import com.badlogic.gdx.utils.Disposable
import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.serialise.toUint
import net.torvald.unsafe.UnsafeHelper
import net.torvald.unsafe.UnsafePtr
/**
* Memory layout:
* ```
* a7 a6 a5 a4 a3 a2 a1 a0 | aF aE aD aC aB aA a9 a8 ||
* ```
* where a_n is a tile number
*
* Original version Created by minjaesong on 2016-01-17.
* Unsafe version Created by minjaesong on 2019-06-08.
*
* Note to self: refrain from using shorts--just do away with two bytes: different system have different endianness
*/
open class BlockLayerI16(val width: Int, val height: Int) : BlockLayer {
override val bytesPerBlock = BYTES_PER_BLOCK
// for some reason, all the efforts of saving the memory space were futile.
// using unsafe pointer gets you 100 fps, whereas using directbytebuffer gets you 90
internal val ptr: UnsafePtr = UnsafeHelper.allocate(width * height * BYTES_PER_BLOCK)
val ptrDestroyed: Boolean
get() = ptr.destroyed
init {
ptr.fillWith(0)
}
/**
* @param data Byte array representation of the layer
*/
constructor(width: Int, height: Int, data: ByteArray) : this(width, height) {
TODO()
data.forEachIndexed { index, byte -> UnsafeHelper.unsafe.putByte(ptr.ptr + index, byte) }
}
/**
* Returns an iterator over stored bytes.
*
* @return an Iterator.
*/
fun bytesIterator(): Iterator<Byte> {
return object : Iterator<Byte> {
private var iteratorCount = 0L
override fun hasNext(): Boolean {
return iteratorCount < width * height * BYTES_PER_BLOCK
}
override fun next(): Byte {
iteratorCount += 1
return ptr[iteratorCount - 1]
}
}
}
internal fun unsafeGetTile(x: Int, y: Int): Int {
val offset = BYTES_PER_BLOCK * (y * width + x)
val lsb = ptr[offset]
val msb = ptr[offset + 1]
return lsb.toUint() + msb.toUint().shl(8)
}
override fun unsafeToBytes(x: Int, y: Int): ByteArray {
val offset = BYTES_PER_BLOCK * (y * width + x)
val lsb = ptr[offset]
val msb = ptr[offset + 1]
return byteArrayOf(msb, lsb)
}
internal fun unsafeSetTile(x: Int, y: Int, tile: Int) {
val offset = BYTES_PER_BLOCK * (y * width + x)
val lsb = tile.and(0xff).toByte()
val msb = tile.ushr(8).and(0xff).toByte()
// try {
ptr[offset] = lsb
ptr[offset + 1] = msb
// }
// catch (e: IndexOutOfBoundsException) {
// printdbgerr(this, "IndexOutOfBoundsException: x = $x, y = $y; offset = $offset")
// throw e
// }
}
override fun unsafeSetTile(x: Int, y: Int, bytes: ByteArray) {
val offset = BYTES_PER_BLOCK * (y * width + x)
ptr[offset] = bytes[1]
ptr[offset + 1] = bytes[0]
}
/**
* @param blockOffset Offset in blocks. BlockOffset of 0x100 is equal to ```layerPtr + 0x200```
*/
/*internal fun unsafeSetTile(blockOffset: Long, tile: Int) {
val offset = BYTES_PER_BLOCK * blockOffset
val lsb = tile.and(0xff).toByte()
val msb = tile.ushr(8).and(0xff).toByte()
unsafe.putByte(layerPtr + offset, lsb)
unsafe.putByte(layerPtr + offset + 1, msb)
}*/
fun isInBound(x: Int, y: Int) = (x >= 0 && y >= 0 && x < width && y < height)
override fun dispose() {
ptr.destroy()
printdbg(this, "BlockLayerI16 with ptr ($ptr) successfully freed")
}
override fun toString(): String = ptr.toString("BlockLayerI16")
companion object {
@Transient val BYTES_PER_BLOCK = 2L
}
}

View File

@@ -0,0 +1,126 @@
package net.torvald.terrarum.gameworld
import com.badlogic.gdx.utils.Disposable
import net.torvald.terrarum.App
import net.torvald.terrarum.serialise.toUint
import net.torvald.unsafe.UnsafeHelper
import net.torvald.unsafe.UnsafePtr
/**
* Memory layout:
* ```
* a7 a6 a5 a4 a3 a2 a1 a0 | aF aE aD aC aB aA a9 a8 | p7 p6 p5 p4 p3 p2 p1 p0 ||
* ```
* where a_n is a tile number, p_n is a placement index
* Created by minjaesong on 2023-10-10.
*/
class BlockLayerI16I8 (val width: Int, val height: Int) : BlockLayer {
override val bytesPerBlock = BYTES_PER_BLOCK
// for some reason, all the efforts of saving the memory space were futile.
// using unsafe pointer gets you 100 fps, whereas using directbytebuffer gets you 90
internal val ptr: UnsafePtr = UnsafeHelper.allocate(width * height * BYTES_PER_BLOCK)
val ptrDestroyed: Boolean
get() = ptr.destroyed
init {
ptr.fillWith(0)
}
/**
* @param data Byte array representation of the layer
*/
constructor(width: Int, height: Int, data: ByteArray) : this(width, height) {
TODO()
data.forEachIndexed { index, byte -> UnsafeHelper.unsafe.putByte(ptr.ptr + index, byte) }
}
/**
* Returns an iterator over stored bytes.
*
* @return an Iterator.
*/
fun bytesIterator(): Iterator<Byte> {
return object : Iterator<Byte> {
private var iteratorCount = 0L
override fun hasNext(): Boolean {
return iteratorCount < width * height * BYTES_PER_BLOCK
}
override fun next(): Byte {
iteratorCount += 1
return ptr[iteratorCount - 1]
}
}
}
internal fun unsafeGetTile(x: Int, y: Int): Pair<Int, Int> {
val offset = BYTES_PER_BLOCK * (y * width + x)
val lsb = ptr[offset]
val msb = ptr[offset + 1]
val placement = ptr[offset + 2]
return lsb.toUint() + msb.toUint().shl(8) to placement.toUint()
}
override fun unsafeToBytes(x: Int, y: Int): ByteArray {
val offset = BYTES_PER_BLOCK * (y * width + x)
val lsb = ptr[offset]
val msb = ptr[offset + 1]
val placement = ptr[offset + 2]
return byteArrayOf(msb, lsb, placement)
}
internal fun unsafeSetTile(x: Int, y: Int, tile: Int, placement: Int) {
val offset = BYTES_PER_BLOCK * (y * width + x)
val lsb = tile.and(0xff).toByte()
val msb = tile.ushr(8).and(0xff).toByte()
// try {
ptr[offset] = lsb
ptr[offset + 1] = msb
ptr[offset + 2] = placement.toByte()
// }
// catch (e: IndexOutOfBoundsException) {
// printdbgerr(this, "IndexOutOfBoundsException: x = $x, y = $y; offset = $offset")
// throw e
// }
}
override fun unsafeSetTile(x: Int, y: Int, bytes: ByteArray) {
val offset = BYTES_PER_BLOCK * (y * width + x)
ptr[offset] = bytes[1]
ptr[offset + 1] = bytes[0]
ptr[offset + 2] = bytes[2]
}
/**
* @param blockOffset Offset in blocks. BlockOffset of 0x100 is equal to ```layerPtr + 0x200```
*/
/*internal fun unsafeSetTile(blockOffset: Long, tile: Int) {
val offset = BYTES_PER_BLOCK * blockOffset
val lsb = tile.and(0xff).toByte()
val msb = tile.ushr(8).and(0xff).toByte()
unsafe.putByte(layerPtr + offset, lsb)
unsafe.putByte(layerPtr + offset + 1, msb)
}*/
fun isInBound(x: Int, y: Int) = (x >= 0 && y >= 0 && x < width && y < height)
override fun dispose() {
ptr.destroy()
App.printdbg(this, "BlockLayerI16I8 with ptr ($ptr) successfully freed")
}
override fun toString(): String = ptr.toString("BlockLayerI16I8")
companion object {
@Transient val BYTES_PER_BLOCK = 3L
}
}

View File

@@ -7,22 +7,20 @@ import net.torvald.terrarum.*
import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.blockproperties.Block
import net.torvald.terrarum.blockproperties.Fluid
import net.torvald.terrarum.concurrent.ThreadExecutor
import net.torvald.terrarum.gameactors.ActorID
import net.torvald.terrarum.gameitems.ItemID
import net.torvald.terrarum.gameitems.isFluid
import net.torvald.terrarum.gameitems.isOre
import net.torvald.terrarum.itemproperties.ItemRemapTable
import net.torvald.terrarum.itemproperties.ItemTable
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
import net.torvald.terrarum.realestate.LandUtil
import net.torvald.terrarum.utils.*
import net.torvald.terrarum.weather.WeatherMixer
import net.torvald.terrarum.weather.WeatherSchedule
import net.torvald.terrarum.weather.Weatherbox
import net.torvald.util.SortedArrayList
import org.dyn4j.geometry.Vector2
import java.util.*
import kotlin.math.absoluteValue
typealias BlockAddress = Long
@@ -40,8 +38,8 @@ class PhysicalStatus() {
* Special version of GameWorld where everything, including layer data, are saved in a single JSON file (i.e. not chunked)
*/
class SimpleGameWorld(width: Int, height: Int) : GameWorld(width, height) {
override lateinit var layerWall: BlockLayer
override lateinit var layerTerrain: BlockLayer
override lateinit var layerWall: BlockLayerI16
override lateinit var layerTerrain: BlockLayerI16
constructor() : this(0, 0)
}
@@ -83,12 +81,12 @@ open class GameWorld(
}
//layers
@Transient lateinit open var layerWall: BlockLayer
@Transient lateinit open var layerTerrain: BlockLayer
val layerOres = HashedOres() // damage to the block follows `terrainDamages`
@Transient lateinit open var layerWall: BlockLayerI16
@Transient lateinit open var layerTerrain: BlockLayerI16
@Transient lateinit open var layerOres: BlockLayerI16I8 // damage to the block follows `terrainDamages`
val wallDamages = HashArray<Float>()
val terrainDamages = HashArray<Float>()
val layerFluids = HashedFluidTypeAndFills()
val layerFluids = HashedFluidTypeAndFills() // TODO: chunk them using BlockLayerI32
@@ -201,8 +199,8 @@ open class GameWorld(
this.spawnX = width / 2
this.spawnY = 150
layerTerrain = BlockLayer(width, height)
layerWall = BlockLayer(width, height)
layerTerrain = BlockLayerI16(width, height)
layerWall = BlockLayerI16(width, height)
// temperature layer: 2x2 is one cell
//layerThermal = MapLayerHalfFloat(width, height, averageTemperature)
@@ -277,6 +275,7 @@ open class GameWorld(
fun getLayer(index: Int) = when(index) {
0 -> layerTerrain
1 -> layerWall
2 -> layerOres
else -> null//throw IllegalArgumentException("Unknown layer index: $index")
}
@@ -549,6 +548,21 @@ open class GameWorld(
throw IllegalArgumentException("illegal mode input: " + mode.toString())
}
fun getTileFromOre(rawX: Int, rawY: Int): OrePlacement? {
val (x, y) = coerceXY(rawX, rawY)
val (tileNum, placement) = layerOres.unsafeGetTile(x, y)
val tileName = tileNumberToNameMap[tileNum.toLong()]
if (tileName == Block.AIR)
return null
else
return OrePlacement(tileName ?: Block.UPDATE, placement)
}
fun setTileOre(rawX: Int, rawY: Int, ore: ItemID, placement: Int) {
val (x, y) = coerceXY(rawX, rawY)
layerOres.unsafeSetTile(x, y, tileNameToNumberMap[ore]!!, placement)
}
fun terrainIterator(): Iterator<ItemID> {
return object : Iterator<ItemID> {

View File

@@ -3,6 +3,8 @@ package net.torvald.terrarum.modulebasegame.gameactors
import net.torvald.terrarum.App
import net.torvald.terrarum.BlockCodex
import net.torvald.terrarum.WireCodex
import net.torvald.terrarum.gameitems.isBlock
import net.torvald.terrarum.gameitems.isWall
/**
* Created by minjaesong on 2016-02-03.
@@ -74,19 +76,22 @@ object PlayerBuilderSigrid {
fun fillTestInventory(inventory: ActorInventory) {
App.tileMaker.tags.forEach { (t, _) ->
val prop = BlockCodex[t]
if (!prop.isActorBlock && !prop.hasTag("AIR") && !prop.hasTag("INTERNAL")) {
if (t.isBlock() || t.isWall()) {
val prop = BlockCodex[t]
if (!prop.isActorBlock && !prop.hasTag("AIR") && !prop.hasTag("INTERNAL")) {
inventory.add(t, 9995)
try {
inventory.add(
"wall@$t",
9995
) // this code will try to add nonexisting wall items, do not get surprised with NPEs
}
catch (e: NullPointerException) { /* tHiS iS fInE */ }
catch (e: Throwable) {
System.err.println("[PlayerBuilder] $e")
inventory.add(t, 9995)
try {
inventory.add(
"wall@$t",
9995
) // this code will try to add nonexisting wall items, do not get surprised with NPEs
}
catch (e: NullPointerException) { /* tHiS iS fInE */
}
catch (e: Throwable) {
System.err.println("[PlayerBuilder] $e")
}
}
}
}

View File

@@ -4,19 +4,17 @@ import com.badlogic.gdx.graphics.Pixmap
import net.torvald.terrarum.*
import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.console.Echo
import net.torvald.terrarum.gameworld.BlockLayer
import net.torvald.terrarum.gameworld.BlockLayerI16
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.modulebasegame.ChunkLoadingLoadScreen
import net.torvald.terrarum.modulebasegame.IngameRenderer
import net.torvald.terrarum.modulebasegame.SavegameMigrator
import net.torvald.terrarum.modulebasegame.TerrarumIngame
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
import net.torvald.terrarum.realestate.LandUtil
import net.torvald.terrarum.savegame.*
import net.torvald.terrarum.savegame.VDFileID.SAVEGAMEINFO
import net.torvald.terrarum.serialise.Common
import net.torvald.terrarum.utils.JsonFetcher
import net.torvald.terrarum.worlddrawer.WorldCamera
import java.io.File
import java.io.Reader
@@ -145,8 +143,8 @@ object LoadSavegame {
val worldDiskSavegameInfo = ByteArray64Reader(worldDisk.getFile(SAVEGAMEINFO)!!.bytes, Common.CHARSET)
val world = ReadWorld(worldDiskSavegameInfo, worldDisk.diskFile)
world.layerTerrain = BlockLayer(world.width, world.height)
world.layerWall = BlockLayer(world.width, world.height)
world.layerTerrain = BlockLayerI16(world.width, world.height)
world.layerWall = BlockLayerI16(world.width, world.height)
newIngame.world = world // must be set before the loadscreen, otherwise the loadscreen will try to read from the NullWorld which is already destroyed
newIngame.worldDisk = VDUtil.readDiskArchive(worldDisk.diskFile, Level.INFO)

View File

@@ -4,6 +4,8 @@ import net.torvald.terrarum.ItemCodex
import net.torvald.terrarum.gameactors.Actor
import net.torvald.terrarum.gameactors.NoSerialise
import net.torvald.terrarum.gameworld.BlockLayer
import net.torvald.terrarum.gameworld.BlockLayerI16
import net.torvald.terrarum.gameworld.BlockLayerI16I8
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.modulebasegame.TerrarumIngame
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
@@ -82,9 +84,7 @@ object WriteWorld {
val ba = ByteArray64()
for (y in cy * LandUtil.CHUNK_H until (cy + 1) * LandUtil.CHUNK_H) {
for (x in cx * LandUtil.CHUNK_W until (cx + 1) * LandUtil.CHUNK_W) {
val tilenum = layer.unsafeGetTile(x, y)
ba.appendByte(tilenum.ushr(8).and(255).toByte())
ba.appendByte(tilenum.and(255).toByte())
ba.appendBytes(layer.unsafeToBytes(x, y))
}
}
@@ -116,17 +116,19 @@ object ReadWorld {
fun decodeChunkToLayer(chunk: ByteArray64, targetLayer: BlockLayer, cx: Int, cy: Int) {
val bytes = Common.unzip(chunk)
if (bytes.size != cw * ch * 2L)
if (bytes.size != cw * ch * targetLayer.bytesPerBlock)
throw UnsupportedOperationException("Chunk size mismatch: decoded chunk size is ${bytes.size} bytes " +
"where ${LandUtil.CHUNK_W * LandUtil.CHUNK_H * 2L} bytes (Int16 of ${LandUtil.CHUNK_W}x${LandUtil.CHUNK_H}) were expected")
"where ${LandUtil.CHUNK_W * LandUtil.CHUNK_H * targetLayer.bytesPerBlock} bytes (Int${8 * targetLayer.bytesPerBlock} of ${LandUtil.CHUNK_W}x${LandUtil.CHUNK_H}) were expected")
for (k in 0 until cw * ch) {
val tilenum = bytes[2L*k].toUint().shl(8) or bytes[2L*k + 1].toUint()
val offx = k % cw
val offy = k / cw
val ba = ByteArray(targetLayer.bytesPerBlock.toInt()) {
bytes[targetLayer.bytesPerBlock * k + it]
}
// try {
targetLayer.unsafeSetTile(cx * cw + offx, cy * ch + offy, tilenum)
targetLayer.unsafeSetTile(cx * cw + offx, cy * ch + offy, ba)
// }
// catch (e: IndexOutOfBoundsException) {
// printdbgerr(this, "IndexOutOfBoundsException, cx = $cx, cy = $cy, k = $k, offx = $offx, offy = $offy")

View File

@@ -111,6 +111,12 @@ class Terragen(world: GameWorld, seed: Long, params: Any) : Gen(world, seed, par
world.setTileTerrain(x, y, newTile, true)
world.setTileWall(x, y, newTile, true)
// TODO TEST CODE
if (newTile == Block.DIRT) {
world.setTileOre(x, y, "ores@basegame:1", 0)
}
}
/*

View File

@@ -4,10 +4,9 @@ import com.badlogic.gdx.utils.Json
import com.badlogic.gdx.utils.JsonValue
import com.badlogic.gdx.utils.JsonWriter
import net.torvald.random.HQRNG
import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.TerrarumAppConfiguration
import net.torvald.terrarum.console.EchoError
import net.torvald.terrarum.gameworld.BlockLayer
import net.torvald.terrarum.gameworld.BlockLayerI16
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.gameworld.WorldTime
import net.torvald.terrarum.savegame.ByteArray64
@@ -42,7 +41,7 @@ object Common {
val CHARSET = Charsets.UTF_8
/** dispose of the `offendingObject` after rejection! */
class BlockLayerHashMismatchError(val oldHash: String, val newHash: String, val offendingObject: BlockLayer) : Error("Old Hash $oldHash != New Hash $newHash")
class BlockLayerHashMismatchError(val oldHash: String, val newHash: String, val offendingObject: BlockLayerI16) : Error("Old Hash $oldHash != New Hash $newHash")
private fun Byte.tostr() = this.toInt().and(255).toString(16).padStart(2,'0')
private val digester = DigestUtils.getSha256Digest()
@@ -76,8 +75,8 @@ object Common {
}
})
// BlockLayer
jsoner.setSerializer(BlockLayer::class.java, object : Json.Serializer<BlockLayer> {
override fun write(json: Json, obj: BlockLayer, knownType: Class<*>?) {
jsoner.setSerializer(BlockLayerI16::class.java, object : Json.Serializer<BlockLayerI16> {
override fun write(json: Json, obj: BlockLayerI16, knownType: Class<*>?) {
digester.reset()
obj.bytesIterator().forEachRemaining { digester.update(it) }
val hash = StringBuilder().let { sb -> digester.digest().forEach { sb.append(it.tostr()) }; sb.toString() }
@@ -87,7 +86,7 @@ object Common {
json.writeValue(layer)
}
override fun read(json: Json, jsonData: JsonValue, type: Class<*>): BlockLayer {
override fun read(json: Json, jsonData: JsonValue, type: Class<*>): BlockLayerI16 {
// full manual
try {
return strToBlockLayer(LayerInfo(
@@ -437,12 +436,12 @@ object Common {
* @param b a BlockLayer
* @return Bytes in [b] which are GZip'd then Ascii85-encoded
*/
private fun blockLayerToStr(b: BlockLayer): String {
private fun blockLayerToStr(b: BlockLayerI16): String {
return bytesToZipdStr(b.bytesIterator())
}
private fun strToBlockLayer(layerInfo: LayerInfo): BlockLayer {
val layer = BlockLayer(layerInfo.x, layerInfo.y)
private fun strToBlockLayer(layerInfo: LayerInfo): BlockLayerI16 {
val layer = BlockLayerI16(layerInfo.x, layerInfo.y)
val unzipdBytes = strToBytes(StringReader(layerInfo.b))
// write to blocklayer and the digester

View File

@@ -162,7 +162,7 @@ class CreateTileAtlas {
if (dirName == "blocks") {
// filter files that do not exist on the blockcodex
dir.list()
.filter { tgaFile -> !tgaFile.isDirectory && (BlockCodex.getOrNull("$modname:${tgaFile.nameWithoutExtension()}") != null) }
.filter { tgaFile -> tgaFile.extension() == "tga" && !tgaFile.isDirectory && (BlockCodex.getOrNull("$modname:${tgaFile.nameWithoutExtension()}") != null) }
.sortedBy { it.nameWithoutExtension().toInt() }
.forEach { tgaFile: FileHandle -> // toInt() to sort by the number, not lexicographically
// tgaFile be like: ./assets/mods/basegame/blocks/32.tga (which is not always .tga)
@@ -173,7 +173,7 @@ class CreateTileAtlas {
}
else {
// TODO test
dir.list().filter { tgaFile -> !tgaFile.isDirectory }.sortedBy { it.nameWithoutExtension().toInt() }.forEach { tgaFile: FileHandle ->
dir.list().filter { tgaFile -> tgaFile.extension() == "tga" && !tgaFile.isDirectory }.sortedBy { it.nameWithoutExtension().toInt() }.forEach { tgaFile: FileHandle ->
val newFile = ModMgr.GameRetextureLoader.altFilePaths.getOrDefault(tgaFile.path(), tgaFile)
tgaList[dirName]!!.add(modname to newFile)
}

View File

@@ -198,6 +198,7 @@ internal class UnsafePtr(pointer: Long, allocSize: Long) {
}
override fun toString() = "0x${ptr.toString(16)} with size $size"
fun toString(prefix: String) = "$prefix 0x${ptr.toString(16)} with size $size"
override fun equals(other: Any?) = this.ptr == (other as UnsafePtr).ptr && this.size == other.size
}