mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
fluids to their own block layer
This commit is contained in:
BIN
assets/mods/basegame/ores/1.tga
LFS
Normal file
BIN
assets/mods/basegame/ores/1.tga
LFS
Normal file
Binary file not shown.
@@ -1,5 +1,7 @@
|
||||
package net.torvald.terrarum.blockproperties
|
||||
|
||||
import net.torvald.terrarum.gameitems.ItemID
|
||||
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2016-08-06.
|
||||
|
||||
@@ -69,10 +69,7 @@ open class BlockLayerI16(val width: Int, val height: Int) : BlockLayer {
|
||||
|
||||
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)
|
||||
return byteArrayOf(ptr[offset + 1], ptr[offset + 0])
|
||||
}
|
||||
|
||||
internal fun unsafeSetTile(x: Int, y: Int, tile: Int) {
|
||||
|
||||
128
src/net/torvald/terrarum/gameworld/BlockLayerI16F16.kt
Normal file
128
src/net/torvald/terrarum/gameworld/BlockLayerI16F16.kt
Normal file
@@ -0,0 +1,128 @@
|
||||
package net.torvald.terrarum.gameworld
|
||||
|
||||
import net.torvald.terrarum.App
|
||||
import net.torvald.terrarum.blockproperties.Fluid
|
||||
import net.torvald.terrarum.gameworld.WorldSimulator.FLUID_MIN_MASS
|
||||
import net.torvald.terrarum.serialise.toUint
|
||||
import net.torvald.unsafe.UnsafeHelper
|
||||
import net.torvald.unsafe.UnsafePtr
|
||||
import net.torvald.util.Float16
|
||||
|
||||
/**
|
||||
* * Memory layout:
|
||||
* * ```
|
||||
* * a7 a6 a5 a4 a3 a2 a1 a0 | aF aE aD aC aB aA a9 a8 | f7 f6 f5 f4 f3 f2 f1 f0 | fF fE fD fC fB fA f9 f8 ||
|
||||
* * ```
|
||||
* * where a_n is a fluid number, f_n is a fluid fill
|
||||
*
|
||||
* Created by minjaesong on 2023-10-10.
|
||||
*/
|
||||
class BlockLayerI16F16(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, Float> {
|
||||
val offset = BYTES_PER_BLOCK * (y * width + x)
|
||||
val lsb = ptr[offset]
|
||||
val msb = ptr[offset + 1]
|
||||
val hbits = (ptr[offset + 2].toUint() or ptr[offset + 3].toUint().shl(8)).toShort()
|
||||
val fill = Float16.toFloat(hbits)
|
||||
|
||||
return lsb.toUint() + msb.toUint().shl(8) to fill
|
||||
}
|
||||
|
||||
override fun unsafeToBytes(x: Int, y: Int): ByteArray {
|
||||
val offset = BYTES_PER_BLOCK * (y * width + x)
|
||||
return byteArrayOf(ptr[offset + 1], ptr[offset + 0], ptr[offset + 3], ptr[offset + 2])
|
||||
}
|
||||
|
||||
internal fun unsafeSetTile(x: Int, y: Int, tile0: Int, fill: Float) {
|
||||
val offset = BYTES_PER_BLOCK * (y * width + x)
|
||||
val hbits = Float16.fromFloat(fill).toInt().and(0xFFFF)
|
||||
|
||||
val tile = if (fill < FLUID_MIN_MASS) 0 else tile0
|
||||
|
||||
val lsb = tile.and(0xff).toByte()
|
||||
val msb = tile.ushr(8).and(0xff).toByte()
|
||||
|
||||
val hlsb = hbits.and(0xff).toByte()
|
||||
val hmsb = hbits.ushr(8).and(0xff).toByte()
|
||||
|
||||
ptr[offset] = lsb
|
||||
ptr[offset + 1] = msb
|
||||
ptr[offset + 2] = hlsb
|
||||
ptr[offset + 3] = hmsb
|
||||
|
||||
}
|
||||
|
||||
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[3]
|
||||
ptr[offset + 3] = 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, "BlockLayerI16F16 with ptr ($ptr) successfully freed")
|
||||
}
|
||||
|
||||
override fun toString(): String = ptr.toString("BlockLayerI16F16")
|
||||
|
||||
companion object {
|
||||
@Transient val BYTES_PER_BLOCK = 4L
|
||||
}
|
||||
}
|
||||
@@ -66,11 +66,7 @@ class BlockLayerI16I8 (val width: Int, val height: Int) : BlockLayer {
|
||||
|
||||
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)
|
||||
return byteArrayOf(ptr[offset + 1], ptr[offset + 0], ptr[offset + 2])
|
||||
}
|
||||
|
||||
internal fun unsafeSetTile(x: Int, y: Int, tile: Int, placement: Int) {
|
||||
|
||||
@@ -84,9 +84,9 @@ open class GameWorld(
|
||||
@Transient lateinit open var layerWall: BlockLayerI16
|
||||
@Transient lateinit open var layerTerrain: BlockLayerI16
|
||||
@Transient lateinit open var layerOres: BlockLayerI16I8 // damage to the block follows `terrainDamages`
|
||||
@Transient lateinit open var layerFluids: BlockLayerI16F16
|
||||
val wallDamages = HashArray<Float>()
|
||||
val terrainDamages = HashArray<Float>()
|
||||
val layerFluids = HashedFluidTypeAndFills() // TODO: chunk them using BlockLayerI32
|
||||
|
||||
|
||||
|
||||
@@ -142,10 +142,27 @@ open class GameWorld(
|
||||
30L * WorldTime.MINUTE_SEC
|
||||
)
|
||||
|
||||
|
||||
val tileNumberToNameMap = HashArray<ItemID>()
|
||||
@Transient private val forcedTileNumberToNames = hashSetOf(
|
||||
Block.AIR, Block.UPDATE
|
||||
)
|
||||
@Transient private val forcedFluidNumberToTiles = hashSetOf(
|
||||
Fluid.NULL
|
||||
)
|
||||
val tileNumberToNameMap = HashArray<ItemID>().also {
|
||||
it[0] = Block.AIR
|
||||
it[2] = Block.UPDATE
|
||||
}
|
||||
val fluidNumberToNameMap = HashArray<ItemID>().also {
|
||||
it[0] = Fluid.NULL
|
||||
}
|
||||
// does not go to the savefile
|
||||
@Transient val tileNameToNumberMap = HashMap<ItemID, Int>()
|
||||
@Transient val tileNameToNumberMap = HashMap<ItemID, Int>().also {
|
||||
it[Block.AIR] = 0
|
||||
it[Block.UPDATE] = 2
|
||||
}
|
||||
@Transient val fluidNameToNumberMap = HashMap<ItemID, Int>().also {
|
||||
it[Fluid.NULL] = 0
|
||||
}
|
||||
|
||||
val extraFields = HashMap<String, Any?>()
|
||||
|
||||
@@ -202,6 +219,7 @@ open class GameWorld(
|
||||
layerTerrain = BlockLayerI16(width, height)
|
||||
layerWall = BlockLayerI16(width, height)
|
||||
layerOres = BlockLayerI16I8(width, height)
|
||||
layerFluids = BlockLayerI16F16(width, height)
|
||||
|
||||
// temperature layer: 2x2 is one cell
|
||||
//layerThermal = MapLayerHalfFloat(width, height, averageTemperature)
|
||||
@@ -223,20 +241,9 @@ open class GameWorld(
|
||||
tileNameToNumberMap[it.key] = it.value.tileNumber
|
||||
}
|
||||
}
|
||||
|
||||
// AN EXCEPTIONAL TERM: tilenum 0 is always redirected to Air tile, even if the tilenum for actual Air tile is not zero
|
||||
tileNumberToNameMap[0] = Block.AIR
|
||||
tileNameToNumberMap[Block.AIR] = 0
|
||||
|
||||
tileNumberToNameMap[2] = Block.UPDATE
|
||||
tileNameToNumberMap[Block.UPDATE] = 2
|
||||
}
|
||||
}
|
||||
|
||||
@Transient private val forcedTileNumberToNames = hashSetOf(
|
||||
Block.AIR, Block.UPDATE
|
||||
)
|
||||
|
||||
fun coordInWorld(x: Int, y: Int) = y in 0 until height // ROUNDWORLD implementation
|
||||
fun coordInWorldStrict(x: Int, y: Int) = x in 0 until width && y in 0 until height // ROUNDWORLD implementation
|
||||
|
||||
@@ -258,12 +265,13 @@ open class GameWorld(
|
||||
}
|
||||
}
|
||||
|
||||
// AN EXCEPTIONAL TERM: tilenum 0 is always redirected to Air tile, even if the tilenum for actual Air tile is not zero
|
||||
// force this rule to the old saves
|
||||
tileNumberToNameMap[0] = Block.AIR
|
||||
tileNameToNumberMap[Block.AIR] = 0
|
||||
|
||||
tileNumberToNameMap[2] = Block.UPDATE
|
||||
tileNameToNumberMap[Block.AIR] = 0
|
||||
tileNameToNumberMap[Block.UPDATE] = 2
|
||||
fluidNumberToNameMap[0] = Fluid.NULL
|
||||
fluidNameToNumberMap[Fluid.NULL] = 0
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,9 +282,9 @@ open class GameWorld(
|
||||
// get() = layerWire.data
|
||||
|
||||
fun getLayer(index: Int) = when(index) {
|
||||
0 -> layerTerrain
|
||||
1 -> layerWall
|
||||
2 -> layerOres
|
||||
TERRAIN -> layerTerrain
|
||||
WALL -> layerWall
|
||||
ORES -> layerOres
|
||||
else -> null//throw IllegalArgumentException("Unknown layer index: $index")
|
||||
}
|
||||
|
||||
@@ -361,7 +369,7 @@ open class GameWorld(
|
||||
terrainDamages.remove(blockAddr)
|
||||
|
||||
if (BlockCodex[itemID].isSolid) {
|
||||
layerFluids.remove(blockAddr)
|
||||
layerFluids.unsafeSetTile(x, y, fluidNameToNumberMap[Fluid.NULL]!!, 0f)
|
||||
}
|
||||
// fluid tiles-item should be modified so that they will also place fluid onto their respective map
|
||||
|
||||
@@ -546,17 +554,14 @@ open class GameWorld(
|
||||
return getTileFromWall(x, y)
|
||||
}
|
||||
else
|
||||
throw IllegalArgumentException("illegal mode input: " + mode.toString())
|
||||
throw IllegalArgumentException("illegal mode input: $mode")
|
||||
}
|
||||
|
||||
fun getTileFromOre(rawX: Int, rawY: Int): OrePlacement? {
|
||||
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)
|
||||
return OrePlacement(tileName ?: Block.UPDATE, placement)
|
||||
}
|
||||
|
||||
fun setTileOre(rawX: Int, rawY: Int, ore: ItemID, placement: Int) {
|
||||
@@ -684,12 +689,14 @@ open class GameWorld(
|
||||
|
||||
val addr = LandUtil.getBlockAddr(this, x, y)
|
||||
|
||||
val fluidNumber = fluidNameToNumberMap[fluidType]!!
|
||||
|
||||
if (fill > WorldSimulator.FLUID_MIN_MASS) {
|
||||
//setTileTerrain(x, y, fluidTypeToBlock(fluidType))
|
||||
layerFluids[addr] = Fill(fluidType, fill)
|
||||
layerFluids.unsafeSetTile(x, y, fluidNumber, fill)
|
||||
}
|
||||
else {
|
||||
layerFluids.remove(addr)
|
||||
layerFluids.unsafeSetTile(x, y, fluidNumber, 0f)
|
||||
}
|
||||
|
||||
|
||||
@@ -701,10 +708,11 @@ open class GameWorld(
|
||||
}
|
||||
|
||||
fun getFluid(x: Int, y: Int): FluidInfo {
|
||||
val addr = LandUtil.getBlockAddr(this, x, y)
|
||||
val type = layerFluids[addr]?.item
|
||||
val fill = layerFluids[addr]?.amount
|
||||
return if (type == null) FluidInfo(Fluid.NULL, 0f) else FluidInfo(type, fill!!)
|
||||
val (x, y) = coerceXY(x, y)
|
||||
val (type, fill) = layerFluids.unsafeGetTile(x, y)
|
||||
val fluidID = fluidNumberToNameMap[type.toLong()] ?: throw NullPointerException("No such fluid: $type")
|
||||
|
||||
return FluidInfo(fluidID, fill)
|
||||
}
|
||||
|
||||
/*private fun fluidTypeToBlock(type: FluidType) = when (type.abs()) {
|
||||
@@ -764,9 +772,9 @@ open class GameWorld(
|
||||
override fun equals(other: Any?) = layerTerrain.ptr == (other as GameWorld).layerTerrain.ptr
|
||||
|
||||
companion object {
|
||||
@Transient const val WALL = 0
|
||||
@Transient const val TERRAIN = 1
|
||||
@Transient const val WIRE = 2
|
||||
@Transient const val WALL = 1
|
||||
@Transient const val TERRAIN = 0
|
||||
@Transient const val ORES = 2
|
||||
|
||||
@Transient val TILES_SUPPORTED = ReferencingRanges.TILES.last + 1
|
||||
//@Transient val SIZEOF: Byte = 2
|
||||
|
||||
@@ -42,7 +42,7 @@ object WorldSimulator {
|
||||
|
||||
const val FLUID_MAX_MASS = 1f // The normal, un-pressurized mass of a full water cell
|
||||
const val FLUID_MAX_COMP = 0.02f // How much excess water a cell can store, compared to the cell above it. A tile of fluid can contain more than MaxMass water.
|
||||
const val FLUID_MIN_MASS = 0.0001f //Ignore cells that are almost dry
|
||||
const val FLUID_MIN_MASS = 1f / 1024f //Ignore cells that are almost dry (smaller than epsilon of float16)
|
||||
const val WIRE_MIN_FLOW = 0.0001f
|
||||
const val minFlow = 0.01f
|
||||
const val maxSpeed = 1f // max units of water moved out of one block to another, per timestamp
|
||||
|
||||
@@ -5,6 +5,7 @@ import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.App.printdbg
|
||||
import net.torvald.terrarum.console.Echo
|
||||
import net.torvald.terrarum.gameworld.BlockLayerI16
|
||||
import net.torvald.terrarum.gameworld.BlockLayerI16F16
|
||||
import net.torvald.terrarum.gameworld.BlockLayerI16I8
|
||||
import net.torvald.terrarum.gameworld.GameWorld
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
@@ -147,6 +148,7 @@ object LoadSavegame {
|
||||
world.layerTerrain = BlockLayerI16(world.width, world.height)
|
||||
world.layerWall = BlockLayerI16(world.width, world.height)
|
||||
world.layerOres = BlockLayerI16I8(world.width, world.height)
|
||||
world.layerFluids = BlockLayerI16F16(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)
|
||||
|
||||
@@ -84,6 +84,12 @@ class Terragen(world: GameWorld, seed: Long, params: Any) : Gen(world, seed, par
|
||||
|
||||
world.setTileTerrain(x, y, terrBlock, true)
|
||||
world.setTileWall(x, y, wallBlock, true)
|
||||
|
||||
|
||||
// TODO TEST CODE
|
||||
if (terrBlock == Block.DIRT) {
|
||||
world.setTileOre(x, y, "ores@basegame:1", 0)
|
||||
}
|
||||
}
|
||||
|
||||
// dither shits
|
||||
@@ -111,12 +117,6 @@ 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)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -4,6 +4,7 @@ import net.torvald.terrarum.App
|
||||
import net.torvald.terrarum.IngameInstance
|
||||
import net.torvald.terrarum.ItemCodex
|
||||
import net.torvald.terrarum.gameactors.Actor
|
||||
import net.torvald.terrarum.gameworld.BlockLayerI16F16
|
||||
import net.torvald.terrarum.gameworld.GameWorld
|
||||
import net.torvald.terrarum.gameworld.SimpleGameWorld
|
||||
import java.io.File
|
||||
@@ -23,6 +24,7 @@ object ReadSimpleWorld {
|
||||
world.tileNumberToNameMap.forEach { l, s ->
|
||||
world.tileNameToNumberMap[s] = l.toInt()
|
||||
}
|
||||
world.layerFluids = BlockLayerI16F16(world.width, world.height)
|
||||
|
||||
ItemCodex.loadFromSave(origin, world.dynamicToStaticTable, world.dynamicItemInventory)
|
||||
}
|
||||
|
||||
@@ -247,13 +247,15 @@ class BasicDebugInfoWindow : UICanvas() {
|
||||
|
||||
val wallNum = it.getTileFromWall(mouseTileX, mouseTileY)
|
||||
val tileNum = it.getTileFromTerrain(mouseTileX, mouseTileY)
|
||||
val oreNum = it.getTileFromOre(mouseTileX, mouseTileY).item
|
||||
val wires = it.getAllWiresFrom(mouseTileX, mouseTileY)
|
||||
val fluid = it.getFluid(mouseTileX, mouseTileY)
|
||||
val wireCount = wires.first?.size?.toString() ?: "no"
|
||||
|
||||
App.fontSmallNumbers.draw(batch, "$ccO$TERRAIN$ccG$tileNum", gap + 7f*(tileCursX + 3), line(tileCursY))
|
||||
App.fontSmallNumbers.draw(batch, "$ccO$WALL$ccG$wallNum", gap + 7f*(tileCursX + 3), line(tileCursY + 1))
|
||||
App.fontSmallNumbers.draw(batch, "$ccO$LIQUID$ccG${fluid.type.padEnd(3)}$ccO$BEAKER$ccG${fluid.amount.toIntAndFrac(2)}", gap + 7f*(tileCursX + 3), line(tileCursY + 2))
|
||||
// App.fontSmallNumbers.draw(batch, "$ccO$LIQUID$ccG${fluid.type.padEnd(3)}$ccO$BEAKER$ccG${fluid.amount.toIntAndFrac(2)}", gap + 7f*(tileCursX + 3), line(tileCursY + 2))
|
||||
App.fontSmallNumbers.draw(batch, "$ccO$LIQUID$ccG$oreNum", gap + 7f*(tileCursX + 3), line(tileCursY + 2))
|
||||
App.fontSmallNumbers.draw(batch, "$ccO$WIRE$ccG$wireCount ${ccY}X$ccO$mouseTileX ${ccY}Y$ccO$mouseTileY", gap + 7f*(tileCursX + 3), line(tileCursY + 3))
|
||||
App.fontSmallNumbers.draw(batch, "$ccR$rawR $ccG$rawG $ccB$rawB $ccW$rawA", gap + 7f*(tileCursX + 3), line(tileCursY + 4))
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ internal object BlocksDrawer {
|
||||
|
||||
val WALL = GameWorld.WALL
|
||||
val TERRAIN = GameWorld.TERRAIN
|
||||
val ORES = GameWorld.ORES
|
||||
//val WIRE = GameWorld.WIRE
|
||||
val FLUID = -2
|
||||
val OCCLUSION = 31337
|
||||
@@ -295,6 +296,7 @@ internal object BlocksDrawer {
|
||||
val thisTile: ItemID = when (mode) {
|
||||
WALL -> world.getTileFromWall(x, y)
|
||||
TERRAIN -> world.getTileFromTerrain(x, y)
|
||||
ORES -> world.getTileFromOre(x, y).item
|
||||
FLUID -> "basegame:-1" // TODO need new wire storing format //world.getFluid(x, y).type.abs()
|
||||
OCCLUSION -> "placeholder_occlusion"
|
||||
else -> throw IllegalArgumentException()
|
||||
@@ -338,6 +340,9 @@ internal object BlocksDrawer {
|
||||
// special case: fluids
|
||||
else if (mode == FLUID)
|
||||
tileNumberBase + connectLut47[nearbyTilesInfo]
|
||||
// special case: ores
|
||||
else if (mode == ORES)
|
||||
tileNumberBase + world.getTileFromOre(x, y).tilePlacement
|
||||
// rest of the cases: terrain and walls
|
||||
else tileNumberBase + when (renderTag.maskType) {
|
||||
CreateTileAtlas.RenderTag.MASK_NA -> 0
|
||||
|
||||
Reference in New Issue
Block a user