From eaca291c9650aa0d06dd9daef792e4bf7292671e Mon Sep 17 00:00:00 2001 From: Bixilon Date: Sat, 27 Mar 2021 17:47:44 +0100 Subject: [PATCH] biomes: correct noise biome accessor --- .../de/bixilon/minosoft/data/world/Chunk.kt | 10 +- .../bixilon/minosoft/data/world/ChunkData.kt | 8 +- .../minosoft/data/world/InChunkPosition.kt | 4 + .../de/bixilon/minosoft/data/world/World.kt | 11 +- .../biome/{ => accessor}/BiomeAccessor.kt | 4 +- .../biome/accessor/BlockBiomeAccessor.kt | 26 +++++ .../{ => accessor}/NoiseBiomeAccessor.kt | 25 ++--- .../NullBiomeAccessor.kt} | 8 +- .../biome/noise/FuzzyNoiseBiomeCalculator.kt | 104 ++++++++++++++++++ .../data/world/biome/source/BiomeSource.kt | 22 ++++ .../DummyBiomeSource.kt} | 12 +- .../world/biome/source/SpatialBiomeArray.kt | 37 +++++++ .../data/world/biome/source/XZBiomeArray.kt | 28 +++++ .../bixilon/minosoft/gui/rendering/Camera.kt | 4 +- .../gui/rendering/chunk/WorldRenderer.kt | 5 +- .../clientbound/play/PacketChunkData.kt | 4 +- .../clientbound/play/PacketJoinGame.kt | 8 ++ .../java/de/bixilon/minosoft/util/MMath.kt | 4 + .../bixilon/minosoft/util/chunk/ChunkUtil.kt | 12 +- 19 files changed, 284 insertions(+), 52 deletions(-) rename src/main/java/de/bixilon/minosoft/data/world/biome/{ => accessor}/BiomeAccessor.kt (88%) create mode 100644 src/main/java/de/bixilon/minosoft/data/world/biome/accessor/BlockBiomeAccessor.kt rename src/main/java/de/bixilon/minosoft/data/world/biome/{ => accessor}/NoiseBiomeAccessor.kt (60%) rename src/main/java/de/bixilon/minosoft/data/world/biome/{DummyBiomeAccessor.kt => accessor/NullBiomeAccessor.kt} (80%) create mode 100644 src/main/java/de/bixilon/minosoft/data/world/biome/noise/FuzzyNoiseBiomeCalculator.kt create mode 100644 src/main/java/de/bixilon/minosoft/data/world/biome/source/BiomeSource.kt rename src/main/java/de/bixilon/minosoft/data/world/biome/{XZBiomeAccessor.kt => source/DummyBiomeSource.kt} (71%) create mode 100644 src/main/java/de/bixilon/minosoft/data/world/biome/source/SpatialBiomeArray.kt create mode 100644 src/main/java/de/bixilon/minosoft/data/world/biome/source/XZBiomeArray.kt diff --git a/src/main/java/de/bixilon/minosoft/data/world/Chunk.kt b/src/main/java/de/bixilon/minosoft/data/world/Chunk.kt index 5da7e84b0..7c7baa516 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/Chunk.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/Chunk.kt @@ -13,7 +13,7 @@ package de.bixilon.minosoft.data.world import de.bixilon.minosoft.data.mappings.blocks.BlockState -import de.bixilon.minosoft.data.world.biome.BiomeAccessor +import de.bixilon.minosoft.data.world.biome.source.BiomeSource import de.bixilon.minosoft.data.world.light.LightAccessor import java.util.* @@ -22,13 +22,13 @@ import java.util.* */ class Chunk( var sections: MutableMap? = null, - var biomeAccessor: BiomeAccessor? = null, + var biomeSource: BiomeSource? = null, var lightAccessor: LightAccessor? = null, ) { private val lock = Object() val isFullyLoaded: Boolean get() { - return sections != null && biomeAccessor != null && lightAccessor != null + return sections != null && biomeSource != null && lightAccessor != null } fun getBlockState(position: InChunkPosition): BlockState? { @@ -59,8 +59,8 @@ class Chunk( getSectionOrCreate(sectionHeight).setData(chunkSection) } } - data.biomeAccessor?.let { - this.biomeAccessor = it + data.biomeSource?.let { + this.biomeSource = it } data.lightAccessor?.let { this.lightAccessor = it diff --git a/src/main/java/de/bixilon/minosoft/data/world/ChunkData.kt b/src/main/java/de/bixilon/minosoft/data/world/ChunkData.kt index aab78fdc0..d9056fc34 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/ChunkData.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/ChunkData.kt @@ -13,12 +13,12 @@ package de.bixilon.minosoft.data.world -import de.bixilon.minosoft.data.world.biome.BiomeAccessor +import de.bixilon.minosoft.data.world.biome.source.BiomeSource import de.bixilon.minosoft.data.world.light.LightAccessor data class ChunkData( var blocks: Map? = null, - var biomeAccessor: BiomeAccessor? = null, + var biomeSource: BiomeSource? = null, var lightAccessor: LightAccessor? = null, ) { @@ -26,8 +26,8 @@ data class ChunkData( data.blocks?.let { this.blocks = it } - data.biomeAccessor?.let { - this.biomeAccessor = it + data.biomeSource?.let { + this.biomeSource = it } data.lightAccessor?.let { this.lightAccessor = it diff --git a/src/main/java/de/bixilon/minosoft/data/world/InChunkPosition.kt b/src/main/java/de/bixilon/minosoft/data/world/InChunkPosition.kt index 23804d52c..2e659aad2 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/InChunkPosition.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/InChunkPosition.kt @@ -46,6 +46,10 @@ data class InChunkPosition(val x: Int, val y: Int, val z: Int) { return this + direction?.directionVector } + fun toVec3i(): Vec3i { + return Vec3i(x, y, z) + } + override fun toString(): String { return "($x $y $z)" } 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 0092aafd3..25072ab8a 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/World.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/World.kt @@ -17,7 +17,10 @@ import de.bixilon.minosoft.data.Difficulties import de.bixilon.minosoft.data.entities.block.BlockEntityMetaData import de.bixilon.minosoft.data.entities.entities.Entity import de.bixilon.minosoft.data.mappings.Dimension +import de.bixilon.minosoft.data.mappings.biomes.Biome import de.bixilon.minosoft.data.mappings.blocks.BlockState +import de.bixilon.minosoft.data.world.biome.accessor.BiomeAccessor +import de.bixilon.minosoft.data.world.biome.accessor.NullBiomeAccessor import de.bixilon.minosoft.data.world.light.WorldLightAccessor import java.util.* import java.util.concurrent.ConcurrentHashMap @@ -25,7 +28,7 @@ import java.util.concurrent.ConcurrentHashMap /** * Collection of chunks and more */ -class World { +class World : BiomeAccessor { val chunks = ConcurrentHashMap() val entityIdMap = HashBiMap.create() val entityUUIDMap = HashBiMap.create() @@ -35,6 +38,8 @@ class World { var difficulty: Difficulties? = null var difficultyLocked = false val worldLightAccessor = WorldLightAccessor(this) + var hashedSeed = 0L + var biomeAccessor: BiomeAccessor = NullBiomeAccessor fun getBlockState(blockPosition: BlockPosition): BlockState? { val chunkLocation = blockPosition.getChunkPosition() @@ -107,4 +112,8 @@ class World { setBlockEntityData(blockPosition, entityMetaData) } } + + override fun getBiome(blockPosition: BlockPosition): Biome? { + return biomeAccessor.getBiome(blockPosition) + } } diff --git a/src/main/java/de/bixilon/minosoft/data/world/biome/BiomeAccessor.kt b/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/BiomeAccessor.kt similarity index 88% rename from src/main/java/de/bixilon/minosoft/data/world/biome/BiomeAccessor.kt rename to src/main/java/de/bixilon/minosoft/data/world/biome/accessor/BiomeAccessor.kt index 24dd904a4..0277b23a1 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/biome/BiomeAccessor.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/BiomeAccessor.kt @@ -11,12 +11,12 @@ * This software is not affiliated with Mojang AB, the original developer of Minecraft. */ -package de.bixilon.minosoft.data.world.biome +package de.bixilon.minosoft.data.world.biome.accessor import de.bixilon.minosoft.data.mappings.biomes.Biome import de.bixilon.minosoft.data.world.BlockPosition interface BiomeAccessor { - fun getBiome(position: BlockPosition, is3d: Boolean = true): Biome? + fun getBiome(blockPosition: BlockPosition): Biome? } diff --git a/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/BlockBiomeAccessor.kt b/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/BlockBiomeAccessor.kt new file mode 100644 index 000000000..6d3112941 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/BlockBiomeAccessor.kt @@ -0,0 +1,26 @@ +/* + * Minosoft + * Copyright (C) 2021 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 + +import de.bixilon.minosoft.data.mappings.biomes.Biome +import de.bixilon.minosoft.data.world.BlockPosition +import de.bixilon.minosoft.data.world.World + +class BlockBiomeAccessor(private val world: World) : BiomeAccessor { + + override fun getBiome(blockPosition: BlockPosition): Biome? { + val biomePosition = blockPosition.getInChunkPosition().toVec3i() + return world.getChunk(blockPosition.getChunkPosition())?.biomeSource?.getBiome(biomePosition) + } +} diff --git a/src/main/java/de/bixilon/minosoft/data/world/biome/NoiseBiomeAccessor.kt b/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/NoiseBiomeAccessor.kt similarity index 60% rename from src/main/java/de/bixilon/minosoft/data/world/biome/NoiseBiomeAccessor.kt rename to src/main/java/de/bixilon/minosoft/data/world/biome/accessor/NoiseBiomeAccessor.kt index 4011712e3..0e99ccd5c 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/biome/NoiseBiomeAccessor.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/NoiseBiomeAccessor.kt @@ -11,29 +11,22 @@ * This software is not affiliated with Mojang AB, the original developer of Minecraft. */ -package de.bixilon.minosoft.data.world.biome +package de.bixilon.minosoft.data.world.biome.accessor import de.bixilon.minosoft.data.mappings.biomes.Biome import de.bixilon.minosoft.data.world.BlockPosition +import de.bixilon.minosoft.data.world.World +import de.bixilon.minosoft.data.world.biome.noise.FuzzyNoiseBiomeCalculator -class NoiseBiomeAccessor( - private val biomes: Array, -) : BiomeAccessor { +class NoiseBiomeAccessor(private val world: World) : BiomeAccessor { + private val blockBiomeAccessor = BlockBiomeAccessor(world) - override fun getBiome(position: BlockPosition, is3d: Boolean): Biome? { - val inChunk = position.getInChunkSectionPosition() - val y = if (is3d) { - inChunk.y / 4 * 16 + override fun getBiome(blockPosition: BlockPosition): Biome? { + val y = if (world.dimension?.supports3DBiomes == true) { + blockPosition.y } else { 0 } - val index = (y + ((inChunk.z / 4 * 4) + (inChunk.x / 4))) - if (index < 0 || index > biomes.size) { - return null - } - - return biomes[index] - - // ToDo: This value is pseudo randomly generated. It depends on the seed of the world (received in join game). + return FuzzyNoiseBiomeCalculator.getBiome(world.hashedSeed, blockPosition.x, y, blockPosition.z, world) } } diff --git a/src/main/java/de/bixilon/minosoft/data/world/biome/DummyBiomeAccessor.kt b/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/NullBiomeAccessor.kt similarity index 80% rename from src/main/java/de/bixilon/minosoft/data/world/biome/DummyBiomeAccessor.kt rename to src/main/java/de/bixilon/minosoft/data/world/biome/accessor/NullBiomeAccessor.kt index d8376dce5..e2809470a 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/biome/DummyBiomeAccessor.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/biome/accessor/NullBiomeAccessor.kt @@ -11,14 +11,14 @@ * This software is not affiliated with Mojang AB, the original developer of Minecraft. */ -package de.bixilon.minosoft.data.world.biome +package de.bixilon.minosoft.data.world.biome.accessor import de.bixilon.minosoft.data.mappings.biomes.Biome import de.bixilon.minosoft.data.world.BlockPosition -class DummyBiomeAccessor(private val biome: Biome) : BiomeAccessor { +object NullBiomeAccessor : BiomeAccessor { - override fun getBiome(position: BlockPosition, is3d: Boolean): Biome { - return biome + override fun getBiome(blockPosition: BlockPosition): Biome? { + return null } } diff --git a/src/main/java/de/bixilon/minosoft/data/world/biome/noise/FuzzyNoiseBiomeCalculator.kt b/src/main/java/de/bixilon/minosoft/data/world/biome/noise/FuzzyNoiseBiomeCalculator.kt new file mode 100644 index 000000000..e426c7196 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/world/biome/noise/FuzzyNoiseBiomeCalculator.kt @@ -0,0 +1,104 @@ +package de.bixilon.minosoft.data.world.biome.noise + +import de.bixilon.minosoft.data.mappings.biomes.Biome +import de.bixilon.minosoft.data.world.ChunkPosition +import de.bixilon.minosoft.data.world.World +import de.bixilon.minosoft.util.MMath.square +import glm_.vec3.Vec3i + +object FuzzyNoiseBiomeCalculator { + + fun getBiome(seed: Long, x: Int, y: Int, z: Int, world: World): Biome? { + val m = x - 2 + val n = y - 2 + val o = z - 2 + + val p = m shr 2 + val q = n shr 2 + val r = o shr 2 + + val d = (m and 0x03) / 4.0 + val e = (n and 0x03) / 4.0 + val f = (o and 0x03) / 4.0 + + var s = 0 + var g = Double.POSITIVE_INFINITY + + fun calculateFraction(a: Int, mask: Int, first: Int, second: Double): Pair { + (a and mask == 0).let { + return Pair( + if (it) first else first + 1, + if (it) second else second - 1.0 + ) + } + } + + fun checkMask(mask: Int, value: Int): Int { + return if (s and mask == 0) { + value + } else { + value + 1 + } + } + + for (i in 0 until 8) { + val (u, xFraction) = calculateFraction(i, 0x04, p, d) + val (v, yFraction) = calculateFraction(i, 0x02, q, e) + val (w, zFraction) = calculateFraction(i, 0x01, r, f) + + + val d3 = calculateFiddle(seed, u, v, w, xFraction, yFraction, zFraction) + if (g > d3) { + s = i + g = d3 + } + } + + val biomeX = checkMask(0x04, p) + val biomeY = checkMask(0x02, q) + val biomeZ = checkMask(0x01, r) + + return world.getChunk(ChunkPosition(biomeX shr 2, biomeZ shr 2))?.biomeSource?.getBiome(Vec3i(biomeX, biomeY, biomeZ)) + } + + private fun calculateFiddle(seed: Long, x: Int, y: Int, z: Int, xFraction: Double, yFraction: Double, zFraction: Double): Double { + var ret = seed + + ret = next(ret, x) + ret = next(ret, y) + ret = next(ret, z) + ret = next(ret, x) + ret = next(ret, y) + ret = next(ret, z) + + val xFractionSalt = distribute(ret) + + ret = next(ret, seed) + + val yFractionSalt = distribute(ret) + + ret = next(ret, seed) + + val zFractionSalt = distribute(ret) + + return square(xFraction + xFractionSalt) + square(yFraction + yFractionSalt) + square(zFraction + zFractionSalt) + } + + private fun distribute(seed: Long): Double { + val d = Math.floorMod(seed shr 24, 1024L).toInt() / 1024.0 + return (d - 0.5) * 0.9 + } + + // https://en.wikipedia.org/wiki/Linear_congruential_generator + private fun next(seed: Long): Long { + return seed * (seed * 6364136223846793005L + 1442695040888963407L) + } + + private fun next(seed: Long, salt: Int): Long { + return next(seed) + salt + } + + private fun next(seed: Long, salt: Long): Long { + return next(seed) + salt + } +} diff --git a/src/main/java/de/bixilon/minosoft/data/world/biome/source/BiomeSource.kt b/src/main/java/de/bixilon/minosoft/data/world/biome/source/BiomeSource.kt new file mode 100644 index 000000000..92f13a349 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/world/biome/source/BiomeSource.kt @@ -0,0 +1,22 @@ +/* + * Minosoft + * Copyright (C) 2021 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.source + +import de.bixilon.minosoft.data.mappings.biomes.Biome +import glm_.vec3.Vec3i + +interface BiomeSource { + + fun getBiome(position: Vec3i): Biome? +} diff --git a/src/main/java/de/bixilon/minosoft/data/world/biome/XZBiomeAccessor.kt b/src/main/java/de/bixilon/minosoft/data/world/biome/source/DummyBiomeSource.kt similarity index 71% rename from src/main/java/de/bixilon/minosoft/data/world/biome/XZBiomeAccessor.kt rename to src/main/java/de/bixilon/minosoft/data/world/biome/source/DummyBiomeSource.kt index 8af1d6d25..05d2f4ccf 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/biome/XZBiomeAccessor.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/biome/source/DummyBiomeSource.kt @@ -11,16 +11,14 @@ * This software is not affiliated with Mojang AB, the original developer of Minecraft. */ -package de.bixilon.minosoft.data.world.biome +package de.bixilon.minosoft.data.world.biome.source import de.bixilon.minosoft.data.mappings.biomes.Biome -import de.bixilon.minosoft.data.world.BlockPosition +import glm_.vec3.Vec3i -class XZBiomeAccessor( - private val biomes: Array, -) : BiomeAccessor { +class DummyBiomeSource(private val biome: Biome) : BiomeSource { - override fun getBiome(position: BlockPosition, is3d: Boolean): Biome { - return biomes[(position.x and 0x0F) or ((position.z and 0x0F) shl 4)] + override fun getBiome(position: Vec3i): Biome { + return biome } } diff --git a/src/main/java/de/bixilon/minosoft/data/world/biome/source/SpatialBiomeArray.kt b/src/main/java/de/bixilon/minosoft/data/world/biome/source/SpatialBiomeArray.kt new file mode 100644 index 000000000..e3e7c94ee --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/world/biome/source/SpatialBiomeArray.kt @@ -0,0 +1,37 @@ +/* + * Minosoft + * Copyright (C) 2021 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.source + +import de.bixilon.minosoft.data.mappings.biomes.Biome +import de.bixilon.minosoft.util.MMath +import glm_.vec3.Vec3i + +class SpatialBiomeArray(private val data: Array) : BiomeSource { + + override fun getBiome(position: Vec3i): Biome { + val index = (MMath.clamp(position.y, 0, Y_BIT_MASK)) shl 2 * X_SECTION_COUNT + X_SECTION_COUNT or + ((position.z and X_BIT_MASK) shl X_SECTION_COUNT) or + (position.x and X_BIT_MASK) + + return this.data[index] + } + + companion object { + private const val X_SECTION_COUNT = 2 + private const val Y_SECTION_COUNT = 6 + + private const val X_BIT_MASK = (1 shl X_SECTION_COUNT) - 1 + private const val Y_BIT_MASK = (1 shl Y_SECTION_COUNT) - 1 + } +} diff --git a/src/main/java/de/bixilon/minosoft/data/world/biome/source/XZBiomeArray.kt b/src/main/java/de/bixilon/minosoft/data/world/biome/source/XZBiomeArray.kt new file mode 100644 index 000000000..77cabee50 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/world/biome/source/XZBiomeArray.kt @@ -0,0 +1,28 @@ +/* + * Minosoft + * Copyright (C) 2021 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.source + +import de.bixilon.minosoft.data.mappings.biomes.Biome +import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition +import glm_.vec3.Vec3i + +class XZBiomeArray(private val biomes: Array) : BiomeSource { + init { + check(biomes.size == ProtocolDefinition.SECTION_WIDTH_X * ProtocolDefinition.SECTION_WIDTH_Z) { "Biome array size does not match the xz block count!" } + } + + override fun getBiome(position: Vec3i): Biome { + return biomes[(position.x and 0x0F) or ((position.z and 0x0F) shl 4)] + } +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/Camera.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/Camera.kt index 45cb45610..97ec6a808 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/Camera.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/Camera.kt @@ -206,14 +206,14 @@ class Camera( headLocation = Position(cameraPosition) feetLocation = Position(headLocation.x, headLocation.y - PLAYER_HEIGHT, headLocation.z) blockPosition = feetLocation.toBlockPosition() - currentBiome = connection.player.world.getChunk(blockPosition.getChunkPosition())?.biomeAccessor?.getBiome(blockPosition, connection.player.world.dimension?.supports3DBiomes ?: false) + currentBiome = connection.player.world.getBiome(blockPosition) chunkPosition = blockPosition.getChunkPosition() sectionHeight = blockPosition.getSectionHeight() inChunkSectionPosition = blockPosition.getInChunkSectionPosition() // recalculate sky color for current biome val blockPosition = Position(cameraPosition).toBlockPosition() - renderWindow.setSkyColor(connection.player.world.getChunk(blockPosition.getChunkPosition())?.biomeAccessor?.getBiome(blockPosition, connection.player.world.dimension?.supports3DBiomes ?: false)?.skyColor ?: RenderConstants.DEFAULT_SKY_COLOR) + renderWindow.setSkyColor(connection.player.world.getBiome(blockPosition)?.skyColor ?: RenderConstants.DEFAULT_SKY_COLOR) frustum.recalculate() renderWindow.worldRenderer.recalculateVisibleChunks() diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt index e7f2db85a..d3f3c7861 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt @@ -54,8 +54,6 @@ class WorldRenderer( queuedChunks.remove(chunkPosition) } val chunk = world.getChunk(chunkPosition) ?: error("Chunk in world is null at $chunkPosition?") - - val dimensionSupports3dBiomes = connection.player.world.dimension?.supports3DBiomes ?: false val meshCollection = ChunkMeshCollection() for ((sectionHeight, section) in sections) { @@ -70,7 +68,8 @@ class WorldRenderer( neighborBlocks[direction.ordinal] = world.getBlockState(blockPosition + direction) } - val biome = chunk.biomeAccessor!!.getBiome(blockPosition, dimensionSupports3dBiomes) + + val biome = world.getBiome(blockPosition) var tintColor: RGBColor? = null diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketChunkData.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketChunkData.kt index 73fb722e2..a4b47b7d2 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketChunkData.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketChunkData.kt @@ -17,7 +17,7 @@ import de.bixilon.minosoft.data.mappings.tweaker.VersionTweaker import de.bixilon.minosoft.data.world.BlockPosition import de.bixilon.minosoft.data.world.ChunkData import de.bixilon.minosoft.data.world.ChunkPosition -import de.bixilon.minosoft.data.world.biome.NoiseBiomeAccessor +import de.bixilon.minosoft.data.world.biome.source.SpatialBiomeArray import de.bixilon.minosoft.modding.event.events.BlockEntityMetaDataChangeEvent import de.bixilon.minosoft.modding.event.events.ChunkDataChangeEvent import de.bixilon.minosoft.protocol.network.Connection @@ -83,7 +83,7 @@ class PacketChunkData : ClientboundPacket() { heightMap = buffer.readNBT() as CompoundTag } if (!isFullChunk) { - chunkData!!.biomeAccessor = NoiseBiomeAccessor(buffer.readBiomeArray()) + chunkData!!.biomeSource = SpatialBiomeArray(buffer.readBiomeArray()) } val size = buffer.readVarInt() val lastPos = buffer.position diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketJoinGame.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketJoinGame.kt index cdfe8538d..a66d24e26 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketJoinGame.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketJoinGame.kt @@ -19,6 +19,8 @@ import de.bixilon.minosoft.data.LevelTypes import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity import de.bixilon.minosoft.data.mappings.Dimension import de.bixilon.minosoft.data.mappings.ResourceLocation +import de.bixilon.minosoft.data.world.biome.accessor.BlockBiomeAccessor +import de.bixilon.minosoft.data.world.biome.accessor.NoiseBiomeAccessor import de.bixilon.minosoft.modding.event.events.JoinGameEvent import de.bixilon.minosoft.protocol.network.Connection import de.bixilon.minosoft.protocol.packets.ClientboundPacket @@ -142,6 +144,12 @@ class PacketJoinGame : ClientboundPacket() { val entity = PlayerEntity(connection, entityId, connection.player.playerUUID, null, null, connection.player.playerName, null, null) connection.player.entity = entity connection.player.world.addEntity(entity) + connection.player.world.hashedSeed = hashedSeed + connection.player.world.biomeAccessor = if (connection.version.versionId < ProtocolVersions.V_19W36A) { + BlockBiomeAccessor(connection.player.world) + } else { + NoiseBiomeAccessor(connection.player.world) + } connection.sender.sendChatMessage("I am alive! ~ Minosoft") } diff --git a/src/main/java/de/bixilon/minosoft/util/MMath.kt b/src/main/java/de/bixilon/minosoft/util/MMath.kt index 40679840d..dbed74e06 100644 --- a/src/main/java/de/bixilon/minosoft/util/MMath.kt +++ b/src/main/java/de/bixilon/minosoft/util/MMath.kt @@ -62,4 +62,8 @@ object MMath { } return intValue } + + fun square(d: Double): Double { + return d * d + } } diff --git a/src/main/java/de/bixilon/minosoft/util/chunk/ChunkUtil.kt b/src/main/java/de/bixilon/minosoft/util/chunk/ChunkUtil.kt index 8288cfeac..ff3968167 100644 --- a/src/main/java/de/bixilon/minosoft/util/chunk/ChunkUtil.kt +++ b/src/main/java/de/bixilon/minosoft/util/chunk/ChunkUtil.kt @@ -18,7 +18,7 @@ import de.bixilon.minosoft.data.mappings.biomes.Biome import de.bixilon.minosoft.data.mappings.blocks.BlockState import de.bixilon.minosoft.data.world.ChunkData import de.bixilon.minosoft.data.world.ChunkSection -import de.bixilon.minosoft.data.world.biome.XZBiomeAccessor +import de.bixilon.minosoft.data.world.biome.source.XZBiomeArray import de.bixilon.minosoft.data.world.light.DummyLightAccessor import de.bixilon.minosoft.data.world.palette.Palette.Companion.choosePalette import de.bixilon.minosoft.protocol.protocol.InByteBuffer @@ -53,7 +53,7 @@ object ChunkUtil { } val addBlockData = buffer.readBytes(addBitMask.cardinality() * (ProtocolDefinition.BLOCKS_PER_SECTION / 2)) if (isFullChunk) { - chunkData.biomeAccessor = readLegacyBiomeArray(buffer) + chunkData.biomeSource = readLegacyBiomeArray(buffer) } // parse data @@ -123,7 +123,7 @@ object ChunkUtil { skyLight = buffer.readBytes(totalHalfEntries) } if (isFullChunk) { - chunkData.biomeAccessor = readLegacyBiomeArray(buffer) + chunkData.biomeSource = readLegacyBiomeArray(buffer) } var arrayPos = 0 @@ -200,14 +200,14 @@ object ChunkUtil { chunkData.blocks = sectionMap if (buffer.versionId < V_19W36A && isFullChunk) { - chunkData.biomeAccessor = readLegacyBiomeArray(buffer) + chunkData.biomeSource = readLegacyBiomeArray(buffer) } return chunkData } - private fun readLegacyBiomeArray(buffer: InByteBuffer): XZBiomeAccessor { + private fun readLegacyBiomeArray(buffer: InByteBuffer): XZBiomeArray { val biomes: MutableList = mutableListOf() for (i in 0 until ProtocolDefinition.SECTION_WIDTH_X * ProtocolDefinition.SECTION_WIDTH_Z) { biomes.add(i, buffer.connection.mapping.biomeRegistry.get(if (buffer.versionId < V_15W35A) { @@ -216,6 +216,6 @@ object ChunkUtil { buffer.readInt() })) } - return XZBiomeAccessor(biomes.toTypedArray()) + return XZBiomeArray(biomes.toTypedArray()) } }