mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-13 03:54:06 +09:00
dynamic chunk generation
This commit is contained in:
@@ -28,6 +28,7 @@ import net.torvald.terrarum.gameitems.mouseInInteractableRange
|
|||||||
import net.torvald.terrarum.gameparticles.ParticleBase
|
import net.torvald.terrarum.gameparticles.ParticleBase
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
import net.torvald.terrarum.gameworld.WorldSimulator
|
import net.torvald.terrarum.gameworld.WorldSimulator
|
||||||
|
import net.torvald.terrarum.gameworld.fmod
|
||||||
import net.torvald.terrarum.langpack.Lang
|
import net.torvald.terrarum.langpack.Lang
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.*
|
import net.torvald.terrarum.modulebasegame.gameactors.*
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.physicssolver.CollisionSolver
|
import net.torvald.terrarum.modulebasegame.gameactors.physicssolver.CollisionSolver
|
||||||
@@ -43,6 +44,8 @@ import net.torvald.terrarum.modulebasegame.worldgenerator.RoguelikeRandomiser
|
|||||||
import net.torvald.terrarum.modulebasegame.worldgenerator.Worldgen
|
import net.torvald.terrarum.modulebasegame.worldgenerator.Worldgen
|
||||||
import net.torvald.terrarum.modulebasegame.worldgenerator.WorldgenParams
|
import net.torvald.terrarum.modulebasegame.worldgenerator.WorldgenParams
|
||||||
import net.torvald.terrarum.realestate.LandUtil
|
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.savegame.VDUtil
|
import net.torvald.terrarum.savegame.VDUtil
|
||||||
import net.torvald.terrarum.savegame.VirtualDisk
|
import net.torvald.terrarum.savegame.VirtualDisk
|
||||||
import net.torvald.terrarum.serialise.Common
|
import net.torvald.terrarum.serialise.Common
|
||||||
@@ -62,6 +65,7 @@ import org.khelekore.prtree.PRTree
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.logging.Level
|
import java.util.logging.Level
|
||||||
|
import kotlin.experimental.and
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
@@ -363,6 +367,9 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
|||||||
// Terrarum.itemCodex.loadFromSave(codices.item)
|
// Terrarum.itemCodex.loadFromSave(codices.item)
|
||||||
// Terrarum.apocryphas = HashMap(codices.apocryphas)
|
// Terrarum.apocryphas = HashMap(codices.apocryphas)
|
||||||
|
|
||||||
|
|
||||||
|
// feed info to the worldgen
|
||||||
|
Worldgen.attachMap(world, WorldgenParams(world.generatorSeed))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -898,6 +905,8 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
|||||||
App.audioMixer.convolveBusCave.volume = 0.0
|
App.audioMixer.convolveBusCave.volume = 0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
actorNowPlaying?.let { if (WORLD_UPDATE_TIMER % 4 == 1) updateWorldGenerator(actorNowPlaying!!) }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
WORLD_UPDATE_TIMER += 1
|
WORLD_UPDATE_TIMER += 1
|
||||||
@@ -1062,6 +1071,24 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Point2iMod(x: Int, y: Int) = Point2i(x fmod world.width, y)
|
||||||
|
|
||||||
|
private fun updateWorldGenerator(actor: ActorWithBody) {
|
||||||
|
val pcx = (actor.intTilewiseHitbox.canonicalX.toInt() fmod world.width) / CHUNK_W
|
||||||
|
val pcy = (actor.intTilewiseHitbox.canonicalY.toInt() fmod world.width) / CHUNK_H
|
||||||
|
listOf(
|
||||||
|
Point2iMod(pcx - 1, pcy - 2), Point2iMod(pcx, pcy - 2), Point2iMod(pcx + 1, pcy - 2),
|
||||||
|
Point2iMod(pcx - 2, pcy - 1), Point2iMod(pcx - 1, pcy - 1), Point2iMod(pcx, pcy - 1), Point2iMod(pcx + 1, pcy - 1), Point2iMod(pcx + 2, pcy - 1),
|
||||||
|
Point2iMod(pcx - 2, pcy), Point2iMod(pcx - 1, pcy), Point2iMod(pcx + 1, pcy), Point2iMod(pcx + 2, pcy),
|
||||||
|
Point2iMod(pcx - 2, pcy + 1), Point2iMod(pcx - 1, pcy + 1), Point2iMod(pcx, pcy + 1), Point2iMod(pcx + 1, pcy + 1), Point2iMod(pcx + 2, pcy + 1),
|
||||||
|
Point2iMod(pcx - 1, pcy + 2), Point2iMod(pcx, pcy + 2), Point2iMod(pcx + 1, pcy + 2),
|
||||||
|
).filter { it.y in 0 until world.height }.filter { (cx, cy) ->
|
||||||
|
world.chunkFlags[cy][cx].and(0x7F) == 0.toByte()
|
||||||
|
}.forEach { (cx, cy) ->
|
||||||
|
Worldgen.generateChunkIngame(cx, cy) { cx, cy -> }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private var worldTransitionOngoing = false
|
private var worldTransitionOngoing = false
|
||||||
private var worldTransitionPauseRequested = -1
|
private var worldTransitionPauseRequested = -1
|
||||||
private var saveRequested2 = false
|
private var saveRequested2 = false
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package net.torvald.terrarum.modulebasegame.serialise
|
|||||||
import net.torvald.gdx.graphics.PixmapIO2
|
import net.torvald.gdx.graphics.PixmapIO2
|
||||||
import net.torvald.terrarum.App.printdbg
|
import net.torvald.terrarum.App.printdbg
|
||||||
import net.torvald.terrarum.TerrarumAppConfiguration
|
import net.torvald.terrarum.TerrarumAppConfiguration
|
||||||
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
import net.torvald.terrarum.modulebasegame.IngameRenderer
|
import net.torvald.terrarum.modulebasegame.IngameRenderer
|
||||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
|
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
|
||||||
@@ -15,6 +16,7 @@ import net.torvald.terrarum.toInt
|
|||||||
import net.torvald.terrarum.utils.PlayerLastStatus
|
import net.torvald.terrarum.utils.PlayerLastStatus
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.zip.GZIPOutputStream
|
import java.util.zip.GZIPOutputStream
|
||||||
|
import kotlin.experimental.and
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2021-09-29.
|
* Created by minjaesong on 2021-09-29.
|
||||||
@@ -111,17 +113,20 @@ class QuickSingleplayerWorldSavingThread(
|
|||||||
|
|
||||||
printdbg(this, "Writing chunks... $chunksWrote/$chunkCount (chunk# $chunkNumber at layer# $layerNum)")
|
printdbg(this, "Writing chunks... $chunksWrote/$chunkCount (chunk# $chunkNumber at layer# $layerNum)")
|
||||||
|
|
||||||
val chunkXY = LandUtil.chunkNumToChunkXY(ingame.world, chunkNumber)
|
val (cx, cy) = LandUtil.chunkNumToChunkXY(ingame.world, chunkNumber)
|
||||||
|
val chunkFlag = ingame.world.chunkFlags[cy][cx]
|
||||||
|
|
||||||
// println("Chunk xy from number $chunkNumber -> (${chunkXY.x}, ${chunkXY.y})")
|
// println("Chunk xy from number $chunkNumber -> (${chunkXY.x}, ${chunkXY.y})")
|
||||||
|
|
||||||
val chunkBytes = WriteWorld.encodeChunk(layer, chunkXY.x, chunkXY.y)
|
if (chunkFlag and 0x7F == GameWorld.CHUNK_LOADED) {
|
||||||
val entryID = 0x1_0000_0000L or layerNum.toLong().shl(24) or chunkNumber.toLong()
|
val chunkBytes = WriteWorld.encodeChunk(layer, cx, cy)
|
||||||
|
val entryID = 0x1_0000_0000L or layerNum.toLong().shl(24) or chunkNumber.toLong()
|
||||||
|
|
||||||
val entryContent = EntryFile(chunkBytes)
|
val entryContent = EntryFile(chunkBytes)
|
||||||
val entry = DiskEntry(entryID, ROOT, creation_t, time_t, entryContent)
|
val entry = DiskEntry(entryID, ROOT, creation_t, time_t, entryContent)
|
||||||
// "W1L0-92,15"
|
// "W1L0-92,15"
|
||||||
addFile(disk, entry); skimmer.appendEntry(entry)
|
addFile(disk, entry); skimmer.appendEntry(entry)
|
||||||
|
}
|
||||||
|
|
||||||
WriteSavegame.saveProgress += chunkProgressMultiplier
|
WriteSavegame.saveProgress += chunkProgressMultiplier
|
||||||
chunksWrote += 1
|
chunksWrote += 1
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package net.torvald.terrarum.modulebasegame.serialise
|
|||||||
|
|
||||||
import net.torvald.gdx.graphics.PixmapIO2
|
import net.torvald.gdx.graphics.PixmapIO2
|
||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.*
|
||||||
|
import net.torvald.terrarum.gameworld.GameWorld.Companion.CHUNK_LOADED
|
||||||
import net.torvald.terrarum.modulebasegame.IngameRenderer
|
import net.torvald.terrarum.modulebasegame.IngameRenderer
|
||||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureBase
|
import net.torvald.terrarum.modulebasegame.gameactors.FixtureBase
|
||||||
@@ -12,6 +13,7 @@ import net.torvald.terrarum.savegame.*
|
|||||||
import net.torvald.terrarum.serialise.Common
|
import net.torvald.terrarum.serialise.Common
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.zip.GZIPOutputStream
|
import java.util.zip.GZIPOutputStream
|
||||||
|
import kotlin.experimental.and
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2021-09-14.
|
* Created by minjaesong on 2021-09-14.
|
||||||
@@ -129,17 +131,20 @@ class WorldSavingThread(
|
|||||||
for (layer in layers.indices) {
|
for (layer in layers.indices) {
|
||||||
for (cx in 0 until cw) {
|
for (cx in 0 until cw) {
|
||||||
for (cy in 0 until ch) {
|
for (cy in 0 until ch) {
|
||||||
|
val chunkFlag = ingame.world.chunkFlags[cy][cx]
|
||||||
val chunkNumber = LandUtil.chunkXYtoChunkNum(ingame.world, cx, cy).toLong()
|
val chunkNumber = LandUtil.chunkXYtoChunkNum(ingame.world, cx, cy).toLong()
|
||||||
|
|
||||||
|
if (chunkFlag and 0x7F == CHUNK_LOADED) {
|
||||||
// Echo("Writing chunks... ${(cw*ch*layer) + chunkNumber + 1}/${cw*ch*layers.size}")
|
// Echo("Writing chunks... ${(cw*ch*layer) + chunkNumber + 1}/${cw*ch*layers.size}")
|
||||||
|
|
||||||
val chunkBytes = WriteWorld.encodeChunk(layers[layer]!!, cx, cy)
|
val chunkBytes = WriteWorld.encodeChunk(layers[layer]!!, cx, cy)
|
||||||
val entryID = 0x1_0000_0000L or layer.toLong().shl(24) or chunkNumber
|
val entryID = 0x1_0000_0000L or layer.toLong().shl(24) or chunkNumber
|
||||||
|
|
||||||
val entryContent = EntryFile(chunkBytes)
|
val entryContent = EntryFile(chunkBytes)
|
||||||
val entry = DiskEntry(entryID, VDFileID.ROOT, creation_t, time_t, entryContent)
|
val entry = DiskEntry(entryID, VDFileID.ROOT, creation_t, time_t, entryContent)
|
||||||
// "W1L0-92,15"
|
// "W1L0-92,15"
|
||||||
addFile(disk, entry)
|
addFile(disk, entry)
|
||||||
|
}
|
||||||
|
|
||||||
WriteSavegame.saveProgress += 1
|
WriteSavegame.saveProgress += 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -193,19 +193,21 @@ object LoadSavegame {
|
|||||||
val cw = LandUtil.CHUNK_W
|
val cw = LandUtil.CHUNK_W
|
||||||
val ch = LandUtil.CHUNK_H
|
val ch = LandUtil.CHUNK_H
|
||||||
val chunkCount = world.width * world.height / (cw * ch)
|
val chunkCount = world.width * world.height / (cw * ch)
|
||||||
val hasOreLayer = (newIngame.worldDisk.getFile(0x1_0000_0000L or 2L.shl(24)) != null)
|
val worldLayer = intArrayOf(0,1,2).map { world.getLayer(it) }
|
||||||
val worldLayer = (if (hasOreLayer) intArrayOf(0,1,2) else intArrayOf(0,1)).map { world.getLayer(it) }
|
for (chunk in 0L until chunkCount) {
|
||||||
val layerCount = worldLayer.size
|
|
||||||
for (chunk in 0L until (world.width * world.height) / (cw * ch)) {
|
|
||||||
for (layer in worldLayer.indices) {
|
for (layer in worldLayer.indices) {
|
||||||
loadscreen.addMessage(Lang["MENU_IO_LOADING"])
|
loadscreen.addMessage(Lang["MENU_IO_LOADING"])
|
||||||
|
|
||||||
val chunkFile = newIngame.worldDisk.getFile(0x1_0000_0000L or layer.toLong().shl(24) or chunk)!!
|
newIngame.worldDisk.getFile(0x1_0000_0000L or layer.toLong().shl(24) or chunk)?.let { chunkFile ->
|
||||||
val (cx, cy) = LandUtil.chunkNumToChunkXY(world, chunk.toInt())
|
val (cx, cy) = LandUtil.chunkNumToChunkXY(world, chunk.toInt())
|
||||||
|
|
||||||
ReadWorld.decodeChunkToLayer(chunkFile.getContent(), worldLayer[layer]!!, cx, cy)
|
if (layer == 2) {
|
||||||
|
printdbg(this, "Loading ore layer chunk ($cx, $cy) size: ${chunkFile.getSizePure()}")
|
||||||
|
}
|
||||||
|
|
||||||
world.chunkFlags[cy][cx] = world.chunkFlags[cy][cx] or CHUNK_LOADED
|
ReadWorld.decodeChunkToLayer(chunkFile.getContent(), worldLayer[layer]!!, cx, cy)
|
||||||
|
world.chunkFlags[cy][cx] = world.chunkFlags[cy][cx] or CHUNK_LOADED
|
||||||
|
}
|
||||||
}
|
}
|
||||||
loadscreen.progress.getAndAdd(1)
|
loadscreen.progress.getAndAdd(1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import com.sudoplay.joise.module.*
|
|||||||
import net.torvald.terrarum.App
|
import net.torvald.terrarum.App
|
||||||
import net.torvald.terrarum.LoadScreenBase
|
import net.torvald.terrarum.LoadScreenBase
|
||||||
import net.torvald.terrarum.blockproperties.Block
|
import net.torvald.terrarum.blockproperties.Block
|
||||||
import net.torvald.terrarum.concurrent.sliceEvenly
|
|
||||||
import net.torvald.terrarum.gameitems.ItemID
|
import net.torvald.terrarum.gameitems.ItemID
|
||||||
import net.torvald.terrarum.gameworld.BlockAddress
|
import net.torvald.terrarum.gameworld.BlockAddress
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
@@ -28,9 +27,11 @@ class Biomegen(world: GameWorld, isFinal: Boolean, seed: Long, params: Any, val
|
|||||||
private lateinit var THISWORLD_SANDSTONE: ItemID
|
private lateinit var THISWORLD_SANDSTONE: ItemID
|
||||||
|
|
||||||
|
|
||||||
override fun getDone(loadscreen: LoadScreenBase) {
|
override fun getDone(loadscreen: LoadScreenBase?) {
|
||||||
loadscreen.stageValue += 1
|
loadscreen?.let {
|
||||||
loadscreen.progress.set(0L)
|
it.stageValue += 1
|
||||||
|
it.progress.set(0L)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
val SAND_RND = (seed shake "SANDYCOLOURS").ushr(7).xor(seed and 255L).and(255L).toInt()
|
val SAND_RND = (seed shake "SANDYCOLOURS").ushr(7).xor(seed and 255L).and(255L).toInt()
|
||||||
|
|||||||
@@ -2,11 +2,9 @@ package net.torvald.terrarum.modulebasegame.worldgenerator
|
|||||||
|
|
||||||
import com.sudoplay.joise.Joise
|
import com.sudoplay.joise.Joise
|
||||||
import com.sudoplay.joise.module.*
|
import com.sudoplay.joise.module.*
|
||||||
import net.torvald.random.XXHash32
|
|
||||||
import net.torvald.terrarum.App
|
import net.torvald.terrarum.App
|
||||||
import net.torvald.terrarum.LoadScreenBase
|
import net.torvald.terrarum.LoadScreenBase
|
||||||
import net.torvald.terrarum.blockproperties.Block
|
import net.torvald.terrarum.blockproperties.Block
|
||||||
import net.torvald.terrarum.concurrent.sliceEvenly
|
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
import net.torvald.terrarum.realestate.LandUtil.CHUNK_H
|
import net.torvald.terrarum.realestate.LandUtil.CHUNK_H
|
||||||
import net.torvald.terrarum.realestate.LandUtil.CHUNK_W
|
import net.torvald.terrarum.realestate.LandUtil.CHUNK_W
|
||||||
@@ -23,9 +21,11 @@ class Cavegen(world: GameWorld, isFinal: Boolean, val highlandLowlandSelectCache
|
|||||||
const val YHEIGHT_DIVISOR = 2.0 / 7.0
|
const val YHEIGHT_DIVISOR = 2.0 / 7.0
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDone(loadscreen: LoadScreenBase) {
|
override fun getDone(loadscreen: LoadScreenBase?) {
|
||||||
loadscreen.stageValue += 1
|
loadscreen?.let {
|
||||||
loadscreen.progress.set(0L)
|
it.stageValue += 1
|
||||||
|
it.progress.set(0L)
|
||||||
|
}
|
||||||
|
|
||||||
Worldgen.threadExecutor.renew()
|
Worldgen.threadExecutor.renew()
|
||||||
submitJob(loadscreen)
|
submitJob(loadscreen)
|
||||||
|
|||||||
@@ -3,11 +3,9 @@ package net.torvald.terrarum.modulebasegame.worldgenerator
|
|||||||
import com.sudoplay.joise.Joise
|
import com.sudoplay.joise.Joise
|
||||||
import com.sudoplay.joise.module.*
|
import com.sudoplay.joise.module.*
|
||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.*
|
||||||
import net.torvald.terrarum.concurrent.sliceEvenly
|
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
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_DIVISOR
|
||||||
import net.torvald.terrarum.modulebasegame.worldgenerator.Terragen.Companion.YHEIGHT_MAGIC
|
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_H
|
||||||
import net.torvald.terrarum.realestate.LandUtil.CHUNK_W
|
import net.torvald.terrarum.realestate.LandUtil.CHUNK_W
|
||||||
import kotlin.math.cos
|
import kotlin.math.cos
|
||||||
@@ -18,9 +16,11 @@ import kotlin.math.sqrt
|
|||||||
* Created by minjaesong on 2023-10-25.
|
* Created by minjaesong on 2023-10-25.
|
||||||
*/
|
*/
|
||||||
class Oregen(world: GameWorld, isFinal: Boolean, private val caveAttenuateBiasScaledCache: ModuleCache, seed: Long, private val ores: List<OregenParams>) : Gen(world, isFinal, 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) {
|
override fun getDone(loadscreen: LoadScreenBase?) {
|
||||||
loadscreen.stageValue += 1
|
loadscreen?.let {
|
||||||
loadscreen.progress.set(0L)
|
it.stageValue += 1
|
||||||
|
it.progress.set(0L)
|
||||||
|
}
|
||||||
|
|
||||||
Worldgen.threadExecutor.renew()
|
Worldgen.threadExecutor.renew()
|
||||||
submitJob(loadscreen)
|
submitJob(loadscreen)
|
||||||
|
|||||||
@@ -4,12 +4,10 @@ import com.sudoplay.joise.Joise
|
|||||||
import net.torvald.random.XXHash64
|
import net.torvald.random.XXHash64
|
||||||
import net.torvald.terrarum.LoadScreenBase
|
import net.torvald.terrarum.LoadScreenBase
|
||||||
import net.torvald.terrarum.Point2i
|
import net.torvald.terrarum.Point2i
|
||||||
import net.torvald.terrarum.concurrent.sliceEvenly
|
|
||||||
import net.torvald.terrarum.gameitems.ItemID
|
import net.torvald.terrarum.gameitems.ItemID
|
||||||
import net.torvald.terrarum.gameitems.isOre
|
import net.torvald.terrarum.gameitems.isOre
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
import net.torvald.terrarum.gameworld.fmod
|
import net.torvald.terrarum.gameworld.fmod
|
||||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
|
||||||
import net.torvald.terrarum.realestate.LandUtil
|
import net.torvald.terrarum.realestate.LandUtil
|
||||||
import net.torvald.terrarum.realestate.LandUtil.CHUNK_H
|
import net.torvald.terrarum.realestate.LandUtil.CHUNK_H
|
||||||
import net.torvald.terrarum.realestate.LandUtil.CHUNK_W
|
import net.torvald.terrarum.realestate.LandUtil.CHUNK_W
|
||||||
@@ -24,7 +22,7 @@ import kotlin.math.max
|
|||||||
*/
|
*/
|
||||||
class OregenAutotiling(world: GameWorld, isFinal: Boolean, seed: Long, val tilingModes: HashMap<ItemID, String>) : Gen(world, isFinal, seed) {
|
class OregenAutotiling(world: GameWorld, isFinal: Boolean, seed: Long, val tilingModes: HashMap<ItemID, String>) : Gen(world, isFinal, seed) {
|
||||||
|
|
||||||
override fun getDone(loadscreen: LoadScreenBase) {
|
override fun getDone(loadscreen: LoadScreenBase?) {
|
||||||
Worldgen.threadExecutor.renew()
|
Worldgen.threadExecutor.renew()
|
||||||
submitJob(loadscreen)
|
submitJob(loadscreen)
|
||||||
Worldgen.threadExecutor.join()
|
Worldgen.threadExecutor.join()
|
||||||
|
|||||||
@@ -29,9 +29,11 @@ class Terragen(world: GameWorld, isFinal: Boolean , val highlandLowlandSelectCac
|
|||||||
private val dirtStoneDitherSize = 3 // actual dither size will be double of this value
|
private val dirtStoneDitherSize = 3 // actual dither size will be double of this value
|
||||||
private val stoneSlateDitherSize = 4
|
private val stoneSlateDitherSize = 4
|
||||||
|
|
||||||
override fun getDone(loadscreen: LoadScreenBase) {
|
override fun getDone(loadscreen: LoadScreenBase?) {
|
||||||
loadscreen.stageValue += 1
|
loadscreen?.let {
|
||||||
loadscreen.progress.set(0L)
|
it.stageValue += 1
|
||||||
|
it.progress.set(0L)
|
||||||
|
}
|
||||||
|
|
||||||
Worldgen.threadExecutor.renew()
|
Worldgen.threadExecutor.renew()
|
||||||
submitJob(loadscreen)
|
submitJob(loadscreen)
|
||||||
@@ -98,7 +100,7 @@ class Terragen(world: GameWorld, isFinal: Boolean , val highlandLowlandSelectCac
|
|||||||
%
|
%
|
||||||
* - where the stone layer actually begins
|
* - where the stone layer actually begins
|
||||||
*/
|
*/
|
||||||
if (dirtStoneTransition > 0) {
|
/*if (dirtStoneTransition > 0) {
|
||||||
for (pos in 0 until dirtStoneDitherSize * 2) {
|
for (pos in 0 until dirtStoneDitherSize * 2) {
|
||||||
val y = pos + dirtStoneTransition - (dirtStoneDitherSize * 2) + 1
|
val y = pos + dirtStoneTransition - (dirtStoneDitherSize * 2) + 1
|
||||||
if (y >= world.height) break
|
if (y >= world.height) break
|
||||||
@@ -116,14 +118,14 @@ class Terragen(world: GameWorld, isFinal: Boolean , val highlandLowlandSelectCac
|
|||||||
world.setTileWall(x, y, newTile, true)
|
world.setTileWall(x, y, newTile, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#
|
#
|
||||||
# - stone-to-slate transition, height = stoneSlateDitherSize
|
# - stone-to-slate transition, height = stoneSlateDitherSize
|
||||||
#
|
#
|
||||||
*/
|
*/
|
||||||
if (stoneSlateTransition > 0) {
|
/*if (stoneSlateTransition > 0) {
|
||||||
for (pos in 0 until stoneSlateDitherSize) {
|
for (pos in 0 until stoneSlateDitherSize) {
|
||||||
val y = pos + stoneSlateTransition - stoneSlateDitherSize + 1
|
val y = pos + stoneSlateTransition - stoneSlateDitherSize + 1
|
||||||
if (y >= world.height) break
|
if (y >= world.height) break
|
||||||
@@ -138,7 +140,7 @@ class Terragen(world: GameWorld, isFinal: Boolean , val highlandLowlandSelectCac
|
|||||||
world.setTileWall(x, y, newTile, true)
|
world.setTileWall(x, y, newTile, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,32 +2,28 @@ package net.torvald.terrarum.modulebasegame.worldgenerator
|
|||||||
|
|
||||||
import com.sudoplay.joise.Joise
|
import com.sudoplay.joise.Joise
|
||||||
import net.torvald.random.HQRNG
|
import net.torvald.random.HQRNG
|
||||||
|
import net.torvald.random.XXHash32
|
||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.*
|
||||||
import net.torvald.terrarum.App.printdbg
|
import net.torvald.terrarum.App.printdbg
|
||||||
import net.torvald.terrarum.blockproperties.Block
|
import net.torvald.terrarum.blockproperties.Block
|
||||||
import net.torvald.terrarum.concurrent.sliceEvenly
|
|
||||||
import net.torvald.terrarum.gameitems.ItemID
|
import net.torvald.terrarum.gameitems.ItemID
|
||||||
import net.torvald.terrarum.gameworld.BlockAddress
|
import net.torvald.terrarum.gameworld.BlockAddress
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||||
import net.torvald.terrarum.modulebasegame.worldgenerator.Biomegen.Companion.BIOME_KEY_PLAINS
|
|
||||||
import net.torvald.terrarum.modulebasegame.worldgenerator.Biomegen.Companion.BIOME_KEY_SPARSE_WOODS
|
|
||||||
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.modulebasegame.worldgenerator.Terragen.Companion.YHEIGHT_DIVISOR
|
||||||
import net.torvald.terrarum.realestate.LandUtil
|
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 net.torvald.terrarum.serialise.toUint
|
||||||
import kotlin.math.absoluteValue
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2023-11-10.
|
* Created by minjaesong on 2023-11-10.
|
||||||
*/
|
*/
|
||||||
class Treegen(world: GameWorld, isFinal: Boolean, seed: Long, val terragenParams: TerragenParams, params: TreegenParams, val biomeMap: HashMap<BlockAddress, Byte>) : Gen(world, isFinal, 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) {
|
override fun getDone(loadscreen: LoadScreenBase?) {
|
||||||
loadscreen.stageValue += 1
|
loadscreen?.let {
|
||||||
loadscreen.progress.set(0L)
|
it.stageValue += 1
|
||||||
|
it.progress.set(0L)
|
||||||
|
}
|
||||||
|
|
||||||
Worldgen.threadExecutor.renew()
|
Worldgen.threadExecutor.renew()
|
||||||
submitJob(loadscreen)
|
submitJob(loadscreen)
|
||||||
@@ -40,7 +36,7 @@ class Treegen(world: GameWorld, isFinal: Boolean, seed: Long, val terragenParams
|
|||||||
override fun draw(xStart: Int, yStart: Int, noises: List<Joise>, soff: Double) {
|
override fun draw(xStart: Int, yStart: Int, noises: List<Joise>, soff: Double) {
|
||||||
for (i in 0 until 10) {
|
for (i in 0 until 10) {
|
||||||
val xs = (xStart + 9*i) until (xStart + 9*i) + 9
|
val xs = (xStart + 9*i) until (xStart + 9*i) + 9
|
||||||
tryToPlant(xs, makeGrassMap(xs), HQRNG(seed shake xs.last.toLong()))
|
tryToPlant(xs, 986578287, makeGrassMap(xs), HQRNG(seed shake xs.last.toLong()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,9 +70,19 @@ class Treegen(world: GameWorld, isFinal: Boolean, seed: Long, val terragenParams
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
private val treePlot1 = arrayOf(2, 3)
|
private val treePlot1 = intArrayOf(2, 3)
|
||||||
private val treePlot2 = arrayOf(6, 7)
|
private val treePlot2 = intArrayOf(6, 7)
|
||||||
private val treePlotM = arrayOf(4, 5)
|
private val treePlotM = intArrayOf(4, 5)
|
||||||
|
|
||||||
|
private fun IntArray.takeRand(x: Int, y: Int, h: Int): Int {
|
||||||
|
val r = ((XXHash32.hashGeoCoord(x, y) * 31 + h) and 0xFFFFFF) / 16777216f
|
||||||
|
return this[(r * this.size).toInt()]
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun List<Int>.takeRand(x: Int, y: Int, h: Int): Int {
|
||||||
|
val r = ((XXHash32.hashGeoCoord(x, y) * 31 + h) and 0xFFFFFF) / 16777216f
|
||||||
|
return this[(r * this.size).toInt()]
|
||||||
|
}
|
||||||
|
|
||||||
private fun Double.toDitherredInt(rng: HQRNG): Int {
|
private fun Double.toDitherredInt(rng: HQRNG): Int {
|
||||||
val ibase = this.floorToInt()
|
val ibase = this.floorToInt()
|
||||||
@@ -84,7 +90,7 @@ class Treegen(world: GameWorld, isFinal: Boolean, seed: Long, val terragenParams
|
|||||||
return if (rng.nextDouble() < 1.0 - thre) ibase else ibase + 1
|
return if (rng.nextDouble() < 1.0 - thre) ibase else ibase + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun tryToPlant(xs: IntProgression, grassMap: Array<List<Int>>, rng: HQRNG) {
|
private fun tryToPlant(xs: IntProgression, ys: Int, grassMap: Array<List<Int>>, rng: HQRNG) {
|
||||||
val treeSpecies = 0
|
val treeSpecies = 0
|
||||||
|
|
||||||
|
|
||||||
@@ -130,28 +136,28 @@ class Treegen(world: GameWorld, isFinal: Boolean, seed: Long, val terragenParams
|
|||||||
|
|
||||||
when (treeToSpawn.size) {
|
when (treeToSpawn.size) {
|
||||||
2 -> {
|
2 -> {
|
||||||
val plot1 = if (treeToSpawn[0] < 3) treePlot1.random() else treePlot1[0]
|
val plot1 = if (treeToSpawn[0] < 3) treePlot1.takeRand(xs.first, ys, 123) else treePlot1[0]
|
||||||
val plot2 = if (treeToSpawn[1] < 3) treePlot2.random() else treePlot2[0]
|
val plot2 = if (treeToSpawn[1] < 3) treePlot2.takeRand(xs.first, ys, 456) else treePlot2[0]
|
||||||
|
|
||||||
// if there is no grass, grassMap[x] is an empty list
|
// if there is no grass, grassMap[x] is an empty list
|
||||||
if (treeToSpawn[0] != 0) {
|
if (treeToSpawn[0] != 0) {
|
||||||
grassMap[plot1].let { if (it.isEmpty()) null else it.random() }?.let {
|
grassMap[plot1].let { if (it.isEmpty()) null else it.takeRand(xs.first + plot1, ys, 1234) }?.let {
|
||||||
plantTree(xs.first + plot1, it, treeSpecies, 1, rng) // TODO use treeSize from the treeToSpawn
|
plantTree(xs.first + plot1, it, treeSpecies, 1, rng) // TODO use treeSize from the treeToSpawn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (treeToSpawn[1] != 0) {
|
if (treeToSpawn[1] != 0) {
|
||||||
grassMap[plot2].let { if (it.isEmpty()) null else it.random() }?.let {
|
grassMap[plot2].let { if (it.isEmpty()) null else it.takeRand(xs.first + plot2, ys, 2345) }?.let {
|
||||||
plantTree(xs.first + plot2, it, treeSpecies, 1, rng) // TODO use treeSize from the treeToSpawn
|
plantTree(xs.first + plot2, it, treeSpecies, 1, rng) // TODO use treeSize from the treeToSpawn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
1 -> {
|
1 -> {
|
||||||
val plot1 = if (treeToSpawn[0] < 3) treePlotM.random() else treePlotM[0]
|
val plot1 = if (treeToSpawn[0] < 3) treePlotM.takeRand(xs.first, ys, 3456) else treePlotM[0]
|
||||||
|
|
||||||
// if there is no grass, grassMap[x] is an empty list
|
// if there is no grass, grassMap[x] is an empty list
|
||||||
if (treeToSpawn[0] != 0) {
|
if (treeToSpawn[0] != 0) {
|
||||||
val treeSize = arrayOf(null, 0, 1, 2)[treeToSpawn[0]]
|
val treeSize = arrayOf(null, 0, 1, 2)[treeToSpawn[0]]
|
||||||
grassMap[plot1].let { if (it.isEmpty()) null else it.random() }?.let {
|
grassMap[plot1].let { if (it.isEmpty()) null else it.takeRand(xs.first + plot1, ys, 4567) }?.let {
|
||||||
plantTree(xs.first + plot1, it, treeSpecies, treeSize!!, rng)
|
plantTree(xs.first + plot1, it, treeSpecies, treeSize!!, rng)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -367,7 +373,9 @@ class Treegen(world: GameWorld, isFinal: Boolean, seed: Long, val terragenParams
|
|||||||
val xEnd = xStart + width
|
val xEnd = xStart + width
|
||||||
var xStart2 = xStart
|
var xStart2 = xStart
|
||||||
var xEnd2 = xEnd
|
var xEnd2 = xEnd
|
||||||
Math.random().let {
|
|
||||||
|
val r = (XXHash32.hashGeoCoord(x, y) * width * height + growCnt).and(0xffffff) / 16777216f
|
||||||
|
r.let {
|
||||||
if (it < 0.25) xStart2 += 1
|
if (it < 0.25) xStart2 += 1
|
||||||
else if (it < 0.5) xEnd2 -= 1
|
else if (it < 0.5) xEnd2 -= 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,10 @@ object Worldgen {
|
|||||||
fun attachMap(world: GameWorld, genParams: WorldgenParams) {
|
fun attachMap(world: GameWorld, genParams: WorldgenParams) {
|
||||||
this.world = world
|
this.world = world
|
||||||
params = genParams
|
params = genParams
|
||||||
|
|
||||||
|
highlandLowlandSelectCache = getHighlandLowlandSelectCache(params.terragenParams, params.seed)
|
||||||
|
caveAttenuateBiasScaledCache = getCaveAttenuateBiasScaled(highlandLowlandSelectCache, params.terragenParams)
|
||||||
|
biomeMap = HashMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal lateinit var highlandLowlandSelectCache: ModuleCache
|
internal lateinit var highlandLowlandSelectCache: ModuleCache
|
||||||
@@ -74,11 +78,6 @@ object Worldgen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun generateMap(loadscreen: LoadScreenBase) {
|
fun generateMap(loadscreen: LoadScreenBase) {
|
||||||
highlandLowlandSelectCache = getHighlandLowlandSelectCache(params.terragenParams, params.seed)
|
|
||||||
caveAttenuateBiasScaledCache = getCaveAttenuateBiasScaled(highlandLowlandSelectCache, params.terragenParams)
|
|
||||||
biomeMap = HashMap()
|
|
||||||
|
|
||||||
|
|
||||||
val jobs = getJobs()
|
val jobs = getJobs()
|
||||||
|
|
||||||
|
|
||||||
@@ -101,6 +100,28 @@ object Worldgen {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chunk flags will be set automatically
|
||||||
|
*/
|
||||||
|
fun generateChunkIngame(cx: Int, cy: Int, callback: (Int, Int) -> Unit) {
|
||||||
|
val jobs = getJobs()
|
||||||
|
printdbg(this, "Generating chunk on ($cx, $cy)")
|
||||||
|
Thread {
|
||||||
|
world.chunkFlags[cy][cx] = GameWorld.CHUNK_GENERATING
|
||||||
|
|
||||||
|
for (i in jobs.indices) {
|
||||||
|
val it = jobs[i]
|
||||||
|
it.theWork.getChunkDone(cx, cy)
|
||||||
|
}
|
||||||
|
|
||||||
|
world.chunkFlags[cy][cx] = GameWorld.CHUNK_LOADED
|
||||||
|
callback(cx, cy)
|
||||||
|
}.let {
|
||||||
|
it.priority = 2
|
||||||
|
it.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data class Work(val loadingScreenName: String, val theWork: Gen, val tags: List<String>)
|
data class Work(val loadingScreenName: String, val theWork: Gen, val tags: List<String>)
|
||||||
|
|
||||||
fun getEstimationSec(width: Int, height: Int): Long {
|
fun getEstimationSec(width: Int, height: Int): Long {
|
||||||
@@ -122,6 +143,7 @@ object Worldgen {
|
|||||||
val yInit = getChunkGenStrip(world).first
|
val yInit = getChunkGenStrip(world).first
|
||||||
val tallies = ArrayList<Pair<Point2i, Vector2f>>() // xypos, score (0..1+)
|
val tallies = ArrayList<Pair<Point2i, Vector2f>>() // xypos, score (0..1+)
|
||||||
var tries = 0
|
var tries = 0
|
||||||
|
var found = false
|
||||||
while (tries < 99) {
|
while (tries < 99) {
|
||||||
val posX = (Math.random() * world.width).toInt()
|
val posX = (Math.random() * world.width).toInt()
|
||||||
var posY = yInit * CHUNK_H
|
var posY = yInit * CHUNK_H
|
||||||
@@ -166,12 +188,23 @@ object Worldgen {
|
|||||||
|
|
||||||
printdbg(this, "...Survey says: $rocks/$rockScoreMin rocks, $trees/$treeScoreMin trees")
|
printdbg(this, "...Survey says: $rocks/$rockScoreMin rocks, $trees/$treeScoreMin trees")
|
||||||
|
|
||||||
if (score.x >= 1f && score.y >= 1f) break
|
if (score.x >= 1f && score.y >= 1f) {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
tries += 1
|
tries += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
return tallies.last().first
|
||||||
|
|
||||||
return tallies.toTypedArray().also {
|
return tallies.toTypedArray().also {
|
||||||
|
it.map { it.second.let {
|
||||||
|
it.x = (it.x).coerceAtMost(1f)
|
||||||
|
it.y = (it.y).coerceAtMost(1f)
|
||||||
|
} }
|
||||||
|
|
||||||
it.shuffle()
|
it.shuffle()
|
||||||
it.sortByDescending { it.second.lengthSquared() }
|
it.sortByDescending { it.second.lengthSquared() }
|
||||||
|
|
||||||
@@ -342,30 +375,36 @@ object Worldgen {
|
|||||||
|
|
||||||
abstract class Gen(val world: GameWorld, val isFinal: Boolean, 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
|
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 getGenerator(seed: Long, params: Any?): List<Joise>
|
||||||
protected abstract fun draw(xStart: Int, yStart: Int, noises: List<Joise>, soff: Double)
|
protected abstract fun draw(xStart: Int, yStart: Int, noises: List<Joise>, soff: Double)
|
||||||
|
|
||||||
protected open fun getChunksRange(): List<Int> {
|
private fun getChunksRange(): List<Int> {
|
||||||
val (yStart, yEnd) = Worldgen.getChunkGenStrip(world)
|
val (yStart, yEnd) = Worldgen.getChunkGenStrip(world)
|
||||||
return (0 until world.width / CHUNK_W).flatMap { cx ->
|
return (0 until world.width / CHUNK_W).flatMap { cx ->
|
||||||
(LandUtil.chunkXYtoChunkNum(world, cx, yStart)..LandUtil.chunkXYtoChunkNum(world, cx, yEnd)).toList()
|
(LandUtil.chunkXYtoChunkNum(world, cx, yStart)..LandUtil.chunkXYtoChunkNum(world, cx, yEnd)).toList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun submitJob(loadscreen: LoadScreenBase) {
|
fun submitJob(loadscreen: LoadScreenBase?) {
|
||||||
getChunksRange().forEach { chunkNum ->
|
getChunksRange().forEach { chunkNum ->
|
||||||
val (chunkX, chunkY) = LandUtil.chunkNumToChunkXY(world, chunkNum)
|
val (chunkX, chunkY) = LandUtil.chunkNumToChunkXY(world, chunkNum)
|
||||||
Worldgen.threadExecutor.submit {
|
Worldgen.threadExecutor.submit {
|
||||||
val localJoise = getGenerator(seed, params)
|
val localJoise = getGenerator(seed, params)
|
||||||
val sampleOffset = world.width / 8.0
|
val sampleOffset = world.width / 8.0
|
||||||
draw(chunkX * LandUtil.CHUNK_W, chunkY * CHUNK_H, localJoise, sampleOffset)
|
draw(chunkX * LandUtil.CHUNK_W, chunkY * CHUNK_H, localJoise, sampleOffset)
|
||||||
loadscreen.progress.addAndGet(1L)
|
loadscreen?.progress?.addAndGet(1L)
|
||||||
|
|
||||||
world.chunkFlags[chunkY][chunkX] = if (isFinal) GameWorld.CHUNK_LOADED else GameWorld.CHUNK_GENERATING
|
world.chunkFlags[chunkY][chunkX] = if (isFinal) GameWorld.CHUNK_LOADED else GameWorld.CHUNK_GENERATING
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getChunkDone(chunkX: Int, chunkY: Int) {
|
||||||
|
val localJoise = getGenerator(seed, params)
|
||||||
|
val sampleOffset = world.width / 8.0
|
||||||
|
draw(chunkX * LandUtil.CHUNK_W, chunkY * CHUNK_H, localJoise, sampleOffset)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class WorldgenParams(
|
data class WorldgenParams(
|
||||||
|
|||||||
@@ -162,20 +162,22 @@ class BasicDebugInfoWindow : UICanvas() {
|
|||||||
val xo = 224
|
val xo = 224
|
||||||
val yo = 78
|
val yo = 78
|
||||||
|
|
||||||
|
try {
|
||||||
|
world?.let { world ->
|
||||||
|
val ppos = ingame?.actorNowPlaying?.centrePosVector
|
||||||
|
val pcx = (ppos?.x?.div(TILE_SIZED)?.fmod(world.width.toDouble())?.div(CHUNK_W)?.toInt() ?: -999)
|
||||||
|
val pcy = (ppos?.y?.div(TILE_SIZED)?.fmod(world.height.toDouble())?.div(CHUNK_H)?.toInt() ?: -999)
|
||||||
|
|
||||||
world?.let { world ->
|
for (y in 0 until world.height / CHUNK_H) {
|
||||||
val ppos = ingame?.actorNowPlaying?.centrePosVector
|
for (x in 0 until world.width / CHUNK_W) {
|
||||||
val pcx = (ppos?.x?.div(TILE_SIZED)?.fmod(world.width.toDouble())?.div(CHUNK_W)?.toInt() ?: -999)
|
val chunkStat = world.chunkFlags[y][x].toUint()
|
||||||
val pcy = (ppos?.y?.div(TILE_SIZED)?.fmod(world.height.toDouble())?.div(CHUNK_H)?.toInt() ?: -999)
|
batch.color = if (pcx == x && pcy == y) chunkStatCurrentChunk else chunkStatColours[chunkStat]
|
||||||
|
Toolkit.fillArea(batch, xo + 3 * x, yo + 3 * y, 2, 2)
|
||||||
for (y in 0 until world.height / CHUNK_H) {
|
}
|
||||||
for (x in 0 until world.width / CHUNK_W) {
|
|
||||||
val chunkStat = world.chunkFlags[y][x].toUint()
|
|
||||||
batch.color = if (pcx == x && pcy == y) chunkStatCurrentChunk else chunkStatColours[chunkStat]
|
|
||||||
Toolkit.fillArea(batch, xo + 3*x, yo + 3*y, 2, 2)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (_: UninitializedPropertyAccessException) {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user