diff --git a/assets/mods/basegame/blocks/blocks.csv b/assets/mods/basegame/blocks/blocks.csv index 295085072..41994ac82 100644 --- a/assets/mods/basegame/blocks/blocks.csv +++ b/assets/mods/basegame/blocks/blocks.csv @@ -3,12 +3,12 @@ "1";"N/A";"N/A";"BLOCK_UPDATE";"0.0312";"0.0312";"0.0312";"0.0312";"1";"1";"AIIR";"0";"1";"N/A";"0";"0";"4";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"INTERNAL,NORANDTILE" # rocks -"16";"17";"17";"BLOCK_STONE";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"ROCK,NATURAL,OREBEARING" -"17";"17";"17";"BLOCK_STONE_QUARRIED";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"ROCK,NATURAL,OREBEARING" +"16";"17";"17";"BLOCK_STONE";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"ROCK,NATURAL,OREBEARING,SHALLOWROCK" +"17";"17";"17";"BLOCK_STONE_QUARRIED";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"ROCK,NATURAL,OREBEARING,SHALLOWROCK" "18";"18";"18";"BLOCK_STONE_TILE_WHITE";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.18";"STONE,NORANDTILE" "19";"19";"19";"BLOCK_STONE_BRICKS";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"STONE,NORANDTILE" -"20";"20";"20";"BLOCK_STONE_DEEP";"0.1252";"0.1252";"0.1252";"0.1252";"80";"24600";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"ROCK,NATURA,OREBEARING" -"21";"21";"21";"BLOCK_STONE_MARBLE";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.1";"ROCK,NATURAL" +"20";"20";"20";"BLOCK_STONE_DEEP";"0.1252";"0.1252";"0.1252";"0.1252";"80";"24600";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"ROCK,NATURA,OREBEARING,DEEPROCK" +"21";"21";"21";"BLOCK_STONE_MARBLE";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.1";"ROCK,NATURAL,DEEPROCK" # dirts "32";"32";"32";"BLOCK_DIRT";"0.1252";"0.1252";"0.1252";"0.1252";"24";"1400";"DIRT";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"DIRT,NATURAL,CULTIVABLE" diff --git a/assets/mods/basegame/commands.csv b/assets/mods/basegame/commands.csv index 228ccc2c3..d3692f183 100644 --- a/assets/mods/basegame/commands.csv +++ b/assets/mods/basegame/commands.csv @@ -19,7 +19,6 @@ MoneyDisp MusicTest Possess PrintWorld -Save Seed SetAV SetBulletin @@ -29,7 +28,6 @@ SetTurb SetTime SetTimeDelta SpawnPhysTestBall -StreamerMode Teleport ToggleNoClip Zoom diff --git a/assets/mods/basegame/items/itemid.csv b/assets/mods/basegame/items/itemid.csv index 7704d21cb..954adc91f 100644 --- a/assets/mods/basegame/items/itemid.csv +++ b/assets/mods/basegame/items/itemid.csv @@ -56,6 +56,7 @@ id;classname;tags 144;net.torvald.terrarum.modulebasegame.gameitems.GemQuartz;SMELTABLE,SIO2 145;net.torvald.terrarum.modulebasegame.gameitems.GemAmethyst;SMELTABLE,SIO2 146;net.torvald.terrarum.modulebasegame.gameitems.ItemRockSalt; +147;net.torvald.terrarum.modulebasegame.gameitems.ItemNitre; # tree seeds by tree species 160;net.torvald.terrarum.modulebasegame.gameitems.ItemSeedOak;SEEDLING diff --git a/assets/mods/basegame/items/items.tga b/assets/mods/basegame/items/items.tga index 5d8247f84..6803212d4 100644 --- a/assets/mods/basegame/items/items.tga +++ b/assets/mods/basegame/items/items.tga @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:31be701c2aabd51ac0e2b9b2f95d75086f5f2a86e02e61aea5477a5d415eab68 +oid sha256:2a30fb3bba561a397f32eac7530ccbc718592fefdb3267a9b6b700f2e4aed9b6 size 2408466 diff --git a/assets/mods/basegame/ores/256.tga b/assets/mods/basegame/ores/256.tga index 0f7b18f0c..b93c33122 100644 --- a/assets/mods/basegame/ores/256.tga +++ b/assets/mods/basegame/ores/256.tga @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:35c9fcf7627753c7f2659df232a8f77acaacde649bb740ec8c1cd696c5031103 +oid sha256:0e6c315bc8b73ab539c1ad441bb61c1b2d4194f220803c5bb1218546729537b9 size 131090 diff --git a/assets/mods/basegame/ores/257.tga b/assets/mods/basegame/ores/257.tga index 40d18124e..f8fb55fe7 100644 --- a/assets/mods/basegame/ores/257.tga +++ b/assets/mods/basegame/ores/257.tga @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b5a01528f361424764bbc3e0c6903fa2105ee002e00a5edbf28015c087711c67 +oid sha256:3c212972db59fc9cee4f4e39a6ce1f5a2d3f1eb51e4c7bdc1c4950c139ff60f1 size 131090 diff --git a/assets/mods/basegame/ores/258.tga b/assets/mods/basegame/ores/258.tga index 0e926e53d..21044e0cb 100644 --- a/assets/mods/basegame/ores/258.tga +++ b/assets/mods/basegame/ores/258.tga @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ebf26fd8dc1f9d31cee8521d5c1107b39ea93a64403b0e6dea908a43140c1063 +oid sha256:da0d273cd5fb2d47eeefd3349e2f29eded4c5f0ce59ae4579e9ef31bab1663d0 size 131090 diff --git a/assets/mods/basegame/ores/259.tga b/assets/mods/basegame/ores/259.tga new file mode 100644 index 000000000..3433502cd --- /dev/null +++ b/assets/mods/basegame/ores/259.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0bd266b0af3b4b794f796dd2ff113c8a564da5ffa553210dab84223c4b8353a3 +size 131090 diff --git a/assets/mods/basegame/ores/ores.csv b/assets/mods/basegame/ores/ores.csv index 0f95de0db..fc65cb505 100644 --- a/assets/mods/basegame/ores/ores.csv +++ b/assets/mods/basegame/ores/ores.csv @@ -1,22 +1,24 @@ "id";"item";"tags" - "1";"item@basegame:128";"COPPER,MALACHITE" - "2";"item@basegame:129";"IRON,HAEMATITE" - "3";"item@basegame:130";"COAL,CARBON" - "4";"item@basegame:131";"ZINC,SPHALERITE" - "5";"item@basegame:132";"TIN,CASSITERITE" - "6";"item@basegame:133";"GOLD,NATURAL_GOLD" - "7";"item@basegame:134";"SILVER,NATURAL_SILVER" - "8";"item@basegame:135";"LEAD,GALENA" +"1";"item@basegame:128";"COPPER,MALACHITE" +"2";"item@basegame:129";"IRON,HAEMATITE" +"3";"item@basegame:130";"COAL,CARBON" +"4";"item@basegame:131";"ZINC,SPHALERITE" +"5";"item@basegame:132";"TIN,CASSITERITE" +"6";"item@basegame:133";"GOLD,NATURAL_GOLD" +"7";"item@basegame:134";"SILVER,NATURAL_SILVER" +"8";"item@basegame:135";"LEAD,GALENA" #"9";"item@basegame:143";"TITANIUM,RUTILE" "256";"item@basegame:146";"SALT" "257";"item@basegame:145";"GEM,SIO2,AMETHYST" "258";"item@basegame:144";"GEM,SIO2,QUARTZ" -#"259";"item@basegame:136";"GEM,RUBY" -#"260";"item@basegame:137";"GEM,EMERALD" -#"261";"item@basegame:138";"GEM,SAPPHIRE" -#"262";"item@basegame:139";"GEM,TOPAZ" -#"263";"item@basegame:140";"GEM,DIAMOND" +"259";"item@basegame:147";"GEM,NITRE" + +#"260";"item@basegame:136";"GEM,RUBY" +#"261";"item@basegame:137";"GEM,EMERALD" +#"262";"item@basegame:138";"GEM,SAPPHIRE" +#"263";"item@basegame:139";"GEM,TOPAZ" +#"264";"item@basegame:140";"GEM,DIAMOND" #"512";"macro@BASETILE";"GRASS" #"513";"macro@BASETILE";"MOSS" \ No newline at end of file diff --git a/assets/mods/basegame/ores/worldgen.csv b/assets/mods/basegame/ores/worldgen.csv index 96dbb490b..6c9d09cdc 100644 --- a/assets/mods/basegame/ores/worldgen.csv +++ b/assets/mods/basegame/ores/worldgen.csv @@ -1,16 +1,17 @@ -"id";"freq";"power";"scale";"ratio";"tiling";"comment" -"1";"0.026";"0.010";"0.517";"1.0";"a16x16";"copper (malachite)" -"2";"0.045";"0.011";"0.517";"1.0";"a16x16";"iron (haematite)" -"3";"0.017";"0.070";"0.511";"3.8";"a16x4";"coal" -"4";"0.019";"0.011";"0.511";"1.0";"a16x16";"zinc (sphalerite)" -"5";"0.017";"0.017";"0.511";"1.0";"a16x16";"tin (cassiterite)" -"6";"0.009";"0.300";"0.474";"1.0";"a16x16";"natural gold" -"7";"0.013";"0.300";"0.476";"1.0";"a16x16";"natural silver" -"8";"0.017";"0.020";"0.511";"1.0";"a16x16";"lead (galena)" +"id";"freq";"power";"scale";"ratio";"tiling";"comment";"blocktagnongrata" +"1";"0.026";"0.010";"0.517";"1.0";"a16x16";"copper (malachite)";"" +"2";"0.045";"0.011";"0.517";"1.0";"a16x16";"iron (haematite)";"" +"3";"0.017";"0.070";"0.511";"3.8";"a16x4";"coal";"" +"4";"0.019";"0.011";"0.511";"1.0";"a16x16";"zinc (sphalerite)";"" +"5";"0.017";"0.017";"0.511";"1.0";"a16x16";"tin (cassiterite)";"" +"6";"0.009";"0.300";"0.474";"1.0";"a16x16";"natural gold";"" +"7";"0.013";"0.300";"0.476";"1.0";"a16x16";"natural silver";"" +"8";"0.017";"0.020";"0.511";"1.0";"a16x16";"lead (galena)";"" -"256";"0.010";"-0.366";"0.528";"2.4";"a16x8";"rocksalt" -"257";"0.007";"0.100";"0.494";"1.0";"a16x8";"amethyst" -"258";"0.019";"0.015";"0.509";"1.0";"a16x8";"quartz" +"256";"0.010";"-0.366";"0.528";"2.4";"a16x8";"rocksalt";"DEEPROCK" +"257";"0.007";"0.100";"0.494";"1.0";"a16x8";"amethyst";"" +"258";"0.019";"0.015";"0.509";"1.0";"a16x8";"quartz";"" +"259";"0.010";"-0.166";"0.517";"1.4";"a16x8";"nitre";"DEEPROCK" ################################################################################ @@ -31,4 +32,5 @@ # - r16: use the hash of the tile position as a variant selection, module 16 # - r8: use the hash of the tile position as a variant selection, module 8 # -# comment: human-readable comments, not actually parsed \ No newline at end of file +# comment: human-readable comments, not actually used +# blocktagnongrata: blocks with matching tag will not bear the ore. leave empty "" to allow all \ No newline at end of file diff --git a/src/net/torvald/terrarum/ModMgr.kt b/src/net/torvald/terrarum/ModMgr.kt index b09c6c7b7..10015e80c 100644 --- a/src/net/torvald/terrarum/ModMgr.kt +++ b/src/net/torvald/terrarum/ModMgr.kt @@ -623,8 +623,9 @@ object ModMgr { val scale = rec.get("scale").toDouble() val ratio = rec.get("ratio").toDouble() val tiling = rec.get("tiling") + val blockTagNonGrata = rec.get("blocktagnongrata").split(',').map { it.trim().toUpperCase() }.toHashSet() - Worldgen.registerOre(OregenParams(tile, freq, power, scale, ratio, tiling)) + Worldgen.registerOre(OregenParams(tile, freq, power, scale, ratio, tiling, blockTagNonGrata)) } } catch (e: IOException) { diff --git a/src/net/torvald/terrarum/console/CommandInterpreter.kt b/src/net/torvald/terrarum/console/CommandInterpreter.kt index 5759cc119..1236d168a 100644 --- a/src/net/torvald/terrarum/console/CommandInterpreter.kt +++ b/src/net/torvald/terrarum/console/CommandInterpreter.kt @@ -15,19 +15,20 @@ import java.util.regex.Pattern internal object CommandInterpreter { private val commandsNoAuth = arrayOf( - "auth", - "qqq", - "setlocale", - "getlocale", - "help", - "version", - "tips", - "screenshot", - "resize", - "echo", - "error", - "seed", - "quicksave" + "auth", + "qqq", + "setlocale", + "getlocale", + "help", + "version", + "tips", + "screenshot", + "resize", + "echo", + "error", + "seed", + "quicksave", + "uuid" ) internal fun execute(command: String) { diff --git a/src/net/torvald/terrarum/debuggerapp/SavegameCracker.kt b/src/net/torvald/terrarum/debuggerapp/SavegameCracker.kt index 5af45c8a6..ea1e403a5 100644 --- a/src/net/torvald/terrarum/debuggerapp/SavegameCracker.kt +++ b/src/net/torvald/terrarum/debuggerapp/SavegameCracker.kt @@ -293,6 +293,31 @@ class SavegameCracker( if (worldIndex.isNotBlank()) println("${ccNoun}World UUID: $ccNoun2$worldIndex") } } + + @Command("Removes the specified chunk(s) completely", "IDs") + fun discardchunk(args: List) { + letdisk { disk -> + val ids = args[1] + val range = if (ids.matches(Regex("""[0-9]+-[0-9]+"""))) + ids.substringBefore('-').toLong()..ids.substringAfter('-').toLong() + else + ids.toLong()..ids.toLong() + + var rms = 0 + + range.forEach { + // TODO update according to the savegame format + val fileIDs = (0..15).map { layer -> 4294967296L + layer.shl(24) or it } + fileIDs.forEach { + if (disk.entries.containsKey(it)) rms += 1 + disk.entries.remove(it) + VDUtil.getAsDirectory(disk, 0).remove(it) + } + } + + println("${cc0}$rms entries removed") + } + } } internal annotation class Command(val help: String = "", val synopsis: String = "") diff --git a/src/net/torvald/terrarum/gameworld/BlockLayer.kt b/src/net/torvald/terrarum/gameworld/BlockLayer.kt index e044d9710..91edf45f6 100644 --- a/src/net/torvald/terrarum/gameworld/BlockLayer.kt +++ b/src/net/torvald/terrarum/gameworld/BlockLayer.kt @@ -7,9 +7,15 @@ import com.badlogic.gdx.utils.Disposable */ interface BlockLayer : Disposable { + val width: Int + val height: Int val bytesPerBlock: Long fun unsafeToBytes(x: Int, y: Int): ByteArray fun unsafeSetTile(x: Int, y: Int, bytes: ByteArray) fun unsafeGetTile(x: Int, y: Int): Int +} + +inline fun BlockLayer.getOffset(x: Int, y: Int): Long { + return this.bytesPerBlock * (y * this.width + x) } \ No newline at end of file diff --git a/src/net/torvald/terrarum/gameworld/BlockLayerI16.kt b/src/net/torvald/terrarum/gameworld/BlockLayerI16.kt index 5fa644dee..48ce37817 100644 --- a/src/net/torvald/terrarum/gameworld/BlockLayerI16.kt +++ b/src/net/torvald/terrarum/gameworld/BlockLayerI16.kt @@ -18,13 +18,13 @@ import net.torvald.unsafe.UnsafePtr * * Note to self: refrain from using shorts--just do away with two bytes: different system have different endianness */ -open class BlockLayerI16(val width: Int, val height: Int) : BlockLayer { +open class BlockLayerI16(override val width: Int, override val height: Int) : BlockLayer { override val bytesPerBlock = BYTES_PER_BLOCK // for some reason, all the efforts of saving the memory space were futile. // using unsafe pointer gets you 100 fps, whereas using directbytebuffer gets you 90 - internal val ptr: UnsafePtr = UnsafeHelper.allocate(width * height * BYTES_PER_BLOCK) + internal val ptr: UnsafePtr = UnsafeHelper.allocate(width * height * bytesPerBlock) val ptrDestroyed: Boolean get() = ptr.destroyed @@ -50,7 +50,7 @@ open class BlockLayerI16(val width: Int, val height: Int) : BlockLayer { return object : Iterator { private var iteratorCount = 0L override fun hasNext(): Boolean { - return iteratorCount < width * height * BYTES_PER_BLOCK + return iteratorCount < width * height * bytesPerBlock } override fun next(): Byte { iteratorCount += 1 @@ -60,7 +60,7 @@ open class BlockLayerI16(val width: Int, val height: Int) : BlockLayer { } override fun unsafeGetTile(x: Int, y: Int): Int { - val offset = BYTES_PER_BLOCK * (y * width + x) + val offset = getOffset(x, y) val lsb = ptr[offset] val msb = ptr[offset + 1] @@ -68,12 +68,12 @@ open class BlockLayerI16(val width: Int, val height: Int) : BlockLayer { } override fun unsafeToBytes(x: Int, y: Int): ByteArray { - val offset = BYTES_PER_BLOCK * (y * width + x) + val offset = getOffset(x, y) return byteArrayOf(ptr[offset + 1], ptr[offset + 0]) } internal fun unsafeSetTile(x: Int, y: Int, tile: Int) { - val offset = BYTES_PER_BLOCK * (y * width + x) + val offset = getOffset(x, y) val lsb = tile.and(0xff).toByte() val msb = tile.ushr(8).and(0xff).toByte() @@ -90,7 +90,7 @@ open class BlockLayerI16(val width: Int, val height: Int) : BlockLayer { } override fun unsafeSetTile(x: Int, y: Int, bytes: ByteArray) { - val offset = BYTES_PER_BLOCK * (y * width + x) + val offset = getOffset(x, y) ptr[offset] = bytes[1] ptr[offset + 1] = bytes[0] } diff --git a/src/net/torvald/terrarum/gameworld/BlockLayerI16F16.kt b/src/net/torvald/terrarum/gameworld/BlockLayerI16F16.kt index 75722209b..37bc2e036 100644 --- a/src/net/torvald/terrarum/gameworld/BlockLayerI16F16.kt +++ b/src/net/torvald/terrarum/gameworld/BlockLayerI16F16.kt @@ -16,13 +16,13 @@ import net.torvald.util.Float16 * * Created by minjaesong on 2023-10-10. */ -class BlockLayerI16F16(val width: Int, val height: Int) : BlockLayer { +class BlockLayerI16F16(override val width: Int, override val height: Int) : BlockLayer { override val bytesPerBlock = BYTES_PER_BLOCK // for some reason, all the efforts of saving the memory space were futile. // using unsafe pointer gets you 100 fps, whereas using directbytebuffer gets you 90 - internal val ptr: UnsafePtr = UnsafeHelper.allocate(width * height * BYTES_PER_BLOCK) + internal val ptr: UnsafePtr = UnsafeHelper.allocate(width * height * bytesPerBlock) val ptrDestroyed: Boolean get() = ptr.destroyed @@ -48,7 +48,7 @@ class BlockLayerI16F16(val width: Int, val height: Int) : BlockLayer { return object : Iterator { private var iteratorCount = 0L override fun hasNext(): Boolean { - return iteratorCount < width * height * BYTES_PER_BLOCK + return iteratorCount < width * height * bytesPerBlock } override fun next(): Byte { iteratorCount += 1 @@ -58,7 +58,7 @@ class BlockLayerI16F16(val width: Int, val height: Int) : BlockLayer { } override fun unsafeGetTile(x: Int, y: Int): Int { - val offset = BYTES_PER_BLOCK * (y * width + x) + val offset = getOffset(x, y) val lsb = ptr[offset] val msb = ptr[offset + 1] val hbits = (ptr[offset + 2].toUint() or ptr[offset + 3].toUint().shl(8)).toShort() @@ -68,7 +68,7 @@ class BlockLayerI16F16(val width: Int, val height: Int) : BlockLayer { } internal fun unsafeGetTile1(x: Int, y: Int): Pair { - val offset = BYTES_PER_BLOCK * (y * width + x) + val offset = getOffset(x, y) val lsb = ptr[offset] val msb = ptr[offset + 1] val hbits = (ptr[offset + 2].toUint() or ptr[offset + 3].toUint().shl(8)).toShort() @@ -78,12 +78,12 @@ class BlockLayerI16F16(val width: Int, val height: Int) : BlockLayer { } override fun unsafeToBytes(x: Int, y: Int): ByteArray { - val offset = BYTES_PER_BLOCK * (y * width + x) + val offset = getOffset(x, y) return byteArrayOf(ptr[offset + 1], ptr[offset + 0], ptr[offset + 3], ptr[offset + 2]) } internal fun unsafeSetTile(x: Int, y: Int, tile0: Int, fill: Float) { - val offset = BYTES_PER_BLOCK * (y * width + x) + val offset = getOffset(x, y) val hbits = Float16.fromFloat(fill).toInt().and(0xFFFF) val tile = if (fill < FLUID_MIN_MASS) 0 else tile0 @@ -102,7 +102,7 @@ class BlockLayerI16F16(val width: Int, val height: Int) : BlockLayer { } override fun unsafeSetTile(x: Int, y: Int, bytes: ByteArray) { - val offset = BYTES_PER_BLOCK * (y * width + x) + val offset = getOffset(x, y) ptr[offset] = bytes[1] ptr[offset + 1] = bytes[0] ptr[offset + 2] = bytes[3] diff --git a/src/net/torvald/terrarum/gameworld/BlockLayerI16I8.kt b/src/net/torvald/terrarum/gameworld/BlockLayerI16I8.kt index c8271f17b..cccac305f 100644 --- a/src/net/torvald/terrarum/gameworld/BlockLayerI16I8.kt +++ b/src/net/torvald/terrarum/gameworld/BlockLayerI16I8.kt @@ -13,13 +13,13 @@ import net.torvald.unsafe.UnsafePtr * where a_n is a tile number, p_n is a placement index * Created by minjaesong on 2023-10-10. */ -class BlockLayerI16I8 (val width: Int, val height: Int) : BlockLayer { +class BlockLayerI16I8 (override val width: Int, override val height: Int) : BlockLayer { override val bytesPerBlock = BYTES_PER_BLOCK // for some reason, all the efforts of saving the memory space were futile. // using unsafe pointer gets you 100 fps, whereas using directbytebuffer gets you 90 - internal val ptr: UnsafePtr = UnsafeHelper.allocate(width * height * BYTES_PER_BLOCK) + internal val ptr: UnsafePtr = UnsafeHelper.allocate(width * height * bytesPerBlock) val ptrDestroyed: Boolean get() = ptr.destroyed @@ -45,7 +45,7 @@ class BlockLayerI16I8 (val width: Int, val height: Int) : BlockLayer { return object : Iterator { private var iteratorCount = 0L override fun hasNext(): Boolean { - return iteratorCount < width * height * BYTES_PER_BLOCK + return iteratorCount < width * height * bytesPerBlock } override fun next(): Byte { iteratorCount += 1 @@ -55,7 +55,7 @@ class BlockLayerI16I8 (val width: Int, val height: Int) : BlockLayer { } override fun unsafeGetTile(x: Int, y: Int): Int { - val offset = BYTES_PER_BLOCK * (y * width + x) + val offset = getOffset(x, y) val lsb = ptr[offset] val msb = ptr[offset + 1] val placement = ptr[offset + 2] @@ -64,7 +64,7 @@ class BlockLayerI16I8 (val width: Int, val height: Int) : BlockLayer { } internal fun unsafeGetTile1(x: Int, y: Int): Pair { - val offset = BYTES_PER_BLOCK * (y * width + x) + val offset = getOffset(x, y) val lsb = ptr[offset] val msb = ptr[offset + 1] val placement = ptr[offset + 2] @@ -73,12 +73,12 @@ class BlockLayerI16I8 (val width: Int, val height: Int) : BlockLayer { } override fun unsafeToBytes(x: Int, y: Int): ByteArray { - val offset = BYTES_PER_BLOCK * (y * width + x) + val offset = getOffset(x, y) return byteArrayOf(ptr[offset + 1], ptr[offset + 0], ptr[offset + 2]) } internal fun unsafeSetTile(x: Int, y: Int, tile: Int, placement: Int) { - val offset = BYTES_PER_BLOCK * (y * width + x) + val offset = getOffset(x, y) val lsb = tile.and(0xff).toByte() val msb = tile.ushr(8).and(0xff).toByte() @@ -96,14 +96,14 @@ class BlockLayerI16I8 (val width: Int, val height: Int) : BlockLayer { } override fun unsafeSetTile(x: Int, y: Int, bytes: ByteArray) { - val offset = BYTES_PER_BLOCK * (y * width + x) + val offset = getOffset(x, y) ptr[offset] = bytes[1] ptr[offset + 1] = bytes[0] ptr[offset + 2] = bytes[2] } internal fun unsafeSetTileKeepPlacement(x: Int, y: Int, tile: Int) { - val offset = BYTES_PER_BLOCK * (y * width + x) + val offset = getOffset(x, y) val lsb = tile.and(0xff).toByte() val msb = tile.ushr(8).and(0xff).toByte() diff --git a/src/net/torvald/terrarum/modulebasegame/ExplosionManager.kt b/src/net/torvald/terrarum/modulebasegame/ExplosionManager.kt new file mode 100644 index 000000000..4afd15257 --- /dev/null +++ b/src/net/torvald/terrarum/modulebasegame/ExplosionManager.kt @@ -0,0 +1,80 @@ +package net.torvald.terrarum.modulebasegame + +import net.torvald.terrarum.gameworld.BlockLayerI16 +import net.torvald.terrarum.gameworld.GameWorld +import net.torvald.terrarum.gameworld.getOffset +import net.torvald.terrarum.tryDispose +import net.torvald.unsafe.UnsafeHelper + +/** + * Created by minjaesong on 2024-02-13. + */ +object ExplosionManager { + + private const val CALC_RADIUS = 127 + private const val CALC_WIDTH = CALC_RADIUS * 2 + 1 + + fun goBoom(world: GameWorld, tx: Int, ty: Int, power: Float) { + // create a copy of the tilemap + val tilemap = BlockLayerI16(CALC_WIDTH, CALC_WIDTH) + + // fill in the tilemap copy + for (line in 0 until CALC_WIDTH) { + memcpyFromWorld(world, tx - CALC_RADIUS, ty - CALC_RADIUS, line, tilemap) + } + + createExplosionWorker(tilemap, tx, ty, power, world).start() + } + + private fun memcpyFromWorld(world: GameWorld, xStart: Int, yStart: Int, yOff: Int, out: BlockLayerI16) { + // if the bounding box must wrap around + if (xStart > world.width - CALC_RADIUS) { + val lenLeft = world.width - xStart + val lenRight = CALC_WIDTH - lenLeft + + UnsafeHelper.memcpy( + world.layerTerrain.ptr, + world.layerTerrain.getOffset(xStart, yStart + yOff), + out.ptr, + out.getOffset(0, yOff), + world.layerTerrain.bytesPerBlock * lenLeft + ) + UnsafeHelper.memcpy( + world.layerTerrain.ptr, + world.layerTerrain.getOffset(0, yStart + yOff), + out.ptr, + out.getOffset(lenLeft, yOff), + world.layerTerrain.bytesPerBlock * lenRight + ) + } + else { + UnsafeHelper.memcpy( + world.layerTerrain.ptr, + world.layerTerrain.getOffset(xStart, yStart + yOff), + out.ptr, + out.getOffset(0, yOff), + world.layerTerrain.bytesPerBlock * CALC_WIDTH + ) + } + } + + /** + * @param tilemap a portion copy of the tilemap from the world, centred to the explosive + * @param tx tilewise centre-x of the explosive + * @param ty tilewise centre-y of the explosive + * @param outWorld world object to write the result to + */ + private fun createExplosionWorker(tilemap: BlockLayerI16, tx: Int, ty: Int, power: Float, outWorld: GameWorld): Thread { + return Thread { + // simulate explosion like lightmaprenderer + + + // write to the world + + + // dispose of the tilemap copy + tilemap.tryDispose() + } + } + +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index e24cdae00..e87d1a704 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -1116,7 +1116,8 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) { 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() + if (cy !in 0 until world.height / CHUNK_H) false + else (world.chunkFlags[cy][cx].and(0x7F) == 0.toByte()) }.forEach { (cx, cy) -> Worldgen.generateChunkIngame(cx, cy) { cx, cy -> listOf(0,1,2).forEach { layer -> diff --git a/src/net/torvald/terrarum/modulebasegame/console/ExportMap.kt b/src/net/torvald/terrarum/modulebasegame/console/ExportMap.kt index a82520854..85832ac7c 100644 --- a/src/net/torvald/terrarum/modulebasegame/console/ExportMap.kt +++ b/src/net/torvald/terrarum/modulebasegame/console/ExportMap.kt @@ -37,6 +37,7 @@ internal object ExportMap : ConsoleCommand { "ores@basegame:256" to Cvec(0xff00ffff.toInt()), "ores@basegame:257" to Cvec(0xee77ffff.toInt()), "ores@basegame:258" to Cvec(0xffffffff.toInt()), + "ores@basegame:259" to Cvec(0xdbd6a1ff.toInt()), ) private val WALL_OVERLAY = Cvec(0.35f, 0.35f, 0.35f, 1f) diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/ActorPrimedBomb.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorPrimedBomb.kt new file mode 100644 index 000000000..2368359c0 --- /dev/null +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorPrimedBomb.kt @@ -0,0 +1,44 @@ +package net.torvald.terrarum.modulebasegame.gameactors + +import net.torvald.terrarum.INGAME +import net.torvald.terrarum.Second +import net.torvald.terrarum.gameactors.ActorWithBody +import net.torvald.terrarum.modulebasegame.ExplosionManager +import org.dyn4j.geometry.Vector2 + +/** + * Created by minjaesong on 2024-02-13. + */ +open class ActorPrimedBomb : ActorWithBody { + + protected constructor() { + renderOrder = RenderOrder.MIDTOP + } + + private var explosionPower: Float = 1f + private var fuse: Second = 1f + + constructor( + initialPos: Vector2, + initialVelo: Vector2, + power: Float, + fuse: Second + ) { + renderOrder = RenderOrder.MIDTOP + + this.explosionPower = power + this.fuse = fuse + } + + override fun updateImpl(delta: Float) { + super.updateImpl(delta) + + fuse -= delta + + if (fuse <= 0f) { + physProp.usePhysics = false + ExplosionManager.goBoom(INGAME.world, intTilewiseHitbox.centeredX.toInt(), intTilewiseHitbox.centeredY.toInt(), explosionPower) + flagDespawn() + } + } +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/gameitems/OreItemBase.kt b/src/net/torvald/terrarum/modulebasegame/gameitems/OreItemBase.kt index 15b059461..5aa56e988 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameitems/OreItemBase.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameitems/OreItemBase.kt @@ -169,6 +169,11 @@ class ItemRockSalt(originalID: ItemID) : OreItemBase(originalID, true) { override val itemImage: TextureRegion get() = CommonResourcePool.getAsItemSheet("basegame.items").get(10,6) } +class ItemNitre(originalID: ItemID) : OreItemBase(originalID, true) { + override var originalName = "ITEM_NITRE" + override val itemImage: TextureRegion + get() = CommonResourcePool.getAsItemSheet("basegame.items").get(15,6) +} class ItemCoalCoke(originalID: ItemID) : OreItemBase(originalID) { diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryCells.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryCells.kt index 157af1621..e21009021 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryCells.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryCells.kt @@ -70,7 +70,12 @@ internal class UIInventoryCells( // tooltip if (Terrarum.mouseScreenX.toFloat() in encumbBarXPos..encumbBarXPos+UIInventoryCells.weightBarWidth && Terrarum.mouseScreenY.toFloat() in encumbBarYPos..encumbBarYPos+UIInventoryFull.controlHelpHeight - 6f) { - INGAME.setTooltipMessage("${actorInventory.capacity}/${actorInventory.maxCapacity}") + val capaStr = if (actorInventory.capacity >= 1125899906842624.0) /* 2^50 */ + "${actorInventory.capacity}" + else + "${(actorInventory.capacity * 100L).toLong() / 100.0}" + + INGAME.setTooltipMessage("$capaStr/${actorInventory.maxCapacity}.0") tooltipShowing[10001] = true } else { diff --git a/src/net/torvald/terrarum/modulebasegame/worldgenerator/Oregen.kt b/src/net/torvald/terrarum/modulebasegame/worldgenerator/Oregen.kt index 584739ed6..642af9ad8 100644 --- a/src/net/torvald/terrarum/modulebasegame/worldgenerator/Oregen.kt +++ b/src/net/torvald/terrarum/modulebasegame/worldgenerator/Oregen.kt @@ -58,7 +58,10 @@ class Oregen(world: GameWorld, isFinal: Boolean, private val caveAttenuateBiasSc 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")) { + val blockTagNonGrata = ores.firstOrNull { it.tile == tileToPut }?.blockTagNonGrata ?: hashSetOf() + val backingTileProp = BlockCodex[backingTile] + + if (tileToPut != null && backingTileProp.hasAllTagOf("ROCK", "OREBEARING") && backingTileProp.hasNoTag(blockTagNonGrata)) { // actually put the ore block world.setTileOre(x, y, tileToPut, 0) // autotiling will be handled by the other worldgen process } @@ -153,4 +156,5 @@ data class OregenParams( val scale: Double, // also adjust this if you've touched the bias value. Number can be greater than 1.0 val ratio: Double, // how stretched the ore veins are. >1.0 = stretched horizontally, <1.0 = stretched vertically val tiling: String, // a16, a47, r16, r8 + val blockTagNonGrata: HashSet, ) \ No newline at end of file diff --git a/src/net/torvald/terrarum/tests/WorldgenNoiseSandbox.kt b/src/net/torvald/terrarum/tests/WorldgenNoiseSandbox.kt index 409d36e11..7704a113c 100644 --- a/src/net/torvald/terrarum/tests/WorldgenNoiseSandbox.kt +++ b/src/net/torvald/terrarum/tests/WorldgenNoiseSandbox.kt @@ -343,9 +343,10 @@ internal object TerragenTest : NoiseMaker { private val QUARTZ = 0//x55ff33ff.toInt() private val AMETHYST = 0//xee77ffff.toInt() private val ROCKSALT = 0xff00ffff.toInt() + private val NITRE = 0xdbd6a1ff.toInt() private val oreCols = listOf( - COPPER_ORE, IRON_ORE, COAL_ORE, ZINC_ORE, TIN_ORE, GOLD_ORE, SILVER_ORE, LEAD_ORE, ROCKSALT, QUARTZ, AMETHYST + COPPER_ORE, IRON_ORE, COAL_ORE, ZINC_ORE, TIN_ORE, GOLD_ORE, SILVER_ORE, LEAD_ORE, ROCKSALT, QUARTZ, AMETHYST, NITRE ) private val terragenYscaling = (NOISEBOX_HEIGHT / 2400.0).pow(0.75) @@ -693,6 +694,7 @@ internal object TerragenTest : NoiseMaker { Joise(generateOreVeinModule(caveAttenuateBiasScaledCache, seed shake "ores@basegame:256", 0.010, -0.366, 0.528, 2.4)), Joise(generateOreVeinModule(caveAttenuateBiasScaledCache, seed shake "ores@basegame:257", 0.007, 0.100, 0.494, 1.0)), Joise(generateOreVeinModule(caveAttenuateBiasScaledCache, seed shake "ores@basegame:258", 0.019, 0.015, 0.509, 1.0)), + Joise(generateOreVeinModule(caveAttenuateBiasScaledCache, seed shake "ores@basegame:259", 0.010, -0.166, 0.517, 1.4)), Joise(generateRockLayer(groundScalingCached, seed, params, (0..7).map { thicknesses[it] + marblerng.nextTriangularBal() * 0.006 to (2.6 * terragenYscaling) + it * 0.18 + marblerng.nextTriangularBal() * 0.09 diff --git a/work_files/graphics/items/basegame_items.kra b/work_files/graphics/items/basegame_items.kra index baaae9ef9..beaaaea16 100644 --- a/work_files/graphics/items/basegame_items.kra +++ b/work_files/graphics/items/basegame_items.kra @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5590cdabbe723d3769d966d6172b2811b55cfc86c4ec89b6c39f2204ecdbfb5a -size 1168632 +oid sha256:93815d16aa8e4c7a22347ac387cdf974d0a897a136e40da744e12accdf6f0061 +size 1207457 diff --git a/work_files/graphics/terrain/gems.kra b/work_files/graphics/terrain/gems.kra index a8eb28455..8820abe38 100644 --- a/work_files/graphics/terrain/gems.kra +++ b/work_files/graphics/terrain/gems.kra @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:41e6d57f36c5c38c088cc137bfff991fe2835a72fef4f3d8f75cd77384c5bc9f -size 631562 +oid sha256:bd4327909a19eac7ff9a2369fb413080e0097bd332770cb2c019831153a3964f +size 717819