Merge pull request 'Grand mapgen cleanup Part 1' (#2355) from mapgen_fixes into master

Reviewed-on: https://git.minetest.land/MineClone2/MineClone2/pulls/2355
Reviewed-by: MysticTempest <mystictempest@noreply.git.minetest.land>
This commit is contained in:
cora 2022-07-01 17:13:18 +00:00
commit cea6af267f
36 changed files with 1298 additions and 863 deletions

View file

@ -2594,7 +2594,16 @@ local function register_decorations()
deco_type = "simple", deco_type = "simple",
place_on = {"group:sand","mcl_core:gravel"}, place_on = {"group:sand","mcl_core:gravel"},
sidelen = 16, sidelen = 16,
noise_params = noise, noise_params = {
offset = -0.0085,
scale = 0.002,
spread = {x = 25, y = 120, z = 25},
seed = 235,
octaves = 5,
persist = 1.8,
lacunarity = 3.5,
flags = "absvalue"
},
y_min = OCEAN_MIN, y_min = OCEAN_MIN,
y_max = -5, y_max = -5,
decoration = "mcl_ocean:dead_brain_coral_block", decoration = "mcl_ocean:dead_brain_coral_block",
@ -3356,6 +3365,29 @@ local function register_decorations()
rotation = "0", rotation = "0",
}) })
--Mushrooms in caves
minetest.register_decoration({
deco_type = "simple",
place_on = {"group:material_stone"},
sidelen = 80,
fill_ratio = 0.009,
noise_threshold = 2.0,
flags = "all_floors",
y_min = mcl_vars.mg_overworld_min,
y_max = mcl_vars.mg_overworld_max,
decoration = "mcl_mushrooms:mushroom_red",
})
minetest.register_decoration({
deco_type = "simple",
place_on = {"group:material_stone"},
sidelen = 80,
fill_ratio = 0.009,
noise_threshold = 2.0,
y_min = mcl_vars.mg_overworld_min,
y_max = mcl_vars.mg_overworld_max,
decoration = "mcl_mushrooms:mushroom_brown",
})
-- Mossy cobblestone boulder (3×3) -- Mossy cobblestone boulder (3×3)
minetest.register_decoration({ minetest.register_decoration({
deco_type = "schematic", deco_type = "schematic",
@ -3374,6 +3406,7 @@ local function register_decorations()
y_max = mcl_vars.mg_overworld_max, y_max = mcl_vars.mg_overworld_max,
schematic = mod_mcl_structures.."/schematics/mcl_structures_boulder.mts", schematic = mod_mcl_structures.."/schematics/mcl_structures_boulder.mts",
flags = "place_center_x, place_center_z", flags = "place_center_x, place_center_z",
rotation = "random",
}) })
-- Small mossy cobblestone boulder (2×2) -- Small mossy cobblestone boulder (2×2)
@ -3394,6 +3427,7 @@ local function register_decorations()
y_max = mcl_vars.mg_overworld_max, y_max = mcl_vars.mg_overworld_max,
schematic = mod_mcl_structures.."/schematics/mcl_structures_boulder_small.mts", schematic = mod_mcl_structures.."/schematics/mcl_structures_boulder_small.mts",
flags = "place_center_x, place_center_z", flags = "place_center_x, place_center_z",
rotation = "random",
}) })
-- Cacti -- Cacti
@ -4551,6 +4585,72 @@ local function register_dimension_decorations()
size = {x = 5, y = 8, z = 5}, size = {x = 5, y = 8, z = 5},
rotation = "random", rotation = "random",
}) })
--BASALT DELTA
minetest.register_decoration({
deco_type = "simple",
decoration = "mcl_blackstone:basalt",
place_on = {"mcl_blackstone:basalt","mcl_nether:netherrack","mcl_blackstone:blackstone"},
sidelen = 80,
height_max = 55,
noise_params={
offset = -0.0085,
scale = 0.002,
spread = {x = 25, y = 120, z = 25},
seed = 2325,
octaves = 5,
persist = 2,
lacunarity = 3.5,
flags = "absvalue"
},
biomes = {"BasaltDelta"},
y_min = mcl_vars.mg_lava_nether_max + 1,
flags = "all_floors, all ceilings",
})
minetest.register_decoration({
deco_type = "simple",
decoration = "mcl_blackstone:basalt",
place_on = {"mcl_blackstone:basalt","mcl_nether:netherrack","mcl_blackstone:blackstone"},
sidelen = 80,
height_max = 15,
noise_params={
offset = -0.0085,
scale = 0.004,
spread = {x = 25, y = 120, z = 25},
seed = 235,
octaves = 5,
persist = 2.5,
lacunarity = 3.5,
flags = "absvalue"
},
biomes = {"BasaltDelta"},
y_min = mcl_vars.mg_lava_nether_max + 1,
flags = "all_floors, all ceilings",
})
minetest.register_decoration({
deco_type = "simple",
decoration = "mcl_nether:magma",
place_on = {"mcl_blackstone:basalt","mcl_nether:netherrack","mcl_blackstone:blackstone"},
sidelen = 80,
fill_ratio = 0.082323,
biomes = {"BasaltDelta"},
place_offset_y = -1,
y_min = mcl_vars.mg_lava_nether_max + 1,
flags = "all_floors, all ceilings",
})
minetest.register_decoration({
deco_type = "simple",
decoration = "mcl_nether:nether_lava_source",
place_on = {"mcl_blackstone:basalt","mcl_nether:netherrack","mcl_blackstone:blackstone"},
spawn_by = {"mcl_blackstone:basalt","mcl_blackstone:blackstone"},
num_spawn_by = 14,
sidelen = 80,
fill_ratio = 4,
biomes = {"BasaltDelta"},
place_offset_y = -1,
y_min = mcl_vars.mg_lava_nether_max + 1,
y_max = mcl_vars.mg_nether_max - 5,
flags = "all_floors, force_placement",
})
--[[ THE END ]] --[[ THE END ]]

View file

