count fluid blocks per section

This commit is contained in:
Bixilon 2021-11-21 20:36:25 +01:00
parent 0dca6587c6
commit 13b77d9fac
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
5 changed files with 53 additions and 17 deletions

View File

@ -14,13 +14,12 @@
package de.bixilon.minosoft.data.world
import de.bixilon.minosoft.data.entities.block.BlockEntity
import de.bixilon.minosoft.data.registries.blocks.BlockState
import de.bixilon.minosoft.data.world.biome.source.BiomeSource
import de.bixilon.minosoft.data.world.container.SectionDataProvider
import de.bixilon.minosoft.data.world.container.BlockSectionDataProvider
import glm_.vec3.Vec3i
class ChunkData(
var blocks: Array<SectionDataProvider<BlockState?>?>? = null,
var blocks: Array<BlockSectionDataProvider?>? = null,
var blockEntities: Map<Vec3i, BlockEntity>? = null,
var biomeSource: BiomeSource? = null,
var light: Array<ByteArray?>? = null,

View File

@ -14,8 +14,8 @@ package de.bixilon.minosoft.data.world
import de.bixilon.minosoft.data.entities.block.BlockEntity
import de.bixilon.minosoft.data.registries.biomes.Biome
import de.bixilon.minosoft.data.registries.blocks.BlockState
import de.bixilon.minosoft.data.world.biome.accessor.NoiseBiomeAccessor
import de.bixilon.minosoft.data.world.container.BlockSectionDataProvider
import de.bixilon.minosoft.data.world.container.SectionDataProvider
import de.bixilon.minosoft.gui.rendering.util.VecUtil.of
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
@ -28,7 +28,7 @@ import glm_.vec3.Vec3i
* Collection of 16x16x16 blocks
*/
class ChunkSection(
var blocks: SectionDataProvider<BlockState?> = SectionDataProvider(checkSize = true),
var blocks: BlockSectionDataProvider = BlockSectionDataProvider(),
var biomes: SectionDataProvider<Biome> = SectionDataProvider(checkSize = false),
var blockEntities: SectionDataProvider<BlockEntity?> = SectionDataProvider(checkSize = false),
var light: ByteArray = ByteArray(ProtocolDefinition.BLOCKS_PER_SECTION), // packed (skyLight: 0xF0, blockLight: 0x0F)

View File

@ -0,0 +1,36 @@
package de.bixilon.minosoft.data.world.container
import de.bixilon.minosoft.data.registries.blocks.BlockState
import de.bixilon.minosoft.data.registries.blocks.types.FluidBlock
import de.bixilon.minosoft.util.KUtil.unsafeCast
class BlockSectionDataProvider(
data: Array<BlockState?>? = null,
) : SectionDataProvider<BlockState?>(data, true) {
var fluidCount = 0
private set
override fun recalculate() {
super.recalculate()
val data: Array<BlockState?> = data?.unsafeCast() ?: return
fluidCount = 0
for (blockState in data) {
if (blockState?.block is FluidBlock) {
fluidCount++
}
}
}
override fun set(index: Int, value: BlockState?): BlockState? {
val previous = super.set(index, value)
if (previous?.block !is FluidBlock && value?.block is FluidBlock) {
fluidCount++
} else if (previous?.block is FluidBlock && value?.block !is FluidBlock) {
fluidCount--
}
return previous
}
}

View File

@ -19,7 +19,7 @@ import de.bixilon.minosoft.util.KUtil.unsafeCast
import de.bixilon.minosoft.util.ReadWriteLock
import glm_.vec3.Vec3i
class SectionDataProvider<T>(
open class SectionDataProvider<T>(
data: Array<T>? = null,
val checkSize: Boolean = false,
) : Iterable<T> {
@ -63,7 +63,7 @@ class SectionDataProvider<T>(
}
private fun recalculate() {
protected open fun recalculate() {
val data = data
if (data == null) {
count = 0
@ -129,20 +129,20 @@ class SectionDataProvider<T>(
set(y shl 8 or (z shl 4) or x, value)
}
operator fun set(index: Int, value: T) {
open operator fun set(index: Int, value: T): T? {
lock()
var data = data
val previous = data?.get(index)
if (value == null) {
if (previous == null) {
unlock()
return
return null
}
count--
if (count == 0) {
this.data = null
unlock()
return
return previous as T?
}
} else if (previous == null) {
count++
@ -163,6 +163,7 @@ class SectionDataProvider<T>(
}
}
unlock()
return previous as T?
}
fun acquire() {

View File

@ -22,7 +22,7 @@ import de.bixilon.minosoft.data.world.ChunkData
import de.bixilon.minosoft.data.world.ChunkSection
import de.bixilon.minosoft.data.world.biome.source.PalettedBiomeArray
import de.bixilon.minosoft.data.world.biome.source.XZBiomeArray
import de.bixilon.minosoft.data.world.container.SectionDataProvider
import de.bixilon.minosoft.data.world.container.BlockSectionDataProvider
import de.bixilon.minosoft.data.world.container.palette.PalettedContainer
import de.bixilon.minosoft.data.world.container.palette.PalettedContainerReader
import de.bixilon.minosoft.data.world.container.palette.palettes.BiomePaletteFactory
@ -67,7 +67,7 @@ object ChunkUtil {
// parse data
var arrayPosition = 0
val sectionBlocks: Array<SectionDataProvider<BlockState?>?> = arrayOfNulls(dimension.sections)
val sectionBlocks: Array<BlockSectionDataProvider?> = arrayOfNulls(dimension.sections)
for ((sectionIndex, sectionHeight) in (dimension.lowestSection until dimension.highestSection).withIndex()) {
if (!sectionBitMask[sectionIndex]) {
continue
@ -99,7 +99,7 @@ object ChunkUtil {
blocks[blockNumber] = buffer.connection.registries.blockStateRegistry[blockId] ?: continue
}
sectionBlocks[sectionHeight] = SectionDataProvider(blocks, true)
sectionBlocks[sectionHeight] = BlockSectionDataProvider(blocks)
}
chunkData.blocks = sectionBlocks
return chunkData
@ -133,7 +133,7 @@ object ChunkUtil {
}
var arrayPos = 0
val sectionBlocks: Array<SectionDataProvider<BlockState?>?> = arrayOfNulls(dimension.sections)
val sectionBlocks: Array<BlockSectionDataProvider?> = arrayOfNulls(dimension.sections)
for ((sectionIndex, sectionHeight) in (dimension.lowestSection until dimension.highestSection).withIndex()) { // max sections per chunks in chunk column
if (!sectionBitMask[sectionIndex]) {
continue
@ -144,7 +144,7 @@ object ChunkUtil {
val block = buffer.connection.registries.blockStateRegistry[blockId] ?: continue
blocks[blockNumber] = block
}
sectionBlocks[sectionHeight] = SectionDataProvider(blocks, true)
sectionBlocks[sectionHeight] = BlockSectionDataProvider(blocks)
}
chunkData.blocks = sectionBlocks
return chunkData
@ -152,7 +152,7 @@ object ChunkUtil {
fun readPaletteChunk(buffer: PlayInByteBuffer, dimension: DimensionProperties, sectionBitMask: BitSet?, isFullChunk: Boolean, containsSkyLight: Boolean = false): ChunkData {
val chunkData = ChunkData()
val sectionBlocks: Array<SectionDataProvider<BlockState?>?> = arrayOfNulls(dimension.sections)
val sectionBlocks: Array<BlockSectionDataProvider?> = arrayOfNulls(dimension.sections)
val light: Array<ByteArray?> = arrayOfNulls(dimension.sections)
var lightReceived = 0
val biomes: Array<Array<Biome>?> = arrayOfNulls(dimension.sections)
@ -169,7 +169,7 @@ object ChunkUtil {
val blockContainer: PalettedContainer<BlockState?> = PalettedContainerReader.read(buffer, buffer.connection.registries.blockStateRegistry, paletteFactory = BlockStatePaletteFactory)
if (blockContainer.palette !is SingularPalette<*> || blockContainer.palette.item != null) {
sectionBlocks[sectionHeight - dimension.lowestSection] = SectionDataProvider(blockContainer.unpack(), checkSize = true)
sectionBlocks[sectionHeight - dimension.lowestSection] = BlockSectionDataProvider(blockContainer.unpack())
}
if (buffer.versionId >= V_21W37A) {
val biomeContainer: PalettedContainer<Biome> = PalettedContainerReader.read(buffer, buffer.connection.registries.biomeRegistry, paletteFactory = BiomePaletteFactory)