Compare commits

...

1 Commits

Author SHA1 Message Date
AFCMS 3a2ce2feb8
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
2022-11-15 21:45:17 +01:00
14 changed files with 804 additions and 672 deletions

View File

@ -1,47 +1,51 @@
mcl_structures.registered_structures = {}
local place_queue = {}
local disabled_structures = minetest.settings:get("mcl_disabled_structures")
if disabled_structures then disabled_structures = disabled_structures:split(",")
else disabled_structures = {} end
local disabled_structures = minetest.settings:get("mcl_disabled_structures"):split(",")
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_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 modpath = minetest.get_modpath("mcl_structures")
local rotations = {
"0",
"90",
"180",
"270"
"270",
}
function mcl_structures.is_disabled(structname)
return table.indexof(disabled_structures,structname) ~= -1
return table.indexof(disabled_structures, structname) ~= -1
end
local function ecb_place(blockpos, action, calls_remaining, param)
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
param.after_placement_callback(param.p1, param.p2, param.size, param.rotation, param.pr, param.callback_param)
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
minetest.log("warning","[mcl_structures] schematic file "..tostring(schematic).." does not exist.")
return end
local s = loadstring(minetest.serialize_schematic(schematic, "lua", {lua_use_comments = false, lua_num_indent_spaces = 0}) .. " return schematic")()
minetest.log("warning", "[mcl_structures] schematic file " .. tostring(schematic) .. " does not exist.")
return
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
local x, z = s.size.x, s.size.z
if rotation then
if rotation == "random" and pr then
rotation = rotations[pr:next(1,#rotations)]
rotation = rotations[pr:next(1, #rotations)]
end
if rotation == "random" then
x = math.max(x, z)
@ -50,23 +54,32 @@ function mcl_structures.place_schematic(pos, schematic, rotation, replacements,
x, z = z, x
end
end
local p1 = {x=pos.x , y=pos.y , z=pos.z }
local p2 = {x=pos.x+x-1, y=pos.y+s.size.y-1, z=pos.z+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))
local param = {pos=vector.new(pos), schematic=s, rotation=rotation, replacements=replacements, force_placement=force_placement, flags=flags, p1=p1, p2=p2, after_placement_callback = after_placement_callback, size=vector.new(s.size), pr=pr, callback_param=callback_param}
local p1 = vector.copy(pos)
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))
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)
return true
end
end
function mcl_structures.get_struct(file)
local localfile = modpath.."/schematics/"..file
function mcl_structures.get_struct(filename)
local localfile = modpath .. "/schematics/" .. filename
local file, errorload = io.open(localfile, "rb")
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
end
assert(file)
local allnode = file:read("*a")
file:close()
@ -75,6 +88,7 @@ end
-- Call on_construct on pos.
-- Useful to init chests from formspec.
---@param pos Vector
local function init_node_construct(pos)
local node = minetest.get_node(pos)
local def = minetest.registered_nodes[node.name]
@ -84,12 +98,17 @@ local function init_node_construct(pos)
end
return false
end
mcl_structures.init_node_construct = init_node_construct
function mcl_structures.fill_chests(p1,p2,loot,pr)
for it,lt in pairs(loot) do
---@param p1 Vector
---@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)
for _,p in pairs(nodes) do
for _, p in pairs(nodes) do
local lootitems = mcl_loot.get_multi_loot(lt, pr)
mcl_structures.init_node_construct(p)
local meta = minetest.get_meta(p)
@ -99,97 +118,127 @@ function mcl_structures.fill_chests(p1,p2,loot,pr)
end
end
---@param pos Vector
---@param def table
---@param pr PseudoRandom
local function generate_loot(pos, def, pr)
local hl = def.sidelen
local p1 = vector.offset(pos,-hl,-hl,-hl)
local p2 = vector.offset(pos,hl,hl,hl)
if def.loot then mcl_structures.fill_chests(p1,p2,def.loot,pr) end
local p1 = vector.offset(pos, -hl, -hl, -hl)
local p2 = vector.offset(pos, hl, hl, hl)
if def.loot then mcl_structures.fill_chests(p1, p2, def.loot, pr) end
end
function mcl_structures.construct_nodes(p1,p2,nodes)
local nn=minetest.find_nodes_in_area(p1,p2,nodes)
for _,p in pairs(nn) do
---@param p1 Vector
---@param p2 Vector
---@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)
end
end
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)
---@param pos Vector
---@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
---@param pp Vector[]
---@return integer
function mcl_structures.find_lowest_y(pp)
local y = 31000
for _,p in pairs(pp) do
for _, p in pairs(pp) do
if p.y < y then y = p.y end
end
return y
end
---@param pp Vector[]
---@return integer
function mcl_structures.find_highest_y(pp)
local y = -31000
for _,p in pairs(pp) do
for _, p in pairs(pp) do
if p.y > y then y = p.y end
end
return y
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 amnt = amnt or 9
table.sort(nn,function(a, b)
amnt = amnt or 9
table.sort(nn, function(a, b)
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
return vector.distance(pos, a) < vector.distance(pos, b)
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
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
for _,v in pairs(nn) do
local p=vector.new(v)
for _, v in pairs(nn) do
local p = vector.copy(v)
repeat
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
--minetest.log(tostring(pos.y - p.y))
if pos.y - p.y > r then r = pos.y - p.y end
--minetest.log(tostring(pos.y - p.y))
if pos.y - p.y > r then
r = pos.y - p.y
end
end
return r
end
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 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 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 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 filler = {}
local top = {}
local dust = {}
for l,v in pairs(nn) do
for l, v in pairs(nn) do
if v.y == ground_p1.y - 1 then
table.insert(filler,v)
table.insert(top,vector.offset(v,0,1,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_p2.y - 3 and v.y > ground_p2.y -5 then
table.insert(filler, v)
table.insert(top, vector.offset(v, 0, 1, 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_p2.y - 3 and v.y > ground_p2.y - 5 then
if math.random(3) == 1 then
table.insert(filler,v)
table.insert(filler, v)
else
table.insert(stone,v)
table.insert(stone, v)
end
else
table.insert(stone,v)
table.insert(stone, v)
end
end
return stone,filler,top,dust
return stone, filler, top, dust
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_filler = "mcl_core:dirt"
local node_top = "mcl_core:dirt_with_grass" or minetest.get_node(ground_p1).name
@ -206,54 +255,56 @@ local function foundation(ground_p1,ground_p2,pos,sidelen)
end
end
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)
local stone, filler, top, dust = get_foundation_nodes(ground_p1, ground_p2, pos, sidelen, node_stone)
minetest.bulk_set_node(top, { name = node_top })
if node_dust then
minetest.bulk_set_node(dust,{name=node_dust})
minetest.bulk_set_node(dust, { name = node_dust })
end
minetest.bulk_set_node(filler,{name=node_filler})
minetest.bulk_set_node(stone,{name=node_stone})
minetest.bulk_set_node(filler, { name = node_filler })
minetest.bulk_set_node(stone, { name = node_stone })
end
--[[
local function process_queue()
if #place_queue < 1 then return end
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
s.after_place(s.pos,s.def,s.pr)
s.after_place(s.pos, s.def, s.pr)
end
end,s.pr)
minetest.after(0.5,process_queue)
end, s.pr)
minetest.after(0.5, process_queue)
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
local sp = {}
if water then
local nn = minetest.find_nodes_in_area(p1,p2,spawnon)
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
table.insert(sp,v)
local nn = minetest.find_nodes_in_area(p1, p2, spawnon)
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
table.insert(sp, v)
end
end
else
sp = minetest.find_nodes_in_area_under_air(p1,p2,spawnon)
sp = minetest.find_nodes_in_area_under_air(p1, p2, spawnon)
end
table.shuffle(sp)
for i,node in pairs(sp) do
for i, node in pairs(sp) do
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
minetest.add_entity(pos,mob)
minetest.add_entity(pos, mob)
end
end
minetest.get_meta(node):set_string("spawnblock","yes")
minetest.get_meta(node):set_string("spawnblock", "yes")
end
end
function mcl_structures.place_structure(pos, def, pr, blockseed, rot)
if not def then return end
if not def then return end
if not rot then rot = "random" end
local log_enabled = logging and not def.terrain_feature
local y_offset = 0
@ -262,87 +313,92 @@ function mcl_structures.place_structure(pos, def, pr, blockseed, rot)
elseif def.y_offset then
y_offset = def.y_offset
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
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_p1 = vector.offset(pos, -def.sidelen / 2, -1, -def.sidelen / 2)
local ground_p2 = vector.offset(pos, def.sidelen / 2, -1, def.sidelen / 2)
local solid = minetest.find_nodes_in_area(ground_p1,ground_p2,{"group:solid"})
if #solid < ( def.sidelen * def.sidelen ) then
local solid = minetest.find_nodes_in_area(ground_p1, ground_p2, { "group:solid" })
if #solid < (def.sidelen * def.sidelen) then
if def.make_foundation then
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
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
return false
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
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
return false
end
if def.filenames then
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]
if file then
local rot = rotations[pr:next(1,#rotations)]
local ap = function(pos,def,pr,blockseed) end
local rot = rotations[pr:next(1, #rotations)]
local ap = function(_, _, _, _) end
if def.daughters then
ap = function(pos,def,pr,blockseed)
for _,d in pairs(def.daughters) do
local p = vector.add(pos,d.pos)
ap = function(pos, def, pr, _)
for _, d in pairs(def.daughters) do
local p = vector.add(pos, d.pos)
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()
if def.loot then generate_loot(pp,def,pr,blockseed) end
if def.construct_nodes then construct_nodes(pp,def,pr,blockseed) end
if def.after_place then
def.after_place(pos,def,pr)
end
end,pr)
mcl_structures.place_schematic(p, d.files[pr:next(1, #d.files)], rot, nil, true, "place_center_x,place_center_z",
function()
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
def.after_place(pos, def, pr)
end
end, pr)
end
end
elseif def.after_place then
ap = def.after_place
end
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 def.loot then generate_loot(pp,def,pr,blockseed) end
if def.construct_nodes then construct_nodes(pp,def,pr,blockseed) end
end
return ap(pp,def,pr,blockseed,p1,p2,size,rotation)
end,pr)
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 def.loot then generate_loot(pp, def, pr) end
if def.construct_nodes then construct_nodes(pp, def, pr) end
end
return ap(pp, def, pr, blockseed)
end, pr)
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
return true
end
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 def.loot then generate_loot(pp,def,pr,blockseed) end
if def.construct_nodes then construct_nodes(pp,def,pr,blockseed) end
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 def.loot then generate_loot(pp, def, pr) end
if def.construct_nodes then construct_nodes(pp, def, pr) end
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
return true
end
end
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
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
local structblock = "mcl_structures:structblock_"..name
local structblock = "mcl_structures:structblock_" .. name
local flags = "place_center_x, place_center_z, force_placement"
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
def.name = name
if nospawn then
@ -352,7 +408,7 @@ function mcl_structures.register_structure(name,def,nospawn) --nospawn means it
if def.place_on then
minetest.register_on_mods_loaded(function() --make sure all previous decorations and biomes have been registered
def.deco = minetest.register_decoration({
name = "mcl_structures:deco_"..name,
name = "mcl_structures:deco_" .. name,
decoration = structblock,
deco_type = "simple",
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_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.deco_id = minetest.get_decoration_id("mcl_structures:deco_"..name)
minetest.set_gen_notify({decoration=true}, { def.deco_id })
def.deco_id = minetest.get_decoration_id("mcl_structures:deco_" .. name)
minetest.set_gen_notify({ decoration = true }, { def.deco_id })
--catching of gennotify happens in mcl_mapgen_core
end)
@ -382,7 +439,7 @@ local structure_spawns = {}
function mcl_structures.register_structure_spawn(def)
--name,y_min,y_max,spawnon,biomes,chance,interval,limit
minetest.register_abm({
label = "Spawn "..def.name,
label = "Spawn " .. def.name,
nodenames = def.spawnon,
min_y = def.y_min 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
if active_object_count_wider > limit + mob_cap_animal 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_meta(pos):get_string("spawnblock") == "" then return end
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
end
end
local mobdef = minetest.registered_entities[def.name]
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
@ -411,10 +468,10 @@ end
minetest.register_lbm({
name = "mcl_structures:struct_lbm",
run_at_every_load = true,
nodenames = {"group:structblock_lbm"},
nodenames = { "group:structblock_lbm" },
action = function(pos, node)
minetest.remove_node(pos)
local name = node.name:gsub("mcl_structures:structblock_","")
local name = node.name:gsub("mcl_structures:structblock_", "")
local def = mcl_structures.registered_structures[name]
if not def then return end
mcl_structures.place_structure(pos)

View File

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

View File

@ -1,57 +1,57 @@
local modname = minetest.get_current_modname()
local S = minetest.get_translator(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 p1 = vector.offset(pos,-def.sidelen/2,-1,-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)
local function spawn_shulkers(pos, def, pr)
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)
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
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
mcl_structures.register_structure("end_shipwreck",{
place_on = {"mcl_end:end_stone"},
mcl_structures.register_structure("end_shipwreck", {
place_on = { "mcl_end:end_stone" },
fill_ratio = 0.001,
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,
--y_max = mcl_vars.mg_end_max,
--y_min = mcl_vars.mg_end_min -100,
biomes = { "End", "EndHighlands", "EndMidlands", "EndBarrens", "EndSmallIslands" },
sidelen = 32,
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"},
after_place = function(pos,def,pr)
local fr = minetest.find_node_near(pos,def.sidelen,{"mcl_itemframes:item_frame"})
construct_nodes = { "mcl_chests:ender_chest_small", "mcl_chests:ender_chest", "mcl_brewing:stand_000",
"mcl_chests:violet_shulker_box_small" },
after_place = function(pos, def, pr)
local fr = minetest.find_node_near(pos, def.sidelen, { "mcl_itemframes:item_frame" })
if fr 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
return spawn_shulkers(pos,def,pr)
return spawn_shulkers(pos, def, pr)
end,
loot = {
[ "mcl_itemframes:item_frame" ] ={{
["mcl_itemframes:item_frame"] = { {
stacks_min = 1,
stacks_max = 1,
items = {
{ itemstring = "mcl_armor:elytra", weight = 100 },
},
}},
[ "mcl_chests:chest_small" ] ={{
} },
["mcl_chests:chest_small"] = { {
stacks_min = 2,
stacks_max = 6,
items = {
{ 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_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_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 },
--{ itemstring = "mcl_bamboo:bamboo", weight = 15, amount_min = 1, amount_max=3 }, --FIXME BAMBOO
{ itemstring = "mcl_core:iron_ingot", weight = 15, amount_min = 4, amount_max = 8 },
@ -59,77 +59,104 @@ mcl_structures.register_structure("end_shipwreck",{
{ itemstring = "mcl_mobitems:saddle", weight = 3, },
{ itemstring = "mcl_core:emerald", weight = 2, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_books:book", weight = 1, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr)
mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr)
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:shovel_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,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end },
{ itemstring = "mcl_armor:helmet_iron_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,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end },
{ itemstring = "mcl_armor:leggings_iron_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,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_tools:pick_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,
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_armor:helmet_iron_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,
func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_armor:leggings_iron_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,
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_mobitems:iron_horse_armor", weight = 1, },
{ itemstring = "mcl_mobitems:gold_horse_armor", weight = 1, },
{ itemstring = "mcl_mobitems:diamond_horse_armor", weight = 1, },
{ itemstring = "mcl_core:apple_gold_enchanted", weight = 2, },
}
}}
} }
}
})
mcl_structures.register_structure("end_boat",{
place_on = {"mcl_end:end_stone"},
mcl_structures.register_structure("end_boat", {
place_on = { "mcl_end:end_stone" },
fill_ratio = 0.01,
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,
--y_max = mcl_vars.mg_end_max,
--y_min = mcl_vars.mg_end_min -100,
biomes = { "End", "EndHighlands", "EndMidlands", "EndBarrens", "EndSmallIslands" },
sidelen = 20,
filenames = {
modpath.."/schematics/mcl_structures_end_boat.mts",
modpath .. "/schematics/mcl_structures_end_boat.mts",
},
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 = {
[ "mcl_chests:chest_small" ] ={{
["mcl_chests:chest_small"] = { {
stacks_min = 2,
stacks_max = 6,
items = {
{ 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_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_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:diamond", weight = 3, amount_min = 2, amount_max = 7 },
{ itemstring = "mcl_mobitems:saddle", weight = 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:shovel_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,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end },
{ itemstring = "mcl_armor:helmet_iron_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,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end },
{ itemstring = "mcl_armor:leggings_iron_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,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_tools:pick_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,
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_armor:helmet_iron_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,
func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_armor:leggings_iron_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,
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_mobitems:iron_horse_armor", weight = 1, },
{ itemstring = "mcl_mobitems:gold_horse_armor", weight = 1, },
{ itemstring = "mcl_core:apple_gold_enchanted", weight = 2, },
}
}}
} }
}
})

View File

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

View File

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

View File

@ -1,54 +1,64 @@
local modname = minetest.get_current_modname()
local S = minetest.get_translator(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)
-- 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 path = modpath.."/schematics/mcl_structures_igloo_top.mts"
local rotation = tostring(pr:next(0,3)*90)
local newpos = vector.offset(pos, 0, -2, 0)
local path = modpath .. "/schematics/mcl_structures_igloo_top.mts"
local rotation = tostring(pr:next(0, 3) * 90)
return mcl_structures.place_schematic(newpos, path, rotation, nil, true, nil, function()
local p1 = 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"})
local p1 = 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" })
end), rotation
end
local function spawn_mobs(p1,p2,vi,zv)
local mc = minetest.find_nodes_in_area_under_air(p1,p2,{"mcl_core:stonebrickmossy"})
local function spawn_mobs(p1, p2, vi, zv)
local mc = minetest.find_nodes_in_area_under_air(p1, p2, { "mcl_core:stonebrickmossy" })
if #mc == 2 then
local vp = mc[1]
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]
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]
elseif zv and vi then
return
end
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")
minetest.after(1,spawn_mobs,p1,p2,vi,zv)
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")
minetest.after(1, spawn_mobs, p1, p2, vi, zv)
end
end
---@param pos Vector
---@param orientation any
---@param loot any
---@param pr PseudoRandom
function mcl_structures.generate_igloo_basement(pos, orientation, loot, pr)
-- 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()
local p1 = vector.offset(pos,-5,-5,-5)
local p2 = vector.offset(pos,5,5,5)
mcl_structures.fill_chests(p1,p2,loot,pr)
mcl_structures.construct_nodes(p1,p2,{"mcl_brewing:stand_000","mcl_books:bookshelf"})
spawn_mobs(p1,p2)
local p1 = vector.offset(pos, -5, -5, -5)
local p2 = vector.offset(pos, 5, 5, 5)
mcl_structures.fill_chests(p1, p2, loot, pr)
mcl_structures.construct_nodes(p1, p2, { "mcl_brewing:stand_000", "mcl_books:bookshelf" })
spawn_mobs(p1, p2)
end, pr)
end
---@param pos Vector
---@param def table
---@param pr PseudoRandom
function mcl_structures.generate_igloo(pos, def, pr)
-- Place igloo
local success, rotation = mcl_structures.generate_igloo_top(pos, pr)
-- Place igloo basement with 50% chance
local r = pr:next(1,2)
local r = pr:next(1, 2)
if r == 1 then
-- Select basement depth
local dim = mcl_worlds.pos_to_dimension(pos)
@ -67,26 +77,26 @@ function mcl_structures.generate_igloo(pos, def, pr)
return success
end
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
local tpos
local dir, tdir
if rotation == "0" then
dir = {x=-1, y=0, z=0}
tdir = {x=1, y=0, z=0}
tpos = {x=pos.x+7, y=pos.y-2, z=pos.z+3}
dir = vector.new(-1, 0, 0)
tdir = vector.new(1, 0, 0)
tpos = vector.offset(pos, 7, -2, 3)
elseif rotation == "90" then
dir = {x=0, y=0, z=-1}
tdir = {x=0, y=0, z=-1}
tpos = {x=pos.x+3, y=pos.y-2, z=pos.z+1}
dir = vector.new(0, 0, -1)
tdir = vector.new(0, 0, -1)
tpos = vector.offset(pos, 3, -2, 1)
elseif rotation == "180" then
dir = {x=1, y=0, z=0}
tdir = {x=-1, y=0, z=0}
tpos = {x=pos.x+1, y=pos.y-2, z=pos.z+3}
dir = vector.new(1, 0, 0)
tdir = vector.new(-1, 0, 0)
tpos = vector.offset(pos, 1, -2, 3)
elseif rotation == "270" then
dir = {x=0, y=0, z=1}
tdir = {x=0, y=0, z=1}
tpos = {x=pos.x+3, y=pos.y-2, z=pos.z+7}
dir = vector.new(0, 0, 1)
tdir = vector.new(0, 0, 1)
tpos = vector.offset(pos, 3, -2, 7)
else
return success
end
@ -107,17 +117,18 @@ function mcl_structures.generate_igloo(pos, def, pr)
brick = "mcl_core:stonebrick"
end
end
minetest.set_node(pos, {name=brick})
minetest.set_node(pos, { name = brick })
end
local ladder_param2 = minetest.dir_to_wallmounted(tdir)
local real_depth = 0
-- Check how deep we can actuall dig
for y=1, depth-5 do
for y = 1, depth - 5 do
real_depth = real_depth + 1
local node = minetest.get_node({x=tpos.x,y=tpos.y-y,z=tpos.z})
local def = minetest.registered_nodes[node.name]
if not (def and def.walkable and def.liquidtype == "none" and def.is_ground_content) then
bpos.y = tpos.y-y+1
local node = minetest.get_node(vector.offset(tpos, 0, -y, 0))
local ndef = minetest.registered_nodes[node.name]
if not (ndef and ndef.walkable and ndef.liquidtype == "none" and ndef.is_ground_content) then
bpos.y = tpos.y - y + 1
break
end
end
@ -125,25 +136,25 @@ function mcl_structures.generate_igloo(pos, def, pr)
return success
end
-- Generate ladder to basement
for y=1, real_depth-1 do
set_brick({x=tpos.x-1,y=tpos.y-y,z=tpos.z })
set_brick({x=tpos.x+1,y=tpos.y-y,z=tpos.z })
set_brick({x=tpos.x ,y=tpos.y-y,z=tpos.z-1})
set_brick({x=tpos.x ,y=tpos.y-y,z=tpos.z+1})
minetest.set_node({x=tpos.x,y=tpos.y-y,z=tpos.z}, {name="mcl_core:ladder", param2=ladder_param2})
for y = 1, real_depth - 1 do
set_brick(vector.offset(tpos, -1, -y, 0))
set_brick(vector.offset(tpos, 1, -y, 0))
set_brick(vector.offset(tpos, 0, -y, -1))
set_brick(vector.offset(tpos, 0, -y, 1))
minetest.set_node(vector.offset(tpos, 0, -y, 0), { name = "mcl_core:ladder", param2 = ladder_param2 })
end
-- Place basement
mcl_structures.generate_igloo_basement(bpos, rotation, def.loot, pr)
-- Place hidden trapdoor
minetest.after(5, function(tpos, dir)
minetest.set_node(tpos, {name="mcl_doors:trapdoor", param2=20+minetest.dir_to_facedir(dir)}) -- TODO: more reliable param2
minetest.after(5, function(tpos2, dir2)
minetest.set_node(tpos2, { name = "mcl_doors:trapdoor", param2 = 20 + minetest.dir_to_facedir(dir2) }) -- TODO: more reliable param2
end, tpos, dir)
end
return success
end
mcl_structures.register_structure("igloo",{
place_on = {"mcl_core:snowblock","mcl_core:snow","group:grass_block_snow"},
mcl_structures.register_structure("igloo", {
place_on = { "mcl_core:snowblock", "mcl_core:snow", "group:grass_block_snow" },
fill_ratio = 0.01,
sidelen = 16,
chunk_probability = 250,
@ -152,29 +163,29 @@ mcl_structures.register_structure("igloo",{
y_max = mcl_vars.mg_overworld_max,
y_min = 0,
y_offset = 0,
biomes = { "ColdTaiga", "IcePlainsSpikes", "IcePlains" },
biomes = { "ColdTaiga", "IcePlainsSpikes", "IcePlains" },
place_func = mcl_structures.generate_igloo,
loot = {
["mcl_chests:chest_small"] = {{
["mcl_chests:chest_small"] = { {
stacks_min = 1,
stacks_max = 1,
items = {
{ itemstring = "mcl_core:apple_gold", weight = 1 },
}
},
{
stacks_min = 2,
stacks_max = 8,
items = {
{ itemstring = "mcl_core:coal_lump", weight = 15, amount_min = 1, amount_max = 4 },
{ itemstring = "mcl_core:apple", weight = 15, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_farming:wheat_item", weight = 10, amount_min = 2, amount_max = 3 },
{ itemstring = "mcl_core:gold_nugget", weight = 10, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_mobitems:rotten_flesh", weight = 10 },
{ itemstring = "mcl_tools:axe_stone", weight = 2 },
{ itemstring = "mcl_core:emerald", weight = 1 },
{ itemstring = "mcl_core:apple_gold", weight = 1 },
}
}},
{
stacks_min = 2,
stacks_max = 8,
items = {
{ itemstring = "mcl_core:coal_lump", weight = 15, amount_min = 1, amount_max = 4 },
{ itemstring = "mcl_core:apple", weight = 15, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_farming:wheat_item", weight = 10, amount_min = 2, amount_max = 3 },
{ itemstring = "mcl_core:gold_nugget", weight = 10, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_mobitems:rotten_flesh", weight = 10 },
{ itemstring = "mcl_tools:axe_stone", weight = 2 },
{ itemstring = "mcl_core:emerald", weight = 1 },
{ itemstring = "mcl_core:apple_gold", weight = 1 },
}
} },
}
})

View File

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

View File

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

View File

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

View File

@ -1,12 +1,11 @@
local modname = minetest.get_current_modname()
local S = minetest.get_translator(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",{
place_on = {"group:grass_block","group:dirt","mcl_core:dirt_with_grass","group:sand"},
mcl_structures.register_structure("pillager_outpost", {
place_on = { "group:grass_block", "group:dirt", "mcl_core:dirt_with_grass", "group:sand" },
fill_ratio = 0.01,
flags = "place_center_x, place_center_z",
solid_ground = true,
@ -18,56 +17,57 @@ mcl_structures.register_structure("pillager_outpost",{
y_min = 1,
biomes = { "Desert", "Plains", "Savanna", "IcePlains", "Taiga" },
filenames = {
modpath.."/schematics/mcl_structures_pillager_outpost.mts",
modpath.."/schematics/mcl_structures_pillager_outpost_2.mts"
modpath .. "/schematics/mcl_structures_pillager_outpost.mts",
modpath .. "/schematics/mcl_structures_pillager_outpost_2.mts"
},
loot = {
["mcl_chests:chest_small" ] ={
{
stacks_min = 2,
stacks_max = 3,
items = {
{ 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:potato_item", weight = 5, amount_min = 2, amount_max=5 },
["mcl_chests:chest_small"] = {
{
stacks_min = 2,
stacks_max = 3,
items = {
{ 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:potato_item", weight = 5, amount_min = 2, amount_max = 5 },
}
},
{
stacks_min = 1,
stacks_max = 2,
items = {
{ 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_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_books:book", weight = 1, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr)
end },
}
},
{
stacks_min = 1,
stacks_max = 3,
items = {
{ itemstring = "mcl_core:darktree", amount_min = 2, amount_max = 3 },
}
},
{
stacks_min = 1,
stacks_max = 1,
items = {
{ itemstring = "mcl_bows:crossbow" },
}
}
},
{
stacks_min = 1,
stacks_max = 2,
items = {
{ 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_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_books:book", weight = 1, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr)
end },
}
},
{
stacks_min = 1,
stacks_max = 3,
items = {
{ itemstring = "mcl_core:darktree", amount_min = 2, amount_max=3 },
}
},
{
stacks_min = 1,
stacks_max = 1,
items = {
{ itemstring = "mcl_bows:crossbow" },
}
}}
}
},
after_place = function(p,def,pr)
local p1 = vector.offset(p,-9,0,-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: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:iron_golem",{"mesecons_button:button_stone_off"},p1,p2,pr,1)
mcl_structures.construct_nodes(p1,p2,{"group:wall"})
after_place = function(p, def, pr)
local p1 = vector.offset(p, -9, 0, -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: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:iron_golem", { "mesecons_button:button_stone_off" }, p1, p2, pr, 1)
mcl_structures.construct_nodes(p1, p2, { "group:wall" })
end
})

View File

@ -1,17 +1,22 @@
local modname = minetest.get_current_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 = {}
if not b then return r end
for k,v in pairs(b) do
if pr:next(1,100) < c then table.insert(r,v) end
for _, v in pairs(b) do
if pr:next(1, 100) < c then table.insert(r, v) end
end
return r
end
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,
flags = "place_center_x, place_center_z, all_floors",
solid_ground = true,
@ -22,46 +27,46 @@ local def = {
sidelen = 10,
y_offset = -5,
filenames = {
modpath.."/schematics/mcl_structures_ruined_portal_1.mts",
modpath.."/schematics/mcl_structures_ruined_portal_2.mts",
modpath.."/schematics/mcl_structures_ruined_portal_3.mts",
modpath.."/schematics/mcl_structures_ruined_portal_4.mts",
modpath.."/schematics/mcl_structures_ruined_portal_5.mts",
modpath.."/schematics/mcl_structures_ruined_portal_99.mts",
modpath .. "/schematics/mcl_structures_ruined_portal_1.mts",
modpath .. "/schematics/mcl_structures_ruined_portal_2.mts",
modpath .. "/schematics/mcl_structures_ruined_portal_3.mts",
modpath .. "/schematics/mcl_structures_ruined_portal_4.mts",
modpath .. "/schematics/mcl_structures_ruined_portal_5.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 p1 = 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 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 brick = minetest.find_nodes_in_area(p1,p2,{"mcl_core:stonebrick"})
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(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(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(brick,50,pr),{name="mcl_core:stonebrickcracked"})
brick = minetest.find_nodes_in_area(p1,p2,{"mcl_core:stonebrick"})
minetest.bulk_set_node(get_replacements(brick,50,pr),{name="mcl_core:stonebrickmossy"})
local p1 = 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 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 brick = minetest.find_nodes_in_area(p1, p2, { "mcl_core:stonebrick" })
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(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(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(brick, 50, pr), { name = "mcl_core:stonebrickcracked" })
brick = minetest.find_nodes_in_area(p1, p2, { "mcl_core:stonebrick" })
minetest.bulk_set_node(get_replacements(brick, 50, pr), { name = "mcl_core:stonebrickmossy" })
end,
loot = {
["mcl_chests:chest_small" ] ={{
["mcl_chests:chest_small"] = { {
stacks_min = 2,
stacks_max = 6,
items = {
{ 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:obsidian", weight = 40, amount_min = 1, amount_max=2 },
{ 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_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_core:gold_nugget", weight = 15, amount_min = 4, amount_max = 24 },
{ itemstring = "mcl_core:apple_gold", weight = 15, },
{ 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 },
--{ 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_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)
ndef.y_min=mcl_vars.mg_lava_nether_max +10
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"},
mcl_structures.register_structure("ruined_portal_nether",ndef)
ndef.y_min = mcl_vars.mg_lava_nether_max + 10
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" }
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 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 pr = PseudoRandom(seed)
--local pr = PseudoRandom(seed)
--schematics by chmodsayshello
local schems = {
modpath.."/schematics/mcl_structures_shipwreck_full_damaged.mts",
modpath.."/schematics/mcl_structures_shipwreck_full_normal.mts",
modpath.."/schematics/mcl_structures_shipwreck_full_back_damaged.mts",
modpath.."/schematics/mcl_structures_shipwreck_half_front.mts",
modpath.."/schematics/mcl_structures_shipwreck_half_back.mts",
modpath .. "/schematics/mcl_structures_shipwreck_full_damaged.mts",
modpath .. "/schematics/mcl_structures_shipwreck_full_normal.mts",
modpath .. "/schematics/mcl_structures_shipwreck_full_back_damaged.mts",
modpath .. "/schematics/mcl_structures_shipwreck_half_front.mts",
modpath .. "/schematics/mcl_structures_shipwreck_half_back.mts",
}
local ocean_biomes = {
@ -94,14 +94,14 @@ local beach_biomes = {
"Jungle_shore"
}
mcl_structures.register_structure("shipwreck",{
place_on = {"group:sand","mcl_core:gravel"},
spawn_by = {"group:water"},
mcl_structures.register_structure("shipwreck", {
place_on = { "group:sand", "mcl_core:gravel" },
spawn_by = { "group:water" },
num_spawn_by = 4,
noise_params = {
offset = 0,
scale = 0.000022,
spread = {x = 250, y = 250, z = 250},
spread = { x = 250, y = 250, z = 250 },
seed = 3,
octaves = 3,
persist = 0.001,
@ -110,10 +110,10 @@ mcl_structures.register_structure("shipwreck",{
sidelen = 16,
flags = "force_placement",
biomes = ocean_biomes,
y_max = water_level-4,
y_max = water_level - 4,
y_min = mcl_vars.mg_overworld_min,
filenames = schems,
y_offset = function(pr) return pr:next(-4,-2) end,
y_offset = function(pr) return pr:next(-4, -2) end,
loot = {
["mcl_chests:chest_small"] = {
stacks_min = 3,
@ -130,42 +130,46 @@ mcl_structures.register_structure("shipwreck",{
{ itemstring = "mcl_mobitems:rotten_flesh", weight = 5, amount_min = 5, amount_max = 24 },
{ itemstring = "mcl_farming:potato_item", weight = 3, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_armor:helmet_leather_enchanted", weight = 3, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end },
mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" })
end },
{ itemstring = "mcl_armor:chestplate_leather_enchanted", weight = 3, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end },
mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" })
end },
{ itemstring = "mcl_armor:leggings_leather_enchanted", weight = 3, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end },
mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" })
end },
{ itemstring = "mcl_armor:boots_leather_enchanted", weight = 3, func = function(stack, pr)
mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end },
mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" })
end },
--{ itemstring = "TODO:bamboo", weight = 2, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_farming:pumpkin", weight = 2, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_tnt:tnt", weight = 1, amount_min = 1, amount_max = 2 },
},
{
stacks_min = 2,
stacks_max = 6,
items = {
{ itemstring = "mcl_core:iron_ingot", weight = 90, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_core:iron_nugget", weight = 50, amount_min = 1, amount_max = 10 },
{ itemstring = "mcl_core:emerald", weight = 40, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_dye:blue", weight = 20, amount_min = 1, amount_max = 10 },
{ itemstring = "mcl_core:gold_ingot", weight = 10, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_core:gold_nugget", weight = 10, amount_min = 1, amount_max = 10 },
{ itemstring = "mcl_experience:bottle", weight = 5, amount_min = 1, amount_max = 1 },
{ itemstring = "mcl_core:diamond", weight = 5, amount_min = 1, amount_max = 1 },
stacks_min = 2,
stacks_max = 6,
items = {
{ itemstring = "mcl_core:iron_ingot", weight = 90, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_core:iron_nugget", weight = 50, amount_min = 1, amount_max = 10 },
{ itemstring = "mcl_core:emerald", weight = 40, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_dye:blue", weight = 20, amount_min = 1, amount_max = 10 },
{ itemstring = "mcl_core:gold_ingot", weight = 10, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_core:gold_nugget", weight = 10, amount_min = 1, amount_max = 10 },
{ itemstring = "mcl_experience:bottle", weight = 5, amount_min = 1, amount_max = 1 },
{ itemstring = "mcl_core:diamond", weight = 5, amount_min = 1, amount_max = 1 },
}
},{
stacks_min = 3,
stacks_max = 3,
items = {
--{ itemstring = "FIXME TREASURE MAP", weight = 8, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_core:paper", weight = 20, amount_min = 1, amount_max = 10 },
{ itemstring = "mcl_mobitems:feather", weight = 10, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_books:book", weight = 5, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_clock:clock", weight = 1, amount_min = 1, amount_max = 1 },
{ itemstring = "mcl_compass:compass", weight = 1, amount_min = 1, amount_max = 1 },
{ itemstring = "mcl_maps:empty_map", weight = 1, amount_min = 1, amount_max = 1 },
}, {
stacks_min = 3,
stacks_max = 3,
items = {
--{ itemstring = "FIXME TREASURE MAP", weight = 8, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_core:paper", weight = 20, amount_min = 1, amount_max = 10 },
{ itemstring = "mcl_mobitems:feather", weight = 10, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_books:book", weight = 5, amount_min = 1, amount_max = 5 },
{ itemstring = "mcl_clock:clock", weight = 1, amount_min = 1, amount_max = 1 },
{ itemstring = "mcl_compass:compass", weight = 1, amount_min = 1, amount_max = 1 },
{ itemstring = "mcl_maps:empty_map", weight = 1, amount_min = 1, amount_max = 1 },
}
},

View File

@ -1,21 +1,21 @@
local modname = minetest.get_current_modname()
local S = minetest.get_translator(modname)
local modpath = minetest.get_modpath(modname)
local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false)
local function spawn_witch(p1,p2)
local c = minetest.find_node_near(p1,15,{"mcl_cauldrons:cauldron"})
local function spawn_witch(p1, p2)
local c = minetest.find_node_near(p1, 15, { "mcl_cauldrons:cauldron" })
if c then
local nn = minetest.find_nodes_in_area_under_air(vector.new(p1.x,c.y-1,p1.z),vector.new(p2.x,c.y-1,p2.z),{"mcl_core:sprucewood"})
local 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
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.can_despawn = false
end
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"}})
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.owner = "!witch!" --so it's not claimable by player
cat._home = c
cat.can_despawn = false
@ -23,24 +23,27 @@ local function spawn_witch(p1,p2)
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 p1 = vector.offset(pos,-hl,-hl,-hl)
local p2 = vector.offset(pos,hl,hl,hl)
local legs = minetest.find_nodes_in_area(vector.offset(pos,-hl,0,-hl),vector.offset(pos,hl,0,hl), "mcl_core:tree")
local p1 = vector.offset(pos, -hl, -hl, -hl)
local p2 = vector.offset(pos, hl, hl, hl)
local legs = minetest.find_nodes_in_area(vector.offset(pos, -hl, 0, -hl), vector.offset(pos, hl, 0, hl), "mcl_core:tree")
local tree = {}
for _,leg in pairs(legs) do
while minetest.get_item_group(mcl_vars.get_node(vector.offset(leg,0,-1,0), true, 333333).name, "water") ~= 0 do
leg = vector.offset(leg,0,-1,0)
table.insert(tree,leg)
for _, leg in pairs(legs) do
while minetest.get_item_group(mcl_vars.get_node(vector.offset(leg, 0, -1, 0), true, 333333).name, "water") ~= 0 do
leg = vector.offset(leg, 0, -1, 0)
table.insert(tree, leg)
end
end
minetest.bulk_set_node(tree, {name = "mcl_core:tree", param2 = 2})
spawn_witch(p1,p2)
minetest.bulk_set_node(tree, { name = "mcl_core:tree", param2 = 2 })
spawn_witch(p1, p2)
end
mcl_structures.register_structure("witch_hut",{
place_on = {"group:sand","group:grass_block","mcl_core:water_source","group:dirt"},
mcl_structures.register_structure("witch_hut", {
place_on = { "group:sand", "group:grass_block", "mcl_core:water_source", "group:dirt" },
fill_ratio = 0.01,
flags = "place_center_x, place_center_z, liquid_surface, force_placement",
sidelen = 8,
@ -49,6 +52,6 @@ mcl_structures.register_structure("witch_hut",{
y_min = -4,
y_offset = 0,
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,
})

View File

@ -1,12 +1,11 @@
local modname = minetest.get_current_modname()
local S = minetest.get_translator(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",{
place_on = {"group:grass_block","group:dirt","mcl_core:dirt_with_grass"},
mcl_structures.register_structure("woodland_cabin", {
place_on = { "group:grass_block", "group:dirt", "mcl_core:dirt_with_grass" },
fill_ratio = 0.01,
flags = "place_center_x, place_center_z",
solid_ground = true,
@ -17,32 +16,33 @@ mcl_structures.register_structure("woodland_cabin",{
biomes = { "RoofedForest" },
sidelen = 32,
filenames = {
modpath.."/schematics/mcl_structures_woodland_cabin.mts",
modpath.."/schematics/mcl_structures_woodland_outpost.mts",
modpath .. "/schematics/mcl_structures_woodland_cabin.mts",
modpath .. "/schematics/mcl_structures_woodland_outpost.mts",
},
construct_nodes = {"mcl_barrels:barrel_closed"},
after_place = function(p,def,pr)
local p1=vector.offset(p,-def.sidelen,-1,-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:evoker",spawnon,p1,p2,pr,1)
mcl_structures.spawn_mobs("mobs_mc:parrot",{"mcl_heads:wither_skeleton"},p1,p2,pr,1)
construct_nodes = { "mcl_barrels:barrel_closed" },
after_place = function(p, def, pr)
local p1 = vector.offset(p, -def.sidelen, -1, -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:evoker", spawnon, p1, p2, pr, 1)
mcl_structures.spawn_mobs("mobs_mc:parrot", { "mcl_heads:wither_skeleton" }, p1, p2, pr, 1)
end,
loot = {
["mcl_chests:chest_small" ] ={{
["mcl_chests:chest_small"] = { {
stacks_min = 3,
stacks_max = 3,
items = {
{ itemstring = "mcl_mobitems:bone", weight = 10, amount_min = 1, amount_max=8 },
{ itemstring = "mcl_mobitems:bone", weight = 10, amount_min = 1, amount_max = 8 },
{ itemstring = "mcl_mobitems:gunpowder", weight = 10, amount_min = 1, amount_max = 8 },
{ itemstring = "mcl_mobitems:rotten_flesh", weight = 10, amount_min = 1, amount_max=8 },
{ itemstring = "mcl_mobitems:string", weight = 10, amount_min = 1, amount_max=8 },
{ itemstring = "mcl_mobitems:rotten_flesh", weight = 10, amount_min = 1, amount_max = 8 },
{ itemstring = "mcl_mobitems:string", weight = 10, amount_min = 1, amount_max = 8 },
{ itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 },
}},{
stacks_min = 1,
stacks_max = 4,
items = {
}
}, {
stacks_min = 1,
stacks_max = 4,
items = {
{ itemstring = "mcl_farming:wheat_item", weight = 20, amount_min = 1, amount_max = 4 },
{ itemstring = "mcl_farming:bread", weight = 20, amount_min = 1, amount_max = 1 },
{ itemstring = "mcl_core:coal_lump", weight = 15, amount_min = 1, amount_max = 4 },
@ -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_buckets:bucket_empty", weight = 10, amount_min = 1, amount_max = 1 },
{ itemstring = "mcl_core:gold_ingot", weight = 5, amount_min = 1, amount_max = 4 },
}},{
stacks_min = 1,
stacks_max = 4,
items = {
}
}, {
stacks_min = 1,
stacks_max = 4,
items = {
--{ itemstring = "FIXME:lead", weight = 20, amount_min = 1, amount_max = 1 },
{ itemstring = "mcl_mobs:nametag", weight = 2, amount_min = 1, amount_max = 3 },
{ itemstring = "mcl_books:book", weight = 1, func = function(stack, pr)mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end },
{ itemstring = "mcl_books:book", weight = 1,
func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, { "soul_speed" }, pr) end },
{ itemstring = "mcl_armor:chestplate_chain", weight = 1, },
{ itemstring = "mcl_armor:chestplate_diamond", weight = 1, },
{ itemstring = "mcl_core:apple_gold_enchanted", weight = 2, },
}
}}
} }
}
})