2023-08-01 15:04:38 +00:00
|
|
|
mcl_lush_caves = {}
|
2023-06-11 19:26:22 +00:00
|
|
|
local modname = minetest.get_current_modname()
|
|
|
|
local modpath = minetest.get_modpath(modname)
|
2023-11-30 11:57:36 +00:00
|
|
|
local S = minetest.get_translator(modname)
|
2023-06-11 19:26:22 +00:00
|
|
|
|
2023-08-07 14:51:25 +00:00
|
|
|
local PARTICLE_DISTANCE = 25
|
|
|
|
|
2023-06-11 19:26:22 +00:00
|
|
|
local adjacents = {
|
|
|
|
vector.new(1,0,0),
|
|
|
|
vector.new(-1,0,0),
|
|
|
|
vector.new(0,0,1),
|
|
|
|
vector.new(0,0,-1),
|
|
|
|
vector.new(0,-1,0)
|
|
|
|
}
|
2023-08-01 15:04:38 +00:00
|
|
|
|
2023-06-11 19:26:22 +00:00
|
|
|
local function vector_distance_xz(a, b)
|
|
|
|
return vector.distance(
|
|
|
|
{ x=a.x, y=0, z=a.z },
|
|
|
|
{ x=b.x, y=0, z=b.z }
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2023-08-01 15:04:38 +00:00
|
|
|
dofile(modpath.."/nodes.lua")
|
|
|
|
dofile(modpath.."/dripleaf.lua")
|
2023-06-11 19:26:22 +00:00
|
|
|
|
2023-08-07 14:51:25 +00:00
|
|
|
local spore_blossom_particlespawner = {
|
|
|
|
texture = "mcl_lush_caves_spore_blossom_particle.png",
|
|
|
|
amount = 32,
|
|
|
|
time = 25,
|
|
|
|
minvel = vector.zero(),
|
|
|
|
maxvel = vector.zero(),
|
|
|
|
minacc = vector.new(-0.2, -0.1, -0.2),
|
|
|
|
maxacc = vector.new(0.2, -0.3, 0.2),
|
|
|
|
minexptime = 1.5,
|
|
|
|
maxexptime = 8.5,
|
|
|
|
minsize = 0.1,
|
|
|
|
maxsize= 0.4,
|
|
|
|
glow = 4,
|
|
|
|
collisiondetection = true,
|
|
|
|
collision_removal = true,
|
|
|
|
}
|
|
|
|
|
|
|
|
minetest.register_abm({
|
|
|
|
label = "Spore Blossom Particles",
|
|
|
|
nodenames = {"mcl_lush_caves:spore_blossom"},
|
|
|
|
interval = 25,
|
|
|
|
chance = 10,
|
|
|
|
action = function(pos, node)
|
|
|
|
if minetest.get_node(vector.offset(pos, 0, -1, 0)).name ~= "air" then return end
|
|
|
|
for _,pl in pairs(minetest.get_connected_players()) do
|
|
|
|
if vector.distance(pos,pl:get_pos()) < PARTICLE_DISTANCE then
|
|
|
|
minetest.add_particlespawner(table.merge(spore_blossom_particlespawner, {
|
|
|
|
minpos = vector.offset(pos, -0.25, -0.5, -0.25),
|
|
|
|
maxpos = vector.offset(pos, 0.25, -0.5, 0.25),
|
|
|
|
playername = pl:get_player_name(),
|
|
|
|
}))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
})
|
|
|
|
|
2023-06-11 19:26:22 +00:00
|
|
|
function mcl_lush_caves.makelake(pos,def,pr)
|
2023-08-02 13:36:30 +00:00
|
|
|
local p1 = vector.offset(pos,-8,-4,-8)
|
|
|
|
local p2 = vector.offset(pos,8,4,8)
|
|
|
|
local nn = minetest.find_nodes_in_area_under_air(p1,p2,{"group:solid"})
|
2023-06-11 19:26:22 +00:00
|
|
|
table.sort(nn,function(a, b)
|
|
|
|
return vector_distance_xz(pos, a) < vector_distance_xz(pos, b)
|
|
|
|
end)
|
|
|
|
if not nn[1] then return end
|
|
|
|
local dripleaves = {}
|
|
|
|
for i=1,pr:next(1,#nn) do
|
|
|
|
minetest.set_node(nn[i],{name="mcl_core:water_source"})
|
|
|
|
if pr:next(1,20) == 1 then
|
|
|
|
table.insert(dripleaves,nn[i])
|
|
|
|
end
|
|
|
|
end
|
2023-08-02 13:36:30 +00:00
|
|
|
local nnn = minetest.find_nodes_in_area(p1,p2,{"mcl_core:water_source"})
|
2023-06-11 19:26:22 +00:00
|
|
|
for k,v in pairs(nnn) do
|
|
|
|
for kk,vv in pairs(adjacents) do
|
|
|
|
local pp = vector.add(v,vv)
|
|
|
|
local an = minetest.get_node(pp)
|
|
|
|
if an.name ~= "mcl_core:water_source" then
|
|
|
|
minetest.set_node(pp,{name="mcl_core:clay"})
|
|
|
|
if pr:next(1,20) == 1 then
|
|
|
|
minetest.set_node(vector.offset(pp,0,1,0),{name="mcl_lush_caves:moss_carpet"})
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
for _,d in pairs(dripleaves) do
|
|
|
|
if minetest.get_item_group(minetest.get_node(d).name,"water") > 0 then
|
|
|
|
minetest.set_node(vector.offset(d,0,-1,0),{name="mcl_lush_caves:dripleaf_big_waterroot"})
|
|
|
|
minetest.registered_nodes["mcl_lush_caves:dripleaf_big_stem"].on_construct(d)
|
|
|
|
for ii = 1, pr:next(1,4) do
|
2023-08-01 15:04:38 +00:00
|
|
|
mcl_lush_caves.dripleaf_grow(d,{name = "mcl_lush_caves:dripleaf_big_stem"})
|
2023-06-11 19:26:22 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2023-12-07 14:26:15 +00:00
|
|
|
local function set_of_content_ids_by_group(group)
|
|
|
|
local result = {}
|
|
|
|
for name, def in pairs(minetest.registered_nodes) do
|
|
|
|
if def.groups[group] then
|
|
|
|
result[minetest.get_content_id(name)] = true
|
2023-06-11 19:26:22 +00:00
|
|
|
end
|
|
|
|
end
|
2023-12-07 14:26:15 +00:00
|
|
|
return result
|
|
|
|
end
|
|
|
|
|
|
|
|
local CONVERTS_TO_ROOTED_DIRT = set_of_content_ids_by_group("material_stone")
|
|
|
|
CONVERTS_TO_ROOTED_DIRT[minetest.get_content_id("mcl_core:dirt")] = true
|
|
|
|
CONVERTS_TO_ROOTED_DIRT[minetest.get_content_id("mcl_core:coarse_dirt")] = true
|
|
|
|
local CONTENT_HANGING_ROOTS = minetest.get_content_id("mcl_lush_caves:hanging_roots")
|
|
|
|
local CONTENT_ROOTED_DIRT = minetest.get_content_id("mcl_lush_caves:rooted_dirt")
|
|
|
|
|
|
|
|
local function squared_average(a, b)
|
|
|
|
local s = a + b
|
|
|
|
return s*s/4
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Azalea tree voxel manipulator buffer
|
|
|
|
local data = {}
|
|
|
|
|
|
|
|
function mcl_lush_caves.makeazalea(pos, def, pr)
|
|
|
|
local distance = {x = 4, y = 40, z = 4}
|
|
|
|
local airup = minetest.find_nodes_in_area_under_air(vector.offset(pos, 0, distance.y, 0), pos, {"mcl_core:dirt_with_grass"})
|
|
|
|
if #airup == 0 then return end
|
|
|
|
local surface_pos = airup[1]
|
|
|
|
|
|
|
|
local function squared_distance(x, z)
|
|
|
|
local dx = x - pos.x
|
|
|
|
local dz = z - pos.z
|
|
|
|
return dx*dx + dz*dz
|
|
|
|
end
|
|
|
|
|
|
|
|
local maximum_random_value = squared_average(distance.x, distance.z) + 1
|
|
|
|
|
|
|
|
local min = vector.offset(pos, -distance.x, -1, -distance.z)
|
|
|
|
local max = vector.offset(pos, distance.x, distance.y, distance.z)
|
|
|
|
|
|
|
|
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
|
|
|
vm:get_data(data)
|
|
|
|
|
|
|
|
local a = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
|
|
|
|
|
|
|
local vi, below
|
|
|
|
for z = min.z, max.z do
|
|
|
|
for y = min.y + 1, surface_pos.y - 1 do
|
|
|
|
for x = min.x, max.x do
|
|
|
|
vi = a:index(x, y, z)
|
|
|
|
local probability_value = maximum_random_value - squared_distance(x, z)
|
|
|
|
if CONVERTS_TO_ROOTED_DIRT[data[vi]] and pr:next(1, maximum_random_value) <= probability_value then
|
|
|
|
data[vi] = CONTENT_ROOTED_DIRT
|
|
|
|
below = a:index(x, y - 1, z)
|
|
|
|
if data[below] == minetest.CONTENT_AIR then
|
|
|
|
data[below] = CONTENT_HANGING_ROOTS
|
|
|
|
end
|
|
|
|
end
|
2023-06-11 19:26:22 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2023-12-07 14:26:15 +00:00
|
|
|
data[a:index(surface_pos.x, surface_pos.y, surface_pos.z)] = CONTENT_ROOTED_DIRT
|
|
|
|
vm:set_data(data)
|
|
|
|
minetest.place_schematic_on_vmanip(vm,
|
|
|
|
vector.offset(surface_pos, -3, 1, -3),
|
|
|
|
modpath.."/schematics/azalea1.mts",
|
|
|
|
"random",nil,nil,
|
|
|
|
"place_center_x place_center_z"
|
|
|
|
)
|
|
|
|
vm:calc_lighting()
|
|
|
|
vm:write_to_map()
|
2023-06-11 19:26:22 +00:00
|
|
|
minetest.log("action","[mcl_lush_caves] Azalea generated at "..minetest.pos_to_string(surface_pos))
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local lushcaves = { "LushCaves", "LushCaves_underground", "LushCaves_ocean", "LushCaves_deep_ocean"}
|
|
|
|
minetest.register_abm({
|
|
|
|
label = "Cave vines grow",
|
|
|
|
nodenames = {"mcl_lush_caves:cave_vines_lit","mcl_lush_caves:cave_vines"},
|
|
|
|
interval = 180,
|
|
|
|
chance = 5,
|
|
|
|
action = function(pos, node, active_object_count, active_object_count_wider)
|
|
|
|
local pu = vector.offset(pos,0,1,0)
|
|
|
|
local pun = minetest.get_node(pu).name
|
|
|
|
local pd = vector.offset(pos,0,-1,0)
|
|
|
|
local pd2 = minetest.get_node(vector.offset(pos,0,-2,0)).name
|
|
|
|
if pun ~= "mcl_lush_caves:cave_vines_lit" and pun ~= "mcl_lush_caves:cave_vines" and pun ~= "mcl_lush_caves:moss" then
|
|
|
|
minetest.set_node(pos,{name="air"})
|
|
|
|
return
|
|
|
|
end
|
|
|
|
node.name = "mcl_lush_caves:cave_vines"
|
|
|
|
if math.random(5) == 1 then
|
|
|
|
node.name="mcl_lush_caves:cave_vines_lit"
|
|
|
|
end
|
|
|
|
if minetest.get_node(pd).name == "air" and pd2 == "air" then
|
|
|
|
minetest.swap_node(pd,node)
|
|
|
|
else
|
|
|
|
minetest.swap_node(pos,{name="mcl_lush_caves:cave_vines_lit"})
|
|
|
|
end
|
|
|
|
end
|
|
|
|
})
|
|
|
|
|
2023-08-01 15:04:38 +00:00
|
|
|
|
2023-06-11 19:26:22 +00:00
|
|
|
|
|
|
|
mcl_structures.register_structure("clay_pool",{
|
|
|
|
place_on = {"group:material_stone","mcl_core:gravel","mcl_lush_caves:moss","mcl_core:clay"},
|
|
|
|
spawn_by = {"air"},
|
|
|
|
num_spawn_by = 1,
|
2023-08-02 13:36:30 +00:00
|
|
|
fill_ratio = 0.01,
|
2023-08-07 14:07:36 +00:00
|
|
|
terrain_feature = true,
|
2023-06-11 19:26:22 +00:00
|
|
|
flags = "all_floors",
|
|
|
|
y_max = -10,
|
|
|
|
biomes = lushcaves,
|
|
|
|
place_func = mcl_lush_caves.makelake,
|
|
|
|
})
|
|
|
|
|
|
|
|
local azaleas = {}
|
|
|
|
local az_limit = 500
|
|
|
|
mcl_structures.register_structure("azalea_tree",{
|
|
|
|
place_on = {"group:material_stone","mcl_core:gravel","mcl_lush_caves:moss","mcl_core:clay"},
|
|
|
|
spawn_by = {"air"},
|
|
|
|
num_spawn_by = 1,
|
|
|
|
fill_ratio = 0.15,
|
|
|
|
flags = "all_ceilings",
|
|
|
|
terrain_feature = true,
|
|
|
|
y_max =0,
|
|
|
|
y_min = mcl_vars.mg_overworld_min + 15,
|
|
|
|
biomes = lushcaves,
|
|
|
|
place_func = function(pos,def,pr)
|
|
|
|
for _,a in pairs(azaleas) do
|
|
|
|
if vector.distance(pos,a) < az_limit then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if mcl_lush_caves.makeazalea(pos,def,pr) then
|
|
|
|
table.insert(azaleas,pos)
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
})
|
|
|
|
--[[
|
|
|
|
minetest.set_gen_notify({cave_begin = true})
|
|
|
|
minetest.set_gen_notify({large_cave_begin = true})
|
|
|
|
|
|
|
|
mcl_mapgen_core.register_generator("lush_caves",nil, function(minp, maxp, blockseed)
|
|
|
|
local gennotify = minetest.get_mapgen_object("gennotify")
|
|
|
|
for _, pos in pairs(gennotify["large_cave_begin"] or {}) do
|
|
|
|
--minetest.log("large cave at "..minetest.pos_to_string(pos))
|
|
|
|
end
|
|
|
|
for _, pos in pairs(gennotify["cave_begin"] or {}) do
|
|
|
|
minetest.log("cave at "..minetest.pos_to_string(pos))
|
|
|
|
end
|
|
|
|
end, 99999, true)
|
|
|
|
--]]
|
2023-11-29 11:21:39 +00:00
|
|
|
|
|
|
|
minetest.register_craft({
|
|
|
|
type = "fuel",
|
|
|
|
recipe = "mcl_lush_caves:azalea",
|
|
|
|
burntime = 5,
|
|
|
|
})
|
|
|
|
|
|
|
|
minetest.register_craft({
|
|
|
|
type = "fuel",
|
|
|
|
recipe = "mcl_lush_caves:azalea_flowering",
|
|
|
|
burntime = 5,
|
|
|
|
})
|
2023-11-30 11:57:36 +00:00
|
|
|
|
|
|
|
mcl_flowerpots.register_potted_flower("mcl_lush_caves:azalea", {
|
|
|
|
name = "azalea",
|
|
|
|
desc = S("Azalea Plant"),
|
|
|
|
image = "mcl_lush_caves_azalea_side.png",
|
|
|
|
})
|
|
|
|
|
|
|
|
mcl_flowerpots.register_potted_flower("mcl_lush_caves:azalea_flowering", {
|
|
|
|
name = "azalea_flowering",
|
|
|
|
desc = S("Flowering Azalea Plant"),
|
|
|
|
image = "mcl_lush_caves_azalea_flowering_side.png",
|
|
|
|
})
|