mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-14 09:56:37 -04:00
biomes: correct noise biome accessor
This commit is contained in:
parent
56eec8fb73
commit
eaca291c96
@ -13,7 +13,7 @@
|
|||||||
package de.bixilon.minosoft.data.world
|
package de.bixilon.minosoft.data.world
|
||||||
|
|
||||||
import de.bixilon.minosoft.data.mappings.blocks.BlockState
|
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 de.bixilon.minosoft.data.world.light.LightAccessor
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@ -22,13 +22,13 @@ import java.util.*
|
|||||||
*/
|
*/
|
||||||
class Chunk(
|
class Chunk(
|
||||||
var sections: MutableMap<Int, ChunkSection>? = null,
|
var sections: MutableMap<Int, ChunkSection>? = null,
|
||||||
var biomeAccessor: BiomeAccessor? = null,
|
var biomeSource: BiomeSource? = null,
|
||||||
var lightAccessor: LightAccessor? = null,
|
var lightAccessor: LightAccessor? = null,
|
||||||
) {
|
) {
|
||||||
private val lock = Object()
|
private val lock = Object()
|
||||||
val isFullyLoaded: Boolean
|
val isFullyLoaded: Boolean
|
||||||
get() {
|
get() {
|
||||||
return sections != null && biomeAccessor != null && lightAccessor != null
|
return sections != null && biomeSource != null && lightAccessor != null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getBlockState(position: InChunkPosition): BlockState? {
|
fun getBlockState(position: InChunkPosition): BlockState? {
|
||||||
@ -59,8 +59,8 @@ class Chunk(
|
|||||||
getSectionOrCreate(sectionHeight).setData(chunkSection)
|
getSectionOrCreate(sectionHeight).setData(chunkSection)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data.biomeAccessor?.let {
|
data.biomeSource?.let {
|
||||||
this.biomeAccessor = it
|
this.biomeSource = it
|
||||||
}
|
}
|
||||||
data.lightAccessor?.let {
|
data.lightAccessor?.let {
|
||||||
this.lightAccessor = it
|
this.lightAccessor = it
|
||||||
|
@ -13,12 +13,12 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.data.world
|
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
|
import de.bixilon.minosoft.data.world.light.LightAccessor
|
||||||
|
|
||||||
data class ChunkData(
|
data class ChunkData(
|
||||||
var blocks: Map<Int, ChunkSection>? = null,
|
var blocks: Map<Int, ChunkSection>? = null,
|
||||||
var biomeAccessor: BiomeAccessor? = null,
|
var biomeSource: BiomeSource? = null,
|
||||||
var lightAccessor: LightAccessor? = null,
|
var lightAccessor: LightAccessor? = null,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@ -26,8 +26,8 @@ data class ChunkData(
|
|||||||
data.blocks?.let {
|
data.blocks?.let {
|
||||||
this.blocks = it
|
this.blocks = it
|
||||||
}
|
}
|
||||||
data.biomeAccessor?.let {
|
data.biomeSource?.let {
|
||||||
this.biomeAccessor = it
|
this.biomeSource = it
|
||||||
}
|
}
|
||||||
data.lightAccessor?.let {
|
data.lightAccessor?.let {
|
||||||
this.lightAccessor = it
|
this.lightAccessor = it
|
||||||
|
@ -46,6 +46,10 @@ data class InChunkPosition(val x: Int, val y: Int, val z: Int) {
|
|||||||
return this + direction?.directionVector
|
return this + direction?.directionVector
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun toVec3i(): Vec3i {
|
||||||
|
return Vec3i(x, y, z)
|
||||||
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "($x $y $z)"
|
return "($x $y $z)"
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,10 @@ import de.bixilon.minosoft.data.Difficulties
|
|||||||
import de.bixilon.minosoft.data.entities.block.BlockEntityMetaData
|
import de.bixilon.minosoft.data.entities.block.BlockEntityMetaData
|
||||||
import de.bixilon.minosoft.data.entities.entities.Entity
|
import de.bixilon.minosoft.data.entities.entities.Entity
|
||||||
import de.bixilon.minosoft.data.mappings.Dimension
|
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.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 de.bixilon.minosoft.data.world.light.WorldLightAccessor
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
@ -25,7 +28,7 @@ import java.util.concurrent.ConcurrentHashMap
|
|||||||
/**
|
/**
|
||||||
* Collection of chunks and more
|
* Collection of chunks and more
|
||||||
*/
|
*/
|
||||||
class World {
|
class World : BiomeAccessor {
|
||||||
val chunks = ConcurrentHashMap<ChunkPosition, Chunk>()
|
val chunks = ConcurrentHashMap<ChunkPosition, Chunk>()
|
||||||
val entityIdMap = HashBiMap.create<Int, Entity>()
|
val entityIdMap = HashBiMap.create<Int, Entity>()
|
||||||
val entityUUIDMap = HashBiMap.create<UUID, Entity>()
|
val entityUUIDMap = HashBiMap.create<UUID, Entity>()
|
||||||
@ -35,6 +38,8 @@ class World {
|
|||||||
var difficulty: Difficulties? = null
|
var difficulty: Difficulties? = null
|
||||||
var difficultyLocked = false
|
var difficultyLocked = false
|
||||||
val worldLightAccessor = WorldLightAccessor(this)
|
val worldLightAccessor = WorldLightAccessor(this)
|
||||||
|
var hashedSeed = 0L
|
||||||
|
var biomeAccessor: BiomeAccessor = NullBiomeAccessor
|
||||||
|
|
||||||
fun getBlockState(blockPosition: BlockPosition): BlockState? {
|
fun getBlockState(blockPosition: BlockPosition): BlockState? {
|
||||||
val chunkLocation = blockPosition.getChunkPosition()
|
val chunkLocation = blockPosition.getChunkPosition()
|
||||||
@ -107,4 +112,8 @@ class World {
|
|||||||
setBlockEntityData(blockPosition, entityMetaData)
|
setBlockEntityData(blockPosition, entityMetaData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getBiome(blockPosition: BlockPosition): Biome? {
|
||||||
|
return biomeAccessor.getBiome(blockPosition)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,12 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* 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.mappings.biomes.Biome
|
||||||
import de.bixilon.minosoft.data.world.BlockPosition
|
import de.bixilon.minosoft.data.world.BlockPosition
|
||||||
|
|
||||||
interface BiomeAccessor {
|
interface BiomeAccessor {
|
||||||
|
|
||||||
fun getBiome(position: BlockPosition, is3d: Boolean = true): Biome?
|
fun getBiome(blockPosition: BlockPosition): Biome?
|
||||||
}
|
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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)
|
||||||
|
}
|
||||||
|
}
|
@ -11,29 +11,22 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* 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.mappings.biomes.Biome
|
||||||
import de.bixilon.minosoft.data.world.BlockPosition
|
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(
|
class NoiseBiomeAccessor(private val world: World) : BiomeAccessor {
|
||||||
private val biomes: Array<Biome>,
|
private val blockBiomeAccessor = BlockBiomeAccessor(world)
|
||||||
) : BiomeAccessor {
|
|
||||||
|
|
||||||
override fun getBiome(position: BlockPosition, is3d: Boolean): Biome? {
|
override fun getBiome(blockPosition: BlockPosition): Biome? {
|
||||||
val inChunk = position.getInChunkSectionPosition()
|
val y = if (world.dimension?.supports3DBiomes == true) {
|
||||||
val y = if (is3d) {
|
blockPosition.y
|
||||||
inChunk.y / 4 * 16
|
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
val index = (y + ((inChunk.z / 4 * 4) + (inChunk.x / 4)))
|
return FuzzyNoiseBiomeCalculator.getBiome(world.hashedSeed, blockPosition.x, y, blockPosition.z, world)
|
||||||
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).
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -11,14 +11,14 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* 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.mappings.biomes.Biome
|
||||||
import de.bixilon.minosoft.data.world.BlockPosition
|
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 {
|
override fun getBiome(blockPosition: BlockPosition): Biome? {
|
||||||
return biome
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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<Int, Double> {
|
||||||
|
(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
|
||||||
|
}
|
||||||
|
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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?
|
||||||
|
}
|
@ -11,16 +11,14 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* 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.mappings.biomes.Biome
|
||||||
import de.bixilon.minosoft.data.world.BlockPosition
|
import glm_.vec3.Vec3i
|
||||||
|
|
||||||
class XZBiomeAccessor(
|
class DummyBiomeSource(private val biome: Biome) : BiomeSource {
|
||||||
private val biomes: Array<Biome>,
|
|
||||||
) : BiomeAccessor {
|
|
||||||
|
|
||||||
override fun getBiome(position: BlockPosition, is3d: Boolean): Biome {
|
override fun getBiome(position: Vec3i): Biome {
|
||||||
return biomes[(position.x and 0x0F) or ((position.z and 0x0F) shl 4)]
|
return biome
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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<Biome>) : 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
|
||||||
|
}
|
||||||
|
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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<Biome>) : 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)]
|
||||||
|
}
|
||||||
|
}
|
@ -206,14 +206,14 @@ class Camera(
|
|||||||
headLocation = Position(cameraPosition)
|
headLocation = Position(cameraPosition)
|
||||||
feetLocation = Position(headLocation.x, headLocation.y - PLAYER_HEIGHT, headLocation.z)
|
feetLocation = Position(headLocation.x, headLocation.y - PLAYER_HEIGHT, headLocation.z)
|
||||||
blockPosition = feetLocation.toBlockPosition()
|
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()
|
chunkPosition = blockPosition.getChunkPosition()
|
||||||
sectionHeight = blockPosition.getSectionHeight()
|
sectionHeight = blockPosition.getSectionHeight()
|
||||||
inChunkSectionPosition = blockPosition.getInChunkSectionPosition()
|
inChunkSectionPosition = blockPosition.getInChunkSectionPosition()
|
||||||
|
|
||||||
// recalculate sky color for current biome
|
// recalculate sky color for current biome
|
||||||
val blockPosition = Position(cameraPosition).toBlockPosition()
|
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()
|
frustum.recalculate()
|
||||||
renderWindow.worldRenderer.recalculateVisibleChunks()
|
renderWindow.worldRenderer.recalculateVisibleChunks()
|
||||||
|
@ -54,8 +54,6 @@ class WorldRenderer(
|
|||||||
queuedChunks.remove(chunkPosition)
|
queuedChunks.remove(chunkPosition)
|
||||||
}
|
}
|
||||||
val chunk = world.getChunk(chunkPosition) ?: error("Chunk in world is null at $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()
|
val meshCollection = ChunkMeshCollection()
|
||||||
|
|
||||||
for ((sectionHeight, section) in sections) {
|
for ((sectionHeight, section) in sections) {
|
||||||
@ -70,7 +68,8 @@ class WorldRenderer(
|
|||||||
neighborBlocks[direction.ordinal] = world.getBlockState(blockPosition + direction)
|
neighborBlocks[direction.ordinal] = world.getBlockState(blockPosition + direction)
|
||||||
}
|
}
|
||||||
|
|
||||||
val biome = chunk.biomeAccessor!!.getBiome(blockPosition, dimensionSupports3dBiomes)
|
|
||||||
|
val biome = world.getBiome(blockPosition)
|
||||||
|
|
||||||
var tintColor: RGBColor? = null
|
var tintColor: RGBColor? = null
|
||||||
|
|
||||||
|
@ -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.BlockPosition
|
||||||
import de.bixilon.minosoft.data.world.ChunkData
|
import de.bixilon.minosoft.data.world.ChunkData
|
||||||
import de.bixilon.minosoft.data.world.ChunkPosition
|
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.BlockEntityMetaDataChangeEvent
|
||||||
import de.bixilon.minosoft.modding.event.events.ChunkDataChangeEvent
|
import de.bixilon.minosoft.modding.event.events.ChunkDataChangeEvent
|
||||||
import de.bixilon.minosoft.protocol.network.Connection
|
import de.bixilon.minosoft.protocol.network.Connection
|
||||||
@ -83,7 +83,7 @@ class PacketChunkData : ClientboundPacket() {
|
|||||||
heightMap = buffer.readNBT() as CompoundTag
|
heightMap = buffer.readNBT() as CompoundTag
|
||||||
}
|
}
|
||||||
if (!isFullChunk) {
|
if (!isFullChunk) {
|
||||||
chunkData!!.biomeAccessor = NoiseBiomeAccessor(buffer.readBiomeArray())
|
chunkData!!.biomeSource = SpatialBiomeArray(buffer.readBiomeArray())
|
||||||
}
|
}
|
||||||
val size = buffer.readVarInt()
|
val size = buffer.readVarInt()
|
||||||
val lastPos = buffer.position
|
val lastPos = buffer.position
|
||||||
|
@ -19,6 +19,8 @@ import de.bixilon.minosoft.data.LevelTypes
|
|||||||
import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity
|
import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity
|
||||||
import de.bixilon.minosoft.data.mappings.Dimension
|
import de.bixilon.minosoft.data.mappings.Dimension
|
||||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
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.modding.event.events.JoinGameEvent
|
||||||
import de.bixilon.minosoft.protocol.network.Connection
|
import de.bixilon.minosoft.protocol.network.Connection
|
||||||
import de.bixilon.minosoft.protocol.packets.ClientboundPacket
|
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)
|
val entity = PlayerEntity(connection, entityId, connection.player.playerUUID, null, null, connection.player.playerName, null, null)
|
||||||
connection.player.entity = entity
|
connection.player.entity = entity
|
||||||
connection.player.world.addEntity(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")
|
connection.sender.sendChatMessage("I am alive! ~ Minosoft")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,4 +62,8 @@ object MMath {
|
|||||||
}
|
}
|
||||||
return intValue
|
return intValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun square(d: Double): Double {
|
||||||
|
return d * d
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.mappings.blocks.BlockState
|
||||||
import de.bixilon.minosoft.data.world.ChunkData
|
import de.bixilon.minosoft.data.world.ChunkData
|
||||||
import de.bixilon.minosoft.data.world.ChunkSection
|
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.light.DummyLightAccessor
|
||||||
import de.bixilon.minosoft.data.world.palette.Palette.Companion.choosePalette
|
import de.bixilon.minosoft.data.world.palette.Palette.Companion.choosePalette
|
||||||
import de.bixilon.minosoft.protocol.protocol.InByteBuffer
|
import de.bixilon.minosoft.protocol.protocol.InByteBuffer
|
||||||
@ -53,7 +53,7 @@ object ChunkUtil {
|
|||||||
}
|
}
|
||||||
val addBlockData = buffer.readBytes(addBitMask.cardinality() * (ProtocolDefinition.BLOCKS_PER_SECTION / 2))
|
val addBlockData = buffer.readBytes(addBitMask.cardinality() * (ProtocolDefinition.BLOCKS_PER_SECTION / 2))
|
||||||
if (isFullChunk) {
|
if (isFullChunk) {
|
||||||
chunkData.biomeAccessor = readLegacyBiomeArray(buffer)
|
chunkData.biomeSource = readLegacyBiomeArray(buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse data
|
// parse data
|
||||||
@ -123,7 +123,7 @@ object ChunkUtil {
|
|||||||
skyLight = buffer.readBytes(totalHalfEntries)
|
skyLight = buffer.readBytes(totalHalfEntries)
|
||||||
}
|
}
|
||||||
if (isFullChunk) {
|
if (isFullChunk) {
|
||||||
chunkData.biomeAccessor = readLegacyBiomeArray(buffer)
|
chunkData.biomeSource = readLegacyBiomeArray(buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
var arrayPos = 0
|
var arrayPos = 0
|
||||||
@ -200,14 +200,14 @@ object ChunkUtil {
|
|||||||
|
|
||||||
chunkData.blocks = sectionMap
|
chunkData.blocks = sectionMap
|
||||||
if (buffer.versionId < V_19W36A && isFullChunk) {
|
if (buffer.versionId < V_19W36A && isFullChunk) {
|
||||||
chunkData.biomeAccessor = readLegacyBiomeArray(buffer)
|
chunkData.biomeSource = readLegacyBiomeArray(buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
return chunkData
|
return chunkData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun readLegacyBiomeArray(buffer: InByteBuffer): XZBiomeAccessor {
|
private fun readLegacyBiomeArray(buffer: InByteBuffer): XZBiomeArray {
|
||||||
val biomes: MutableList<Biome> = mutableListOf()
|
val biomes: MutableList<Biome> = mutableListOf()
|
||||||
for (i in 0 until ProtocolDefinition.SECTION_WIDTH_X * ProtocolDefinition.SECTION_WIDTH_Z) {
|
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) {
|
biomes.add(i, buffer.connection.mapping.biomeRegistry.get(if (buffer.versionId < V_15W35A) {
|
||||||
@ -216,6 +216,6 @@ object ChunkUtil {
|
|||||||
buffer.readInt()
|
buffer.readInt()
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
return XZBiomeAccessor(biomes.toTypedArray())
|
return XZBiomeArray(biomes.toTypedArray())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user