mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-11 02:54:04 +09:00
new gem on worldgen
This commit is contained in:
80
src/net/torvald/terrarum/modulebasegame/ExplosionManager.kt
Normal file
80
src/net/torvald/terrarum/modulebasegame/ExplosionManager.kt
Normal 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()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 ->
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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>,
|
||||
)
|
||||
Reference in New Issue
Block a user