new gem on worldgen

This commit is contained in:
minjaesong
2024-02-13 23:42:43 +09:00
parent 6e1af36a63
commit e5ac560966
27 changed files with 263 additions and 82 deletions

View File

@@ -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()
}
}
}

View File

@@ -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 ->

View File

@@ -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)

View File

@@ -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()
}
}
}

View File

@@ -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) {

View File

@@ -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 {

View File

@@ -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<String>,
)