Fix AirBlock, CaveAirBlock and DaylightDetectorBlock
This commit is contained in:
parent
ac5132feda
commit
47de022bb7
9 changed files with 22 additions and 18 deletions
|
@ -9,14 +9,15 @@ import com.google.common.cache.LoadingCache
|
||||||
import space.uranos.player.Player
|
import space.uranos.player.Player
|
||||||
import space.uranos.util.createWeakValuesLoadingCache
|
import space.uranos.util.createWeakValuesLoadingCache
|
||||||
import space.uranos.world.*
|
import space.uranos.world.*
|
||||||
import space.uranos.world.block.Air
|
import space.uranos.world.block.AirBlock
|
||||||
|
|
||||||
class AnvilChunk(world: AnvilWorld, key: Key) : Chunk(world, key) {
|
class AnvilChunk(world: AnvilWorld, key: Key) : Chunk(world, key) {
|
||||||
// TODO: Implement light
|
// TODO: Implement light
|
||||||
|
|
||||||
override fun getData(player: Player?): ChunkData {
|
override fun getData(player: Player?): ChunkData {
|
||||||
return ChunkData(
|
return ChunkData(
|
||||||
sections.map { section -> if (section.blocks.all { it == Air }) null else section.blocks }.toTypedArray(),
|
sections.map { section -> if (section.blocks.all { it == AirBlock }) null else section.blocks }
|
||||||
|
.toTypedArray(),
|
||||||
Array(ChunkData.BIOME_AREAS_IN_CHUNK) { Biome.PLAINS }
|
Array(ChunkData.BIOME_AREAS_IN_CHUNK) { Biome.PLAINS }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,11 @@
|
||||||
package space.uranos.testplugin.anvil
|
package space.uranos.testplugin.anvil
|
||||||
|
|
||||||
import space.uranos.world.Chunk
|
import space.uranos.world.Chunk
|
||||||
import space.uranos.world.block.Air
|
import space.uranos.world.block.AirBlock
|
||||||
import space.uranos.world.block.Block
|
import space.uranos.world.block.Block
|
||||||
|
|
||||||
class AnvilChunkSection {
|
class AnvilChunkSection {
|
||||||
val blocks: Array<Block> = Array(Chunk.BLOCKS_IN_A_SECTION) { Air }
|
val blocks: Array<Block> = Array(Chunk.BLOCKS_IN_A_SECTION) { AirBlock }
|
||||||
val blockLightValues: UByteArray = UByteArray(Chunk.BLOCKS_IN_A_SECTION / 2) { 0xFF.toUByte() }
|
val blockLightValues: UByteArray = UByteArray(Chunk.BLOCKS_IN_A_SECTION / 2) { 0xFF.toUByte() }
|
||||||
val skyLightValues: UByteArray = UByteArray(Chunk.BLOCKS_IN_A_SECTION / 2) { 0xFF.toUByte() }
|
val skyLightValues: UByteArray = UByteArray(Chunk.BLOCKS_IN_A_SECTION / 2) { 0xFF.toUByte() }
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ data class ChunkData(
|
||||||
* The outer array must have 16 items representing the chunk sections.
|
* The outer array must have 16 items representing the chunk sections.
|
||||||
*
|
*
|
||||||
* The inner arrays contain the blocks (x, z, y) of a chunk section and must have a size of 4096.
|
* The inner arrays contain the blocks (x, z, y) of a chunk section and must have a size of 4096.
|
||||||
* If a chunk section only contains air, it should be null (instead of an array of Air).
|
* If a chunk section only contains air, it should be null (instead of an array of AirBlock).
|
||||||
*/
|
*/
|
||||||
val sections: Array<Array<Block>?>,
|
val sections: Array<Array<Block>?>,
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ data class ChunkData(
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An array (first x, then z) containing the y coordinates of the highest block in every column which is
|
* An array (first x, then z) containing the y coordinates of the highest block in every column which is
|
||||||
* neither [Air][space.uranos.world.block.Air] nor [CaveAir][space.uranos.world.block.CaveAir].
|
* neither [AirBlock][space.uranos.world.block.AirBlock] nor [CaveAirBlock][space.uranos.world.block.CaveAirBlock].
|
||||||
* Will be computed using [sections] if null.
|
* Will be computed using [sections] if null.
|
||||||
*/
|
*/
|
||||||
val nonAirBlocksHeightmap: ByteArray? = null
|
val nonAirBlocksHeightmap: ByteArray? = null
|
||||||
|
|
|
@ -9,7 +9,7 @@ package space.uranos.world.block
|
||||||
/**
|
/**
|
||||||
* Material: [AIR][Material.AIR]
|
* Material: [AIR][Material.AIR]
|
||||||
*/
|
*/
|
||||||
object Air : Block(), Material<Air> by material(
|
object AirBlock : Block(), Material<AirBlock> by material(
|
||||||
0,
|
0,
|
||||||
"minecraft:air",
|
"minecraft:air",
|
||||||
0,
|
0,
|
|
@ -16,7 +16,7 @@ import kotlin.reflect.KClass
|
||||||
abstract class Block internal constructor() {
|
abstract class Block internal constructor() {
|
||||||
companion object {
|
companion object {
|
||||||
/**
|
/**
|
||||||
* See [DaylightDetector] for an example on how this function should be used.
|
* See [DaylightDetectorBlock] for an example on how this function should be used.
|
||||||
*/
|
*/
|
||||||
internal inline fun <reified T : Block> material(
|
internal inline fun <reified T : Block> material(
|
||||||
numericID: Int,
|
numericID: Int,
|
||||||
|
|
|
@ -8,7 +8,7 @@ package space.uranos.world.block
|
||||||
/**
|
/**
|
||||||
* Material: [CAVE_AIR][Material.CAVE_AIR]
|
* Material: [CAVE_AIR][Material.CAVE_AIR]
|
||||||
*/
|
*/
|
||||||
object CaveAir : Block(), Material<CaveAir> by material(
|
object CaveAirBlock : Block(), Material<CaveAirBlock> by material(
|
||||||
617,
|
617,
|
||||||
"minecraft:cave_air",
|
"minecraft:cave_air",
|
||||||
9130,
|
9130,
|
|
@ -5,13 +5,13 @@
|
||||||
|
|
||||||
package space.uranos.world.block
|
package space.uranos.world.block
|
||||||
|
|
||||||
data class DaylightDetector(
|
data class DaylightDetectorBlock(
|
||||||
@Attribute
|
@Attribute
|
||||||
val inverted: Boolean = false,
|
val inverted: Boolean = false,
|
||||||
@Attribute(15)
|
@Attribute(15)
|
||||||
val power: Int
|
val power: Int
|
||||||
) : Block() {
|
) : Block() {
|
||||||
companion object : Material<DaylightDetector> by material(
|
companion object : Material<DaylightDetectorBlock> by material(
|
||||||
333,
|
333,
|
||||||
"minecraft:daylight_detector",
|
"minecraft:daylight_detector",
|
||||||
6698,
|
6698,
|
|
@ -7,11 +7,11 @@ import strikt.assertions.isEqualTo
|
||||||
class BlockCodecTest {
|
class BlockCodecTest {
|
||||||
@Test
|
@Test
|
||||||
fun `getStateID returns 6698 for DaylightDetector(inverted=true, power=0)`() {
|
fun `getStateID returns 6698 for DaylightDetector(inverted=true, power=0)`() {
|
||||||
expectThat(DaylightDetector.codec.getStateID(DaylightDetector(true, 0))).isEqualTo(6698)
|
expectThat(DaylightDetectorBlock.codec.getStateID(DaylightDetectorBlock(true, 0))).isEqualTo(6698)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `getStateID returns 6729 for DaylightDetector(inverted=false, power=15)`() {
|
fun `getStateID returns 6729 for DaylightDetector(inverted=false, power=15)`() {
|
||||||
expectThat(DaylightDetector.codec.getStateID(DaylightDetector(false, 15))).isEqualTo(6729)
|
expectThat(DaylightDetectorBlock.codec.getStateID(DaylightDetectorBlock(false, 15))).isEqualTo(6729)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,15 +14,15 @@ import space.uranos.net.packet.OutgoingPacketCodec
|
||||||
import space.uranos.util.generateHeightmap
|
import space.uranos.util.generateHeightmap
|
||||||
import space.uranos.util.setBit
|
import space.uranos.util.setBit
|
||||||
import space.uranos.util.toCompactLongArray
|
import space.uranos.util.toCompactLongArray
|
||||||
import space.uranos.world.block.Air
|
import space.uranos.world.block.AirBlock
|
||||||
import space.uranos.world.block.CaveAir
|
import space.uranos.world.block.CaveAirBlock
|
||||||
import space.uranos.world.block.Material
|
import space.uranos.world.block.Material
|
||||||
import space.uranos.world.block.material
|
import space.uranos.world.block.material
|
||||||
import kotlin.math.ceil
|
import kotlin.math.ceil
|
||||||
import kotlin.math.log
|
import kotlin.math.log
|
||||||
|
|
||||||
object ChunkDataPacketCodec : OutgoingPacketCodec<ChunkDataPacket>(0x20, ChunkDataPacket::class) {
|
object ChunkDataPacketCodec : OutgoingPacketCodec<ChunkDataPacket>(0x20, ChunkDataPacket::class) {
|
||||||
private val airBlocks: Set<Material<*>> = setOf(Air, CaveAir)
|
private val airBlocks: Set<Material<*>> = setOf(AirBlock, CaveAirBlock)
|
||||||
private val nonSolidBlocks = Material.all.filter { it.collisionShape.isEmpty() }
|
private val nonSolidBlocks = Material.all.filter { it.collisionShape.isEmpty() }
|
||||||
|
|
||||||
private val numberOfBitsPerBlock = ceil(log(Material.all.last().codec.lastStateID.toDouble(), 2.0)).toInt()
|
private val numberOfBitsPerBlock = ceil(log(Material.all.last().codec.lastStateID.toDouble(), 2.0)).toInt()
|
||||||
|
@ -67,8 +67,11 @@ object ChunkDataPacketCodec : OutgoingPacketCodec<ChunkDataPacket>(0x20, ChunkDa
|
||||||
// Blocks
|
// Blocks
|
||||||
val dataBuf = Unpooled.buffer() // TODO: Set an initial capacity
|
val dataBuf = Unpooled.buffer() // TODO: Set an initial capacity
|
||||||
for (section in data.sections.filterNotNull()) {
|
for (section in data.sections.filterNotNull()) {
|
||||||
val ids = section.map { it.material().codec.getStateID(it) }.toIntArray()
|
val ids = section.map {
|
||||||
dataBuf.writeShort(ids.count { !(it == Air.codec.id || it == CaveAir.codec.id) })
|
println(it)
|
||||||
|
it.material().codec.getStateID(it)
|
||||||
|
}.toIntArray()
|
||||||
|
dataBuf.writeShort(ids.count { !(it == AirBlock.codec.id || it == CaveAirBlock.codec.id) })
|
||||||
dataBuf.writeByte(numberOfBitsPerBlock)
|
dataBuf.writeByte(numberOfBitsPerBlock)
|
||||||
|
|
||||||
val array = ids.toCompactLongArray(numberOfBitsPerBlock)
|
val array = ids.toCompactLongArray(numberOfBitsPerBlock)
|
||||||
|
|
Reference in a new issue