fix heightmap calculation, improve skylight

This commit is contained in:
Bixilon 2022-08-31 20:08:18 +02:00
parent 6abcc7b27a
commit ebe44035e5
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
6 changed files with 45 additions and 28 deletions

View File

@ -41,6 +41,7 @@ data class StatusEffect(
}
companion object : ResourceLocationCodec<StatusEffect> {
override fun deserialize(registries: Registries?, resourceLocation: ResourceLocation, data: Map<String, Any>): StatusEffect {
val attributes: MutableMap<ResourceLocation, EntityAttributeModifier> = mutableMapOf()
val uuidAttributes: MutableMap<UUID, EntityAttributeModifier> = mutableMapOf()

View File

@ -24,6 +24,7 @@ import de.bixilon.minosoft.data.registries.blocks.BlockState
import de.bixilon.minosoft.data.registries.blocks.types.entity.BlockWithEntity
import de.bixilon.minosoft.data.world.biome.accessor.BiomeAccessor
import de.bixilon.minosoft.data.world.biome.source.BiomeSource
import de.bixilon.minosoft.data.world.chunk.ChunkSection.Companion.getIndex
import de.bixilon.minosoft.data.world.chunk.ChunkSection.Companion.index
import de.bixilon.minosoft.data.world.chunk.light.BorderSectionLight
import de.bixilon.minosoft.data.world.container.BlockSectionDataProvider
@ -336,6 +337,7 @@ class Chunk(
}
section.light.recalculate()
}
recalculateSkylight()
}
fun calculateLight() {
@ -346,6 +348,7 @@ class Chunk(
}
section.light.calculate()
}
recalculateSkylight()
}
fun resetLight() {
@ -418,13 +421,14 @@ class Chunk(
@Synchronized
private fun updateHeightmap() {
val maxY = ((highestSection + 1) * ProtocolDefinition.SECTION_MAX_Y) - 1
val maxY = highestSection * ProtocolDefinition.SECTION_HEIGHT_Y
for (x in 0 until ProtocolDefinition.SECTION_WIDTH_X) {
z@ for (z in 0 until ProtocolDefinition.SECTION_WIDTH_Z) {
checkHeightmapY(x, maxY, z)
}
}
recalculateSkylight()
}
private fun checkHeightmapY(x: Int, startY: Int, z: Int) {
@ -443,7 +447,8 @@ class Chunk(
y -= ProtocolDefinition.SECTION_HEIGHT_Y
continue
}
if (section.blocks[x, y.inSectionHeight, z]?.isSolid == true) {
val block = section.blocks[x, y.inSectionHeight, z]
if (block == null || !block.isSolid) {
y--
continue
}
@ -479,5 +484,34 @@ class Chunk(
// we used to be the highest block, find out the block below us
checkHeightmapY(x, y - 1, z)
}
private fun recalculateSkylight() {
for (x in 0 until ProtocolDefinition.SECTION_WIDTH_X) {
for (z in 0 until ProtocolDefinition.SECTION_WIDTH_Z) {
calculateSkylight(x, z)
}
}
}
private fun calculateSkylight(x: Int, z: Int) {
val maxHeight = heightmap[(z shl 4) or x]
for (sectionHeight in highestSection - 1 downTo maxHeight.sectionHeight + 1) {
val section = sections?.get(sectionHeight - lowestSection) ?: continue
for (y in 0 until ProtocolDefinition.SECTION_HEIGHT_Y) {
val index = getIndex(x, y, z)
section.light.light[index] = (section.light.light[index].toInt() and 0x0F or 0xF0).toByte()
}
section.light.update = true
}
val maxSection = sections?.get(maxHeight.sectionHeight - lowestSection)
if (maxSection != null) {
for (y in ProtocolDefinition.SECTION_MAX_Y downTo maxHeight.inSectionHeight) {
val index = getIndex(x, y, z)
maxSection.light.light[index] = (maxSection.light.light[index].toInt() and 0x0F or 0xF0).toByte()
}
maxSection.light.update = true
}
}
}

View File

@ -152,7 +152,7 @@ class OpenGLRenderSystem(
override fun set(capability: RenderingCapabilities, status: Boolean) {
val enabled = capabilities.contains(capability)
if ((enabled && status) || (!status && !enabled)) {
if (enabled == status) {
return
}

View File

@ -106,6 +106,7 @@ class ChunkS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
when {
buffer.versionId < V_1_9_4 -> {
}
buffer.versionId < V_21W37A -> {
val blockEntities: MutableMap<Vec3i, BlockEntity> = mutableMapOf()
val positionOffset = Vec3i.of(chunkPosition, dimension.minSection, Vec3i.EMPTY)
@ -113,16 +114,18 @@ class ChunkS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
val nbt = buffer.readNBT().asJsonObject()
val position = Vec3i(nbt["x"]?.toInt() ?: continue, nbt["y"]?.toInt() ?: continue, nbt["z"]?.toInt() ?: continue) - positionOffset
val resourceLocation = (nbt["id"]?.toResourceLocation() ?: continue).fix()
val type = buffer.connection.registries.blockEntityTypeRegistry[resourceLocation] ?: let {
val type = buffer.connection.registries.blockEntityTypeRegistry[resourceLocation]
if (type == null) {
Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.WARN) { "Unknown block entity: $resourceLocation" }
null
} ?: continue
continue
}
val entity = type.build(buffer.connection)
entity.updateNBT(nbt)
blockEntities[position] = entity
}
this.chunkData.blockEntities = blockEntities
}
else -> {
val blockEntities: MutableMap<Vec3i, BlockEntity> = mutableMapOf()

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020 Moritz Zwerger
* Copyright (C) 2020-2022 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
@ -13,36 +13,16 @@
package de.bixilon.minosoft.util
object BitByte {
fun isBitSet(`in`: Long, pos: Int): Boolean {
val mask = 1L shl pos
return `in` and mask == mask
}
fun isBitSet(`in`: Int, pos: Int): Boolean {
val mask = 1 shl pos
return `in` and mask == mask
}
@JvmStatic
fun isBitMask(`in`: Int, mask: Int): Boolean {
return `in` and mask == mask
}
fun getBitCount(input: Long): Byte {
var ret: Byte = 0
for (i in 0 until java.lang.Long.SIZE) {
if (isBitSet(input, i)) {
ret++
}
}
return ret
}
fun isBitSetShort(`in`: Short, pos: Int): Boolean {
val mask = 1 shl pos
return `in`.toInt() and mask == mask
}
infix fun Int.isBit(bit: Int): Boolean {
return isBitSet(this, bit)
}

View File

@ -127,6 +127,5 @@ ${intend}Build version: $GIT_BUILD_VERSION
${intend}Commit: $GIT_COMMIT_ID_DESCRIBE_SHORT
${intend}Dirty: $GIT_DIRTY
""".removeSuffix("\n")
}
}