Merge branch 'master' into dyable-leather-armor
commit
d7ae8c62db
|
@ -175,3 +175,86 @@ minetest.craftitemdef_default.stack_max = 64
|
||||||
-- Set random seed for all other mods (Remember to make sure no other mod calls this function)
|
-- Set random seed for all other mods (Remember to make sure no other mod calls this function)
|
||||||
math.randomseed(os.time())
|
math.randomseed(os.time())
|
||||||
|
|
||||||
|
local chunks = {} -- intervals of chunks generated
|
||||||
|
function mcl_vars.add_chunk(pos)
|
||||||
|
local n = mcl_vars.get_chunk_number(pos) -- unsigned int
|
||||||
|
local prev
|
||||||
|
for i, d in pairs(chunks) do
|
||||||
|
if n <= d[2] then -- we've found it
|
||||||
|
if (n == d[2]) or (n >= d[1]) then return end -- already here
|
||||||
|
if n == d[1]-1 then -- right before:
|
||||||
|
if prev and (prev[2] == n-1) then
|
||||||
|
prev[2] = d[2]
|
||||||
|
table.remove(chunks, i)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
d[1] = n
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if prev and (prev[2] == n-1) then --join to previous
|
||||||
|
prev[2] = n
|
||||||
|
return
|
||||||
|
end
|
||||||
|
table.insert(chunks, i, {n, n}) -- insert new interval before i
|
||||||
|
return
|
||||||
|
end
|
||||||
|
prev = d
|
||||||
|
end
|
||||||
|
chunks[#chunks+1] = {n, n}
|
||||||
|
end
|
||||||
|
function mcl_vars.is_generated(pos)
|
||||||
|
local n = mcl_vars.get_chunk_number(pos) -- unsigned int
|
||||||
|
for i, d in pairs(chunks) do
|
||||||
|
if n <= d[2] then
|
||||||
|
return (n >= d[1])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- "Trivial" (actually NOT) function to just read the node and some stuff to not just return "ignore", like mt 5.4 does.
|
||||||
|
-- p: Position, if it's wrong, {name="error"} node will return.
|
||||||
|
-- force: optional (default: false) - Do the maximum to still read the node within us_timeout.
|
||||||
|
-- us_timeout: optional (default: 244 = 0.000244 s = 1/80/80/80), set it at least to 3000000 to let mapgen to finish its job.
|
||||||
|
--
|
||||||
|
-- returns node definition, eg. {name="air"}. Unfortunately still can return {name="ignore"}.
|
||||||
|
function mcl_vars.get_node(p, force, us_timeout)
|
||||||
|
-- check initial circumstances
|
||||||
|
if not p or not p.x or not p.y or not p.z then return {name="error"} end
|
||||||
|
|
||||||
|
-- try common way
|
||||||
|
local node = minetest.get_node(p)
|
||||||
|
if node.name ~= "ignore" then
|
||||||
|
return node
|
||||||
|
end
|
||||||
|
|
||||||
|
-- copy table to get sure it won't changed by other threads
|
||||||
|
local pos = {x=p.x,y=p.y,z=p.z}
|
||||||
|
|
||||||
|
-- try LVM
|
||||||
|
minetest.get_voxel_manip():read_from_map(pos, pos)
|
||||||
|
node = minetest.get_node(pos)
|
||||||
|
if node.name ~= "ignore" or not force then
|
||||||
|
return node
|
||||||
|
end
|
||||||
|
|
||||||
|
-- all ways failed - need to emerge (or forceload if generated)
|
||||||
|
local us_timeout = us_timeout or 244
|
||||||
|
if mcl_vars.is_generated(pos) then
|
||||||
|
minetest.chat_send_all("IMPOSSIBLE! Please report this to MCL2 issue tracker!")
|
||||||
|
minetest.forceload_block(pos)
|
||||||
|
else
|
||||||
|
minetest.emerge_area(pos, pos)
|
||||||
|
end
|
||||||
|
|
||||||
|
local t = minetest.get_us_time()
|
||||||
|
|
||||||
|
node = minetest.get_node(pos)
|
||||||
|
|
||||||
|
while (not node or node.name == "ignore") and (minetest.get_us_time() - t < us_timeout) do
|
||||||
|
node = minetest.get_node(pos)
|
||||||
|
end
|
||||||
|
|
||||||
|
return node
|
||||||
|
-- it still can return "ignore", LOL, even if force = true, but only after time out
|
||||||
|
end
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
local has_awards = minetest.get_modpath("awards")
|
||||||
|
|
||||||
|
mcl_item_entity = {}
|
||||||
|
|
||||||
--basic settings
|
--basic settings
|
||||||
local item_drop_settings = {} --settings table
|
local item_drop_settings = {} --settings table
|
||||||
item_drop_settings.age = 1.0 --how old a dropped item (_insta_collect==false) has to be before collecting
|
item_drop_settings.age = 1.0 --how old a dropped item (_insta_collect==false) has to be before collecting
|
||||||
|
@ -16,16 +20,33 @@ local get_gravity = function()
|
||||||
return tonumber(minetest.settings:get("movement_gravity")) or 9.81
|
return tonumber(minetest.settings:get("movement_gravity")) or 9.81
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local registered_pickup_achievement = {}
|
||||||
|
|
||||||
|
--TODO: remove limitation of 1 award per itemname
|
||||||
|
function mcl_item_entity.register_pickup_achievement(itemname, award)
|
||||||
|
if not has_awards then
|
||||||
|
minetest.log("warning", "[mcl_item_entity] Trying to register pickup achievement ["..award.."] for ["..itemname.."] while awards missing")
|
||||||
|
elseif registered_pickup_achievement[itemname] then
|
||||||
|
minetest.log("error", "[mcl_item_entity] Trying to register already existing pickup achievement ["..award.."] for ["..itemname.."]")
|
||||||
|
else
|
||||||
|
registered_pickup_achievement[itemname] = award
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
mcl_item_entity.register_pickup_achievement("tree", "mcl:mineWood")
|
||||||
|
mcl_item_entity.register_pickup_achievement("mcl_mobitems:blaze_rod", "mcl:blazeRod")
|
||||||
|
mcl_item_entity.register_pickup_achievement("mcl_mobitems:leather", "mcl:killCow")
|
||||||
|
mcl_item_entity.register_pickup_achievement("mcl_core:diamond", "mcl:diamonds")
|
||||||
|
|
||||||
local check_pickup_achievements = function(object, player)
|
local check_pickup_achievements = function(object, player)
|
||||||
local itemname = ItemStack(object:get_luaentity().itemstring):get_name()
|
if has_awards then
|
||||||
if minetest.get_item_group(itemname, "tree") ~= 0 then
|
local itemname = ItemStack(object:get_luaentity().itemstring):get_name()
|
||||||
awards.unlock(player:get_player_name(), "mcl:mineWood")
|
local playername = player:get_player_name()
|
||||||
elseif itemname == "mcl_mobitems:blaze_rod" then
|
for name,award in pairs(registered_pickup_achievement) do
|
||||||
awards.unlock(player:get_player_name(), "mcl:blazeRod")
|
if itemname == name or minetest.get_item_group(itemname, name) ~= 0 then
|
||||||
elseif itemname == "mcl_mobitems:leather" then
|
awards.unlock(playername, award)
|
||||||
awards.unlock(player:get_player_name(), "mcl:killCow")
|
end
|
||||||
elseif itemname == "mcl_core:diamond" then
|
end
|
||||||
awards.unlock(player:get_player_name(), "mcl:diamonds")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -238,3 +238,20 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
awards.show_to(name, name, nil, false)
|
awards.show_to(name, name, nil, false)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
awards.register_achievement("mcl:stoneAge", {
|
||||||
|
title = S("Stone Age"),
|
||||||
|
description = S("Mine a stone with new pickaxe."),
|
||||||
|
icon = "default_cobble.png",
|
||||||
|
})
|
||||||
|
awards.register_achievement("mcl:hotStuff", {
|
||||||
|
title = S("Hot Stuff"),
|
||||||
|
description = S("Put lava in a bucket."),
|
||||||
|
icon = "bucket_lava.png",
|
||||||
|
})
|
||||||
|
awards.register_achievement("mcl:obsidian", {
|
||||||
|
title = S("Ice Bucket Challenge"),
|
||||||
|
description = S("Obtain an obsidian block."),
|
||||||
|
icon = "default_obsidian.png",
|
||||||
|
})
|
||||||
|
|
|
@ -89,6 +89,7 @@ function mcl_beds.register_bed(name, def)
|
||||||
selection_box = selection_box_bottom,
|
selection_box = selection_box_bottom,
|
||||||
collision_box = collision_box_bottom,
|
collision_box = collision_box_bottom,
|
||||||
drop = "",
|
drop = "",
|
||||||
|
node_placement_prediction = "",
|
||||||
on_place = function(itemstack, placer, pointed_thing)
|
on_place = function(itemstack, placer, pointed_thing)
|
||||||
local under = pointed_thing.under
|
local under = pointed_thing.under
|
||||||
|
|
||||||
|
|
|
@ -5,17 +5,17 @@ Add an API to register buckets to mcl
|
||||||
|
|
||||||
Register a new liquid
|
Register a new liquid
|
||||||
Accept folowing params:
|
Accept folowing params:
|
||||||
* source_place = a string or function.
|
* source_place: a string or function.
|
||||||
* string: name of the node to place
|
* string: name of the node to place
|
||||||
* function(pos): will returns name of the node to place with pos being the placement position
|
* function(pos): will returns name of the node to place with pos being the placement position
|
||||||
* source_take = table of liquid source node names to take
|
* source_take: table of liquid source node names to take
|
||||||
* itemname = itemstring of the new bucket item (or nil if liquid is not takeable)
|
* itemname: itemstring of the new bucket item (or nil if liquid is not takeable)
|
||||||
* inventory_image = texture of the new bucket item (ignored if itemname == nil)
|
* inventory_image: texture of the new bucket item (ignored if itemname == nil)
|
||||||
* name = user-visible bucket description
|
* name: user-visible bucket description
|
||||||
* longdesc = long explanatory description (for help)
|
* longdesc: long explanatory description (for help)
|
||||||
* usagehelp = short usage explanation (for help)
|
* usagehelp: short usage explanation (for help)
|
||||||
* tt_help = very short tooltip help
|
* tt_help: very short tooltip help
|
||||||
* extra_check(pos, placer) = optional function(pos) which can returns false to avoid placing the liquid. Placer is object/player who is placing the liquid, can be nil.
|
* extra_check(pos, placer): (optional) function(pos) which can returns false to avoid placing the liquid. Placer is object/player who is placing the liquid, can be nil.
|
||||||
* groups = optional list of item groups
|
* groups: optional list of item groups
|
||||||
|
|
||||||
This function can be called from any mod (which depends on this one)
|
This function can be called from any mod (which depends on this one)
|
|
@ -207,6 +207,9 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", {
|
||||||
-- Fill bucket, but not in Creative Mode
|
-- Fill bucket, but not in Creative Mode
|
||||||
if not minetest.is_creative_enabled(user:get_player_name()) then
|
if not minetest.is_creative_enabled(user:get_player_name()) then
|
||||||
new_bucket = ItemStack({name = liquiddef.itemname})
|
new_bucket = ItemStack({name = liquiddef.itemname})
|
||||||
|
if liquiddef.itemname == "mcl_buckets:bucket_lava" and awards and awards.unlock and user and user:is_player() then
|
||||||
|
awards.unlock(user:get_player_name(), "mcl:hotStuff")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.add_node(pointed_thing.under, {name="air"})
|
minetest.add_node(pointed_thing.under, {name="air"})
|
||||||
|
|
|
@ -33,6 +33,11 @@ minetest.register_node("mcl_core:stone", {
|
||||||
_mcl_blast_resistance = 6,
|
_mcl_blast_resistance = 6,
|
||||||
_mcl_hardness = 1.5,
|
_mcl_hardness = 1.5,
|
||||||
_mcl_silk_touch_drop = true,
|
_mcl_silk_touch_drop = true,
|
||||||
|
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||||
|
if awards and awards.unlock and digger and digger:is_player() then
|
||||||
|
awards.unlock(digger:get_player_name(), "mcl:stoneAge")
|
||||||
|
end
|
||||||
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_node("mcl_core:stone_with_coal", {
|
minetest.register_node("mcl_core:stone_with_coal", {
|
||||||
|
@ -814,6 +819,11 @@ minetest.register_node("mcl_core:obsidian", {
|
||||||
groups = {pickaxey=5, building_block=1, material_stone=1},
|
groups = {pickaxey=5, building_block=1, material_stone=1},
|
||||||
_mcl_blast_resistance = 1200,
|
_mcl_blast_resistance = 1200,
|
||||||
_mcl_hardness = 50,
|
_mcl_hardness = 50,
|
||||||
|
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||||
|
if awards and awards.unlock and digger and digger:is_player() then
|
||||||
|
awards.unlock(digger:get_player_name(), "mcl:obsidian")
|
||||||
|
end
|
||||||
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_node("mcl_core:ice", {
|
minetest.register_node("mcl_core:ice", {
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
# mcl_crafting_table
|
||||||
|
Add a node which allow players to craft more complex things.
|
||||||
|
|
||||||
|
## mcl_crafting_table.show_crafting_form(player)
|
||||||
|
Show the crafting form to a player.
|
||||||
|
Used in the node registration, but can be used by external mods.
|
|
@ -66,12 +66,7 @@ minetest.register_on_shutdown(function()
|
||||||
storage:set_string("nether_exits_keys", minetest.serialize(keys))
|
storage:set_string("nether_exits_keys", minetest.serialize(keys))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
mcl_portals.get_node = function(pos)
|
local get_node = mcl_vars.get_node
|
||||||
if mcl_mapgen_core and mcl_mapgen_core.get_node then
|
|
||||||
mcl_portals.get_node = mcl_mapgen_core.get_node
|
|
||||||
end
|
|
||||||
return minetest.get_node(pos)
|
|
||||||
end
|
|
||||||
local set_node = minetest.set_node
|
local set_node = minetest.set_node
|
||||||
local registered_nodes = minetest.registered_nodes
|
local registered_nodes = minetest.registered_nodes
|
||||||
local is_protected = minetest.is_protected
|
local is_protected = minetest.is_protected
|
||||||
|
@ -97,7 +92,6 @@ local limits = {
|
||||||
-- Incoming verification performed: two nodes must be portal nodes, and an obsidian below them.
|
-- Incoming verification performed: two nodes must be portal nodes, and an obsidian below them.
|
||||||
-- If the verification passes - position adds to the table and saves to mod storage on exit.
|
-- If the verification passes - position adds to the table and saves to mod storage on exit.
|
||||||
local function add_exit(p)
|
local function add_exit(p)
|
||||||
local get_node = mcl_portals.get_node
|
|
||||||
if not p or not p.y or not p.z or not p.x then return end
|
if not p or not p.y or not p.z or not p.x then return end
|
||||||
local x, y, z = floor(p.x), floor(p.y), floor(p.z)
|
local x, y, z = floor(p.x), floor(p.y), floor(p.z)
|
||||||
local p = {x = x, y = y, z = z}
|
local p = {x = x, y = y, z = z}
|
||||||
|
@ -109,7 +103,7 @@ local function add_exit(p)
|
||||||
local e = exits[k]
|
local e = exits[k]
|
||||||
for i = 1, #e do
|
for i = 1, #e do
|
||||||
local t = e[i]
|
local t = e[i]
|
||||||
if t.x == p.x and t.y == p.y and t.z == p.z then
|
if t and t.x == p.x and t.y == p.y and t.z == p.z then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -202,7 +196,6 @@ local function destroy_nether_portal(pos, node)
|
||||||
local nn, orientation = node.name, node.param2
|
local nn, orientation = node.name, node.param2
|
||||||
local obsidian = nn == OBSIDIAN
|
local obsidian = nn == OBSIDIAN
|
||||||
|
|
||||||
local get_node = mcl_portals.get_node
|
|
||||||
local check_remove = function(pos, orientation)
|
local check_remove = function(pos, orientation)
|
||||||
local node = get_node(pos)
|
local node = get_node(pos)
|
||||||
if node and (node.name == PORTAL and (orientation == nil or (node.param2 == orientation))) then
|
if node and (node.name == PORTAL and (orientation == nil or (node.param2 == orientation))) then
|
||||||
|
@ -285,12 +278,14 @@ minetest.register_node(PORTAL, {
|
||||||
_mcl_blast_resistance = 0,
|
_mcl_blast_resistance = 0,
|
||||||
})
|
})
|
||||||
|
|
||||||
local function light_frame(x1, y1, z1, x2, y2, z2, name)
|
local function light_frame(x1, y1, z1, x2, y2, z2, name, node, node_frame)
|
||||||
local orientation = 0
|
local orientation = 0
|
||||||
if x1 == x2 then
|
if x1 == x2 then
|
||||||
orientation = 1
|
orientation = 1
|
||||||
end
|
end
|
||||||
local pos = {}
|
local pos = {}
|
||||||
|
local node = node or {name = PORTAL, param2 = orientation}
|
||||||
|
local node_frame = node_frame or {name = OBSIDIAN}
|
||||||
for x = x1 - 1 + orientation, x2 + 1 - orientation do
|
for x = x1 - 1 + orientation, x2 + 1 - orientation do
|
||||||
pos.x = x
|
pos.x = x
|
||||||
for z = z1 - orientation, z2 + orientation do
|
for z = z1 - orientation, z2 + orientation do
|
||||||
|
@ -299,9 +294,9 @@ local function light_frame(x1, y1, z1, x2, y2, z2, name)
|
||||||
pos.y = y
|
pos.y = y
|
||||||
local frame = (x < x1) or (x > x2) or (y < y1) or (y > y2) or (z < z1) or (z > z2)
|
local frame = (x < x1) or (x > x2) or (y < y1) or (y > y2) or (z < z1) or (z > z2)
|
||||||
if frame then
|
if frame then
|
||||||
set_node(pos, {name = OBSIDIAN})
|
set_node(pos, node_frame)
|
||||||
else
|
else
|
||||||
set_node(pos, {name = PORTAL, param2 = orientation})
|
set_node(pos, node)
|
||||||
add_exit({x=pos.x, y=pos.y-1, z=pos.z})
|
add_exit({x=pos.x, y=pos.y-1, z=pos.z})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -310,12 +305,13 @@ local function light_frame(x1, y1, z1, x2, y2, z2, name)
|
||||||
end
|
end
|
||||||
|
|
||||||
--Build arrival portal
|
--Build arrival portal
|
||||||
function build_nether_portal(pos, width, height, orientation, name)
|
function build_nether_portal(pos, width, height, orientation, name, clear_before_build)
|
||||||
local width, height, orientation = width or W_MIN - 2, height or H_MIN - 2, orientation or random(0, 1)
|
local width, height, orientation = width or W_MIN - 2, height or H_MIN - 2, orientation or random(0, 1)
|
||||||
|
|
||||||
light_frame(pos.x, pos.y, pos.z, pos.x + (1 - orientation) * (width - 1), pos.y + height - 1, pos.z + orientation * (width - 1))
|
if clear_before_build then
|
||||||
|
light_frame(pos.x, pos.y, pos.z, pos.x + (1 - orientation) * (width - 1), pos.y + height - 1, pos.z + orientation * (width - 1), name, {name="air"}, {name="air"})
|
||||||
local get_node = mcl_portals.get_node
|
end
|
||||||
|
light_frame(pos.x, pos.y, pos.z, pos.x + (1 - orientation) * (width - 1), pos.y + height - 1, pos.z + orientation * (width - 1), name)
|
||||||
|
|
||||||
-- Build obsidian platform:
|
-- Build obsidian platform:
|
||||||
for x = pos.x - orientation, pos.x + orientation + (width - 1) * (1 - orientation), 1 + orientation do
|
for x = pos.x - orientation, pos.x + orientation + (width - 1) * (1 - orientation), 1 + orientation do
|
||||||
|
@ -345,7 +341,7 @@ function mcl_portals.spawn_nether_portal(pos, rot, pr, name)
|
||||||
o = random(0,1)
|
o = random(0,1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
build_nether_portal(pos, nil, nil, o, name)
|
build_nether_portal(pos, nil, nil, o, name, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Teleportation cooloff for some seconds, to prevent back-and-forth teleportation
|
-- Teleportation cooloff for some seconds, to prevent back-and-forth teleportation
|
||||||
|
@ -379,7 +375,13 @@ local function finalize_teleport(obj, exit)
|
||||||
|
|
||||||
-- If player stands, player is at ca. something+0.5 which might cause precision problems, so we used ceil for objpos.y
|
-- If player stands, player is at ca. something+0.5 which might cause precision problems, so we used ceil for objpos.y
|
||||||
objpos = {x = floor(objpos.x+0.5), y = ceil(objpos.y), z = floor(objpos.z+0.5)}
|
objpos = {x = floor(objpos.x+0.5), y = ceil(objpos.y), z = floor(objpos.z+0.5)}
|
||||||
if mcl_portals.get_node(objpos).name ~= PORTAL then return end
|
if get_node(objpos).name ~= PORTAL then return end
|
||||||
|
|
||||||
|
-- THIS IS A TEMPORATY CODE SECTION FOR COMPATIBILITY REASONS -- 1 of 2 -- TODO: Remove --
|
||||||
|
-- Old worlds have no exits indexed - adding the exit to return here:
|
||||||
|
add_exit(objpos)
|
||||||
|
-- TEMPORATY CODE SECTION ENDS HERE --
|
||||||
|
|
||||||
|
|
||||||
-- Enable teleportation cooloff for some seconds, to prevent back-and-forth teleportation
|
-- Enable teleportation cooloff for some seconds, to prevent back-and-forth teleportation
|
||||||
teleport_cooloff(obj)
|
teleport_cooloff(obj)
|
||||||
|
@ -436,7 +438,8 @@ local function ecb_scan_area_2(blockpos, action, calls_remaining, param)
|
||||||
local pos0, distance
|
local pos0, distance
|
||||||
local lava = get_lava_level(pos, pos1, pos2)
|
local lava = get_lava_level(pos, pos1, pos2)
|
||||||
|
|
||||||
-- THIS IS A TEMPORATY CODE SECTION FOR COMPATIBILITY REASONS --
|
-- THIS IS A TEMPORATY CODE SECTION FOR COMPATIBILITY REASONS -- 2 of 2 -- TODO: Remove --
|
||||||
|
-- Find portals for old worlds (new worlds keep them all in the table):
|
||||||
local portals = find_nodes_in_area(pos1, pos2, {PORTAL})
|
local portals = find_nodes_in_area(pos1, pos2, {PORTAL})
|
||||||
if portals and #portals>0 then
|
if portals and #portals>0 then
|
||||||
for _, p in pairs(portals) do
|
for _, p in pairs(portals) do
|
||||||
|
@ -463,7 +466,6 @@ local function ecb_scan_area_2(blockpos, action, calls_remaining, param)
|
||||||
local nodes2 = find_nodes_in_area(node1, node2, {"air"})
|
local nodes2 = find_nodes_in_area(node1, node2, {"air"})
|
||||||
if nodes2 then
|
if nodes2 then
|
||||||
local nc2 = #nodes2
|
local nc2 = #nodes2
|
||||||
log("action", "[mcl_portals] nc2=" .. tostring(nc2))
|
|
||||||
if nc2 == 27 and not is_area_protected(node, node2, name) then
|
if nc2 == 27 and not is_area_protected(node, node2, name) then
|
||||||
local distance0 = dist(pos, node)
|
local distance0 = dist(pos, node)
|
||||||
if distance0 < 2 then
|
if distance0 < 2 then
|
||||||
|
@ -522,7 +524,7 @@ local function create_portal(pos, limit1, limit2, name, obj)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function available_for_nether_portal(p)
|
local function available_for_nether_portal(p)
|
||||||
local nn = mcl_portals.get_node(p).name
|
local nn = get_node(p).name
|
||||||
local obsidian = nn == OBSIDIAN
|
local obsidian = nn == OBSIDIAN
|
||||||
if nn ~= "air" and minetest.get_item_group(nn, "fire") ~= 1 then
|
if nn ~= "air" and minetest.get_item_group(nn, "fire") ~= 1 then
|
||||||
return false, obsidian
|
return false, obsidian
|
||||||
|
@ -629,7 +631,7 @@ local function teleport_no_delay(obj, pos)
|
||||||
|
|
||||||
-- If player stands, player is at ca. something+0.5 which might cause precision problems, so we used ceil for objpos.y
|
-- If player stands, player is at ca. something+0.5 which might cause precision problems, so we used ceil for objpos.y
|
||||||
objpos = {x = floor(objpos.x+0.5), y = ceil(objpos.y), z = floor(objpos.z+0.5)}
|
objpos = {x = floor(objpos.x+0.5), y = ceil(objpos.y), z = floor(objpos.z+0.5)}
|
||||||
if mcl_portals.get_node(objpos).name ~= PORTAL then return end
|
if get_node(objpos).name ~= PORTAL then return end
|
||||||
|
|
||||||
local target, dim = get_target(objpos)
|
local target, dim = get_target(objpos)
|
||||||
if not target then return end
|
if not target then return end
|
||||||
|
|
|
@ -12,6 +12,8 @@ end
|
||||||
local min_y = math.max(mcl_vars.mg_overworld_min, mcl_vars.mg_bedrock_overworld_max) + 1
|
local min_y = math.max(mcl_vars.mg_overworld_min, mcl_vars.mg_bedrock_overworld_max) + 1
|
||||||
local max_y = mcl_vars.mg_overworld_max - 1
|
local max_y = mcl_vars.mg_overworld_max - 1
|
||||||
|
|
||||||
|
local get_node = mcl_vars.get_node
|
||||||
|
|
||||||
-- Calculate the number of dungeon spawn attempts
|
-- Calculate the number of dungeon spawn attempts
|
||||||
-- In Minecraft, there 8 dungeon spawn attempts Minecraft chunk (16*256*16 = 65536 blocks).
|
-- In Minecraft, there 8 dungeon spawn attempts Minecraft chunk (16*256*16 = 65536 blocks).
|
||||||
-- Minetest chunks don't have this size, so scale the number accordingly.
|
-- Minetest chunks don't have this size, so scale the number accordingly.
|
||||||
|
@ -49,8 +51,8 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
|
||||||
local y_floor = y
|
local y_floor = y
|
||||||
local y_ceiling = y + dim.y + 1
|
local y_ceiling = y + dim.y + 1
|
||||||
if check then for tx = x+1, x+dim.x do for tz = z+1, z+dim.z do
|
if check then for tx = x+1, x+dim.x do for tz = z+1, z+dim.z do
|
||||||
if not minetest.registered_nodes[mcl_mapgen_core.get_node({x = tx, y = y_floor , z = tz}).name].walkable
|
if not minetest.registered_nodes[get_node({x = tx, y = y_floor , z = tz}).name].walkable
|
||||||
or not minetest.registered_nodes[mcl_mapgen_core.get_node({x = tx, y = y_ceiling, z = tz}).name].walkable then return false end
|
or not minetest.registered_nodes[get_node({x = tx, y = y_ceiling, z = tz}).name].walkable then return false end
|
||||||
end end end
|
end end end
|
||||||
|
|
||||||
-- Check for air openings (2 stacked air at ground level) in wall positions
|
-- Check for air openings (2 stacked air at ground level) in wall positions
|
||||||
|
@ -63,25 +65,25 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
|
||||||
|
|
||||||
local x2,z2 = x+dim.x+1, z+dim.z+1
|
local x2,z2 = x+dim.x+1, z+dim.z+1
|
||||||
|
|
||||||
if mcl_mapgen_core.get_node({x=x, y=y+1, z=z}).name == "air" and mcl_mapgen_core.get_node({x=x, y=y+2, z=z}).name == "air" then
|
if get_node({x=x, y=y+1, z=z}).name == "air" and get_node({x=x, y=y+2, z=z}).name == "air" then
|
||||||
openings_counter = openings_counter + 1
|
openings_counter = openings_counter + 1
|
||||||
if not openings[x] then openings[x]={} end
|
if not openings[x] then openings[x]={} end
|
||||||
openings[x][z] = true
|
openings[x][z] = true
|
||||||
table.insert(corners, {x=x, z=z})
|
table.insert(corners, {x=x, z=z})
|
||||||
end
|
end
|
||||||
if mcl_mapgen_core.get_node({x=x2, y=y+1, z=z}).name == "air" and mcl_mapgen_core.get_node({x=x2, y=y+2, z=z}).name == "air" then
|
if get_node({x=x2, y=y+1, z=z}).name == "air" and get_node({x=x2, y=y+2, z=z}).name == "air" then
|
||||||
openings_counter = openings_counter + 1
|
openings_counter = openings_counter + 1
|
||||||
if not openings[x2] then openings[x2]={} end
|
if not openings[x2] then openings[x2]={} end
|
||||||
openings[x2][z] = true
|
openings[x2][z] = true
|
||||||
table.insert(corners, {x=x2, z=z})
|
table.insert(corners, {x=x2, z=z})
|
||||||
end
|
end
|
||||||
if mcl_mapgen_core.get_node({x=x, y=y+1, z=z2}).name == "air" and mcl_mapgen_core.get_node({x=x, y=y+2, z=z2}).name == "air" then
|
if get_node({x=x, y=y+1, z=z2}).name == "air" and get_node({x=x, y=y+2, z=z2}).name == "air" then
|
||||||
openings_counter = openings_counter + 1
|
openings_counter = openings_counter + 1
|
||||||
if not openings[x] then openings[x]={} end
|
if not openings[x] then openings[x]={} end
|
||||||
openings[x][z2] = true
|
openings[x][z2] = true
|
||||||
table.insert(corners, {x=x, z=z2})
|
table.insert(corners, {x=x, z=z2})
|
||||||
end
|
end
|
||||||
if mcl_mapgen_core.get_node({x=x2, y=y+1, z=z2}).name == "air" and mcl_mapgen_core.get_node({x=x2, y=y+2, z=z2}).name == "air" then
|
if get_node({x=x2, y=y+1, z=z2}).name == "air" and get_node({x=x2, y=y+2, z=z2}).name == "air" then
|
||||||
openings_counter = openings_counter + 1
|
openings_counter = openings_counter + 1
|
||||||
if not openings[x2] then openings[x2]={} end
|
if not openings[x2] then openings[x2]={} end
|
||||||
openings[x2][z2] = true
|
openings[x2][z2] = true
|
||||||
|
@ -89,13 +91,13 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
|
||||||
end
|
end
|
||||||
|
|
||||||
for wx = x+1, x+dim.x do
|
for wx = x+1, x+dim.x do
|
||||||
if mcl_mapgen_core.get_node({x=wx, y=y+1, z=z}).name == "air" and mcl_mapgen_core.get_node({x=wx, y=y+2, z=z}).name == "air" then
|
if get_node({x=wx, y=y+1, z=z}).name == "air" and get_node({x=wx, y=y+2, z=z}).name == "air" then
|
||||||
openings_counter = openings_counter + 1
|
openings_counter = openings_counter + 1
|
||||||
if check and openings_counter > 5 then return end
|
if check and openings_counter > 5 then return end
|
||||||
if not openings[wx] then openings[wx]={} end
|
if not openings[wx] then openings[wx]={} end
|
||||||
openings[wx][z] = true
|
openings[wx][z] = true
|
||||||
end
|
end
|
||||||
if mcl_mapgen_core.get_node({x=wx, y=y+1, z=z2}).name == "air" and mcl_mapgen_core.get_node({x=wx, y=y+2, z=z2}).name == "air" then
|
if get_node({x=wx, y=y+1, z=z2}).name == "air" and get_node({x=wx, y=y+2, z=z2}).name == "air" then
|
||||||
openings_counter = openings_counter + 1
|
openings_counter = openings_counter + 1
|
||||||
if check and openings_counter > 5 then return end
|
if check and openings_counter > 5 then return end
|
||||||
if not openings[wx] then openings[wx]={} end
|
if not openings[wx] then openings[wx]={} end
|
||||||
|
@ -103,13 +105,13 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for wz = z+1, z+dim.z do
|
for wz = z+1, z+dim.z do
|
||||||
if mcl_mapgen_core.get_node({x=x, y=y+1, z=wz}).name == "air" and mcl_mapgen_core.get_node({x=x, y=y+2, z=wz}).name == "air" then
|
if get_node({x=x, y=y+1, z=wz}).name == "air" and get_node({x=x, y=y+2, z=wz}).name == "air" then
|
||||||
openings_counter = openings_counter + 1
|
openings_counter = openings_counter + 1
|
||||||
if check and openings_counter > 5 then return end
|
if check and openings_counter > 5 then return end
|
||||||
if not openings[x] then openings[x]={} end
|
if not openings[x] then openings[x]={} end
|
||||||
openings[x][wz] = true
|
openings[x][wz] = true
|
||||||
end
|
end
|
||||||
if mcl_mapgen_core.get_node({x=x2, y=y+1, z=wz}).name == "air" and mcl_mapgen_core.get_node({x=x2, y=y+2, z=wz}).name == "air" then
|
if get_node({x=x2, y=y+1, z=wz}).name == "air" and get_node({x=x2, y=y+2, z=wz}).name == "air" then
|
||||||
openings_counter = openings_counter + 1
|
openings_counter = openings_counter + 1
|
||||||
if check and openings_counter > 5 then return end
|
if check and openings_counter > 5 then return end
|
||||||
if not openings[x2] then openings[x2]={} end
|
if not openings[x2] then openings[x2]={} end
|
||||||
|
@ -185,7 +187,7 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
|
||||||
|
|
||||||
-- Calculate the mob spawner position, to be re-used for later
|
-- Calculate the mob spawner position, to be re-used for later
|
||||||
local sp = {x = x + math.ceil(dim.x/2), y = y+1, z = z + math.ceil(dim.z/2)}
|
local sp = {x = x + math.ceil(dim.x/2), y = y+1, z = z + math.ceil(dim.z/2)}
|
||||||
local rn = minetest.registered_nodes[mcl_mapgen_core.get_node(sp).name]
|
local rn = minetest.registered_nodes[get_node(sp).name]
|
||||||
if rn and rn.is_ground_content then
|
if rn and rn.is_ground_content then
|
||||||
table.insert(spawner_posses, sp)
|
table.insert(spawner_posses, sp)
|
||||||
end
|
end
|
||||||
|
@ -200,7 +202,7 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
|
||||||
|
|
||||||
-- Do not overwrite nodes with is_ground_content == false (e.g. bedrock)
|
-- Do not overwrite nodes with is_ground_content == false (e.g. bedrock)
|
||||||
-- Exceptions: cobblestone and mossy cobblestone so neighborings dungeons nicely connect to each other
|
-- Exceptions: cobblestone and mossy cobblestone so neighborings dungeons nicely connect to each other
|
||||||
local name = mcl_mapgen_core.get_node(p).name
|
local name = get_node(p).name
|
||||||
if minetest.registered_nodes[name].is_ground_content or name == "mcl_core:cobble" or name == "mcl_core:mossycobble" then
|
if minetest.registered_nodes[name].is_ground_content or name == "mcl_core:cobble" or name == "mcl_core:mossycobble" then
|
||||||
-- Floor
|
-- Floor
|
||||||
if ty == y then
|
if ty == y then
|
||||||
|
@ -245,7 +247,7 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
|
||||||
if forChest and (currentChest < totalChests + 1) and (chestSlots[currentChest] == chestSlotCounter) then
|
if forChest and (currentChest < totalChests + 1) and (chestSlots[currentChest] == chestSlotCounter) then
|
||||||
currentChest = currentChest + 1
|
currentChest = currentChest + 1
|
||||||
table.insert(chests, {x=tx, y=ty, z=tz})
|
table.insert(chests, {x=tx, y=ty, z=tz})
|
||||||
else
|
-- else
|
||||||
--minetest.swap_node(p, {name = "air"})
|
--minetest.swap_node(p, {name = "air"})
|
||||||
end
|
end
|
||||||
if forChest then
|
if forChest then
|
||||||
|
@ -263,8 +265,8 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
|
||||||
-- Detect the 4 horizontal neighbors
|
-- Detect the 4 horizontal neighbors
|
||||||
local spos = vector.add(pos, surround_vectors[s])
|
local spos = vector.add(pos, surround_vectors[s])
|
||||||
local wpos = vector.subtract(pos, surround_vectors[s])
|
local wpos = vector.subtract(pos, surround_vectors[s])
|
||||||
local nodename = minetest.get_node(spos).name
|
local nodename = get_node(spos).name
|
||||||
local nodename2 = minetest.get_node(wpos).name
|
local nodename2 = get_node(wpos).name
|
||||||
local nodedef = minetest.registered_nodes[nodename]
|
local nodedef = minetest.registered_nodes[nodename]
|
||||||
local nodedef2 = minetest.registered_nodes[nodename2]
|
local nodedef2 = minetest.registered_nodes[nodename2]
|
||||||
-- The chest needs an open space in front of it and a walkable node (except chest) behind it
|
-- The chest needs an open space in front of it and a walkable node (except chest) behind it
|
||||||
|
@ -345,6 +347,7 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
minetest.log("action", "[mcl_dungeons] Filling chest " .. tostring(c) .. " at " .. minetest.pos_to_string(pos))
|
||||||
mcl_loot.fill_inventory(meta:get_inventory(), "main", mcl_loot.get_multi_loot(loottable, pr), pr)
|
mcl_loot.fill_inventory(meta:get_inventory(), "main", mcl_loot.get_multi_loot(loottable, pr), pr)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,45 +1,8 @@
|
||||||
mcl_mapgen_core = {}
|
mcl_mapgen_core = {}
|
||||||
mcl_mapgen_core.registered_generators = {}
|
local registered_generators = {}
|
||||||
|
|
||||||
local lvm, nodes, param2 = 0, 0, 0
|
local lvm, nodes, param2 = 0, 0, 0
|
||||||
|
local lvm_buffer = {}
|
||||||
local generating = {} -- generating chunks
|
|
||||||
local chunks = {} -- intervals of chunks generated
|
|
||||||
local function add_chunk(pos)
|
|
||||||
local n = mcl_vars.get_chunk_number(pos) -- unsigned int
|
|
||||||
local prev
|
|
||||||
for i, d in pairs(chunks) do
|
|
||||||
if n <= d[2] then -- we've found it
|
|
||||||
if (n == d[2]) or (n >= d[1]) then return end -- already here
|
|
||||||
if n == d[1]-1 then -- right before:
|
|
||||||
if prev and (prev[2] == n-1) then
|
|
||||||
prev[2] = d[2]
|
|
||||||
table.remove(chunks, i)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
d[1] = n
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if prev and (prev[2] == n-1) then --join to previous
|
|
||||||
prev[2] = n
|
|
||||||
return
|
|
||||||
end
|
|
||||||
table.insert(chunks, i, {n, n}) -- insert new interval before i
|
|
||||||
return
|
|
||||||
end
|
|
||||||
prev = d
|
|
||||||
end
|
|
||||||
chunks[#chunks+1] = {n, n}
|
|
||||||
end
|
|
||||||
function mcl_mapgen_core.is_generated(pos)
|
|
||||||
local n = mcl_vars.get_chunk_number(pos) -- unsigned int
|
|
||||||
for i, d in pairs(chunks) do
|
|
||||||
if n <= d[2] then
|
|
||||||
return (n >= d[1])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Aliases for map generator outputs
|
-- Aliases for map generator outputs
|
||||||
|
@ -1850,24 +1813,22 @@ end
|
||||||
|
|
||||||
minetest.register_on_generated(function(minp, maxp, blockseed)
|
minetest.register_on_generated(function(minp, maxp, blockseed)
|
||||||
minetest.log("action", "[mcl_mapgen_core] Generating chunk " .. minetest.pos_to_string(minp) .. " ... " .. minetest.pos_to_string(maxp))
|
minetest.log("action", "[mcl_mapgen_core] Generating chunk " .. minetest.pos_to_string(minp) .. " ... " .. minetest.pos_to_string(maxp))
|
||||||
add_chunk(minp)
|
|
||||||
local p1, p2 = {x=minp.x, y=minp.y, z=minp.z}, {x=maxp.x, y=maxp.y, z=maxp.z}
|
local p1, p2 = {x=minp.x, y=minp.y, z=minp.z}, {x=maxp.x, y=maxp.y, z=maxp.z}
|
||||||
if lvm > 0 then
|
if lvm > 0 then
|
||||||
local lvm_used, shadow = false, false
|
local lvm_used, shadow = false, false
|
||||||
local lb = {} -- buffer
|
|
||||||
local lb2 = {} -- param2
|
local lb2 = {} -- param2
|
||||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||||
local e1, e2 = {x=emin.x, y=emin.y, z=emin.z}, {x=emax.x, y=emax.y, z=emax.z}
|
local e1, e2 = {x=emin.x, y=emin.y, z=emin.z}, {x=emax.x, y=emax.y, z=emax.z}
|
||||||
local data2
|
local data2
|
||||||
local data = vm:get_data(lb)
|
local data = vm:get_data(lvm_buffer)
|
||||||
if param2 > 0 then
|
if param2 > 0 then
|
||||||
data2 = vm:get_param2_data(lb2)
|
data2 = vm:get_param2_data(lb2)
|
||||||
end
|
end
|
||||||
local area = VoxelArea:new({MinEdge=e1, MaxEdge=e2})
|
local area = VoxelArea:new({MinEdge=e1, MaxEdge=e2})
|
||||||
|
|
||||||
for _, rec in pairs(mcl_mapgen_core.registered_generators) do
|
for _, rec in pairs(registered_generators) do
|
||||||
if rec.vf then
|
if rec.vf then
|
||||||
local lvm_used0, shadow0 = rec.vf(vm, data, data2, p1, p2, area, p1, p2, blockseed)
|
local lvm_used0, shadow0 = rec.vf(vm, data, data2, e1, e2, area, p1, p2, blockseed)
|
||||||
if lvm_used0 then
|
if lvm_used0 then
|
||||||
lvm_used = true
|
lvm_used = true
|
||||||
end
|
end
|
||||||
|
@ -1890,18 +1851,18 @@ minetest.register_on_generated(function(minp, maxp, blockseed)
|
||||||
end
|
end
|
||||||
|
|
||||||
if nodes > 0 then
|
if nodes > 0 then
|
||||||
for _, rec in pairs(mcl_mapgen_core.registered_generators) do
|
for _, rec in pairs(registered_generators) do
|
||||||
if rec.nf then
|
if rec.nf then
|
||||||
rec.nf(p1, p2, blockseed)
|
rec.nf(p1, p2, blockseed)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- add_chunk(minp)
|
mcl_vars.add_chunk(minp)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
minetest.register_on_generated=function(node_function)
|
minetest.register_on_generated=function(node_function)
|
||||||
mcl_mapgen_core.register_generator("mod_"..tostring(#mcl_mapgen_core.registered_generators+1), nil, node_function)
|
mcl_mapgen_core.register_generator("mod_"..tostring(#registered_generators+1), nil, node_function)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mcl_mapgen_core.register_generator(id, lvm_function, node_function, priority, needs_param2)
|
function mcl_mapgen_core.register_generator(id, lvm_function, node_function, priority, needs_param2)
|
||||||
|
@ -1920,18 +1881,18 @@ function mcl_mapgen_core.register_generator(id, lvm_function, node_function, pri
|
||||||
needs_param2 = needs_param2,
|
needs_param2 = needs_param2,
|
||||||
}
|
}
|
||||||
|
|
||||||
mcl_mapgen_core.registered_generators[id] = new_record
|
registered_generators[id] = new_record
|
||||||
table.sort(
|
table.sort(
|
||||||
mcl_mapgen_core.registered_generators,
|
registered_generators,
|
||||||
function(a, b)
|
function(a, b)
|
||||||
return (a.i < b.i) or ((a.i == b.i) and (a.vf ~= nil) and (b.vf == nil))
|
return (a.i < b.i) or ((a.i == b.i) and (a.vf ~= nil) and (b.vf == nil))
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mcl_mapgen_core.unregister_generator(id)
|
function mcl_mapgen_core.unregister_generator(id)
|
||||||
if not mcl_mapgen_core.registered_generators[id] then return end
|
if not registered_generators[id] then return end
|
||||||
local rec = mcl_mapgen_core.registered_generators[id]
|
local rec = registered_generators[id]
|
||||||
mcl_mapgen_core.registered_generators[id] = nil
|
registered_generators[id] = nil
|
||||||
if rec.vf then lvm = lvm - 1 end
|
if rec.vf then lvm = lvm - 1 end
|
||||||
if rev.nf then nodes = nodes - 1 end
|
if rev.nf then nodes = nodes - 1 end
|
||||||
if rec.needs_param2 then param2 = param2 - 1 end
|
if rec.needs_param2 then param2 = param2 - 1 end
|
||||||
|
@ -2134,9 +2095,9 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed)
|
||||||
-- Nether block fixes:
|
-- Nether block fixes:
|
||||||
-- * Replace water with Nether lava.
|
-- * Replace water with Nether lava.
|
||||||
-- * Replace stone, sand dirt in v6 so the Nether works in v6.
|
-- * Replace stone, sand dirt in v6 so the Nether works in v6.
|
||||||
elseif minp.y <= mcl_vars.mg_nether_max and maxp.y >= mcl_vars.mg_nether_min then
|
elseif emin.y <= mcl_vars.mg_nether_max and emax.y >= mcl_vars.mg_nether_min then
|
||||||
if mg_name == "v6" then
|
if mg_name == "v6" then
|
||||||
local nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"})
|
local nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"})
|
||||||
for n=1, #nodes do
|
for n=1, #nodes do
|
||||||
local p_pos = area:index(nodes[n].x, nodes[n].y, nodes[n].z)
|
local p_pos = area:index(nodes[n].x, nodes[n].y, nodes[n].z)
|
||||||
if data[p_pos] == c_water then
|
if data[p_pos] == c_water then
|
||||||
|
@ -2151,16 +2112,10 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
minetest.emerge_area(minp, maxp, function(blockpos, action, calls_remaining, param)
|
local nodes = minetest.find_nodes_in_area(emin, emax, {"group:water"})
|
||||||
if calls_remaining > 0 then return end
|
for _, n in pairs(nodes) do
|
||||||
-- local nodes = minetest.find_nodes_in_area(param.minp, param.maxp, {"mcl_core:water_source"})
|
data[area:index(n.x, n.y, n.z)] = c_nether_lava
|
||||||
local nodes = minetest.find_nodes_in_area(param.minp, param.maxp, {"group:water"})
|
end
|
||||||
local sn=(mcl_observers and mcl_observers.swap_node) or minetest.swap_node
|
|
||||||
local l = {name="mcl_nether:nether_lava_source"}
|
|
||||||
for _, n in pairs(nodes) do
|
|
||||||
sn(n, l)
|
|
||||||
end
|
|
||||||
end, {minp=vector.new(minp), maxp=vector.new(maxp)})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- End block fixes:
|
-- End block fixes:
|
||||||
|
@ -2168,17 +2123,16 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed)
|
||||||
-- * Remove stone, sand, dirt in v6 so our End map generator works in v6.
|
-- * Remove stone, sand, dirt in v6 so our End map generator works in v6.
|
||||||
-- * Generate spawn platform (End portal destination)
|
-- * Generate spawn platform (End portal destination)
|
||||||
elseif minp.y <= mcl_vars.mg_end_max and maxp.y >= mcl_vars.mg_end_min then
|
elseif minp.y <= mcl_vars.mg_end_max and maxp.y >= mcl_vars.mg_end_min then
|
||||||
local nodes, node
|
local nodes, n
|
||||||
if mg_name == "v6" then
|
if mg_name == "v6" then
|
||||||
nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"})
|
nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"})
|
||||||
else
|
else
|
||||||
nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:water_source"})
|
nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source"})
|
||||||
end
|
end
|
||||||
if #nodes > 0 then
|
if #nodes > 0 then
|
||||||
lvm_used = true
|
lvm_used = true
|
||||||
for n=1, #nodes do
|
for _, n in pairs(nodes) do
|
||||||
node = nodes[n]
|
data[area:index(n.x, n.y, n.z)] = c_air
|
||||||
data[area:index(node.x, node.y, node.z)] = c_air
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -2231,48 +2185,3 @@ end
|
||||||
|
|
||||||
mcl_mapgen_core.register_generator("main", basic, nil, 1, true)
|
mcl_mapgen_core.register_generator("main", basic, nil, 1, true)
|
||||||
|
|
||||||
-- "Trivial" (actually NOT) function to just read the node and some stuff to not just return "ignore", like 5.3.0 does.
|
|
||||||
-- p: Position, if it's wrong, {name="error"} node will return.
|
|
||||||
-- force: optional (default: false) - Do the maximum to still read the node within us_timeout.
|
|
||||||
-- us_timeout: optional (default: 244 = 0.000244 s = 1/80/80/80), set it at least to 3000000 to let mapgen to finish its job.
|
|
||||||
--
|
|
||||||
-- returns node definition, eg. {name="air"}. Unfortunately still can return {name="ignore"}.
|
|
||||||
function mcl_mapgen_core.get_node(p, force, us_timeout)
|
|
||||||
-- check initial circumstances
|
|
||||||
if not p or not p.x or not p.y or not p.z then return {name="error"} end
|
|
||||||
|
|
||||||
-- try common way
|
|
||||||
local node = minetest.get_node(p)
|
|
||||||
if node.name ~= "ignore" then
|
|
||||||
return node
|
|
||||||
end
|
|
||||||
|
|
||||||
-- copy table to get sure it won't changed by other threads
|
|
||||||
local pos = {x=p.x,y=p.y,z=p.z}
|
|
||||||
|
|
||||||
-- try LVM
|
|
||||||
minetest.get_voxel_manip():read_from_map(pos, pos)
|
|
||||||
node = minetest.get_node(pos)
|
|
||||||
if node.name ~= "ignore" or not force then
|
|
||||||
return node
|
|
||||||
end
|
|
||||||
|
|
||||||
-- all ways failed - need to emerge (or forceload if generated)
|
|
||||||
local us_timeout = us_timeout or 244
|
|
||||||
if mcl_mapgen_core.is_generated(pos) then
|
|
||||||
minetest.forceload_block(pos)
|
|
||||||
else
|
|
||||||
minetest.emerge_area(pos, pos)
|
|
||||||
end
|
|
||||||
|
|
||||||
local t = minetest.get_us_time()
|
|
||||||
|
|
||||||
node = minetest.get_node(pos)
|
|
||||||
|
|
||||||
while (not node or node.name == "ignore") and (minetest.get_us_time() - t < us_timeout) do
|
|
||||||
node = minetest.get_node(pos)
|
|
||||||
end
|
|
||||||
|
|
||||||
return node
|
|
||||||
-- it still can return "ignore", LOL, even if force = true, but only after time out
|
|
||||||
end
|
|
||||||
|
|
|
@ -272,7 +272,7 @@ local function hut_placement_callback(p1, p2, size, orientation, pr)
|
||||||
if not p1 or not p2 then return end
|
if not p1 or not p2 then return end
|
||||||
local legs = minetest.find_nodes_in_area(p1, p2, "mcl_core:tree")
|
local legs = minetest.find_nodes_in_area(p1, p2, "mcl_core:tree")
|
||||||
for i = 1, #legs do
|
for i = 1, #legs do
|
||||||
while minetest.get_item_group(mcl_mapgen_core.get_node({x=legs[i].x, y=legs[i].y-1, z=legs[i].z}, true, 333333).name, "water") ~= 0 do
|
while minetest.get_item_group(mcl_vars.get_node({x=legs[i].x, y=legs[i].y-1, z=legs[i].z}, true, 333333).name, "water") ~= 0 do
|
||||||
legs[i].y = legs[i].y - 1
|
legs[i].y = legs[i].y - 1
|
||||||
minetest.swap_node(legs[i], {name = "mcl_core:tree", param2 = 2})
|
minetest.swap_node(legs[i], {name = "mcl_core:tree", param2 = 2})
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
function settlements.build_schematic(vm, data, va, pos, building, replace_wall, name)
|
function settlements.build_schematic(vm, data, va, pos, building, replace_wall, name)
|
||||||
-- get building node material for better integration to surrounding
|
-- get building node material for better integration to surrounding
|
||||||
local platform_material = mcl_mapgen_core.get_node(pos)
|
local platform_material = mcl_vars.get_node(pos)
|
||||||
if not platform_material or (platform_material.name == "air" or platform_material.name == "ignore") then
|
if not platform_material or (platform_material.name == "air" or platform_material.name == "ignore") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
|
@ -52,7 +52,7 @@ function settlements.terraform(settlement_info, pr)
|
||||||
else
|
else
|
||||||
-- write ground
|
-- write ground
|
||||||
-- local p = {x=pos.x+xi, y=pos.y+yi, z=pos.z+zi}
|
-- local p = {x=pos.x+xi, y=pos.y+yi, z=pos.z+zi}
|
||||||
-- local node = mcl_mapgen_core.get_node(p)
|
-- local node = mcl_vars.get_node(p)
|
||||||
-- if node and node.name ~= "air" then
|
-- if node and node.name ~= "air" then
|
||||||
-- minetest.swap_node(p,{name="air"})
|
-- minetest.swap_node(p,{name="air"})
|
||||||
-- end
|
-- end
|
||||||
|
|
|
@ -1,28 +1,5 @@
|
||||||
local c_dirt_with_grass = minetest.get_content_id("mcl_core:dirt_with_grass")
|
local get_node = mcl_vars.get_node
|
||||||
local c_dirt_with_snow = minetest.get_content_id("mcl_core:dirt_with_grass_snow")
|
|
||||||
--local c_dirt_with_dry_grass = minetest.get_content_id("mcl_core:dirt_with_dry_grass")
|
|
||||||
local c_podzol = minetest.get_content_id("mcl_core:podzol")
|
|
||||||
local c_sand = minetest.get_content_id("mcl_core:sand")
|
|
||||||
local c_desert_sand = minetest.get_content_id("mcl_core:redsand")
|
|
||||||
--local c_silver_sand = minetest.get_content_id("mcl_core:silver_sand")
|
|
||||||
--
|
|
||||||
local c_air = minetest.get_content_id("air")
|
|
||||||
local c_snow = minetest.get_content_id("mcl_core:snow")
|
|
||||||
local c_fern_1 = minetest.get_content_id("mcl_flowers:fern")
|
|
||||||
local c_fern_2 = minetest.get_content_id("mcl_flowers:fern")
|
|
||||||
local c_fern_3 = minetest.get_content_id("mcl_flowers:fern")
|
|
||||||
local c_rose = minetest.get_content_id("mcl_flowers:poppy")
|
|
||||||
local c_viola = minetest.get_content_id("mcl_flowers:blue_orchid")
|
|
||||||
local c_geranium = minetest.get_content_id("mcl_flowers:allium")
|
|
||||||
local c_tulip = minetest.get_content_id("mcl_flowers:tulip_orange")
|
|
||||||
local c_dandelion_y = minetest.get_content_id("mcl_flowers:dandelion")
|
|
||||||
local c_dandelion_w = minetest.get_content_id("mcl_flowers:oxeye_daisy")
|
|
||||||
local c_bush_leaves = minetest.get_content_id("mcl_core:leaves")
|
|
||||||
local c_bush_stem = minetest.get_content_id("mcl_core:tree")
|
|
||||||
local c_a_bush_leaves = minetest.get_content_id("mcl_core:acacialeaves")
|
|
||||||
local c_a_bush_stem = minetest.get_content_id("mcl_core:acaciatree")
|
|
||||||
local c_water_source = minetest.get_content_id("mcl_core:water_source")
|
|
||||||
local c_water_flowing = minetest.get_content_id("mcl_core:water_flowing")
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- function to copy tables
|
-- function to copy tables
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
@ -53,9 +30,9 @@ function settlements.find_surface(pos, wait)
|
||||||
-- check, in which direction to look for surface
|
-- check, in which direction to look for surface
|
||||||
local surface_node
|
local surface_node
|
||||||
if wait then
|
if wait then
|
||||||
surface_node = mcl_mapgen_core.get_node(p6, true, 10000000)
|
surface_node = get_node(p6, true, 10000000)
|
||||||
else
|
else
|
||||||
surface_node = mcl_mapgen_core.get_node(p6)
|
surface_node = get_node(p6)
|
||||||
end
|
end
|
||||||
if surface_node.name=="air" or surface_node.name=="ignore" then
|
if surface_node.name=="air" or surface_node.name=="ignore" then
|
||||||
itter = -1
|
itter = -1
|
||||||
|
@ -65,7 +42,7 @@ function settlements.find_surface(pos, wait)
|
||||||
-- Check Surface_node and Node above
|
-- Check Surface_node and Node above
|
||||||
--
|
--
|
||||||
if settlements.surface_mat[surface_node.name] then
|
if settlements.surface_mat[surface_node.name] then
|
||||||
local surface_node_plus_1 = mcl_mapgen_core.get_node({ x=p6.x, y=p6.y+1, z=p6.z})
|
local surface_node_plus_1 = get_node({ x=p6.x, y=p6.y+1, z=p6.z})
|
||||||
if surface_node_plus_1 and surface_node and
|
if surface_node_plus_1 and surface_node and
|
||||||
(string.find(surface_node_plus_1.name,"air") or
|
(string.find(surface_node_plus_1.name,"air") or
|
||||||
string.find(surface_node_plus_1.name,"snow") or
|
string.find(surface_node_plus_1.name,"snow") or
|
||||||
|
@ -90,7 +67,7 @@ function settlements.find_surface(pos, wait)
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
cnt = cnt+1
|
cnt = cnt+1
|
||||||
surface_node = mcl_mapgen_core.get_node(p6)
|
surface_node = get_node(p6)
|
||||||
end
|
end
|
||||||
settlements.debug("find_surface5: cnt_max overflow")
|
settlements.debug("find_surface5: cnt_max overflow")
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
# mcl_wip
|
||||||
|
Used to mark items or nodes as WIP.
|
||||||
|
|
||||||
|
## mcl_wip.register_wip_item(itemname)
|
||||||
|
Register <itemname> as a WIP item.
|
||||||
|
If <itemname> isn't a valid itemname, an error will be shown after mods loaded.
|
||||||
|
|
||||||
|
## mcl_wip.register_experimental_item(itemname)
|
||||||
|
Register <itemname> as a experimental item.
|
||||||
|
If <itemname> isn't a valid itemname, an error will be shown after mods loaded.
|
||||||
|
|
||||||
|
## mcl_wip.registered_wip_items
|
||||||
|
Table containing WIP items names.
|
||||||
|
|
||||||
|
## mcl_wip.registered_experimental_items
|
||||||
|
Table containing experimental items names.
|
|
@ -0,0 +1,14 @@
|
||||||
|
# mcl_death_drop
|
||||||
|
Drop registered inventories on player death.
|
||||||
|
|
||||||
|
## mcl_death_drop.register_dropped_list(inv, listname, drop)
|
||||||
|
* inv: can be:
|
||||||
|
* "PLAYER": will be interpreted like player inventory (to avoid multiple calling to get_inventory())
|
||||||
|
* function(player): must return inventory
|
||||||
|
* listname: string
|
||||||
|
* drop: bool
|
||||||
|
* true: the entire list will be dropped
|
||||||
|
* false: items with curse_of_vanishing enchantement will be broken.
|
||||||
|
|
||||||
|
## mcl_death_drop.registered_dropped_lists
|
||||||
|
Table containing dropped list inventory, name and drop state.
|
|
@ -1,26 +1,40 @@
|
||||||
|
local random = math.random
|
||||||
|
|
||||||
|
mcl_death_drop = {}
|
||||||
|
|
||||||
|
mcl_death_drop.registered_dropped_lists = {}
|
||||||
|
|
||||||
|
function mcl_death_drop.register_dropped_list(inv, listname, drop)
|
||||||
|
table.insert(mcl_death_drop.registered_dropped_lists, {inv=inv, listname=listname, drop=drop})
|
||||||
|
end
|
||||||
|
|
||||||
|
mcl_death_drop.register_dropped_list("PLAYER", "main", true)
|
||||||
|
mcl_death_drop.register_dropped_list("PLAYER", "craft", true)
|
||||||
|
mcl_death_drop.register_dropped_list("PLAYER", "armor", true)
|
||||||
|
mcl_death_drop.register_dropped_list(function(player) return select(3, armor:get_valid_player(player)) end , "armor", false)
|
||||||
|
|
||||||
minetest.register_on_dieplayer(function(player)
|
minetest.register_on_dieplayer(function(player)
|
||||||
local keep = minetest.settings:get_bool("mcl_keepInventory", false)
|
local keep = minetest.settings:get_bool("mcl_keepInventory", false)
|
||||||
if keep == false then
|
if keep == false then
|
||||||
-- Drop inventory, crafting grid and armor
|
-- Drop inventory, crafting grid and armor
|
||||||
local inv = player:get_inventory()
|
local playerinv = player:get_inventory()
|
||||||
local pos = player:get_pos()
|
local pos = player:get_pos()
|
||||||
local name, player_armor_inv, armor_armor_inv, pos = armor:get_valid_player(player, "[on_dieplayer]")
|
|
||||||
-- No item drop if in deep void
|
-- No item drop if in deep void
|
||||||
local void, void_deadly = mcl_worlds.is_in_void(pos)
|
local void, void_deadly = mcl_worlds.is_in_void(pos)
|
||||||
local lists = {
|
|
||||||
{ inv = inv, listname = "main", drop = true },
|
for l=1,#mcl_death_drop.registered_dropped_lists do
|
||||||
{ inv = inv, listname = "craft", drop = true },
|
local inv = mcl_death_drop.registered_dropped_lists[l].inv
|
||||||
{ inv = player_armor_inv, listname = "armor", drop = true },
|
if inv == "PLAYER" then
|
||||||
{ inv = armor_armor_inv, listname = "armor", drop = false },
|
inv = playerinv
|
||||||
}
|
elseif type(inv) == "function" then
|
||||||
for l=1,#lists do
|
inv = inv(player)
|
||||||
local inv = lists[l].inv
|
end
|
||||||
local listname = lists[l].listname
|
local listname = mcl_death_drop.registered_dropped_lists[l].listname
|
||||||
local drop = lists[l].drop
|
local drop = mcl_death_drop.registered_dropped_lists[l].drop
|
||||||
if inv ~= nil then
|
if inv ~= nil then
|
||||||
for i, stack in ipairs(inv:get_list(listname)) do
|
for i, stack in ipairs(inv:get_list(listname)) do
|
||||||
local x = math.random(0, 9)/3
|
local x = random(0, 9)/3
|
||||||
local z = math.random(0, 9)/3
|
local z = random(0, 9)/3
|
||||||
pos.x = pos.x + x
|
pos.x = pos.x + x
|
||||||
pos.z = pos.z + z
|
pos.z = pos.z + z
|
||||||
if not void_deadly and drop and not mcl_enchanting.has_enchantment(stack, "curse_of_vanishing") then
|
if not void_deadly and drop and not mcl_enchanting.has_enchantment(stack, "curse_of_vanishing") then
|
||||||
|
|
|
@ -81,13 +81,7 @@ local dir_step = storage:get_int("mcl_spawn_dir_step") or 0
|
||||||
local dir_ind = storage:get_int("mcl_spawn_dir_ind") or 1
|
local dir_ind = storage:get_int("mcl_spawn_dir_ind") or 1
|
||||||
local emerge_pos1, emerge_pos2
|
local emerge_pos1, emerge_pos2
|
||||||
|
|
||||||
-- Get world 'mapgen_limit' and 'chunksize' to calculate 'spawn_limit'.
|
local spawn_limit = mcl_vars.mapgen_edge_max
|
||||||
-- This accounts for how mapchunks are not generated if they or their shell exceed
|
|
||||||
-- 'mapgen_limit'.
|
|
||||||
|
|
||||||
local mapgen_limit = tonumber(minetest.get_mapgen_setting("mapgen_limit"))
|
|
||||||
local chunksize = tonumber(minetest.get_mapgen_setting("chunksize"))
|
|
||||||
local spawn_limit = math.max(mapgen_limit - (chunksize + 1) * 16, 0)
|
|
||||||
|
|
||||||
|
|
||||||
--Functions
|
--Functions
|
||||||
|
@ -503,10 +497,17 @@ function mcl_spawn.shadow_worker()
|
||||||
mcl_spawn.search()
|
mcl_spawn.search()
|
||||||
minetest.log("action", "[mcl_spawn] Started world spawn point search")
|
minetest.log("action", "[mcl_spawn] Started world spawn point search")
|
||||||
end
|
end
|
||||||
if success and ((not good_for_respawn(wsp)) or (not can_find_tree(wsp))) then
|
|
||||||
success = false
|
if success then
|
||||||
minetest.log("action", "[mcl_spawn] World spawn position isn't safe anymore: "..minetest.pos_to_string(wsp))
|
local wsp_node = minetest.get_node(wsp)
|
||||||
mcl_spawn.search()
|
if wsp_node and wsp_node.name == "ignore" then
|
||||||
|
-- special case - respawn area unloaded from memory - it's okay, skip for now
|
||||||
|
|
||||||
|
elseif ((not good_for_respawn(wsp)) or ((no_trees_area_counter >= 0) and not can_find_tree(wsp))) then
|
||||||
|
success = false
|
||||||
|
minetest.log("action", "[mcl_spawn] World spawn position isn't safe anymore: "..minetest.pos_to_string(wsp))
|
||||||
|
mcl_spawn.search()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.after(respawn_search_interval, mcl_spawn.shadow_worker)
|
minetest.after(respawn_search_interval, mcl_spawn.shadow_worker)
|
||||||
|
|
Loading…
Reference in New Issue