1
0
Fork 0

First pass on `mcl_structures` (there are still issues I can't resolve)

- use new vectors
- comment unused functions and variables (translator, etc)
- no longer redifine variables in a confusible way
- add (very) basic type annotations
- simplify some parts of the code
- make /spawnstruct command always return boolean + output instead of chant_send_player
- simplify /spawnstruct command code
mcl-structures-fixes
AFCMS 2022-11-11 10:35:25 +01:00
parent 589bf75e6a
commit 3a2ce2feb8
No known key found for this signature in database
GPG Key ID: 8720389A25B652E3
14 changed files with 804 additions and 672 deletions

View File

@ -1,47 +1,51 @@
mcl_structures.registered_structures = {} mcl_structures.registered_structures = {}
local place_queue = {} local place_queue = {}
local disabled_structures = minetest.settings:get("mcl_disabled_structures") local disabled_structures = minetest.settings:get("mcl_disabled_structures"):split(",")
if disabled_structures then disabled_structures = disabled_structures:split(",")
else disabled_structures = {} end
local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false) local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false)
local mob_cap_player = tonumber(minetest.settings:get("mcl_mob_cap_player")) or 75 local mob_cap_player = tonumber(minetest.settings:get("mcl_mob_cap_player")) or 75
local mob_cap_animal = tonumber(minetest.settings:get("mcl_mob_cap_animal")) or 10 local mob_cap_animal = tonumber(minetest.settings:get("mcl_mob_cap_animal")) or 10
local logging = minetest.settings:get_bool("mcl_logging_structures",true) local logging = minetest.settings:get_bool("mcl_logging_structures", true)
local mg_name = minetest.get_mapgen_setting("mg_name") local mg_name = minetest.get_mapgen_setting("mg_name")
local modpath = minetest.get_modpath("mcl_structures")
local rotations = { local rotations = {
"0", "0",
"90", "90",
"180", "180",
"270" "270",
} }
function mcl_structures.is_disabled(structname) function mcl_structures.is_disabled(structname)
return table.indexof(disabled_structures,structname) ~= -1 return table.indexof(disabled_structures, structname) ~= -1
end end
local function ecb_place(blockpos, action, calls_remaining, param) local function ecb_place(blockpos, action, calls_remaining, param)
if calls_remaining >= 1 then return end if calls_remaining >= 1 then return end
minetest.place_schematic(param.pos, param.schematic, param.rotation, param.replacements, param.force_placement, param.flags) minetest.place_schematic(param.pos, param.schematic, param.rotation, param.replacements, param.force_placement,
param.flags)
if param.after_placement_callback and param.p1 and param.p2 then if param.after_placement_callback and param.p1 and param.p2 then
param.after_placement_callback(param.p1, param.p2, param.size, param.rotation, param.pr, param.callback_param) param.after_placement_callback(param.p1, param.p2, param.size, param.rotation, param.pr, param.callback_param)
end end
end end
function mcl_structures.place_schematic(pos, schematic, rotation, replacements, force_placement, flags, after_placement_callback, pr, callback_param) function mcl_structures.place_schematic(pos, schematic, rotation, replacements, force_placement, flags,
after_placement_callback, pr, callback_param)
if type(schematic) ~= "table" and not mcl_util.file_exists(schematic) then if type(schematic) ~= "table" and not mcl_util.file_exists(schematic) then
minetest.log("warning","[mcl_structures] schematic file "..tostring(schematic).." does not exist.") minetest.log("warning", "[mcl_structures] schematic file " .. tostring(schematic) .. " does not exist.")
return end return
local s = loadstring(minetest.serialize_schematic(schematic, "lua", {lua_use_comments = false, lua_num_indent_spaces = 0}) .. " return schematic")() end
local s = loadstring(minetest.serialize_schematic(schematic, "lua",
{ lua_use_comments = false, lua_num_indent_spaces = 0 }) .. " return schematic")()
if s and s.size then if s and s.size then
local x, z = s.size.x, s.size.z local x, z = s.size.x, s.size.z
if rotation then if rotation then
if rotation == "random" and pr then if rotation == "random" and pr then
rotation = rotations[pr:next(1,#rotations)] rotation = rotations[pr:next(1, #rotations)]
end end
if rotation == "random" then if rotation == "random" then
x = math.max(x, z) x = math.max(x, z)
@ -50,23 +54,32 @@ function mcl_structures.place_schematic(pos, schematic, rotation, replacements,
x, z = z, x x, z = z, x
end end
end end
local p1 = {x=pos.x , y=pos.y , z=pos.z } local p1 = vector.copy(pos)
local p2 = {x=pos.x+x-1, y=pos.y+s.size.y-1, z=pos.z+z-1} local p2 = vector.offset(pos, x - 1, s.size.y - 1, z - 1)
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",
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} "[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.copy(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.copy(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 return true
end end
end end
function mcl_structures.get_struct(file) function mcl_structures.get_struct(filename)
local localfile = modpath.."/schematics/"..file local localfile = modpath .. "/schematics/" .. filename
local file, errorload = io.open(localfile, "rb") local file, errorload = io.open(localfile, "rb")
if errorload then if errorload then
minetest.log("error", "[mcl_structures] Could not open this struct: "..localfile) minetest.log("error", "[mcl_structures] Could not open this struct: " .. localfile)
return nil return nil
end end
assert(file)
local allnode = file:read("*a") local allnode = file:read("*a")
file:close() file:close()
@ -75,6 +88,7 @@ end
-- Call on_construct on pos. -- Call on_construct on pos.
-- Useful to init chests from formspec. -- Useful to init chests from formspec.
---@param pos Vector
local function init_node_construct(pos) local function init_node_construct(pos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local def = minetest.registered_nodes[node.name] local def = minetest.registered_nodes[node.name]
@ -84,12 +98,17 @@ local function init_node_construct(pos)
end end
return false return false
end end
mcl_structures.init_node_construct = init_node_construct mcl_structures.init_node_construct = init_node_construct
function mcl_structures.fill_chests(p1,p2,loot,pr) ---@param p1 Vector
for it,lt in pairs(loot) do ---@param p2 Vector
---@param loot table
---@param pr PseudoRandom
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) local nodes = minetest.find_nodes_in_area(p1, p2, it)
for _,p in pairs(nodes) do for _, p in pairs(nodes) do
local lootitems = mcl_loot.get_multi_loot(lt, pr) local lootitems = mcl_loot.get_multi_loot(lt, pr)
mcl_structures.init_node_construct(p) mcl_structures.init_node_construct(p)
local meta = minetest.get_meta(p) local meta = minetest.get_meta(p)
@ -99,97 +118,127 @@ function mcl_structures.fill_chests(p1,p2,loot,pr)
end end
end end
---@param pos Vector
---@param def table
---@param pr PseudoRandom
local function generate_loot(pos, def, pr) local function generate_loot(pos, def, pr)
local hl = def.sidelen local hl = def.sidelen
local p1 = vector.offset(pos,-hl,-hl,-hl) local p1 = vector.offset(pos, -hl, -hl, -hl)
local p2 = 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 if def.loot then mcl_structures.fill_chests(p1, p2, def.loot, pr) end
end end
function mcl_structures.construct_nodes(p1,p2,nodes) ---@param p1 Vector
local nn=minetest.find_nodes_in_area(p1,p2,nodes) ---@param p2 Vector
for _,p in pairs(nn) do ---@param nodes string[]
function mcl_structures.construct_nodes(p1, p2, nodes)
local nn = minetest.find_nodes_in_area(p1, p2, nodes)
for _, p in pairs(nn) do
mcl_structures.init_node_construct(p) mcl_structures.init_node_construct(p)
end end
end end
local function construct_nodes(pos,def,pr) ---@param pos Vector
return mcl_structures.construct_nodes(vector.offset(pos,-def.sidelen/2,0,-def.sidelen/2),vector.offset(pos,def.sidelen/2,def.sidelen,def.sidelen/2),def.construct_nodes) ---@param def table
---@param pr PseudoRandom
local function construct_nodes(pos, def, pr)
return mcl_structures.construct_nodes(
vector.offset(pos, -def.sidelen / 2, 0, -def.sidelen / 2),
vector.offset(pos, def.sidelen / 2, def.sidelen, def.sidelen / 2),
def.construct_nodes
)
end end
---@param pp Vector[]
---@return integer
function mcl_structures.find_lowest_y(pp) function mcl_structures.find_lowest_y(pp)
local y = 31000 local y = 31000
for _,p in pairs(pp) do for _, p in pairs(pp) do
if p.y < y then y = p.y end if p.y < y then y = p.y end
end end
return y return y
end end
---@param pp Vector[]
---@return integer
function mcl_structures.find_highest_y(pp) function mcl_structures.find_highest_y(pp)
local y = -31000 local y = -31000
for _,p in pairs(pp) do for _, p in pairs(pp) do
if p.y > y then y = p.y end if p.y > y then y = p.y end
end end
return y return y
end end
local function smooth_cube(nn,pos,plane,amnt) ---@param nn Vector[]
---@param pos Vector
---@param plane? boolean
---@param amnt? integer
---@return Vector[]
local function smooth_cube(nn, pos, plane, amnt)
local r = {} local r = {}
local amnt = amnt or 9 amnt = amnt or 9
table.sort(nn,function(a, b) table.sort(nn, function(a, b)
if false or plane then if false or plane then
return vector.distance(vector.new(pos.x,0,pos.z), vector.new(a.x,0,a.z)) < vector.distance(vector.new(pos.x,0,pos.z), vector.new(b.x,0,b.z)) return vector.distance(vector.new(pos.x, 0, pos.z), vector.new(a.x, 0, a.z)) <
vector.distance(vector.new(pos.x, 0, pos.z), vector.new(b.x, 0, b.z))
else else
return vector.distance(pos, a) < vector.distance(pos, b) return vector.distance(pos, a) < vector.distance(pos, b)
end end
end) end)
for i=1,math.max(1,#nn-amnt) do table.insert(r,nn[i]) end for i = 1, math.max(1, #nn - amnt) do table.insert(r, nn[i]) end
return r return r
end end
local function find_ground(pos,nn,gn) ---@param pos Vector
---@param nn Vector[]
---@param gn string
---@return integer
local function find_ground(pos, nn, gn)
local r = 0 local r = 0
for _,v in pairs(nn) do for _, v in pairs(nn) do
local p=vector.new(v) local p = vector.copy(v)
repeat repeat
local n = minetest.get_node(p).name local n = minetest.get_node(p).name
p = vector.offset(p,0,-1,0) p = vector.offset(p, 0, -1, 0)
until not n or n == "mcl_core:bedrock" or n == "ignore" or n == gn until not n or n == "mcl_core:bedrock" or n == "ignore" or n == gn
--minetest.log(tostring(pos.y - p.y)) --minetest.log(tostring(pos.y - p.y))
if pos.y - p.y > r then r = pos.y - p.y end if pos.y - p.y > r then
r = pos.y - p.y
end
end end
return r return r
end end
local function get_foundation_nodes(ground_p1,ground_p2,pos,sidelen,node_stone) local function get_foundation_nodes(ground_p1, ground_p2, pos, sidelen, node_stone)
local replace = {"air","group:liquid","mcl_core:snow","group:tree","group:leaves","group:plant","grass_block","group:dirt"} local replace = { "air", "group:liquid", "mcl_core:snow", "group:tree", "group:leaves", "group:plant", "grass_block",
local depth = find_ground(pos,minetest.find_nodes_in_area(ground_p1,ground_p2,replace),node_stone) "group:dirt" }
local nn = smooth_cube(minetest.find_nodes_in_area(vector.offset(ground_p1,0,-1,0),vector.offset(ground_p2,0,-depth,0),replace),vector.offset(pos,0,-depth,0),true,sidelen * 64) local depth = find_ground(pos, minetest.find_nodes_in_area(ground_p1, ground_p2, replace), node_stone)
local nn = smooth_cube(minetest.find_nodes_in_area(vector.offset(ground_p1, 0, -1, 0),
vector.offset(ground_p2, 0, -depth, 0), replace), vector.offset(pos, 0, -depth, 0), true, sidelen * 64)
local stone = {} local stone = {}
local filler = {} local filler = {}
local top = {} local top = {}
local dust = {} local dust = {}
for l,v in pairs(nn) do for l, v in pairs(nn) do
if v.y == ground_p1.y - 1 then if v.y == ground_p1.y - 1 then
table.insert(filler,v) table.insert(filler, v)
table.insert(top,vector.offset(v,0,1,0)) table.insert(top, vector.offset(v, 0, 1, 0))
table.insert(dust,vector.offset(v,0,2,0)) table.insert(dust, vector.offset(v, 0, 2, 0))
elseif v.y < ground_p1.y -1 and v.y > ground_p2.y -4 then table.insert(filler,v) elseif v.y < ground_p1.y - 1 and v.y > ground_p2.y - 4 then table.insert(filler, v)
elseif v.y < ground_p2.y - 3 and v.y > ground_p2.y -5 then elseif v.y < ground_p2.y - 3 and v.y > ground_p2.y - 5 then
if math.random(3) == 1 then if math.random(3) == 1 then
table.insert(filler,v) table.insert(filler, v)
else else
table.insert(stone,v) table.insert(stone, v)
end end
else else
table.insert(stone,v) table.insert(stone, v)
end end
end end
return stone,filler,top,dust return stone, filler, top, dust
end end
local function foundation(ground_p1,ground_p2,pos,sidelen) local function foundation(ground_p1, ground_p2, pos, sidelen)
local node_stone = "mcl_core:stone" local node_stone = "mcl_core:stone"
local node_filler = "mcl_core:dirt" local node_filler = "mcl_core:dirt"
local node_top = "mcl_core:dirt_with_grass" or minetest.get_node(ground_p1).name local node_top = "mcl_core:dirt_with_grass" or minetest.get_node(ground_p1).name
@ -206,49 +255,51 @@ local function foundation(ground_p1,ground_p2,pos,sidelen)
end end
end end
local stone,filler,top,dust = get_foundation_nodes(ground_p1,ground_p2,pos,sidelen,node_stone) local stone, filler, top, dust = get_foundation_nodes(ground_p1, ground_p2, pos, sidelen, node_stone)
minetest.bulk_set_node(top,{name=node_top},node_stone) minetest.bulk_set_node(top, { name = node_top })
if node_dust then if node_dust then
minetest.bulk_set_node(dust,{name=node_dust}) minetest.bulk_set_node(dust, { name = node_dust })
end end
minetest.bulk_set_node(filler,{name=node_filler}) minetest.bulk_set_node(filler, { name = node_filler })
minetest.bulk_set_node(stone,{name=node_stone}) minetest.bulk_set_node(stone, { name = node_stone })
end end
--[[
local function process_queue() local function process_queue()
if #place_queue < 1 then return end if #place_queue < 1 then return end
local s = table.remove(place_queue) local s = table.remove(place_queue)
mcl_structures.place_schematic(s.pos, s.file, s.rot, nil, true, "place_center_x,place_center_z",function(s) mcl_structures.place_schematic(s.pos, s.file, s.rot, nil, true, "place_center_x,place_center_z", function(s)
if s.after_place then if s.after_place then
s.after_place(s.pos,s.def,s.pr) s.after_place(s.pos, s.def, s.pr)
end end
end,s.pr) end, s.pr)
minetest.after(0.5,process_queue) minetest.after(0.5, process_queue)
end end
]]
function mcl_structures.spawn_mobs(mob,spawnon,p1,p2,pr,n,water) function mcl_structures.spawn_mobs(mob, spawnon, p1, p2, pr, n, water)
n = n or 1 n = n or 1
local sp = {} local sp = {}
if water then if water then
local nn = minetest.find_nodes_in_area(p1,p2,spawnon) local nn = minetest.find_nodes_in_area(p1, p2, spawnon)
for k,v in pairs(nn) do for k, v in pairs(nn) do
if minetest.get_item_group(minetest.get_node(vector.offset(v,0,1,0)).name,"water") > 0 then if minetest.get_item_group(minetest.get_node(vector.offset(v, 0, 1, 0)).name, "water") > 0 then
table.insert(sp,v) table.insert(sp, v)
end end
end end
else else
sp = minetest.find_nodes_in_area_under_air(p1,p2,spawnon) sp = minetest.find_nodes_in_area_under_air(p1, p2, spawnon)
end end
table.shuffle(sp) table.shuffle(sp)
for i,node in pairs(sp) do for i, node in pairs(sp) do
if not peaceful and i <= n then if not peaceful and i <= n then
local pos = vector.offset(node,0,1,0) local pos = vector.offset(node, 0, 1, 0)
if pos then if pos then
minetest.add_entity(pos,mob) minetest.add_entity(pos, mob)
end end
end end
minetest.get_meta(node):set_string("spawnblock","yes") minetest.get_meta(node):set_string("spawnblock", "yes")
end end
end end
@ -262,87 +313,92 @@ function mcl_structures.place_structure(pos, def, pr, blockseed, rot)
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) local pp = vector.offset(pos, 0, y_offset, 0)
if def.solid_ground and def.sidelen then if def.solid_ground and def.sidelen then
local ground_p1 = vector.offset(pos,-def.sidelen/2,-1,-def.sidelen/2) 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 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"}) local solid = minetest.find_nodes_in_area(ground_p1, ground_p2, { "group:solid" })
if #solid < ( def.sidelen * def.sidelen ) then if #solid < (def.sidelen * def.sidelen) then
if def.make_foundation then if def.make_foundation then
foundation(vector.offset(pos,-def.sidelen/2 - 3,-1,-def.sidelen/2 - 3),vector.offset(pos,def.sidelen/2 + 3,-1,def.sidelen/2 + 3),pos,def.sidelen) foundation(vector.offset(pos, -def.sidelen / 2 - 3, -1, -def.sidelen / 2 - 3),
vector.offset(pos, def.sidelen / 2 + 3, -1, def.sidelen / 2 + 3), pos, def.sidelen)
else else
if log_enabled then if log_enabled then
minetest.log("warning","[mcl_structures] "..def.name.." at "..minetest.pos_to_string(pp).." not placed. No solid ground.") minetest.log("warning",
"[mcl_structures] " .. def.name .. " at " .. minetest.pos_to_string(pp) .. " not placed. No solid ground.")
end end
return false return false
end end
end end
end end
if def.on_place and not def.on_place(pos,def,pr,blockseed) then if def.on_place and not def.on_place(pos, def, pr, blockseed) then
if log_enabled then if log_enabled then
minetest.log("warning","[mcl_structures] "..def.name.." at "..minetest.pos_to_string(pp).." not placed. Conditions not satisfied.") minetest.log("warning",
"[mcl_structures] " .. def.name .. " at " .. minetest.pos_to_string(pp) .. " not placed. Conditions not satisfied.")
end end
return false return false
end end
if def.filenames then if def.filenames then
if #def.filenames <= 0 then return false end if #def.filenames <= 0 then return false end
local r = pr:next(1,#def.filenames) local r = pr:next(1, #def.filenames)
local file = def.filenames[r] local file = def.filenames[r]
if file then if file then
local rot = rotations[pr:next(1,#rotations)] local rot = rotations[pr:next(1, #rotations)]
local ap = function(pos,def,pr,blockseed) end local ap = function(_, _, _, _) end
if def.daughters then if def.daughters then
ap = function(pos,def,pr,blockseed) ap = function(pos, def, pr, _)
for _,d in pairs(def.daughters) do for _, d in pairs(def.daughters) do
local p = vector.add(pos,d.pos) local p = vector.add(pos, d.pos)
local rot = d.rot or 0 local rot = d.rot or 0
mcl_structures.place_schematic(p, d.files[pr:next(1,#d.files)], rot, nil, true, "place_center_x,place_center_z",function() mcl_structures.place_schematic(p, d.files[pr:next(1, #d.files)], rot, nil, true, "place_center_x,place_center_z",
if def.loot then generate_loot(pp,def,pr,blockseed) end function()
if def.construct_nodes then construct_nodes(pp,def,pr,blockseed) end if def.loot then generate_loot(pp, def, pr) end
if def.construct_nodes then construct_nodes(pp, def, pr) end
if def.after_place then if def.after_place then
def.after_place(pos,def,pr) def.after_place(pos, def, pr)
end end
end,pr) end, pr)
end end
end end
elseif def.after_place then elseif def.after_place then
ap = def.after_place ap = def.after_place
end end
mcl_structures.place_schematic(pp, file, rot, def.replacements, true, "place_center_x,place_center_z",function(p1, p2, size, rotation) mcl_structures.place_schematic(pp, file, rot, def.replacements, true, "place_center_x,place_center_z",
function(p1, p2, size, rotation)
if not def.daughters then if not def.daughters then
if def.loot then generate_loot(pp,def,pr,blockseed) end if def.loot then generate_loot(pp, def, pr) end
if def.construct_nodes then construct_nodes(pp,def,pr,blockseed) end if def.construct_nodes then construct_nodes(pp, def, pr) end
end end
return ap(pp,def,pr,blockseed,p1,p2,size,rotation) return ap(pp, def, pr, blockseed)
end,pr) end, pr)
if log_enabled then if log_enabled then
minetest.log("action","[mcl_structures] "..def.name.." placed at "..minetest.pos_to_string(pp)) minetest.log("action", "[mcl_structures] " .. def.name .. " placed at " .. minetest.pos_to_string(pp))
end end
return true return true
end end
elseif def.place_func and def.place_func(pp,def,pr,blockseed) then elseif def.place_func and def.place_func(pp, def, pr, blockseed) then
if not def.after_place or ( def.after_place and def.after_place(pp,def,pr,blockseed) ) then if not def.after_place or (def.after_place and def.after_place(pp, def, pr, blockseed)) then
if def.loot then generate_loot(pp,def,pr,blockseed) end if def.loot then generate_loot(pp, def, pr) end
if def.construct_nodes then construct_nodes(pp,def,pr,blockseed) end if def.construct_nodes then construct_nodes(pp, def, pr) end
if log_enabled then if log_enabled then
minetest.log("action","[mcl_structures] "..def.name.." placed at "..minetest.pos_to_string(pp)) minetest.log("action", "[mcl_structures] " .. def.name .. " placed at " .. minetest.pos_to_string(pp))
end end
return true return true
end end
end end
if log_enabled then if log_enabled then
minetest.log("warning","[mcl_structures] placing "..def.name.." failed at "..minetest.pos_to_string(pos)) minetest.log("warning", "[mcl_structures] placing " .. def.name .. " failed at " .. minetest.pos_to_string(pos))
end 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
if mcl_structures.is_disabled(name) then return end if mcl_structures.is_disabled(name) then return end
local structblock = "mcl_structures:structblock_"..name local structblock = "mcl_structures:structblock_" .. name
local flags = "place_center_x, place_center_z, force_placement" local flags = "place_center_x, place_center_z, force_placement"
local y_offset = 0 local y_offset = 0
local sbgroups = { structblock = 1, not_in_creative_inventory=1 } local sbgroups = { structblock = 1, not_in_creative_inventory = 1 }
if def.flags then flags = def.flags end if def.flags then flags = def.flags end
def.name = name def.name = name
if nospawn then if nospawn then
@ -352,7 +408,7 @@ function mcl_structures.register_structure(name,def,nospawn) --nospawn means it
if def.place_on then if def.place_on then
minetest.register_on_mods_loaded(function() --make sure all previous decorations and biomes have been registered minetest.register_on_mods_loaded(function() --make sure all previous decorations and biomes have been registered
def.deco = minetest.register_decoration({ def.deco = minetest.register_decoration({
name = "mcl_structures:deco_"..name, name = "mcl_structures:deco_" .. name,
decoration = structblock, decoration = structblock,
deco_type = "simple", deco_type = "simple",
place_on = def.place_on, place_on = def.place_on,
@ -366,10 +422,11 @@ function mcl_structures.register_structure(name,def,nospawn) --nospawn means it
y_max = def.y_max, y_max = def.y_max,
y_min = def.y_min y_min = def.y_min
}) })
minetest.register_node(":"..structblock, {drawtype="airlike", walkable = false, pointable = false,groups = sbgroups,sunlight_propagates = true,}) minetest.register_node(":" .. structblock,
{ drawtype = "airlike", walkable = false, pointable = false, groups = sbgroups, sunlight_propagates = true, })
def.structblock = structblock def.structblock = structblock
def.deco_id = minetest.get_decoration_id("mcl_structures:deco_"..name) def.deco_id = minetest.get_decoration_id("mcl_structures:deco_" .. name)
minetest.set_gen_notify({decoration=true}, { def.deco_id }) minetest.set_gen_notify({ decoration = true }, { def.deco_id })
--catching of gennotify happens in mcl_mapgen_core --catching of gennotify happens in mcl_mapgen_core
end) end)
@ -382,7 +439,7 @@ local structure_spawns = {}
function mcl_structures.register_structure_spawn(def) function mcl_structures.register_structure_spawn(def)
--name,y_min,y_max,spawnon,biomes,chance,interval,limit --name,y_min,y_max,spawnon,biomes,chance,interval,limit
minetest.register_abm({ minetest.register_abm({
label = "Spawn "..def.name, label = "Spawn " .. def.name,
nodenames = def.spawnon, nodenames = def.spawnon,
min_y = def.y_min or -31000, min_y = def.y_min or -31000,
max_y = def.y_max or 31000, max_y = def.y_max or 31000,
@ -392,17 +449,17 @@ function mcl_structures.register_structure_spawn(def)
local limit = def.limit or 7 local limit = def.limit or 7
if active_object_count_wider > limit + mob_cap_animal then return end if active_object_count_wider > limit + mob_cap_animal then return end
if active_object_count_wider > mob_cap_player then return end if active_object_count_wider > mob_cap_player then return end
local p = vector.offset(pos,0,1,0) local p = vector.offset(pos, 0, 1, 0)
if minetest.get_node(p).name ~= "air" then return end if minetest.get_node(p).name ~= "air" then return end
if minetest.get_meta(pos):get_string("spawnblock") == "" then return end if minetest.get_meta(pos):get_string("spawnblock") == "" then return end
if mg_name ~= "v6" and mg_name ~= "singlenode" and def.biomes then if mg_name ~= "v6" and mg_name ~= "singlenode" and def.biomes then
if table.indexof(def.biomes,minetest.get_biome_name(minetest.get_biome_data(p).biome)) == -1 then if table.indexof(def.biomes, minetest.get_biome_name(minetest.get_biome_data(p).biome)) == -1 then
return return
end end
end end
local mobdef = minetest.registered_entities[def.name] local mobdef = minetest.registered_entities[def.name]
if mobdef.can_spawn and not mobdef.can_spawn(p) then return end if mobdef.can_spawn and not mobdef.can_spawn(p) then return end
minetest.add_entity(p,def.name) minetest.add_entity(p, def.name)
end, end,
}) })
end end
@ -411,10 +468,10 @@ end
minetest.register_lbm({ minetest.register_lbm({
name = "mcl_structures:struct_lbm", name = "mcl_structures:struct_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) 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
mcl_structures.place_structure(pos) mcl_structures.place_structure(pos)

View File

@ -1,18 +1,20 @@
local modname = minetest.get_current_modname() local modname = minetest.get_current_modname()
local S = minetest.get_translator(modname)
local modpath = minetest.get_modpath(modname) local modpath = minetest.get_modpath(modname)
local function temple_placement_callback(pos,def, pr) ---@param pos Vector
---@param def table
---@param pr PseudoRandom
local function temple_placement_callback(pos, def, pr)
local hl = def.sidelen / 2 local hl = def.sidelen / 2
local p1 = vector.offset(pos,-hl,-hl,-hl) local p1 = vector.offset(pos, -hl, -hl, -hl)
local p2 = vector.offset(pos,hl,hl,hl) local p2 = vector.offset(pos, hl, hl, hl)
-- Delete cacti leftovers: -- Delete cacti leftovers:
local cactus_nodes = minetest.find_nodes_in_area_under_air(p1, p2, "mcl_core:cactus") local cactus_nodes = minetest.find_nodes_in_area_under_air(p1, p2, "mcl_core:cactus")
if cactus_nodes and #cactus_nodes > 0 then if cactus_nodes and #cactus_nodes > 0 then
for _, pos in pairs(cactus_nodes) do for _, cpos in pairs(cactus_nodes) do
local node_below = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}) local node_below = minetest.get_node(vector.offset(cpos, 0, -1, 0))
if node_below and node_below.name == "mcl_core:sandstone" then if node_below and node_below.name == "mcl_core:sandstone" then
minetest.swap_node(pos, {name="air"}) minetest.swap_node(cpos, { name = "air" })
end end
end end
end end
@ -20,7 +22,7 @@ local function temple_placement_callback(pos,def, pr)
-- Initialize pressure plates and randomly remove up to 5 plates -- 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 = minetest.find_nodes_in_area(p1, p2, "mesecons_pressureplates:pressure_plate_stone_off")
local pplates_remove = 5 local pplates_remove = 5
for p=1, #pplates do for p = 1, #pplates do
if pplates_remove > 0 and pr:next(1, 100) >= 50 then if pplates_remove > 0 and pr:next(1, 100) >= 50 then
-- Remove plate -- Remove plate
minetest.remove_node(pplates[p]) minetest.remove_node(pplates[p])
@ -32,8 +34,8 @@ local function temple_placement_callback(pos,def, pr)
end end
end end
mcl_structures.register_structure("desert_temple",{ mcl_structures.register_structure("desert_temple", {
place_on = {"group:sand"}, place_on = { "group:sand" },
fill_ratio = 0.01, fill_ratio = 0.01,
flags = "place_center_x, place_center_z", flags = "place_center_x, place_center_z",
solid_ground = true, solid_ground = true,
@ -44,19 +46,19 @@ mcl_structures.register_structure("desert_temple",{
y_max = mcl_vars.mg_overworld_max, y_max = mcl_vars.mg_overworld_max,
y_min = 1, y_min = 1,
biomes = { "Desert" }, biomes = { "Desert" },
filenames = { modpath.."/schematics/mcl_structures_desert_temple.mts" }, filenames = { modpath .. "/schematics/mcl_structures_desert_temple.mts" },
after_place = temple_placement_callback, after_place = temple_placement_callback,
loot = { loot = {
["mcl_chests:chest" ] ={ ["mcl_chests:chest"] = {
{ {
stacks_min = 2, stacks_min = 2,
stacks_max = 4, stacks_max = 4,
items = { items = {
{ itemstring = "mcl_mobitems:bone", weight = 25, amount_min = 4, amount_max=6 }, { 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: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_mobitems:spider_eye", weight = 25, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_books:book", weight = 20, func = function(stack, pr) { itemstring = "mcl_books:book", weight = 20, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr)
end }, end },
{ itemstring = "mcl_mobitems:saddle", weight = 20, }, { itemstring = "mcl_mobitems:saddle", weight = 20, },
{ itemstring = "mcl_core:apple_gold", weight = 20, }, { itemstring = "mcl_core:apple_gold", weight = 20, },
@ -81,6 +83,7 @@ mcl_structures.register_structure("desert_temple",{
{ itemstring = "mcl_core:sand", 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 }, { itemstring = "mcl_mobitems:string", weight = 10, amount_min = 1, amount_max = 8 },
} }
}} }
}
} }
}) })

View File

@ -1,57 +1,57 @@
local modname = minetest.get_current_modname() local modname = minetest.get_current_modname()
local S = minetest.get_translator(modname)
local modpath = minetest.get_modpath(modname) local modpath = minetest.get_modpath(modname)
local spawnon = {"mcl_end:purpur_block"} local spawnon = { "mcl_end:purpur_block" }
local function spawn_shulkers(pos,def,pr) local function spawn_shulkers(pos, def, pr)
local p1 = vector.offset(pos,-def.sidelen/2,-1,-def.sidelen/2) local p1 = vector.offset(pos, -def.sidelen / 2, -1, -def.sidelen / 2)
local p2 = vector.offset(pos,def.sidelen/2,def.sidelen,def.sidelen/2) local p2 = vector.offset(pos, def.sidelen / 2, def.sidelen, def.sidelen / 2)
mcl_structures.spawn_mobs("mobs_mc:shulker",spawnon,p1,p2,pr,1) mcl_structures.spawn_mobs("mobs_mc:shulker", spawnon, p1, p2, pr, 1)
local guard = minetest.find_node_near(pos,def.sidelen,{"mcl_itemframes:item_frame"}) local guard = minetest.find_node_near(pos, def.sidelen, { "mcl_itemframes:item_frame" })
if guard then if guard then
minetest.add_entity(vector.offset(guard,0,-1.5,0),"mobs_mc:shulker") minetest.add_entity(vector.offset(guard, 0, -1.5, 0), "mobs_mc:shulker")
end end
end end
mcl_structures.register_structure("end_shipwreck",{ mcl_structures.register_structure("end_shipwreck", {
place_on = {"mcl_end:end_stone"}, place_on = { "mcl_end:end_stone" },
fill_ratio = 0.001, fill_ratio = 0.001,
flags = "place_center_x, place_center_z, all_floors", flags = "place_center_x, place_center_z, all_floors",
y_offset = function(pr) return pr:next(-50,-20) end, y_offset = function(pr) return pr:next(-50, -20) end,
chunk_probability = 800, chunk_probability = 800,
--y_max = mcl_vars.mg_end_max, --y_max = mcl_vars.mg_end_max,
--y_min = mcl_vars.mg_end_min -100, --y_min = mcl_vars.mg_end_min -100,
biomes = { "End", "EndHighlands", "EndMidlands", "EndBarrens", "EndSmallIslands" }, biomes = { "End", "EndHighlands", "EndMidlands", "EndBarrens", "EndSmallIslands" },
sidelen = 32, sidelen = 32,
filenames = { filenames = {
modpath.."/schematics/mcl_structures_end_shipwreck_1.mts", modpath .. "/schematics/mcl_structures_end_shipwreck_1.mts",
}, },
construct_nodes = {"mcl_chests:ender_chest_small","mcl_chests:ender_chest","mcl_brewing:stand_000","mcl_chests:violet_shulker_box_small"}, construct_nodes = { "mcl_chests:ender_chest_small", "mcl_chests:ender_chest", "mcl_brewing:stand_000",
after_place = function(pos,def,pr) "mcl_chests:violet_shulker_box_small" },
local fr = minetest.find_node_near(pos,def.sidelen,{"mcl_itemframes:item_frame"}) after_place = function(pos, def, pr)
local fr = minetest.find_node_near(pos, def.sidelen, { "mcl_itemframes:item_frame" })
if fr then if fr then
if mcl_itemframes then if mcl_itemframes then
mcl_itemframes.update_item_entity(fr,minetest.get_node(fr)) mcl_itemframes.update_item_entity(fr, minetest.get_node(fr))
end end
end end
return spawn_shulkers(pos,def,pr) return spawn_shulkers(pos, def, pr)
end, end,
loot = { loot = {
[ "mcl_itemframes:item_frame" ] ={{ ["mcl_itemframes:item_frame"] = { {
stacks_min = 1, stacks_min = 1,
stacks_max = 1, stacks_max = 1,
items = { items = {
{ itemstring = "mcl_armor:elytra", weight = 100 }, { itemstring = "mcl_armor:elytra", weight = 100 },
}, },
}}, } },
[ "mcl_chests:chest_small" ] ={{ ["mcl_chests:chest_small"] = { {
stacks_min = 2, stacks_min = 2,
stacks_max = 6, stacks_max = 6,
items = { items = {
{ itemstring = "mcl_mobitems:bone", weight = 20, amount_min = 4, amount_max=6 }, { itemstring = "mcl_mobitems:bone", weight = 20, amount_min = 4, amount_max = 6 },
{ itemstring = "mcl_farming:beetroot_seeds", weight = 16, amount_min = 1, amount_max=10 }, { itemstring = "mcl_farming:beetroot_seeds", weight = 16, amount_min = 1, amount_max = 10 },
{ itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, 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_bamboo:bamboo", weight = 15, amount_min = 1, amount_max=3 }, --FIXME BAMBOO
{ itemstring = "mcl_core:iron_ingot", weight = 15, amount_min = 4, amount_max = 8 }, { itemstring = "mcl_core:iron_ingot", weight = 15, amount_min = 4, amount_max = 8 },
@ -59,77 +59,104 @@ mcl_structures.register_structure("end_shipwreck",{
{ itemstring = "mcl_mobitems:saddle", weight = 3, }, { itemstring = "mcl_mobitems:saddle", weight = 3, },
{ itemstring = "mcl_core:emerald", weight = 2, amount_min = 1, amount_max = 3 }, { itemstring = "mcl_core:emerald", weight = 2, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_books:book", weight = 1, func = function(stack, pr) { itemstring = "mcl_books:book", weight = 1, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr)
end }, end },
{ itemstring = "mcl_tools:pick_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, { itemstring = "mcl_tools:pick_iron_enchanted", weight = 3,
{ itemstring = "mcl_tools:shovel_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_tools:sword_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, { itemstring = "mcl_tools:shovel_iron_enchanted", weight = 3,
{ itemstring = "mcl_armor:helmet_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_armor:chestplate_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, { itemstring = "mcl_tools:sword_iron_enchanted", weight = 3,
{ itemstring = "mcl_armor:leggings_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_armor:boots_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, { itemstring = "mcl_armor:helmet_iron_enchanted", weight = 3,
{ itemstring = "mcl_tools:pick_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_tools:shovel_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, { itemstring = "mcl_armor:chestplate_iron_enchanted", weight = 3,
{ itemstring = "mcl_tools:sword_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_armor:helmet_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, { itemstring = "mcl_armor:leggings_iron_enchanted", weight = 3,
{ itemstring = "mcl_armor:chestplate_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_armor:leggings_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, { itemstring = "mcl_armor:boots_iron_enchanted", weight = 3,
{ itemstring = "mcl_armor:boots_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_tools:pick_diamond_enchanted", weight = 3,
func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_tools:shovel_diamond_enchanted", weight = 3,
func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_tools:sword_diamond_enchanted", weight = 3,
func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_armor:helmet_diamond_enchanted", weight = 3,
func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_armor:chestplate_diamond_enchanted", weight = 3,
func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_armor:leggings_diamond_enchanted", weight = 3,
func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_armor:boots_diamond_enchanted", weight = 3,
func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_core:emerald", weight = 2, amount_min = 1, amount_max = 3 }, { itemstring = "mcl_core:emerald", weight = 2, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_mobitems:iron_horse_armor", weight = 1, }, { itemstring = "mcl_mobitems:iron_horse_armor", weight = 1, },
{ itemstring = "mcl_mobitems:gold_horse_armor", weight = 1, }, { itemstring = "mcl_mobitems:gold_horse_armor", weight = 1, },
{ itemstring = "mcl_mobitems:diamond_horse_armor", weight = 1, }, { itemstring = "mcl_mobitems:diamond_horse_armor", weight = 1, },
{ itemstring = "mcl_core:apple_gold_enchanted", weight = 2, }, { itemstring = "mcl_core:apple_gold_enchanted", weight = 2, },
} }
}} } }
} }
}) })
mcl_structures.register_structure("end_boat",{ mcl_structures.register_structure("end_boat", {
place_on = {"mcl_end:end_stone"}, place_on = { "mcl_end:end_stone" },
fill_ratio = 0.01, fill_ratio = 0.01,
flags = "place_center_x, place_center_z, all_floors", flags = "place_center_x, place_center_z, all_floors",
y_offset = function(pr) return pr:next(15,30) end, y_offset = function(pr) return pr:next(15, 30) end,
chunk_probability = 900, chunk_probability = 900,
--y_max = mcl_vars.mg_end_max, --y_max = mcl_vars.mg_end_max,
--y_min = mcl_vars.mg_end_min -100, --y_min = mcl_vars.mg_end_min -100,
biomes = { "End", "EndHighlands", "EndMidlands", "EndBarrens", "EndSmallIslands" }, biomes = { "End", "EndHighlands", "EndMidlands", "EndBarrens", "EndSmallIslands" },
sidelen = 20, sidelen = 20,
filenames = { filenames = {
modpath.."/schematics/mcl_structures_end_boat.mts", modpath .. "/schematics/mcl_structures_end_boat.mts",
}, },
after_place = spawn_shulkers, after_place = spawn_shulkers,
construct_nodes = {"mcl_chests:ender_chest_small","mcl_chests:ender_chest","mcl_brewing:stand_000","mcl_chests:violet_shulker_box_small"}, construct_nodes = { "mcl_chests:ender_chest_small", "mcl_chests:ender_chest", "mcl_brewing:stand_000",
"mcl_chests:violet_shulker_box_small" },
loot = { loot = {
[ "mcl_chests:chest_small" ] ={{ ["mcl_chests:chest_small"] = { {
stacks_min = 2, stacks_min = 2,
stacks_max = 6, stacks_max = 6,
items = { items = {
{ itemstring = "mcl_mobitems:bone", weight = 20, amount_min = 4, amount_max=6 }, { itemstring = "mcl_mobitems:bone", weight = 20, amount_min = 4, amount_max = 6 },
{ itemstring = "mcl_farming:beetroot_seeds", weight = 16, amount_min = 1, amount_max=10 }, { itemstring = "mcl_farming:beetroot_seeds", weight = 16, amount_min = 1, amount_max = 10 },
{ itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 }, { itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 },
{ itemstring = "mcl_core:iron_ingot", weight = 15, amount_min = 4, amount_max = 8 }, { itemstring = "mcl_core:iron_ingot", weight = 15, amount_min = 4, amount_max = 8 },
{ itemstring = "mcl_core:diamond", weight = 3, amount_min = 2, amount_max = 7 }, { itemstring = "mcl_core:diamond", weight = 3, amount_min = 2, amount_max = 7 },
{ itemstring = "mcl_mobitems:saddle", weight = 3, }, { itemstring = "mcl_mobitems:saddle", weight = 3, },
{ itemstring = "mcl_core:emerald", weight = 2, amount_min = 1, amount_max = 3 }, { itemstring = "mcl_core:emerald", weight = 2, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_tools:pick_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, { itemstring = "mcl_tools:pick_iron_enchanted", weight = 3,
{ itemstring = "mcl_tools:shovel_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_tools:sword_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, { itemstring = "mcl_tools:shovel_iron_enchanted", weight = 3,
{ itemstring = "mcl_armor:helmet_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_armor:chestplate_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, { itemstring = "mcl_tools:sword_iron_enchanted", weight = 3,
{ itemstring = "mcl_armor:leggings_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_armor:boots_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, { itemstring = "mcl_armor:helmet_iron_enchanted", weight = 3,
{ itemstring = "mcl_tools:pick_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_tools:shovel_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, { itemstring = "mcl_armor:chestplate_iron_enchanted", weight = 3,
{ itemstring = "mcl_armor:helmet_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_armor:leggings_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, { itemstring = "mcl_armor:leggings_iron_enchanted", weight = 3,
{ itemstring = "mcl_armor:boots_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_armor:boots_iron_enchanted", weight = 3,
func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_tools:pick_diamond_enchanted", weight = 3,
func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_tools:shovel_diamond_enchanted", weight = 3,
func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_armor:helmet_diamond_enchanted", weight = 3,
func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_armor:leggings_diamond_enchanted", weight = 3,
func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_armor:boots_diamond_enchanted", weight = 3,
func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_core:emerald", weight = 2, amount_min = 1, amount_max = 3 }, { itemstring = "mcl_core:emerald", weight = 2, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_mobitems:iron_horse_armor", weight = 1, }, { itemstring = "mcl_mobitems:iron_horse_armor", weight = 1, },
{ itemstring = "mcl_mobitems:gold_horse_armor", weight = 1, }, { itemstring = "mcl_mobitems:gold_horse_armor", weight = 1, },
{ itemstring = "mcl_core:apple_gold_enchanted", weight = 2, }, { itemstring = "mcl_core:apple_gold_enchanted", weight = 2, },
} }
}} } }
} }
}) })

View File

@ -1,34 +1,35 @@
local modname = minetest.get_current_modname() local modname = minetest.get_current_modname()
local S = minetest.get_translator(modname)
local modpath = minetest.get_modpath(modname) local modpath = minetest.get_modpath(modname)
mcl_structures.register_structure("end_spawn_obsidian_platform",{ mcl_structures.register_structure("end_spawn_obsidian_platform", {
static_pos ={mcl_vars.mg_end_platform_pos}, static_pos = { mcl_vars.mg_end_platform_pos },
place_func = function(pos,def,pr) place_func = function(pos, def, pr)
local obby = minetest.find_nodes_in_area(vector.offset(pos,-2,0,-2),vector.offset(pos,2,0,2),{"air","mcl_end:end_stone"}) local obby = minetest.find_nodes_in_area(vector.offset(pos, -2, 0, -2), vector.offset(pos, 2, 0, 2),
local air = minetest.find_nodes_in_area(vector.offset(pos,-2,1,-2),vector.offset(pos,2,3,2),{"air","mcl_end:end_stone"}) { "air", "mcl_end:end_stone" })
minetest.bulk_set_node(obby,{name="mcl_core:obsidian"}) local air = minetest.find_nodes_in_area(vector.offset(pos, -2, 1, -2), vector.offset(pos, 2, 3, 2),
minetest.bulk_set_node(air,{name="air"}) { "air", "mcl_end:end_stone" })
minetest.bulk_set_node(obby, { name = "mcl_core:obsidian" })
minetest.bulk_set_node(air, { name = "air" })
return true return true
end, end,
}) })
mcl_structures.register_structure("end_exit_portal",{ mcl_structures.register_structure("end_exit_portal", {
static_pos = { mcl_vars.mg_end_exit_portal_pos }, static_pos = { mcl_vars.mg_end_exit_portal_pos },
filenames = { filenames = {
modpath.."/schematics/mcl_structures_end_exit_portal.mts" modpath .. "/schematics/mcl_structures_end_exit_portal.mts"
}, },
after_place = function(pos,def,pr,blockseed) after_place = function(pos, def, pr, blockseed)
if minetest.settings:get_bool("only_peaceful_mobs", false) then if minetest.settings:get_bool("only_peaceful_mobs", false) then
return return
end end
local p1 = vector.offset(pos,-16,-16,-16) local p1 = vector.offset(pos, -16, -16, -16)
local p2 = vector.offset(pos,16,21,16) local p2 = vector.offset(pos, 16, 21, 16)
minetest.emerge_area(p1,p2,function(blockpos, action, calls_remaining, param) minetest.emerge_area(p1, p2, function(blockpos, action, calls_remaining, param)
if calls_remaining > 0 then return end if calls_remaining > 0 then return end
minetest.bulk_set_node(minetest.find_nodes_in_area(p1,p2,{"mcl_portals:portal_end"}),{name="air"}) minetest.bulk_set_node(minetest.find_nodes_in_area(p1, p2, { "mcl_portals:portal_end" }), { name = "air" })
local obj = minetest.add_entity(vector.offset(pos,3, 11, 3), "mobs_mc:enderdragon") local obj = minetest.add_entity(vector.offset(pos, 3, 11, 3), "mobs_mc:enderdragon")
if obj then if obj then
local dragon_entity = obj:get_luaentity() local dragon_entity = obj:get_luaentity()
dragon_entity._portal_pos = pos dragon_entity._portal_pos = pos
@ -38,84 +39,88 @@ mcl_structures.register_structure("end_exit_portal",{
else else
minetest.log("error", "[mcl_mapgen_core] ERROR! Ender dragon doesn't want to spawn") minetest.log("error", "[mcl_mapgen_core] ERROR! Ender dragon doesn't want to spawn")
end end
minetest.fix_light(p1,p2) minetest.fix_light(p1, p2)
end) end)
end end
}) })
mcl_structures.register_structure("end_exit_portal_open",{ mcl_structures.register_structure("end_exit_portal_open", {
filenames = { filenames = {
modpath.."/schematics/mcl_structures_end_exit_portal.mts" modpath .. "/schematics/mcl_structures_end_exit_portal.mts"
}, },
after_place = function(pos,def,pr) after_place = function(pos, def, pr)
local p1 = vector.offset(pos,-16,-16,-16) local p1 = vector.offset(pos, -16, -16, -16)
local p2 = vector.offset(pos,16,16,16) local p2 = vector.offset(pos, 16, 16, 16)
minetest.fix_light(p1,p2) minetest.fix_light(p1, p2)
end end
}) })
mcl_structures.register_structure("end_gateway_portal",{ mcl_structures.register_structure("end_gateway_portal", {
filenames = { filenames = {
modpath.."/schematics/mcl_structures_end_gateway_portal.mts" modpath .. "/schematics/mcl_structures_end_gateway_portal.mts"
}, },
}) })
local function get_tower(p,h,tbl) local function get_tower(p, h, tbl)
for i = 1,h do for i = 1, h do
table.insert(tbl,vector.offset(p,0,i,0)) table.insert(tbl, vector.offset(p, 0, i, 0))
end end
end end
local function make_endspike(pos,width,height) local function make_endspike(pos, width, height)
local nn = minetest.find_nodes_in_area(vector.offset(pos,-width/2,0,-width/2),vector.offset(pos,width/2,0,width/2),{"air","group:solid"}) local nn = minetest.find_nodes_in_area(vector.offset(pos, -width / 2, 0, -width / 2),
table.sort(nn,function(a, b) vector.offset(pos, width / 2, 0, width / 2), { "air", "group:solid" })
table.sort(nn, function(a, b)
return vector.distance(pos, a) < vector.distance(pos, b) return vector.distance(pos, a) < vector.distance(pos, b)
end) end)
local nodes = {} local nodes = {}
for i = 1,math.ceil(#nn*0.55) do for i = 1, math.ceil(#nn * 0.55) do
get_tower(nn[i],height,nodes) get_tower(nn[i], height, nodes)
end end
minetest.bulk_set_node(nodes,{ name="mcl_core:obsidian"} ) minetest.bulk_set_node(nodes, { name = "mcl_core:obsidian" })
return vector.offset(pos,0,height,0) return vector.offset(pos, 0, height, 0)
end end
function make_cage(pos,width) local function make_cage(pos, width)
local nodes = {} local nodes = {}
local nodes2 = {} local nodes2 = {}
local r = math.max(1,math.floor(width/2) - 2) local r = math.max(1, math.floor(width / 2) - 2)
for x=-r,r do for y = 0,width do for z = -r,r do for x = -r, r do for y = 0, width do for z = -r, r do
if x == r or x == -r or z==r or z == -r then if x == r or x == -r or z == r or z == -r then
table.insert(nodes,vector.add(pos,vector.new(x,y,z))) table.insert(nodes, vector.add(pos, vector.new(x, y, z)))
end
end
end
end end
end end end
if xpanes then if xpanes then
minetest.bulk_set_node(nodes,{ name="xpanes:bar_flat"} ) minetest.bulk_set_node(nodes, { name = "xpanes:bar_flat" })
for _,p in pairs(nodes) do for _, p in pairs(nodes) do
xpanes.update_pane(p) xpanes.update_pane(p)
end end
end end
end end
local function get_points_on_circle(pos,r,n) local function get_points_on_circle(pos, r, n)
local rt = {} local rt = {}
for i=1, n do for i = 1, n do
table.insert(rt,vector.offset(pos,r * math.cos(((i-1)/n) * (2*math.pi)),0, r* math.sin(((i-1)/n) * (2*math.pi)) )) table.insert(rt, vector.offset(pos, r * math.cos(((i - 1) / n) * (2 * math.pi)), 0,
r * math.sin(((i - 1) / n) * (2 * math.pi))))
end end
return rt return rt
end end
mcl_structures.register_structure("end_spike",{ mcl_structures.register_structure("end_spike", {
static_pos =get_points_on_circle(vector.offset(mcl_vars.mg_end_exit_portal_pos,0,-20,0),43,10), static_pos = get_points_on_circle(vector.offset(mcl_vars.mg_end_exit_portal_pos, 0, -20, 0), 43, 10),
place_func = function(pos,def,pr) place_func = function(pos, def, pr)
local d = pr:next(6,12) local d = pr:next(6, 12)
local h = d * pr:next(4,6) local h = d * pr:next(4, 6)
local p1 = vector.offset(pos, -d / 2, 0, -d / 2) local p1 = vector.offset(pos, -d / 2, 0, -d / 2)
local p2 = vector.offset(pos, d / 2, h + d, d / 2) local p2 = vector.offset(pos, d / 2, h + d, d / 2)
minetest.emerge_area(p1, p2, function(blockpos, action, calls_remaining, param) minetest.emerge_area(p1, p2, function(blockpos, action, calls_remaining, param)
if calls_remaining ~= 0 then return end if calls_remaining ~= 0 then return end
local s = make_endspike(pos,d,h) local s = make_endspike(pos, d, h)
minetest.set_node(vector.offset(s,0,1,0),{name="mcl_core:bedrock"}) minetest.set_node(vector.offset(s, 0, 1, 0), { name = "mcl_core:bedrock" })
minetest.add_entity(vector.offset(s,0,2,0),"mcl_end:crystal") minetest.add_entity(vector.offset(s, 0, 2, 0), "mcl_end:crystal")
if pr:next(1,3) == 1 then if pr:next(1, 3) == 1 then
make_cage(vector.offset(s,0,1,0),d) make_cage(vector.offset(s, 0, 1, 0), d)
end end
end) end)
return true return true

View File

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

View File

@ -1,54 +1,64 @@
local modname = minetest.get_current_modname() local modname = minetest.get_current_modname()
local S = minetest.get_translator(modname)
local modpath = minetest.get_modpath(modname) local modpath = minetest.get_modpath(modname)
---@param pos Vector
---@param pr PseudoRandom
---@return boolean|nil
---@return string
function mcl_structures.generate_igloo_top(pos, pr) function mcl_structures.generate_igloo_top(pos, pr)
-- Furnace does ot work atm because apparently meta is not set. Need a bit of help with fixing this for furnaces, bookshelves, and brewing stands. -- Furnace does ot work atm because apparently meta is not set. Need a bit of help with fixing this for furnaces, bookshelves, and brewing stands.
local newpos = {x=pos.x,y=pos.y-2,z=pos.z} local newpos = vector.offset(pos, 0, -2, 0)
local path = modpath.."/schematics/mcl_structures_igloo_top.mts" local path = modpath .. "/schematics/mcl_structures_igloo_top.mts"
local rotation = tostring(pr:next(0,3)*90) local rotation = tostring(pr:next(0, 3) * 90)
return mcl_structures.place_schematic(newpos, path, rotation, nil, true, nil, function() return mcl_structures.place_schematic(newpos, path, rotation, nil, true, nil, function()
local p1 = vector.offset(pos,-5,-5,-5) local p1 = vector.offset(pos, -5, -5, -5)
local p2 = vector.offset(pos,5,5,5) local p2 = vector.offset(pos, 5, 5, 5)
mcl_structures.construct_nodes(p1,p2,{"mcl_furnaces:furnace","mcl_books:bookshelf"}) mcl_structures.construct_nodes(p1, p2, { "mcl_furnaces:furnace", "mcl_books:bookshelf" })
end), rotation end), rotation
end end
local function spawn_mobs(p1,p2,vi,zv) local function spawn_mobs(p1, p2, vi, zv)
local mc = minetest.find_nodes_in_area_under_air(p1,p2,{"mcl_core:stonebrickmossy"}) local mc = minetest.find_nodes_in_area_under_air(p1, p2, { "mcl_core:stonebrickmossy" })
if #mc == 2 then if #mc == 2 then
local vp = mc[1] local vp = mc[1]
local zp = mc[2] local zp = mc[2]
if not vi and zv and zv:get_pos() and vector.distance(mc[1],zv:get_pos()) < 2 then if not vi and zv and zv:get_pos() and vector.distance(mc[1], zv:get_pos()) < 2 then
vp = mc[2] vp = mc[2]
elseif not zv and vi and vi:get_pos() and vector.distance(mc[2],vi:get_pos()) < 2 then elseif not zv and vi and vi:get_pos() and vector.distance(mc[2], vi:get_pos()) < 2 then
zp = mc[1] zp = mc[1]
elseif zv and vi then elseif zv and vi then
return return
end end
vi = minetest.add_entity(vector.offset(mc[1],0,1,0),"mobs_mc:villager") vi = minetest.add_entity(vector.offset(mc[1], 0, 1, 0), "mobs_mc:villager")
zv = minetest.add_entity(vector.offset(mc[2],0,1,0),"mobs_mc:villager_zombie") zv = minetest.add_entity(vector.offset(mc[2], 0, 1, 0), "mobs_mc:villager_zombie")
minetest.after(1,spawn_mobs,p1,p2,vi,zv) minetest.after(1, spawn_mobs, p1, p2, vi, zv)
end end
end end
---@param pos Vector
---@param orientation any
---@param loot any
---@param pr PseudoRandom
function mcl_structures.generate_igloo_basement(pos, orientation, loot, pr) function mcl_structures.generate_igloo_basement(pos, orientation, loot, pr)
-- TODO: Add monster eggs -- TODO: Add monster eggs
local path = modpath.."/schematics/mcl_structures_igloo_basement.mts" local path = modpath .. "/schematics/mcl_structures_igloo_basement.mts"
mcl_structures.place_schematic(pos, path, orientation, nil, true, nil, function() mcl_structures.place_schematic(pos, path, orientation, nil, true, nil, function()
local p1 = vector.offset(pos,-5,-5,-5) local p1 = vector.offset(pos, -5, -5, -5)
local p2 = vector.offset(pos,5,5,5) local p2 = vector.offset(pos, 5, 5, 5)
mcl_structures.fill_chests(p1,p2,loot,pr) mcl_structures.fill_chests(p1, p2, loot, pr)
mcl_structures.construct_nodes(p1,p2,{"mcl_brewing:stand_000","mcl_books:bookshelf"}) mcl_structures.construct_nodes(p1, p2, { "mcl_brewing:stand_000", "mcl_books:bookshelf" })
spawn_mobs(p1,p2) spawn_mobs(p1, p2)
end, pr) end, pr)
end end
---@param pos Vector
---@param def table
---@param pr PseudoRandom
function mcl_structures.generate_igloo(pos, def, pr) function mcl_structures.generate_igloo(pos, def, pr)
-- Place igloo -- Place igloo
local success, rotation = mcl_structures.generate_igloo_top(pos, pr) local success, rotation = mcl_structures.generate_igloo_top(pos, pr)
-- Place igloo basement with 50% chance -- Place igloo basement with 50% chance
local r = pr:next(1,2) local r = pr:next(1, 2)
if r == 1 then if r == 1 then
-- Select basement depth -- Select basement depth
local dim = mcl_worlds.pos_to_dimension(pos) local dim = mcl_worlds.pos_to_dimension(pos)
@ -67,26 +77,26 @@ function mcl_structures.generate_igloo(pos, def, pr)
return success return success
end end
local depth = pr:next(19, buffer) local depth = pr:next(19, buffer)
local bpos = {x=pos.x, y=pos.y-depth, z=pos.z} local bpos = vector.offset(pos, 0, -depth, 0)
-- trapdoor position -- trapdoor position
local tpos local tpos
local dir, tdir local dir, tdir
if rotation == "0" then if rotation == "0" then
dir = {x=-1, y=0, z=0} dir = vector.new(-1, 0, 0)
tdir = {x=1, y=0, z=0} tdir = vector.new(1, 0, 0)
tpos = {x=pos.x+7, y=pos.y-2, z=pos.z+3} tpos = vector.offset(pos, 7, -2, 3)
elseif rotation == "90" then elseif rotation == "90" then
dir = {x=0, y=0, z=-1} dir = vector.new(0, 0, -1)
tdir = {x=0, y=0, z=-1} tdir = vector.new(0, 0, -1)
tpos = {x=pos.x+3, y=pos.y-2, z=pos.z+1} tpos = vector.offset(pos, 3, -2, 1)
elseif rotation == "180" then elseif rotation == "180" then
dir = {x=1, y=0, z=0} dir = vector.new(1, 0, 0)
tdir = {x=-1, y=0, z=0} tdir = vector.new(-1, 0, 0)
tpos = {x=pos.x+1, y=pos.y-2, z=pos.z+3} tpos = vector.offset(pos, 1, -2, 3)
elseif rotation == "270" then elseif rotation == "270" then
dir = {x=0, y=0, z=1} dir = vector.new(0, 0, 1)
tdir = {x=0, y=0, z=1} tdir = vector.new(0, 0, 1)
tpos = {x=pos.x+3, y=pos.y-2, z=pos.z+7} tpos = vector.offset(pos, 3, -2, 7)
else else
return success return success
end end
@ -107,17 +117,18 @@ function mcl_structures.generate_igloo(pos, def, pr)
brick = "mcl_core:stonebrick" brick = "mcl_core:stonebrick"
end end
end end
minetest.set_node(pos, {name=brick}) minetest.set_node(pos, { name = brick })
end end
local ladder_param2 = minetest.dir_to_wallmounted(tdir) local ladder_param2 = minetest.dir_to_wallmounted(tdir)
local real_depth = 0 local real_depth = 0
-- Check how deep we can actuall dig -- Check how deep we can actuall dig
for y=1, depth-5 do for y = 1, depth - 5 do
real_depth = real_depth + 1 real_depth = real_depth + 1
local node = minetest.get_node({x=tpos.x,y=tpos.y-y,z=tpos.z}) local node = minetest.get_node(vector.offset(tpos, 0, -y, 0))
local def = minetest.registered_nodes[node.name] local ndef = minetest.registered_nodes[node.name]
if not (def and def.walkable and def.liquidtype == "none" and def.is_ground_content) then if not (ndef and ndef.walkable and ndef.liquidtype == "none" and ndef.is_ground_content) then
bpos.y = tpos.y-y+1 bpos.y = tpos.y - y + 1
break break
end end
end end
@ -125,25 +136,25 @@ function mcl_structures.generate_igloo(pos, def, pr)
return success return success
end end
-- Generate ladder to basement -- Generate ladder to basement
for y=1, real_depth-1 do for y = 1, real_depth - 1 do
set_brick({x=tpos.x-1,y=tpos.y-y,z=tpos.z }) set_brick(vector.offset(tpos, -1, -y, 0))
set_brick({x=tpos.x+1,y=tpos.y-y,z=tpos.z }) set_brick(vector.offset(tpos, 1, -y, 0))
set_brick({x=tpos.x ,y=tpos.y-y,z=tpos.z-1}) set_brick(vector.offset(tpos, 0, -y, -1))
set_brick({x=tpos.x ,y=tpos.y-y,z=tpos.z+1}) set_brick(vector.offset(tpos, 0, -y, 1))
minetest.set_node({x=tpos.x,y=tpos.y-y,z=tpos.z}, {name="mcl_core:ladder", param2=ladder_param2}) minetest.set_node(vector.offset(tpos, 0, -y, 0), { name = "mcl_core:ladder", param2 = ladder_param2 })
end end
-- Place basement -- Place basement
mcl_structures.generate_igloo_basement(bpos, rotation, def.loot, pr) mcl_structures.generate_igloo_basement(bpos, rotation, def.loot, pr)
-- Place hidden trapdoor -- Place hidden trapdoor
minetest.after(5, function(tpos, dir) minetest.after(5, function(tpos2, dir2)
minetest.set_node(tpos, {name="mcl_doors:trapdoor", param2=20+minetest.dir_to_facedir(dir)}) -- TODO: more reliable param2 minetest.set_node(tpos2, { name = "mcl_doors:trapdoor", param2 = 20 + minetest.dir_to_facedir(dir2) }) -- TODO: more reliable param2
end, tpos, dir) end, tpos, dir)
end end
return success return success
end end
mcl_structures.register_structure("igloo",{ mcl_structures.register_structure("igloo", {
place_on = {"mcl_core:snowblock","mcl_core:snow","group:grass_block_snow"}, place_on = { "mcl_core:snowblock", "mcl_core:snow", "group:grass_block_snow" },
fill_ratio = 0.01, fill_ratio = 0.01,
sidelen = 16, sidelen = 16,
chunk_probability = 250, chunk_probability = 250,
@ -155,7 +166,7 @@ mcl_structures.register_structure("igloo",{
biomes = { "ColdTaiga", "IcePlainsSpikes", "IcePlains" }, biomes = { "ColdTaiga", "IcePlainsSpikes", "IcePlains" },
place_func = mcl_structures.generate_igloo, place_func = mcl_structures.generate_igloo,
loot = { loot = {
["mcl_chests:chest_small"] = {{ ["mcl_chests:chest_small"] = { {
stacks_min = 1, stacks_min = 1,
stacks_max = 1, stacks_max = 1,
items = { items = {
@ -175,6 +186,6 @@ mcl_structures.register_structure("igloo",{
{ itemstring = "mcl_core:emerald", weight = 1 }, { itemstring = "mcl_core:emerald", weight = 1 },
{ itemstring = "mcl_core:apple_gold", weight = 1 }, { itemstring = "mcl_core:apple_gold", weight = 1 },
} }
}}, } },
} }
}) })

View File

@ -4,23 +4,23 @@ local modpath = minetest.get_modpath(modname)
mcl_structures = {} mcl_structures = {}
dofile(modpath.."/api.lua") dofile(modpath .. "/api.lua")
dofile(modpath.."/shipwrecks.lua") dofile(modpath .. "/shipwrecks.lua")
dofile(modpath.."/desert_temple.lua") dofile(modpath .. "/desert_temple.lua")
dofile(modpath.."/jungle_temple.lua") dofile(modpath .. "/jungle_temple.lua")
dofile(modpath.."/ocean_ruins.lua") dofile(modpath .. "/ocean_ruins.lua")
dofile(modpath.."/witch_hut.lua") dofile(modpath .. "/witch_hut.lua")
dofile(modpath.."/igloo.lua") dofile(modpath .. "/igloo.lua")
dofile(modpath.."/woodland_mansion.lua") dofile(modpath .. "/woodland_mansion.lua")
dofile(modpath.."/ruined_portal.lua") dofile(modpath .. "/ruined_portal.lua")
dofile(modpath.."/geode.lua") dofile(modpath .. "/geode.lua")
dofile(modpath.."/pillager_outpost.lua") dofile(modpath .. "/pillager_outpost.lua")
dofile(modpath.."/end_spawn.lua") dofile(modpath .. "/end_spawn.lua")
dofile(modpath.."/end_city.lua") dofile(modpath .. "/end_city.lua")
mcl_structures.register_structure("desert_well",{ mcl_structures.register_structure("desert_well", {
place_on = {"group:sand"}, place_on = { "group:sand" },
fill_ratio = 0.01, fill_ratio = 0.01,
flags = "place_center_x, place_center_z", flags = "place_center_x, place_center_z",
not_near = { "desert_temple_new" }, not_near = { "desert_temple_new" },
@ -31,51 +31,55 @@ mcl_structures.register_structure("desert_well",{
y_min = 1, y_min = 1,
y_offset = -2, y_offset = -2,
biomes = { "Desert" }, biomes = { "Desert" },
filenames = { modpath.."/schematics/mcl_structures_desert_well.mts" }, filenames = { modpath .. "/schematics/mcl_structures_desert_well.mts" },
}) })
mcl_structures.register_structure("fossil",{ mcl_structures.register_structure("fossil", {
place_on = {"group:material_stone","group:sand"}, place_on = { "group:material_stone", "group:sand" },
fill_ratio = 0.01, fill_ratio = 0.01,
flags = "place_center_x, place_center_z", flags = "place_center_x, place_center_z",
solid_ground = true, solid_ground = true,
sidelen = 13, sidelen = 13,
chunk_probability = 1000, chunk_probability = 1000,
y_offset = function(pr) return ( pr:next(1,16) * -1 ) -16 end, y_offset = function(pr) return (pr:next(1, 16) * -1) - 16 end,
y_max = 15, y_max = 15,
y_min = mcl_vars.mg_overworld_min + 35, y_min = mcl_vars.mg_overworld_min + 35,
biomes = { "Desert" }, biomes = { "Desert" },
filenames = { filenames = {
modpath.."/schematics/mcl_structures_fossil_skull_1.mts", -- 4×5×5 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_2.mts", -- 5×5×5
modpath.."/schematics/mcl_structures_fossil_skull_3.mts", -- 5×5×7 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_skull_4.mts", -- 7×5×5
modpath.."/schematics/mcl_structures_fossil_spine_1.mts", -- 3×3×13 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_2.mts", -- 5×4×13
modpath.."/schematics/mcl_structures_fossil_spine_3.mts", -- 7×4×13 modpath .. "/schematics/mcl_structures_fossil_spine_3.mts", -- 7×4×13
modpath.."/schematics/mcl_structures_fossil_spine_4.mts", -- 8×5×13 modpath .. "/schematics/mcl_structures_fossil_spine_4.mts", -- 8×5×13
}, },
}) })
mcl_structures.register_structure("boulder",{ mcl_structures.register_structure("boulder", {
filenames = { 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_small.mts",
modpath.."/schematics/mcl_structures_boulder_small.mts", modpath .. "/schematics/mcl_structures_boulder_small.mts",
modpath.."/schematics/mcl_structures_boulder.mts", modpath .. "/schematics/mcl_structures_boulder.mts",
-- small boulder 3x as likely -- small boulder 3x as likely
}, },
},true) --is spawned as a normal decoration. this is just for /spawnstruct }, true) --is spawned as a normal decoration. this is just for /spawnstruct
mcl_structures.register_structure("ice_spike_small",{ mcl_structures.register_structure("ice_spike_small", {
filenames = { modpath.."/schematics/mcl_structures_ice_spike_small.mts" }, filenames = { modpath .. "/schematics/mcl_structures_ice_spike_small.mts" },
},true) --is spawned as a normal decoration. this is just for /spawnstruct }, true) --is spawned as a normal decoration. this is just for /spawnstruct
mcl_structures.register_structure("ice_spike_large",{
mcl_structures.register_structure("ice_spike_large", {
sidelen = 6, sidelen = 6,
filenames = { modpath.."/schematics/mcl_structures_ice_spike_large.mts" }, filenames = { modpath .. "/schematics/mcl_structures_ice_spike_large.mts" },
},true) --is spawned as a normal decoration. this is just for /spawnstruct }, true) --is spawned as a normal decoration. this is just for /spawnstruct
-- Debug command
---Debug command
---@param dir Vector
---@return '"0"'|'"90"'|'"180"'|'"270"'
local function dir_to_rotation(dir) local function dir_to_rotation(dir)
local ax, az = math.abs(dir.x), math.abs(dir.z) local ax, az = math.abs(dir.x), math.abs(dir.z)
if ax > az then if ax > az then
@ -93,43 +97,49 @@ end
minetest.register_chatcommand("spawnstruct", { minetest.register_chatcommand("spawnstruct", {
params = "dungeon", params = "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)
local player = minetest.get_player_by_name(name) local player = minetest.get_player_by_name(name)
if not player then return end
if not player then
return false, S("Player isn't online")
end
local pos = player:get_pos() local pos = player:get_pos()
if not pos then return end
pos = vector.round(pos) pos = vector.round(pos)
local dir = minetest.yaw_to_dir(player:get_look_horizontal()) local dir = minetest.yaw_to_dir(player:get_look_horizontal())
local rot = dir_to_rotation(dir) local rot = dir_to_rotation(dir)
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.")
local uknown_struct_message = S("Error: Unknown structure type. Please use “/spawnstruct <type>”.") ..
"\n" .. S("Use /help spawnstruct to see a list of avaiable types.")
if param == "dungeon" and mcl_dungeons and mcl_dungeons.spawn_dungeon then if param == "dungeon" and mcl_dungeons and mcl_dungeons.spawn_dungeon then
mcl_dungeons.spawn_dungeon(pos, rot, pr) mcl_dungeons.spawn_dungeon(pos, rot, pr)
elseif param == "" then
message = S("Error: No structure type given. Please use “/spawnstruct <type>”.")
errord = true
else else
for n,d in pairs(mcl_structures.registered_structures) do if mcl_structures.registered_structures[param] then
if n == param then mcl_structures.place_structure(pos, mcl_structures.registered_structures[param], pr, math.random(), rot)
mcl_structures.place_structure(pos,d,pr,math.random(),rot) else
return true,message message = uknown_struct_message
end
end
message = S("Error: Unknown structure type. Please use “/spawnstruct <type>”.")
errord = true errord = true
end end
minetest.chat_send_player(name, message) end
if errord then if errord then
minetest.chat_send_player(name, S("Use /help spawnstruct to see a list of avaiable types.")) return false, message
else
return true, message
end end
end end
}) })
minetest.register_on_mods_loaded(function() minetest.register_on_mods_loaded(function()
local p = "" local p = ""
for n,_ in pairs(mcl_structures.registered_structures) do for n, _ in pairs(mcl_structures.registered_structures) do
p = p .. " | "..n p = p .. " | " .. n
end end
minetest.registered_chatcommands["spawnstruct"].params = minetest.registered_chatcommands["spawnstruct"].params .. p minetest.registered_chatcommands["spawnstruct"].params = minetest.registered_chatcommands["spawnstruct"].params .. p
end) end)

View File

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

View File

@ -1,5 +1,4 @@
local modname = minetest.get_current_modname() local modname = minetest.get_current_modname()
local S = minetest.get_translator(modname)
local modpath = minetest.get_modpath(modname) local modpath = minetest.get_modpath(modname)
local cold_oceans = { local cold_oceans = {
@ -71,8 +70,8 @@ local warm_oceans = {
} }
local cold = { local cold = {
place_on = {"group:sand","mcl_core:gravel","mcl_core:dirt","mcl_core:clay","group:material_stone"}, place_on = { "group:sand", "mcl_core:gravel", "mcl_core:dirt", "mcl_core:clay", "group:material_stone" },
spawn_by = {"mcl_core:water_source"}, spawn_by = { "mcl_core:water_source" },
num_spawn_by = 2, num_spawn_by = 2,
fill_ratio = 0.01, fill_ratio = 0.01,
flags = "place_center_x, place_center_z, force_placement", flags = "place_center_x, place_center_z, force_placement",
@ -85,26 +84,26 @@ local cold = {
chunk_probability = 400, chunk_probability = 400,
sidelen = 20, sidelen = 20,
filenames = { filenames = {
modpath.."/schematics/mcl_structures_ocean_ruins_cold_1.mts", 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_2.mts",
modpath.."/schematics/mcl_structures_ocean_ruins_cold_3.mts", modpath .. "/schematics/mcl_structures_ocean_ruins_cold_3.mts",
}, },
loot = { loot = {
["mcl_chests:chest_small" ] = { ["mcl_chests:chest_small"] = {
{ {
stacks_min = 2, stacks_min = 2,
stacks_max = 4, stacks_max = 4,
items = { items = {
{ itemstring = "mcl_core:coal_lump", weight = 25, amount_min = 1, amount_max=4 }, { 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_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_core:gold_nugget", weight = 25, amount_min = 1, amount_max = 3 },
--{ itemstring = "mcl_maps:treasure_map", weight = 20, }, --FIXME Treasure map --{ itemstring = "mcl_maps:treasure_map", weight = 20, }, --FIXME Treasure map
{ itemstring = "mcl_books:book", weight = 10, func = function(stack, pr) { itemstring = "mcl_books:book", weight = 10, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr)
end }, end },
{ itemstring = "mcl_fishing:fishing_rod_enchanted", weight = 20, func = function(stack, pr) { itemstring = "mcl_fishing:fishing_rod_enchanted", weight = 20, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr)
end }, end },
{ itemstring = "mcl_core:emerald", weight = 15, amount_min = 1, amount_max = 1 }, { 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_armor:chestplate_leather", weight = 15, amount_min = 1, amount_max = 1 },
@ -122,11 +121,11 @@ local cold = {
local warm = table.copy(cold) local warm = table.copy(cold)
warm.biomes = warm_oceans warm.biomes = warm_oceans
warm.filenames = { warm.filenames = {
modpath.."/schematics/mcl_structures_ocean_ruins_warm_1.mts", 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_2.mts",
modpath.."/schematics/mcl_structures_ocean_ruins_warm_3.mts", modpath .. "/schematics/mcl_structures_ocean_ruins_warm_3.mts",
modpath.."/schematics/mcl_structures_ocean_ruins_warm_4.mts", modpath .. "/schematics/mcl_structures_ocean_ruins_warm_4.mts",
} }
mcl_structures.register_structure("cold_ocean_ruins",cold) mcl_structures.register_structure("cold_ocean_ruins", cold)
mcl_structures.register_structure("warm_ocean_ruins",warm) mcl_structures.register_structure("warm_ocean_ruins", warm)

View File

@ -1,12 +1,11 @@
local modname = minetest.get_current_modname() local modname = minetest.get_current_modname()
local S = minetest.get_translator(modname)
local modpath = minetest.get_modpath(modname) local modpath = minetest.get_modpath(modname)
local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false) --local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false)
local spawnon = {"mcl_core:stripped_oak","mcl_stairs:slab_birchwood_top"} local spawnon = { "mcl_core:stripped_oak", "mcl_stairs:slab_birchwood_top" }
mcl_structures.register_structure("pillager_outpost",{ mcl_structures.register_structure("pillager_outpost", {
place_on = {"group:grass_block","group:dirt","mcl_core:dirt_with_grass","group:sand"}, place_on = { "group:grass_block", "group:dirt", "mcl_core:dirt_with_grass", "group:sand" },
fill_ratio = 0.01, fill_ratio = 0.01,
flags = "place_center_x, place_center_z", flags = "place_center_x, place_center_z",
solid_ground = true, solid_ground = true,
@ -18,30 +17,30 @@ mcl_structures.register_structure("pillager_outpost",{
y_min = 1, y_min = 1,
biomes = { "Desert", "Plains", "Savanna", "IcePlains", "Taiga" }, biomes = { "Desert", "Plains", "Savanna", "IcePlains", "Taiga" },
filenames = { filenames = {
modpath.."/schematics/mcl_structures_pillager_outpost.mts", modpath .. "/schematics/mcl_structures_pillager_outpost.mts",
modpath.."/schematics/mcl_structures_pillager_outpost_2.mts" modpath .. "/schematics/mcl_structures_pillager_outpost_2.mts"
}, },
loot = { loot = {
["mcl_chests:chest_small" ] ={ ["mcl_chests:chest_small"] = {
{ {
stacks_min = 2, stacks_min = 2,
stacks_max = 3, stacks_max = 3,
items = { items = {
{ itemstring = "mcl_farming:wheat_item", weight = 7, amount_min = 3, amount_max=5 }, { itemstring = "mcl_farming:wheat_item", weight = 7, amount_min = 3, amount_max = 5 },
{ itemstring = "mcl_farming:carrot_item", weight = 5, amount_min = 3, amount_max=5 }, { itemstring = "mcl_farming:carrot_item", weight = 5, amount_min = 3, amount_max = 5 },
{ itemstring = "mcl_farming:potato_item", weight = 5, amount_min = 2, amount_max=5 }, { itemstring = "mcl_farming:potato_item", weight = 5, amount_min = 2, amount_max = 5 },
} }
}, },
{ {
stacks_min = 1, stacks_min = 1,
stacks_max = 2, stacks_max = 2,
items = { items = {
{ itemstring = "mcl_experience:bottle", weight = 6, amount_min = 0, amount_max=1 }, { itemstring = "mcl_experience:bottle", weight = 6, amount_min = 0, amount_max = 1 },
{ itemstring = "mcl_bows:arrow", weight = 4, amount_min = 2, amount_max=7 }, { itemstring = "mcl_bows:arrow", weight = 4, amount_min = 2, amount_max = 7 },
{ itemstring = "mcl_mobitems:string", weight = 4, amount_min = 1, amount_max=6 }, { itemstring = "mcl_mobitems:string", weight = 4, amount_min = 1, amount_max = 6 },
{ itemstring = "mcl_core:iron_ingot", weight = 3, amount_min = 1, amount_max = 3 }, { itemstring = "mcl_core:iron_ingot", weight = 3, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_books:book", weight = 1, func = function(stack, pr) { itemstring = "mcl_books:book", weight = 1, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr)
end }, end },
} }
}, },
@ -49,7 +48,7 @@ mcl_structures.register_structure("pillager_outpost",{
stacks_min = 1, stacks_min = 1,
stacks_max = 3, stacks_max = 3,
items = { items = {
{ itemstring = "mcl_core:darktree", amount_min = 2, amount_max=3 }, { itemstring = "mcl_core:darktree", amount_min = 2, amount_max = 3 },
} }
}, },
{ {
@ -58,16 +57,17 @@ mcl_structures.register_structure("pillager_outpost",{
items = { items = {
{ itemstring = "mcl_bows:crossbow" }, { itemstring = "mcl_bows:crossbow" },
} }
}} }
}
}, },
after_place = function(p,def,pr) after_place = function(p, def, pr)
local p1 = vector.offset(p,-9,0,-9) local p1 = vector.offset(p, -9, 0, -9)
local p2 = vector.offset(p,9,32,9) local p2 = vector.offset(p, 9, 32, 9)
mcl_structures.spawn_mobs("mobs_mc:evoker",spawnon,p1,p2,pr,1) mcl_structures.spawn_mobs("mobs_mc:evoker", spawnon, p1, p2, pr, 1)
mcl_structures.spawn_mobs("mobs_mc:pillager",spawnon,p1,p2,pr,5) mcl_structures.spawn_mobs("mobs_mc:pillager", spawnon, p1, p2, pr, 5)
mcl_structures.spawn_mobs("mobs_mc:parrot",{"mesecons_pressureplates:pressure_plate_stone_off"},p1,p2,pr,3) mcl_structures.spawn_mobs("mobs_mc:parrot", { "mesecons_pressureplates:pressure_plate_stone_off" }, p1, p2, pr, 3)
mcl_structures.spawn_mobs("mobs_mc:iron_golem",{"mesecons_button:button_stone_off"},p1,p2,pr,1) mcl_structures.spawn_mobs("mobs_mc:iron_golem", { "mesecons_button:button_stone_off" }, p1, p2, pr, 1)
mcl_structures.construct_nodes(p1,p2,{"group:wall"}) mcl_structures.construct_nodes(p1, p2, { "group:wall" })
end end
}) })

View File

@ -1,17 +1,22 @@
local modname = minetest.get_current_modname() local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname) local modpath = minetest.get_modpath(modname)
local function get_replacements(b,c,pr) ---@param b Vector[]
---@param c integer
---@param pr PseudoRandom
---@return Vector[]
local function get_replacements(b, c, pr)
local r = {} local r = {}
if not b then return r end if not b then return r end
for k,v in pairs(b) do for _, v in pairs(b) do
if pr:next(1,100) < c then table.insert(r,v) end if pr:next(1, 100) < c then table.insert(r, v) end
end end
return r return r
end end
local def = { local def = {
place_on = {"group:grass_block","group:dirt","mcl_core:dirt_with_grass","group:grass_block","group:sand","group:grass_block_snow","mcl_core:snow"}, place_on = { "group:grass_block", "group:dirt", "mcl_core:dirt_with_grass", "group:grass_block", "group:sand",
"group:grass_block_snow", "mcl_core:snow" },
fill_ratio = 0.01, fill_ratio = 0.01,
flags = "place_center_x, place_center_z, all_floors", flags = "place_center_x, place_center_z, all_floors",
solid_ground = true, solid_ground = true,
@ -22,46 +27,46 @@ local def = {
sidelen = 10, sidelen = 10,
y_offset = -5, y_offset = -5,
filenames = { filenames = {
modpath.."/schematics/mcl_structures_ruined_portal_1.mts", modpath .. "/schematics/mcl_structures_ruined_portal_1.mts",
modpath.."/schematics/mcl_structures_ruined_portal_2.mts", modpath .. "/schematics/mcl_structures_ruined_portal_2.mts",
modpath.."/schematics/mcl_structures_ruined_portal_3.mts", modpath .. "/schematics/mcl_structures_ruined_portal_3.mts",
modpath.."/schematics/mcl_structures_ruined_portal_4.mts", modpath .. "/schematics/mcl_structures_ruined_portal_4.mts",
modpath.."/schematics/mcl_structures_ruined_portal_5.mts", modpath .. "/schematics/mcl_structures_ruined_portal_5.mts",
modpath.."/schematics/mcl_structures_ruined_portal_99.mts", modpath .. "/schematics/mcl_structures_ruined_portal_99.mts",
}, },
after_place = function(pos,def,pr) after_place = function(pos, def, pr)
local hl = def.sidelen / 2 local hl = def.sidelen / 2
local p1 = vector.offset(pos,-hl,-hl,-hl) local p1 = vector.offset(pos, -hl, -hl, -hl)
local p2 = vector.offset(pos,hl,hl,hl) local p2 = vector.offset(pos, hl, hl, hl)
local gold = minetest.find_nodes_in_area(p1,p2,{"mcl_core:goldblock"}) local gold = minetest.find_nodes_in_area(p1, p2, { "mcl_core:goldblock" })
local lava = minetest.find_nodes_in_area(p1,p2,{"mcl_core:lava_source"}) local lava = minetest.find_nodes_in_area(p1, p2, { "mcl_core:lava_source" })
local rack = minetest.find_nodes_in_area(p1,p2,{"mcl_nether:netherrack"}) local rack = minetest.find_nodes_in_area(p1, p2, { "mcl_nether:netherrack" })
local brick = minetest.find_nodes_in_area(p1,p2,{"mcl_core:stonebrick"}) local brick = minetest.find_nodes_in_area(p1, p2, { "mcl_core:stonebrick" })
local obby = minetest.find_nodes_in_area(p1,p2,{"mcl_core:obsidian"}) local obby = minetest.find_nodes_in_area(p1, p2, { "mcl_core:obsidian" })
minetest.bulk_set_node(get_replacements(gold,30,pr),{name="air"}) minetest.bulk_set_node(get_replacements(gold, 30, pr), { name = "air" })
minetest.bulk_set_node(get_replacements(lava,20,pr),{name="mcl_nether:magma"}) minetest.bulk_set_node(get_replacements(lava, 20, pr), { name = "mcl_nether:magma" })
minetest.bulk_set_node(get_replacements(rack,7,pr),{name="mcl_nether:magma"}) minetest.bulk_set_node(get_replacements(rack, 7, pr), { name = "mcl_nether:magma" })
minetest.bulk_set_node(get_replacements(obby,30,pr),{name="mcl_core:crying_obsidian"}) minetest.bulk_set_node(get_replacements(obby, 30, pr), { name = "mcl_core:crying_obsidian" })
minetest.bulk_set_node(get_replacements(obby,10,pr),{name="air"}) minetest.bulk_set_node(get_replacements(obby, 10, pr), { name = "air" })
minetest.bulk_set_node(get_replacements(brick,50,pr),{name="mcl_core:stonebrickcracked"}) minetest.bulk_set_node(get_replacements(brick, 50, pr), { name = "mcl_core:stonebrickcracked" })
brick = minetest.find_nodes_in_area(p1,p2,{"mcl_core:stonebrick"}) brick = minetest.find_nodes_in_area(p1, p2, { "mcl_core:stonebrick" })
minetest.bulk_set_node(get_replacements(brick,50,pr),{name="mcl_core:stonebrickmossy"}) minetest.bulk_set_node(get_replacements(brick, 50, pr), { name = "mcl_core:stonebrickmossy" })
end, end,
loot = { loot = {
["mcl_chests:chest_small" ] ={{ ["mcl_chests:chest_small"] = { {
stacks_min = 2, stacks_min = 2,
stacks_max = 6, stacks_max = 6,
items = { items = {
{ itemstring = "mcl_core:iron_nugget", weight = 40, amount_min = 9, amount_max = 18 }, { itemstring = "mcl_core:iron_nugget", weight = 40, amount_min = 9, amount_max = 18 },
{ itemstring = "mcl_core:flint", weight = 40, amount_min = 1, amount_max=4 }, { itemstring = "mcl_core:flint", weight = 40, amount_min = 1, amount_max = 4 },
{ itemstring = "mcl_core:obsidian", weight = 40, amount_min = 1, amount_max=2 }, { itemstring = "mcl_core:obsidian", weight = 40, amount_min = 1, amount_max = 2 },
{ itemstring = "mcl_fire:fire_charge", weight = 40, amount_min = 1, amount_max = 1 }, { itemstring = "mcl_fire:fire_charge", weight = 40, amount_min = 1, amount_max = 1 },
{ itemstring = "mcl_fire:flint_and_steel", weight = 40, amount_min = 1, amount_max = 1 }, { itemstring = "mcl_fire:flint_and_steel", weight = 40, amount_min = 1, amount_max = 1 },
{ itemstring = "mcl_core:gold_nugget", weight = 15, amount_min = 4, amount_max = 24 }, { itemstring = "mcl_core:gold_nugget", weight = 15, amount_min = 4, amount_max = 24 },
{ itemstring = "mcl_core:apple_gold", weight = 15, }, { itemstring = "mcl_core:apple_gold", weight = 15, },
{ itemstring = "mcl_books:book", weight = 1, func = function(stack, pr) { itemstring = "mcl_books:book", weight = 1, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr)
end }, end },
--{ itemstring = "mcl_bamboo:bamboo", weight = 15, amount_min = 1, amount_max=3 }, --FIXME BAMBOO --{ itemstring = "mcl_bamboo:bamboo", weight = 15, amount_min = 1, amount_max=3 }, --FIXME BAMBOO
@ -74,12 +79,16 @@ local def = {
{ itemstring = "mcl_mobitems:diamond_horse_armor", weight = 1, }, { itemstring = "mcl_mobitems:diamond_horse_armor", weight = 1, },
{ itemstring = "mcl_core:apple_gold", weight = 15, }, { itemstring = "mcl_core:apple_gold", weight = 15, },
} }
}} } }
} }
} }
mcl_structures.register_structure("ruined_portal_overworld",def)
mcl_structures.register_structure("ruined_portal_overworld", def)
local ndef = table.copy(def) local ndef = table.copy(def)
ndef.y_min=mcl_vars.mg_lava_nether_max +10 ndef.y_min = mcl_vars.mg_lava_nether_max + 10
ndef.y_max=mcl_vars.mg_nether_max - 15 ndef.y_max = mcl_vars.mg_nether_max - 15
ndef.place_on = {"mcl_nether:netherrack","group:soul_block","mcl_blackstone:basalt,mcl_blackstone:blackstone","mcl_crimson:crimson_nylium","mcl_crimson:warped_nylium"}, ndef.place_on = { "mcl_nether:netherrack", "group:soul_block", "mcl_blackstone:basalt,mcl_blackstone:blackstone",
mcl_structures.register_structure("ruined_portal_nether",ndef) "mcl_crimson:crimson_nylium", "mcl_crimson:warped_nylium" }
mcl_structures.register_structure("ruined_portal_nether", ndef)

View File

@ -2,17 +2,17 @@ local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname) local modpath = minetest.get_modpath(modname)
--local S = minetest.get_translator(modname) --local S = minetest.get_translator(modname)
local seed = minetest.get_mapgen_setting("seed") --local seed = minetest.get_mapgen_setting("seed")
local water_level = minetest.get_mapgen_setting("water_level") local water_level = minetest.get_mapgen_setting("water_level")
local pr = PseudoRandom(seed) --local pr = PseudoRandom(seed)
--schematics by chmodsayshello --schematics by chmodsayshello
local schems = { local schems = {
modpath.."/schematics/mcl_structures_shipwreck_full_damaged.mts", modpath .. "/schematics/mcl_structures_shipwreck_full_damaged.mts",
modpath.."/schematics/mcl_structures_shipwreck_full_normal.mts", modpath .. "/schematics/mcl_structures_shipwreck_full_normal.mts",
modpath.."/schematics/mcl_structures_shipwreck_full_back_damaged.mts", modpath .. "/schematics/mcl_structures_shipwreck_full_back_damaged.mts",
modpath.."/schematics/mcl_structures_shipwreck_half_front.mts", modpath .. "/schematics/mcl_structures_shipwreck_half_front.mts",
modpath.."/schematics/mcl_structures_shipwreck_half_back.mts", modpath .. "/schematics/mcl_structures_shipwreck_half_back.mts",
} }
local ocean_biomes = { local ocean_biomes = {
@ -94,14 +94,14 @@ local beach_biomes = {
"Jungle_shore" "Jungle_shore"
} }
mcl_structures.register_structure("shipwreck",{ mcl_structures.register_structure("shipwreck", {
place_on = {"group:sand","mcl_core:gravel"}, place_on = { "group:sand", "mcl_core:gravel" },
spawn_by = {"group:water"}, spawn_by = { "group:water" },
num_spawn_by = 4, num_spawn_by = 4,
noise_params = { noise_params = {
offset = 0, offset = 0,
scale = 0.000022, scale = 0.000022,
spread = {x = 250, y = 250, z = 250}, spread = { x = 250, y = 250, z = 250 },
seed = 3, seed = 3,
octaves = 3, octaves = 3,
persist = 0.001, persist = 0.001,
@ -110,10 +110,10 @@ mcl_structures.register_structure("shipwreck",{
sidelen = 16, sidelen = 16,
flags = "force_placement", flags = "force_placement",
biomes = ocean_biomes, biomes = ocean_biomes,
y_max = water_level-4, y_max = water_level - 4,
y_min = mcl_vars.mg_overworld_min, y_min = mcl_vars.mg_overworld_min,
filenames = schems, filenames = schems,
y_offset = function(pr) return pr:next(-4,-2) end, y_offset = function(pr) return pr:next(-4, -2) end,
loot = { loot = {
["mcl_chests:chest_small"] = { ["mcl_chests:chest_small"] = {
stacks_min = 3, stacks_min = 3,
@ -130,13 +130,17 @@ mcl_structures.register_structure("shipwreck",{
{ itemstring = "mcl_mobitems:rotten_flesh", weight = 5, amount_min = 5, amount_max = 24 }, { 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_farming:potato_item", weight = 3, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_armor:helmet_leather_enchanted", weight = 3, func = function(stack, pr) { itemstring = "mcl_armor:helmet_leather_enchanted", weight = 3, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end }, mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" })
end },
{ itemstring = "mcl_armor:chestplate_leather_enchanted", weight = 3, func = function(stack, pr) { itemstring = "mcl_armor:chestplate_leather_enchanted", weight = 3, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end }, mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" })
end },
{ itemstring = "mcl_armor:leggings_leather_enchanted", weight = 3, func = function(stack, pr) { itemstring = "mcl_armor:leggings_leather_enchanted", weight = 3, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end }, mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" })
end },
{ itemstring = "mcl_armor:boots_leather_enchanted", weight = 3, func = function(stack, pr) { itemstring = "mcl_armor:boots_leather_enchanted", weight = 3, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end }, mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" })
end },
--{ itemstring = "TODO:bamboo", weight = 2, amount_min = 1, amount_max = 3 }, --{ 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_farming:pumpkin", weight = 2, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_tnt:tnt", weight = 1, amount_min = 1, amount_max = 2 }, { itemstring = "mcl_tnt:tnt", weight = 1, amount_min = 1, amount_max = 2 },
@ -155,7 +159,7 @@ mcl_structures.register_structure("shipwreck",{
{ itemstring = "mcl_experience:bottle", weight = 5, amount_min = 1, amount_max = 1 }, { itemstring = "mcl_experience:bottle", weight = 5, amount_min = 1, amount_max = 1 },
{ itemstring = "mcl_core:diamond", weight = 5, amount_min = 1, amount_max = 1 }, { itemstring = "mcl_core:diamond", weight = 5, amount_min = 1, amount_max = 1 },
} }
},{ }, {
stacks_min = 3, stacks_min = 3,
stacks_max = 3, stacks_max = 3,
items = { items = {

View File

@ -1,21 +1,21 @@
local modname = minetest.get_current_modname() local modname = minetest.get_current_modname()
local S = minetest.get_translator(modname)
local modpath = minetest.get_modpath(modname) local modpath = minetest.get_modpath(modname)
local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false) local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false)
local function spawn_witch(p1,p2) local function spawn_witch(p1, p2)
local c = minetest.find_node_near(p1,15,{"mcl_cauldrons:cauldron"}) local c = minetest.find_node_near(p1, 15, { "mcl_cauldrons:cauldron" })
if c then 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 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 local witch
if not peaceful then if not peaceful then
witch = minetest.add_entity(vector.offset(nn[math.random(#nn)],0,1,0),"mobs_mc:witch"):get_luaentity() witch = minetest.add_entity(vector.offset(nn[math.random(#nn)], 0, 1, 0), "mobs_mc:witch"):get_luaentity()
witch._home = c witch._home = c
witch.can_despawn = false witch.can_despawn = false
end end
local cat = minetest.add_entity(vector.offset(nn[math.random(#nn)],0,1,0),"mobs_mc:cat"):get_luaentity() local cat = minetest.add_entity(vector.offset(nn[math.random(#nn)], 0, 1, 0), "mobs_mc:cat"):get_luaentity()
cat.object:set_properties({textures = {"mobs_mc_cat_black.png"}}) cat.object:set_properties({ textures = { "mobs_mc_cat_black.png" } })
cat.owner = "!witch!" --so it's not claimable by player cat.owner = "!witch!" --so it's not claimable by player
cat._home = c cat._home = c
cat.can_despawn = false cat.can_despawn = false
@ -23,24 +23,27 @@ local function spawn_witch(p1,p2)
end end
end end
local function hut_placement_callback(pos,def,pr) ---@param pos Vector
---@param def table
---@param pr PseudoRandom
local function hut_placement_callback(pos, def, pr)
local hl = def.sidelen / 2 local hl = def.sidelen / 2
local p1 = vector.offset(pos,-hl,-hl,-hl) local p1 = vector.offset(pos, -hl, -hl, -hl)
local p2 = 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 legs = minetest.find_nodes_in_area(vector.offset(pos, -hl, 0, -hl), vector.offset(pos, hl, 0, hl), "mcl_core:tree")
local tree = {} local tree = {}
for _,leg in pairs(legs) do 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 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) leg = vector.offset(leg, 0, -1, 0)
table.insert(tree,leg) table.insert(tree, leg)
end end
end end
minetest.bulk_set_node(tree, {name = "mcl_core:tree", param2 = 2}) minetest.bulk_set_node(tree, { name = "mcl_core:tree", param2 = 2 })
spawn_witch(p1,p2) spawn_witch(p1, p2)
end end
mcl_structures.register_structure("witch_hut",{ mcl_structures.register_structure("witch_hut", {
place_on = {"group:sand","group:grass_block","mcl_core:water_source","group:dirt"}, place_on = { "group:sand", "group:grass_block", "mcl_core:water_source", "group:dirt" },
fill_ratio = 0.01, fill_ratio = 0.01,
flags = "place_center_x, place_center_z, liquid_surface, force_placement", flags = "place_center_x, place_center_z, liquid_surface, force_placement",
sidelen = 8, sidelen = 8,
@ -49,6 +52,6 @@ mcl_structures.register_structure("witch_hut",{
y_min = -4, y_min = -4,
y_offset = 0, y_offset = 0,
biomes = { "Swampland", "Swampland_ocean", "Swampland_shore" }, biomes = { "Swampland", "Swampland_ocean", "Swampland_shore" },
filenames = { modpath.."/schematics/mcl_structures_witch_hut.mts" }, filenames = { modpath .. "/schematics/mcl_structures_witch_hut.mts" },
after_place = hut_placement_callback, after_place = hut_placement_callback,
}) })

View File

@ -1,12 +1,11 @@
local modname = minetest.get_current_modname() local modname = minetest.get_current_modname()
local S = minetest.get_translator(modname)
local modpath = minetest.get_modpath(modname) local modpath = minetest.get_modpath(modname)
local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false) --local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false)
local spawnon = {"mcl_deepslate:deepslate","mcl_core:birchwood","mcl_wool:red_carpet","mcl_wool:brown_carpet"} local spawnon = { "mcl_deepslate:deepslate", "mcl_core:birchwood", "mcl_wool:red_carpet", "mcl_wool:brown_carpet" }
mcl_structures.register_structure("woodland_cabin",{ mcl_structures.register_structure("woodland_cabin", {
place_on = {"group:grass_block","group:dirt","mcl_core:dirt_with_grass"}, place_on = { "group:grass_block", "group:dirt", "mcl_core:dirt_with_grass" },
fill_ratio = 0.01, fill_ratio = 0.01,
flags = "place_center_x, place_center_z", flags = "place_center_x, place_center_z",
solid_ground = true, solid_ground = true,
@ -17,29 +16,30 @@ mcl_structures.register_structure("woodland_cabin",{
biomes = { "RoofedForest" }, biomes = { "RoofedForest" },
sidelen = 32, sidelen = 32,
filenames = { filenames = {
modpath.."/schematics/mcl_structures_woodland_cabin.mts", modpath .. "/schematics/mcl_structures_woodland_cabin.mts",
modpath.."/schematics/mcl_structures_woodland_outpost.mts", modpath .. "/schematics/mcl_structures_woodland_outpost.mts",
}, },
construct_nodes = {"mcl_barrels:barrel_closed"}, construct_nodes = { "mcl_barrels:barrel_closed" },
after_place = function(p,def,pr) after_place = function(p, def, pr)
local p1=vector.offset(p,-def.sidelen,-1,-def.sidelen) local p1 = vector.offset(p, -def.sidelen, -1, -def.sidelen)
local p2=vector.offset(p,def.sidelen,def.sidelen,def.sidelen) local p2 = vector.offset(p, def.sidelen, def.sidelen, def.sidelen)
mcl_structures.spawn_mobs("mobs_mc:vindicator",spawnon,p1,p2,pr,5) mcl_structures.spawn_mobs("mobs_mc:vindicator", spawnon, p1, p2, pr, 5)
mcl_structures.spawn_mobs("mobs_mc:evoker",spawnon,p1,p2,pr,1) mcl_structures.spawn_mobs("mobs_mc:evoker", spawnon, p1, p2, pr, 1)
mcl_structures.spawn_mobs("mobs_mc:parrot",{"mcl_heads:wither_skeleton"},p1,p2,pr,1) mcl_structures.spawn_mobs("mobs_mc:parrot", { "mcl_heads:wither_skeleton" }, p1, p2, pr, 1)
end, end,
loot = { loot = {
["mcl_chests:chest_small" ] ={{ ["mcl_chests:chest_small"] = { {
stacks_min = 3, stacks_min = 3,
stacks_max = 3, stacks_max = 3,
items = { items = {
{ itemstring = "mcl_mobitems:bone", weight = 10, amount_min = 1, amount_max=8 }, { 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: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:rotten_flesh", weight = 10, amount_min = 1, amount_max = 8 },
{ itemstring = "mcl_mobitems:string", 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 }, { itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 },
}},{ }
}, {
stacks_min = 1, stacks_min = 1,
stacks_max = 4, stacks_max = 4,
items = { items = {
@ -53,18 +53,20 @@ mcl_structures.register_structure("woodland_cabin",{
{ itemstring = "mcl_core:iron_ingot", weight = 10, amount_min = 1, 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_buckets:bucket_empty", weight = 10, amount_min = 1, amount_max = 1 },
{ itemstring = "mcl_core:gold_ingot", weight = 5, amount_min = 1, amount_max = 4 }, { itemstring = "mcl_core:gold_ingot", weight = 5, amount_min = 1, amount_max = 4 },
}},{ }
}, {
stacks_min = 1, stacks_min = 1,
stacks_max = 4, stacks_max = 4,
items = { items = {
--{ itemstring = "FIXME:lead", weight = 20, amount_min = 1, amount_max = 1 }, --{ 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_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_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_chain", weight = 1, },
{ itemstring = "mcl_armor:chestplate_diamond", weight = 1, }, { itemstring = "mcl_armor:chestplate_diamond", weight = 1, },
{ itemstring = "mcl_core:apple_gold_enchanted", weight = 2, }, { itemstring = "mcl_core:apple_gold_enchanted", weight = 2, },
} }
}} } }
} }
}) })