mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-16 08:36:07 +09:00
lone leaves decaying
This commit is contained in:
@@ -1038,4 +1038,7 @@ fun <S, T> List<S>.cartesianProduct(other: List<T>) = this.flatMap { thisIt ->
|
|||||||
other.map { otherIt ->
|
other.map { otherIt ->
|
||||||
thisIt to otherIt
|
thisIt to otherIt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Float.ditherToInt() = (this + Math.random() - 0.5).roundToInt()
|
||||||
|
fun Double.ditherToInt() = (this + Math.random() - 0.5).roundToInt()
|
||||||
|
|||||||
@@ -2068,7 +2068,7 @@ open class ActorWithBody : Actor {
|
|||||||
|
|
||||||
private fun makeDust(collisionDamage: Double, vecSum: Vector2) {
|
private fun makeDust(collisionDamage: Double, vecSum: Vector2) {
|
||||||
val particleCount = (collisionDamage / 24.0).pow(0.75)
|
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()
|
val feetTiles = getFeetTiles()
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package net.torvald.terrarum.gameworld
|
|||||||
import com.badlogic.gdx.utils.Queue
|
import com.badlogic.gdx.utils.Queue
|
||||||
import net.torvald.random.HQRNG
|
import net.torvald.random.HQRNG
|
||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.*
|
||||||
|
import net.torvald.terrarum.App.printdbg
|
||||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED
|
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED
|
||||||
import net.torvald.terrarum.blockproperties.Block
|
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
|
||||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame.Companion.inUpdateRange
|
import net.torvald.terrarum.modulebasegame.TerrarumIngame.Companion.inUpdateRange
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.*
|
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 org.dyn4j.geometry.Vector2
|
||||||
|
import kotlin.math.cosh
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2016-08-03.
|
* Created by minjaesong on 2016-08-03.
|
||||||
@@ -94,6 +99,8 @@ object WorldSimulator {
|
|||||||
// TODO update logic
|
// TODO update logic
|
||||||
}
|
}
|
||||||
App.measureDebugTime("WorldSimulator.collisionDroppedItem") { collideDroppedItems() }
|
App.measureDebugTime("WorldSimulator.collisionDroppedItem") { collideDroppedItems() }
|
||||||
|
App.measureDebugTime("WorldSimulator.dropTreeLeaves") { dropTreeLeaves() }
|
||||||
|
|
||||||
|
|
||||||
//printdbg(this, "============================")
|
//printdbg(this, "============================")
|
||||||
}
|
}
|
||||||
@@ -112,8 +119,17 @@ object WorldSimulator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun sech2(x: Float) = 1f / cosh(x).sqr()
|
||||||
|
|
||||||
fun growOrKillGrass() {
|
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 rx = rng.nextInt(updateXFrom, updateXTo + 1)
|
||||||
val ry = rng.nextInt(updateYFrom, updateYTo + 1)
|
val ry = rng.nextInt(updateYFrom, updateYTo + 1)
|
||||||
val tile = world.getTileFromTerrain(rx, ry)
|
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() {
|
fun collideDroppedItems() {
|
||||||
ingame.actorContainerActive.filter { it is DroppedItem }.forEach { droppedItem0 ->
|
ingame.actorContainerActive.filter { it is DroppedItem }.forEach { droppedItem0 ->
|
||||||
val droppedItem = droppedItem0 as DroppedItem
|
val droppedItem = droppedItem0 as DroppedItem
|
||||||
|
|||||||
@@ -125,9 +125,11 @@ open class DroppedItem : ActorWithBody {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getLum(itemID: ItemID): Cvec {
|
private fun getLum(itemID: ItemID): Cvec {
|
||||||
return if (itemID.isBlock() || itemID.isWall()) {
|
return if (itemID.isBlock()) {
|
||||||
BlockCodex[itemID.substringAfter('@')].getLumCol(randKey1, randKey2)
|
BlockCodex[itemID].getLumCol(randKey1, randKey2)
|
||||||
}
|
}
|
||||||
|
else if (itemID.isWall())
|
||||||
|
BlockCodex[itemID.substringAfter('@')].getLumCol(randKey1, randKey2)
|
||||||
else {
|
else {
|
||||||
Cvec(
|
Cvec(
|
||||||
ItemCodex[itemID]?.itemProperties?.getAsFloat(AVKey.LUMR) ?: 0f,
|
ItemCodex[itemID]?.itemProperties?.getAsFloat(AVKey.LUMR) ?: 0f,
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ object AxeCore {
|
|||||||
).let { tileBroken ->
|
).let { tileBroken ->
|
||||||
// tile busted
|
// tile busted
|
||||||
if (tileBroken != null) {
|
if (tileBroken != null) {
|
||||||
removeLeaf(x, y, tileBroken.substringAfter(':').toInt() - 112)
|
removeLeaf(x, y)
|
||||||
PickaxeCore.makeDust(tile, x, y, 9)
|
PickaxeCore.makeDust(tile, x, y, 9)
|
||||||
}
|
}
|
||||||
// tile not busted
|
// tile not busted
|
||||||
@@ -110,8 +110,8 @@ object AxeCore {
|
|||||||
val tileThereR = INGAME.world.getTileFromTerrain(x+1, y - upCtr)
|
val tileThereR = INGAME.world.getTileFromTerrain(x+1, y - upCtr)
|
||||||
val propThereL = BlockCodex[tileThereL]
|
val propThereL = BlockCodex[tileThereL]
|
||||||
val propThereR = BlockCodex[tileThereR]
|
val propThereR = BlockCodex[tileThereR]
|
||||||
val treeTrunkXoff = if (propThereL.hasAllTag(listOf("TREELARGE", "TREETRUNK"))) -1
|
val treeTrunkXoff = if (propThereL.hasAllTagOf("TREELARGE", "TREETRUNK")) -1
|
||||||
else if (propThereR.hasAllTag(listOf("TREELARGE", "TREETRUNK"))) 1
|
else if (propThereR.hasAllTagOf("TREELARGE", "TREETRUNK")) 1
|
||||||
else 0
|
else 0
|
||||||
|
|
||||||
if (treeTrunkXoff != 0) {
|
if (treeTrunkXoff != 0) {
|
||||||
@@ -128,7 +128,7 @@ object AxeCore {
|
|||||||
val tileHere = INGAME.world.getTileFromTerrain(x, y - upCtr)
|
val tileHere = INGAME.world.getTileFromTerrain(x, y - upCtr)
|
||||||
val propHere = BlockCodex[tileHere]
|
val propHere = BlockCodex[tileHere]
|
||||||
|
|
||||||
if (propHere.hasAllTag(listOf("TREELARGE", "TREETRUNK"))) {
|
if (propHere.hasAllTagOf("TREELARGE", "TREETRUNK")) {
|
||||||
INGAME.world.setTileTerrain(x, y - upCtr, Block.AIR, false)
|
INGAME.world.setTileTerrain(x, y - upCtr, Block.AIR, false)
|
||||||
PickaxeCore.dropItem(propHere.drop, x, y - upCtr)
|
PickaxeCore.dropItem(propHere.drop, x, y - upCtr)
|
||||||
PickaxeCore.makeDust(tile, x, y - upCtr, 2 + Math.random().roundToInt())
|
PickaxeCore.makeDust(tile, x, y - upCtr, 2 + Math.random().roundToInt())
|
||||||
@@ -154,20 +154,20 @@ object AxeCore {
|
|||||||
for (l in -1 downTo -branchSize) {
|
for (l in -1 downTo -branchSize) {
|
||||||
val tileBranch = INGAME.world.getTileFromTerrain(x + l, y - upCtr)
|
val tileBranch = INGAME.world.getTileFromTerrain(x + l, y - upCtr)
|
||||||
if (tileBranch == thisLeaf)
|
if (tileBranch == thisLeaf)
|
||||||
removeLeaf(x + l, y - upCtr, thisLeaf.substringAfter(':').toInt() - 112)
|
removeLeaf(x + l, y - upCtr)
|
||||||
else break
|
else break
|
||||||
}
|
}
|
||||||
// scan horizontally right
|
// scan horizontally right
|
||||||
for (l in 1 .. branchSize) {
|
for (l in 1 .. branchSize) {
|
||||||
val tileBranch = INGAME.world.getTileFromTerrain(x + l, y - upCtr)
|
val tileBranch = INGAME.world.getTileFromTerrain(x + l, y - upCtr)
|
||||||
if (tileBranch == thisLeaf)
|
if (tileBranch == thisLeaf)
|
||||||
removeLeaf(x + l, y - upCtr, thisLeaf.substringAfter(':').toInt() - 112)
|
removeLeaf(x + l, y - upCtr)
|
||||||
else break
|
else break
|
||||||
}
|
}
|
||||||
// deal with the current tile
|
// deal with the current tile
|
||||||
val tileBranch = INGAME.world.getTileFromTerrain(x, y - upCtr)
|
val tileBranch = INGAME.world.getTileFromTerrain(x, y - upCtr)
|
||||||
if (tileBranch == thisLeaf)
|
if (tileBranch == thisLeaf)
|
||||||
removeLeaf(x, y - upCtr, thisLeaf.substringAfter(':').toInt() - 112)
|
removeLeaf(x, y - upCtr)
|
||||||
else break
|
else break
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -200,8 +200,9 @@ object AxeCore {
|
|||||||
usageStatus
|
usageStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun removeLeaf(x: Int, y: Int, species: Int) {
|
fun removeLeaf(x: Int, y: Int) {
|
||||||
val tileBack = INGAME.world.getTileFromTerrain(x, y)
|
val tileBack = INGAME.world.getTileFromTerrain(x, y)
|
||||||
|
val species = tileBack.substringAfter(":").toInt() - 112
|
||||||
INGAME.world.setTileTerrain(x, y, Block.AIR, false)
|
INGAME.world.setTileTerrain(x, y, Block.AIR, false)
|
||||||
// drop items
|
// drop items
|
||||||
when (Math.random()) {
|
when (Math.random()) {
|
||||||
|
|||||||
@@ -348,8 +348,6 @@ internal object TerragenTest : NoiseMaker {
|
|||||||
private val terragenYscaling = (NOISEBOX_HEIGHT / 2400.0).pow(0.75)
|
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 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) {
|
override fun draw(x: Int, y: Int, noiseValue: List<Double>, outTex: Pixmap) {
|
||||||
val terr = noiseValue[0].tiered(terragenTiers)
|
val terr = noiseValue[0].tiered(terragenTiers)
|
||||||
val cave = if (noiseValue[1] < 0.5) 0 else 1
|
val cave = if (noiseValue[1] < 0.5) 0 else 1
|
||||||
|
|||||||
Reference in New Issue
Block a user