From d3cd3465c71b29eaaee2bf9893dbeb0638822af7 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sun, 28 Jan 2024 20:14:48 +0900 Subject: [PATCH] lone leaves decaying --- src/net/torvald/terrarum/Terrarum.kt | 5 ++- .../terrarum/gameactors/ActorWithBody.kt | 2 +- .../terrarum/gameworld/WorldSimulator.kt | 35 ++++++++++++++++++- .../modulebasegame/gameactors/DroppedItem.kt | 6 ++-- .../modulebasegame/gameitems/AxeCore.kt | 17 ++++----- .../terrarum/tests/WorldgenNoiseSandbox.kt | 2 -- 6 files changed, 52 insertions(+), 15 deletions(-) diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index 2b470d81b..cf7058ca9 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -1038,4 +1038,7 @@ fun List.cartesianProduct(other: List) = this.flatMap { thisIt -> other.map { otherIt -> thisIt to otherIt } -} \ No newline at end of file +} + +fun Float.ditherToInt() = (this + Math.random() - 0.5).roundToInt() +fun Double.ditherToInt() = (this + Math.random() - 0.5).roundToInt() diff --git a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt index 9d34708a5..460e69133 100644 --- a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt +++ b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt @@ -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() diff --git a/src/net/torvald/terrarum/gameworld/WorldSimulator.kt b/src/net/torvald/terrarum/gameworld/WorldSimulator.kt index 7bed16252..90d69dda9 100644 --- a/src/net/torvald/terrarum/gameworld/WorldSimulator.kt +++ b/src/net/torvald/terrarum/gameworld/WorldSimulator.kt @@ -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 diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/DroppedItem.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/DroppedItem.kt index 6915107d9..8ad6804bd 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/DroppedItem.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/DroppedItem.kt @@ -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, diff --git a/src/net/torvald/terrarum/modulebasegame/gameitems/AxeCore.kt b/src/net/torvald/terrarum/modulebasegame/gameitems/AxeCore.kt index aa14cc120..3ce99d7b1 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameitems/AxeCore.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameitems/AxeCore.kt @@ -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()) { diff --git a/src/net/torvald/terrarum/tests/WorldgenNoiseSandbox.kt b/src/net/torvald/terrarum/tests/WorldgenNoiseSandbox.kt index 40667105e..d92be58a2 100644 --- a/src/net/torvald/terrarum/tests/WorldgenNoiseSandbox.kt +++ b/src/net/torvald/terrarum/tests/WorldgenNoiseSandbox.kt @@ -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, outTex: Pixmap) { val terr = noiseValue[0].tiered(terragenTiers) val cave = if (noiseValue[1] < 0.5) 0 else 1