mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 11:24:56 -04:00
skylight: create section if not present, fix locking bugs
This commit is contained in:
parent
68af0e1f0f
commit
4f1add582d
@ -49,7 +49,7 @@ class Chunk(
|
||||
var sections: Array<ChunkSection?>? = null,
|
||||
var biomeSource: BiomeSource? = null,
|
||||
) : Iterable<ChunkSection?>, BiomeAccessor {
|
||||
private val lock = ThreadLock()
|
||||
private val lock = ThreadLock()
|
||||
private val world = connection.world
|
||||
var bottomLight = BorderSectionLight(false, this)
|
||||
var topLight = BorderSectionLight(true, this)
|
||||
@ -192,16 +192,15 @@ class Chunk(
|
||||
|
||||
fun setBlockEntity(position: Vec3i, blockEntity: BlockEntity?) = setBlockEntity(position.x, position.y, position.z, blockEntity)
|
||||
|
||||
@Synchronized
|
||||
private fun initialize(): Array<ChunkSection?> {
|
||||
val sections: Array<ChunkSection?> = arrayOfNulls(world.dimension!!.sections)
|
||||
this.sections = sections
|
||||
return sections
|
||||
private fun initialize() {
|
||||
lock.lock()
|
||||
this.sections = arrayOfNulls(world.dimension!!.sections)
|
||||
lock.unlock()
|
||||
}
|
||||
|
||||
|
||||
@Synchronized
|
||||
fun setData(data: ChunkData) {
|
||||
lock.lock()
|
||||
if (sections == null) {
|
||||
initialize()
|
||||
}
|
||||
@ -236,6 +235,7 @@ class Chunk(
|
||||
biomesInitialized = true
|
||||
}
|
||||
}
|
||||
lock.unlock()
|
||||
world.onChunkUpdate(chunkPosition, this)
|
||||
connection.fireEvent(ChunkDataChangeEvent(connection, EventInitiators.UNKNOWN, chunkPosition, this))
|
||||
}
|
||||
@ -440,9 +440,8 @@ class Chunk(
|
||||
Broken("Can not get chunk from offset: $chunkOffset")
|
||||
}
|
||||
|
||||
|
||||
@Synchronized
|
||||
private fun updateHeightmap() {
|
||||
lock.lock()
|
||||
val maxY = highestSection * ProtocolDefinition.SECTION_HEIGHT_Y
|
||||
|
||||
for (x in 0 until ProtocolDefinition.SECTION_WIDTH_X) {
|
||||
@ -450,6 +449,7 @@ class Chunk(
|
||||
checkHeightmapY(x, maxY, z)
|
||||
}
|
||||
}
|
||||
lock.unlock()
|
||||
recalculateSkylight()
|
||||
}
|
||||
|
||||
@ -506,18 +506,16 @@ class Chunk(
|
||||
}
|
||||
|
||||
private fun recalculateSkylight() {
|
||||
if (world.dimension?.hasSkyLight != true) {
|
||||
if (world.dimension?.hasSkyLight != true || this.neighbours == null) {
|
||||
// no need to calculate it
|
||||
return
|
||||
}
|
||||
lock.lock()
|
||||
for (x in 0 until ProtocolDefinition.SECTION_WIDTH_X) {
|
||||
for (z in 0 until ProtocolDefinition.SECTION_WIDTH_Z) {
|
||||
traceSkylightDown(x, z)
|
||||
startSkylightFloodFill(x, z)
|
||||
}
|
||||
}
|
||||
lock.unlock()
|
||||
}
|
||||
|
||||
private inline fun traceSkylightDown(x: Int, z: Int) {
|
||||
|
@ -152,28 +152,28 @@ class SectionLight(
|
||||
if (z > 0) {
|
||||
traceIncrease(x, y, z - 1, neighbourLuminance, Directions.SOUTH)
|
||||
} else {
|
||||
(neighbours[Directions.O_NORTH] ?: section.chunk?.neighbours?.get(ChunkNeighbours.NORTH)?.getOrPut(section.sectionHeight - 1, false))?.light?.traceIncrease(x, y, ProtocolDefinition.SECTION_MAX_Z, neighbourLuminance, Directions.SOUTH)
|
||||
neighbours[Directions.O_NORTH, ChunkNeighbours.NORTH]?.light?.traceIncrease(x, y, ProtocolDefinition.SECTION_MAX_Z, neighbourLuminance, Directions.SOUTH)
|
||||
}
|
||||
}
|
||||
if (source == null || (source != Directions.SOUTH && block?.lightProperties?.propagatesLight(source, Directions.SOUTH) != false)) {
|
||||
if (z < ProtocolDefinition.SECTION_MAX_Y) {
|
||||
traceIncrease(x, y, z + 1, neighbourLuminance, Directions.NORTH)
|
||||
} else {
|
||||
(neighbours[Directions.O_SOUTH] ?: section.chunk?.neighbours?.get(ChunkNeighbours.SOUTH)?.getOrPut(section.sectionHeight, false))?.light?.traceIncrease(x, y, 0, neighbourLuminance, Directions.NORTH)
|
||||
neighbours[Directions.O_SOUTH, ChunkNeighbours.SOUTH]?.light?.traceIncrease(x, y, 0, neighbourLuminance, Directions.NORTH)
|
||||
}
|
||||
}
|
||||
if (source == null || (source != Directions.WEST && block?.lightProperties?.propagatesLight(source, Directions.WEST) != false)) {
|
||||
if (x > 0) {
|
||||
traceIncrease(x - 1, y, z, neighbourLuminance, Directions.EAST)
|
||||
} else {
|
||||
(neighbours[Directions.O_WEST] ?: section.chunk?.neighbours?.get(ChunkNeighbours.WEST)?.getOrPut(section.sectionHeight, false))?.light?.traceIncrease(ProtocolDefinition.SECTION_MAX_X, y, z, neighbourLuminance, Directions.EAST)
|
||||
neighbours[Directions.O_WEST, ChunkNeighbours.WEST]?.light?.traceIncrease(ProtocolDefinition.SECTION_MAX_X, y, z, neighbourLuminance, Directions.EAST)
|
||||
}
|
||||
}
|
||||
if (source == null || (source != Directions.EAST && block?.lightProperties?.propagatesLight(source, Directions.EAST) != false)) {
|
||||
if (x < ProtocolDefinition.SECTION_MAX_X) {
|
||||
traceIncrease(x + 1, y, z, neighbourLuminance, Directions.WEST)
|
||||
} else {
|
||||
(neighbours[Directions.O_EAST] ?: section.chunk?.neighbours?.get(ChunkNeighbours.EAST)?.getOrPut(section.sectionHeight, false))?.light?.traceIncrease(0, y, z, neighbourLuminance, Directions.WEST)
|
||||
neighbours[Directions.O_EAST, ChunkNeighbours.EAST]?.light?.traceIncrease(0, y, z, neighbourLuminance, Directions.WEST)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -265,48 +265,53 @@ class SectionLight(
|
||||
if (direction != Directions.UP && (direction == null || light.propagatesLight(direction, Directions.DOWN))) {
|
||||
if (y > 0) {
|
||||
traceSkylight(x, y - 1, z, nextNeighbourLevel, Directions.DOWN, totalY - 1, false)
|
||||
} else {
|
||||
neighbours[Directions.O_UP]?.light?.traceSkylight(x, 0, z, nextLevel, direction, totalY, false)
|
||||
} else if (section.sectionHeight != section.chunk?.highestSection) {
|
||||
(neighbours[Directions.O_UP] ?: section.chunk?.getOrPut(section.sectionHeight + 1, false))?.light?.traceSkylight(x, 0, z, nextLevel, direction, totalY, false)
|
||||
}
|
||||
}
|
||||
if (direction != Directions.DOWN && direction != null && (light.propagatesLight(direction, Directions.UP))) {
|
||||
if (y < ProtocolDefinition.SECTION_MAX_Y) {
|
||||
traceSkylight(x, y + 1, z, nextNeighbourLevel, Directions.UP, totalY + 1, false)
|
||||
} else {
|
||||
} else if (section.sectionHeight == section.chunk?.lowestSection) {
|
||||
// ToDo: Trace through bottom light
|
||||
neighbours[Directions.O_DOWN]?.light?.traceSkylight(x, ProtocolDefinition.SECTION_MAX_Y, z, nextLevel, direction, totalY, false)
|
||||
} else {
|
||||
(neighbours[Directions.O_DOWN] ?: section.chunk?.getOrPut(section.sectionHeight - 1, false))?.light?.traceSkylight(x, ProtocolDefinition.SECTION_MAX_Y, z, nextLevel, direction, totalY, false)
|
||||
}
|
||||
}
|
||||
if (direction != Directions.NORTH && (direction == null || light.propagatesLight(direction, Directions.SOUTH))) {
|
||||
if (z > 0) {
|
||||
traceSkylight(x, y, z - 1, nextNeighbourLevel, Directions.SOUTH, totalY, false)
|
||||
} else {
|
||||
neighbours[Directions.O_NORTH]?.light?.traceSkylight(x, y, ProtocolDefinition.SECTION_MAX_Z, nextNeighbourLevel, Directions.SOUTH, totalY, false)
|
||||
neighbours[Directions.O_NORTH, ChunkNeighbours.NORTH]?.light?.traceSkylight(x, y, ProtocolDefinition.SECTION_MAX_Z, nextNeighbourLevel, Directions.SOUTH, totalY, false)
|
||||
}
|
||||
}
|
||||
if (direction != Directions.SOUTH && (direction == null || light.propagatesLight(direction, Directions.NORTH))) {
|
||||
if (z < ProtocolDefinition.SECTION_MAX_Z) {
|
||||
traceSkylight(x, y, z + 1, nextNeighbourLevel, Directions.NORTH, totalY, false)
|
||||
} else {
|
||||
neighbours[Directions.O_SOUTH]?.light?.traceSkylight(x, y, 0, nextNeighbourLevel, Directions.NORTH, totalY, false)
|
||||
neighbours[Directions.O_SOUTH, ChunkNeighbours.SOUTH]?.light?.traceSkylight(x, y, 0, nextNeighbourLevel, Directions.NORTH, totalY, false)
|
||||
}
|
||||
}
|
||||
if (direction != Directions.WEST && (direction == null || light.propagatesLight(direction, Directions.EAST))) {
|
||||
if (x > 0) {
|
||||
traceSkylight(x - 1, y, z, nextNeighbourLevel, Directions.EAST, totalY, false)
|
||||
} else {
|
||||
neighbours[Directions.O_WEST]?.light?.traceSkylight(ProtocolDefinition.SECTION_MAX_X, y, z, nextLevel, direction, totalY, false)
|
||||
neighbours[Directions.O_WEST, ChunkNeighbours.WEST]?.light?.traceSkylight(ProtocolDefinition.SECTION_MAX_X, y, z, nextLevel, direction, totalY, false)
|
||||
}
|
||||
}
|
||||
if (direction != Directions.EAST && (direction == null || light.propagatesLight(direction, Directions.WEST))) {
|
||||
if (x < ProtocolDefinition.SECTION_MAX_X) {
|
||||
traceSkylight(x + 1, y, z, nextNeighbourLevel, Directions.WEST, totalY, false)
|
||||
} else {
|
||||
neighbours[Directions.O_EAST]?.light?.traceSkylight(0, y, z, nextLevel, direction, totalY, false)
|
||||
neighbours[Directions.O_EAST, ChunkNeighbours.EAST]?.light?.traceSkylight(0, y, z, nextLevel, direction, totalY, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private operator fun Array<ChunkSection?>.get(direction: Int, neighbour: Int): ChunkSection? {
|
||||
return this[direction] ?: section.chunk?.neighbours?.get(neighbour)?.getOrPut(section.sectionHeight, false)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val BLOCK_LIGHT_MASK = 0x0F
|
||||
const val SKY_LIGHT_MASK = 0xF0
|
||||
|
Loading…
x
Reference in New Issue
Block a user