diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/data/world/WorldTestUtil.kt b/src/integration-test/kotlin/de/bixilon/minosoft/data/world/WorldTestUtil.kt
index ceeae9aa1..edb114ae7 100644
--- a/src/integration-test/kotlin/de/bixilon/minosoft/data/world/WorldTestUtil.kt
+++ b/src/integration-test/kotlin/de/bixilon/minosoft/data/world/WorldTestUtil.kt
@@ -20,6 +20,8 @@ import de.bixilon.kutil.observer.DataObserver
import de.bixilon.kutil.reflection.ReflectionUtil.forceSet
import de.bixilon.minosoft.data.registries.blocks.state.BlockState
import de.bixilon.minosoft.data.registries.dimension.DimensionProperties
+import de.bixilon.minosoft.data.world.biome.WorldBiomes
+import de.bixilon.minosoft.data.world.biome.source.BiomeSource
import de.bixilon.minosoft.data.world.border.WorldBorder
import de.bixilon.minosoft.data.world.chunk.ChunkSection.Companion.getIndex
import de.bixilon.minosoft.data.world.chunk.chunk.Chunk
@@ -48,14 +50,16 @@ object WorldTestUtil {
world::entities.forceSet(WorldEntities())
world::view.forceSet(TEST_WORLD_VIEW)
world::time.forceSet(DataObserver(WorldTime()))
+ world::biomes.forceSet(WorldBiomes(world))
return world
}
- fun World.initialize(size: Int) {
+ fun World.initialize(size: Int, biome: (ChunkPosition) -> BiomeSource) {
for (x in -size..size) {
for (z in -size..size) {
- chunks.create(ChunkPosition(x, z))
+ val position = ChunkPosition(x, z)
+ chunks.create(position, biome.invoke(position))
}
}
}
diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/data/world/biome/WorldBiomesTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/data/world/biome/WorldBiomesTest.kt
new file mode 100644
index 000000000..7eb43ee23
--- /dev/null
+++ b/src/integration-test/kotlin/de/bixilon/minosoft/data/world/biome/WorldBiomesTest.kt
@@ -0,0 +1,149 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020-2023 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If not, see .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.data.world.biome
+
+import de.bixilon.minosoft.data.registries.biomes.Biome
+import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
+import de.bixilon.minosoft.data.world.World
+import de.bixilon.minosoft.data.world.WorldTestUtil.initialize
+import de.bixilon.minosoft.data.world.biome.accessor.noise.NoiseBiomeAccessor
+import de.bixilon.minosoft.data.world.biome.source.BiomeSource
+import de.bixilon.minosoft.data.world.biome.source.DummyBiomeSource
+import de.bixilon.minosoft.data.world.chunk.chunk.Chunk
+import de.bixilon.minosoft.data.world.positions.BlockPosition
+import de.bixilon.minosoft.data.world.positions.ChunkPosition
+import de.bixilon.minosoft.data.world.positions.InChunkPosition
+import de.bixilon.minosoft.protocol.network.connection.play.ConnectionTestUtil.createConnection
+import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
+import org.testng.Assert.*
+import org.testng.annotations.Test
+
+@Test(groups = ["biomes"])
+class WorldBiomesTest {
+ private val b1 = Biome(minosoft("b1"), 0.0f, 0.0f)
+ private val b2 = Biome(minosoft("b2"), 0.0f, 0.0f)
+ private val b3 = Biome(minosoft("b3"), 0.0f, 0.0f)
+
+ private fun create(noise: ((PlayConnection) -> NoiseBiomeAccessor)?, source: (ChunkPosition) -> BiomeSource): World {
+ val connection = createConnection(0)
+ connection.world.biomes.noise = noise?.invoke(connection)
+ connection.world.initialize(1, source)
+
+ return connection.world
+ }
+
+ fun `simple biome getting at origin chunk`() {
+ val world = create(null) { if (it.x == 0 && it.y == 0) PositionedSource(InChunkPosition(1, 2, 3), b1, b3) else DummyBiomeSource(b2) }
+ assertEquals(world.biomes[1, 2, 3], b1)
+ assertEquals(world.biomes[1, 2, 4], b3)
+ assertEquals(world.biomes[16, 2, 4], b2)
+ assertEquals(world.biomes[BlockPosition(1, 2, 3)], b1)
+ assertEquals(world.biomes[BlockPosition(1, 2, 4)], b3)
+ assertEquals(world.biomes[BlockPosition(16, 2, 4)], b2)
+ val chunk = world.chunks[0, 0]!!
+ assertEquals(world.biomes.getBiome(1, 2, 3, chunk), b1)
+ assertEquals(world.biomes.getBiome(1, 2, 4, chunk), b3)
+ assertEquals(chunk.getBiome(1, 2, 3), b1)
+ assertEquals(chunk.getBiome(1, 2, 4), b3)
+ }
+
+ fun `simple biome getting at chunk -1, -1`() {
+ val world = create(null) { if (it.x == -1 && it.y == -1) PositionedSource(InChunkPosition(15, 2, 14), b1, b3) else DummyBiomeSource(b2) }
+ assertEquals(world.biomes[-1, 2, -2], b1)
+ assertEquals(world.biomes[-1, 2, -6], b3)
+ assertEquals(world.biomes[1, 2, 6], b2)
+ assertEquals(world.biomes[BlockPosition(-1, 2, -2)], b1)
+ val chunk = world.chunks[-1, -1]!!
+ assertEquals(world.biomes.getBiome(15, 2, 14, chunk), b1)
+ assertEquals(world.biomes.getBiome(15, 2, 13, chunk), b3)
+ assertEquals(chunk.getBiome(15, 2, 14), b1)
+ assertEquals(chunk.getBiome(15, 2, 13), b3)
+ }
+
+ fun `ensure no caching is done without noise`() {
+ val source = CounterSource(b1)
+ val world = create(null) { source }
+ val chunk = world.chunks[0, 0]!!
+ chunk.getOrPut(0)
+
+ assertEquals(source.counter, 0)
+ assertEquals(world.biomes[1, 2, 3], b1)
+ assertEquals(source.counter, 1)
+ assertFalse(chunk.cacheBiomes)
+ assertEquals(chunk[0]!!.biomes[1, 2, 3], null)
+ }
+
+ fun `ensure caching is done with noise`() {
+ val source = CounterSource(b1)
+ val world = create({ FastNoiseAccessor(it) }) { source }
+ val chunk = world.chunks[0, 0]!!
+ chunk.getOrPut(0)
+
+ assertEquals(source.counter, 4096)
+ assertEquals(world.biomes[1, 2, 3], b1)
+ assertEquals(source.counter, 4096)
+ assertTrue(chunk.cacheBiomes)
+ assertEquals(chunk[0]!!.biomes[1, 2, 3], b1)
+ }
+
+ fun `ensure world position is converted to chunk position`() {
+ val source = VerifyPositionSource(b1)
+ val world = create(null) { source }
+
+ assertEquals(world.biomes[1, 2, 3], b1)
+ assertEquals(world.biomes[16, 2, 4], b1)
+ assertEquals(world.biomes[-4, 2, -4], b1)
+
+ assertEquals(world.biomes[-4, -2, -4], b1)
+ assertEquals(world.biomes[-4, 1024, -4], b1)
+ }
+
+
+ private class PositionedSource(
+ val position: InChunkPosition,
+ val biome: Biome?,
+ val fallback: Biome?,
+ ) : BiomeSource {
+
+ override fun getBiome(x: Int, y: Int, z: Int): Biome? {
+ if (x != position.x || y != position.y || z != position.z) return fallback
+ return biome
+ }
+ }
+
+ private class CounterSource(val biome: Biome?) : BiomeSource {
+ var counter = 0
+ override fun getBiome(x: Int, y: Int, z: Int): Biome? {
+ counter++
+ return biome
+ }
+ }
+
+ private class VerifyPositionSource(val biome: Biome?) : BiomeSource {
+ override fun getBiome(x: Int, y: Int, z: Int): Biome? {
+ if (x < 0 || x > 15) throw IllegalArgumentException("Invalid x: $x")
+ if (y < 0 || y > 255) throw IllegalArgumentException("Invalid y: $y")
+ if (z < 0 || z > 15) throw IllegalArgumentException("Invalid z: $z")
+
+ return biome
+ }
+ }
+
+ private class FastNoiseAccessor(connection: PlayConnection) : NoiseBiomeAccessor(connection, 0L) {
+
+ override fun get(x: Int, y: Int, z: Int, chunkPositionX: Int, chunkPositionZ: Int, chunk: Chunk, neighbours: Array?): Biome? {
+ return chunk.biomeSource.getBiome(x, y, z)
+ }
+ }
+}
diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/data/world/biome/accessor/NoiseBiomeAccessorTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/data/world/biome/accessor/VoronoiBiomeAccessorTest.kt
similarity index 87%
rename from src/integration-test/kotlin/de/bixilon/minosoft/data/world/biome/accessor/NoiseBiomeAccessorTest.kt
rename to src/integration-test/kotlin/de/bixilon/minosoft/data/world/biome/accessor/VoronoiBiomeAccessorTest.kt
index 399b9cd53..3dfa9885f 100644
--- a/src/integration-test/kotlin/de/bixilon/minosoft/data/world/biome/accessor/NoiseBiomeAccessorTest.kt
+++ b/src/integration-test/kotlin/de/bixilon/minosoft/data/world/biome/accessor/VoronoiBiomeAccessorTest.kt
@@ -1,6 +1,6 @@
/*
* Minosoft
- * Copyright (C) 2020-2022 Moritz Zwerger
+ * Copyright (C) 2020-2023 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.
*
@@ -14,12 +14,14 @@
package de.bixilon.minosoft.data.world.biome.accessor
import de.bixilon.kotlinglm.vec3.Vec3i
+import de.bixilon.minosoft.data.world.biome.accessor.noise.VoronoiBiomeAccessor
+import de.bixilon.minosoft.test.ITUtil.allocate
import org.objenesis.ObjenesisStd
import org.testng.Assert.assertEquals
import org.testng.annotations.Test
@Test(groups = ["biome"])
-class NoiseBiomeAccessorTest {
+class VoronoiBiomeAccessorTest {
private val OBJENESIS = ObjenesisStd()
fun testBiomeNoise1() {
@@ -51,7 +53,7 @@ class NoiseBiomeAccessorTest {
}
private fun calculate(x: Int, y: Int, z: Int, seed: Long): Vec3i {
- val accessor = OBJENESIS.newInstance(NoiseBiomeAccessor::class.java)
+ val accessor = VoronoiBiomeAccessor::class.java.allocate()
return accessor.getBiomePosition(seed, x, y, z)
}
}
diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/data/world/chunk/LightTestingUtil.kt b/src/integration-test/kotlin/de/bixilon/minosoft/data/world/chunk/LightTestingUtil.kt
index 4f8ec743d..997a1ae20 100644
--- a/src/integration-test/kotlin/de/bixilon/minosoft/data/world/chunk/LightTestingUtil.kt
+++ b/src/integration-test/kotlin/de/bixilon/minosoft/data/world/chunk/LightTestingUtil.kt
@@ -21,6 +21,7 @@ import de.bixilon.kutil.reflection.ReflectionUtil.jvmField
import de.bixilon.minosoft.data.registries.blocks.state.BlockState
import de.bixilon.minosoft.data.registries.dimension.DimensionProperties
import de.bixilon.minosoft.data.world.World
+import de.bixilon.minosoft.data.world.biome.WorldBiomes
import de.bixilon.minosoft.data.world.chunk.chunk.Chunk
import de.bixilon.minosoft.data.world.chunk.light.ChunkLight
import de.bixilon.minosoft.data.world.chunk.neighbours.ChunkNeighbours
@@ -48,6 +49,7 @@ object LightTestingUtil {
val world = objenesis.newInstance(World::class.java)
world::dimension.forceSet(DataObserver(DimensionProperties(skyLight = true)))
world::connection.forceSet(createConnection())
+ world::biomes.forceSet(WorldBiomes(world))
return world
}
diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/data/world/chunk/manager/ChunkManagerTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/data/world/chunk/manager/ChunkManagerTest.kt
index 09bf742a6..83d83cc06 100644
--- a/src/integration-test/kotlin/de/bixilon/minosoft/data/world/chunk/manager/ChunkManagerTest.kt
+++ b/src/integration-test/kotlin/de/bixilon/minosoft/data/world/chunk/manager/ChunkManagerTest.kt
@@ -17,7 +17,7 @@ import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.data.registries.biomes.Biome
import de.bixilon.minosoft.data.registries.blocks.types.stone.StoneTest0
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
-import de.bixilon.minosoft.data.world.biome.accessor.NoiseBiomeAccessor
+import de.bixilon.minosoft.data.world.biome.accessor.noise.VoronoiBiomeAccessor
import de.bixilon.minosoft.data.world.biome.source.BiomeSource
import de.bixilon.minosoft.data.world.biome.source.DummyBiomeSource
import de.bixilon.minosoft.data.world.biome.source.SpatialBiomeArray
@@ -428,7 +428,7 @@ class ChunkManagerTest {
fun noBiomeCache() {
val manager = create()
- manager.world.cacheBiomeAccessor = null
+ manager.world.biomes.noise = null
val matrix = manager.createMatrix()
val chunk = matrix[1][1]
@@ -438,7 +438,7 @@ class ChunkManagerTest {
fun noiseBiomeCache() {
val manager = create()
val biome = Biome(minosoft("test"), 0.0f, 0.0f, null, null, null, null, null)
- manager.world.cacheBiomeAccessor = NoiseBiomeAccessor(manager.world.connection, 0L)
+ manager.world.biomes.noise = VoronoiBiomeAccessor(manager.world.connection, 0L)
val source = SpatialBiomeArray(Array(1024) { biome })
val matrix = manager.createMatrix(source)
@@ -446,7 +446,7 @@ class ChunkManagerTest {
assertEquals(chunk.getOrPut(0)!!.biomes.count, 4096)
assertEquals(chunk.getOrPut(0)!!.biomes[0], biome)
- assertEquals(manager.world.getBiome(BlockPosition(5, 5, 5)), biome)
+ assertEquals(manager.world.biomes.getBiome(BlockPosition(5, 5, 5)), biome)
assertEquals(chunk.getBiome(BlockPosition(5, 5, 5)), biome)
}
}
diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/protocol/network/connection/play/ConnectionTestUtil.kt b/src/integration-test/kotlin/de/bixilon/minosoft/protocol/network/connection/play/ConnectionTestUtil.kt
index 3e53c08af..77e37d3b9 100644
--- a/src/integration-test/kotlin/de/bixilon/minosoft/protocol/network/connection/play/ConnectionTestUtil.kt
+++ b/src/integration-test/kotlin/de/bixilon/minosoft/protocol/network/connection/play/ConnectionTestUtil.kt
@@ -30,6 +30,7 @@ import de.bixilon.minosoft.data.language.lang.LanguageList
import de.bixilon.minosoft.data.registries.registries.Registries
import de.bixilon.minosoft.data.world.WorldTestUtil.createWorld
import de.bixilon.minosoft.data.world.WorldTestUtil.initialize
+import de.bixilon.minosoft.data.world.biome.source.DummyBiomeSource
import de.bixilon.minosoft.modding.event.master.EventMaster
import de.bixilon.minosoft.protocol.network.network.client.test.TestNetwork
import de.bixilon.minosoft.protocol.versions.Versions
@@ -93,7 +94,7 @@ object ConnectionTestUtil {
CAMERA.forceSet(connection, ConnectionCamera(connection))
connection.camera.init()
if (worldSize > 0) {
- connection.world.initialize(worldSize)
+ connection.world.initialize(worldSize) { DummyBiomeSource(null) }
}
return connection
}
diff --git a/src/main/java/de/bixilon/minosoft/data/registries/blocks/types/building/plants/DoublePlant.kt b/src/main/java/de/bixilon/minosoft/data/registries/blocks/types/building/plants/DoublePlant.kt
index ba33f3cab..7f2e01d91 100644
--- a/src/main/java/de/bixilon/minosoft/data/registries/blocks/types/building/plants/DoublePlant.kt
+++ b/src/main/java/de/bixilon/minosoft/data/registries/blocks/types/building/plants/DoublePlant.kt
@@ -120,7 +120,7 @@ abstract class DoublePlant(identifier: ResourceLocation, settings: BlockSettings
override val tintProvider: TintProvider? = null
override fun initTint(manager: TintManager) {
- this::tintProvider.forceSet(TallGrassTintCalculator(manager.grassTintCalculator))
+ this::tintProvider.forceSet(TallGrassTintCalculator(manager.grass))
}
companion object : BlockFactory {
@@ -135,7 +135,7 @@ abstract class DoublePlant(identifier: ResourceLocation, settings: BlockSettings
override val tintProvider: TintProvider? = null
override fun initTint(manager: TintManager) {
- this::tintProvider.forceSet(TallGrassTintCalculator(manager.grassTintCalculator))
+ this::tintProvider.forceSet(TallGrassTintCalculator(manager.grass))
}
companion object : BlockFactory {
@@ -173,7 +173,7 @@ abstract class DoublePlant(identifier: ResourceLocation, settings: BlockSettings
}
override fun initTint(manager: TintManager) {
- this::tintProvider.forceSet(TallGrassTintCalculator(manager.grassTintCalculator)) // TODO: only tint if lower block is tinted
+ this::tintProvider.forceSet(TallGrassTintCalculator(manager.grass)) // TODO: only tint if lower block is tinted
}
private class Model : PickedBlockRender {
diff --git a/src/main/java/de/bixilon/minosoft/data/registries/blocks/types/wood/LeavesBlock.kt b/src/main/java/de/bixilon/minosoft/data/registries/blocks/types/wood/LeavesBlock.kt
index fad01a653..4b083dda5 100644
--- a/src/main/java/de/bixilon/minosoft/data/registries/blocks/types/wood/LeavesBlock.kt
+++ b/src/main/java/de/bixilon/minosoft/data/registries/blocks/types/wood/LeavesBlock.kt
@@ -47,7 +47,7 @@ abstract class LeavesBlock(identifier: ResourceLocation, settings: BlockSettings
override val tintProvider: TintProvider? = null
override fun initTint(manager: TintManager) {
- this::tintProvider.forceSet(manager.foliageTintCalculator)
+ this::tintProvider.forceSet(manager.foliage)
}
override fun buildState(version: Version, settings: BlockStateSettings): BlockState {
diff --git a/src/main/java/de/bixilon/minosoft/data/world/World.kt b/src/main/java/de/bixilon/minosoft/data/world/World.kt
index 06e21064f..a57bd8e52 100644
--- a/src/main/java/de/bixilon/minosoft/data/world/World.kt
+++ b/src/main/java/de/bixilon/minosoft/data/world/World.kt
@@ -20,7 +20,6 @@ import de.bixilon.kutil.observer.DataObserver.Companion.observed
import de.bixilon.kutil.random.RandomUtil.nextInt
import de.bixilon.minosoft.data.entities.block.BlockEntity
import de.bixilon.minosoft.data.entities.entities.Entity
-import de.bixilon.minosoft.data.registries.biomes.Biome
import de.bixilon.minosoft.data.registries.blocks.state.BlockState
import de.bixilon.minosoft.data.registries.blocks.types.properties.rendering.RandomDisplayTickable
import de.bixilon.minosoft.data.registries.dimension.DimensionProperties
@@ -28,8 +27,7 @@ import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.registries.shapes.aabb.AABB
import de.bixilon.minosoft.data.world.audio.AbstractAudioPlayer
import de.bixilon.minosoft.data.world.audio.WorldAudioPlayer
-import de.bixilon.minosoft.data.world.biome.accessor.BiomeAccessor
-import de.bixilon.minosoft.data.world.biome.accessor.NoiseBiomeAccessor
+import de.bixilon.minosoft.data.world.biome.WorldBiomes
import de.bixilon.minosoft.data.world.border.WorldBorder
import de.bixilon.minosoft.data.world.chunk.chunk.Chunk
import de.bixilon.minosoft.data.world.chunk.light.ChunkLightUtil.hasSkyLight
@@ -57,10 +55,10 @@ import java.util.*
*/
class World(
val connection: PlayConnection,
-) : BiomeAccessor, WorldAudioPlayer, WorldParticleRenderer {
+) : WorldAudioPlayer, WorldParticleRenderer {
val lock = SimpleLock()
val random = Random()
- var cacheBiomeAccessor: NoiseBiomeAccessor? = null
+ val biomes = WorldBiomes(this)
val chunks = ChunkManager(this, 1000, 100)
val entities = WorldEntities()
var hardcore by observed(false)
@@ -149,14 +147,6 @@ class World(
chunks[position.chunkPosition]?.set(position.inChunkPosition, entity) // TODO: fire event if needed
}
- override fun getBiome(blockPosition: BlockPosition): Biome? {
- return chunks[blockPosition.chunkPosition]?.getBiome(blockPosition.inChunkPosition)
- }
-
- override fun getBiome(x: Int, y: Int, z: Int): Biome? {
- return this.chunks[Vec2i(x shr 4, z shr 4)]?.getBiome(x and 0x0F, y, z and 0x0F)
- }
-
fun tick() {
val simulationDistance = view.simulationDistance
val cameraPosition = connection.player.physics.positionInfo.chunkPosition
diff --git a/src/main/java/de/bixilon/minosoft/data/world/audio/WorldAudioPlayer.kt b/src/main/java/de/bixilon/minosoft/data/world/audio/WorldAudioPlayer.kt
index 0d4d093cd..b67cb06de 100644
--- a/src/main/java/de/bixilon/minosoft/data/world/audio/WorldAudioPlayer.kt
+++ b/src/main/java/de/bixilon/minosoft/data/world/audio/WorldAudioPlayer.kt
@@ -16,7 +16,7 @@ package de.bixilon.minosoft.data.world.audio
import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
-@Deprecated("")
+@Deprecated("use world.audio")
interface WorldAudioPlayer : AbstractAudioPlayer {
val audioPlayer: AbstractAudioPlayer?
diff --git a/src/main/java/de/bixilon/minosoft/data/world/biome/WorldBiomes.kt b/src/main/java/de/bixilon/minosoft/data/world/biome/WorldBiomes.kt
new file mode 100644
index 000000000..4be7344b0
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/data/world/biome/WorldBiomes.kt
@@ -0,0 +1,52 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020-2023 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If not, see .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.data.world.biome
+
+import de.bixilon.kotlinglm.func.common.clamp
+import de.bixilon.minosoft.data.registries.biomes.Biome
+import de.bixilon.minosoft.data.world.World
+import de.bixilon.minosoft.data.world.biome.accessor.BiomeAccessor
+import de.bixilon.minosoft.data.world.biome.accessor.noise.NoiseBiomeAccessor
+import de.bixilon.minosoft.data.world.chunk.chunk.Chunk
+import de.bixilon.minosoft.data.world.positions.BlockPosition
+import de.bixilon.minosoft.gui.rendering.util.VecUtil.sectionHeight
+
+class WorldBiomes(val world: World) : BiomeAccessor {
+ var noise: NoiseBiomeAccessor? = null
+ set(value) {
+ field = value
+ resetCache()
+ }
+
+ operator fun get(position: BlockPosition) = getBiome(position)
+ override fun getBiome(position: BlockPosition) = getBiome(position.x, position.y, position.z)
+
+ operator fun get(x: Int, y: Int, z: Int) = getBiome(x, y, z)
+ override fun getBiome(x: Int, y: Int, z: Int): Biome? {
+ val chunk = world.chunks[x shr 4, z shr 4] ?: return null
+ return getBiome(x and 0x0F, y.clamp(world.dimension.minY, world.dimension.maxY), z and 0x0F, chunk)
+ }
+
+ fun getBiome(x: Int, y: Int, z: Int, chunk: Chunk): Biome? {
+ val noise = this.noise ?: return chunk.biomeSource.getBiome(x, y, z)
+ chunk[y.sectionHeight]?.let { return it.biomes[x, y, z] } // access cache
+
+ return noise.get(x, y, z, chunk)
+ }
+
+
+ fun resetCache() {
+ // TODO
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/BiomeAccessor.kt b/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/BiomeAccessor.kt
index 3cbceeb19..e7795627c 100644
--- a/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/BiomeAccessor.kt
+++ b/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/BiomeAccessor.kt
@@ -1,6 +1,6 @@
/*
* Minosoft
- * Copyright (C) 2020-2022 Moritz Zwerger
+ * Copyright (C) 2020-2023 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.
*
@@ -19,8 +19,8 @@ import de.bixilon.minosoft.data.registries.biomes.Biome
interface BiomeAccessor {
- fun getBiome(blockPosition: Vec3i): Biome? {
- return getBiome(blockPosition.x, blockPosition.y, blockPosition.z)
+ fun getBiome(position: Vec3i): Biome? {
+ return getBiome(position.x, position.y, position.z)
}
fun getBiome(x: Int, y: Int, z: Int): Biome?
diff --git a/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/NullBiomeAccessor.kt b/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/NullBiomeAccessor.kt
index e3ac8294a..a9fd93c6c 100644
--- a/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/NullBiomeAccessor.kt
+++ b/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/NullBiomeAccessor.kt
@@ -1,6 +1,6 @@
/*
* Minosoft
- * Copyright (C) 2020-2022 Moritz Zwerger
+ * Copyright (C) 2020-2023 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.
*
@@ -19,7 +19,7 @@ import de.bixilon.minosoft.data.registries.biomes.Biome
object NullBiomeAccessor : BiomeAccessor {
- override fun getBiome(blockPosition: Vec3i): Biome? {
+ override fun getBiome(position: Vec3i): Biome? {
return null
}
diff --git a/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/noise/NoiseBiomeAccessor.kt b/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/noise/NoiseBiomeAccessor.kt
new file mode 100644
index 000000000..9da4de0e1
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/noise/NoiseBiomeAccessor.kt
@@ -0,0 +1,49 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020-2023 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If not, see .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.data.world.biome.accessor.noise
+
+import de.bixilon.kutil.observer.DataObserver.Companion.observe
+import de.bixilon.minosoft.data.registries.biomes.Biome
+import de.bixilon.minosoft.data.world.chunk.chunk.Chunk
+import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
+import de.bixilon.minosoft.protocol.protocol.ProtocolVersions.V_19W36A
+
+abstract class NoiseBiomeAccessor(
+ connection: PlayConnection,
+ val seed: Long = 0L,
+) {
+ protected val world = connection.world
+ protected var fastNoise = false
+
+ init {
+ val profile = connection.profiles.rendering
+ profile.performance::fastBiomeNoise.observe(this, true) { fastNoise = it }
+ }
+
+ abstract fun get(x: Int, y: Int, z: Int, chunkPositionX: Int, chunkPositionZ: Int, chunk: Chunk, neighbours: Array?): Biome?
+
+ fun get(x: Int, y: Int, z: Int, chunk: Chunk): Biome? {
+ val neighbours = chunk.neighbours.get() ?: return null
+ return get((chunk.chunkPosition.x shl 4) or x, y, (chunk.chunkPosition.y shl 4) or z, chunk.chunkPosition.x, chunk.chunkPosition.y, chunk, neighbours)
+ }
+
+
+ companion object {
+
+ fun get(connection: PlayConnection, seed: Long): NoiseBiomeAccessor? = when {
+ connection.version < V_19W36A -> null
+ else -> VoronoiBiomeAccessor(connection, seed)
+ }
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/NoiseBiomeAccessor.kt b/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/noise/VoronoiBiomeAccessor.kt
similarity index 84%
rename from src/main/java/de/bixilon/minosoft/data/world/biome/accessor/NoiseBiomeAccessor.kt
rename to src/main/java/de/bixilon/minosoft/data/world/biome/accessor/noise/VoronoiBiomeAccessor.kt
index 4e127a1d4..e18815894 100644
--- a/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/NoiseBiomeAccessor.kt
+++ b/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/noise/VoronoiBiomeAccessor.kt
@@ -11,30 +11,22 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
-package de.bixilon.minosoft.data.world.biome.accessor
+package de.bixilon.minosoft.data.world.biome.accessor.noise
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.kotlinglm.vec3.Vec3i
import de.bixilon.kutil.math.simple.DoubleMath.square
-import de.bixilon.kutil.observer.DataObserver.Companion.observe
import de.bixilon.minosoft.data.registries.biomes.Biome
import de.bixilon.minosoft.data.world.biome.source.SpatialBiomeArray
import de.bixilon.minosoft.data.world.chunk.chunk.Chunk
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
-class NoiseBiomeAccessor(
- private val connection: PlayConnection,
- var hashedSeed: Long = 0L,
-) {
- private val world = connection.world
- private var fastNoise = false
+open class VoronoiBiomeAccessor(
+ connection: PlayConnection,
+ seed: Long = 0L,
+) : NoiseBiomeAccessor(connection, seed) {
- init {
- val profile = connection.profiles.rendering
- profile.performance::fastBiomeNoise.observe(this, true) { fastNoise = it }
- }
-
- fun getBiome(x: Int, y: Int, z: Int, chunkPositionX: Int, chunkPositionZ: Int, chunk: Chunk, neighbours: Array?): Biome? {
+ override fun get(x: Int, y: Int, z: Int, chunkPositionX: Int, chunkPositionZ: Int, chunk: Chunk, neighbours: Array?): Biome? {
val biomeY = if (world.dimension.supports3DBiomes) y else 0
if (fastNoise) {
@@ -44,7 +36,7 @@ class NoiseBiomeAccessor(
return source.data[(biomeY and 0x0F) shr 2 and 0x3F shl 4 or ((z and 0x0F) shr 2 and 0x03 shl 2) or ((x and 0x0F) shr 2 and 0x03)]
}
- return getBiome(hashedSeed, x, biomeY, z, chunkPositionX, chunkPositionZ, chunk, neighbours)
+ return getBiome(seed, x, biomeY, z, chunkPositionX, chunkPositionZ, chunk, neighbours)
}
@@ -156,17 +148,17 @@ class NoiseBiomeAccessor(
ret = next(ret, y)
ret = next(ret, z)
- val xFractionSalt = distribute(ret)
+ val xSalt = distribute(ret)
ret = next(ret, seed)
- val yFractionSalt = distribute(ret)
+ val ySalt = distribute(ret)
ret = next(ret, seed)
- val zFractionSalt = distribute(ret)
+ val zSalt = distribute(ret)
- return (xFraction + xFractionSalt).square() + (yFraction + yFractionSalt).square() + (zFraction + zFractionSalt).square()
+ return (xFraction + xSalt).square() + (yFraction + ySalt).square() + (zFraction + zSalt).square()
}
private fun distribute(seed: Long): Double {
diff --git a/src/main/java/de/bixilon/minosoft/data/world/chunk/ChunkSection.kt b/src/main/java/de/bixilon/minosoft/data/world/chunk/ChunkSection.kt
index 5f4408c7f..8b95322d4 100644
--- a/src/main/java/de/bixilon/minosoft/data/world/chunk/ChunkSection.kt
+++ b/src/main/java/de/bixilon/minosoft/data/world/chunk/ChunkSection.kt
@@ -19,7 +19,7 @@ import de.bixilon.kutil.cast.CastUtil.unsafeNull
import de.bixilon.kutil.reflection.ReflectionUtil.jvmField
import de.bixilon.minosoft.data.entities.block.BlockEntity
import de.bixilon.minosoft.data.registries.biomes.Biome
-import de.bixilon.minosoft.data.world.biome.accessor.NoiseBiomeAccessor
+import de.bixilon.minosoft.data.world.biome.accessor.noise.NoiseBiomeAccessor
import de.bixilon.minosoft.data.world.chunk.chunk.Chunk
import de.bixilon.minosoft.data.world.chunk.light.SectionLight
import de.bixilon.minosoft.data.world.container.SectionDataProvider
@@ -67,7 +67,7 @@ class ChunkSection(
}
}
- fun buildBiomeCache(neighbours: Array, biomeAccessor: NoiseBiomeAccessor) {
+ fun buildBiomeCache(neighbours: Array, noise: NoiseBiomeAccessor) {
val chunkPositionX = chunk.chunkPosition.x
val chunkPositionZ = chunk.chunkPosition.y
val blockOffset = Vec3i.of(chunk.chunkPosition, sectionHeight)
@@ -76,7 +76,7 @@ class ChunkSection(
val z = blockOffset.z
val biomes: Array = arrayOfNulls(ProtocolDefinition.BLOCKS_PER_SECTION)
for (index in 0 until ProtocolDefinition.BLOCKS_PER_SECTION) {
- biomes[index] = biomeAccessor.getBiome(x + (index and 0x0F), y + ((index shr 8) and 0x0F), z + ((index shr 4) and 0x0F), chunkPositionX, chunkPositionZ, chunk, neighbours)
+ biomes[index] = noise.get(x + (index and 0x0F), y + ((index shr 8) and 0x0F), z + ((index shr 4) and 0x0F), chunkPositionX, chunkPositionZ, chunk, neighbours)
}
this.biomes.setData(biomes.cast())
}
diff --git a/src/main/java/de/bixilon/minosoft/data/world/chunk/chunk/Chunk.kt b/src/main/java/de/bixilon/minosoft/data/world/chunk/chunk/Chunk.kt
index f124bc7db..291e8a8c5 100644
--- a/src/main/java/de/bixilon/minosoft/data/world/chunk/chunk/Chunk.kt
+++ b/src/main/java/de/bixilon/minosoft/data/world/chunk/chunk/Chunk.kt
@@ -52,7 +52,7 @@ class Chunk(
val light = ChunkLight(this)
val minSection = world.dimension.minSection
val maxSection = world.dimension.maxSection
- val cacheBiomes = world.cacheBiomeAccessor != null
+ val cacheBiomes = world.biomes.noise != null
val neighbours = ChunkNeighbours(this)
@@ -187,7 +187,7 @@ class Chunk(
section.blocks.unsafeSetSection(section)
val neighbours = this.neighbours.get()
if (neighbours != null) {
- this.neighbours.completeSection(neighbours, section, sectionHeight, world.cacheBiomeAccessor)
+ this.neighbours.completeSection(neighbours, section, sectionHeight, world.biomes.noise)
}
sections[index] = section
@@ -230,11 +230,10 @@ class Chunk(
override fun getBiome(x: Int, y: Int, z: Int): Biome? {
val y = y.clamp(world.dimension.minY, world.dimension.maxY)
- if (cacheBiomes) {
- val section = this[y.sectionHeight] ?: return connection.world.cacheBiomeAccessor?.getBiome((chunkPosition.x shl 4) or x, y, (chunkPosition.y shl 4) or z, chunkPosition.x, chunkPosition.y, this, this.neighbours.get())
- return section.biomes[x, y.inSectionHeight, z]
+ if (!cacheBiomes) {
+ return biomeSource.getBiome(x, y, z)
}
- return biomeSource.getBiome(x and 0x0F, y, z and 0x0F)
+ return connection.world.biomes.getBiome(x, y, z, this)
}
}
diff --git a/src/main/java/de/bixilon/minosoft/data/world/chunk/neighbours/ChunkNeighbours.kt b/src/main/java/de/bixilon/minosoft/data/world/chunk/neighbours/ChunkNeighbours.kt
index 720c23484..1d8dcc011 100644
--- a/src/main/java/de/bixilon/minosoft/data/world/chunk/neighbours/ChunkNeighbours.kt
+++ b/src/main/java/de/bixilon/minosoft/data/world/chunk/neighbours/ChunkNeighbours.kt
@@ -18,7 +18,7 @@ import de.bixilon.kotlinglm.vec3.Vec3i
import de.bixilon.kutil.cast.CastUtil.unsafeCast
import de.bixilon.kutil.exception.Broken
import de.bixilon.minosoft.data.registries.blocks.state.BlockState
-import de.bixilon.minosoft.data.world.biome.accessor.NoiseBiomeAccessor
+import de.bixilon.minosoft.data.world.biome.accessor.noise.NoiseBiomeAccessor
import de.bixilon.minosoft.data.world.chunk.ChunkSection
import de.bixilon.minosoft.data.world.chunk.chunk.Chunk
import de.bixilon.minosoft.data.world.positions.ChunkPositionUtil.chunkPosition
@@ -70,19 +70,19 @@ class ChunkNeighbours(val chunk: Chunk) : Iterable {
remove(getIndex(offset))
}
- fun completeSection(neighbours: Array, section: ChunkSection, sectionHeight: SectionHeight, biomeCacheAccessor: NoiseBiomeAccessor?) {
+ fun completeSection(neighbours: Array, section: ChunkSection, sectionHeight: SectionHeight, noise: NoiseBiomeAccessor?) {
section.neighbours = ChunkUtil.getDirectNeighbours(neighbours, chunk, sectionHeight)
- if (biomeCacheAccessor != null) {
- section.buildBiomeCache(neighbours, biomeCacheAccessor)
+ if (noise != null) {
+ section.buildBiomeCache(neighbours, noise)
}
}
private fun complete(neighbours: Array) {
- val biomeCacheAccessor = chunk.world.cacheBiomeAccessor
+ val noise = chunk.world.biomes.noise
for ((index, section) in chunk.sections.withIndex()) {
if (section == null) continue
val sectionHeight = index + chunk.minSection
- completeSection(neighbours, section, sectionHeight, biomeCacheAccessor)
+ completeSection(neighbours, section, sectionHeight, noise)
}
chunk.light.recalculate(false)
chunk.light.propagateFromNeighbours(fireEvent = false, fireSameChunkEvent = false)
diff --git a/src/main/java/de/bixilon/minosoft/data/world/particle/WorldParticleRenderer.kt b/src/main/java/de/bixilon/minosoft/data/world/particle/WorldParticleRenderer.kt
index b45b17414..ca61de003 100644
--- a/src/main/java/de/bixilon/minosoft/data/world/particle/WorldParticleRenderer.kt
+++ b/src/main/java/de/bixilon/minosoft/data/world/particle/WorldParticleRenderer.kt
@@ -15,7 +15,7 @@ package de.bixilon.minosoft.data.world.particle
import de.bixilon.minosoft.gui.rendering.particle.types.Particle
-@Deprecated("")
+@Deprecated("use world.particle")
interface WorldParticleRenderer : AbstractParticleRenderer {
val particleRenderer: AbstractParticleRenderer?
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/tint/DefaultTints.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/tint/DefaultTints.kt
index 1a1cf6027..a58987b9f 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/tint/DefaultTints.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/tint/DefaultTints.kt
@@ -28,10 +28,10 @@ import de.bixilon.minosoft.gui.rendering.tint.tints.redstone.RedstoneWireTintCal
object DefaultTints {
fun init(manager: TintManager) {
- manager.applyTo(setOf(MinecraftBlocks.POTTED_FERN), manager.grassTintCalculator)
+ manager.applyTo(setOf(MinecraftBlocks.POTTED_FERN), manager.grass)
manager.applyTo(setOf(MinecraftBlocks.REDSTONE_WIRE), RedstoneWireTintCalculator)
manager.applyTo(setOf(MinecraftBlocks.WATER_CAULDRON, MinecraftBlocks.CAULDRON), WaterTintProvider)
- manager.applyTo(setOf(MinecraftBlocks.SUGAR_CANE), SugarCaneTintCalculator(manager.grassTintCalculator))
+ manager.applyTo(setOf(MinecraftBlocks.SUGAR_CANE), SugarCaneTintCalculator(manager.grass))
manager.applyTo(setOf(MinecraftBlocks.ATTACHED_MELON_STEM, MinecraftBlocks.ATTACHED_PUMPKIN_STEM), StaticTintProvider(0xE0C71C))
manager.applyTo(setOf(MinecraftBlocks.MELON_STEM, MinecraftBlocks.PUMPKIN_STEM), StemTintCalculator)
manager.applyTo(setOf(MinecraftBlocks.LILY_PAD), StaticTintProvider(block = 0x208030, item = 0x71C35C))
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/tint/TintManager.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/tint/TintManager.kt
index f77f8f24e..8d756cf39 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/tint/TintManager.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/tint/TintManager.kt
@@ -28,12 +28,12 @@ import de.bixilon.minosoft.gui.rendering.tint.tints.plants.FoliageTintCalculator
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
class TintManager(val connection: PlayConnection) {
- val grassTintCalculator = GrassTintCalculator()
- val foliageTintCalculator = FoliageTintCalculator()
+ val grass = GrassTintCalculator()
+ val foliage = FoliageTintCalculator()
fun init(assetsManager: AssetsManager) {
- grassTintCalculator.init(assetsManager)
- foliageTintCalculator.init(assetsManager)
+ grass.init(assetsManager)
+ foliage.init(assetsManager)
for (block in connection.registries.block) {
if (block !is TintedBlock) continue
@@ -61,7 +61,8 @@ class TintManager(val connection: PlayConnection) {
fun getParticleTint(state: BlockState, x: Int, y: Int, z: Int): Int? {
if (state.block !is TintedBlock) return null
val tintProvider = state.block.tintProvider ?: return null
- val biome = connection.world.getBiome(x, y, z)
+ // TODO: cache chunk
+ val biome = connection.world.biomes.getBiome(x, y, z)
return tintProvider.getParticleColor(state, biome, x, y, z)
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/tint/tints/grass/GrassTinted.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/tint/tints/grass/GrassTinted.kt
index 480aeda42..4c00961a8 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/tint/tints/grass/GrassTinted.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/tint/tints/grass/GrassTinted.kt
@@ -20,6 +20,6 @@ import de.bixilon.minosoft.gui.rendering.tint.TintedBlock
interface GrassTinted : TintedBlock {
override fun initTint(manager: TintManager) {
- this::class.java.getDeclaredField("tintProvider").forceSet(this, manager.grassTintCalculator)
+ this::class.java.getDeclaredField("tintProvider").forceSet(this, manager.grass)
}
}
diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/InitializeS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/InitializeS2CP.kt
index 9d946f23d..a1607e852 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/InitializeS2CP.kt
+++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/InitializeS2CP.kt
@@ -21,7 +21,7 @@ import de.bixilon.minosoft.data.entities.GlobalPosition
import de.bixilon.minosoft.data.entities.data.types.GlobalPositionEntityDataType
import de.bixilon.minosoft.data.registries.dimension.DimensionProperties
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
-import de.bixilon.minosoft.data.world.biome.accessor.NoiseBiomeAccessor
+import de.bixilon.minosoft.data.world.biome.accessor.noise.NoiseBiomeAccessor
import de.bixilon.minosoft.data.world.difficulty.Difficulties
import de.bixilon.minosoft.modding.event.events.DimensionChangeEvent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
@@ -180,9 +180,7 @@ class InitializeS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
connection.world.entities.clear(connection, local = true)
connection.world.entities.add(entityId, null, playerEntity)
- if (connection.version.versionId >= ProtocolVersions.V_19W36A && !connection.profiles.rendering.performance.fastBiomeNoise) {
- connection.world.cacheBiomeAccessor = NoiseBiomeAccessor(connection, hashedSeed)
- }
+ connection.world.biomes.noise = NoiseBiomeAccessor.get(connection, hashedSeed)
connection.world.border.reset()
if (connection.version < V_1_20_2_PRE1) {
diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/RespawnS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/RespawnS2CP.kt
index 2dff51217..c702f65aa 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/RespawnS2CP.kt
+++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/RespawnS2CP.kt
@@ -18,6 +18,7 @@ import de.bixilon.minosoft.data.entities.GlobalPosition
import de.bixilon.minosoft.data.entities.data.types.GlobalPositionEntityDataType
import de.bixilon.minosoft.data.registries.dimension.DimensionProperties
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
+import de.bixilon.minosoft.data.world.biome.accessor.noise.NoiseBiomeAccessor
import de.bixilon.minosoft.data.world.difficulty.Difficulties
import de.bixilon.minosoft.modding.event.events.DimensionChangeEvent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
@@ -114,7 +115,7 @@ class RespawnS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
}
connection.world.dimension = dimension
connection.world.name = world
- connection.world.cacheBiomeAccessor?.hashedSeed = hashedSeed
+ connection.world.biomes.noise = NoiseBiomeAccessor.get(connection, hashedSeed)
connection.state = PlayConnectionStates.SPAWNING
if (dimensionChange) {
diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/block/chunk/ChunkBiomeS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/block/chunk/ChunkBiomeS2CP.kt
index cb590143f..40f3fbc25 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/block/chunk/ChunkBiomeS2CP.kt
+++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/block/chunk/ChunkBiomeS2CP.kt
@@ -13,6 +13,7 @@
package de.bixilon.minosoft.protocol.packets.s2c.play.block.chunk
import de.bixilon.kotlinglm.vec2.Vec2i
+import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
import de.bixilon.minosoft.protocol.protocol.buffers.play.PlayInByteBuffer
import de.bixilon.minosoft.util.logging.Log
@@ -23,7 +24,7 @@ class ChunkBiomeS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
val data = buffer.readArray { ChunkBiomeData(buffer.readLongChunkPosition(), buffer.readByteArray()) }
- class ChunkBiomeData(
+ data class ChunkBiomeData(
val position: Vec2i,
val data: ByteArray,
)
@@ -33,7 +34,15 @@ class ChunkBiomeS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
return Vec2i(long.toInt(), (long shr 32).toInt())
}
- // TODO: handle
+ override fun handle(connection: PlayConnection) {
+ if (data.isEmpty()) return
+
+ for ((position, data) in data) {
+ val chunk = connection.world.chunks[position] ?: continue
+ // TODO: handle
+ }
+ connection.world.biomes.resetCache()
+ }
override fun log(reducedLog: Boolean) {
Log.log(LogMessageType.NETWORK_IN, level = LogLevels.VERBOSE) { "Chunk biome (data=$data)" }