trees spawning

This commit is contained in:
minjaesong
2023-11-11 21:41:39 +09:00
parent 2f85579fb3
commit dd2dfed198
15 changed files with 191 additions and 31 deletions

View File

@@ -79,6 +79,12 @@ class BlockProp {
fun hasAnyTagOf(vararg s: String) = s.any { hasTag(it) }
fun hasAnyTag(s: Collection<String>) = s.any { hasTag(it) }
fun hasAnyTag(s: Array<String>) = s.any { hasTag(it) }
fun hasAllTagOf(vararg s: String) = s.all { hasTag(it) }
fun hasAllTag(s: Collection<String>) = s.all { hasTag(it) }
fun hasAllTag(s: Array<String>) = s.all { hasTag(it) }
fun hasNoTagOf(vararg s: String) = s.none { hasTag(it) }
fun hasNoTag(s: Collection<String>) = s.none { hasTag(it) }
fun hasNoTag(s: Array<String>) = s.none { hasTag(it) }
/**
* @param luminosity

View File

@@ -48,6 +48,11 @@ open class FancyWorldReadLoadScreen(screenToBeLoaded: IngameInstance, private va
CommonResourcePool.getAsTexture("basegame-gui-loadscrlayer01"),
CommonResourcePool.getAsTexture("basegame-gui-loadscrlayer02"),
CommonResourcePool.getAsTexture("basegame-gui-loadscrlayer03"),
CommonResourcePool.getAsTexture("basegame-gui-loadscrlayer03"),
CommonResourcePool.getAsTexture("basegame-gui-loadscrlayer03"),
CommonResourcePool.getAsTexture("basegame-gui-loadscrlayer03"),
CommonResourcePool.getAsTexture("basegame-gui-loadscrlayer03"),
CommonResourcePool.getAsTexture("basegame-gui-loadscrlayer03"),
)
val drawWidth = Toolkit.drawWidth

View File

@@ -1,6 +1,7 @@
package net.torvald.terrarum.modulebasegame.worldgenerator
import net.torvald.terrarum.App
import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.BlockCodex
import net.torvald.terrarum.LoadScreenBase
import net.torvald.terrarum.blockproperties.Block
@@ -73,7 +74,7 @@ class Treegen(world: GameWorld, seed: Long, params: TreegenParams, val biomeMap:
}
// filter duplicates
if (found && ys.last() != y - yi) {
if (found && (ys.isEmpty() || ys.last() != y - yi)) {
ys.add(y - yi)
}
}
@@ -97,23 +98,89 @@ class Treegen(world: GameWorld, seed: Long, params: TreegenParams, val biomeMap:
val grad2 = yRight - y
if ((grad1 * grad2).absoluteValue <= 1) {
printdbg(this, "Trying to plant tree at $x, $y")
val rnd = Math.random()
val biome = biomeMap[LandUtil.getBlockAddr(world, x, y)] ?: 0
val prob = treegenProbabilityToBiome[biome]!!
val prob = treegenProbabilityToBiome[biome] ?: 0.0
// actually plant a tree
if (rnd < prob) {
if (prob > 0.0 && rnd < prob) {
plantTree(x, y, 0, 1) // TODO randomly select species and small/large tree
}
}
}
for (y in grassMap[x - xs.first]) {
}
}
}
// don't use POI -- generate tiles using code for randomisation
/**
* @param y where the grass/dirt tile is
*/
private fun plantTree(x: Int, y: Int, type: Int, size: Int) {
val trunk = "basegame:" + ((if (size >= 1) 64 else 72) + type)
val foliage = "basegame:" + (112 + type)
var growCnt = 1
if (size == 1) {
var heightSum = 5+3+2+1
// check for minimum height
if ((1..heightSum).any { BlockCodex[world.getTileFromTerrain(x, y - it)].isSolid }) {
printdbg(this, "Ceiling not tall enough, aborting")
return
}
// roll for dice until we get a height that fits into the given terrain
var stem=0; var bulb1=0; var bulb2=0; var bulb3=0;
// do {
stem = 7 + fudgeN(2)
bulb1 = 4 + fudgeN(1)
bulb2 = 3 + fudgeN(1)
bulb3 = 2 + fudgeN(1)
heightSum = stem + bulb1 + bulb2 + bulb3
// }
// while ((1..heightSum).none { BlockCodex[world.getTileFromTerrain(x, y - it)].isSolid })
printdbg(this, "Planting tree; params: $stem, $bulb1, $bulb2, $bulb3")
// trunk
for (i in 0 until stem) {
for (xi in -1..+1) {
world.setTileTerrain(x + xi, y - growCnt, if (xi == 0) trunk else Block.AIR, true)
}
growCnt += 1
}
// bulb base
for (x in x-2..x+2) {
world.setTileTerrain(x, y - growCnt, foliage, true)
}
growCnt += 1
// bulb 1
for (i in 0 until bulb1) {
for (x in x-3..x+3) {
world.setTileTerrain(x, y - growCnt, foliage, true)
}
growCnt += 1
}
// bulb 2
for (i in 0 until bulb2) {
for (x in x-2..x+2) {
world.setTileTerrain(x, y - growCnt, foliage, true)
}
growCnt += 1
}
// bulb 3
for (i in 0 until bulb3) {
for (x in x-1..x+1) {
world.setTileTerrain(x, y - growCnt, foliage, true)
}
growCnt += 1
}
}
else throw IllegalArgumentException("Unknown tree size: $size")
}
/**
* Rearranges the list such that:
* `1,2,3,4,5,6,7,8,9`
@@ -134,10 +201,16 @@ class Treegen(world: GameWorld, seed: Long, params: TreegenParams, val biomeMap:
return r
}
/**
* @return normally distributed integer, for `maxvar=1`, `[-1, 0, 1]`; for `maxvar=2`, `[-2, -1, 0, 1, 2]`, etc.
*/
private fun fudgeN(maxvar: Int) = (0 until maxvar).sumOf { (Math.random() * 3).toInt() - 1 }
}
data class TreegenParams(
val woodlandsTreeDist: Int = 9, // distances are merely a suggestion tho
val shrublandsTreeDist: Int = 14,
val plainsTreeDist: Int = 21,
val shrublandsTreeDist: Int = 12,
val plainsTreeDist: Int = 16,
)

