diff --git a/src/main/java/de/bixilon/minosoft/data/player/LocalPlayerEntity.kt b/src/main/java/de/bixilon/minosoft/data/player/LocalPlayerEntity.kt index 7511604f1..6ee8c52c1 100644 --- a/src/main/java/de/bixilon/minosoft/data/player/LocalPlayerEntity.kt +++ b/src/main/java/de/bixilon/minosoft/data/player/LocalPlayerEntity.kt @@ -122,6 +122,9 @@ class LocalPlayerEntity( private val slowMovement: Boolean get() = isSneaking // ToDo: Or should leave swimming pose + override val hasCollisions: Boolean + get() = gamemode != Gamemodes.SPECTATOR + var isUsingItem = false override var activeHand: Hands? = null diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/block/WorldRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/block/WorldRenderer.kt index 59bab79b7..fc7f7e50a 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/block/WorldRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/block/WorldRenderer.kt @@ -108,13 +108,20 @@ class WorldRenderer( connection.registerEvent(CallbackEventInvoker.of { updateSection(it.blockPosition.chunkPosition, it.blockPosition.sectionHeight) }) connection.registerEvent(CallbackEventInvoker.of { val chunk = world[it.chunkPosition] ?: return@of + if (!chunk.isFullyLoaded || it.chunkPosition in incomplete) { + return@of + } + val neighbourChunks = getChunkNeighbours(getChunkNeighbourPositions(it.chunkPosition)) + if (!neighbourChunks.fullyLoaded) { + return@of + } val meshes = meshes.getOrPut(it.chunkPosition) { synchronizedMapOf() } val sectionHeights: MutableSet = mutableSetOf() for (blockPosition in it.blocks.keys) { sectionHeights += blockPosition.sectionHeight } for (sectionHeight in sectionHeights) { - updateSection(it.chunkPosition, sectionHeight, chunk, meshes) + updateSection(it.chunkPosition, sectionHeight, chunk, neighbourChunks.unsafeCast(), meshes) } }) connection.registerEvent(CallbackEventInvoker.of { unloadChunk(it.chunkPosition) }) @@ -183,6 +190,16 @@ class WorldRenderer( ) } + private val Array.fullyLoaded: Boolean + get() { + for (neighbour in this) { + if (neighbour?.isFullyLoaded != true) { + return false + } + } + return true + } + /** * Called when chunk data changes * Checks if the chunk is visible and if so, updates the mesh. If not visible, unloads the current mesh and queues it for loading @@ -192,26 +209,19 @@ class WorldRenderer( return } val neighbourPositions = getChunkNeighbourPositions(chunkPosition) - val neighbours = getChunkNeighbours(neighbourPositions) - - var neighboursLoaded = true - for (neighbour in neighbours) { - if (neighbour?.isFullyLoaded != true) { - neighboursLoaded = false - } - } + val neighbourChunks = getChunkNeighbours(neighbourPositions) if (checkQueue) { for ((index, neighbourPosition) in neighbourPositions.withIndex()) { if (neighbourPosition !in incomplete) { continue } - val neighbourChunk = neighbours[index] ?: continue + val neighbourChunk = neighbourChunks[index] ?: continue updateChunk(neighbourPosition, neighbourChunk, false) } } - if (!neighboursLoaded) { + if (!neighbourChunks.fullyLoaded) { incomplete += chunkPosition return } @@ -219,18 +229,18 @@ class WorldRenderer( val meshes = this.meshes.getOrPut(chunkPosition) { synchronizedMapOf() } for ((sectionHeight, section) in chunk.sections!!) { - updateSection(chunkPosition, sectionHeight, chunk, meshes) + updateSection(chunkPosition, sectionHeight, chunk, neighbourChunks.unsafeCast(), meshes) } } - private fun updateSection(chunkPosition: Vec2i, sectionHeight: Int, chunk: Chunk = world[chunkPosition]!!, meshes: SynchronizedMap = this.meshes.getOrPut(chunkPosition) { synchronizedMapOf() }) { + private fun updateSection(chunkPosition: Vec2i, sectionHeight: Int, chunk: Chunk = world[chunkPosition]!!, neighbourChunks: Array = getChunkNeighbours(getChunkNeighbourPositions(chunkPosition)).unsafeCast(), meshes: SynchronizedMap = this.meshes.getOrPut(chunkPosition) { synchronizedMapOf() }) { val task = ThreadPoolRunnable(priority = LOW) { - updateSectionSync(chunkPosition, sectionHeight, chunk, meshes) + updateSectionSync(chunkPosition, sectionHeight, chunk, neighbourChunks, meshes) } DefaultThreadPool += task } - private fun updateSectionSync(chunkPosition: Vec2i, sectionHeight: Int, chunk: Chunk, meshes: SynchronizedMap) { + private fun updateSectionSync(chunkPosition: Vec2i, sectionHeight: Int, chunk: Chunk, neighbourChunks: Array, meshes: SynchronizedMap) { if (!chunk.isFullyLoaded || chunkPosition in incomplete) { // chunk not loaded and/or neighbours also not fully loaded return @@ -257,7 +267,7 @@ class WorldRenderer( queue.remove(chunkPosition) } } - val neighbours = getSectionNeighbours(getChunkNeighbours(getChunkNeighbourPositions(chunkPosition)).unsafeCast(), chunk, sectionHeight) + val neighbours = getSectionNeighbours(neighbourChunks, chunk, sectionHeight) prepareSection(chunkPosition, sectionHeight, section, neighbours, meshes) } else { queue.getOrPut(chunkPosition) { synchronizedSetOf() } += sectionHeight @@ -343,9 +353,10 @@ class WorldRenderer( this.queue.remove(chunkPosition) continue } + val neighbours = getChunkNeighbours(getChunkNeighbourPositions(chunkPosition)) val meshes = this.meshes.getOrPut(chunkPosition) { synchronizedMapOf() } for (sectionHeight in sectionHeights) { - updateSection(chunkPosition, sectionHeight, chunk, meshes) + updateSection(chunkPosition, sectionHeight, chunk, neighbours.unsafeCast(), meshes) } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/block/preparer/CullSectionPreparer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/block/preparer/CullSectionPreparer.kt index 5070a60e8..08fd01676 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/block/preparer/CullSectionPreparer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/block/preparer/CullSectionPreparer.kt @@ -51,7 +51,7 @@ class CullSectionPreparer( blocks[ChunkSection.getIndex(x, y, z - 1)] } neighbourBlocks[Directions.SOUTH.ordinal] = if (z == ProtocolDefinition.SECTION_MAX_Z) { - neighbours[Directions.NORTH.ordinal]?.blocks?.get(ChunkSection.getIndex(x, y, 0)) + neighbours[Directions.SOUTH.ordinal]?.blocks?.get(ChunkSection.getIndex(x, y, 0)) } else { blocks[ChunkSection.getIndex(x, y, z + 1)] } @@ -62,7 +62,7 @@ class CullSectionPreparer( blocks[ChunkSection.getIndex(x - 1, y, z)] } neighbourBlocks[Directions.EAST.ordinal] = if (x == ProtocolDefinition.SECTION_MAX_X) { - neighbours[Directions.WEST.ordinal]?.blocks?.get(ChunkSection.getIndex(0, y, z)) + neighbours[Directions.EAST.ordinal]?.blocks?.get(ChunkSection.getIndex(0, y, z)) } else { blocks[ChunkSection.getIndex(x + 1, y, z)] } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/input/camera/Camera.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/input/camera/Camera.kt index d3598260c..5291b09a5 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/input/camera/Camera.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/input/camera/Camera.kt @@ -59,7 +59,7 @@ class Camera( val renderWindow: RenderWindow, ) { var fogColor = Previous(ChatColors.GREEN) - var fogStart = 100.0f + var fogStart = 1000.0f private var mouseSensitivity = Minosoft.config.config.game.controls.moseSensitivity @Deprecated("", ReplaceWith("connection.player")) diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/JoinGameS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/JoinGameS2CP.kt index 7777c67e4..51aec361a 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/JoinGameS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/JoinGameS2CP.kt @@ -147,7 +147,6 @@ class JoinGameS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() { } override fun handle(connection: PlayConnection) { - val gamemode = Gamemodes.SPECTATOR val playerEntity = connection.player val previousGamemode = playerEntity.tabListItem.gamemode