lone leaves decaying

This commit is contained in:
minjaesong
2024-01-28 20:14:48 +09:00
parent 6e69fb3872
commit d3cd3465c7
6 changed files with 52 additions and 15 deletions

View File

@@ -1038,4 +1038,7 @@ fun <S, T> List<S>.cartesianProduct(other: List<T>) = this.flatMap { thisIt ->
other.map { otherIt ->
thisIt to otherIt
}
}
}
fun Float.ditherToInt() = (this + Math.random() - 0.5).roundToInt()
fun Double.ditherToInt() = (this + Math.random() - 0.5).roundToInt()

View File

@@ -2068,7 +2068,7 @@ open class ActorWithBody : Actor {
private fun makeDust(collisionDamage: Double, vecSum: Vector2) {
val particleCount = (collisionDamage / 24.0).pow(0.75)
val trueParticleCount = particleCount.toInt() + (Math.random() < (particleCount % 1.0)).toInt()
val trueParticleCount = particleCount.ditherToInt()
val feetTiles = getFeetTiles()

View File

@@ -3,6 +3,7 @@ package net.torvald.terrarum.gameworld
import com.badlogic.gdx.utils.Queue
import net.torvald.random.HQRNG
import net.torvald.terrarum.*
import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED
import net.torvald.terrarum.blockproperties.Block
@@ -13,9 +14,13 @@ import net.torvald.terrarum.gameitems.ItemID
import net.torvald.terrarum.modulebasegame.TerrarumIngame
import net.torvald.terrarum.modulebasegame.TerrarumIngame.Companion.inUpdateRange
import net.torvald.terrarum.modulebasegame.gameactors.*
import net.torvald.terrarum.modulebasegame.gameitems.AxeCore
import net.torvald.terrarum.modulebasegame.gameitems.PickaxeCore
import org.dyn4j.geometry.Vector2
import kotlin.math.cosh
import kotlin.math.min
import kotlin.math.roundToInt
import kotlin.math.sqrt
/**
* Created by minjaesong on 2016-08-03.
@@ -94,6 +99,8 @@ object WorldSimulator {
// TODO update logic
}
App.measureDebugTime("WorldSimulator.collisionDroppedItem") { collideDroppedItems() }
App.measureDebugTime("WorldSimulator.dropTreeLeaves") { dropTreeLeaves() }
//printdbg(this, "============================")
}
@@ -112,8 +119,17 @@ object WorldSimulator {
}
}
private fun sech2(x: Float) = 1f / cosh(x).sqr()
fun growOrKillGrass() {
repeat(2 * world.worldTime.timeDelta) { // TODO: season-dependent growth rate
// season-dependent growth rate
// https://www.desmos.com/calculator/ivxyxuj0bm
val baseCount = 2 * world.worldTime.timeDelta
val season = world.worldTime.ecologicalSeason.coerceIn(0f, 5f) // 1->1.0, 2.5->3.0, 4->1.0
val seasonalMult = 1f + sech2((season - 2.5f)) * 2f
val repeatCount = (baseCount * seasonalMult).ditherToInt()
repeat(repeatCount) {
val rx = rng.nextInt(updateXFrom, updateXTo + 1)
val ry = rng.nextInt(updateYFrom, updateYTo + 1)
val tile = world.getTileFromTerrain(rx, ry)
@@ -135,6 +151,23 @@ object WorldSimulator {
}
}
fun dropTreeLeaves() {
repeat(26 * world.worldTime.timeDelta) {
val rx = rng.nextInt(updateXFrom, updateXTo + 1)
val ry = rng.nextInt(updateYFrom, updateYTo + 1)
val tile = world.getTileFromTerrain(rx, ry)
// if the dirt tile has a grass and an air tile nearby, put grass to it
if (BlockCodex[tile].hasAllTagOf("TREE", "LEAVES")) {
val nearby8 = getNearbyTiles8(rx, ry)
val nearbyCount = nearby8.count { BlockCodex[it].hasTag("TREE") }
if (nearbyCount <= 1) {
AxeCore.removeLeaf(rx, ry)
}
}
}
}
fun collideDroppedItems() {
ingame.actorContainerActive.filter { it is DroppedItem }.forEach { droppedItem0 ->
val droppedItem = droppedItem0 as DroppedItem

View File

@@ -125,9 +125,11 @@ open class DroppedItem : ActorWithBody {
}
private fun getLum(itemID: ItemID): Cvec {
return if (itemID.isBlock() || itemID.isWall()) {
BlockCodex[itemID.substringAfter('@')].getLumCol(randKey1, randKey2)
return if (itemID.isBlock()) {
BlockCodex[itemID].getLumCol(randKey1, randKey2)
}
else if (itemID.isWall())
BlockCodex[itemID.substringAfter('@')].getLumCol(randKey1, randKey2)
else {
Cvec(
ItemCodex[itemID]?.itemProperties?.getAsFloat(AVKey.LUMR) ?: 0f,

View File

@@ -82,7 +82,7 @@ object AxeCore {
).let { tileBroken ->
// tile busted
if (tileBroken != null) {
removeLeaf(x, y, tileBroken.substringAfter(':').toInt() - 112)
removeLeaf(x, y)
PickaxeCore.makeDust(tile, x, y, 9)
}
// tile not busted
@@ -110,8 +110,8 @@ object AxeCore {
val tileThereR = INGAME.world.getTileFromTerrain(x+1, y - upCtr)
val propThereL = BlockCodex[tileThereL]
val propThereR = BlockCodex[tileThereR]
val treeTrunkXoff = if (propThereL.hasAllTag(listOf("TREELARGE", "TREETRUNK"))) -1
else if (propThereR.hasAllTag(listOf("TREELARGE", "TREETRUNK"))) 1
val treeTrunkXoff = if (propThereL.hasAllTagOf("TREELARGE", "TREETRUNK")) -1
else if (propThereR.hasAllTagOf("TREELARGE", "TREETRUNK")) 1
else 0
if (treeTrunkXoff != 0) {
@@ -128,7 +128,7 @@ object AxeCore {
val tileHere = INGAME.world.getTileFromTerrain(x, y - upCtr)
val propHere = BlockCodex[tileHere]
if (propHere.hasAllTag(listOf("TREELARGE", "TREETRUNK"))) {
if (propHere.hasAllTagOf("TREELARGE", "TREETRUNK")) {
INGAME.world.setTileTerrain(x, y - upCtr, Block.AIR, false)
PickaxeCore.dropItem(propHere.drop, x, y - upCtr)
PickaxeCore.makeDust(tile, x, y - upCtr, 2 + Math.random().roundToInt())
@@ -154,20 +154,20 @@ object AxeCore {
for (l in -1 downTo -branchSize) {
val tileBranch = INGAME.world.getTileFromTerrain(x + l, y - upCtr)
if (tileBranch == thisLeaf)
removeLeaf(x + l, y - upCtr, thisLeaf.substringAfter(':').toInt() - 112)
removeLeaf(x + l, y - upCtr)
else break
}
// scan horizontally right
for (l in 1 .. branchSize) {
val tileBranch = INGAME.world.getTileFromTerrain(x + l, y - upCtr)
if (tileBranch == thisLeaf)
removeLeaf(x + l, y - upCtr, thisLeaf.substringAfter(':').toInt() - 112)
removeLeaf(x + l, y - upCtr)
else break
}
// deal with the current tile
val tileBranch = INGAME.world.getTileFromTerrain(x, y - upCtr)
if (tileBranch == thisLeaf)
removeLeaf(x, y - upCtr, thisLeaf.substringAfter(':').toInt() - 112)
removeLeaf(x, y - upCtr)
else break
}
else {
@@ -200,8 +200,9 @@ object AxeCore {
usageStatus
}
private fun removeLeaf(x: Int, y: Int, species: Int) {
fun removeLeaf(x: Int, y: Int) {
val tileBack = INGAME.world.getTileFromTerrain(x, y)
val species = tileBack.substringAfter(":").toInt() - 112
INGAME.world.setTileTerrain(x, y, Block.AIR, false)
// drop items
when (Math.random()) {

View File

@@ -348,8 +348,6 @@ internal object TerragenTest : NoiseMaker {
private val terragenYscaling = (NOISEBOX_HEIGHT / 2400.0).pow(0.75)
private val terragenTiers = listOf(.0, .5, 1.0, 2.5).map { it * terragenYscaling } // pow 1.0 for 1-to-1 scaling; 0.75 is used to make deep-rock layers actually deep for huge world size
private fun Double.dither() = Math.random() < this
override fun draw(x: Int, y: Int, noiseValue: List<Double>, outTex: Pixmap) {
val terr = noiseValue[0].tiered(terragenTiers)
val cave = if (noiseValue[1] < 0.5) 0 else 1