forked from MineClone5/MineClone5
Update Fork #1
|
@ -15,19 +15,19 @@ See https://git.minetest.land/MineClone2/MineClone2/issues/1395
|
|||
`vm_context` will pass into next lvm callback function from the queue!
|
||||
`vm_context`: a table which already contains some LVM data as the fields, and some of them can be added in your lvm callback function:
|
||||
`vm`: curent voxel manipulator object itself;
|
||||
`blockseed`: seed of this mapchunk;
|
||||
`chunkseed`: seed of this mapchunk;
|
||||
`minp` & `maxp`: minimum and maximum chunk position;
|
||||
`emin` & `emax`: minimum and maximum chunk position WITH SHELL AROUND IT;
|
||||
`area`: voxel area, can be helpful to access data;
|
||||
`data`: LVM buffer data array, data loads into it before the callbacks;
|
||||
`write`: set it to true in your lvm callback functionm, if you changed `data` and want to write it;
|
||||
`data2`: LVM buffer data array of `param2`, !NO ANY DATA LOADS INTO IT BEFORE THE CALLBACKS! - you load it yourself:
|
||||
`vm_context.data2 = vm_context.data2 or vm_context.vm.get_param2_data(vm_context.lvm_param2_buffer)`
|
||||
`write_param2`: set it to true in your lvm callback function, if you used `data2` and want to write it;
|
||||
`param2_data`: LVM buffer data array of `param2`, !NO ANY DATA LOADS INTO IT BEFORE THE CALLBACKS! - you load it yourself:
|
||||
`vm_context.param2_data = vm_context.param2_data or vm_context.vm:get_param2_data(vm_context.lvm_param2_buffer)`
|
||||
`write_param2`: set it to true in your lvm callback function, if you used `param2_data` and want to write it;
|
||||
`light`: LVM buffer data array of light, !NO ANY DATA LOADS INTO IT BEFORE THE CALLBACKS! - you load it yourself:
|
||||
`vm_context.light = vm_context.light or vm_context.vm.get_light_data(vm_context.lvm_light_buffer)`
|
||||
`write_light`: set it to true in your lvm callback function, if you used `light` and want to write it;
|
||||
`lvm_param2_buffer`: static `param2` buffer pointer, used to load `data2` array;
|
||||
`lvm_param2_buffer`: static `param2` buffer pointer, used to load `param2_data` array;
|
||||
`shadow`: set it to false to disable shadow propagation;
|
||||
`heightmap`: mapgen object contanting y coordinates of ground level,
|
||||
!NO ANY DATA LOADS INTO IT BEFORE THE CALLBACKS! - load it yourself:
|
||||
|
|
|
@ -125,7 +125,7 @@ minetest.register_on_shutdown(function()
|
|||
end)
|
||||
|
||||
local vm_context -- here will be many references and flags, like: param2, light_data, heightmap, biomemap, heatmap, humiditymap, gennotify, write_lvm, write_param2, shadow
|
||||
local data, data2, light, area
|
||||
local data, param2_data, light, area
|
||||
local current_blocks = {}
|
||||
local current_chunks = {}
|
||||
local lvm_buffer, lvm_param2_buffer, lvm_light_buffer = {}, {}, {} -- Static buffer pointers
|
||||
|
@ -139,7 +139,7 @@ minetest.register_on_generated(function(minp, maxp, chunkseed)
|
|||
area = VoxelArea:new({MinEdge=emin, MaxEdge=emax})
|
||||
vm_context = {
|
||||
data = data,
|
||||
data2 = data2,
|
||||
param2_data = param2_data,
|
||||
light = light,
|
||||
area = area,
|
||||
lvm_buffer = lvm_buffer,
|
||||
|
@ -270,7 +270,7 @@ minetest.register_on_generated(function(minp, maxp, chunkseed)
|
|||
vm:set_data(data)
|
||||
end
|
||||
if vm_context.write_param2 then
|
||||
vm:set_param2_data(data2)
|
||||
vm:set_param2_data(vm_context.param2_data)
|
||||
end
|
||||
if vm_context.write_light then
|
||||
vm:set_light_data(light)
|
||||
|
@ -291,7 +291,7 @@ minetest.register_on_generated(function(minp, maxp, chunkseed)
|
|||
area = VoxelArea:new({MinEdge=minp, MaxEdge=maxp})
|
||||
vm_context = {
|
||||
data = data,
|
||||
data2 = data2,
|
||||
param2_data = param2_data,
|
||||
light = light,
|
||||
area = area,
|
||||
lvm_buffer = lvm_buffer,
|
||||
|
@ -314,7 +314,7 @@ minetest.register_on_generated(function(minp, maxp, chunkseed)
|
|||
vm:set_data(data)
|
||||
end
|
||||
if vm_context.write_param2 then
|
||||
vm:set_param2_data(data2)
|
||||
vm:set_param2_data(param2_data)
|
||||
end
|
||||
if vm_context.write_light then
|
||||
vm:set_light_data(light)
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
|
||||
local mg_name = minetest.get_mapgen_setting("mg_name")
|
||||
local mg_name = mcl_mapgen.name
|
||||
local v6 = mcl_mapgen.v6
|
||||
|
||||
local math = math
|
||||
local vector = vector
|
||||
|
@ -381,7 +382,7 @@ function mcl_core.generate_tree(pos, tree_type, options)
|
|||
local balloon = options and options.balloon
|
||||
|
||||
if tree_type == nil or tree_type == OAK_TREE_ID then
|
||||
if mg_name == "v6" then
|
||||
if v6 then
|
||||
mcl_core.generate_v6_oak_tree(pos)
|
||||
else
|
||||
if balloon then
|
||||
|
@ -396,7 +397,7 @@ function mcl_core.generate_tree(pos, tree_type, options)
|
|||
if two_by_two then
|
||||
mcl_core.generate_huge_spruce_tree(pos)
|
||||
else
|
||||
if mg_name == "v6" then
|
||||
if v6 then
|
||||
mcl_core.generate_v6_spruce_tree(pos)
|
||||
else
|
||||
mcl_core.generate_spruce_tree(pos)
|
||||
|
@ -408,7 +409,7 @@ function mcl_core.generate_tree(pos, tree_type, options)
|
|||
if two_by_two then
|
||||
mcl_core.generate_huge_jungle_tree(pos)
|
||||
else
|
||||
if mg_name == "v6" then
|
||||
if v6 then
|
||||
mcl_core.generate_v6_jungle_tree(pos)
|
||||
else
|
||||
mcl_core.generate_jungle_tree(pos)
|
||||
|
@ -786,7 +787,7 @@ function mcl_core.generate_huge_jungle_tree(pos)
|
|||
end
|
||||
|
||||
|
||||
local grass_spread_randomizer = PseudoRandom(minetest.get_mapgen_setting("seed"))
|
||||
local grass_spread_randomizer = PseudoRandom(mcl_mapgen.seed)
|
||||
|
||||
function mcl_core.get_grass_palette_index(pos)
|
||||
local biome_data = minetest.get_biome_data(pos)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
name = mcl_core
|
||||
description = Core items of MineClone 2: Basic biome blocks (dirt, sand, stones, etc.), derived items, glass, sugar cane, cactus, barrier, mining tools, hand, craftitems, and misc. items which don't really fit anywhere else.
|
||||
depends = mcl_autogroup, mcl_init, mcl_sounds, mcl_particles, mcl_util, mcl_worlds, doc_items, mcl_enchanting, mcl_colors
|
||||
depends = mcl_autogroup, mcl_init, mcl_sounds, mcl_particles, mcl_util, mcl_worlds, doc_items, mcl_enchanting, mcl_colors, mcl_mapgen
|
||||
optional_depends = doc
|
||||
|
|
|
@ -84,21 +84,9 @@ local c_realm_barrier = minetest.get_content_id("mcl_core:realm_barrier")
|
|||
local c_top_snow = minetest.get_content_id("mcl_core:snow")
|
||||
local c_snow_block = minetest.get_content_id("mcl_core:snowblock")
|
||||
local c_clay = minetest.get_content_id("mcl_core:clay")
|
||||
local c_leaves = minetest.get_content_id("mcl_core:leaves")
|
||||
local c_jungleleaves = minetest.get_content_id("mcl_core:jungleleaves")
|
||||
--local c_jungletree = minetest.get_content_id("mcl_core:jungletree")
|
||||
local c_vine = minetest.get_content_id("mcl_core:vine")
|
||||
local c_air = minetest.CONTENT_AIR
|
||||
|
||||
local c_cocoas = nil
|
||||
if minetest.get_modpath("mcl_cocoas") then
|
||||
c_cocoas = {
|
||||
minetest.get_content_id("mcl_cocoas:cocoa_1"),
|
||||
minetest.get_content_id("mcl_cocoas:cocoa_2"),
|
||||
minetest.get_content_id("mcl_cocoas:cocoa_3")
|
||||
}
|
||||
end
|
||||
|
||||
--
|
||||
-- Ore generation
|
||||
--
|
||||
|
@ -1167,9 +1155,6 @@ minetest.set_mapgen_setting("mg_flags", mg_flags_str, true)
|
|||
return x, z
|
||||
end]]
|
||||
|
||||
-- Perlin noise objects
|
||||
local perlin_vines, perlin_vines_fine, perlin_vines_upwards, perlin_vines_length, perlin_vines_density
|
||||
|
||||
local dragon_spawn_pos = false
|
||||
local dragon_spawned, portal_generated = false, false
|
||||
|
||||
|
@ -1209,214 +1194,6 @@ function mcl_mapgen_core.generate_end_exit_portal(pos)
|
|||
portal_generated = true
|
||||
end
|
||||
|
||||
|
||||
-- Buffers for LuaVoxelManip
|
||||
-- local lvm_buffer = {}
|
||||
-- local lvm_buffer_param2 = {}
|
||||
|
||||
-- Generate tree decorations in the bounding box. This adds:
|
||||
-- * Cocoa at jungle trees
|
||||
-- * Jungle tree vines
|
||||
-- * Oak vines in swamplands
|
||||
local function generate_tree_decorations(minp, maxp, seed, data, param2_data, area, biomemap, lvm_used, pr)
|
||||
if maxp.y < 0 then
|
||||
return lvm_used
|
||||
end
|
||||
|
||||
local oaktree, oakleaves, jungletree, jungleleaves = {}, {}, {}, {}
|
||||
local swampland = minetest.get_biome_id("Swampland")
|
||||
local swampland_shore = minetest.get_biome_id("Swampland_shore")
|
||||
local jungle = minetest.get_biome_id("Jungle")
|
||||
local jungle_shore = minetest.get_biome_id("Jungle_shore")
|
||||
local jungle_m = minetest.get_biome_id("JungleM")
|
||||
local jungle_m_shore = minetest.get_biome_id("JungleM_shore")
|
||||
local jungle_edge = minetest.get_biome_id("JungleEdge")
|
||||
local jungle_edge_shore = minetest.get_biome_id("JungleEdge_shore")
|
||||
local jungle_edge_m = minetest.get_biome_id("JungleEdgeM")
|
||||
local jungle_edge_m_shore = minetest.get_biome_id("JungleEdgeM_shore")
|
||||
|
||||
-- Modifier for Jungle M biome: More vines and cocoas
|
||||
local dense_vegetation = false
|
||||
|
||||
if biomemap then
|
||||
-- Biome map available: Check if the required biome (jungle or swampland)
|
||||
-- is in this mapchunk. We are only interested in trees in the correct biome.
|
||||
-- The nodes are added if the correct biome is *anywhere* in the mapchunk.
|
||||
-- TODO: Strictly generate vines in the correct biomes only.
|
||||
local swamp_biome_found, jungle_biome_found = false, false
|
||||
for b=1, #biomemap do
|
||||
local id = biomemap[b]
|
||||
|
||||
if not swamp_biome_found and (id == swampland or id == swampland_shore) then
|
||||
oaktree = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:tree"})
|
||||
oakleaves = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:leaves"})
|
||||
swamp_biome_found = true
|
||||
end
|
||||
if not jungle_biome_found and (id == jungle or id == jungle_shore or id == jungle_m or id == jungle_m_shore or id == jungle_edge or id == jungle_edge_shore or id == jungle_edge_m or id == jungle_edge_m_shore) then
|
||||
jungletree = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:jungletree"})
|
||||
jungleleaves = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:jungleleaves"})
|
||||
jungle_biome_found = true
|
||||
end
|
||||
if not dense_vegetation and (id == jungle_m or id == jungle_m_shore) then
|
||||
dense_vegetation = true
|
||||
end
|
||||
if swamp_biome_found and jungle_biome_found and dense_vegetation then
|
||||
break
|
||||
end
|
||||
end
|
||||
else
|
||||
-- If there is no biome map, we just count all jungle things we can find.
|
||||
-- Oak vines will not be generated.
|
||||
jungletree = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:jungletree"})
|
||||
jungleleaves = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:jungleleaves"})
|
||||
end
|
||||
|
||||
local pos, treepos, dir
|
||||
|
||||
if c_cocoas ~= nil then
|
||||
local cocoachance = 40
|
||||
if dense_vegetation then
|
||||
cocoachance = 32
|
||||
end
|
||||
|
||||
-- Pass 1: Generate cocoas at jungle trees
|
||||
for n = 1, #jungletree do
|
||||
|
||||
pos = table.copy(jungletree[n])
|
||||
treepos = table.copy(pos)
|
||||
|
||||
if minetest.find_node_near(pos, 1, {"mcl_core:jungleleaves"}) then
|
||||
|
||||
dir = pr:next(1, cocoachance)
|
||||
|
||||
if dir == 1 then
|
||||
pos.z = pos.z + 1
|
||||
elseif dir == 2 then
|
||||
pos.z = pos.z - 1
|
||||
elseif dir == 3 then
|
||||
pos.x = pos.x + 1
|
||||
elseif dir == 4 then
|
||||
pos.x = pos.x -1
|
||||
end
|
||||
|
||||
local p_pos = area:index(pos.x, pos.y, pos.z)
|
||||
local l = minetest.get_node_light(pos)
|
||||
|
||||
if dir < 5
|
||||
and data[p_pos] == c_air
|
||||
and l and l > 12 then
|
||||
local c = pr:next(1, 3)
|
||||
data[p_pos] = c_cocoas[c]
|
||||
param2_data[p_pos] = minetest.dir_to_facedir(vector.subtract(treepos, pos))
|
||||
lvm_used = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Pass 2: Generate vines at jungle wood, jungle leaves in jungle and oak wood, oak leaves in swampland
|
||||
perlin_vines = perlin_vines or minetest.get_perlin(555, 4, 0.6, 500)
|
||||
perlin_vines_fine = perlin_vines_fine or minetest.get_perlin(43000, 3, 0.6, 1)
|
||||
perlin_vines_length = perlin_vines_length or minetest.get_perlin(435, 4, 0.6, 75)
|
||||
perlin_vines_upwards = perlin_vines_upwards or minetest.get_perlin(436, 3, 0.6, 10)
|
||||
perlin_vines_density = perlin_vines_density or minetest.get_perlin(436, 3, 0.6, 500)
|
||||
|
||||
-- Extra long vines in Jungle M
|
||||
local maxvinelength = 7
|
||||
if dense_vegetation then
|
||||
maxvinelength = 14
|
||||
end
|
||||
local treething
|
||||
for i=1, 4 do
|
||||
if i==1 then
|
||||
treething = jungletree
|
||||
elseif i == 2 then
|
||||
treething = jungleleaves
|
||||
elseif i == 3 then
|
||||
treething = oaktree
|
||||
elseif i == 4 then
|
||||
treething = oakleaves
|
||||
end
|
||||
|
||||
for n = 1, #treething do
|
||||
pos = treething[n]
|
||||
|
||||
treepos = table.copy(pos)
|
||||
|
||||
local dirs = {
|
||||
{x=1,y=0,z=0},
|
||||
{x=-1,y=0,z=0},
|
||||
{x=0,y=0,z=1},
|
||||
{x=0,y=0,z=-1},
|
||||
}
|
||||
|
||||
for d = 1, #dirs do
|
||||
local pos = vector.add(pos, dirs[d])
|
||||
local p_pos = area:index(pos.x, pos.y, pos.z)
|
||||
|
||||
local vine_threshold = math.max(0.33333, perlin_vines_density:get_2d(pos))
|
||||
if dense_vegetation then
|
||||
vine_threshold = vine_threshold * (2/3)
|
||||
end
|
||||
|
||||
if perlin_vines:get_2d(pos) > -1.0 and perlin_vines_fine:get_3d(pos) > vine_threshold and data[p_pos] == c_air then
|
||||
|
||||
local rdir = {}
|
||||
rdir.x = -dirs[d].x
|
||||
rdir.y = dirs[d].y
|
||||
rdir.z = -dirs[d].z
|
||||
local param2 = minetest.dir_to_wallmounted(rdir)
|
||||
|
||||
-- Determine growth direction
|
||||
local grow_upwards = false
|
||||
-- Only possible on the wood, not on the leaves
|
||||
if i == 1 then
|
||||
grow_upwards = perlin_vines_upwards:get_3d(pos) > 0.8
|
||||
end
|
||||
if grow_upwards then
|
||||
-- Grow vines up 1-4 nodes, even through jungleleaves.
|
||||
-- This may give climbing access all the way to the top of the tree :-)
|
||||
-- But this will be fairly rare.
|
||||
local length = math.ceil(math.abs(perlin_vines_length:get_3d(pos)) * 4)
|
||||
for l=0, length-1 do
|
||||
local t_pos = area:index(treepos.x, treepos.y, treepos.z)
|
||||
|
||||
if (data[p_pos] == c_air or data[p_pos] == c_jungleleaves or data[p_pos] == c_leaves) and mcl_core.supports_vines(minetest.get_name_from_content_id(data[t_pos])) then
|
||||
data[p_pos] = c_vine
|
||||
param2_data[p_pos] = param2
|
||||
lvm_used = true
|
||||
|
||||
else
|
||||
break
|
||||
end
|
||||
pos.y = pos.y + 1
|
||||
p_pos = area:index(pos.x, pos.y, pos.z)
|
||||
treepos.y = treepos.y + 1
|
||||
end
|
||||
else
|
||||
-- Grow vines down, length between 1 and maxvinelength
|
||||
local length = math.ceil(math.abs(perlin_vines_length:get_3d(pos)) * maxvinelength)
|
||||
for l=0, length-1 do
|
||||
if data[p_pos] == c_air then
|
||||
data[p_pos] = c_vine
|
||||
param2_data[p_pos] = param2
|
||||
lvm_used = true
|
||||
|
||||
else
|
||||
break
|
||||
end
|
||||
pos.y = pos.y - 1
|
||||
p_pos = area:index(pos.x, pos.y, pos.z)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
return lvm_used
|
||||
end
|
||||
|
||||
-- Generate mushrooms in caves manually.
|
||||
-- Minetest's API does not support decorations in caves yet. :-(
|
||||
local function generate_underground_mushrooms(minp, maxp, seed)
|
||||
|
@ -1604,8 +1381,8 @@ end
|
|||
-- Below the bedrock, generate air/void
|
||||
local function basic_safe(vm_context)
|
||||
local vm, data, emin, emax, area, minp, maxp, chunkseed, blockseed = vm_context.vm, vm_context.data, vm_context.emin, vm_context.emax, vm_context.area, vm_context.minp, vm_context.maxp, vm_context.chunkseed, vm_context.blockseed
|
||||
vm_context.data2 = vm_context.data2 or vm:get_param2_data(vm_context.lvm_param2_buffer)
|
||||
local data2 = vm_context.data2
|
||||
vm_context.param2_data = vm_context.param2_data or vm:get_param2_data(vm_context.lvm_param2_buffer)
|
||||
local param2_data = vm_context.param2_data
|
||||
|
||||
local lvm_used = false
|
||||
local pr = PseudoRandom(blockseed)
|
||||
|
@ -1649,14 +1426,9 @@ local function basic_safe(vm_context)
|
|||
end
|
||||
end
|
||||
|
||||
-- Clay, vines, cocoas
|
||||
-- lvm_used = generate_clay(minp, maxp, chunkseed, data, area, lvm_used)
|
||||
|
||||
vm_context.biomemap = vm_context.biomemap or minetest.get_mapgen_object("biomemap")
|
||||
local biomemap = vm_context.biomemap
|
||||
|
||||
lvm_used = generate_tree_decorations(minp, maxp, blockseed, data, data2, area, biomemap, lvm_used, pr)
|
||||
|
||||
----- Interactive block fixing section -----
|
||||
----- The section to perform basic block overrides of the core mapgen generated world. -----
|
||||
|
||||
|
@ -1714,8 +1486,8 @@ local function basic_safe(vm_context)
|
|||
if bn then
|
||||
local biome = minetest.registered_biomes[bn]
|
||||
if biome and biome._mcl_biome_type then
|
||||
data2[p_pos] = biome._mcl_palette_index
|
||||
lvm_used = true
|
||||
param2_data[p_pos] = biome._mcl_palette_index
|
||||
vm_context.write_param2 = true
|
||||
end
|
||||
end
|
||||
if data[p_pos] == c_dirt_with_grass_snow and p_pos_above and data[p_pos_above] ~= c_top_snow and data[p_pos_above] ~= c_snow_block then
|
||||
|
@ -1829,6 +1601,7 @@ mcl_mapgen.register_mapgen_block_lvm(basic_safe, 1)
|
|||
|
||||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
dofile(modpath .. "/clay.lua")
|
||||
dofile(modpath .. "/tree_decoration.lua")
|
||||
if minetest.get_modpath("mcl_structures") then
|
||||
dofile(modpath .. "/structures.lua")
|
||||
end
|
||||
|
|
|
@ -163,16 +163,9 @@ local function spawn_witch_hut(p, nn, pr, vm_context)
|
|||
vm_context.biomemap = minetest_get_mapgen_object('biomemap')
|
||||
biomemap = vm_context.biomemap
|
||||
end
|
||||
-- minetest.chat_send_all(minetest.serialize(biomemap))
|
||||
local swampland = minetest.get_biome_id("Swampland")
|
||||
local swampland_shore = minetest.get_biome_id("Swampland_shore")
|
||||
local bi = xz_to_biomemap_index(p.x, p.z, vm_context.minp, vm_context.maxp)
|
||||
if (biomemap[bi] == swampland) then
|
||||
minetest.chat_send_all('swampland')
|
||||
end
|
||||
if (biomemap[bi] == swampland_shore) then
|
||||
minetest.chat_send_all('swampland_shore')
|
||||
end
|
||||
-- if biomemap[bi] ~= swampland and biomemap[bi] ~= swampland_shore then return end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,251 @@
|
|||
-- Generate tree decorations in the bounding box. This adds:
|
||||
-- * Cocoa at jungle trees
|
||||
-- * Jungle tree vines
|
||||
-- * Oak vines in swamplands
|
||||
|
||||
local minetest_find_nodes_in_area = minetest.find_nodes_in_area
|
||||
local minetest_find_node_near = minetest.find_node_near
|
||||
local minetest_get_node_light = minetest.get_node_light
|
||||
local minetest_dir_to_facedir = minetest.dir_to_facedir
|
||||
local minetest_dir_to_wallmounted = minetest.dir_to_wallmounted
|
||||
local table_copy = table.copy
|
||||
local vector_subtract = vector.subtract
|
||||
local vector_add = vector.add
|
||||
local math_max = math.max
|
||||
local math_ceil = math.ceil
|
||||
local math_abs = math.abs
|
||||
|
||||
local c_air = minetest.CONTENT_AIR
|
||||
local c_cocoas
|
||||
local c_jungleleaves = minetest.get_content_id("mcl_core:jungleleaves")
|
||||
local c_leaves = minetest.get_content_id("mcl_core:leaves")
|
||||
local c_vine = minetest.get_content_id("mcl_core:vine")
|
||||
|
||||
if minetest.get_modpath("mcl_cocoas") then
|
||||
c_cocoas = {
|
||||
minetest.get_content_id("mcl_cocoas:cocoa_1"),
|
||||
minetest.get_content_id("mcl_cocoas:cocoa_2"),
|
||||
minetest.get_content_id("mcl_cocoas:cocoa_3"),
|
||||
}
|
||||
end
|
||||
|
||||
local swampland
|
||||
local swampland_shore
|
||||
local jungle
|
||||
local jungle_shore
|
||||
local jungle_m
|
||||
local jungle_m_shore
|
||||
local jungle_edge
|
||||
local jungle_edge_shore
|
||||
local jungle_edge_m
|
||||
local jungle_edge_m_shore
|
||||
|
||||
local perlin_vines, perlin_vines_fine, perlin_vines_upwards, perlin_vines_length, perlin_vines_density
|
||||
|
||||
local dirs = {
|
||||
{x = 1, y = 0, z = 0},
|
||||
{x = -1, y = 0, z = 0},
|
||||
{x = 0, y = 0, z = 1},
|
||||
{x = 0, y = 0, z = -1},
|
||||
}
|
||||
|
||||
local function generate_tree_decorations(vm_context)
|
||||
local maxp = vm_context.maxp
|
||||
if maxp.y < 0 then return end
|
||||
local minp = vm_context.minp
|
||||
|
||||
local data = vm_context.data
|
||||
vm_context.param2_data = vm_context.param2_data or vm_context.vm:get_param2_data(vm_context.lvm_param2_buffer)
|
||||
local param2_data = vm_context.param2_data
|
||||
local area = vm_context.area
|
||||
|
||||
local biomemap = vm_context.biomemap
|
||||
|
||||
local pr = PseudoRandom(vm_context.chunkseed)
|
||||
|
||||
local oaktree, oakleaves, jungletree, jungleleaves = {}, {}, {}, {}
|
||||
|
||||
-- Modifier for Jungle M biome: More vines and cocoas
|
||||
local dense_vegetation = false
|
||||
|
||||
if biomemap then
|
||||
swampland = swampland or minetest.get_biome_id("Swampland")
|
||||
swampland_shore = swampland_shore or minetest.get_biome_id("Swampland_shore")
|
||||
jungle = jungle or minetest.get_biome_id("Jungle")
|
||||
jungle_shore = jungle_shore or minetest.get_biome_id("Jungle_shore")
|
||||
jungle_m = jungle_m or minetest.get_biome_id("JungleM")
|
||||
jungle_m_shore = jungle_m_shore or minetest.get_biome_id("JungleM_shore")
|
||||
jungle_edge = jungle_edge or minetest.get_biome_id("JungleEdge")
|
||||
jungle_edge_shore = jungle_edge_shore or minetest.get_biome_id("JungleEdge_shore")
|
||||
jungle_edge_m = jungle_edge_m or minetest.get_biome_id("JungleEdgeM")
|
||||
jungle_edge_m_shore = jungle_edge_m_shore or minetest.get_biome_id("JungleEdgeM_shore")
|
||||
|
||||
-- Biome map available: Check if the required biome (jungle or swampland)
|
||||
-- is in this mapchunk. We are only interested in trees in the correct biome.
|
||||
-- The nodes are added if the correct biome is *anywhere* in the mapchunk.
|
||||
-- TODO: Strictly generate vines in the correct biomes only.
|
||||
local swamp_biome_found, jungle_biome_found = false, false
|
||||
for b=1, #biomemap do
|
||||
local id = biomemap[b]
|
||||
|
||||
if not swamp_biome_found and (id == swampland or id == swampland_shore) then
|
||||
oaktree = minetest_find_nodes_in_area(minp, maxp, {"mcl_core:tree"})
|
||||
oakleaves = minetest_find_nodes_in_area(minp, maxp, {"mcl_core:leaves"})
|
||||
swamp_biome_found = true
|
||||
end
|
||||
if not jungle_biome_found and (id == jungle or id == jungle_shore or id == jungle_m or id == jungle_m_shore or id == jungle_edge or id == jungle_edge_shore or id == jungle_edge_m or id == jungle_edge_m_shore) then
|
||||
jungletree = minetest_find_nodes_in_area(minp, maxp, {"mcl_core:jungletree"})
|
||||
jungleleaves = minetest_find_nodes_in_area(minp, maxp, {"mcl_core:jungleleaves"})
|
||||
jungle_biome_found = true
|
||||
end
|
||||
if not dense_vegetation and (id == jungle_m or id == jungle_m_shore) then
|
||||
dense_vegetation = true
|
||||
end
|
||||
if swamp_biome_found and jungle_biome_found and dense_vegetation then
|
||||
break
|
||||
end
|
||||
end
|
||||
else
|
||||
-- If there is no biome map, we just count all jungle things we can find.
|
||||
-- Oak vines will not be generated.
|
||||
jungletree = minetest_find_nodes_in_area(minp, maxp, {"mcl_core:jungletree"})
|
||||
jungleleaves = minetest_find_nodes_in_area(minp, maxp, {"mcl_core:jungleleaves"})
|
||||
end
|
||||
|
||||
local pos, treepos, dir
|
||||
|
||||
if c_cocoas then
|
||||
local cocoachance = 40
|
||||
if dense_vegetation then
|
||||
cocoachance = 32
|
||||
end
|
||||
|
||||
-- Pass 1: Generate cocoas at jungle trees
|
||||
for n = 1, #jungletree do
|
||||
|
||||
pos = table_copy(jungletree[n])
|
||||
treepos = table_copy(pos)
|
||||
|
||||
if minetest_find_node_near(pos, 1, {"mcl_core:jungleleaves"}) then
|
||||
|
||||
dir = pr:next(1, cocoachance)
|
||||
|
||||
if dir == 1 then
|
||||
pos.z = pos.z + 1
|
||||
elseif dir == 2 then
|
||||
pos.z = pos.z - 1
|
||||
elseif dir == 3 then
|
||||
pos.x = pos.x + 1
|
||||
elseif dir == 4 then
|
||||
pos.x = pos.x -1
|
||||
end
|
||||
|
||||
local p_pos = area:index(pos.x, pos.y, pos.z)
|
||||
local l = minetest_get_node_light(pos)
|
||||
|
||||
if dir < 5
|
||||
and data[p_pos] == c_air
|
||||
and l and l > 12 then
|
||||
local c = pr:next(1, 3)
|
||||
data[p_pos] = c_cocoas[c]
|
||||
vm_context.write = true
|
||||
param2_data[p_pos] = minetest_dir_to_facedir(vector_subtract(treepos, pos))
|
||||
vm_context.write_param2 = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Pass 2: Generate vines at jungle wood, jungle leaves in jungle and oak wood, oak leaves in swampland
|
||||
perlin_vines = perlin_vines or minetest.get_perlin(555, 4, 0.6, 500)
|
||||
perlin_vines_fine = perlin_vines_fine or minetest.get_perlin(43000, 3, 0.6, 1)
|
||||
perlin_vines_length = perlin_vines_length or minetest.get_perlin(435, 4, 0.6, 75)
|
||||
perlin_vines_upwards = perlin_vines_upwards or minetest.get_perlin(436, 3, 0.6, 10)
|
||||
perlin_vines_density = perlin_vines_density or minetest.get_perlin(436, 3, 0.6, 500)
|
||||
|
||||
-- Extra long vines in Jungle M
|
||||
local maxvinelength = 7
|
||||
if dense_vegetation then
|
||||
maxvinelength = 14
|
||||
end
|
||||
local treething
|
||||
for i=1, 4 do
|
||||
if i==1 then
|
||||
treething = jungletree
|
||||
elseif i == 2 then
|
||||
treething = jungleleaves
|
||||
elseif i == 3 then
|
||||
treething = oaktree
|
||||
elseif i == 4 then
|
||||
treething = oakleaves
|
||||
end
|
||||
|
||||
for n = 1, #treething do
|
||||
pos = treething[n]
|
||||
|
||||
treepos = table_copy(pos)
|
||||
|
||||
for d = 1, #dirs do
|
||||
local pos = vector_add(pos, dirs[d])
|
||||
local p_pos = area:index(pos.x, pos.y, pos.z)
|
||||
|
||||
local vine_threshold = math_max(0.33333, perlin_vines_density:get_2d(pos))
|
||||
if dense_vegetation then
|
||||
vine_threshold = vine_threshold * (2/3)
|
||||
end
|
||||
|
||||
if perlin_vines:get_2d(pos) > -1.0 and perlin_vines_fine:get_3d(pos) > vine_threshold and data[p_pos] == c_air then
|
||||
|
||||
local rdir = {}
|
||||
rdir.x = -dirs[d].x
|
||||
rdir.y = dirs[d].y
|
||||
rdir.z = -dirs[d].z
|
||||
local param2 = minetest_dir_to_wallmounted(rdir)
|
||||
|
||||
-- Determine growth direction
|
||||
local grow_upwards = false
|
||||
-- Only possible on the wood, not on the leaves
|
||||
if i == 1 then
|
||||
grow_upwards = perlin_vines_upwards:get_3d(pos) > 0.8
|
||||
end
|
||||
if grow_upwards then
|
||||
-- Grow vines up 1-4 nodes, even through jungleleaves.
|
||||
-- This may give climbing access all the way to the top of the tree :-)
|
||||
-- But this will be fairly rare.
|
||||
local length = math_ceil(math_abs(perlin_vines_length:get_3d(pos)) * 4)
|
||||
for l=0, length-1 do
|
||||
local t_pos = area:index(treepos.x, treepos.y, treepos.z)
|
||||
|
||||
if (data[p_pos] == c_air or data[p_pos] == c_jungleleaves or data[p_pos] == c_leaves) and mcl_core.supports_vines(minetest.get_name_from_content_id(data[t_pos])) then
|
||||
data[p_pos] = c_vine
|
||||
param2_data[p_pos] = param2
|
||||
vm_context.write = true
|
||||
else
|
||||
break
|
||||
end
|
||||
pos.y = pos.y + 1
|
||||
p_pos = area:index(pos.x, pos.y, pos.z)
|
||||
treepos.y = treepos.y + 1
|
||||
end
|
||||
else
|
||||
-- Grow vines down, length between 1 and maxvinelength
|
||||
local length = math_ceil(math_abs(perlin_vines_length:get_3d(pos)) * maxvinelength)
|
||||
for l=0, length-1 do
|
||||
if data[p_pos] == c_air then
|
||||
data[p_pos] = c_vine
|
||||
param2_data[p_pos] = param2
|
||||
vm_context.write = true
|
||||
else
|
||||
break
|
||||
end
|
||||
pos.y = pos.y - 1
|
||||
p_pos = area:index(pos.x, pos.y, pos.z)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
mcl_mapgen.register_on_generated(generate_tree_decorations, 0)
|
Loading…
Reference in New Issue