diff --git a/biome-distribution/presets/single.yml b/biome-distribution/presets/single.yml index 299d544d..2bc613b5 100644 --- a/biome-distribution/presets/single.yml +++ b/biome-distribution/presets/single.yml @@ -1,3 +1,3 @@ biomes: type: SINGLE - biome: TUNDRA_TRACKS # The singular biome that will be used. + biome: SCARLET_SANCTUARY # The singular biome that will be used. diff --git a/biome-distribution/stages/add_rivers.yml b/biome-distribution/stages/add_rivers.yml index 1e347e7b..780c950b 100644 --- a/biome-distribution/stages/add_rivers.yml +++ b/biome-distribution/stages/add_rivers.yml @@ -68,6 +68,18 @@ stages: SELF: 1 PLATEAO_RIVER_INNER: 1 sampler: *riverSampler + - type: REPLACE + from: USE_SCARLET_RIVER + to: + SELF: 1 + SCARLET_SANCTUARY_RIVER: 1 + sampler: *riverSampler + - type: REPLACE + from: USE_COLD_FUNGI_RIVER + to: + SELF: 1 + FROZEN_FUNGI_RIVER: 1 + sampler: *riverSampler - type: REPLACE from: USE_RIVER to: diff --git a/biome-distribution/stages/fill_temperature_zones.yml b/biome-distribution/stages/fill_temperature_zones.yml index 30da2d14..09a0dc58 100644 --- a/biome-distribution/stages/fill_temperature_zones.yml +++ b/biome-distribution/stages/fill_temperature_zones.yml @@ -14,6 +14,7 @@ stages: MOUNTAIN_MIRRORS: 2 ALPINE_ASCENDANCY: 1 TUNDRA_TRACKS: 2 + FROZEN_FUNGI: 1 - type: REPLACE from: medium sampler: @@ -34,6 +35,7 @@ stages: SAKURA_STREAMS: 1 BAMBOO_BASIN: 2 BADLANDS_BALCONIES: 2 + SCARLET_SANCTUARY: 2 _plateao: 1 # LAND_MEDIUM_A: 1 # LAND_MEDIUM_B: 1 diff --git a/biomes/rearth/base/eq_tilted_plateau.yml b/biomes/rearth/base/eq_tilted_plateau.yml new file mode 100644 index 00000000..87166316 --- /dev/null +++ b/biomes/rearth/base/eq_tilted_plateau.yml @@ -0,0 +1,64 @@ +id: EQ_TILTED_PLATEAU +type: BIOME +abstract: true + +vars: &variables + base: 71 + height: 10 + cellDist: ${customization.yml:biomeSpread.cellDistance} + +terrain: + sampler: + dimensions: 3 + type: EXPRESSION + variables: *variables + expression: | + cliffify(-y + base + height * surfaceOffset(x,z) + + (biomeTilt(x - 2, z - 2) + 0.5) * 55, -1) + + (wallAddition(x,y,z) + 1) * 2 + functions: + cliffify: + arguments: [x, border] + expression: | + if (x > border, + if (x > 6, max(0.06428571 + 1.2975*(x / 3 + 5) - 0.1223214*(x / 3 + 5)^2, 0.1), max(0.06428571 + 1.2975*x - 0.1223214*x^2, 0.1)), + x) + samplers: + wallAddition: + dimensions: 3 + type: OPEN_SIMPLEX_2S + frequency: 0.09 + biomeTilt: + dimensions: 2 + type: DOMAIN_WARP + warp: + type: OPEN_SIMPLEX_2 + frequency: 0.05 + amplitude: 7 + sampler: + dimensions: 2 + type: CELLULAR + return: OffsetNoiseLookup + jitter: ${customization.yml:biomeSpread.cellJitter} + frequency: 1 / ${customization.yml:biomeSpread.cellDistance} + lookup: + dimensions: 2 + type: EXPRESSION + variables: *variables + expression: | + x / cellDist + z / cellDist * 0.7 + biomeDist: + dimensions: 2 + type: CELLULAR + return: Distance + jitter: ${customization.yml:biomeSpread.cellJitter} + frequency: 1 / ${customization.yml:biomeSpread.cellDistance} + surfaceOffset: + dimensions: 2 + type: FBM + sampler: + type: OPEN_SIMPLEX_2S + frequency: 0.006 + octaves: 3 + lacunarity: 2 + gain: 0.5 diff --git a/biomes/rearth/rivers/frozen_fungi_river.yml b/biomes/rearth/rivers/frozen_fungi_river.yml new file mode 100644 index 00000000..0e1b5019 --- /dev/null +++ b/biomes/rearth/rivers/frozen_fungi_river.yml @@ -0,0 +1,69 @@ +id: FROZEN_FUNGI_RIVER +type: BIOME +extends: + - MOUNTAIN_RIVER_FROZEN + - EQ_GLOBAL_RIVER + - FROZEN_FUNGI + +original-noise: &originalNoise $biomes/rearth/base/eq_tilted_plateau.yml:terrain.sampler # Original noise to be turned into river + +vars: &variables + ceilingHeight: 80 # Base Y level of the ceiling + ceilingVariation: 4 # How many blocks upwards ceiling height can vary + originalStrength: 1 # How much the original noise contributes to ceiling shape + ceilingSpikeVar: 18 # How many blocks down ceiling spikes will go + + floorHeight: 42 # Base Y level of the floor + floorVariation: 0 # How many blocks* upwards floor height can vary + floorSpikeBias: 1 # How biased spikes are to going up or down, greater = more upwards + floorStrength: 0.5 # Strength of negation above the floor, used for carving adjacent biomes + floorSpikeVar: 18 # How many blocks* upwards spikes will come up from the floor + # * Gets factored by floorStrength + +terrain: + sampler: + type: EXPRESSION + dimensions: 3 + expression: | + if(y > ceilingHeight + ceilingVariation, parentEq(x, y, z), // If y above carved area, use parent eq + if(y < floorHeight, bottomEq(x, y, z), // If y below carved area, use bottom eq + max(parentEq(x, y, z) - topEq(x, y, z), bottomEq(x, y, z)) // Otherwise combine top and bottom together + ) // This ensures no unnecessary calculations + ) // and saves some performance + variables: *variables + samplers: + parentEq: *originalNoise + topEq: # Top half of river - includes original terrain + type: EXPRESSION + dimensions: 3 + expression: if(ceilingEq(x, y, z) > 0, (ceilingEq(x, y, z)^2)*(1/originalStrength), 0) + variables: *variables + samplers: + ceilingEq: # Controls the shape of the ceiling + type: EXPRESSION + dimensions: 3 + expression: -y + ceilingHeight + (noise(x, z)+1)/2 * ceilingVariation + variables: *variables + samplers: + noise: + dimensions: 2 + type: OPEN_SIMPLEX_2 + spikes: &spikes + dimensions: 2 + type: LINEAR + min: -1 + max: 0.2 + sampler: + type: CELLULAR + frequency: 0.08 + bottomEq: # Bottom half of river - makes up the river bed + type: EXPRESSION + dimensions: 3 + expression: -y + floorHeight - if(y > floorHeight,floorStrength*(-(-y + floorHeight))^2,0) + (noise(x, z)+1)/2 * floorVariation + variables: *variables + samplers: + noise: + dimensions: 2 + type: OPEN_SIMPLEX_2 + frequency: 0.03 + spikes: *spikes # Use same noise from ceiling spikes diff --git a/biomes/rearth/rivers/scarlet_sactuary_river.yml b/biomes/rearth/rivers/scarlet_sactuary_river.yml new file mode 100644 index 00000000..f58a94cd --- /dev/null +++ b/biomes/rearth/rivers/scarlet_sactuary_river.yml @@ -0,0 +1,69 @@ +id: SCARLET_SANCTUARY_RIVER +type: BIOME +extends: + - RIVER + - EQ_GLOBAL_RIVER + - SCARLET_SANCTUARY + +original-noise: &originalNoise $biomes/rearth/base/eq_tilted_plateau.yml:terrain.sampler # Original noise to be turned into river + +vars: &variables + ceilingHeight: 80 # Base Y level of the ceiling + ceilingVariation: 4 # How many blocks upwards ceiling height can vary + originalStrength: 1 # How much the original noise contributes to ceiling shape + ceilingSpikeVar: 18 # How many blocks down ceiling spikes will go + + floorHeight: 42 # Base Y level of the floor + floorVariation: 0 # How many blocks* upwards floor height can vary + floorSpikeBias: 1 # How biased spikes are to going up or down, greater = more upwards + floorStrength: 0.5 # Strength of negation above the floor, used for carving adjacent biomes + floorSpikeVar: 18 # How many blocks* upwards spikes will come up from the floor + # * Gets factored by floorStrength + +terrain: + sampler: + type: EXPRESSION + dimensions: 3 + expression: | + if(y > ceilingHeight + ceilingVariation, parentEq(x, y, z), // If y above carved area, use parent eq + if(y < floorHeight, bottomEq(x, y, z), // If y below carved area, use bottom eq + max(parentEq(x, y, z) - topEq(x, y, z), bottomEq(x, y, z)) // Otherwise combine top and bottom together + ) // This ensures no unnecessary calculations + ) // and saves some performance + variables: *variables + samplers: + parentEq: *originalNoise + topEq: # Top half of river - includes original terrain + type: EXPRESSION + dimensions: 3 + expression: if(ceilingEq(x, y, z) > 0, (ceilingEq(x, y, z)^2)*(1/originalStrength), 0) + variables: *variables + samplers: + ceilingEq: # Controls the shape of the ceiling + type: EXPRESSION + dimensions: 3 + expression: -y + ceilingHeight + (noise(x, z)+1)/2 * ceilingVariation + variables: *variables + samplers: + noise: + dimensions: 2 + type: OPEN_SIMPLEX_2 + spikes: &spikes + dimensions: 2 + type: LINEAR + min: -1 + max: 0.2 + sampler: + type: CELLULAR + frequency: 0.08 + bottomEq: # Bottom half of river - makes up the river bed + type: EXPRESSION + dimensions: 3 + expression: -y + floorHeight - if(y > floorHeight,floorStrength*(-(-y + floorHeight))^2,0) + (noise(x, z)+1)/2 * floorVariation + variables: *variables + samplers: + noise: + dimensions: 2 + type: OPEN_SIMPLEX_2 + frequency: 0.03 + spikes: *spikes # Use same noise from ceiling spikes diff --git a/biomes/rearth/variants/frozen_fungi.yml b/biomes/rearth/variants/frozen_fungi.yml new file mode 100644 index 00000000..619386f8 --- /dev/null +++ b/biomes/rearth/variants/frozen_fungi.yml @@ -0,0 +1,49 @@ +id: FROZEN_FUNGI +type: BIOME +vanilla: minecraft:mushroom_fields +extends: [ EQ_TILTED_PLATEAU, CARVING_LAND, BASE ] +color: $biomes/colors.yml:MUSHROOM_HILLS + +tags: + - USE_COLD_FUNGI_RIVER + +colors: + foliage: 0xa6e2ed + grass: 0x2AB2C7 + water: 0xA298E4 + water-fog: 0x50533 + +palette: + - SHROOM_SNOW_MIX: 319 + - MUDDY_BEACH: 63 + - << meta.yml:palette-bottom + +features: + preprocessors: + - POWDER_SNOW_DEPOSITS + slabs: + - SNOW_LAYERS + trees: + - COLD_FUNGI + flora: + - SMALL_MUSHROOMS + landforms: + - MOSSY_BOULDERS +# - GIANT_BOULDERS +# flora: +# - GRASS +# - TALL_GRASS +# - CROSSING_STONE_VINES +# - LARGE_LEAF_VINES_UNCOLORED +# - TREE_VINES +# - POPPY_PATCH +# - FERNS +# - DANDELION_PATCH +# - SMALL_DRIPLEAF +# - BIG_DRIPLEAF +# - SMALL_MUSHROOMS +# trees: +# - DEAD_SWAMP_TREES +# - DEAD_TREES_SPARSE +# - LUSH_FOREST_TREES +# - LARGE_MUSHROOMS \ No newline at end of file diff --git a/biomes/rearth/variants/scarlet_sanctuary.yml b/biomes/rearth/variants/scarlet_sanctuary.yml new file mode 100644 index 00000000..2bac082e --- /dev/null +++ b/biomes/rearth/variants/scarlet_sanctuary.yml @@ -0,0 +1,41 @@ +id: SCARLET_SANCTUARY +type: BIOME +vanilla: minecraft:forest +extends: [ EQ_TILTED_PLATEAU, CARVING_LAND, BASE ] +color: $biomes/colors.yml:BAMBOO_JUNGLE + +tags: + - USE_SCARLET_RIVER + +colors: + foliage: 0xEC5448 + grass: 0x599c2c + water: 0x5DB7EF + water-fog: 0x14a2c5 + +palette: + - GRASS_DENSE_MOSSY: 319 + - MUDDY_BEACH: 63 + - << meta.yml:palette-bottom + + +features: + landforms: + - GIANT_BOULDERS + flora: + - GRASS + - TALL_GRASS + - CROSSING_STONE_VINES + - LARGE_LEAF_VINES_UNCOLORED + - TREE_VINES + - POPPY_PATCH + - FERNS + - DANDELION_PATCH + - SMALL_DRIPLEAF + - BIG_DRIPLEAF + - SMALL_MUSHROOMS + trees: + - DEAD_SWAMP_TREES + - DEAD_TREES_SPARSE + - LUSH_FOREST_TREES + - LARGE_MUSHROOMS \ No newline at end of file diff --git a/features/rearth/giant_boulders.yml b/features/rearth/giant_boulders.yml new file mode 100644 index 00000000..bea47c7b --- /dev/null +++ b/features/rearth/giant_boulders.yml @@ -0,0 +1,43 @@ +id: GIANT_BOULDERS +type: FEATURE + +distributor: + type: AND + distributors: + - type: PADDED_GRID + width: 15 + padding: 5 + salt: 1923 + - type: SAMPLER + sampler: + type: PROBABILITY + sampler: + type: OPEN_SIMPLEX_2 + salt: 3119 + frequency: 0.06 + threshold: 0.15 + +locator: + type: AND + locators: + - type: SURFACE + range: &range + min: ${meta.yml:ocean-level} + 5 + max: $meta.yml:top-y + - type: PATTERN + range: *range + pattern: + type: MATCH_SET + blocks: $features/vegetation/meta.yml:plantable-blocks + offset: -1 + - type: ADJACENT_PATTERN + range: *range + match-all: true + pattern: + type: MATCH_AIR + offset: 0 + +structures: + distribution: + type: CONSTANT + structures: big_boulder \ No newline at end of file diff --git a/features/rearth/lush_forest_trees.yml b/features/rearth/lush_forest_trees.yml new file mode 100644 index 00000000..bb848c71 --- /dev/null +++ b/features/rearth/lush_forest_trees.yml @@ -0,0 +1,38 @@ +id: LUSH_FOREST_TREES +type: FEATURE + +distributor: + type: PADDED_GRID + width: 14 + padding: 4 + salt: 5932 + +locator: + type: AND + locators: + - type: TOP + range: &range + min: 64 + max: 255 + - type: PATTERN + range: *range + pattern: + type: MATCH_SET + blocks: $features/vegetation/meta.yml:plantable-blocks + offset: -1 + - type: PATTERN + range: *range + pattern: + type: MATCH_SET + blocks: + - minecraft:snow + - minecraft:air + offset: 0 + +structures: + distribution: + type: WHITE_NOISE + structures: + - large_oak_tree_procedural: 1 + - large_birch_tree_procedural: 1 + - large_spruce_tree: 1 diff --git a/features/vegetation/meta.yml b/features/vegetation/meta.yml index 66ac1bad..586f384c 100644 --- a/features/vegetation/meta.yml +++ b/features/vegetation/meta.yml @@ -2,6 +2,7 @@ plantable-blocks: - minecraft:mud - minecraft:grass_block - minecraft:podzol + - minecraft:mycelium - minecraft:dirt - minecraft:coarse_dirt - minecraft:moss_block diff --git a/features/vegetation/small_mushrooms.yml b/features/vegetation/small_mushrooms.yml index 34cf8c71..67815c47 100644 --- a/features/vegetation/small_mushrooms.yml +++ b/features/vegetation/small_mushrooms.yml @@ -19,10 +19,18 @@ distributor: threshold: 0.7 locator: - type: TOP - range: &range - min: ${meta.yml:ocean-level} + 3 - max: $meta.yml:top-y + type: AND + locators: + - type: TOP + range: &range + min: ${meta.yml:ocean-level} + 3 + max: $meta.yml:top-y + - type: PATTERN + range: *range + pattern: + type: MATCH_SET + blocks: $features/vegetation/meta.yml:plantable-blocks + offset: -1 structures: distribution: diff --git a/features/vegetation/trees/cold_fungi.yml b/features/vegetation/trees/cold_fungi.yml new file mode 100644 index 00000000..b725ba7f --- /dev/null +++ b/features/vegetation/trees/cold_fungi.yml @@ -0,0 +1,33 @@ +id: COLD_FUNGI +type: FEATURE + +distributor: + type: PADDED_GRID + width: 12 + padding: 5 + salt: 2931 + +locator: + type: AND + locators: + - type: TOP + range: &range + min: ${meta.yml:ocean-level} + 3 + max: $meta.yml:top-y + - type: PATTERN + range: *range + pattern: + type: MATCH_SET + blocks: $features/vegetation/meta.yml:plantable-blocks + offset: -1 + +structures: + distribution: + type: WHITE_NOISE + seed: 9512 + structures: + - large_mixed_mushroom_procedural: 15 + - oak_tree_procedural: 9 + - large_oak_tree_procedural: 1 + - large_oak_tree_procedural_2: 1 + \ No newline at end of file diff --git a/features/vegetation/trees/large_mushrooms.yml b/features/vegetation/trees/large_mushrooms.yml index c8373f99..3316f36b 100644 --- a/features/vegetation/trees/large_mushrooms.yml +++ b/features/vegetation/trees/large_mushrooms.yml @@ -17,8 +17,8 @@ locator: - type: PATTERN range: *range pattern: - type: MATCH - block: minecraft:mycelium + type: MATCH_SET + blocks: $features/vegetation/meta.yml:plantable-blocks offset: -1 structures: diff --git a/features/vegetation/trees/solid_color_trees.yml b/features/vegetation/trees/solid_color_trees.yml new file mode 100644 index 00000000..1adb4536 --- /dev/null +++ b/features/vegetation/trees/solid_color_trees.yml @@ -0,0 +1,39 @@ +id: UNCOLORED_TREES +type: FEATURE + +distributor: + type: PADDED_GRID + width: 10 + padding: 3 + salt: 9591 + +locator: + type: AND + locators: + - type: TOP + range: &range + min: ${meta.yml:ocean-level} + 3 + max: $meta.yml:top-y + - type: PATTERN + range: *range + pattern: + type: MATCH_SET + blocks: $features/vegetation/meta.yml:plantable-blocks + offset: -1 + - type: PATTERN + range: *range + pattern: + type: MATCH_SET + blocks: + - minecraft:snow + - minecraft:air + offset: 0 + +structures: + distribution: + type: CELLULAR + return: CellValue + frequency: 0.03 + structures: + - spruce_tree_procedural: 1 + - birch_tree_procedural: 1 \ No newline at end of file diff --git a/features/vegetation/vines/crossing_stone_vines.yml b/features/vegetation/vines/crossing_stone_vines.yml new file mode 100644 index 00000000..487abef3 --- /dev/null +++ b/features/vegetation/vines/crossing_stone_vines.yml @@ -0,0 +1,30 @@ +id: CROSSING_STONE_VINES +type: FEATURE + +# Adds leaf + vine segments that generate down from ceilings + +distributor: + type: SAMPLER + sampler: + type: POSITIVE_WHITE_NOISE + salt: 1975 + threshold: 0.05 + +locator: + type: PATTERN + range: + min: ${meta.yml:ocean-level} + 29 + max: ${meta.yml:ocean-level} + 74 + pattern: + type: AND + patterns: + - type: MATCH_AIR + offset: 0 + - type: MATCH + block: minecraft:stone + offset: 1 + +structures: + distribution: + type: CONSTANT + structures: crossing_vines_uncolored \ No newline at end of file diff --git a/features/vegetation/vines/large_leaf_vines_uncolored.yml b/features/vegetation/vines/large_leaf_vines_uncolored.yml new file mode 100644 index 00000000..ae81abe6 --- /dev/null +++ b/features/vegetation/vines/large_leaf_vines_uncolored.yml @@ -0,0 +1,76 @@ +id: LARGE_LEAF_VINES_UNCOLORED +type: FEATURE + +# Adds 'webs' of leaf blocks to surface blocks + +distributor: + type: SAMPLER + sampler: + type: PROBABILITY + sampler: + type: OPEN_SIMPLEX_2 + frequency: 0.03 + threshold: 0.75 + +locator: + type: AND + locators: + # Check if block is solid air + - type: PATTERN + range: &range + min: ${meta.yml:ocean-level} + 29 + max: ${meta.yml:ocean-level} + 119 + pattern: + type: MATCH_AIR + offset: 0 + # Check if there is a surrounding solid block + - type: OR + locators: + # If any side faces are solid + - type: ADJACENT_PATTERN + range: *range + pattern: + type: MATCH_SOLID + offset: 0 + # OR any top / bottom faces are solid + - type: PATTERN + range: *range + pattern: + type: OR + patterns: + - type: MATCH_SOLID + offset: 1 + - type: MATCH_SOLID + offset: -1 + # Use noise to create 'webbed' effect + - type: SAMPLER_3D + sampler: + dimensions: 3 + type: EXPRESSION + variables: + threshold: 0.5 + expression: if(noise(x,y,z) > threshold, 1, -1) + samplers: + noise: + # Warped distance2div produces a web effect + dimensions: 3 + type: DOMAIN_WARP + amplitude: 10 + warp: + type: FBM + octaves: 2 + sampler: + type: OPEN_SIMPLEX_2 + sampler: + type: LINEAR + min: -1 + max: 0 + sampler: + type: CELLULAR + return: Distance2Div + frequency: 0.06 + +structures: + distribution: + type: CONSTANT + structures: BLOCK:minecraft:azalea_leaves[persistent=true] \ No newline at end of file diff --git a/features/vegetation/vines/tree_leaves.yml b/features/vegetation/vines/tree_leaves.yml new file mode 100644 index 00000000..e51ef489 --- /dev/null +++ b/features/vegetation/vines/tree_leaves.yml @@ -0,0 +1,33 @@ +id: TREE_VINES +type: FEATURE + +# Adds leaf + vine segments that generate down from ceilings + +distributor: + type: SAMPLER + sampler: + type: POSITIVE_WHITE_NOISE + salt: 79498 + threshold: 0.06 + +locator: + type: PATTERN + range: + min: ${meta.yml:ocean-level} + 19 + max: ${meta.yml:ocean-level} + 119 + pattern: + type: AND + patterns: + - type: MATCH_AIR + offset: 0 + - type: MATCH_SET + blocks: + - minecraft:spruce_leaves + - minecraft:oak_leaves + - minecraft:birch_leaves + offset: 1 + +structures: + distribution: + type: CONSTANT + structures: tree_vines \ No newline at end of file diff --git a/palettes/grass/grass_dense_mossy.yml b/palettes/grass/grass_dense_mossy.yml new file mode 100644 index 00000000..1060de1b --- /dev/null +++ b/palettes/grass/grass_dense_mossy.yml @@ -0,0 +1,32 @@ +id: GRASS_DENSE_MOSSY +type: PALETTE + +layers: + - materials: + - minecraft:grass_block: 1 + - minecraft:moss_block: 1 + layers: 1 + - materials: + - minecraft:dirt: 2 + layers: 1 + - materials: + - minecraft:stone: 1 + layers: 1 + +sampler: + dimensions: 2 + type: DOMAIN_WARP + amplitude: 10 + warp: + dimensions: 2 + type: LINEAR + min: -1 + max: 0.2 + sampler: + type: CELLULAR + frequency: 0.10 + sampler: + type: FBM + octaves: 3 + sampler: + type: OPEN_SIMPLEX_2 \ No newline at end of file diff --git a/palettes/snowy/podzol_mycelium_snow_mix.yml b/palettes/snowy/podzol_mycelium_snow_mix.yml new file mode 100644 index 00000000..2c554121 --- /dev/null +++ b/palettes/snowy/podzol_mycelium_snow_mix.yml @@ -0,0 +1,26 @@ +id: SHROOM_SNOW_MIX +type: PALETTE + +layers: + - materials: + - minecraft:mycelium: 3 + - minecraft:podzol: 1 + - minecraft:snow_block: 4 + layers: 1 + sampler: + type: DOMAIN_WARP + amplitude: 1 + warp: + type: GAUSSIAN + sampler: + type: OPEN_SIMPLEX_2 + frequency: 0.02 + - materials: + - minecraft:mycelium: 1 + - minecraft:dirt: 2 + layers: 1 + sampler: + type: WHITE_NOISE + salt: 9231 + - materials: minecraft:stone + layers: 1 \ No newline at end of file diff --git a/structures/misc/big_boulder.tesf b/structures/misc/big_boulder.tesf new file mode 100644 index 00000000..b915dddc --- /dev/null +++ b/structures/misc/big_boulder.tesf @@ -0,0 +1,39 @@ +num randPrecision = 100; +num radius = 4+randomInt(randPrecision)/randPrecision*4; +num warp = 5; +num warpFreq = 8; +// Randomize iceberg x,y,z +num xRand = 3+randomInt(5); +num yRand = 4+randomInt(3); +num zRand = 4+randomInt(5); +num height = 25; +num radiusSquared = pow(radius,2); +num yTranslate = 1; + +for (num x = -radius-warp-xRand; x < radius+warp+xRand; x = x + 1) { + for (num y = (-radius-(warp*yRand))- height; y < (radius+(warp*yRand)) + height; y = y + 1) { + for (num z = -radius-warp-zRand; z < radius+warp+zRand; z = z + 1) { + num warpX = warp * sampler("simplex3", + warpFreq*(x+originX()), + warpFreq*(y+originY()+1000), + warpFreq*(z+originZ())); + num warpY = warp * sampler("simplex3", + warpFreq*(x+originX()), + warpFreq*(y+originY()+2000), + warpFreq*(z+originZ())); + num warpZ = warp * sampler("simplex3", + warpFreq*(x+originX()), + warpFreq*(y+originY()+3000), + warpFreq*(z+originZ())); + + // Iceberg equation + num size = (pow(x+warpX,2)/xRand)+(pow((y+warpY),2)/yRand / 6)+(pow(z+warpZ,2)/zRand); + + // Places iceberg blocks if within range + if ( size < radiusSquared ) { + block(x, y+yTranslate, z,"minecraft:stone"); + } + } + } +} + diff --git a/structures/rearth/large_oak_tree.tesf b/structures/rearth/large_oak_tree.tesf new file mode 100644 index 00000000..d0db9da9 --- /dev/null +++ b/structures/rearth/large_oak_tree.tesf @@ -0,0 +1,182 @@ +num randPrecision = 100; +num goldenAngle = 2.39996; +num pi = 3.14159; + +num trunkHeight = 14+randomInt(6); +str trunkBlock = "minecraft:dark_oak_log"; +num sideBranchInterval = 1; +num sideBranchMinHeight = 6+randomInt(2); +num sideBranchLengthMin = 7+randomInt(5); +num sideBranchLengthVariation = 2; +num sideBranchVerticalVariation = 0; +num sideBranchVerticalDirection = 0.3+randomInt(randPrecision)/randPrecision/2; +num sideBranchLeafRadiusMin = 5; +num sideBranchLeafTranslate = 0; +num sideBranchLeafTopFlatness = 2; +num sideBranchLeafBottomFlatness = 3; +num sideBranchLeafDensity = 1; +// str sideBranchLeafBlock = "minecraft:air"; +str sideBranchLeafBlock = "minecraft:dark_oak_leaves[distance=2,persistent=false]"; +str sideBranchBlockX = "minecraft:dark_oak_log[axis=x]"; +str sideBranchBlockY = "minecraft:dark_oak_log[axis=y]"; +str sideBranchBlockZ = "minecraft:dark_oak_log[axis=z]"; + +num topBranches = 6 + randomInt(3); +num topBranchLengthUpwardsMin = 7+randomInt(4); +num topBranchLengthOutwardsMin = 6+randomInt(14); +num topBranchVerticalDirection = 0.3; +num topBranchLeafRadiusMin = 6; +num topBranchLeafTranslate = 0; +num topBranchLeafTopFlatness = 2; +num topBranchLeafBottomFlatness = 4; +num topBranchLeafDensity = 0.8; +str topBranchLeafBlock = "minecraft:dark_oak_leaves[distance=3,persistent=false]"; +// str topBranchLeafBlock = "minecraft:air"; + +num branchAngle = randomInt(randPrecision)/randPrecision*2*pi; +for (num i = -6; i < trunkHeight; i = i + 1) { + if (i > sideBranchMinHeight) { + if (i % sideBranchInterval + randomInt(2) == 0) { + // Branch direction vector + num dx = sin(branchAngle); + num dy = sideBranchVerticalDirection + randomInt(randPrecision)/randPrecision*sideBranchVerticalVariation; + num dz = cos(branchAngle); + // Normalize vector + num mag = sqrt(pow(dx,2)+pow(dy,2)+pow(dz,2)); + dx = dx/mag; + dy = dy/mag; + dz = dz/mag; + // Branch origin + num ox = 0; + num oy = i; + num oz = 0; + // Set branch block based on largest unsigned vector component + str branchBlock = sideBranchBlockY; + if (abs(dx) > max(abs(dy),abs(dz))) branchBlock = sideBranchBlockX; + else if (abs(dz) > max(abs(dy),abs(dx))) branchBlock = sideBranchBlockZ; + num branchLength = sideBranchLengthMin + randomInt(randPrecision)/randPrecision*sideBranchLengthVariation; + // Generate branch + for (num l = 0; l <= branchLength; l = l + 1) { + block(l*dx+ox, l*dy+oy, l*dz+oz, branchBlock); + block(l*dx+ox, l*dy+oy - 1, l*dz+oz, branchBlock); + } + // Rotate angle of next branch + branchAngle = branchAngle + goldenAngle; + // Generate leaf cluster at the end of the branch + num radius = sideBranchLeafRadiusMin; + num radiusSquared = pow(radius, 2); + // Leaf cluster origin (end of branch) + num leafClusterOffset = branchLength - 1; + num lox = ox+leafClusterOffset*dx; + num loy = oy+leafClusterOffset*dy + sideBranchLeafTranslate; + num loz = oz+leafClusterOffset*dz; + + // spread wood around end to prevent leave decay + for (num l = -3; l <= 3; l = l + 1) { + if (l == 0) { + continue; + } + block(lox + l, loy, loz, sideBranchBlockX); + block(lox, loy, loz + l, sideBranchBlockZ); + } + + // generate leave cluster + for (num cx = ceil(-radius); cx <= ceil(radius); cx = cx + 1) { + for (num cy = ceil(-radius/sideBranchLeafBottomFlatness); cy <= ceil(radius/sideBranchLeafTopFlatness); cy = cy + 1) { + for (num cz = ceil(-radius); cz <= ceil(radius); cz = cz + 1) { + num squashFactor = sideBranchLeafBottomFlatness; + if (cy > 0) squashFactor = sideBranchLeafTopFlatness; + num distanceSquared = pow(cx,2)+pow(cy*squashFactor,2)+pow(cz,2); + if (distanceSquared < radiusSquared && randomInt(randPrecision)/randPrecision < sideBranchLeafDensity) { + block(lox+cx, loy+cy, loz+cz, sideBranchLeafBlock, false); + } + } + } + } + } + } + + num trunkRadius = 2; + num baseHeight = 3; + num radiusMax = 2.6; + + num baseWidth = min(max(-i + baseHeight, 0), radiusMax) / 2.4; + num baseAddWidth = round(baseWidth); + num usedRadius = trunkRadius + baseAddWidth; + num trunkLevelRadiusInnerSquared = pow2(trunkRadius + baseWidth - 0.8); + + // trunk placement + for (num x = -usedRadius; x < usedRadius; x = x + 1) { + for (num z = -usedRadius; z < usedRadius; z = z + 1) { + num distanceSquared = pow2(x)+pow2(z); + if (distanceSquared < trunkLevelRadiusInnerSquared) { + block(x, i, z, trunkBlock, false); + } + } + } + + +} + +for (num b = 1; b <= topBranches; b = b + 1) { + num t = b/topBranches; + num ti = 1-t; + // Branch direction vector + num dx = sin(branchAngle) * t; + num dy = topBranchVerticalDirection; + num dz = cos(branchAngle) * t; + // Normalize vector + num mag = sqrt(pow(dx,2)+pow(dy,2)+pow(dz,2)); + dx = dx/mag; + dy = dy/mag; + dz = dz/mag; + // Branch origin + num ox = 0; + num oy = trunkHeight; + num oz = 0; + // Set branch block based on largest unsigned vector component + str branchBlock = sideBranchBlockY; + if (abs(dx) > max(abs(dy),abs(dz))) branchBlock = sideBranchBlockX; + else if (abs(dz) > max(abs(dy),abs(dx))) branchBlock = sideBranchBlockZ; + num branchLength = topBranchLengthUpwardsMin*ti + topBranchLengthOutwardsMin*t; + // Generate branch + for (num l = 0; l <= branchLength; l = l + 1) { + block(l*dx+ox, l*dy+oy, l*dz+oz, branchBlock); + block(l*dx+ox, l*dy+oy - 1, l*dz+oz, branchBlock); + } + // Rotate angle of next branch + branchAngle = branchAngle + goldenAngle; + // Generate leaf cluster at the end of the branch + num radius = topBranchLeafRadiusMin; + num radiusSquared = pow(radius, 2); + + // Leaf cluster origin (end of branch) + num leafClusterOffset = branchLength - 1; + num lox = ox+leafClusterOffset*dx; + num loy = oy+leafClusterOffset*dy + topBranchLeafTranslate; + num loz = oz+leafClusterOffset*dz; + + // spread wood around end to prevent leave decay + for (num l = -4; l <= 4; l = l + 1) { + if (l == 0) { + continue; + } + block(lox + l, loy, loz, sideBranchBlockX); + block(lox, loy, loz + l, sideBranchBlockZ); + } + + for (num cx = ceil(-radius); cx <= ceil(radius); cx = cx + 1) { + for (num cy = ceil(-radius/topBranchLeafBottomFlatness); cy <= ceil(radius/topBranchLeafTopFlatness); cy = cy + 1) { + for (num cz = ceil(-radius); cz <= ceil(radius); cz = cz + 1) { + num squashFactor = topBranchLeafBottomFlatness; + if (cy > 0) squashFactor = topBranchLeafTopFlatness; + num distanceSquared = pow(cx,2)+pow(cy*squashFactor,2)+pow(cz,2); + if (distanceSquared < radiusSquared && randomInt(randPrecision)/randPrecision < topBranchLeafDensity) { + block(lox+cx, loy+cy, loz+cz, topBranchLeafBlock, false); + } + } + } + } +} + +block(0, -1, 0, "minecraft:dirt"); \ No newline at end of file diff --git a/structures/rearth/large_spruce_tree.tesf b/structures/rearth/large_spruce_tree.tesf new file mode 100644 index 00000000..5312d356 --- /dev/null +++ b/structures/rearth/large_spruce_tree.tesf @@ -0,0 +1,182 @@ +num randPrecision = 100; +num goldenAngle = 2.39996; +num pi = 3.14159; + +num trunkHeight = 17+randomInt(6); +str trunkBlock = "minecraft:spruce_log"; +num sideBranchInterval = 1; +num sideBranchMinHeight = 5+randomInt(2); +num sideBranchLengthMin = 6+randomInt(5); +num sideBranchLengthVariation = 2; +num sideBranchVerticalVariation = 0; +num sideBranchVerticalDirection = 0.3+randomInt(randPrecision)/randPrecision/2; +num sideBranchLeafRadiusMin = 5; +num sideBranchLeafTranslate = 0; +num sideBranchLeafTopFlatness = 2; +num sideBranchLeafBottomFlatness = 3; +num sideBranchLeafDensity = 1; +// str sideBranchLeafBlock = "minecraft:air"; +str sideBranchLeafBlock = "minecraft:spruce_leaves[distance=2,persistent=false]"; +str sideBranchBlockX = "minecraft:spruce_log[axis=x]"; +str sideBranchBlockY = "minecraft:spruce_log[axis=y]"; +str sideBranchBlockZ = "minecraft:spruce_log[axis=z]"; + +num topBranches = 6 + randomInt(3); +num topBranchLengthUpwardsMin = 7+randomInt(4); +num topBranchLengthOutwardsMin = 6+randomInt(14); +num topBranchVerticalDirection = 0.3; +num topBranchLeafRadiusMin = 6; +num topBranchLeafTranslate = 0; +num topBranchLeafTopFlatness = 1; +num topBranchLeafBottomFlatness = 3; +num topBranchLeafDensity = 1; +str topBranchLeafBlock = "minecraft:spruce_leaves[distance=3,persistent=false]"; +// str topBranchLeafBlock = "minecraft:air"; + +num branchAngle = randomInt(randPrecision)/randPrecision*2*pi; +for (num i = -6; i < trunkHeight; i = i + 1) { + if (i > sideBranchMinHeight) { + if (i % sideBranchInterval + randomInt(2) == 0) { + // Branch direction vector + num dx = sin(branchAngle); + num dy = sideBranchVerticalDirection + randomInt(randPrecision)/randPrecision*sideBranchVerticalVariation; + num dz = cos(branchAngle); + // Normalize vector + num mag = sqrt(pow(dx,2)+pow(dy,2)+pow(dz,2)); + dx = dx/mag; + dy = dy/mag; + dz = dz/mag; + // Branch origin + num ox = 0; + num oy = i; + num oz = 0; + // Set branch block based on largest unsigned vector component + str branchBlock = sideBranchBlockY; + if (abs(dx) > max(abs(dy),abs(dz))) branchBlock = sideBranchBlockX; + else if (abs(dz) > max(abs(dy),abs(dx))) branchBlock = sideBranchBlockZ; + num branchLength = sideBranchLengthMin + randomInt(randPrecision)/randPrecision*sideBranchLengthVariation; + // Generate branch + for (num l = 0; l <= branchLength; l = l + 1) { + block(l*dx+ox, l*dy+oy, l*dz+oz, branchBlock); + block(l*dx+ox, l*dy+oy - 1, l*dz+oz, branchBlock); + } + // Rotate angle of next branch + branchAngle = branchAngle + goldenAngle; + // Generate leaf cluster at the end of the branch + num radius = sideBranchLeafRadiusMin; + num radiusSquared = pow(radius, 2); + // Leaf cluster origin (end of branch) + num leafClusterOffset = branchLength - 1; + num lox = ox+leafClusterOffset*dx; + num loy = oy+leafClusterOffset*dy + sideBranchLeafTranslate; + num loz = oz+leafClusterOffset*dz; + + // spread wood around end to prevent leave decay + for (num l = -3; l <= 3; l = l + 1) { + if (l == 0) { + continue; + } + block(lox + l, loy, loz, sideBranchBlockX); + block(lox, loy, loz + l, sideBranchBlockZ); + } + + // generate leave cluster + for (num cx = ceil(-radius); cx <= ceil(radius); cx = cx + 1) { + for (num cy = ceil(-radius/sideBranchLeafBottomFlatness); cy <= ceil(radius/sideBranchLeafTopFlatness); cy = cy + 1) { + for (num cz = ceil(-radius); cz <= ceil(radius); cz = cz + 1) { + num squashFactor = sideBranchLeafBottomFlatness; + if (cy > 0) squashFactor = sideBranchLeafTopFlatness; + num distanceSquared = pow(cx,2)+pow(cy*squashFactor,2)+pow(cz,2); + if (distanceSquared < radiusSquared && randomInt(randPrecision)/randPrecision < sideBranchLeafDensity) { + block(lox+cx, loy+cy, loz+cz, sideBranchLeafBlock, false); + } + } + } + } + } + } + + num trunkRadius = 2; + num baseHeight = 3; + num radiusMax = 2.6; + + num baseWidth = min(max(-i + baseHeight, 0), radiusMax) / 2.4; + num baseAddWidth = round(baseWidth); + num usedRadius = trunkRadius + baseAddWidth; + num trunkLevelRadiusInnerSquared = pow2(trunkRadius + baseWidth - 0.8); + + // trunk placement + for (num x = -usedRadius; x < usedRadius; x = x + 1) { + for (num z = -usedRadius; z < usedRadius; z = z + 1) { + num distanceSquared = pow2(x)+pow2(z); + if (distanceSquared < trunkLevelRadiusInnerSquared) { + block(x, i, z, trunkBlock, false); + } + } + } + + +} + +for (num b = 1; b <= topBranches; b = b + 1) { + num t = b/topBranches; + num ti = 1-t; + // Branch direction vector + num dx = sin(branchAngle) * t; + num dy = topBranchVerticalDirection; + num dz = cos(branchAngle) * t; + // Normalize vector + num mag = sqrt(pow(dx,2)+pow(dy,2)+pow(dz,2)); + dx = dx/mag; + dy = dy/mag; + dz = dz/mag; + // Branch origin + num ox = 0; + num oy = trunkHeight; + num oz = 0; + // Set branch block based on largest unsigned vector component + str branchBlock = sideBranchBlockY; + if (abs(dx) > max(abs(dy),abs(dz))) branchBlock = sideBranchBlockX; + else if (abs(dz) > max(abs(dy),abs(dx))) branchBlock = sideBranchBlockZ; + num branchLength = topBranchLengthUpwardsMin*ti + topBranchLengthOutwardsMin*t; + // Generate branch + for (num l = 0; l <= branchLength; l = l + 1) { + block(l*dx+ox, l*dy+oy, l*dz+oz, branchBlock); + block(l*dx+ox, l*dy+oy - 1, l*dz+oz, branchBlock); + } + // Rotate angle of next branch + branchAngle = branchAngle + goldenAngle; + // Generate leaf cluster at the end of the branch + num radius = topBranchLeafRadiusMin; + num radiusSquared = pow(radius, 2); + + // Leaf cluster origin (end of branch) + num leafClusterOffset = branchLength - 1; + num lox = ox+leafClusterOffset*dx; + num loy = oy+leafClusterOffset*dy + topBranchLeafTranslate; + num loz = oz+leafClusterOffset*dz; + + // spread wood around end to prevent leave decay + for (num l = -4; l <= 4; l = l + 1) { + if (l == 0) { + continue; + } + block(lox + l, loy, loz, sideBranchBlockX); + block(lox, loy, loz + l, sideBranchBlockZ); + } + + for (num cx = ceil(-radius); cx <= ceil(radius); cx = cx + 1) { + for (num cy = ceil(-radius/topBranchLeafBottomFlatness); cy <= ceil(radius/topBranchLeafTopFlatness); cy = cy + 1) { + for (num cz = ceil(-radius); cz <= ceil(radius); cz = cz + 1) { + num squashFactor = topBranchLeafBottomFlatness; + if (cy > 0) squashFactor = topBranchLeafTopFlatness; + num distanceSquared = pow(cx,2)+pow(cy*squashFactor,2)+pow(cz,2); + if (distanceSquared < radiusSquared && randomInt(randPrecision)/randPrecision < topBranchLeafDensity) { + block(lox+cx, loy+cy, loz+cz, topBranchLeafBlock, false); + } + } + } + } +} + +block(0, -1, 0, "minecraft:dirt"); \ No newline at end of file diff --git a/structures/vegetation/vines/crossing_vines_segment_uncolored.tesf b/structures/vegetation/vines/crossing_vines_segment_uncolored.tesf new file mode 100644 index 00000000..f1d79623 --- /dev/null +++ b/structures/vegetation/vines/crossing_vines_segment_uncolored.tesf @@ -0,0 +1,17 @@ +block(0, 0, 0, "minecraft:azalea_leaves[persistent=true]", false); + +// Random chance of placing adjacent blocks +if (randomInt(2) == 0) block( 1, 0, 0, "minecraft:azalea_leaves[persistent=true]", false); +if (randomInt(2) == 0) block(-1, 0, 0, "minecraft:azalea_leaves[persistent=true]", false); +if (randomInt(2) == 0) block( 0, -1, 0, "minecraft:azalea_leaves[persistent=true]", false); +if (randomInt(2) == 0) block( 0, 0, 1, "minecraft:azalea_leaves[persistent=true]", false); +if (randomInt(2) == 0) block( 0, 0, -1, "minecraft:azalea_leaves[persistent=true]", false); + +// Chance to place a hanging strand of leaves +if (randomInt(10) == 0) { + num length = randomInt(10); + for (num i = 0; i < length; i = i + 1) { + if (check(0, -i, 0) == "LAND") break; + block(0, -i, 0, "minecraft:azalea_leaves[persistent=true]", false); + } +} \ No newline at end of file diff --git a/structures/vegetation/vines/crossing_vines_uncolored.tesf b/structures/vegetation/vines/crossing_vines_uncolored.tesf new file mode 100644 index 00000000..d3697a99 --- /dev/null +++ b/structures/vegetation/vines/crossing_vines_uncolored.tesf @@ -0,0 +1,84 @@ +// Look for solid blocks within a circle from the origin + +num twopi = 6.28318530718; +num checkRadius = 20; // Radius of circle + +bool foundPos = false; +num x = 0; +num y = 0; +num z = 0; + +num cx = 0; +num cz = 0; + +for (num i = 0; i < twopi; i = i + twopi/10) { + cx = sin(i) * checkRadius; + cz = cos(i) * checkRadius; + if (check(cx, y, cz) == "LAND") { + foundPos = true; + x = cx; + z = cz; + break; + } +} +if (!foundPos) fail; + +// Draw diagonal line using Bresenham's algorithm - +// where the Y coordinate is determined by a parabola + +// Start point +num x1 = 0; +num z1 = 0; + +// End point +num x2 = round(x); +num z2 = round(z); + +// Deltas +num dx = abs(x2 - x1); +num dz = abs(z2 - z1); + +// Iteration sign +num xs = 1; +if (x2 < x1) xs = xs * -1; +num zs = 1; +if (z2 < z1) zs = zs * -1; + +// Parabola variables +num t = 0; +num yDepth = 0; +num droopiness = 10; + +structure(x1, yDepth, z1, "crossing_vines_segment_uncolored", "NONE"); + +if (dx >= dz) { + // Driving axis is X + num p = 2 * dz - dx; + while (round(x1) != round(x2)) { + x1 = x1 + xs; + if (p >= 0) { + z1 = z1 + zs; + p = p - (2 * dx); + } + p = p + (2 * dz); + t = abs(x2 - x1) / dx; + yDepth = (4 * pow(t - 0.5, 2) - 1) * droopiness; + if (check(x1, yDepth, z1) == "LAND") return; + structure(x1, yDepth, z1, "crossing_vines_segment_uncolored", "NONE"); + } +} else { + // Driving axis is Z + num p = 2 * dx - dz; + while (round(z1) != round(z2)) { + z1 = z1 + zs; + if (p >= 0) { + x1 = x1 + xs; + p = p - (2 * dz); + } + p = p + (2 * dx); + t = abs(z2 - z1) / dz; + yDepth = (4 * pow(t - 0.5, 2) - 1) * droopiness; + if (check(x1, yDepth, z1) == "LAND") return; + structure(x1, yDepth, z1, "crossing_vines_segment_uncolored", "NONE"); + } +} \ No newline at end of file diff --git a/structures/vegetation/vines/tree_vines.tesf b/structures/vegetation/vines/tree_vines.tesf new file mode 100644 index 00000000..7b98122e --- /dev/null +++ b/structures/vegetation/vines/tree_vines.tesf @@ -0,0 +1,34 @@ +// Generate a column of leaves down from ceiling block +num leafDepth = 2 + randomInt(2); // Length of center column of leaves +for (num i = 0; i < leafDepth; i = i + 1) block(0, -i, 0, "minecraft:oak_leaves[persistent=true]", false); + +// Add shorter columns of leaves directly adjacent if adjacent ceiling blocks are present +if (check(0, 0, -1) == "LAND") { + num leafDepthNorth = randomInt(floor(leafDepth)); + for (num i = 0; i < leafDepthNorth; i = i + 1) block(0, -i, -1, "minecraft:oak_leaves[persistent=true]", false); +} +if (check(0, 0, 1) == "LAND") { + num leafDepthSouth = randomInt(floor(leafDepth)); + for (num i = 0; i < leafDepthSouth; i = i + 1) block(0, -i, 1, "minecraft:oak_leaves[persistent=true]", false); +} +if (check(1, 0, 0) == "LAND") { + num leafDepthEast = randomInt(floor(leafDepth)); + for (num i = 0; i < leafDepthEast; i = i + 1) block(1, -i, 0, "minecraft:oak_leaves[persistent=true]", false); +} +if (check(-1, 0, 0) == "LAND") { + num leafDepthWest = randomInt(floor(leafDepth)); + for (num i = 0; i < leafDepthWest; i = i + 1) block(-1, -i, 0, "minecraft:oak_leaves[persistent=true]", false); +} + +// Finally add vines of random lengths coming from center column +num vineDepthNorth = randomInt(10); +for (num i = leafDepth; i < leafDepth + vineDepthNorth; i = i + 1) block(0, -i, -1, "minecraft:vine[south=true]", false); +num vineDepthSouth = randomInt(10); +for (num i = leafDepth; i < leafDepth + vineDepthSouth; i = i + 1) block(0, -i, 1, "minecraft:vine[north=true]", false); +num vineDepthEast = randomInt(10); +for (num i = leafDepth; i < leafDepth + vineDepthEast; i = i + 1) block(1, -i, 0, "minecraft:vine[west=true]", false); +num vineDepthWest = randomInt(10); +for (num i = leafDepth; i < leafDepth + vineDepthWest; i = i + 1) block(-1, -i, 0, "minecraft:vine[east=true]", false); + + +