View File

@@ -268,7 +268,8 @@ internal object BlocksDrawer {
private lateinit var wallStickerTiles: Array<Int>
private lateinit var connectMutualTiles: Array<Int>
private lateinit var connectSelfTiles: Array<Int>
private lateinit var treeTiles: Array<Int>
private lateinit var treeLeavesTiles: Array<Int>
private lateinit var treeTrunkTiles: Array<Int>
internal fun rebuildInternalPrecalculations() {
if (App.IS_DEVELOPMENT_BUILD) {
@@ -300,8 +301,12 @@ internal object BlocksDrawer {
isConnectSelf(id) && !id.startsWith("virt:") && id != Block.NULL
}.map { world.tileNameToNumberMap[it.key] ?: throw NullPointerException("No tilenumber for ${it.key} exists") }.sorted().toTypedArray()
treeTiles = BlockCodex.blockProps.filter { (id, prop) ->
isTreeTile(id) && !id.startsWith("virt:") && id != Block.NULL
treeLeavesTiles = BlockCodex.blockProps.filter { (id, prop) ->
isTreeFoliage(id) && !id.startsWith("virt:") && id != Block.NULL
}.map { world.tileNameToNumberMap[it.key] ?: throw NullPointerException("No tilenumber for ${it.key} exists") }.sorted().toTypedArray()
treeTrunkTiles = BlockCodex.blockProps.filter { (id, prop) ->
isTreeTrunk(id) && !id.startsWith("virt:") && id != Block.NULL
}.map { world.tileNameToNumberMap[it.key] ?: throw NullPointerException("No tilenumber for ${it.key} exists") }.sorted().toTypedArray()
}
@@ -371,9 +376,13 @@ internal object BlocksDrawer {
/*else if (mode == FLUID) {
getNearbyTilesInfoFluids(x, y)
}*/
else if (treeTiles.binarySearch(thisTile) >= 0) {
else if (treeLeavesTiles.binarySearch(thisTile) >= 0) {
getNearbyTilesInfoTrees(x, y, mode).swizzle8(thisTile, hash)
}
else if (treeTrunkTiles.binarySearch(thisTile) >= 0) {
hash = 0
getNearbyTilesInfoTrees(x, y, mode)
}
else if (platformTiles.binarySearch(thisTile) >= 0) {
hash %= 2
getNearbyTilesInfoPlatform(x, y).swizzleH2(thisTile, hash)
@@ -550,12 +559,22 @@ internal object BlocksDrawer {
}
private fun getNearbyTilesInfoTrees(x: Int, y: Int, mode: Int): Int {
val tileThis = world.getTileFromTerrain(x, y)
val nearbyTiles: List<ItemID> = getNearbyTilesPos(x, y).map { world.getTileFrom(mode, it.x, it.y) }
var ret = 0
for (i in nearbyTiles.indices) {
if (isTreeTile(nearbyTiles[i])) {
ret += (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3
if (isTreeFoliage(tileThis)) {
for (i in nearbyTiles.indices) {
if (isTreeFoliage(nearbyTiles[i])) { // foliage "shadow" should not connect to the tree trunk
ret += (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3
}
}
}
else if (isTreeTrunk(tileThis)) {
for (i in nearbyTiles.indices) {
if (isTreeTrunk(nearbyTiles[i]) || i == 6 && isTreeFoliage(nearbyTiles[6])) { // if tile above is leaves, connect to it
ret += (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3
}
}
}
@@ -886,7 +905,8 @@ internal object BlocksDrawer {
fun isWallSticker(b: ItemID) = App.tileMaker.getRenderTag(b).connectionType == CreateTileAtlas.RenderTag.CONNECT_WALL_STICKER
fun isPlatform(b: ItemID) = App.tileMaker.getRenderTag(b).connectionType == CreateTileAtlas.RenderTag.CONNECT_WALL_STICKER_CONNECT_SELF
//fun isBlendMul(b: Int) = TILES_BLEND_MUL.contains(b)
fun isTreeTile(b: ItemID) = BlockCodex[b].hasTag("TREE")
fun isTreeFoliage(b: ItemID) = BlockCodex[b].hasAllTagOf("TREE", "LEAVES")
fun isTreeTrunk(b: ItemID) = BlockCodex[b].let { it.hasTag("TREE") && !it.hasTag("LEAVES") }
fun tileInCamera(x: Int, y: Int) =
x >= WorldCamera.x.div(TILE_SIZE) && y >= WorldCamera.y.div(TILE_SIZE) &&