diff --git a/src/net/torvald/UnsafePtr.kt b/src/net/torvald/UnsafePtr.kt index 3f4ce9ca9..ca95aaafb 100644 --- a/src/net/torvald/UnsafePtr.kt +++ b/src/net/torvald/UnsafePtr.kt @@ -97,12 +97,12 @@ internal class UnsafePtr(pointer: Long, allocSize: Long) { } private inline fun checkNullPtr(index: Long) { // ignore what IDEA says and do inline this - //// commenting out because of the suspected (or minor?) performance impact. - //// You may break the glass and use this tool when some fucking incomprehensible bugs ("vittujen vitun bugit") - //// appear (e.g. getting garbage values when it fucking shouldn't) + // commenting out because of the suspected (or minor?) performance impact. + // You may break the glass and use this tool when some fucking incomprehensible bugs ("vittujen vitun bugit") + // appear (e.g. getting garbage values when it fucking shouldn't) - //assert(!destroyed) { throw NullPointerException("The pointer is already destroyed ($this)") } - //if (index !in 0 until size) throw IndexOutOfBoundsException("Index: $index; alloc size: $size") +// assert(!destroyed) { throw NullPointerException("The pointer is already destroyed ($this)") } +// if (index !in 0 until size) throw IndexOutOfBoundsException("Index: $index; alloc size: $size") } operator fun get(index: Long): Byte { diff --git a/src/net/torvald/terrarum/TitleScreen.kt b/src/net/torvald/terrarum/TitleScreen.kt index abb21846a..8339b146d 100644 --- a/src/net/torvald/terrarum/TitleScreen.kt +++ b/src/net/torvald/terrarum/TitleScreen.kt @@ -24,6 +24,7 @@ import net.torvald.terrarum.modulebasegame.IngameRenderer import net.torvald.terrarum.modulebasegame.TerrarumIngame import net.torvald.terrarum.modulebasegame.ui.UIRemoCon import net.torvald.terrarum.modulebasegame.ui.UITitleRemoConYaml +import net.torvald.terrarum.realestate.LandUtil import net.torvald.terrarum.serialise.ReadWorld import net.torvald.terrarum.ui.UICanvas import net.torvald.terrarum.weather.WeatherMixer @@ -125,12 +126,12 @@ class TitleScreen(batch: SpriteBatch) : IngameInstance(batch) { try { val reader = java.io.FileReader(ModMgr.getFile("basegame", "demoworld")) //ReadWorld.readWorldAndSetNewWorld(Terrarum.ingame!! as TerrarumIngame, reader) - val world = ReadWorld.invoke(reader) + val world = ReadWorld.readLayerFormat(reader) demoWorld = world printdbg(this, "Demo world loaded") } catch (e: IOException) { - demoWorld = GameWorld(1, 64, 64, 0L, 0L, 0) + demoWorld = GameWorld(1, LandUtil.CHUNK_W, LandUtil.CHUNK_H, 0L, 0L, 0) printdbg(this, "Demo world not found, using empty world") } diff --git a/src/net/torvald/terrarum/gameworld/BlockLayer.kt b/src/net/torvald/terrarum/gameworld/BlockLayer.kt index ac79a5b47..dacc7fc2a 100644 --- a/src/net/torvald/terrarum/gameworld/BlockLayer.kt +++ b/src/net/torvald/terrarum/gameworld/BlockLayer.kt @@ -68,8 +68,14 @@ open class BlockLayer(val width: Int, val height: Int) : Disposable { val msb = tile.ushr(8).and(0xff).toByte() - ptr[offset] = lsb - ptr[offset + 1] = msb +// try { + ptr[offset] = lsb + ptr[offset + 1] = msb +// } +// catch (e: IndexOutOfBoundsException) { +// printdbgerr(this, "IndexOutOfBoundsException: x = $x, y = $y; offset = $offset") +// throw e +// } } /** diff --git a/src/net/torvald/terrarum/gameworld/GameWorld.kt b/src/net/torvald/terrarum/gameworld/GameWorld.kt index c683408bc..56416aff0 100644 --- a/src/net/torvald/terrarum/gameworld/GameWorld.kt +++ b/src/net/torvald/terrarum/gameworld/GameWorld.kt @@ -18,7 +18,15 @@ import kotlin.math.absoluteValue typealias BlockAddress = Long -class GameWorld() : Disposable { +/** + * Special version of GameWorld where layer data are not transient + */ +class GameWorldTitleScreen : GameWorld() { + override lateinit var layerWall: BlockLayer + override lateinit var layerTerrain: BlockLayer +} + +open class GameWorld() : Disposable { var worldName: String = "New World" /** Index start at 1 */ @@ -43,8 +51,8 @@ class GameWorld() : Disposable { internal set //layers - lateinit var layerWall: BlockLayer - lateinit var layerTerrain: BlockLayer + @Transient lateinit open var layerWall: BlockLayer + @Transient lateinit open var layerTerrain: BlockLayer //val layerThermal: MapLayerHalfFloat // in Kelvins //val layerFluidPressure: MapLayerHalfFloat // (milibar - 1000) @@ -185,6 +193,12 @@ class GameWorld() : Disposable { //val wireArray: ByteArray // get() = layerWire.data + fun getLayer(index: Int) = when(index) { + 0 -> layerTerrain + 1 -> layerWall + else -> throw IllegalArgumentException("Unknown layer index: $index") + } + fun coerceXY(x: Int, y: Int) = (x fmod width) to (y.coerceIn(0, height - 1)) /** diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index 4cdb0c7bb..54b33369b 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -34,10 +34,10 @@ import net.torvald.terrarum.modulebasegame.ui.* import net.torvald.terrarum.modulebasegame.worldgenerator.RoguelikeRandomiser import net.torvald.terrarum.modulebasegame.worldgenerator.Worldgen import net.torvald.terrarum.modulebasegame.worldgenerator.WorldgenParams -import net.torvald.terrarum.tvda.VDUtil import net.torvald.terrarum.realestate.LandUtil import net.torvald.terrarum.serialise.Common import net.torvald.terrarum.serialise.WriteMeta +import net.torvald.terrarum.tvda.VDUtil import net.torvald.terrarum.ui.UICanvas import net.torvald.terrarum.weather.WeatherMixer import net.torvald.terrarum.worlddrawer.BlocksDrawer @@ -296,6 +296,7 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { // init map as chosen size val timeNow = App.getTIME_T() world = GameWorld(1, worldParams.width, worldParams.height, timeNow, timeNow, 0) // new game, so the creation time is right now + world.generatorSeed = worldParams.worldGenSeed gameworldIndices.add(world.worldIndex) world.extraFields["basegame.economy"] = GameEconomy() diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIProxyNewRandomGame.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIProxyNewRandomGame.kt index c605f4b32..8b16e297f 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIProxyNewRandomGame.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIProxyNewRandomGame.kt @@ -2,6 +2,7 @@ package net.torvald.terrarum.modulebasegame.ui import com.badlogic.gdx.graphics.Camera import com.badlogic.gdx.graphics.g2d.SpriteBatch +import net.torvald.random.HQRNG import net.torvald.terrarum.App import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.Second @@ -37,8 +38,8 @@ class UIProxyNewRandomGame : UICanvas() { val ingame = TerrarumIngame(App.batch) -// val worldParam = TerrarumIngame.NewWorldParameters(2880, 1344, HQRNG().nextLong()) - val worldParam = TerrarumIngame.NewWorldParameters(2880, 1350, 0x51621D) + val worldParam = TerrarumIngame.NewWorldParameters(2880, 1350, HQRNG().nextLong()) +// val worldParam = TerrarumIngame.NewWorldParameters(2880, 1350, 0x51621D) //val worldParam = TerrarumIngame.NewWorldParameters(6000, 1800, 0x51621DL) // small // val worldParam = TerrarumIngame.NewWorldParameters(9000, 2250, 0x51621DL) // normal diff --git a/src/net/torvald/terrarum/serialise/Common.kt b/src/net/torvald/terrarum/serialise/Common.kt index c470f7d5a..68a8ad4d6 100644 --- a/src/net/torvald/terrarum/serialise/Common.kt +++ b/src/net/torvald/terrarum/serialise/Common.kt @@ -75,9 +75,6 @@ object Common { } override fun read(json: Json, jsonData: JsonValue, type: Class<*>): BlockLayer { - // full auto - //return strToBlockLayer(json.fromJson(type, jsonData.toJson(JsonWriter.OutputType.minimal)) as LayerInfo) - // full manual try { return strToBlockLayer(LayerInfo( diff --git a/src/net/torvald/terrarum/serialise/WriteMeta.kt b/src/net/torvald/terrarum/serialise/WriteMeta.kt index 49c88cc39..b0c9858e2 100644 --- a/src/net/torvald/terrarum/serialise/WriteMeta.kt +++ b/src/net/torvald/terrarum/serialise/WriteMeta.kt @@ -21,7 +21,6 @@ object WriteMeta { val meta = WorldMeta( genver = Common.GENVER, savename = world.worldName, - terrseed = world.generatorSeed, randseed0 = RoguelikeRandomiser.RNG.state0, randseed1 = RoguelikeRandomiser.RNG.state1, weatseed0 = WeatherMixer.RNG.state0, @@ -46,7 +45,6 @@ object WriteMeta { data class WorldMeta( val genver: Int = -1, val savename: String = "", - val terrseed: Long = 0, val randseed0: Long = 0, val randseed1: Long = 0, val weatseed0: Long = 0, diff --git a/src/net/torvald/terrarum/serialise/WriteSavegame.kt b/src/net/torvald/terrarum/serialise/WriteSavegame.kt index fc6bd9fb6..e7e2a9ada 100644 --- a/src/net/torvald/terrarum/serialise/WriteSavegame.kt +++ b/src/net/torvald/terrarum/serialise/WriteSavegame.kt @@ -5,6 +5,7 @@ import net.torvald.gdx.graphics.PixmapIO2 import net.torvald.terrarum.* import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.console.Echo +import net.torvald.terrarum.gameworld.BlockLayer import net.torvald.terrarum.modulebasegame.IngameRenderer import net.torvald.terrarum.modulebasegame.TerrarumIngame import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer @@ -97,11 +98,11 @@ object WriteSavegame { // Write World // val worldNum = ingame.world.worldIndex - /*val worldContent = EntryFile(WriteWorld.encodeToByteArray64(ingame)) - val world = DiskEntry(worldNum.toLong(), 0, "world${worldNum}".toByteArray(Common.CHARSET), creation_t, time_t, worldContent) - addFile(disk, world)*/ + val worldMeta = EntryFile(WriteWorld.encodeToByteArray64(ingame)) + val world = DiskEntry(worldNum.toLong(), 0, creation_t, time_t, worldMeta) + addFile(disk, world) - val layers = arrayOf(ingame.world.layerTerrain, ingame.world.layerWall) + val layers = intArrayOf(0,1).map { ingame.world.getLayer(it) } val cw = ingame.world.width / LandUtil.CHUNK_W val ch = ingame.world.height / LandUtil.CHUNK_H for (layer in layers.indices) { @@ -119,8 +120,6 @@ object WriteSavegame { } } - // TODO save worldinfo - // Write Actors // listOf(ingame.actorContainerActive, ingame.actorContainerInactive).forEach { actors -> @@ -174,12 +173,31 @@ object LoadSavegame { // val faction = Common.jsoner.fromJson(FactionCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -20))) val apocryphas = Common.jsoner.fromJson(Apocryphas.javaClass, getUnzipInputStream(getFileBytes(disk, -1024))) + // set lateinit vars on the gameworld + world.layerTerrain = BlockLayer(world.width, world.height) + world.layerWall = BlockLayer(world.width, world.height) + val worldParam = TerrarumIngame.Codices(meta, item, apocryphas) newIngame.world = world newIngame.gameLoadInfoPayload = worldParam newIngame.gameLoadMode = TerrarumIngame.GameLoadMode.LOAD_FROM newIngame.savegameArchive = disk + // load all the world blocklayer chunks + val worldnum = world.worldIndex.toLong() + val cw = LandUtil.CHUNK_W; val ch = LandUtil.CHUNK_H + val chunksX = world.width / cw + for (layer in 0L..1L) { + val worldLayer = world.getLayer(layer.toInt()) + + for (chunk in 0L until (world.width * world.height) / (cw * ch)) { + val chunkFile = VDUtil.getAsNormalFile(disk, worldnum.shl(32) or layer.shl(24) or chunk) + val cx = chunk % chunksX + val cy = chunk / chunksX + ReadWorld.decodeChunkToLayer(chunkFile.getContent(), worldLayer, cx.toInt(), cy.toInt()) + } + } + actors.forEach { newIngame.addNewActor(it) } // by doing this, whatever the "possession" the player had will be broken by the game load diff --git a/src/net/torvald/terrarum/serialise/WriteWorld.kt b/src/net/torvald/terrarum/serialise/WriteWorld.kt index e2327fa0a..d3f3519c1 100644 --- a/src/net/torvald/terrarum/serialise/WriteWorld.kt +++ b/src/net/torvald/terrarum/serialise/WriteWorld.kt @@ -7,10 +7,11 @@ import net.torvald.terrarum.gameactors.ActorID import net.torvald.terrarum.gameactors.BlockMarkerActor import net.torvald.terrarum.gameworld.BlockLayer import net.torvald.terrarum.gameworld.GameWorld +import net.torvald.terrarum.gameworld.GameWorldTitleScreen import net.torvald.terrarum.modulebasegame.TerrarumIngame +import net.torvald.terrarum.realestate.LandUtil import net.torvald.terrarum.tvda.ByteArray64 import net.torvald.terrarum.tvda.ByteArray64Writer -import net.torvald.terrarum.realestate.LandUtil import java.io.Reader /** @@ -75,6 +76,9 @@ object WriteWorld { */ object ReadWorld { + fun readLayerFormat(worldDataStream: Reader): GameWorld = + fillInDetails(Common.jsoner.fromJson(GameWorldTitleScreen::class.java, worldDataStream)) + operator fun invoke(worldDataStream: Reader): GameWorld = fillInDetails(Common.jsoner.fromJson(GameWorld::class.java, worldDataStream)) @@ -87,7 +91,7 @@ object ReadWorld { } fun readWorldAndSetNewWorld(ingame: TerrarumIngame, worldDataStream: Reader): GameWorld { - val world = invoke(worldDataStream) + val world = readLayerFormat(worldDataStream) ingame.world = world return world } @@ -95,7 +99,7 @@ object ReadWorld { private val cw = LandUtil.CHUNK_W private val ch = LandUtil.CHUNK_H - fun decodeToLayer(chunk: ByteArray64, targetLayer: BlockLayer, cx: Int, cy: Int) { + fun decodeChunkToLayer(chunk: ByteArray64, targetLayer: BlockLayer, cx: Int, cy: Int) { val bytes = Common.unzip(chunk) if (bytes.size != cw * ch * 2L) throw UnsupportedOperationException("Chunk size mismatch: decoded chunk size is ${bytes.size} bytes " + @@ -105,7 +109,14 @@ object ReadWorld { val tilenum = bytes[2L*k].toUint().shl(8) or bytes[2L*k + 1].toUint() val offx = k % cw val offy = k / cw - targetLayer.unsafeSetTile(cx * cw + offx, cy * ch * offy, tilenum) + +// try { + targetLayer.unsafeSetTile(cx * cw + offx, cy * ch + offy, tilenum) +// } +// catch (e: IndexOutOfBoundsException) { +// printdbgerr(this, "IndexOutOfBoundsException, cx = $cx, cy = $cy, k = $k, offx = $offx, offy = $offy") +// throw e +// } } }