mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-08 04:41:51 +09:00
partial chunk generation
This commit is contained in:
@@ -10,13 +10,15 @@ import net.torvald.terrarum.gameitems.ItemID
|
||||
import net.torvald.terrarum.gameworld.BlockAddress
|
||||
import net.torvald.terrarum.gameworld.GameWorld
|
||||
import net.torvald.terrarum.realestate.LandUtil
|
||||
import net.torvald.terrarum.realestate.LandUtil.CHUNK_H
|
||||
import net.torvald.terrarum.realestate.LandUtil.CHUNK_W
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2019-09-02.
|
||||
*/
|
||||
class Biomegen(world: GameWorld, seed: Long, params: Any, val biomeMapOut: HashMap<BlockAddress, Byte>) : Gen(world, seed, params) {
|
||||
class Biomegen(world: GameWorld, isFinal: Boolean, seed: Long, params: Any, val biomeMapOut: HashMap<BlockAddress, Byte>) : Gen(world, isFinal, seed, params) {
|
||||
|
||||
private val YHEIGHT_MAGIC = 2800.0 / 3.0
|
||||
private val YHEIGHT_DIVISOR = 2.0 / 7.0
|
||||
@@ -46,28 +48,7 @@ class Biomegen(world: GameWorld, seed: Long, params: Any, val biomeMapOut: HashM
|
||||
// loadscreen.progress.set((loadscreen.progress.get() + 0x1_000000_000000L) and 0x7FFF_000000_000000L)
|
||||
|
||||
Worldgen.threadExecutor.renew()
|
||||
(0 until world.width).sliceEvenly(Worldgen.genSlices).map { xs ->
|
||||
Worldgen.threadExecutor.submit {
|
||||
val localJoise = getGenerator(seed, params as BiomegenParams)
|
||||
for (x in xs) {
|
||||
for (y in 0 until world.height) {
|
||||
val sampleTheta = (x.toDouble() / world.width) * TWO_PI
|
||||
val sampleOffset = world.width / 8.0
|
||||
val sampleX = sin(sampleTheta) * sampleOffset + sampleOffset // plus sampleOffset to make only
|
||||
val sampleZ = cos(sampleTheta) * sampleOffset + sampleOffset // positive points are to be sampled
|
||||
val sampleY = y - (world.height - YHEIGHT_MAGIC) * YHEIGHT_DIVISOR // Q&D offsetting to make ratio of sky:ground to be constant
|
||||
// DEBUG NOTE: it is the OFFSET FROM THE IDEAL VALUE (observed land height - (HEIGHT * DIVISOR)) that must be constant
|
||||
val noise = localJoise.map { it.get(sampleX, sampleY, sampleZ) }
|
||||
|
||||
draw(x, y, noise, world)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
loadscreen.progress.addAndGet((xs.last - xs.first + 1).toLong())
|
||||
}
|
||||
}
|
||||
|
||||
submitJob(loadscreen)
|
||||
Worldgen.threadExecutor.join()
|
||||
|
||||
App.printdbg(this, "Waking up Worldgen")
|
||||
@@ -112,43 +93,53 @@ class Biomegen(world: GameWorld, seed: Long, params: Any, val biomeMapOut: HashM
|
||||
|
||||
}
|
||||
|
||||
private fun draw(x: Int, y: Int, noiseValue: List<Double>, world: GameWorld) {
|
||||
val control1 = noiseValue[0].coerceIn(0.0, 0.99999).times(slices).toInt().coerceAtMost(slices - 1)
|
||||
val control2 = noiseValue[1].coerceIn(0.0, 0.99999).times(9).toInt().coerceAtMost(9 - 1)
|
||||
val control3 = noiseValue[2].coerceIn(0.0, 0.99999).times(9).toInt().coerceAtMost(9 - 1)
|
||||
val ba = LandUtil.getBlockAddr(world, x, y)
|
||||
override fun draw(xStart: Int, yStart: Int, noises: List<Joise>, soff: Double) {
|
||||
for (x in xStart until xStart + CHUNK_W) {
|
||||
val sampleTheta = (x.toDouble() / world.width) * TWO_PI
|
||||
val sx = sin(sampleTheta) * soff + soff // plus sampleOffset to make only
|
||||
val sz = cos(sampleTheta) * soff + soff // positive points are to be sampled
|
||||
for (y in yStart until yStart + CHUNK_H) {
|
||||
val sy = y - (world.height - YHEIGHT_MAGIC) * YHEIGHT_DIVISOR // Q&D offsetting to make ratio of sky:ground to be constant
|
||||
|
||||
if (y > 0) {
|
||||
val tileThis = world.getTileFromTerrain(x, y)
|
||||
val wallThis = world.getTileFromWall(x, y)
|
||||
val nearbyTerr = nearbyArr.map { world.getTileFromTerrain(x + it.first, y + it.second) }
|
||||
val nearbyWall = nearbyArr.map { world.getTileFromWall(x + it.first, y + it.second) }
|
||||
val exposedToAir = nearbyTerr.any { it == Block.AIR } && nearbyWall.any { it == Block.AIR }
|
||||
val hasNoFloor = (nearbyTerr[BT] == Block.AIR)
|
||||
val control1 =
|
||||
noises[0].get(sx, sy, sz).coerceIn(0.0, 0.99999).times(slices).toInt().coerceAtMost(slices - 1)
|
||||
val control2 = noises[1].get(sx, sy, sz).coerceIn(0.0, 0.99999).times(9).toInt().coerceAtMost(9 - 1)
|
||||
val control3 = noises[2].get(sx, sy, sz).coerceIn(0.0, 0.99999).times(9).toInt().coerceAtMost(9 - 1)
|
||||
val ba = LandUtil.getBlockAddr(world, x, y)
|
||||
|
||||
val grassRock = when (control1) {
|
||||
0 -> { // woodlands
|
||||
if (tileThis == Block.DIRT && exposedToAir) {
|
||||
biomeMapOut[ba] = BIOME_KEY_WOODLANDS
|
||||
Block.GRASS to null
|
||||
}
|
||||
else null to null
|
||||
}
|
||||
1 -> { // sparse forest
|
||||
if (tileThis == Block.DIRT && exposedToAir) {
|
||||
biomeMapOut[ba] = BIOME_KEY_SPARSE_WOODS
|
||||
Block.GRASS to null
|
||||
}
|
||||
else null to null
|
||||
}
|
||||
2, 3 -> { // plains
|
||||
if (tileThis == Block.DIRT && exposedToAir) {
|
||||
biomeMapOut[ba] = BIOME_KEY_PLAINS
|
||||
Block.GRASS to null
|
||||
}
|
||||
else null to null
|
||||
}
|
||||
/*3 -> { // sands
|
||||
if (y > 0) {
|
||||
val tileThis = world.getTileFromTerrain(x, y)
|
||||
val wallThis = world.getTileFromWall(x, y)
|
||||
val nearbyTerr = nearbyArr.map { world.getTileFromTerrain(x + it.first, y + it.second) }
|
||||
val nearbyWall = nearbyArr.map { world.getTileFromWall(x + it.first, y + it.second) }
|
||||
val exposedToAir = nearbyTerr.any { it == Block.AIR } && nearbyWall.any { it == Block.AIR }
|
||||
val hasNoFloor = (nearbyTerr[BT] == Block.AIR)
|
||||
|
||||
val grassRock = when (control1) {
|
||||
0 -> { // woodlands
|
||||
if (tileThis == Block.DIRT && exposedToAir) {
|
||||
biomeMapOut[ba] = BIOME_KEY_WOODLANDS
|
||||
Block.GRASS to null
|
||||
}
|
||||
else null to null
|
||||
}
|
||||
|
||||
1 -> { // sparse forest
|
||||
if (tileThis == Block.DIRT && exposedToAir) {
|
||||
biomeMapOut[ba] = BIOME_KEY_SPARSE_WOODS
|
||||
Block.GRASS to null
|
||||
}
|
||||
else null to null
|
||||
}
|
||||
|
||||
2, 3 -> { // plains
|
||||
if (tileThis == Block.DIRT && exposedToAir) {
|
||||
biomeMapOut[ba] = BIOME_KEY_PLAINS
|
||||
Block.GRASS to null
|
||||
}
|
||||
else null to null
|
||||
}
|
||||
/*3 -> { // sands
|
||||
if (tileThis == Block.DIRT && (nearbyTerr[BT] == Block.STONE || nearbyTerr[BT] == Block.AIR)) {
|
||||
world.setTileTerrain(x, y, Block.SANDSTONE, true)
|
||||
}
|
||||
@@ -156,67 +147,75 @@ class Biomegen(world: GameWorld, seed: Long, params: Any, val biomeMapOut: HashM
|
||||
world.setTileTerrain(x, y, Block.SAND, true)
|
||||
}
|
||||
}*/
|
||||
4 -> { // rockylands
|
||||
if (tileThis == Block.DIRT || tileThis == Block.STONE_QUARRIED) {
|
||||
if (exposedToAir) biomeMapOut[ba] = BIOME_KEY_ROCKY
|
||||
Block.STONE to Block.STONE
|
||||
}
|
||||
else null to null
|
||||
}
|
||||
else -> null to null
|
||||
}
|
||||
val sablum = when (control2) {
|
||||
0 -> {
|
||||
if (tileThis == Block.DIRT && hasNoFloor) {
|
||||
if (exposedToAir) biomeMapOut[ba] = BIOME_KEY_GRAVELS
|
||||
Block.STONE_QUARRIED to null
|
||||
}
|
||||
else if (tileThis == Block.DIRT) {
|
||||
if (exposedToAir) biomeMapOut[ba] = BIOME_KEY_GRAVELS
|
||||
Block.GRAVEL to null
|
||||
}
|
||||
else null to null
|
||||
}
|
||||
8 -> {
|
||||
if (tileThis == Block.DIRT && hasNoFloor) {
|
||||
if (exposedToAir) biomeMapOut[ba] = BIOME_KEY_SANDY
|
||||
THISWORLD_SANDSTONE to null
|
||||
}
|
||||
else if (tileThis == Block.DIRT) {
|
||||
if (exposedToAir) biomeMapOut[ba] = BIOME_KEY_SANDY
|
||||
THISWORLD_SAND to null
|
||||
}
|
||||
else null to null
|
||||
}
|
||||
else -> null to null
|
||||
}
|
||||
val lutum = when (control3) {
|
||||
0 -> {
|
||||
if (tileThis == Block.DIRT || wallThis == Block.DIRT) {
|
||||
Block.CLAY to Block.CLAY
|
||||
}
|
||||
else null to null
|
||||
}
|
||||
else -> null to null
|
||||
}
|
||||
4 -> { // rockylands
|
||||
if (tileThis == Block.DIRT || tileThis == Block.STONE_QUARRIED) {
|
||||
if (exposedToAir) biomeMapOut[ba] = BIOME_KEY_ROCKY
|
||||
Block.STONE to Block.STONE
|
||||
}
|
||||
else null to null
|
||||
}
|
||||
|
||||
val outTile = if (grassRock.first == Block.STONE)
|
||||
grassRock
|
||||
else if (sablum.first != null)
|
||||
sablum
|
||||
else if (lutum.first != null)
|
||||
lutum
|
||||
else grassRock
|
||||
else -> null to null
|
||||
}
|
||||
val sablum = when (control2) {
|
||||
0 -> {
|
||||
if (tileThis == Block.DIRT && hasNoFloor) {
|
||||
if (exposedToAir) biomeMapOut[ba] = BIOME_KEY_GRAVELS
|
||||
Block.STONE_QUARRIED to null
|
||||
}
|
||||
else if (tileThis == Block.DIRT) {
|
||||
if (exposedToAir) biomeMapOut[ba] = BIOME_KEY_GRAVELS
|
||||
Block.GRAVEL to null
|
||||
}
|
||||
else null to null
|
||||
}
|
||||
|
||||
8 -> {
|
||||
if (tileThis == Block.DIRT && hasNoFloor) {
|
||||
if (exposedToAir) biomeMapOut[ba] = BIOME_KEY_SANDY
|
||||
THISWORLD_SANDSTONE to null
|
||||
}
|
||||
else if (tileThis == Block.DIRT) {
|
||||
if (exposedToAir) biomeMapOut[ba] = BIOME_KEY_SANDY
|
||||
THISWORLD_SAND to null
|
||||
}
|
||||
else null to null
|
||||
}
|
||||
|
||||
else -> null to null
|
||||
}
|
||||
val lutum = when (control3) {
|
||||
0 -> {
|
||||
if (tileThis == Block.DIRT || wallThis == Block.DIRT) {
|
||||
Block.CLAY to Block.CLAY
|
||||
}
|
||||
else null to null
|
||||
}
|
||||
|
||||
else -> null to null
|
||||
}
|
||||
|
||||
val outTile = if (grassRock.first == Block.STONE)
|
||||
grassRock
|
||||
else if (sablum.first != null)
|
||||
sablum
|
||||
else if (lutum.first != null)
|
||||
lutum
|
||||
else grassRock
|
||||
|
||||
|
||||
if (outTile.first != null && tileThis != Block.AIR)
|
||||
world.setTileTerrain(x, y, outTile.first!!, true)
|
||||
if (outTile.second != null)
|
||||
world.setTileWall(x, y, outTile.second!!, true)
|
||||
if (outTile.first != null && tileThis != Block.AIR)
|
||||
world.setTileTerrain(x, y, outTile.first!!, true)
|
||||
if (outTile.second != null)
|
||||
world.setTileWall(x, y, outTile.second!!, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getGenerator(seed: Long, params: BiomegenParams): List<Joise> {
|
||||
override fun getGenerator(seed: Long, params: Any?): List<Joise> {
|
||||
val params = params as BiomegenParams
|
||||
|
||||
return listOf(
|
||||
makeRandomSpotties("TERRA", params.featureSize1),
|
||||
makeRandomSpotties("SABLUM", params.featureSize2),
|
||||
|
||||
@@ -8,13 +8,15 @@ import net.torvald.terrarum.LoadScreenBase
|
||||
import net.torvald.terrarum.blockproperties.Block
|
||||
import net.torvald.terrarum.concurrent.sliceEvenly
|
||||
import net.torvald.terrarum.gameworld.GameWorld
|
||||
import net.torvald.terrarum.realestate.LandUtil.CHUNK_H
|
||||
import net.torvald.terrarum.realestate.LandUtil.CHUNK_W
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2023-11-04.
|
||||
*/
|
||||
class Cavegen(world: GameWorld, val highlandLowlandSelectCache: ModuleCache, seed: Long, params: Any) : Gen(world, seed, params) {
|
||||
class Cavegen(world: GameWorld, isFinal: Boolean, val highlandLowlandSelectCache: ModuleCache, seed: Long, params: Any) : Gen(world, isFinal, seed, params) {
|
||||
|
||||
companion object {
|
||||
const val YHEIGHT_MAGIC = 2800.0 / 3.0
|
||||
@@ -26,18 +28,7 @@ class Cavegen(world: GameWorld, val highlandLowlandSelectCache: ModuleCache, see
|
||||
loadscreen.progress.set(0L)
|
||||
|
||||
Worldgen.threadExecutor.renew()
|
||||
(0 until world.width).sliceEvenly(Worldgen.genSlices).mapIndexed { i, xs ->
|
||||
Worldgen.threadExecutor.submit {
|
||||
val localJoise = getGenerator(seed, params as TerragenParams)
|
||||
for (x in xs) {
|
||||
val sampleTheta = (x.toDouble() / world.width) * TWO_PI
|
||||
val sampleOffset = world.width / 8.0
|
||||
draw(x, localJoise, sampleTheta, sampleOffset)
|
||||
}
|
||||
loadscreen.progress.addAndGet((xs.last - xs.first + 1).toLong())
|
||||
}
|
||||
}
|
||||
|
||||
submitJob(loadscreen)
|
||||
Worldgen.threadExecutor.join()
|
||||
|
||||
App.printdbg(this, "Waking up Worldgen")
|
||||
@@ -45,24 +36,30 @@ class Cavegen(world: GameWorld, val highlandLowlandSelectCache: ModuleCache, see
|
||||
|
||||
|
||||
//private fun draw(x: Int, y: Int, width: Int, height: Int, noiseValue: List<Double>, world: GameWorld) {
|
||||
private fun draw(x: Int, noises: List<Joise>, st: Double, soff: Double) {
|
||||
for (y in 0 until world.height) {
|
||||
val sx = sin(st) * soff + soff // plus sampleOffset to make only
|
||||
val sz = cos(st) * soff + soff // positive points are to be sampled
|
||||
val sy = y - (world.height - YHEIGHT_MAGIC) * YHEIGHT_DIVISOR // Q&D offsetting to make ratio of sky:ground to be constant
|
||||
// DEBUG NOTE: it is the OFFSET FROM THE IDEAL VALUE (observed land height - (HEIGHT * DIVISOR)) that must be constant
|
||||
val noiseValue = noises.map { it.get(sx, sy, sz) }
|
||||
override fun draw(xStart: Int, yStart: Int, noises: List<Joise>, soff: Double) {
|
||||
for (x in xStart until xStart + CHUNK_W) {
|
||||
val st = (x.toDouble() / world.width) * TWO_PI
|
||||
|
||||
val cave = if (noiseValue[0] < 0.5) 0 else 1
|
||||
for (y in yStart until yStart + CHUNK_H) {
|
||||
val sx = sin(st) * soff + soff // plus sampleOffset to make only
|
||||
val sz = cos(st) * soff + soff // positive points are to be sampled
|
||||
val sy = y - (world.height - YHEIGHT_MAGIC) * YHEIGHT_DIVISOR // Q&D offsetting to make ratio of sky:ground to be constant
|
||||
// DEBUG NOTE: it is the OFFSET FROM THE IDEAL VALUE (observed land height - (HEIGHT * DIVISOR)) that must be constant
|
||||
val noiseValue = noises.map { it.get(sx, sy, sz) }
|
||||
|
||||
if (cave == 0) {
|
||||
world.setTileTerrain(x, y, Block.AIR, true)
|
||||
val cave = if (noiseValue[0] < 0.5) 0 else 1
|
||||
|
||||
if (cave == 0) {
|
||||
world.setTileTerrain(x, y, Block.AIR, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun getGenerator(seed: Long, params: TerragenParams): List<Joise> {
|
||||
override fun getGenerator(seed: Long, params: Any?): List<Joise> {
|
||||
val params = params as TerragenParams
|
||||
|
||||
val caveMagic: Long = 0x00215741CDF // Urist McDF
|
||||
val cavePerturbMagic: Long = 0xA2410C // Armok
|
||||
val caveBlockageMagic: Long = 0xD15A57E5 // Disaster
|
||||
|
||||
@@ -7,6 +7,9 @@ import net.torvald.terrarum.concurrent.sliceEvenly
|
||||
import net.torvald.terrarum.gameworld.GameWorld
|
||||
import net.torvald.terrarum.modulebasegame.worldgenerator.Terragen.Companion.YHEIGHT_DIVISOR
|
||||
import net.torvald.terrarum.modulebasegame.worldgenerator.Terragen.Companion.YHEIGHT_MAGIC
|
||||
import net.torvald.terrarum.realestate.LandUtil
|
||||
import net.torvald.terrarum.realestate.LandUtil.CHUNK_H
|
||||
import net.torvald.terrarum.realestate.LandUtil.CHUNK_W
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
import kotlin.math.sqrt
|
||||
@@ -14,31 +17,20 @@ import kotlin.math.sqrt
|
||||
/**
|
||||
* Created by minjaesong on 2023-10-25.
|
||||
*/
|
||||
class Oregen(world: GameWorld, private val caveAttenuateBiasScaledCache: ModuleCache, seed: Long, private val ores: List<OregenParams>) : Gen(world, seed) {
|
||||
class Oregen(world: GameWorld, isFinal: Boolean, private val caveAttenuateBiasScaledCache: ModuleCache, seed: Long, private val ores: List<OregenParams>) : Gen(world, isFinal, seed) {
|
||||
override fun getDone(loadscreen: LoadScreenBase) {
|
||||
loadscreen.stageValue += 1
|
||||
loadscreen.progress.set(0L)
|
||||
|
||||
Worldgen.threadExecutor.renew()
|
||||
(0 until world.width).sliceEvenly(Worldgen.genSlices).mapIndexed { i, xs ->
|
||||
Worldgen.threadExecutor.submit {
|
||||
val localJoise = getGenerator(seed)
|
||||
for (x in xs) {
|
||||
val sampleTheta = (x.toDouble() / world.width) * TWO_PI
|
||||
val sampleOffset = world.width / 8.0
|
||||
draw(x, localJoise, sampleTheta, sampleOffset)
|
||||
}
|
||||
loadscreen.progress.addAndGet((xs.last - xs.first + 1).toLong())
|
||||
}
|
||||
}
|
||||
|
||||
submitJob(loadscreen)
|
||||
Worldgen.threadExecutor.join()
|
||||
}
|
||||
|
||||
/**
|
||||
* @return List of noise instances, each instance refers to one of the spawnable ores
|
||||
*/
|
||||
private fun getGenerator(seed: Long): List<Joise> {
|
||||
override fun getGenerator(seed: Long, any: Any?): List<Joise> {
|
||||
return ores.map {
|
||||
generateOreVeinModule(caveAttenuateBiasScaledCache, seed shake it.tile, it.freq, it.power, it.scale, it.ratio)
|
||||
}
|
||||
@@ -47,24 +39,29 @@ class Oregen(world: GameWorld, private val caveAttenuateBiasScaledCache: ModuleC
|
||||
/**
|
||||
* Indices of `noises` has one-to-one mapping to the `ores`
|
||||
*/
|
||||
private fun draw(x: Int, noises: List<Joise>, st: Double, soff: Double) {
|
||||
for (y in 0 until world.height) {
|
||||
val sx = sin(st) * soff + soff // plus sampleOffset to make only
|
||||
val sz = cos(st) * soff + soff // positive points are to be sampled
|
||||
val sy = y - (world.height - YHEIGHT_MAGIC) * YHEIGHT_DIVISOR // Q&D offsetting to make ratio of sky:ground to be constant
|
||||
// DEBUG NOTE: it is the OFFSET FROM THE IDEAL VALUE (observed land height - (HEIGHT * DIVISOR)) that must be constant
|
||||
override fun draw(xStart: Int, yStart: Int, noises: List<Joise>, soff: Double) {
|
||||
for (x in xStart until xStart + CHUNK_W) {
|
||||
val st = (x.toDouble() / world.width) * TWO_PI
|
||||
|
||||
// get the actual noise values
|
||||
// the size of the two lists are guaranteed to be identical as they all derive from the same `ores`
|
||||
val noiseValues = noises.map { it.get(sx, sy, sz) }
|
||||
val oreTiles = ores.map { it.tile }
|
||||
for (y in yStart until yStart + CHUNK_H) {
|
||||
val sx = sin(st) * soff + soff // plus sampleOffset to make only
|
||||
val sz = cos(st) * soff + soff // positive points are to be sampled
|
||||
val sy = y - (world.height - YHEIGHT_MAGIC) * YHEIGHT_DIVISOR // Q&D offsetting to make ratio of sky:ground to be constant
|
||||
// DEBUG NOTE: it is the OFFSET FROM THE IDEAL VALUE (observed land height - (HEIGHT * DIVISOR)) that must be constant
|
||||
|
||||
val tileToPut = noiseValues.zip(oreTiles).firstNotNullOfOrNull { (n, tile) -> if (n > 0.5) tile else null }
|
||||
val backingTile = world.getTileFromTerrain(x, y)
|
||||
// get the actual noise values
|
||||
// the size of the two lists are guaranteed to be identical as they all derive from the same `ores`
|
||||
val noiseValues = noises.map { it.get(sx, sy, sz) }
|
||||
val oreTiles = ores.map { it.tile }
|
||||
|
||||
if (tileToPut != null && BlockCodex[backingTile].hasAllTagOf("ROCK", "OREBEARING")) {
|
||||
// actually put the ore block
|
||||
world.setTileOre(x, y, tileToPut, 0) // autotiling will be handled by the other worldgen process
|
||||
val tileToPut =
|
||||
noiseValues.zip(oreTiles).firstNotNullOfOrNull { (n, tile) -> if (n > 0.5) tile else null }
|
||||
val backingTile = world.getTileFromTerrain(x, y)
|
||||
|
||||
if (tileToPut != null && BlockCodex[backingTile].hasAllTagOf("ROCK", "OREBEARING")) {
|
||||
// actually put the ore block
|
||||
world.setTileOre(x, y, tileToPut, 0) // autotiling will be handled by the other worldgen process
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.torvald.terrarum.modulebasegame.worldgenerator
|
||||
|
||||
import com.sudoplay.joise.Joise
|
||||
import net.torvald.random.XXHash64
|
||||
import net.torvald.terrarum.LoadScreenBase
|
||||
import net.torvald.terrarum.Point2i
|
||||
@@ -10,6 +11,8 @@ import net.torvald.terrarum.gameworld.GameWorld
|
||||
import net.torvald.terrarum.gameworld.fmod
|
||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||
import net.torvald.terrarum.realestate.LandUtil
|
||||
import net.torvald.terrarum.realestate.LandUtil.CHUNK_H
|
||||
import net.torvald.terrarum.realestate.LandUtil.CHUNK_W
|
||||
import net.torvald.terrarum.serialise.toBig64
|
||||
import net.torvald.terrarum.toInt
|
||||
import net.torvald.terrarum.utils.OrePlacement
|
||||
@@ -19,18 +22,11 @@ import kotlin.math.max
|
||||
/**
|
||||
* Created by minjaesong on 2023-10-26.
|
||||
*/
|
||||
class OregenAutotiling(world: GameWorld, seed: Long, val tilingModes: HashMap<ItemID, String>) : Gen(world, seed) {
|
||||
class OregenAutotiling(world: GameWorld, isFinal: Boolean, seed: Long, val tilingModes: HashMap<ItemID, String>) : Gen(world, isFinal, seed) {
|
||||
|
||||
override fun getDone(loadscreen: LoadScreenBase) {
|
||||
Worldgen.threadExecutor.renew()
|
||||
(0 until world.width).sliceEvenly(Worldgen.genSlices).mapIndexed { i, xs ->
|
||||
Worldgen.threadExecutor.submit {
|
||||
for (x in xs) {
|
||||
draw(x)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
submitJob(loadscreen)
|
||||
Worldgen.threadExecutor.join()
|
||||
}
|
||||
|
||||
@@ -39,62 +35,74 @@ class OregenAutotiling(world: GameWorld, seed: Long, val tilingModes: HashMap<It
|
||||
return (XXHash64.hash(LandUtil.getBlockAddr(world, x, y).toBig64(), ((x*16777619) xor (y+1073)).toLong()) fmod mod.toLong()).toInt()
|
||||
}
|
||||
|
||||
private fun draw(x: Int) {
|
||||
for (y in 0 until world.height) {
|
||||
val (ore, _) = world.getTileFromOre(x, y)
|
||||
override fun draw(xStart: Int, yStart: Int, noises: List<Joise>, soff: Double) {
|
||||
for (x in xStart until xStart + CHUNK_W) {
|
||||
for (y in yStart until yStart + CHUNK_H) {
|
||||
|
||||
if (ore.isOre()) {
|
||||
// get tiling mode
|
||||
val tilingMode = tilingModes[ore]
|
||||
val (ore, _) = world.getTileFromOre(x, y)
|
||||
|
||||
val placement = when (tilingMode) {
|
||||
"a16" -> {
|
||||
// get placement (tile connection) info
|
||||
val autotiled = getNearbyOres8(x, y).foldIndexed(0) { index, acc, placement ->
|
||||
acc or (placement.item == ore).toInt(index)
|
||||
}
|
||||
BlocksDrawer.connectLut16[autotiled]
|
||||
if (ore.isOre()) {
|
||||
// get tiling mode
|
||||
val tilingMode = tilingModes[ore]
|
||||
|
||||
val placement = when (tilingMode) {
|
||||
"a16" -> {
|
||||
// get placement (tile connection) info
|
||||
val autotiled = getNearbyOres8(x, y).foldIndexed(0) { index, acc, placement ->
|
||||
acc or (placement.item == ore).toInt(index)
|
||||
}
|
||||
BlocksDrawer.connectLut16[autotiled]
|
||||
|
||||
}
|
||||
"a16x4" -> {
|
||||
// get placement (tile connection) info
|
||||
val mult = getHashCoord(x, y, 4)
|
||||
val autotiled = getNearbyOres8(x, y).foldIndexed(0) { index, acc, placement ->
|
||||
acc or (placement.item == ore).toInt(index)
|
||||
}
|
||||
BlocksDrawer.connectLut16[autotiled] or mult.shl(4)
|
||||
}
|
||||
"a16x16" -> {
|
||||
// get placement (tile connection) info
|
||||
val mult = getHashCoord(x, y, 16)
|
||||
val autotiled = getNearbyOres8(x, y).foldIndexed(0) { index, acc, placement ->
|
||||
acc or (placement.item == ore).toInt(index)
|
||||
|
||||
"a16x4" -> {
|
||||
// get placement (tile connection) info
|
||||
val mult = getHashCoord(x, y, 4)
|
||||
val autotiled = getNearbyOres8(x, y).foldIndexed(0) { index, acc, placement ->
|
||||
acc or (placement.item == ore).toInt(index)
|
||||
}
|
||||
BlocksDrawer.connectLut16[autotiled] or mult.shl(4)
|
||||
}
|
||||
BlocksDrawer.connectLut16[autotiled] or mult.shl(4)
|
||||
}
|
||||
"a47" -> {
|
||||
// get placement (tile connection) info
|
||||
val autotiled = getNearbyOres8(x, y).foldIndexed(0) { index, acc, placement ->
|
||||
acc or (placement.item == ore).toInt(index)
|
||||
|
||||
"a16x16" -> {
|
||||
// get placement (tile connection) info
|
||||
val mult = getHashCoord(x, y, 16)
|
||||
val autotiled = getNearbyOres8(x, y).foldIndexed(0) { index, acc, placement ->
|
||||
acc or (placement.item == ore).toInt(index)
|
||||
}
|
||||
BlocksDrawer.connectLut16[autotiled] or mult.shl(4)
|
||||
}
|
||||
BlocksDrawer.connectLut47[autotiled]
|
||||
|
||||
"a47" -> {
|
||||
// get placement (tile connection) info
|
||||
val autotiled = getNearbyOres8(x, y).foldIndexed(0) { index, acc, placement ->
|
||||
acc or (placement.item == ore).toInt(index)
|
||||
}
|
||||
BlocksDrawer.connectLut47[autotiled]
|
||||
}
|
||||
|
||||
"r16" -> {
|
||||
getHashCoord(x, y, 16)
|
||||
}
|
||||
|
||||
"r8" -> {
|
||||
getHashCoord(x, y, 8)
|
||||
}
|
||||
|
||||
else -> throw IllegalArgumentException("Unknown tiling mode: $tilingMode")
|
||||
}
|
||||
"r16" -> {
|
||||
getHashCoord(x, y, 16)
|
||||
}
|
||||
"r8" -> {
|
||||
getHashCoord(x, y, 8)
|
||||
}
|
||||
else -> throw IllegalArgumentException("Unknown tiling mode: $tilingMode")
|
||||
|
||||
|
||||
// actually put the ore block
|
||||
world.setTileOre(x, y, ore, placement) // autotiling will be handled by the other worldgen process
|
||||
}
|
||||
|
||||
|
||||
// actually put the ore block
|
||||
world.setTileOre(x, y, ore, placement) // autotiling will be handled by the other worldgen process
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getGenerator(seed: Long, params: Any?): List<Joise> {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
private fun getNearbyTilesPos8(x: Int, y: Int): Array<Point2i> {
|
||||
return arrayOf(
|
||||
|
||||
@@ -9,6 +9,9 @@ import net.torvald.terrarum.LoadScreenBase
|
||||
import net.torvald.terrarum.blockproperties.Block
|
||||
import net.torvald.terrarum.concurrent.sliceEvenly
|
||||
import net.torvald.terrarum.gameworld.GameWorld
|
||||
import net.torvald.terrarum.realestate.LandUtil
|
||||
import net.torvald.terrarum.realestate.LandUtil.CHUNK_H
|
||||
import net.torvald.terrarum.realestate.LandUtil.CHUNK_W
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.sin
|
||||
@@ -16,7 +19,7 @@ import kotlin.math.sin
|
||||
/**
|
||||
* Created by minjaesong on 2019-07-23.
|
||||
*/
|
||||
class Terragen(world: GameWorld, val highlandLowlandSelectCache: ModuleCache, seed: Long, params: Any) : Gen(world, seed, params) {
|
||||
class Terragen(world: GameWorld, isFinal: Boolean , val highlandLowlandSelectCache: ModuleCache, seed: Long, params: Any) : Gen(world, isFinal, seed, params) {
|
||||
|
||||
companion object {
|
||||
const val YHEIGHT_MAGIC = 2800.0 / 3.0
|
||||
@@ -31,18 +34,7 @@ class Terragen(world: GameWorld, val highlandLowlandSelectCache: ModuleCache, se
|
||||
loadscreen.progress.set(0L)
|
||||
|
||||
Worldgen.threadExecutor.renew()
|
||||
(0 until world.width).sliceEvenly(Worldgen.genSlices).mapIndexed { i, xs ->
|
||||
Worldgen.threadExecutor.submit {
|
||||
val localJoise = getGenerator(seed, params as TerragenParams)
|
||||
for (x in xs) {
|
||||
val sampleTheta = (x.toDouble() / world.width) * TWO_PI
|
||||
val sampleOffset = world.width / 8.0
|
||||
draw(x, localJoise, sampleTheta, sampleOffset)
|
||||
}
|
||||
loadscreen.progress.addAndGet((xs.last - xs.first + 1).toLong())
|
||||
}
|
||||
}
|
||||
|
||||
submitJob(loadscreen)
|
||||
Worldgen.threadExecutor.join()
|
||||
|
||||
printdbg(this, "Waking up Worldgen")
|
||||
@@ -64,36 +56,40 @@ class Terragen(world: GameWorld, val highlandLowlandSelectCache: ModuleCache, se
|
||||
private val terragenTiers = listOf(.0, .5, 1.0, 2.5).map { it * terragenYscaling } // pow 1.0 for 1-to-1 scaling; 0.75 is used to make deep-rock layers actually deep for huge world size
|
||||
|
||||
//private fun draw(x: Int, y: Int, width: Int, height: Int, noiseValue: List<Double>, world: GameWorld) {
|
||||
private fun draw(x: Int, noises: List<Joise>, st: Double, soff: Double) {
|
||||
var dirtStoneTransition = 0
|
||||
var stoneSlateTransition = 0
|
||||
override fun draw(xStart: Int, yStart: Int, noises: List<Joise>, soff: Double) {
|
||||
for (x in xStart until xStart + CHUNK_W) {
|
||||
val st = (x.toDouble() / world.width) * TWO_PI
|
||||
|
||||
for (y in 0 until world.height) {
|
||||
val sx = sin(st) * soff + soff // plus sampleOffset to make only
|
||||
val sz = cos(st) * soff + soff // positive points are to be sampled
|
||||
val sy = y - (world.height - YHEIGHT_MAGIC) * YHEIGHT_DIVISOR // Q&D offsetting to make ratio of sky:ground to be constant
|
||||
// DEBUG NOTE: it is the OFFSET FROM THE IDEAL VALUE (observed land height - (HEIGHT * DIVISOR)) that must be constant
|
||||
val noiseValue = noises.map { it.get(sx, sy, sz) }
|
||||
var dirtStoneTransition = 0
|
||||
var stoneSlateTransition = 0
|
||||
|
||||
val terr = noiseValue[0].tiered(terragenTiers)
|
||||
for (y in yStart until yStart + CHUNK_H) {
|
||||
val sx = sin(st) * soff + soff // plus sampleOffset to make only
|
||||
val sz = cos(st) * soff + soff // positive points are to be sampled
|
||||
val sy = y - (world.height - YHEIGHT_MAGIC) * YHEIGHT_DIVISOR // Q&D offsetting to make ratio of sky:ground to be constant
|
||||
// DEBUG NOTE: it is the OFFSET FROM THE IDEAL VALUE (observed land height - (HEIGHT * DIVISOR)) that must be constant
|
||||
val noiseValue = noises.map { it.get(sx, sy, sz) }
|
||||
|
||||
// mark off the position where the transition occurred
|
||||
if (dirtStoneTransition == 0 && terr == 2)
|
||||
dirtStoneTransition = y
|
||||
if (stoneSlateTransition == 0 && terr == 3)
|
||||
stoneSlateTransition = y
|
||||
val terr = noiseValue[0].tiered(terragenTiers)
|
||||
|
||||
val isMarble = noiseValue[1] > 0.5
|
||||
// mark off the position where the transition occurred
|
||||
if (dirtStoneTransition == 0 && terr == 2)
|
||||
dirtStoneTransition = y
|
||||
if (stoneSlateTransition == 0 && terr == 3)
|
||||
stoneSlateTransition = y
|
||||
|
||||
val wallBlock = if (isMarble) Block.STONE_MARBLE else groundDepthBlock[terr]
|
||||
val terrBlock = if (isMarble) Block.STONE_MARBLE else wallBlock
|
||||
val isMarble = noiseValue[1] > 0.5
|
||||
|
||||
world.setTileTerrain(x, y, terrBlock, true)
|
||||
world.setTileWall(x, y, wallBlock, true)
|
||||
}
|
||||
val wallBlock = if (isMarble) Block.STONE_MARBLE else groundDepthBlock[terr]
|
||||
val terrBlock = if (isMarble) Block.STONE_MARBLE else wallBlock
|
||||
|
||||
// dither shits
|
||||
/*
|
||||
world.setTileTerrain(x, y, terrBlock, true)
|
||||
world.setTileWall(x, y, wallBlock, true)
|
||||
}
|
||||
|
||||
|
||||
// dither shits
|
||||
/*
|
||||
#
|
||||
# - dirt-to-cobble transition, height = dirtStoneDitherSize
|
||||
#
|
||||
@@ -102,46 +98,55 @@ class Terragen(world: GameWorld, val highlandLowlandSelectCache: ModuleCache, se
|
||||
%
|
||||
* - where the stone layer actually begins
|
||||
*/
|
||||
for (pos in 0 until dirtStoneDitherSize * 2) {
|
||||
val y = pos + dirtStoneTransition - (dirtStoneDitherSize * 2) + 1
|
||||
if (y >= world.height) break
|
||||
val hash = XXHash32.hashGeoCoord(x, y).and(0x7FFFFFFF) / 2147483647.0
|
||||
if (dirtStoneTransition > 0) {
|
||||
for (pos in 0 until dirtStoneDitherSize * 2) {
|
||||
val y = pos + dirtStoneTransition - (dirtStoneDitherSize * 2) + 1
|
||||
if (y >= world.height) break
|
||||
val hash = XXHash32.hashGeoCoord(x, y).and(0x7FFFFFFF) / 2147483647.0
|
||||
// val fore = world.getTileFromTerrain(x, y)
|
||||
// val back = world.getTileFromWall(x, y)
|
||||
val newTile = if (pos < dirtStoneDitherSize)
|
||||
if (hash < pos.toDouble() / dirtStoneDitherSize) Block.STONE_QUARRIED else Block.DIRT
|
||||
else // don't +1 to pos.toDouble(); I've suffered
|
||||
if (hash >= (pos.toDouble() - dirtStoneDitherSize) / dirtStoneDitherSize) Block.STONE_QUARRIED else Block.STONE
|
||||
val newTile = if (pos < dirtStoneDitherSize)
|
||||
if (hash < pos.toDouble() / dirtStoneDitherSize) Block.STONE_QUARRIED else Block.DIRT
|
||||
else // don't +1 to pos.toDouble(); I've suffered
|
||||
if (hash >= (pos.toDouble() - dirtStoneDitherSize) / dirtStoneDitherSize) Block.STONE_QUARRIED else Block.STONE
|
||||
|
||||
// if (fore != Block.AIR)
|
||||
world.setTileTerrain(x, y, newTile, true)
|
||||
if (y in yStart until yStart + CHUNK_H) {
|
||||
world.setTileTerrain(x, y, newTile, true)
|
||||
world.setTileWall(x, y, newTile, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
world.setTileWall(x, y, newTile, true)
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
#
|
||||
# - stone-to-slate transition, height = stoneSlateDitherSize
|
||||
#
|
||||
*/
|
||||
for (pos in 0 until stoneSlateDitherSize) {
|
||||
val y = pos + stoneSlateTransition - stoneSlateDitherSize + 1
|
||||
if (y >= world.height) break
|
||||
val hash = XXHash32.hashGeoCoord(x, y).and(0x7FFFFFFF) / 2147483647.0
|
||||
if (stoneSlateTransition > 0) {
|
||||
for (pos in 0 until stoneSlateDitherSize) {
|
||||
val y = pos + stoneSlateTransition - stoneSlateDitherSize + 1
|
||||
if (y >= world.height) break
|
||||
val hash = XXHash32.hashGeoCoord(x, y).and(0x7FFFFFFF) / 2147483647.0
|
||||
// val fore = world.getTileFromTerrain(x, y)
|
||||
// val back = world.getTileFromWall(x, y)
|
||||
val newTile = if (hash < pos.toDouble() / stoneSlateDitherSize) Block.STONE_SLATE else Block.STONE
|
||||
val newTile = if (hash < pos.toDouble() / stoneSlateDitherSize) Block.STONE_SLATE else Block.STONE
|
||||
|
||||
if (y in yStart until yStart + CHUNK_H) {
|
||||
// if (fore != Block.AIR)
|
||||
world.setTileTerrain(x, y, newTile, true)
|
||||
|
||||
world.setTileWall(x, y, newTile, true)
|
||||
world.setTileTerrain(x, y, newTile, true)
|
||||
world.setTileWall(x, y, newTile, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val thicknesses = listOf(0.016, 0.021, 0.029, 0.036, 0.036, 0.029, 0.021, 0.016)
|
||||
|
||||
private fun getGenerator(seed: Long, params: TerragenParams): List<Joise> {
|
||||
override fun getGenerator(seed: Long, params: Any?): List<Joise> {
|
||||
val params = params as TerragenParams
|
||||
|
||||
// this noise tree WILL generate noise value greater than 1.0
|
||||
// they should be treated properly when you actually generate the world out of the noisemap
|
||||
// for the visualisation, no treatment will be done in this demo app.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.torvald.terrarum.modulebasegame.worldgenerator
|
||||
|
||||
import com.sudoplay.joise.Joise
|
||||
import net.torvald.random.HQRNG
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.App.printdbg
|
||||
@@ -14,31 +15,39 @@ import net.torvald.terrarum.modulebasegame.worldgenerator.Biomegen.Companion.BIO
|
||||
import net.torvald.terrarum.modulebasegame.worldgenerator.Biomegen.Companion.BIOME_KEY_WOODLANDS
|
||||
import net.torvald.terrarum.modulebasegame.worldgenerator.Terragen.Companion.YHEIGHT_DIVISOR
|
||||
import net.torvald.terrarum.realestate.LandUtil
|
||||
import net.torvald.terrarum.realestate.LandUtil.CHUNK_H
|
||||
import net.torvald.terrarum.realestate.LandUtil.CHUNK_W
|
||||
import net.torvald.terrarum.serialise.toUint
|
||||
import kotlin.math.absoluteValue
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2023-11-10.
|
||||
*/
|
||||
class Treegen(world: GameWorld, seed: Long, val terragenParams: TerragenParams, params: TreegenParams, val biomeMap: HashMap<BlockAddress, Byte>) : Gen(world, seed, params) {
|
||||
class Treegen(world: GameWorld, isFinal: Boolean, seed: Long, val terragenParams: TerragenParams, params: TreegenParams, val biomeMap: HashMap<BlockAddress, Byte>) : Gen(world, isFinal, seed, params) {
|
||||
|
||||
override fun getDone(loadscreen: LoadScreenBase) {
|
||||
loadscreen.stageValue += 1
|
||||
loadscreen.progress.set(0L)
|
||||
|
||||
Worldgen.threadExecutor.renew()
|
||||
(0 until world.width).sliceEvenly(Worldgen.genSlices).rearrange().mapIndexed { i, xs ->
|
||||
Worldgen.threadExecutor.submit {
|
||||
tryToPlant(xs, makeGrassMap(xs), HQRNG(seed shake xs.last.toLong()))
|
||||
loadscreen.progress.addAndGet((xs.last - xs.first + 1).toLong())
|
||||
}
|
||||
}
|
||||
|
||||
submitJob(loadscreen)
|
||||
Worldgen.threadExecutor.join()
|
||||
|
||||
App.printdbg(this, "Waking up Worldgen")
|
||||
}
|
||||
|
||||
|
||||
override fun draw(xStart: Int, yStart: Int, noises: List<Joise>, soff: Double) {
|
||||
for (i in 0 until 10) {
|
||||
val xs = (xStart + 9*i) until (xStart + 9*i) + 9
|
||||
tryToPlant(xs, makeGrassMap(xs), HQRNG(seed shake xs.last.toLong()))
|
||||
}
|
||||
}
|
||||
|
||||
override fun getGenerator(seed: Long, params: Any?): List<Joise> {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
private fun makeGrassMap(xs: IntProgression): Array<List<Int>> {
|
||||
val r = Array<List<Int>>(xs.last - xs.first + 1) { emptyList() }
|
||||
val ymax = (world.height * YHEIGHT_DIVISOR + terragenParams.featureSize).ceilToInt()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.torvald.terrarum.modulebasegame.worldgenerator
|
||||
|
||||
import com.jme3.math.Vector2f
|
||||
import com.sudoplay.joise.Joise
|
||||
import com.sudoplay.joise.module.*
|
||||
import net.torvald.random.XXHash64
|
||||
import net.torvald.terrarum.*
|
||||
@@ -10,7 +11,9 @@ import net.torvald.terrarum.gameworld.BlockAddress
|
||||
import net.torvald.terrarum.gameworld.GameWorld
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||
import net.torvald.terrarum.realestate.LandUtil
|
||||
import net.torvald.terrarum.realestate.LandUtil.CHUNK_H
|
||||
import net.torvald.terrarum.realestate.LandUtil.CHUNK_W
|
||||
import kotlin.math.roundToLong
|
||||
|
||||
/**
|
||||
@@ -25,7 +28,6 @@ object Worldgen {
|
||||
private set
|
||||
|
||||
val threadExecutor = TerrarumIngame.worldgenThreadExecutor
|
||||
var genSlices = -1
|
||||
|
||||
private val threadLock = java.lang.Object()
|
||||
|
||||
@@ -60,14 +62,14 @@ object Worldgen {
|
||||
}
|
||||
}
|
||||
return listOf(
|
||||
Work(Lang["MENU_IO_WORLDGEN_RETICULATING_SPLINES"], Terragen(world, highlandLowlandSelectCache, params.seed, params.terragenParams), listOf("TERRAIN")),
|
||||
Work(Lang["MENU_IO_WORLDGEN_GROWING_MINERALS"], Oregen(world, caveAttenuateBiasScaledCache, params.seed, oreRegistry), listOf("ORES")),
|
||||
Work(Lang["MENU_IO_WORLDGEN_POSITIONING_ROCKS"], OregenAutotiling(world, params.seed, oreTilingModes), listOf("ORES")),
|
||||
Work(Lang["MENU_IO_WORLDGEN_RETICULATING_SPLINES"], Terragen(world, false, highlandLowlandSelectCache, params.seed, params.terragenParams), listOf("TERRAIN")),
|
||||
Work(Lang["MENU_IO_WORLDGEN_GROWING_MINERALS"], Oregen(world, false, caveAttenuateBiasScaledCache, params.seed, oreRegistry), listOf("ORES")),
|
||||
Work(Lang["MENU_IO_WORLDGEN_POSITIONING_ROCKS"], OregenAutotiling(world, false, params.seed, oreTilingModes), listOf("ORES")),
|
||||
// TODO generate rock veins
|
||||
// TODO generate gemstones
|
||||
Work(Lang["MENU_IO_WORLDGEN_CARVING_EARTH"], Cavegen(world, highlandLowlandSelectCache, params.seed, params.terragenParams), listOf("TERRAIN", "CAVE")),
|
||||
Work(Lang["MENU_IO_WORLDGEN_PAINTING_GREEN"], Biomegen(world, params.seed, params.biomegenParams, biomeMap), listOf("BIOME")),
|
||||
Work(Lang["MENU_IO_WORLDGEN_PAINTING_GREEN"], Treegen(world, params.seed, params.terragenParams, params.treegenParams, biomeMap), listOf("TREES")),
|
||||
Work(Lang["MENU_IO_WORLDGEN_CARVING_EARTH"], Cavegen(world, false, highlandLowlandSelectCache, params.seed, params.terragenParams), listOf("TERRAIN", "CAVE")),
|
||||
Work(Lang["MENU_IO_WORLDGEN_PAINTING_GREEN"], Biomegen(world, false, params.seed, params.biomegenParams, biomeMap), listOf("BIOME")),
|
||||
Work(Lang["MENU_IO_WORLDGEN_PAINTING_GREEN"], Treegen(world, true, params.seed, params.terragenParams, params.treegenParams, biomeMap), listOf("TREES")),
|
||||
).filter(tagFilter)
|
||||
}
|
||||
|
||||
@@ -76,8 +78,6 @@ object Worldgen {
|
||||
caveAttenuateBiasScaledCache = getCaveAttenuateBiasScaled(highlandLowlandSelectCache, params.terragenParams)
|
||||
biomeMap = HashMap()
|
||||
|
||||
genSlices = world.width / 9
|
||||
|
||||
|
||||
val jobs = getJobs()
|
||||
|
||||
@@ -111,7 +111,7 @@ object Worldgen {
|
||||
* @return starting chunk Y index, ending chunk Y index (inclusive)
|
||||
*/
|
||||
fun getChunkGenStrip(world: GameWorld): Pair<Int, Int> {
|
||||
val start = (0.00342f * world.height - 3.22f).floorToInt()
|
||||
val start = (0.00342f * world.height - 3.22f).floorToInt().coerceAtLeast(0)
|
||||
return start to start + 6
|
||||
}
|
||||
|
||||
@@ -340,8 +340,32 @@ object Worldgen {
|
||||
|
||||
}
|
||||
|
||||
abstract class Gen(val world: GameWorld, val seed: Long, val params: Any? = null) {
|
||||
abstract class Gen(val world: GameWorld, val isFinal: Boolean, val seed: Long, val params: Any? = null) {
|
||||
|
||||
open fun getDone(loadscreen: LoadScreenBase) { } // trying to use different name so that it won't be confused with Runnable or Callable
|
||||
protected abstract fun getGenerator(seed: Long, params: Any?): List<Joise>
|
||||
protected abstract fun draw(xStart: Int, yStart: Int, noises: List<Joise>, soff: Double)
|
||||
|
||||
protected open fun getChunksRange(): List<Int> {
|
||||
val (yStart, yEnd) = Worldgen.getChunkGenStrip(world)
|
||||
return (0 until world.width / CHUNK_W).flatMap { cx ->
|
||||
(LandUtil.chunkXYtoChunkNum(world, cx, yStart)..LandUtil.chunkXYtoChunkNum(world, cx, yEnd)).toList()
|
||||
}
|
||||
}
|
||||
|
||||
open fun submitJob(loadscreen: LoadScreenBase) {
|
||||
getChunksRange().forEach { chunkNum ->
|
||||
val (chunkX, chunkY) = LandUtil.chunkNumToChunkXY(world, chunkNum)
|
||||
Worldgen.threadExecutor.submit {
|
||||
val localJoise = getGenerator(seed, params)
|
||||
val sampleOffset = world.width / 8.0
|
||||
draw(chunkX * LandUtil.CHUNK_W, chunkY * CHUNK_H, localJoise, sampleOffset)
|
||||
loadscreen.progress.addAndGet(1L)
|
||||
|
||||
world.chunkFlags[chunkY][chunkX] = if (isFinal) GameWorld.CHUNK_LOADED else GameWorld.CHUNK_GENERATING
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class WorldgenParams(
|
||||
|
||||
Reference in New Issue
Block a user