@ -1,86 +0,0 @@
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),
vector.new(0,-1,0)
}
local function set_node_no_bedrock(pos,node)
local n = minetest.get_node(pos)
if n.name == "mcl_core:bedrock" then return end
return minetest.set_node(pos,node)
end
local function makegeode(pos,pr)
local size = pr:next(4,7)
local p1 = vector.offset(pos,-size,-size,-size)
local p2 = vector.offset(pos,size,size,size)
local calcite = {}
local nn = minetest.find_nodes_in_area(p1,p2,{"group:material_stone"})
table.sort(nn,function(a, b)
return vector.distance(pos, a) < vector.distance(pos, b)
end)
if not nn[1] then return end
for i=1,math.random(#nn) do
set_node_no_bedrock(nn[i],{name="mcl_amethyst:amethyst_block"})
end
for k,v in pairs(minetest.find_nodes_in_area(p1,p2,{"mcl_amethyst:amethyst_block"})) do
local all_amethyst = true
for kk,vv in pairs(adjacents) do
local pp = vector.add(v,vv)
local an = minetest.get_node(pp)
if an.name ~= "mcl_amethyst:amethyst_block" then
if minetest.get_item_group(an.name,"material_stone") > 0 then
set_node_no_bedrock(pp,{name="mcl_amethyst:calcite"})
table.insert(calcite,pp)
if pr:next(1,5) == 1 then
set_node_no_bedrock(v,{name="mcl_amethyst:budding_amethyst_block"})
end
all_amethyst = false
elseif an.name ~= "mcl_amethyst:amethyst_block" and an.name ~= "air" then
all_amethyst = false
end
end
end
if all_amethyst then set_node_no_bedrock(v,{name="air"}) end
end
for _,v in pairs(calcite) do
for _,vv in pairs(minetest.find_nodes_in_area(vector.offset(v,-1,-1,-1),vector.offset(v,1,1,1),{"group:material_stone"})) do
set_node_no_bedrock(vv,{name="mcl_blackstone:basalt_smooth"})
end
end
for k,v in pairs(minetest.find_nodes_in_area_under_air(p1,p2,{"mcl_amethyst:amethyst_block","mcl_amethyst:budding_amethyst_block"})) do
local r = pr:next(1,50)
if r < 10 then
set_node_no_bedrock(vector.offset(v,0,1,0),{name="mcl_amethyst:amethyst_cluster",param2=1})
end
end
return true
end
mcl_structures.register_structure("geode",{
place_on = {"mcl_core:stone"},
noise_params = {
offset = 0,
scale = 0.00022,
spread = {x = 250, y = 250, z = 250},
seed = 7894353,
octaves = 3,
persist = 0.001,
flags = "absvalue",
},
flags = "place_center_x, place_center_z, force_placement",
y_max = -24,
y_min = mcl_vars.mg_overworld_min,
y_offset = function(pr) return pr:next(-4,-2) end,
place_func = function(pos,def,pr)
local p = vector.new(pos.x + pr:next(-30,30),pos.y,pos.z + pr:next(-30,30))
return makegeode(p,pr)
end
})

View file

@ -1,3 +0,0 @@
name = mcl_geodes
author = cora
depends = mcl_init, mcl_structures

View file

@ -1262,12 +1262,10 @@ end
-- TODO: Try to use more efficient structure generating code -- TODO: Try to use more efficient structure generating code
local function generate_structures(minp, maxp, blockseed, biomemap) local function generate_structures(minp, maxp, blockseed, biomemap)
local chunk_has_desert_well = false
local chunk_has_desert_temple = false
local chunk_has_igloo = false local chunk_has_igloo = false
local struct_min, struct_max = -3, 111 --64 local struct_min, struct_max = -3, 111 --64
--except end exit portall all v6
if maxp.y >= struct_min and minp.y <= struct_max then if mg_name == "v6" and maxp.y >= struct_min and minp.y <= struct_max then
-- Generate structures -- Generate structures
local pr = PcgRandom(blockseed) local pr = PcgRandom(blockseed)
perlin_structures = perlin_structures or minetest.get_perlin(329, 3, 0.6, 100) perlin_structures = perlin_structures or minetest.get_perlin(329, 3, 0.6, 100)
@ -1301,32 +1299,8 @@ local function generate_structures(minp, maxp, blockseed, biomemap)
local nn0 = minetest.get_node(p).name local nn0 = minetest.get_node(p).name
-- Check if the node can be replaced -- Check if the node can be replaced
if minetest.registered_nodes[nn0] and minetest.registered_nodes[nn0].buildable_to then if minetest.registered_nodes[nn0] and minetest.registered_nodes[nn0].buildable_to then
-- Desert temples and desert wells
if nn == "mcl_core:sand" or (nn == "mcl_core:sandstone") then
if not chunk_has_desert_temple and not chunk_has_desert_well and ground_y > 3 then
-- Spawn desert temple
-- TODO: Check surface
if pr:next(1,12000) == 1 then
mcl_structures.call_struct(p, "desert_temple", nil, pr)
chunk_has_desert_temple = true
end
end
if not chunk_has_desert_temple and not chunk_has_desert_well and ground_y > 3 then
local desert_well_prob = minecraft_chunk_probability(1000, minp, maxp)
-- Spawn desert well
if pr:next(1, desert_well_prob) == 1 then
-- Check surface
local surface = minetest.find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, {x=p.x+5, y=p.y-1, z=p.z+5}, "mcl_core:sand")
if #surface >= 25 then
mcl_structures.call_struct(p, "desert_well", nil, pr)
chunk_has_desert_well = true
end
end
end
-- Igloos -- Igloos
elseif not chunk_has_igloo and (nn == "mcl_core:snowblock" or nn == "mcl_core:snow" or (minetest.get_item_group(nn, "grass_block_snow") == 1)) then if not chunk_has_igloo and (nn == "mcl_core:snowblock" or nn == "mcl_core:snow" or (minetest.get_item_group(nn, "grass_block_snow") == 1)) then
if pr:next(1, 4400) == 1 then if pr:next(1, 4400) == 1 then
-- Check surface -- Check surface
local floor = {x=p.x+9, y=p.y-1, z=p.z+9} local floor = {x=p.x+9, y=p.y-1, z=p.z+9}
@ -1357,7 +1331,7 @@ local function generate_structures(minp, maxp, blockseed, biomemap)
end end
end end
-- Witch hut -- Witch hut (v6)
if ground_y <= 0 and nn == "mcl_core:dirt" then if ground_y <= 0 and nn == "mcl_core:dirt" then
local prob = minecraft_chunk_probability(48, minp, maxp) local prob = minecraft_chunk_probability(48, minp, maxp)
if pr:next(1, prob) == 1 then if pr:next(1, prob) == 1 then
@ -1365,23 +1339,14 @@ local function generate_structures(minp, maxp, blockseed, biomemap)
local swampland = minetest.get_biome_id("Swampland") local swampland = minetest.get_biome_id("Swampland")
local swampland_shore = minetest.get_biome_id("Swampland_shore") local swampland_shore = minetest.get_biome_id("Swampland_shore")
-- Where do witches live? -- Where do witches live?
-- v6: In Normal biome
local here_be_witches = false if biomeinfo.get_v6_biome(p) == "Normal" then
if mg_name == "v6" then here_be_witches = true
-- v6: In Normal biome
if biomeinfo.get_v6_biome(p) == "Normal" then
here_be_witches = true
end
else
-- Other mapgens: In swampland biome
local bi = xz_to_biomemap_index(p.x, p.z, minp, maxp)
if biomemap[bi] == swampland or biomemap[bi] == swampland_shore then
here_be_witches = true
end
end end
local here_be_witches = false
if here_be_witches then if here_be_witches then
local r = tostring(pr:next(0, 3) * 90) -- "0", "90", "180" or 270" local r = tostring(pr:next(0, 3) * 90) -- "0", "90", "180" or 270"
local p1 = {x=p.x-1, y=WITCH_HUT_HEIGHT+2, z=p.z-1} local p1 = {x=p.x-1, y=WITCH_HUT_HEIGHT+2, z=p.z-1}
local size local size
@ -1401,9 +1366,7 @@ local function generate_structures(minp, maxp, blockseed, biomemap)
-- FIXME: For some mysterious reason (black magic?) this -- FIXME: For some mysterious reason (black magic?) this
-- function does sometimes NOT spawn the witch hut. One can only see the -- function does sometimes NOT spawn the witch hut. One can only see the
-- oak wood nodes in the water, but no hut. :-/ -- oak wood nodes in the water, but no hut. :-/
mcl_structures.call_struct(place, "witch_hut", r, pr) mcl_structures.place_structure(place,mcl_structures.registered_structures["witch_hut"],pr)
-- TODO: Spawn witch in or around hut when the mob sucks less.
local function place_tree_if_free(pos, prev_result) local function place_tree_if_free(pos, prev_result)
local nn = minetest.get_node(pos).name local nn = minetest.get_node(pos).name
@ -1462,7 +1425,7 @@ local function generate_structures(minp, maxp, blockseed, biomemap)
-- Ice spikes in v6 -- Ice spikes in v6
-- In other mapgens, ice spikes are generated as decorations. -- In other mapgens, ice spikes are generated as decorations.
if mg_name == "v6" and not chunk_has_igloo and nn == "mcl_core:snowblock" then if nn == "mcl_core:snowblock" then
local spike = pr:next(1,58000) local spike = pr:next(1,58000)
if spike < 3 then if spike < 3 then
-- Check surface -- Check surface
@ -1472,7 +1435,7 @@ local function generate_structures(minp, maxp, blockseed, biomemap)
local spruce_collisions = minetest.find_nodes_in_area({x=p.x+1,y=p.y+2,z=p.z+1}, {x=p.x+4, y=p.y+6, z=p.z+4}, {"mcl_core:sprucetree", "mcl_core:spruceleaves"}) local spruce_collisions = minetest.find_nodes_in_area({x=p.x+1,y=p.y+2,z=p.z+1}, {x=p.x+4, y=p.y+6, z=p.z+4}, {"mcl_core:sprucetree", "mcl_core:spruceleaves"})
if #surface >= 9 and #spruce_collisions == 0 then if #surface >= 9 and #spruce_collisions == 0 then
mcl_structures.call_struct(p, "ice_spike_large", nil, pr) mcl_structures.place_structure(p,mcl_structures.registered_structures["ice_spike_large"],pr)
end end
elseif spike < 100 then elseif spike < 100 then
-- Check surface -- Check surface
@ -1483,7 +1446,7 @@ local function generate_structures(minp, maxp, blockseed, biomemap)
local spruce_collisions = minetest.find_nodes_in_area({x=p.x+1,y=p.y+1,z=p.z+1}, {x=p.x+6, y=p.y+6, z=p.z+6}, {"mcl_core:sprucetree", "mcl_core:spruceleaves"}) local spruce_collisions = minetest.find_nodes_in_area({x=p.x+1,y=p.y+1,z=p.z+1}, {x=p.x+6, y=p.y+6, z=p.z+6}, {"mcl_core:sprucetree", "mcl_core:spruceleaves"})
if #surface >= 25 and #spruce_collisions == 0 then if #surface >= 25 and #spruce_collisions == 0 then
mcl_structures.call_struct(p, "ice_spike_small", nil, pr) mcl_structures.place_structure(p,mcl_structures.registered_structures["ice_spike_small"],pr)
end end
end end
end end
@ -1720,7 +1683,7 @@ local function generate_tree_decorations(minp, maxp, seed, data, param2_data, ar
end end
-- Generate mushrooms in caves manually. -- Generate mushrooms in caves manually.
-- Minetest's API does not support decorations in caves yet. :-( -- only v6. minetest supports cave decos via "all_floors" flag now
local function generate_underground_mushrooms(minp, maxp, seed) local function generate_underground_mushrooms(minp, maxp, seed)
local pr_shroom = PseudoRandom(seed-24359) local pr_shroom = PseudoRandom(seed-24359)
-- Generate rare underground mushrooms -- Generate rare underground mushrooms
@ -1747,76 +1710,69 @@ local function generate_underground_mushrooms(minp, maxp, seed)
end end
end end
local nether_wart_chance
if mg_name == "v6" then
nether_wart_chance = 85
else
nether_wart_chance = 170
end
-- Generate Nether decorations manually: Eternal fire, mushrooms, nether wart -- Generate Nether decorations manually: Eternal fire, mushrooms, nether wart
-- (only v6) -- (only v6)
local nether_wart_chance = 85
local function generate_nether_decorations(minp, maxp, seed) local function generate_nether_decorations(minp, maxp, seed)
if mg_name == "v6" then local pr_nether = PseudoRandom(seed+667)
local pr_nether = PseudoRandom(seed+667)
if minp.y > mcl_vars.mg_nether_max or maxp.y < mcl_vars.mg_nether_min then if minp.y > mcl_vars.mg_nether_max or maxp.y < mcl_vars.mg_nether_min then
return return
end
minetest.log("action", "[mcl_mapgen_core] Nether decorations " .. minetest.pos_to_string(minp) .. " ... " .. minetest.pos_to_string(maxp))
-- TODO: Generate everything based on Perlin noise instead of PseudoRandom
local bpos
local rack = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:netherrack"})
local magma = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:magma"})
local ssand = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:soul_sand"})
-- Helper function to spawn “fake” decoration
local function special_deco(nodes, spawn_func)
for n = 1, #nodes do
bpos = {x = nodes[n].x, y = nodes[n].y + 1, z = nodes[n].z }
spawn_func(bpos)
end
end
-- Eternal fire on netherrack
special_deco(rack, function(bpos)
-- Eternal fire on netherrack
if pr_nether:next(1,100) <= 3 then
minetest.set_node(bpos, {name = "mcl_fire:eternal_fire"})
end
end)
-- Eternal fire on magma cubes
special_deco(magma, function(bpos)
if pr_nether:next(1,150) == 1 then
minetest.set_node(bpos, {name = "mcl_fire:eternal_fire"})
end
end)
-- Mushrooms on netherrack
-- Note: Spawned *after* the fire because of light level checks
special_deco(rack, function(bpos)
local l = minetest.get_node_light(bpos, 0.5)
if bpos.y > mcl_vars.mg_lava_nether_max + 6 and l and l <= 12 and pr_nether:next(1,1000) <= 4 then
-- TODO: Make mushrooms appear in groups, use Perlin noise
if pr_nether:next(1,2) == 1 then
minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_brown"})
else
minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_red"})
end
end
end)
-- Nether wart on soul sand
-- TODO: Spawn in Nether fortresses
special_deco(ssand, function(bpos)
if pr_nether:next(1, nether_wart_chance) == 1 then
minetest.set_node(bpos, {name = "mcl_nether:nether_wart"})
end
end)
end end
minetest.log("action", "[mcl_mapgen_core] Nether decorations " .. minetest.pos_to_string(minp) .. " ... " .. minetest.pos_to_string(maxp))
-- TODO: Generate everything based on Perlin noise instead of PseudoRandom
local bpos
local rack = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:netherrack"})
local magma = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:magma"})
local ssand = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:soul_sand"})
-- Helper function to spawn “fake” decoration
local function special_deco(nodes, spawn_func)
for n = 1, #nodes do
bpos = {x = nodes[n].x, y = nodes[n].y + 1, z = nodes[n].z }
spawn_func(bpos)
end
end
-- Eternal fire on netherrack
special_deco(rack, function(bpos)
-- Eternal fire on netherrack
if pr_nether:next(1,100) <= 3 then
minetest.set_node(bpos, {name = "mcl_fire:eternal_fire"})
end
end)
-- Eternal fire on magma cubes
special_deco(magma, function(bpos)
if pr_nether:next(1,150) == 1 then
minetest.set_node(bpos, {name = "mcl_fire:eternal_fire"})
end
end)
-- Mushrooms on netherrack
-- Note: Spawned *after* the fire because of light level checks
special_deco(rack, function(bpos)
local l = minetest.get_node_light(bpos, 0.5)
if bpos.y > mcl_vars.mg_lava_nether_max + 6 and l and l <= 12 and pr_nether:next(1,1000) <= 4 then
-- TODO: Make mushrooms appear in groups, use Perlin noise
if pr_nether:next(1,2) == 1 then
minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_brown"})
else
minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_red"})
end
end
end)
-- Nether wart on soul sand
-- TODO: Spawn in Nether fortresses
special_deco(ssand, function(bpos)
if pr_nether:next(1, nether_wart_chance) == 1 then
minetest.set_node(bpos, {name = "mcl_nether:nether_wart"})
end
end)
end end
minetest.register_on_generated(function(minp, maxp, blockseed) minetest.register_on_generated(function(minp, maxp, blockseed)
@ -2200,10 +2156,33 @@ end
local function basic_node(minp, maxp, blockseed) local function basic_node(minp, maxp, blockseed)
if mg_name ~= "singlenode" then if mg_name ~= "singlenode" then
-- Generate special decorations -- Generate special decorations
generate_underground_mushrooms(minp, maxp, blockseed) if mg_name == "v6" then
generate_nether_decorations(minp, maxp, blockseed) generate_underground_mushrooms(minp, maxp, blockseed)
generate_nether_decorations(minp, maxp, blockseed)
end
generate_structures(minp, maxp, blockseed, minetest.get_mapgen_object("biomemap")) generate_structures(minp, maxp, blockseed, minetest.get_mapgen_object("biomemap"))
end end
end end
mcl_mapgen_core.register_generator("main", basic, basic_node, 1, true) mcl_mapgen_core.register_generator("main", basic, basic_node, 1, true)
mcl_mapgen_core.register_generator("structures",nil, function(minp, maxp, blockseed)
local gennotify = minetest.get_mapgen_object("gennotify")
local pr = PseudoRandom(blockseed + 42)
local has_struct = {}
local poshash = minetest.hash_node_position(minp)
for _,struct in pairs(mcl_structures.registered_structures) do
if struct.deco_id then
local has = false
if has_struct[struct.name] == nil then has_struct[struct.name] = {} end
for _, pos in pairs(gennotify["decoration#"..struct.deco_id] or {}) do
local realpos = vector.offset(pos,0,1,0)
minetest.remove_node(realpos)
if struct.chunk_probability == nil or (not has and pr:next(1,struct.chunk_probability) == 1 ) then
mcl_structures.place_structure(realpos,struct,pr)
has=true
end
end
end
end
end, 100, true)

View file

@ -14,17 +14,10 @@ mcl_structures.register_structure("nether_outpost",{
}, },
flags = "all_floors", flags = "all_floors",
biomes = {"Nether","SoulsandValley","WarpedForest","CrimsonForest","BasaltDelta"}, biomes = {"Nether","SoulsandValley","WarpedForest","CrimsonForest","BasaltDelta"},
on_place = function(pos,def,pr) sidelen = 15,
local sidelen = 15 solid_ground = true,
local node = minetest.get_node(vector.offset(pos,1,1,0)) make_foundation = true,
local solid = minetest.find_nodes_in_area(vector.offset(pos,-sidelen/2,-1,-sidelen/2),vector.offset(pos,sidelen/2,-1,sidelen/2),{"group:solid"}) y_min = mcl_vars.mg_lava_nether_max - 1,
local air = minetest.find_nodes_in_area(vector.offset(pos,-sidelen/2,1,-sidelen/2),vector.offset(pos,sidelen/2,4,sidelen/2),{"air"})
if #solid < ( sidelen * sidelen ) or
#air < (sidelen * sidelen ) then return false end
minetest.bulk_set_node(solid,node)
return true
end,
y_min = mcl_vars.mg_lava_nether_max,
y_max = mcl_vars.mg_nether_max - 30, y_max = mcl_vars.mg_nether_max - 30,
filenames = { modpath.."/schematics/nether_outpost.mts" }, filenames = { modpath.."/schematics/nether_outpost.mts" },
y_offset = 0, y_offset = 0,

View file

@ -1,179 +0,0 @@
local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
--local S = minetest.get_translator(modname)
local seed = minetest.get_mapgen_setting("seed")
local water_level = minetest.get_mapgen_setting("water_level")
local pr = PseudoRandom(seed)
--schematics by chmodsayshello
local schems = {
modpath.."/schematics/".."shipwreck_full_damaged"..".mts",
modpath.."/schematics/".."shipwreck_full_normal"..".mts",
modpath.."/schematics/".."shipwreck_full_back_damaged"..".mts",
modpath.."/schematics/".."shipwreck_half_front"..".mts",
modpath.."/schematics/".."shipwreck_half_back"..".mts",
}
local function get_supply_loot()
return {
stacks_min = 3,
stacks_max = 10,
items = {
--{ itemstring = "TODO:sus_stew", weight = 10, amount_min = 1, amount_max = 1 },
{ itemstring = "mcl_core:paper", weight = 8, amount_min = 1, amount_max = 12 },
{ itemstring = "mcl_farming:wheat_item", weight = 7, amount_min = 8, amount_max = 21 },
{ itemstring = "mcl_farming:carrot_item", weight = 7, amount_min = 4, amount_max = 8 },
{ itemstring = "mcl_farming:potato_item_poison", weight = 7, amount_min = 2, amount_max = 6 },
{ itemstring = "mcl_farming:potato_item", weight = 7, amount_min = 2, amount_max = 6 },
--{ itemstring = "TODO:moss_block", weight = 7, amount_min = 1, amount_max = 4 },
{ itemstring = "mcl_core:coal_lump", weight = 6, amount_min = 2, amount_max = 8 },
{ itemstring = "mcl_mobitems:rotten_flesh", weight = 5, amount_min = 5, amount_max = 24 },
{ itemstring = "mcl_farming:potato_item", weight = 3, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_armor:helmet_leather_enchanted", weight = 3, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end },
{ itemstring = "mcl_armor:chestplate_leather_enchanted", weight = 3, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end },
{ itemstring = "mcl_armor:leggings_leather_enchanted", weight = 3, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end },
{ itemstring = "mcl_armor:boots_leather_enchanted", weight = 3, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end },
--{ itemstring = "TODO:bamboo", weight = 2, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_farming:pumpkin", weight = 2, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_tnt:tnt", weight = 1, amount_min = 1, amount_max = 2 },
}
}
end
local function get_treasure_loot()
return {
stacks_min = 3,
stacks_max = 10,
items = {
{ itemstring = "mcl_core:iron_ingot", weight = 8, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_core:iron_nugget", weight = 8, amount_min = 1, amount_max = 10 },
{ itemstring = "mcl_core:emerald", weight = 8, amount_min = 1, amount_max = 12 },
{ itemstring = "mcl_dye:blue", weight = 8, amount_min = 1, amount_max = 12 },
{ itemstring = "mcl_core:gold_ingot", weight = 8, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_core:gold_nugget", weight = 8, amount_min = 1, amount_max = 10 },
{ itemstring = "mcl_experience:bottle", weight = 8, amount_min = 1, amount_max = 10 },
{ itemstring = "mcl_core:diamond", weight = 8, amount_min = 1, amount_max = 10 },
}
}
end
local function fill_chests(p1,p2)
for _,p in pairs(minetest.find_nodes_in_area(p1,p2,{"mcl_chests:chest_small"})) do
if minetest.get_meta(p):get_string("infotext") ~= "Chest" then
minetest.registered_nodes["mcl_chests:chest_small"].on_construct(p)
end
local inv = minetest.get_inventory( {type="node", pos=p} )
local loot = get_supply_loot()
if pr:next(1,10) == 1 then loot = get_treasure_loot() end
mcl_loot.fill_inventory(inv, "main", mcl_loot.get_multi_loot({loot}, pr), pr)
end
end
local ocean_biomes = {
"RoofedForest_ocean",
"JungleEdgeM_ocean",
"BirchForestM_ocean",
"BirchForest_ocean",
"IcePlains_deep_ocean",
"Jungle_deep_ocean",
"Savanna_ocean",
"MesaPlateauF_ocean",
"ExtremeHillsM_deep_ocean",
"Savanna_deep_ocean",
"SunflowerPlains_ocean",
"Swampland_deep_ocean",
"Swampland_ocean",
"MegaSpruceTaiga_deep_ocean",
"ExtremeHillsM_ocean",
"JungleEdgeM_deep_ocean",
"SunflowerPlains_deep_ocean",
"BirchForest_deep_ocean",
"IcePlainsSpikes_ocean",
"Mesa_ocean",
"StoneBeach_ocean",
"Plains_deep_ocean",
"JungleEdge_deep_ocean",
"SavannaM_deep_ocean",
"Desert_deep_ocean",
"Mesa_deep_ocean",
"ColdTaiga_deep_ocean",
"Plains_ocean",
"MesaPlateauFM_ocean",
"Forest_deep_ocean",
"JungleM_deep_ocean",
"FlowerForest_deep_ocean",
"MushroomIsland_ocean",
"MegaTaiga_ocean",
"StoneBeach_deep_ocean",
"IcePlainsSpikes_deep_ocean",
"ColdTaiga_ocean",
"SavannaM_ocean",
"MesaPlateauF_deep_ocean",
"MesaBryce_deep_ocean",
"ExtremeHills+_deep_ocean",
"ExtremeHills_ocean",
"MushroomIsland_deep_ocean",
"Forest_ocean",
"MegaTaiga_deep_ocean",
"JungleEdge_ocean",
"MesaBryce_ocean",
"MegaSpruceTaiga_ocean",
"ExtremeHills+_ocean",
"Jungle_ocean",
"RoofedForest_deep_ocean",
"IcePlains_ocean",
"FlowerForest_ocean",
"ExtremeHills_deep_ocean",
"MesaPlateauFM_deep_ocean",
"Desert_ocean",
"Taiga_ocean",
"BirchForestM_deep_ocean",
"Taiga_deep_ocean",
"JungleM_ocean"
}
local beach_biomes = {
"FlowerForest_beach",
"Forest_beach",
"StoneBeach",
"ColdTaiga_beach_water",
"Taiga_beach",
"Savanna_beach",
"Plains_beach",
"ExtremeHills_beach",
"ColdTaiga_beach",
"Swampland_shore",
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore"
}
mcl_structures.register_structure("shipwreck",{
place_on = {"group:sand","mcl_core:gravel"},
spawn_by = {"group:water"},
num_spawn_by = 4,
noise_params = {
offset = 0,
scale = 0.000022,
spread = {x = 250, y = 250, z = 250},
seed = 3,
octaves = 3,
persist = 0.001,
flags = "absvalue",
},
flags = "force_placement",
biomes = ocean_biomes,
y_max = water_level-4,
y_min = mcl_vars.mg_overworld_min,
filenames = schems,
y_offset = function(pr) return pr:next(-4,-2) end,
after_place = function(pos)
fill_chests(vector.offset(pos,-20,-5,-20),vector.offset(pos,20,15,20))
end
})

View file

@ -1,3 +0,0 @@
name = mcl_shipwrecks
author = cora
depends = mcl_loot, mcl_structures, mcl_enchanting

View file

@ -12,13 +12,22 @@ If nospawn is truthy the structure will not be placed by mapgen and the decorati
y_max =, y_max =,
place_on = {}, place_on = {},
spawn_by = {}, spawn_by = {},
num_spawn_by = num_spawn_by =,
flags = (default: "place_center_x, place_center_z, force_placement") flags = (default: "place_center_x, place_center_z, force_placement")
(same as decoration def) (same as decoration def)
y_offset =, --can be a number or a function returning a number y_offset =, --can be a number or a function returning a number
filenames = {} OR place_func = function(pos,def,pr) filenames = {} OR place_func = function(pos,def,pr)
-- filenames can be a list of any schematics accepted by mcl_structures.place_schematic / minetest.place_schematic -- filenames can be a list of any schematics accepted by mcl_structures.place_schematic / minetest.place_schematic
on_place = function(pos,def,pr) end,
-- called before placement. denies placement when returning falsy.
after_place = function(pos,def,pr) after_place = function(pos,def,pr)
-- executed after successful placement
sidelen = int, --length of one side of the structure. used for foundations.
solid_ground = bool, -- structure requires solid ground
make_foundation = bool, -- a foundation is automatically built for the structure. needs the sidelen param
loot = ,
--a table of loot tables for mcl_loot indexed by node names
-- e.g. { ["mcl_chests:chest_small"] = {loot},... }
} }
## mcl_structures.registered_structures ## mcl_structures.registered_structures
Table of the registered structure defintions indexed by name. Table of the registered structure defintions indexed by name.

View file

@ -1,30 +1,122 @@
mcl_structures.registered_structures = {} mcl_structures.registered_structures = {}
function mcl_structures.fill_chests(p1,p2,loot,pr)
for it,lt in pairs(loot) do
local nodes = minetest.find_nodes_in_area(p1, p2, it)
for _,p in pairs(nodes) do
local lootitems = mcl_loot.get_multi_loot(lt, pr)
mcl_structures.init_node_construct(p)
local meta = minetest.get_meta(p)
local inv = meta:get_inventory()
mcl_loot.fill_inventory(inv, "main", lootitems, pr)
end
end
end
local function generate_loot(pos, def, pr)
local hl = def.sidelen / 2
local p1 = vector.offset(pos,-hl,-hl,-hl)
local p2 = vector.offset(pos,hl,hl,hl)
if def.loot then mcl_structures.fill_chests(p1,p2,def.loot,pr) end
end
function mcl_structures.find_lowest_y(pp)
local y = 31000
for _,p in pairs(pp) do
if p.y < y then y = p.y end
end
return y
end
function mcl_structures.find_highest_y(pp)
local y = -31000
for _,p in pairs(pp) do
if p.y > y then y = p.y end
end
return y
end
function mcl_structures.place_structure(pos, def, pr) function mcl_structures.place_structure(pos, def, pr)
if not def then return end if not def then return end
local logging = not def.terrain_feature
local y_offset = 0 local y_offset = 0
if type(def.y_offset) == "function" then if type(def.y_offset) == "function" then
y_offset = def.y_offset(pr) y_offset = def.y_offset(pr)
elseif def.y_offset then elseif def.y_offset then
y_offset = def.y_offset y_offset = def.y_offset
end end
local pp = vector.offset(pos,0,y_offset,0)
if def.solid_ground and def.sidelen then
local ground_p1 = vector.offset(pos,-def.sidelen/2,-1,-def.sidelen/2)
local ground_p2 = vector.offset(pos,def.sidelen/2,-1,def.sidelen/2)
local solid = minetest.find_nodes_in_area(ground_p1,ground_p2,{"group:solid"})
if #solid < ( def.sidelen * def.sidelen ) then
if def.make_foundation then
local node_stone = "mcl_core:stone"
local node_filler = "mcl_core:dirt"
local node_top = "mcl_core:dirt_with_grass" or minetest.get_node(ground_p1).name
local node_dust = nil
if minetest.get_mapgen_setting("mg_name") ~= "v6" then
local b = minetest.registered_biomes[minetest.get_biome_name(minetest.get_biome_data(pos).biome)]
--minetest.log(dump(b.node_top))
if b.node_top then node_top = b.node_top end
if b.node_filler then node_filler = b.node_filler end
if b.node_stone then node_stone = b.node_stone end
if b.node_dust then node_dust = b.node_dust end
end
local replace = {"air","group:liquid","mcl_core:snow","group:tree","group:leaves"}
minetest.bulk_set_node(minetest.find_nodes_in_area(ground_p1,ground_p2,replace),{name=node_top})
if node_dust then
minetest.bulk_set_node(minetest.find_nodes_in_area(vector.offset(ground_p1,0,1,0),vector.offset(ground_p2,0,1,0),{"air"}),{name=node_dust})
end
minetest.bulk_set_node(minetest.find_nodes_in_area(vector.offset(ground_p1,0,-1,0),vector.offset(ground_p2,0,-4,0),replace),{name=node_filler})
minetest.bulk_set_node(minetest.find_nodes_in_area(vector.offset(ground_p1,0,-5,0),vector.offset(ground_p2,0,-30,0),replace),{name=node_stone})
else
if logging then
minetest.log("warning","[mcl_structures] "..def.name.." at "..minetest.pos_to_string(pp).." not placed. No solid ground.")
end
return false
end
end
end
if def.on_place and not def.on_place(pos,def,pr) then if def.on_place and not def.on_place(pos,def,pr) then
minetest.log("warning","[mcl_structures] "..def.name.." at "..minetest.pos_to_string(pos).." not placed. Conditions not satisfied.") if logging then
minetest.log("warning","[mcl_structures] "..def.name.." at "..minetest.pos_to_string(pp).." not placed. Conditions not satisfied.")
end
return false return false
end end
if def.filenames then if def.filenames then
local file = def.filenames[pr:next(1,#def.filenames)] if #def.filenames <= 0 then return false end
local pp = vector.offset(pos,0,y_offset,0) local r = pr:next(1,#def.filenames)
mcl_structures.place_schematic(pp, file, "random", nil, true, "place_center_x,place_center_z",def.after_place,pr,{pos,def}) local file = def.filenames[r]
minetest.log("action","[mcl_structures] "..def.name.." placed at "..minetest.pos_to_string(pos)) if file then
return true local ap = function(pos,def,pr) end
if def.after_place then ap = def.after_place end
mcl_structures.place_schematic(pp, file, "random", nil, true, "place_center_x,place_center_z",function(p)
if def.loot then generate_loot(pos,def,pr) end
return ap(pos,def,pr)
end,pr)
if logging then
minetest.log("action","[mcl_structures] "..def.name.." placed at "..minetest.pos_to_string(pp))
end
return true
end
elseif def.place_func and def.place_func(pos,def,pr) then elseif def.place_func and def.place_func(pos,def,pr) then
if not def.after_place or ( def.after_place and def.after_place(pos,def,pr) ) then if not def.after_place or ( def.after_place and def.after_place(pos,def,pr) ) then
minetest.log("action","[mcl_structures] "..def.name.." placed at "..minetest.pos_to_string(pos)) if logging then
minetest.log("action","[mcl_structures] "..def.name.." placed at "..minetest.pos_to_string(pp))
end
return true return true
end end
end end
minetest.log("warning","[mcl_structures] placing "..def.name.." failed at "..minetest.pos_to_string(pos)) if logging then
minetest.log("warning","[mcl_structures] placing "..def.name.." failed at "..minetest.pos_to_string(pos))
end
end end
function mcl_structures.register_structure(name,def,nospawn) --nospawn means it will be placed by another (non-nospawn) structure that contains it's structblock i.e. it will not be placed by mapgen directly function mcl_structures.register_structure(name,def,nospawn) --nospawn means it will be placed by another (non-nospawn) structure that contains it's structblock i.e. it will not be placed by mapgen directly
@ -38,35 +130,29 @@ function mcl_structures.register_structure(name,def,nospawn) --nospawn means it
sbgroups.structblock = nil sbgroups.structblock = nil
sbgroups.structblock_lbm = 1 sbgroups.structblock_lbm = 1
else else
def.deco = minetest.register_decoration({ minetest.register_on_mods_loaded(function() --make sure all previous decorations and biomes have been registered
name = "mcl_structures:deco_"..name, def.deco = minetest.register_decoration({
decoration = structblock, name = "mcl_structures:deco_"..name,
deco_type = "simple", decoration = structblock,
place_on = def.place_on, deco_type = "simple",
spawn_by = def.spawn_by, place_on = def.place_on,
num_spawn_by = def.num_spawn_by, spawn_by = def.spawn_by,
sidelen = 80, num_spawn_by = def.num_spawn_by,
fill_ratio = def.fill_ratio, sidelen = 80,
noise_params = def.noise_params, fill_ratio = def.fill_ratio,
flags = flags, noise_params = def.noise_params,
biomes = def.biomes, flags = flags,
y_max = def.y_max, biomes = def.biomes,
y_min = def.y_min y_max = def.y_max,
}) y_min = def.y_min
local deco_id = minetest.get_decoration_id("mcl_structures:deco_"..name) })
minetest.set_gen_notify({decoration=true}, { deco_id }) minetest.register_node(":"..structblock, {drawtype="airlike", walkable = false, pointable = false,groups = sbgroups})
minetest.register_on_generated(function(minp, maxp, blockseed) def.structblock = structblock
local gennotify = minetest.get_mapgen_object("gennotify") def.deco_id = minetest.get_decoration_id("mcl_structures:deco_"..name)
local pr = PseudoRandom(blockseed + 42) minetest.set_gen_notify({decoration=true}, { def.deco_id })
for _, pos in pairs(gennotify["decoration#"..deco_id] or {}) do --catching of gennotify happens in mcl_mapgen_core
local realpos = vector.offset(pos,0,-1,0)
minetest.remove_node(realpos)
mcl_structures.place_structure(realpos,def,pr)
end
end) end)
end end
minetest.register_node(":"..structblock, {drawtype="airlike", walkable = false, pointable = false,groups = sbgroups})
def.structblock = structblock
mcl_structures.registered_structures[name] = def mcl_structures.registered_structures[name] = def
end end
@ -76,10 +162,10 @@ minetest.register_lbm({
run_at_every_load = true, run_at_every_load = true,
nodenames = {"group:structblock_lbm"}, nodenames = {"group:structblock_lbm"},
action = function(pos, node) action = function(pos, node)
minetest.remove_node(pos)
local name = node.name:gsub("mcl_structures:structblock_","") local name = node.name:gsub("mcl_structures:structblock_","")
local def = mcl_structures.registered_structures[name] local def = mcl_structures.registered_structures[name]
if not def then return end if not def then return end
minetest.remove_node(pos)
mcl_structures.place_structure(pos) mcl_structures.place_structure(pos)
end end
}) })

View file

@ -0,0 +1,86 @@
local modname = minetest.get_current_modname()
local S = minetest.get_translator(modname)
local modpath = minetest.get_modpath(modname)
local function temple_placement_callback(pos,def, pr)
local hl = def.sidelen / 2
local p1 = vector.offset(pos,-hl,-hl,-hl)
local p2 = vector.offset(pos,hl,hl,hl)
-- Delete cacti leftovers:
local cactus_nodes = minetest.find_nodes_in_area_under_air(p1, p2, "mcl_core:cactus")
if cactus_nodes and #cactus_nodes > 0 then
for _, pos in pairs(cactus_nodes) do
local node_below = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z})
if node_below and node_below.name == "mcl_core:sandstone" then
minetest.swap_node(pos, {name="air"})
end
end
end
-- Initialize pressure plates and randomly remove up to 5 plates
local pplates = minetest.find_nodes_in_area(p1, p2, "mesecons_pressureplates:pressure_plate_stone_off")
local pplates_remove = 5
for p=1, #pplates do
if pplates_remove > 0 and pr:next(1, 100) >= 50 then
-- Remove plate
minetest.remove_node(pplates[p])
pplates_remove = pplates_remove - 1
else
-- Initialize plate
minetest.registered_nodes["mesecons_pressureplates:pressure_plate_stone_off"].on_construct(pplates[p])
end
end
end
mcl_structures.register_structure("desert_temple",{
place_on = {"group:sand"},
fill_ratio = 0.01,
flags = "place_center_x, place_center_z",
solid_ground = true,
make_foundation = true,
sidelen = 18,
y_offset = -12,
chunk_probability = 300,
y_max = mcl_vars.mg_overworld_max,
y_min = 1,
biomes = { "Desert" },
filenames = { modpath.."/schematics/mcl_structures_desert_temple.mts" },
after_place = temple_placement_callback,
loot = {
["mcl_chests:chest" ] ={
{
stacks_min = 2,
stacks_max = 4,
items = {
{ itemstring = "mcl_mobitems:bone", weight = 25, amount_min = 4, amount_max=6 },
{ itemstring = "mcl_mobitems:rotten_flesh", weight = 25, amount_min = 3, amount_max=7 },
{ itemstring = "mcl_mobitems:spider_eye", weight = 25, amount_min = 1, amount_max=3 },
{ itemstring = "mcl_books:book", weight = 20, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr)
end },
{ itemstring = "mcl_mobitems:saddle", weight = 20, },
{ itemstring = "mcl_core:apple_gold", weight = 20, },
{ itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 },
{ itemstring = "mcl_core:iron_ingot", weight = 15, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_core:emerald", weight = 15, amount_min = 1, amount_max = 3 },
{ itemstring = "", weight = 15, },
{ itemstring = "mcl_mobitems:iron_horse_armor", weight = 15, },
{ itemstring = "mcl_mobitems:gold_horse_armor", weight = 10, },
{ itemstring = "mcl_mobitems:diamond_horse_armor", weight = 5, },
{ itemstring = "mcl_core:diamond", weight = 5, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_core:apple_gold_enchanted", weight = 2, },
}
},
{
stacks_min = 4,
stacks_max = 4,
items = {
{ itemstring = "mcl_mobitems:bone", weight = 10, amount_min = 1, amount_max = 8 },
{ itemstring = "mcl_mobitems:rotten_flesh", weight = 10, amount_min = 1, amount_max = 8 },
{ itemstring = "mcl_mobitems:gunpowder", weight = 10, amount_min = 1, amount_max = 8 },
{ itemstring = "mcl_core:sand", weight = 10, amount_min = 1, amount_max = 8 },
{ itemstring = "mcl_mobitems:string", weight = 10, amount_min = 1, amount_max = 8 },
}
}}
}
})

View file

@ -0,0 +1,88 @@
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),
vector.new(0,-1,0)
}
local function set_node_no_bedrock(pos,node)
local n = minetest.get_node(pos)
if n.name == "mcl_core:bedrock" then return end
return minetest.set_node(pos,node)
end
local function makegeode(pos,def,pr)
local size = pr:next(5,7)
local p1 = vector.offset(pos,-size,-size,-size)
local p2 = vector.offset(pos,size,size,size)
minetest.emerge_area(p1, p2, function(blockpos, action, calls_remaining, param)
if calls_remaining ~= 0 then return end
local calcite = {}
local nn = minetest.find_nodes_in_area(p1,p2,{"group:material_stone"})
table.sort(nn,function(a, b)
return vector.distance(pos, a) < vector.distance(pos, b)
end)
if not nn[1] then return end
for i=1,math.random(#nn) do
set_node_no_bedrock(nn[i],{name="mcl_amethyst:amethyst_block"})
end
for k,v in pairs(minetest.find_nodes_in_area(p1,p2,{"mcl_amethyst:amethyst_block"})) do
local all_amethyst = true
for kk,vv in pairs(adjacents) do
local pp = vector.add(v,vv)
local an = minetest.get_node(pp)
if an.name ~= "mcl_amethyst:amethyst_block" then
if minetest.get_item_group(an.name,"material_stone") > 0 then
set_node_no_bedrock(pp,{name="mcl_amethyst:calcite"})
table.insert(calcite,pp)
if pr:next(1,5) == 1 then
set_node_no_bedrock(v,{name="mcl_amethyst:budding_amethyst_block"})
end
all_amethyst = false
elseif an.name ~= "mcl_amethyst:amethyst_block" and an.name ~= "air" then
all_amethyst = false
end
end
end
if all_amethyst then set_node_no_bedrock(v,{name="air"}) end
end
for _,v in pairs(calcite) do
for _,vv in pairs(minetest.find_nodes_in_area(vector.offset(v,-1,-1,-1),vector.offset(v,1,1,1),{"group:material_stone"})) do
set_node_no_bedrock(vv,{name="mcl_blackstone:basalt_smooth"})
end
end
for k,v in pairs(minetest.find_nodes_in_area_under_air(p1,p2,{"mcl_amethyst:amethyst_block","mcl_amethyst:budding_amethyst_block"})) do
local r = pr:next(1,50)
if r < 10 then
set_node_no_bedrock(vector.offset(v,0,1,0),{name="mcl_amethyst:amethyst_cluster",param2=1})
end
end
return true
end)
return true
end
mcl_structures.register_structure("geode",{
place_on = {"group:material_stone"},
noise_params = {
offset = 0,
scale = 0.00022,
spread = {x = 250, y = 250, z = 250},
seed = 7894353,
octaves = 3,
persist = 0.001,
flags = "absvalue",
},
flags = "force_placement",
terrain_feature = true,
y_max = -24,
y_min = mcl_vars.mg_overworld_min,
y_offset = function(pr) return pr:next(-4,-2) end,
place_func = makegeode,
})

View file

@ -0,0 +1,163 @@
local modname = minetest.get_current_modname()
local S = minetest.get_translator(modname)
local modpath = minetest.get_modpath(modname)
function mcl_structures.generate_igloo_top(pos, pr)
-- FIXME: This spawns bookshelf instead of furnace. Fix this!
-- Furnace does ot work atm because apparently meta is not set. :-(
local newpos = {x=pos.x,y=pos.y-2,z=pos.z}
local path = modpath.."/schematics/mcl_structures_igloo_top.mts"
local rotation = tostring(pr:next(0,3)*90)
return mcl_structures.place_schematic(newpos, path, rotation, nil, true), rotation
end
function mcl_structures.generate_igloo_basement(pos, orientation, loot, pr)
-- TODO: Add brewing stand
-- TODO: Add monster eggs
local path = modpath.."/schematics/mcl_structures_igloo_basement.mts"
mcl_structures.place_schematic(pos, path, orientation, nil, true, nil, function()
local p1 = vector.offset(pos,-5,-5,-5)
local p2 = vector.offset(pos,5,5,5)
mcl_structures.fill_chests(p1,p2,loot,pr)
local mc = minetest.find_nodes_in_area_under_air(p1,p2,{"mcl_core:stonebrickmossy"})
if #mc == 2 then
table.shuffle(mc)
minetest.add_entity(vector.offset(mc[1],0,1,0),"mobs_mc:villager")
minetest.add_entity(vector.offset(mc[2],0,1,0),"mobs_mc:villager_zombie")
end
end, pr)
end
function mcl_structures.generate_igloo(pos, def, pr)
-- Place igloo
local success, rotation = mcl_structures.generate_igloo_top(pos, pr)
-- Place igloo basement with 50% chance
local r = pr:next(1,2)
if r == 1 then
-- Select basement depth
local dim = mcl_worlds.pos_to_dimension(pos)
--local buffer = pos.y - (mcl_vars.mg_lava_overworld_max + 10)
local buffer
if dim == "nether" then
buffer = pos.y - (mcl_vars.mg_lava_nether_max + 10)
elseif dim == "end" then
buffer = pos.y - (mcl_vars.mg_end_min + 1)
elseif dim == "overworld" then
buffer = pos.y - (mcl_vars.mg_lava_overworld_max + 10)
else
return success
end
if buffer <= 19 then
return success
end
local depth = pr:next(19, buffer)
local bpos = {x=pos.x, y=pos.y-depth, z=pos.z}
-- trapdoor position
local tpos
local dir, tdir
if rotation == "0" then
dir = {x=-1, y=0, z=0}
tdir = {x=1, y=0, z=0}
tpos = {x=pos.x+7, y=pos.y-1, z=pos.z+3}
elseif rotation == "90" then
dir = {x=0, y=0, z=-1}
tdir = {x=0, y=0, z=-1}
tpos = {x=pos.x+3, y=pos.y-1, z=pos.z+1}
elseif rotation == "180" then
dir = {x=1, y=0, z=0}
tdir = {x=-1, y=0, z=0}
tpos = {x=pos.x+1, y=pos.y-1, z=pos.z+3}
elseif rotation == "270" then
dir = {x=0, y=0, z=1}
tdir = {x=0, y=0, z=1}
tpos = {x=pos.x+3, y=pos.y-1, z=pos.z+7}
else
return success
end
local function set_brick(pos)
local c = pr:next(1, 3) -- cracked chance
local m = pr:next(1, 10) -- chance for monster egg
local brick
if m == 1 then
if c == 1 then
brick = "mcl_monster_eggs:monster_egg_stonebrickcracked"
else
brick = "mcl_monster_eggs:monster_egg_stonebrick"
end
else
if c == 1 then
brick = "mcl_core:stonebrickcracked"
else
brick = "mcl_core:stonebrick"
end
end
minetest.set_node(pos, {name=brick})
end
local ladder_param2 = minetest.dir_to_wallmounted(tdir)
local real_depth = 0
-- Check how deep we can actuall dig
for y=1, depth-5 do
real_depth = real_depth + 1
local node = minetest.get_node({x=tpos.x,y=tpos.y-y,z=tpos.z})
local def = minetest.registered_nodes[node.name]
if not (def and def.walkable and def.liquidtype == "none" and def.is_ground_content) then
bpos.y = tpos.y-y+1
break
end
end
if real_depth <= 6 then
return success
end
-- Generate ladder to basement
for y=1, real_depth-1 do
set_brick({x=tpos.x-1,y=tpos.y-y,z=tpos.z })
set_brick({x=tpos.x+1,y=tpos.y-y,z=tpos.z })
set_brick({x=tpos.x ,y=tpos.y-y,z=tpos.z-1})
set_brick({x=tpos.x ,y=tpos.y-y,z=tpos.z+1})
minetest.set_node({x=tpos.x,y=tpos.y-y,z=tpos.z}, {name="mcl_core:ladder", param2=ladder_param2})
end
-- Place basement
mcl_structures.generate_igloo_basement(bpos, rotation, def.loot, pr)
-- Place hidden trapdoor
minetest.after(5, function(tpos, dir)
minetest.set_node(tpos, {name="mcl_doors:trapdoor", param2=20+minetest.dir_to_facedir(dir)}) -- TODO: more reliable param2
end, tpos, dir)
end
return success
end
mcl_structures.register_structure("igloo",{
place_on = {"mcl_core:snowblock","mcl_core:snow","group:grass_block_snow"},
fill_ratio = 0.01,
sidelen = 16,
chunk_probability = 250,
solid_ground = true,
make_foundation = true,
y_max = mcl_vars.mg_overworld_max,
y_min = 0,
y_offset = 0,
biomes = { "ColdTaiga", "IcePlainsSpikes", "IcePlains" },
place_func = mcl_structures.generate_igloo,
loot = {
["mcl_chests:chest"] = {{
stacks_min = 1,
stacks_max = 1,
items = {
{ itemstring = "mcl_core:apple_gold", weight = 1 },
}
},
{
stacks_min = 2,
stacks_max = 8,
items = {
{ itemstring = "mcl_core:coal_lump", weight = 15, amount_min = 1, amount_max = 4 },
{ itemstring = "mcl_core:apple", weight = 15, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_farming:wheat_item", weight = 10, amount_min = 2, amount_max = 3 },
{ itemstring = "mcl_core:gold_nugget", weight = 10, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_mobitems:rotten_flesh", weight = 10 },
{ itemstring = "mcl_tools:axe_stone", weight = 2 },
{ itemstring = "mcl_core:emerald", weight = 1 },
}
}},
}
})

View file

@ -39,6 +39,7 @@ function mcl_structures.place_schematic(pos, schematic, rotation, replacements,
minetest.log("verbose", "[mcl_structures] size=" ..minetest.pos_to_string(s.size) .. ", rotation=" .. tostring(rotation) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2)) minetest.log("verbose", "[mcl_structures] size=" ..minetest.pos_to_string(s.size) .. ", rotation=" .. tostring(rotation) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2))
local param = {pos=vector.new(pos), schematic=s, rotation=rotation, replacements=replacements, force_placement=force_placement, flags=flags, p1=p1, p2=p2, after_placement_callback = after_placement_callback, size=vector.new(s.size), pr=pr, callback_param=callback_param} local param = {pos=vector.new(pos), schematic=s, rotation=rotation, replacements=replacements, force_placement=force_placement, flags=flags, p1=p1, p2=p2, after_placement_callback = after_placement_callback, size=vector.new(s.size), pr=pr, callback_param=callback_param}
minetest.emerge_area(p1, p2, ecb_place, param) minetest.emerge_area(p1, p2, ecb_place, param)
return true
end end
end end
@ -67,6 +68,7 @@ local function init_node_construct(pos)
end end
return false return false
end end
mcl_structures.init_node_construct = init_node_construct
-- The call of Struct -- The call of Struct
function mcl_structures.call_struct(pos, struct_style, rotation, pr) function mcl_structures.call_struct(pos, struct_style, rotation, pr)
@ -74,23 +76,7 @@ function mcl_structures.call_struct(pos, struct_style, rotation, pr)
if not rotation then if not rotation then
rotation = "random" rotation = "random"
end end
if struct_style == "desert_temple" then if struct_style == "end_exit_portal" then
return mcl_structures.generate_desert_temple(pos, rotation, pr)
elseif struct_style == "desert_well" then
return mcl_structures.generate_desert_well(pos, rotation)
elseif struct_style == "igloo" then
return mcl_structures.generate_igloo(pos, rotation, pr)
elseif struct_style == "witch_hut" then
return mcl_structures.generate_witch_hut(pos, rotation)
elseif struct_style == "ice_spike_small" then
return mcl_structures.generate_ice_spike_small(pos, rotation)
elseif struct_style == "ice_spike_large" then
return mcl_structures.generate_ice_spike_large(pos, rotation)
elseif struct_style == "boulder" then
return mcl_structures.generate_boulder(pos, rotation, pr)
elseif struct_style == "fossil" then
return mcl_structures.generate_fossil(pos, rotation, pr)
elseif struct_style == "end_exit_portal" then
return mcl_structures.generate_end_exit_portal(pos, rotation) return mcl_structures.generate_end_exit_portal(pos, rotation)
elseif struct_style == "end_exit_portal_open" then elseif struct_style == "end_exit_portal_open" then
return mcl_structures.generate_end_exit_portal_open(pos, rotation) return mcl_structures.generate_end_exit_portal_open(pos, rotation)
@ -101,245 +87,6 @@ function mcl_structures.call_struct(pos, struct_style, rotation, pr)
end end
end end
function mcl_structures.generate_desert_well(pos, rot)
local newpos = {x=pos.x,y=pos.y-2,z=pos.z}
local path = modpath.."/schematics/mcl_structures_desert_well.mts"
return mcl_structures.place_schematic(newpos, path, rot or "0", nil, true)
end
function mcl_structures.generate_igloo(pos, rotation, pr)
-- Place igloo
local success, rotation = mcl_structures.generate_igloo_top(pos, pr)
-- Place igloo basement with 50% chance
local r = pr:next(1,2)
if r == 1 then
-- Select basement depth
local dim = mcl_worlds.pos_to_dimension(pos)
--local buffer = pos.y - (mcl_vars.mg_lava_overworld_max + 10)
local buffer
if dim == "nether" then
buffer = pos.y - (mcl_vars.mg_lava_nether_max + 10)
elseif dim == "end" then
buffer = pos.y - (mcl_vars.mg_end_min + 1)
elseif dim == "overworld" then
buffer = pos.y - (mcl_vars.mg_lava_overworld_max + 10)
else
return success
end
if buffer <= 19 then
return success
end
local depth = pr:next(19, buffer)
local bpos = {x=pos.x, y=pos.y-depth, z=pos.z}
-- trapdoor position
local tpos
local dir, tdir
if rotation == "0" then
dir = {x=-1, y=0, z=0}
tdir = {x=1, y=0, z=0}
tpos = {x=pos.x+7, y=pos.y-1, z=pos.z+3}
elseif rotation == "90" then
dir = {x=0, y=0, z=-1}
tdir = {x=0, y=0, z=-1}
tpos = {x=pos.x+3, y=pos.y-1, z=pos.z+1}
elseif rotation == "180" then
dir = {x=1, y=0, z=0}
tdir = {x=-1, y=0, z=0}
tpos = {x=pos.x+1, y=pos.y-1, z=pos.z+3}
elseif rotation == "270" then
dir = {x=0, y=0, z=1}
tdir = {x=0, y=0, z=1}
tpos = {x=pos.x+3, y=pos.y-1, z=pos.z+7}
else
return success
end
local function set_brick(pos)
local c = pr:next(1, 3) -- cracked chance
local m = pr:next(1, 10) -- chance for monster egg
local brick
if m == 1 then
if c == 1 then
brick = "mcl_monster_eggs:monster_egg_stonebrickcracked"
else
brick = "mcl_monster_eggs:monster_egg_stonebrick"
end
else
if c == 1 then
brick = "mcl_core:stonebrickcracked"
else
brick = "mcl_core:stonebrick"
end
end
minetest.set_node(pos, {name=brick})
end
local ladder_param2 = minetest.dir_to_wallmounted(tdir)
local real_depth = 0
-- Check how deep we can actuall dig
for y=1, depth-5 do
real_depth = real_depth + 1
local node = minetest.get_node({x=tpos.x,y=tpos.y-y,z=tpos.z})
local def = minetest.registered_nodes[node.name]
if not (def and def.walkable and def.liquidtype == "none" and def.is_ground_content) then
bpos.y = tpos.y-y+1
break
end
end
if real_depth <= 6 then
return success
end
-- Generate ladder to basement
for y=1, real_depth-1 do
set_brick({x=tpos.x-1,y=tpos.y-y,z=tpos.z })
set_brick({x=tpos.x+1,y=tpos.y-y,z=tpos.z })
set_brick({x=tpos.x ,y=tpos.y-y,z=tpos.z-1})
set_brick({x=tpos.x ,y=tpos.y-y,z=tpos.z+1})
minetest.set_node({x=tpos.x,y=tpos.y-y,z=tpos.z}, {name="mcl_core:ladder", param2=ladder_param2})
end
-- Place basement
mcl_structures.generate_igloo_basement(bpos, rotation, pr)
-- Place hidden trapdoor
minetest.after(5, function(tpos, dir)
minetest.set_node(tpos, {name="mcl_doors:trapdoor", param2=20+minetest.dir_to_facedir(dir)}) -- TODO: more reliable param2
end, tpos, dir)
end
return success
end
function mcl_structures.generate_igloo_top(pos, pr)
-- FIXME: This spawns bookshelf instead of furnace. Fix this!
-- Furnace does ot work atm because apparently meta is not set. :-(
local newpos = {x=pos.x,y=pos.y-1,z=pos.z}
local path = modpath.."/schematics/mcl_structures_igloo_top.mts"
local rotation = tostring(pr:next(0,3)*90)
return mcl_structures.place_schematic(newpos, path, rotation, nil, true), rotation
end
local function igloo_placement_callback(p1, p2, size, orientation, pr)
local chest_offset
if orientation == "0" then
chest_offset = {x=5, y=1, z=5}
elseif orientation == "90" then
chest_offset = {x=5, y=1, z=3}
elseif orientation == "180" then
chest_offset = {x=3, y=1, z=1}
elseif orientation == "270" then
chest_offset = {x=1, y=1, z=5}
else
return
end
--local size = {x=9,y=5,z=7}
local lootitems = mcl_loot.get_multi_loot({
{
stacks_min = 1,
stacks_max = 1,
items = {
{ itemstring = "mcl_core:apple_gold", weight = 1 },
}
},
{
stacks_min = 2,
stacks_max = 8,
items = {
{ itemstring = "mcl_core:coal_lump", weight = 15, amount_min = 1, amount_max = 4 },
{ itemstring = "mcl_core:apple", weight = 15, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_farming:wheat_item", weight = 10, amount_min = 2, amount_max = 3 },
{ itemstring = "mcl_core:gold_nugget", weight = 10, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_mobitems:rotten_flesh", weight = 10 },
{ itemstring = "mcl_tools:axe_stone", weight = 2 },
{ itemstring = "mcl_core:emerald", weight = 1 },
}
}}, pr)
local chest_pos = vector.add(p1, chest_offset)
init_node_construct(chest_pos)
local meta = minetest.get_meta(chest_pos)
local inv = meta:get_inventory()
mcl_loot.fill_inventory(inv, "main", lootitems, pr)
end
function mcl_structures.generate_igloo_basement(pos, orientation, pr)
-- TODO: Add brewing stand
-- TODO: Add monster eggs
-- TODO: Spawn villager and zombie villager
local path = modpath.."/schematics/mcl_structures_igloo_basement.mts"
mcl_structures.place_schematic(pos, path, orientation, nil, true, nil, igloo_placement_callback, pr)
end
function mcl_structures.generate_boulder(pos, rotation, pr)
-- Choose between 2 boulder sizes (2×2×2 or 3×3×3)
local r = pr:next(1, 10)
local path
if r <= 3 then
path = modpath.."/schematics/mcl_structures_boulder_small.mts"
else
path = modpath.."/schematics/mcl_structures_boulder.mts"
end
local newpos = {x=pos.x,y=pos.y-1,z=pos.z}
return minetest.place_schematic(newpos, path, rotation) -- don't serialize schematics for registered biome decorations, for MT 5.4.0, https://github.com/minetest/minetest/issues/10995
end
local function spawn_witch(p1,p2)
local c = minetest.find_node_near(p1,15,{"mcl_cauldrons:cauldron"})
if c then
local nn = minetest.find_nodes_in_area_under_air(vector.new(p1.x,c.y-1,p1.z),vector.new(p2.x,c.y-1,p2.z),{"mcl_core:sprucewood"})
local witch = minetest.add_entity(vector.offset(nn[math.random(#nn)],0,1,0),"mobs_mc:witch"):get_luaentity()
local cat = minetest.add_entity(vector.offset(nn[math.random(#nn)],0,1,0),"mobs_mc:cat"):get_luaentity()
witch._home = c
witch.can_despawn = false
cat.object:set_properties({textures = {"mobs_mc_cat_black.png"}})
cat.owner = "!witch!" --so it's not claimable by player
cat._home = c
cat.can_despawn = false
return
end
end
local function hut_placement_callback(p1, p2, size, orientation, pr)
if not p1 or not p2 then return end
local legs = minetest.find_nodes_in_area(p1, p2, "mcl_core:tree")
for i = 1, #legs do
while minetest.get_item_group(mcl_vars.get_node({x=legs[i].x, y=legs[i].y-1, z=legs[i].z}, true, 333333).name, "water") ~= 0 do
legs[i].y = legs[i].y - 1
minetest.swap_node(legs[i], {name = "mcl_core:tree", param2 = 2})
end
end
spawn_witch(p1,p2)
end
function mcl_structures.generate_witch_hut(pos, rotation, pr)
local path = modpath.."/schematics/mcl_structures_witch_hut.mts"
mcl_structures.place_schematic(pos, path, rotation, nil, true, nil, hut_placement_callback, pr)
end
function mcl_structures.generate_ice_spike_small(pos, rotation)
local path = modpath.."/schematics/mcl_structures_ice_spike_small.mts"
return minetest.place_schematic(pos, path, rotation or "random", nil, false) -- don't serialize schematics for registered biome decorations, for MT 5.4.0
end
function mcl_structures.generate_ice_spike_large(pos, rotation)
local path = modpath.."/schematics/mcl_structures_ice_spike_large.mts"
return minetest.place_schematic(pos, path, rotation or "random", nil, false) -- don't serialize schematics for registered biome decorations, for MT 5.4.0
end
function mcl_structures.generate_fossil(pos, rotation, pr)
-- Generates one out of 8 possible fossil pieces
local newpos = {x=pos.x,y=pos.y-1,z=pos.z}
local fossils = {
"mcl_structures_fossil_skull_1.mts", -- 4×5×5
"mcl_structures_fossil_skull_2.mts", -- 5×5×5
"mcl_structures_fossil_skull_3.mts", -- 5×5×7
"mcl_structures_fossil_skull_4.mts", -- 7×5×5
"mcl_structures_fossil_spine_1.mts", -- 3×3×13
"mcl_structures_fossil_spine_2.mts", -- 5×4×13
"mcl_structures_fossil_spine_3.mts", -- 7×4×13
"mcl_structures_fossil_spine_4.mts", -- 8×5×13
}
local r = pr:next(1, #fossils)
local path = modpath.."/schematics/"..fossils[r]
return mcl_structures.place_schematic(newpos, path, rotation or "random", nil, true)
end
function mcl_structures.generate_end_exit_portal(pos, rot) function mcl_structures.generate_end_exit_portal(pos, rot)
local path = modpath.."/schematics/mcl_structures_end_exit_portal.mts" local path = modpath.."/schematics/mcl_structures_end_exit_portal.mts"
@ -443,93 +190,6 @@ function mcl_structures.generate_end_portal_shrine(pos, rotation, pr)
mcl_structures.place_schematic(newpos, path, rotation or "0", nil, true, nil, shrine_placement_callback, pr) mcl_structures.place_schematic(newpos, path, rotation or "0", nil, true, nil, shrine_placement_callback, pr)
end end
local function temple_placement_callback(p1, p2, size, rotation, pr)
-- Delete cacti leftovers:
local cactus_nodes = minetest.find_nodes_in_area_under_air(p1, p2, "mcl_core:cactus")
if cactus_nodes and #cactus_nodes > 0 then
for _, pos in pairs(cactus_nodes) do
local node_below = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z})
if node_below and node_below.name == "mcl_core:sandstone" then
minetest.swap_node(pos, {name="air"})
end
end
end
-- Find chests.
-- FIXME: Searching this large area just for the chets is not efficient. Need a better way to find the chests;
-- probably let's just infer it from newpos because the schematic always the same.
local chests = minetest.find_nodes_in_area(p1, p2, "mcl_chests:chest")
-- Add desert temple loot into chests
for c=1, #chests do
local lootitems = mcl_loot.get_multi_loot({
{
stacks_min = 2,
stacks_max = 4,
items = {
{ itemstring = "mcl_mobitems:bone", weight = 25, amount_min = 4, amount_max=6 },
{ itemstring = "mcl_mobitems:rotten_flesh", weight = 25, amount_min = 3, amount_max=7 },
{ itemstring = "mcl_mobitems:spider_eye", weight = 25, amount_min = 1, amount_max=3 },
{ itemstring = "mcl_books:book", weight = 20, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr)
end },
{ itemstring = "mcl_mobitems:saddle", weight = 20, },
{ itemstring = "mcl_core:apple_gold", weight = 20, },
{ itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 },
{ itemstring = "mcl_core:iron_ingot", weight = 15, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_core:emerald", weight = 15, amount_min = 1, amount_max = 3 },
{ itemstring = "", weight = 15, },
{ itemstring = "mcl_mobitems:iron_horse_armor", weight = 15, },
{ itemstring = "mcl_mobitems:gold_horse_armor", weight = 10, },
{ itemstring = "mcl_mobitems:diamond_horse_armor", weight = 5, },
{ itemstring = "mcl_core:diamond", weight = 5, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_core:apple_gold_enchanted", weight = 2, },
}
},
{
stacks_min = 4,
stacks_max = 4,
items = {
{ itemstring = "mcl_mobitems:bone", weight = 10, amount_min = 1, amount_max = 8 },
{ itemstring = "mcl_mobitems:rotten_flesh", weight = 10, amount_min = 1, amount_max = 8 },
{ itemstring = "mcl_mobitems:gunpowder", weight = 10, amount_min = 1, amount_max = 8 },
{ itemstring = "mcl_core:sand", weight = 10, amount_min = 1, amount_max = 8 },
{ itemstring = "mcl_mobitems:string", weight = 10, amount_min = 1, amount_max = 8 },
}
}}, pr)
init_node_construct(chests[c])
local meta = minetest.get_meta(chests[c])
local inv = meta:get_inventory()
mcl_loot.fill_inventory(inv, "main", lootitems, pr)
end
-- Initialize pressure plates and randomly remove up to 5 plates
local pplates = minetest.find_nodes_in_area(p1, p2, "mesecons_pressureplates:pressure_plate_stone_off")
local pplates_remove = 5
for p=1, #pplates do
if pplates_remove > 0 and pr:next(1, 100) >= 50 then
-- Remove plate
minetest.remove_node(pplates[p])
pplates_remove = pplates_remove - 1
else
-- Initialize plate
minetest.registered_nodes["mesecons_pressureplates:pressure_plate_stone_off"].on_construct(pplates[p])
end
end
end
function mcl_structures.generate_desert_temple(pos, rotation, pr)
-- No Generating for the temple ... Why using it ? No Change
local path = modpath.."/schematics/mcl_structures_desert_temple.mts"
local newpos = {x=pos.x,y=pos.y-12,z=pos.z}
--local size = {x=22, y=24, z=22}
if newpos == nil then
return
end
mcl_structures.place_schematic(newpos, path, rotation or "random", nil, true, nil, temple_placement_callback, pr)
end
local structure_data = {} local structure_data = {}
--[[ Returns a table of structure of the specified type. --[[ Returns a table of structure of the specified type.
@ -572,10 +232,79 @@ local function dir_to_rotation(dir)
end end
dofile(modpath.."/api.lua") dofile(modpath.."/api.lua")
dofile(modpath.."/shipwrecks.lua")
dofile(modpath.."/desert_temple.lua")
dofile(modpath.."/jungle_temple.lua")
dofile(modpath.."/ocean_ruins.lua")
dofile(modpath.."/witch_hut.lua")
dofile(modpath.."/igloo.lua")
dofile(modpath.."/woodland_mansion.lua")
dofile(modpath.."/geode.lua")
mcl_structures.register_structure("desert_well",{
place_on = {"group:sand"},
fill_ratio = 0.01,
flags = "place_center_x, place_center_z",
not_near = { "desert_temple_new" },
solid_ground = true,
sidelen = 4,
chunk_probability = 600,
y_max = mcl_vars.mg_overworld_max,
y_min = 1,
y_offset = -2,
biomes = { "Desert" },
filenames = { modpath.."/schematics/mcl_structures_desert_well.mts" },
})
mcl_structures.register_structure("fossil",{
place_on = {"group:material_stone","group:sand"},
fill_ratio = 0.01,
flags = "place_center_x, place_center_z",
solid_ground = true,
sidelen = 13,
chunk_probability = 1000,
y_offset = function(pr) return ( pr:next(1,16) * -1 ) -16 end,
y_max = 15,
y_min = mcl_vars.mg_overworld_min + 35,
biomes = { "Desert" },
filenames = {
modpath.."/schematics/mcl_structures_fossil_skull_1.mts", -- 4×5×5
modpath.."/schematics/mcl_structures_fossil_skull_2.mts", -- 5×5×5
modpath.."/schematics/mcl_structures_fossil_skull_3.mts", -- 5×5×7
modpath.."/schematics/mcl_structures_fossil_skull_4.mts", -- 7×5×5
modpath.."/schematics/mcl_structures_fossil_spine_1.mts", -- 3×3×13
modpath.."/schematics/mcl_structures_fossil_spine_2.mts", -- 5×4×13
modpath.."/schematics/mcl_structures_fossil_spine_3.mts", -- 7×4×13
modpath.."/schematics/mcl_structures_fossil_spine_4.mts", -- 8×5×13
},
})
mcl_structures.register_structure("boulder",{
filenames = {
modpath.."/schematics/mcl_structures_boulder_small.mts",
modpath.."/schematics/mcl_structures_boulder_small.mts",
modpath.."/schematics/mcl_structures_boulder_small.mts",
modpath.."/schematics/mcl_structures_boulder.mts",
-- small boulder 3x as likely
},
},true) --is spawned as a normal decoration. this is just for /spawnstruct
mcl_structures.register_structure("ice_spike_small",{
filenames = {
modpath.."/schematics/mcl_structures_ice_spike_small.mts"
},
},true) --is spawned as a normal decoration. this is just for /spawnstruct
mcl_structures.register_structure("ice_spike_large",{
sidelen = 6,
filenames = {
modpath.."/schematics/mcl_structures_ice_spike_large.mts"
},
},true) --is spawned as a normal decoration. this is just for /spawnstruct
-- Debug command -- Debug command
minetest.register_chatcommand("spawnstruct", { minetest.register_chatcommand("spawnstruct", {
params = "desert_temple | desert_well | igloo | witch_hut | boulder | ice_spike_small | ice_spike_large | fossil | end_exit_portal | end_exit_portal_open | end_gateway_portal | end_portal_shrine | nether_portal | dungeon", params = "end_exit_portal | end_exit_portal_open | end_gateway_portal | end_portal_shrine | nether_portal | dungeon",
description = S("Generate a pre-defined structure near your position."), description = S("Generate a pre-defined structure near your position."),
privs = {debug = true}, privs = {debug = true},
func = function(name, param) func = function(name, param)
@ -589,23 +318,7 @@ minetest.register_chatcommand("spawnstruct", {
local pr = PseudoRandom(pos.x+pos.y+pos.z) local pr = PseudoRandom(pos.x+pos.y+pos.z)
local errord = false local errord = false
local message = S("Structure placed.") local message = S("Structure placed.")
if param == "desert_temple" then if param == "end_exit_portal" then
mcl_structures.generate_desert_temple(pos, rot, pr)
elseif param == "desert_well" then
mcl_structures.generate_desert_well(pos, rot)
elseif param == "igloo" then
mcl_structures.generate_igloo(pos, rot, pr)
elseif param == "witch_hut" then
mcl_structures.generate_witch_hut(pos, rot, pr)
elseif param == "boulder" then
mcl_structures.generate_boulder(pos, rot, pr)
elseif param == "fossil" then
mcl_structures.generate_fossil(pos, rot, pr)
elseif param == "ice_spike_small" then
mcl_structures.generate_ice_spike_small(pos, rot, pr)
elseif param == "ice_spike_large" then
mcl_structures.generate_ice_spike_large(pos, rot, pr)
elseif param == "end_exit_portal" then
mcl_structures.generate_end_exit_portal(pos, rot, pr) mcl_structures.generate_end_exit_portal(pos, rot, pr)
elseif param == "end_exit_portal_open" then elseif param == "end_exit_portal_open" then
mcl_structures.generate_end_exit_portal_open(pos, rot, pr) mcl_structures.generate_end_exit_portal_open(pos, rot, pr)

View file

@ -0,0 +1,44 @@
local modname = minetest.get_current_modname()
local S = minetest.get_translator(modname)
local modpath = minetest.get_modpath(modname)
mcl_structures.register_structure("jungle_temple",{
place_on = {"group:grass_block","group:dirt","mcl_core:dirt_with_grass"},
fill_ratio = 0.01,
flags = "place_center_x, place_center_z",
solid_ground = true,
make_foundation = true,
y_offset = function(pr) return pr:next(-3,0) -5 end,
chunk_probability = 200,
y_max = mcl_vars.mg_overworld_max,
y_min = 1,
biomes = { "Jungle" },
sidelen = 18,
filenames = {
modpath.."/schematics/mcl_structures_jungle_temple.mts",
modpath.."/schematics/mcl_structures_jungle_temple_nice.mts",
},
loot = {
["mcl_chests:trapped_chest_small" ] ={{
stacks_min = 2,
stacks_max = 6,
items = {
{ itemstring = "mcl_mobitems:bone", weight = 20, amount_min = 4, amount_max=6 },
{ itemstring = "mcl_mobitems:rotten_flesh", weight = 16, amount_min = 3, amount_max=7 },
{ itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 },
--{ itemstring = "mcl_bamboo:bamboo", weight = 15, amount_min = 1, amount_max=3 }, --FIXME BAMBOO
{ itemstring = "mcl_core:iron_ingot", weight = 15, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_core:diamond", weight = 3, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_mobitems:saddle", weight = 3, },
{ itemstring = "mcl_core:emerald", weight = 2, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_books:book", weight = 1, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr)
end },
{ itemstring = "mcl_mobitems:iron_horse_armor", weight = 1, },
{ itemstring = "mcl_mobitems:gold_horse_armor", weight = 1, },
{ itemstring = "mcl_mobitems:diamond_horse_armor", weight = 1, },
{ itemstring = "mcl_core:apple_gold_enchanted", weight = 2, },
}
}}
}
})

View file

@ -1,4 +1,4 @@
name = mcl_structures name = mcl_structures
author = Wuzzy, cora author = Wuzzy, cora
description = Structure placement for MCL2 description = Structure placement for MCL2
depends = mcl_loot depends = mcl_init, mcl_loot

View file

@ -0,0 +1,132 @@
local modname = minetest.get_current_modname()
local S = minetest.get_translator(modname)
local modpath = minetest.get_modpath(modname)
local cold_oceans = {
"RoofedForest_ocean",
"BirchForestM_ocean",
"BirchForest_ocean",
"IcePlains_deep_ocean",
"ExtremeHillsM_deep_ocean",
"SunflowerPlains_ocean",
"MegaSpruceTaiga_deep_ocean",
"ExtremeHillsM_ocean",
"SunflowerPlains_deep_ocean",
"BirchForest_deep_ocean",
"IcePlainsSpikes_ocean",
"StoneBeach_ocean",
"ColdTaiga_deep_ocean",
"Forest_deep_ocean",
"FlowerForest_deep_ocean",
"MegaTaiga_ocean",
"StoneBeach_deep_ocean",
"IcePlainsSpikes_deep_ocean",
"ColdTaiga_ocean",
"ExtremeHills+_deep_ocean",
"ExtremeHills_ocean",
"Forest_ocean",
"MegaTaiga_deep_ocean",
"MegaSpruceTaiga_ocean",
"ExtremeHills+_ocean",
"RoofedForest_deep_ocean",
"IcePlains_ocean",
"FlowerForest_ocean",
"ExtremeHills_deep_ocean",
"Taiga_ocean",
"BirchForestM_deep_ocean",
"Taiga_deep_ocean",
}
local warm_oceans = {
"JungleEdgeM_ocean",
"Jungle_deep_ocean",
"Savanna_ocean",
"MesaPlateauF_ocean",
"Swampland_ocean",
"Mesa_ocean",
"Plains_ocean",
"MesaPlateauFM_ocean",
"MushroomIsland_ocean",
"SavannaM_ocean",
"JungleEdge_ocean",
"MesaBryce_ocean",
"Jungle_ocean",
"Desert_ocean",
"JungleM_ocean",
"JungleEdgeM_deep_ocean",
"Jungle_deep_ocean",
"Savanna_deep_ocean",
"MesaPlateauF_deep_ocean",
"Swampland_deep_ocean",
"Mesa_deep_ocean",
"Plains_deep_ocean",
"MesaPlateauFM_deep_ocean",
"MushroomIsland_deep_ocean",
"SavannaM_deep_ocean",
"JungleEdge_deep_ocean",
"MesaBryce_deep_ocean",
"Jungle_deep_ocean",
"Desert_deep_ocean",
"JungleM_deep_ocean",
}
local cold = {
place_on = {"group:sand","mcl_core:gravel","mcl_core:dirt","mcl_core:clay","group:material_stone"},
spawn_by = {"mcl_core:water_source"},
num_spawn_by = 2,
fill_ratio = 0.01,
flags = "place_center_x, place_center_z, force_placement",
solid_ground = true,
make_foundation = true,
y_offset = -1,
y_min = mcl_vars.mg_overworld_min,
y_max = -2,
biomes = cold_oceans,
chunk_probability = 400,
sidelen = 20,
filenames = {
modpath.."/schematics/mcl_structures_ocean_ruins_cold_1.mts",
modpath.."/schematics/mcl_structures_ocean_ruins_cold_2.mts",
modpath.."/schematics/mcl_structures_ocean_ruins_cold_3.mts",
},
loot = {
["mcl_chests:chest_small" ] = {
{
stacks_min = 2,
stacks_max = 4,
items = {
{ itemstring = "mcl_core:coal_lump", weight = 25, amount_min = 1, amount_max=4 },
{ itemstring = "mcl_farming:wheat_item", weight = 25, amount_min = 2, amount_max=3 },
{ itemstring = "mcl_core:gold_nugget", weight = 25, amount_min = 1, amount_max=3 },
--{ itemstring = "mcl_maps:treasure_map", weight = 20, }, --FIXME Treasure map
{ itemstring = "mcl_books:book", weight = 10, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr)
end },
{ itemstring = "mcl_fishing:fishing_rod_enchanted", weight = 20, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr)
end },
{ itemstring = "mcl_core:emerald", weight = 15, amount_min = 1, amount_max = 1 },
{ itemstring = "mcl_armor:chestplate_leather", weight = 15, amount_min = 1, amount_max = 1 },
{ itemstring = "mcl_core:apple_gold", weight = 20, },
{ itemstring = "mcl_armor:helmet_gold", weight = 15, amount_min = 1, amount_max = 1 },
{ itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 },
{ itemstring = "mcl_core:iron_ingot", weight = 15, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_core:apple_gold_enchanted", weight = 2, },
}
}
}
},
}
local warm = table.copy(cold)
warm.biomes = warm_oceans
warm.filenames = {
modpath.."/schematics/mcl_structures_ocean_ruins_warm_1.mts",
modpath.."/schematics/mcl_structures_ocean_ruins_warm_2.mts",
modpath.."/schematics/mcl_structures_ocean_ruins_warm_3.mts",
modpath.."/schematics/mcl_structures_ocean_ruins_warm_4.mts",
}
mcl_structures.register_structure("cold_ocean_ruins",cold)
mcl_structures.register_structure("warm_ocean_ruins",warm)

View file

@ -0,0 +1,161 @@
local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
--local S = minetest.get_translator(modname)
local seed = minetest.get_mapgen_setting("seed")
local water_level = minetest.get_mapgen_setting("water_level")
local pr = PseudoRandom(seed)
--schematics by chmodsayshello
local schems = {
modpath.."/schematics/mcl_structures_shipwreck_full_damaged.mts",
modpath.."/schematics/mcl_structures_shipwreck_full_normal.mts",
modpath.."/schematics/mcl_structures_shipwreck_full_back_damaged.mts",
modpath.."/schematics/mcl_structures_shipwreck_half_front.mts",
modpath.."/schematics/mcl_structures_shipwreck_half_back.mts",
}
local ocean_biomes = {
"RoofedForest_ocean",
"JungleEdgeM_ocean",
"BirchForestM_ocean",
"BirchForest_ocean",
"IcePlains_deep_ocean",
"Jungle_deep_ocean",
"Savanna_ocean",
"MesaPlateauF_ocean",
"ExtremeHillsM_deep_ocean",
"Savanna_deep_ocean",
"SunflowerPlains_ocean",
"Swampland_deep_ocean",
"Swampland_ocean",
"MegaSpruceTaiga_deep_ocean",
"ExtremeHillsM_ocean",
"JungleEdgeM_deep_ocean",
"SunflowerPlains_deep_ocean",
"BirchForest_deep_ocean",
"IcePlainsSpikes_ocean",
"Mesa_ocean",
"StoneBeach_ocean",
"Plains_deep_ocean",
"JungleEdge_deep_ocean",
"SavannaM_deep_ocean",
"Desert_deep_ocean",
"Mesa_deep_ocean",
"ColdTaiga_deep_ocean",
"Plains_ocean",
"MesaPlateauFM_ocean",
"Forest_deep_ocean",
"JungleM_deep_ocean",
"FlowerForest_deep_ocean",
"MushroomIsland_ocean",
"MegaTaiga_ocean",
"StoneBeach_deep_ocean",
"IcePlainsSpikes_deep_ocean",
"ColdTaiga_ocean",
"SavannaM_ocean",
"MesaPlateauF_deep_ocean",
"MesaBryce_deep_ocean",
"ExtremeHills+_deep_ocean",
"ExtremeHills_ocean",
"MushroomIsland_deep_ocean",
"Forest_ocean",
"MegaTaiga_deep_ocean",
"JungleEdge_ocean",
"MesaBryce_ocean",
"MegaSpruceTaiga_ocean",
"ExtremeHills+_ocean",
"Jungle_ocean",
"RoofedForest_deep_ocean",
"IcePlains_ocean",
"FlowerForest_ocean",
"ExtremeHills_deep_ocean",
"MesaPlateauFM_deep_ocean",
"Desert_ocean",
"Taiga_ocean",
"BirchForestM_deep_ocean",
"Taiga_deep_ocean",
"JungleM_ocean"
}
local beach_biomes = {
"FlowerForest_beach",
"Forest_beach",
"StoneBeach",
"ColdTaiga_beach_water",
"Taiga_beach",
"Savanna_beach",
"Plains_beach",
"ExtremeHills_beach",
"ColdTaiga_beach",
"Swampland_shore",
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore"
}
mcl_structures.register_structure("shipwreck",{
place_on = {"group:sand","mcl_core:gravel"},
spawn_by = {"group:water"},
num_spawn_by = 4,
noise_params = {
offset = 0,
scale = 0.000022,
spread = {x = 250, y = 250, z = 250},
seed = 3,
octaves = 3,
persist = 0.001,
flags = "absvalue",
},
sidelen = 16,
flags = "force_placement",
biomes = ocean_biomes,
y_max = water_level-4,
y_min = mcl_vars.mg_overworld_min,
filenames = schems,
y_offset = function(pr) return pr:next(-4,-2) end,
loot = {
["mcl_chests:chest_small"] = {
stacks_min = 3,
stacks_max = 10,
items = {
{ itemstring = "mcl_sus_stew:stew", weight = 10, amount_min = 1, amount_max = 1 },
{ itemstring = "mcl_core:paper", weight = 8, amount_min = 1, amount_max = 12 },
{ itemstring = "mcl_farming:wheat_item", weight = 7, amount_min = 8, amount_max = 21 },
{ itemstring = "mcl_farming:carrot_item", weight = 7, amount_min = 4, amount_max = 8 },
{ itemstring = "mcl_farming:potato_item_poison", weight = 7, amount_min = 2, amount_max = 6 },
{ itemstring = "mcl_farming:potato_item", weight = 7, amount_min = 2, amount_max = 6 },
--{ itemstring = "TODO:moss_block", weight = 7, amount_min = 1, amount_max = 4 },
{ itemstring = "mcl_core:coal_lump", weight = 6, amount_min = 2, amount_max = 8 },
{ itemstring = "mcl_mobitems:rotten_flesh", weight = 5, amount_min = 5, amount_max = 24 },
{ itemstring = "mcl_farming:potato_item", weight = 3, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_armor:helmet_leather_enchanted", weight = 3, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end },
{ itemstring = "mcl_armor:chestplate_leather_enchanted", weight = 3, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end },
{ itemstring = "mcl_armor:leggings_leather_enchanted", weight = 3, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end },
{ itemstring = "mcl_armor:boots_leather_enchanted", weight = 3, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end },
--{ itemstring = "TODO:bamboo", weight = 2, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_farming:pumpkin", weight = 2, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_tnt:tnt", weight = 1, amount_min = 1, amount_max = 2 },
},
{
stacks_min = 3,
stacks_max = 10,
items = {
{ itemstring = "mcl_core:iron_ingot", weight = 8, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_core:iron_nugget", weight = 8, amount_min = 1, amount_max = 10 },
{ itemstring = "mcl_core:emerald", weight = 8, amount_min = 1, amount_max = 12 },
{ itemstring = "mcl_dye:blue", weight = 8, amount_min = 1, amount_max = 12 },
{ itemstring = "mcl_core:gold_ingot", weight = 8, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_core:gold_nugget", weight = 8, amount_min = 1, amount_max = 10 },
{ itemstring = "mcl_experience:bottle", weight = 8, amount_min = 1, amount_max = 10 },
{ itemstring = "mcl_core:diamond", weight = 8, amount_min = 1, amount_max = 10 },
}
}
}
}
})

View file

@ -0,0 +1,49 @@
local modname = minetest.get_current_modname()
local S = minetest.get_translator(modname)
local modpath = minetest.get_modpath(modname)
local function spawn_witch(p1,p2)
local c = minetest.find_node_near(p1,15,{"mcl_cauldrons:cauldron"})
if c then
local nn = minetest.find_nodes_in_area_under_air(vector.new(p1.x,c.y-1,p1.z),vector.new(p2.x,c.y-1,p2.z),{"mcl_core:sprucewood"})
local witch = minetest.add_entity(vector.offset(nn[math.random(#nn)],0,1,0),"mobs_mc:witch"):get_luaentity()
local cat = minetest.add_entity(vector.offset(nn[math.random(#nn)],0,1,0),"mobs_mc:cat"):get_luaentity()
witch._home = c
witch.can_despawn = false
cat.object:set_properties({textures = {"mobs_mc_cat_black.png"}})
cat.owner = "!witch!" --so it's not claimable by player
cat._home = c
cat.can_despawn = false
return
end
end
local function hut_placement_callback(pos,def,pr)
local hl = def.sidelen / 2
local p1 = vector.offset(pos,-hl,-hl,-hl)
local p2 = vector.offset(pos,hl,hl,hl)
local legs = minetest.find_nodes_in_area(vector.offset(pos,-hl,0,-hl),vector.offset(pos,hl,0,hl), "mcl_core:tree")
local tree = {}
for _,leg in pairs(legs) do
while minetest.get_item_group(mcl_vars.get_node(vector.offset(leg,0,-1,0), true, 333333).name, "water") ~= 0 do
leg = vector.offset(leg,0,-1,0)
table.insert(tree,leg)
end
end
minetest.bulk_set_node(tree, {name = "mcl_core:tree", param2 = 2})
spawn_witch(p1,p2)
end
mcl_structures.register_structure("witch_hut",{
place_on = {"group:sand","group:grass_block","mcl_core:water_source","group:dirt"},
fill_ratio = 0.01,
flags = "place_center_x, place_center_z, liquid_surface, force_placement",
sidelen = 8,
chunk_probability = 300,
y_max = mcl_vars.mg_overworld_max,
y_min = -4,
y_offset = 0,
biomes = { "Swampland", "Swampland_ocean", "Swampland_shore" },
filenames = { modpath.."/schematics/mcl_structures_witch_hut.mts" },
after_place = hut_placement_callback,
})

View file

@ -0,0 +1,58 @@
local modname = minetest.get_current_modname()
local S = minetest.get_translator(modname)
local modpath = minetest.get_modpath(modname)
mcl_structures.register_structure("woodland_cabin",{
place_on = {"group:grass_block","group:dirt","mcl_core:dirt_with_grass"},
fill_ratio = 0.01,
flags = "place_center_x, place_center_z",
solid_ground = true,
make_foundation = true,
chunk_probability = 800,
y_max = mcl_vars.mg_overworld_max,
y_min = 1,
biomes = { "RoofedForest" },
sidelen = 32,
filenames = {
modpath.."/schematics/mcl_structures_woodland_cabin.mts",
modpath.."/schematics/mcl_structures_woodland_outpost.mts",
},
loot = {
["mcl_chests:chest_small" ] ={{
stacks_min = 3,
stacks_max = 3,
items = {
{ itemstring = "mcl_mobitems:bone", weight = 10, amount_min = 1, amount_max=8 },
{ itemstring = "mcl_mobitems:gunpowder", weight = 10, amount_min = 1, amount_max = 8 },
{ itemstring = "mcl_mobitems:rotten_flesh", weight = 10, amount_min = 1, amount_max=8 },
{ itemstring = "mcl_mobitems:string", weight = 10, amount_min = 1, amount_max=8 },
{ itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 },
}},{
stacks_min = 1,
stacks_max = 4,
items = {
{ itemstring = "mcl_farming:wheat_item", weight = 20, amount_min = 1, amount_max = 4 },
{ itemstring = "mcl_farming:bread", weight = 20, amount_min = 1, amount_max = 1 },
{ itemstring = "mcl_core:coal_lump", weight = 15, amount_min = 1, amount_max = 4 },
{ itemstring = "mesecons:mesecon", weight = 15, amount_min = 1, amount_max = 4 },
{ itemstring = "mcl_farming:beetroot_seeds", weight = 10, amount_min = 2, amount_max = 4 },
{ itemstring = "mcl_farming:melon_seeds", weight = 10, amount_min = 2, amount_max = 4 },
{ itemstring = "mcl_farming:pumpkin_seeds", weight = 10, amount_min = 2, amount_max = 4 },
{ itemstring = "mcl_core:iron_ingot", weight = 10, amount_min = 1, amount_max = 4 },
{ itemstring = "mcl_buckets:bucket_empty", weight = 10, amount_min = 1, amount_max = 1 },
{ itemstring = "mcl_core:gold_ingot", weight = 5, amount_min = 1, amount_max = 4 },
}},{
stacks_min = 1,
stacks_max = 4,
items = {
--{ itemstring = "FIXME:lead", weight = 20, amount_min = 1, amount_max = 1 },
{ itemstring = "mcl_mobs:nametag", weight = 2, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_books:book", weight = 1, func = function(stack, pr)mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end },
{ itemstring = "mcl_armor:chestplate_chain", weight = 1, },
{ itemstring = "mcl_armor:chestplate_diamond", weight = 1, },
{ itemstring = "mcl_core:apple_gold_enchanted", weight = 2, },
}
}}
}
})

View file

@ -23,59 +23,71 @@ local function set_node_no_bedrock(pos,node)
return minetest.set_node(pos,node) return minetest.set_node(pos,node)
end end
local function airtower(pos) local function airtower(pos,tbl,h)
for i=0,55 do for i=1,h do
set_node_no_bedrock(vector.offset(pos,0,i,0),{name="air"}) table.insert(tbl,vector.offset(pos,0,i,0))
end end
end end
local function makelake(pos,size,liquid,placein,border,pr) local function makelake(pos,size,liquid,placein,border,pr)
local node_under = minetest.get_node(vector.offset(pos,0,1,0)) local node_under = minetest.get_node(vector.offset(pos,0,-1,0))
local p1 = vector.offset(pos,-size,-size,-size) local p1 = vector.offset(pos,-size,-1,-size)
local p2 = vector.offset(pos,size,size,size) local p2 = vector.offset(pos,size,-1,size)
local nn = minetest.find_nodes_in_area(p1,p2,placein) minetest.emerge_area(p1, p2, function(blockpos, action, calls_remaining, param)
table.sort(nn,function(a, b) if calls_remaining ~= 0 then return end
return vector.distance(vector.new(pos.x,0,pos.z), a) < vector.distance(vector.new(pos.x,0,pos.z), b) local nn = minetest.find_nodes_in_area(p1,p2,placein)
table.sort(nn,function(a, b)
return vector.distance(vector.new(pos.x,0,pos.z), a) < vector.distance(vector.new(pos.x,0,pos.z), b)
end)
if not nn[1] then return end
local y = pos.y - pr:next(1,2)
local lq = {}
local air = {}
local r = pr:next(1,#nn)
if r > #nn then return end
for i=1,r do
if nn[i].y == y then
airtower(nn[i],air,55)
table.insert(lq,nn[i])
end
end
minetest.bulk_set_node(lq,{name=liquid})
minetest.bulk_set_node(air,{name="air"})
air = {}
local br = {}
for k,v in pairs(lq) do
for kk,vv in pairs(adjacents) do
local pp = vector.add(v,vv)
local an = minetest.get_node(pp)
local un = minetest.get_node(vector.offset(pp,0,1,0))
if not border then
if minetest.get_item_group(an.name,"solid") > 0 then
border = an.name
elseif minetest.get_item_group(minetest.get_node(nn[1]).name,"solid") > 0 then
border = minetest.get_node_or_nil(nn[1]).name
else
border = "mcl_core:stone"
end
if border == nil or border == "mcl_core:dirt" then border = "mcl_core:dirt_with_grass" end
end
if an.name ~= liquid then
table.insert(br,pp)
if un.name ~= liquid then
airtower(pp,air,55)
end
end
end
end
minetest.bulk_set_node(br,{name=border})
minetest.bulk_set_node(air,{name="air"})
return true
end) end)
if not nn[1] then return end
local y = pos.y + 1
local lq = {}
for i=1,pr:next(1,#nn) do
if nn[i].y == y then
set_node_no_bedrock(nn[i],{name=liquid})
airtower(vector.offset(nn[i],0,1,0))
table.insert(lq,nn[i])
end
end
for k,v in pairs(lq) do
for kk,vv in pairs(adjacents) do
local pp = vector.add(v,vv)
local an = minetest.get_node(pp)
local un = minetest.get_node(vector.offset(pp,0,1,0))
if not border then
if minetest.get_item_group(an.name,"solid") > 0 then
border = an.name
elseif minetest.get_item_group(minetest.get_node(nn[1]).name,"solid") > 0 then
border = minetest.get_node(nn[1]).name
else
border = "mcl_core:stone"
end
if border == "mcl_core:dirt" then border = "mcl_core:dirt_with_grass" end
end
if an.name ~= liquid then
set_node_no_bedrock(pp,{name=border})
if un.name ~= liquid then
airtower(vector.offset(pp,0,1,0))
end
end
end
end
return true return true
end end
mcl_structures.register_structure("lavapool",{ mcl_structures.register_structure("lavapool",{
place_on = {"group:sand", "group:dirt", "group:stone"}, place_on = {"group:sand", "group:dirt", "group:stone"},
terrain_feature = true,
noise_params = { noise_params = {
offset = 0, offset = 0,
scale = 0.0000022, scale = 0.0000022,
@ -89,12 +101,13 @@ mcl_structures.register_structure("lavapool",{
y_max = mcl_vars.mg_overworld_max, y_max = mcl_vars.mg_overworld_max,
y_min = minetest.get_mapgen_setting("water_level"), y_min = minetest.get_mapgen_setting("water_level"),
place_func = function(pos,def,pr) place_func = function(pos,def,pr)
return makelake(pos,5,"mcl_core:lava_source","mcl_core:stone",{"group:material_stone", "group:sand", "group:dirt"},pr) return makelake(pos,5,"mcl_core:lava_source",{"group:material_stone", "group:sand", "group:dirt"},"mcl_core:stone",pr)
end end
}) })
mcl_structures.register_structure("water_lake",{ mcl_structures.register_structure("water_lake",{
place_on = {"group:dirt","group:stone"}, place_on = {"group:dirt","group:stone"},
terrain_feature = true,
noise_params = { noise_params = {
offset = 0, offset = 0,
scale = 0.000032, scale = 0.000032,
@ -108,26 +121,34 @@ mcl_structures.register_structure("water_lake",{
y_max = mcl_vars.mg_overworld_max, y_max = mcl_vars.mg_overworld_max,
y_min = minetest.get_mapgen_setting("water_level"), y_min = minetest.get_mapgen_setting("water_level"),
place_func = function(pos,def,pr) place_func = function(pos,def,pr)
return makelake(pos,5,"mcl_core:water_source",{"group:material_stone", "group:sand", "group:dirt"},nil,pr) return makelake(pos,5,"mcl_core:water_source",{"group:material_stone", "group:sand", "group:dirt","group:grass_block"},nil,pr)
end end
}) })
local pool_adjacents = {
vector.new(1,0,0),
vector.new(-1,0,0),
vector.new(0,-1,0),
vector.new(0,0,1),
vector.new(0,0,-1),
}
mcl_structures.register_structure("basalt_column",{ mcl_structures.register_structure("basalt_column",{
place_on = {"mcl_blackstone:blackstone","mcl_blackstone:basalt"}, place_on = {"mcl_blackstone:blackstone","mcl_blackstone:basalt"},
terrain_feature = true,
spawn_by = {"air"}, spawn_by = {"air"},
num_spawn_by = 2, num_spawn_by = 2,
noise_params = { noise_params = {
offset = 0, offset = 0,
scale = 0.02, scale = 0.003,
spread = {x = 250, y = 250, z = 250}, spread = {x = 250, y = 250, z = 250},
seed = 7225213, seed = 72235213,
octaves = 5, octaves = 5,
persist = 0.1, persist = 0.3,
flags = "absvalue", flags = "absvalue",
}, },
flags = "all_floors", flags = "all_floors",
y_max = mcl_vars.mg_nether_max, y_max = mcl_vars.mg_nether_max - 20,
y_min = mcl_vars.mg_lava_nether_max + 1, y_min = mcl_vars.mg_lava_nether_max + 1,
biomes = { "BasaltDelta" }, biomes = { "BasaltDelta" },
place_func = function(pos,def,pr) place_func = function(pos,def,pr)
@ -136,30 +157,40 @@ mcl_structures.register_structure("basalt_column",{
return vector.distance(vector.new(pos.x,0,pos.z), a) < vector.distance(vector.new(pos.x,0,pos.z), b) return vector.distance(vector.new(pos.x,0,pos.z), a) < vector.distance(vector.new(pos.x,0,pos.z), b)
end) end)
if #nn < 1 then return false end if #nn < 1 then return false end
local basalt = {}
local magma = {}
for i=1,pr:next(1,#nn) do for i=1,pr:next(1,#nn) do
if minetest.get_node(vector.offset(nn[i],0,-1,0)).name ~= "air" then if minetest.get_node(vector.offset(nn[i],0,-1,0)).name ~= "air" then
local dst=vector.distance(pos,nn[i]) local dst=vector.distance(pos,nn[i])
for ii=0,pr:next(2,14)-dst do local r = pr:next(1,14)-dst
set_node_no_bedrock(vector.new(nn[i].x,nn[i].y + ii,nn[i].z),{name="mcl_blackstone:basalt"}) for ii=0,r do
if pr:next(1,25) == 1 then
table.insert(magma,vector.new(nn[i].x,nn[i].y + ii,nn[i].z))
else
table.insert(basalt,vector.new(nn[i].x,nn[i].y + ii,nn[i].z))
end
end end
end end
end end
minetest.bulk_set_node(magma,{name="mcl_nether:magma"})
minetest.bulk_set_node(basalt,{name="mcl_blackstone:basalt"})
return true return true
end end
}) })
mcl_structures.register_structure("basalt_pillar",{ mcl_structures.register_structure("basalt_pillar",{
place_on = {"mcl_blackstone:blackstone","mcl_blackstone:basalt"}, place_on = {"mcl_blackstone:blackstone","mcl_blackstone:basalt"},
terrain_feature = true,
noise_params = { noise_params = {
offset = 0, offset = 0,
scale = 0.001, scale = 0.001,
spread = {x = 250, y = 250, z = 250}, spread = {x = 250, y = 250, z = 250},
seed = 783213, seed = 7113,
octaves = 5, octaves = 5,
persist = 0.1, persist = 0.1,
flags = "absvalue", flags = "absvalue",
}, },
flags = "all_floors", flags = "all_floors",
y_max = mcl_vars.mg_nether_max, y_max = mcl_vars.mg_nether_max-40,
y_min = mcl_vars.mg_lava_nether_max + 1, y_min = mcl_vars.mg_lava_nether_max + 1,
biomes = { "BasaltDelta" }, biomes = { "BasaltDelta" },
place_func = function(pos,def,pr) place_func = function(pos,def,pr)
@ -168,14 +199,22 @@ mcl_structures.register_structure("basalt_pillar",{
return vector.distance(vector.new(pos.x,0,pos.z), a) < vector.distance(vector.new(pos.x,0,pos.z), b) return vector.distance(vector.new(pos.x,0,pos.z), a) < vector.distance(vector.new(pos.x,0,pos.z), b)
end) end)
if #nn < 1 then return false end if #nn < 1 then return false end
local basalt = {}
local magma = {}
for i=1,pr:next(1,#nn) do for i=1,pr:next(1,#nn) do
if minetest.get_node(vector.offset(nn[i],0,-1,0)).name ~= "air" then if minetest.get_node(vector.offset(nn[i],0,-1,0)).name ~= "air" then
local dst=vector.distance(pos,nn[i]) local dst=vector.distance(pos,nn[i])
for ii=0,pr:next(19,34)-dst do for ii=0,pr:next(19,35)-dst do
set_node_no_bedrock(vector.new(nn[i].x,nn[i].y + ii,nn[i].z),{name="mcl_blackstone:basalt"}) if pr:next(1,20) == 1 then
table.insert(magma,vector.new(nn[i].x,nn[i].y + ii,nn[i].z))
else
table.insert(basalt,vector.new(nn[i].x,nn[i].y + ii,nn[i].z))
end
end end
end end
end end
minetest.bulk_set_node(basalt,{name="mcl_blackstone:basalt"})
minetest.bulk_set_node(magma,{name="mcl_nether:magma"})
return true return true
end end
}) })
@ -184,9 +223,10 @@ mcl_structures.register_structure("lavadelta",{
place_on = {"mcl_blackstone:blackstone","mcl_blackstone:basalt"}, place_on = {"mcl_blackstone:blackstone","mcl_blackstone:basalt"},
spawn_by = {"mcl_blackstone:basalt","mcl_blackstone:blackstone"}, spawn_by = {"mcl_blackstone:basalt","mcl_blackstone:blackstone"},
num_spawn_by = 2, num_spawn_by = 2,
terrain_feature = true,
noise_params = { noise_params = {
offset = 0, offset = 0,
scale = 0.01, scale = 0.005,
spread = {x = 250, y = 250, z = 250}, spread = {x = 250, y = 250, z = 250},
seed = 78375213, seed = 78375213,
octaves = 5, octaves = 5,
@ -198,27 +238,32 @@ mcl_structures.register_structure("lavadelta",{
y_min = mcl_vars.mg_lava_nether_max + 1, y_min = mcl_vars.mg_lava_nether_max + 1,
biomes = { "BasaltDelta" }, biomes = { "BasaltDelta" },
place_func = function(pos,def,pr) place_func = function(pos,def,pr)
local nn = minetest.find_nodes_in_area_under_air(vector.offset(pos,-10,-1,-10),vector.offset(pos,10,-1,10),{"mcl_blackstone:basalt","mcl_blackstone:blackstone"}) local nn = minetest.find_nodes_in_area_under_air(vector.offset(pos,-10,-1,-10),vector.offset(pos,10,-2,10),{"mcl_blackstone:basalt","mcl_blackstone:blackstone","mcl_nether:netherrack"})
table.sort(nn,function(a, b) table.sort(nn,function(a, b)
return vector.distance(vector.new(pos.x,0,pos.z), a) < vector.distance(vector.new(pos.x,0,pos.z), b) return vector.distance(vector.new(pos.x,0,pos.z), a) < vector.distance(vector.new(pos.x,0,pos.z), b)
end) end)
if #nn < 1 then return false end if #nn < 1 then return false end
local lava = {} local lava = {}
for i=1,pr:next(1,#nn) do for i=1,pr:next(1,#nn) do
set_node_no_bedrock(nn[i],{name="mcl_nether:nether_lava_source"})
table.insert(lava,nn[i]) table.insert(lava,nn[i])
end end
minetest.bulk_set_node(lava,{name="mcl_nether:nether_lava_source"})
local basalt = {}
local magma = {}
for _,v in pairs(lava) do for _,v in pairs(lava) do
for _,vv in pairs(adjacents) do for _,vv in pairs(adjacents) do
local p = vector.add(v,vv) local p = vector.add(v,vv)
if minetest.get_node(p).name ~= "mcl_nether:nether_lava_source" then if minetest.get_node(p).name ~= "mcl_nether:nether_lava_source" then
set_node_no_bedrock(p,{name="mcl_blackstone:basalt"}) table.insert(basalt,p)
end end
end end
if math.random(3) == 1 then if math.random(3) == 1 then
set_node_no_bedrock(v,{name="mcl_nether:magma"}) table.insert(magma,v)
end end
end end
minetest.bulk_set_node(basalt,{name="mcl_blackstone:basalt"})
minetest.bulk_set_node(magma,{name="mcl_nether:magma"})
return true return true
end end
}) })