From 9bb5e748b9443e03b76262c693d1d38fa6500d16 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sat, 27 Mar 2021 15:20:01 +0100 Subject: [PATCH 01/18] Add documentation to mcl_crafting_table API --- mods/ITEMS/mcl_crafting_table/API.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 mods/ITEMS/mcl_crafting_table/API.md diff --git a/mods/ITEMS/mcl_crafting_table/API.md b/mods/ITEMS/mcl_crafting_table/API.md new file mode 100644 index 000000000..45aa0c9ce --- /dev/null +++ b/mods/ITEMS/mcl_crafting_table/API.md @@ -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. \ No newline at end of file From cb294a5cadc77fe4da3495389a05aa5fed7023af Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sat, 27 Mar 2021 15:27:34 +0100 Subject: [PATCH 02/18] Add documentation to mcl_wip (pretty useless...) --- mods/MISC/mcl_wip/API.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 mods/MISC/mcl_wip/API.md diff --git a/mods/MISC/mcl_wip/API.md b/mods/MISC/mcl_wip/API.md new file mode 100644 index 000000000..e3439af77 --- /dev/null +++ b/mods/MISC/mcl_wip/API.md @@ -0,0 +1,16 @@ +# mcl_wip +Used to mark items or nodes as WIP. + +## mcl_wip.register_wip_item(itemname) +Register as a WIP item. +If isn't a valid itemname, an error will be shown after mods loaded. + +## mcl_wip.register_experimental_item(itemname) +Register as a experimental item. +If 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. \ No newline at end of file From 30e50a64ef6ffcad961321ea1dc3cb07e51f640f Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sat, 27 Mar 2021 20:12:48 +0100 Subject: [PATCH 03/18] basic API (WIP) --- mods/PLAYER/mcl_death_drop/API.md | 12 ++++++++++ mods/PLAYER/mcl_death_drop/init.lua | 34 +++++++++++++++++++---------- 2 files changed, 34 insertions(+), 12 deletions(-) create mode 100644 mods/PLAYER/mcl_death_drop/API.md diff --git a/mods/PLAYER/mcl_death_drop/API.md b/mods/PLAYER/mcl_death_drop/API.md new file mode 100644 index 000000000..6f1d1cde7 --- /dev/null +++ b/mods/PLAYER/mcl_death_drop/API.md @@ -0,0 +1,12 @@ +# mcl_death_drop +Drop registered inventories on player death. + +## mcl_death_drop.register_dropped_list(inv, listname, drop) +* inv: string of function returning a string +* listname: string +* drop: bool +-- if true the entire list will be dropped +-- if false, items with curse_of_vanishing enchantement will be broken. + +## mcl_death_drop.registered_dropped_lists +Table containing dropped list definition. \ No newline at end of file diff --git a/mods/PLAYER/mcl_death_drop/init.lua b/mods/PLAYER/mcl_death_drop/init.lua index 56e6ea522..6c51618a1 100644 --- a/mods/PLAYER/mcl_death_drop/init.lua +++ b/mods/PLAYER/mcl_death_drop/init.lua @@ -1,3 +1,18 @@ +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_player_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 minetest.get_inventory({type="detached", name=player:get_player_name().."_armor"}) end , "armor", false) + minetest.register_on_dieplayer(function(player) local keep = minetest.settings:get_bool("mcl_keepInventory", false) if keep == false then @@ -7,20 +22,15 @@ minetest.register_on_dieplayer(function(player) local name, player_armor_inv, armor_armor_inv, pos = armor:get_valid_player(player, "[on_dieplayer]") -- No item drop if in deep void local void, void_deadly = mcl_worlds.is_in_void(pos) - local lists = { - { inv = inv, listname = "main", drop = true }, - { inv = inv, listname = "craft", drop = true }, - { inv = player_armor_inv, listname = "armor", drop = true }, - { inv = armor_armor_inv, listname = "armor", drop = false }, - } - for l=1,#lists do - local inv = lists[l].inv - local listname = lists[l].listname - local drop = lists[l].drop + + for l=1,#mcl_death_drop.registered_dropped_lists do + local inv = mcl_death_drop.registered_dropped_lists[l].inv + local listname = mcl_death_drop.registered_dropped_lists[l].listname + local drop = mcl_death_drop.registered_dropped_lists[l].drop if inv ~= nil then for i, stack in ipairs(inv:get_list(listname)) do - local x = math.random(0, 9)/3 - local z = math.random(0, 9)/3 + local x = random(0, 9)/3 + local z = random(0, 9)/3 pos.x = pos.x + x pos.z = pos.z + z if not void_deadly and drop and not mcl_enchanting.has_enchantment(stack, "curse_of_vanishing") then From 6a6b5970b351ca96ea12baf026055940b8880570 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sat, 27 Mar 2021 20:23:51 +0100 Subject: [PATCH 04/18] fix API --- mods/PLAYER/mcl_death_drop/init.lua | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/mods/PLAYER/mcl_death_drop/init.lua b/mods/PLAYER/mcl_death_drop/init.lua index 6c51618a1..693b21cd8 100644 --- a/mods/PLAYER/mcl_death_drop/init.lua +++ b/mods/PLAYER/mcl_death_drop/init.lua @@ -5,7 +5,7 @@ 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_player_lists, {inv=inv, listname=listname, drop=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) @@ -17,7 +17,7 @@ minetest.register_on_dieplayer(function(player) local keep = minetest.settings:get_bool("mcl_keepInventory", false) if keep == false then -- Drop inventory, crafting grid and armor - local inv = player:get_inventory() + local playerinv = player:get_inventory() 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 @@ -25,6 +25,11 @@ minetest.register_on_dieplayer(function(player) for l=1,#mcl_death_drop.registered_dropped_lists do local inv = mcl_death_drop.registered_dropped_lists[l].inv + if inv == "PLAYER" then + inv = playerinv + elseif type(inv) == "function" then + inv = inv(player) + end local listname = mcl_death_drop.registered_dropped_lists[l].listname local drop = mcl_death_drop.registered_dropped_lists[l].drop if inv ~= nil then From 3ba7a402513faf9585e2a0018003608abd6759f6 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sat, 27 Mar 2021 23:07:46 +0100 Subject: [PATCH 05/18] Add API documentation --- mods/ITEMS/mcl_buckets/API.md | 20 ++++++++++---------- mods/PLAYER/mcl_death_drop/API.md | 10 ++++++---- mods/PLAYER/mcl_death_drop/init.lua | 3 +-- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/mods/ITEMS/mcl_buckets/API.md b/mods/ITEMS/mcl_buckets/API.md index 69ee4b21d..53f7d3698 100644 --- a/mods/ITEMS/mcl_buckets/API.md +++ b/mods/ITEMS/mcl_buckets/API.md @@ -5,17 +5,17 @@ Add an API to register buckets to mcl Register a new liquid Accept folowing params: -* source_place = a string or function. +* source_place: a string or function. * string: name of the node to place * 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 -* 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) -* name = user-visible bucket description -* longdesc = long explanatory description (for help) -* usagehelp = short usage explanation (for 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. -* groups = optional list of item groups +* source_take: table of liquid source node names to take +* 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) +* name: user-visible bucket description +* longdesc: long explanatory description (for help) +* usagehelp: short usage explanation (for 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. +* groups: optional list of item groups This function can be called from any mod (which depends on this one) \ No newline at end of file diff --git a/mods/PLAYER/mcl_death_drop/API.md b/mods/PLAYER/mcl_death_drop/API.md index 6f1d1cde7..70fbd1499 100644 --- a/mods/PLAYER/mcl_death_drop/API.md +++ b/mods/PLAYER/mcl_death_drop/API.md @@ -2,11 +2,13 @@ Drop registered inventories on player death. ## mcl_death_drop.register_dropped_list(inv, listname, drop) -* inv: string of function returning a string +* inv: can be: + * "PLAYER": player inventory (to avoid multiple calling to get_inventory()) + * function: must return inventory * listname: string * drop: bool --- if true the entire list will be dropped --- if false, items with curse_of_vanishing enchantement will be broken. + * 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 definition. \ No newline at end of file +Table containing dropped list inventory, name and drop state. \ No newline at end of file diff --git a/mods/PLAYER/mcl_death_drop/init.lua b/mods/PLAYER/mcl_death_drop/init.lua index 693b21cd8..7c54334a9 100644 --- a/mods/PLAYER/mcl_death_drop/init.lua +++ b/mods/PLAYER/mcl_death_drop/init.lua @@ -11,7 +11,7 @@ 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 minetest.get_inventory({type="detached", name=player:get_player_name().."_armor"}) end , "armor", false) +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) local keep = minetest.settings:get_bool("mcl_keepInventory", false) @@ -19,7 +19,6 @@ minetest.register_on_dieplayer(function(player) -- Drop inventory, crafting grid and armor local playerinv = player:get_inventory() 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 local void, void_deadly = mcl_worlds.is_in_void(pos) From 57ce5143b9ee0fe0fe8b422521a9deb38ed36928 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sat, 27 Mar 2021 23:39:22 +0100 Subject: [PATCH 06/18] Clarify API documentation --- mods/PLAYER/mcl_death_drop/API.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/PLAYER/mcl_death_drop/API.md b/mods/PLAYER/mcl_death_drop/API.md index 70fbd1499..b19e2fd7c 100644 --- a/mods/PLAYER/mcl_death_drop/API.md +++ b/mods/PLAYER/mcl_death_drop/API.md @@ -3,8 +3,8 @@ Drop registered inventories on player death. ## mcl_death_drop.register_dropped_list(inv, listname, drop) * inv: can be: - * "PLAYER": player inventory (to avoid multiple calling to get_inventory()) - * function: must return inventory + * "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 From 54e7529754e0c5b1f6b597e7771273e716e3c48a Mon Sep 17 00:00:00 2001 From: kay27 Date: Sun, 28 Mar 2021 04:32:57 +0400 Subject: [PATCH 07/18] [mcl_achievements] Add mcl:stoneAge, mcl:hotStuff, mcl:obsidian --- mods/HUD/mcl_achievements/init.lua | 17 +++++++++++++++++ mods/ITEMS/mcl_buckets/init.lua | 3 +++ mods/ITEMS/mcl_core/nodes_base.lua | 10 ++++++++++ 3 files changed, 30 insertions(+) diff --git a/mods/HUD/mcl_achievements/init.lua b/mods/HUD/mcl_achievements/init.lua index 7473568d2..2f1db1fe6 100644 --- a/mods/HUD/mcl_achievements/init.lua +++ b/mods/HUD/mcl_achievements/init.lua @@ -238,3 +238,20 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) awards.show_to(name, name, nil, false) 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", +}) diff --git a/mods/ITEMS/mcl_buckets/init.lua b/mods/ITEMS/mcl_buckets/init.lua index 30e4075c8..0ba68b723 100644 --- a/mods/ITEMS/mcl_buckets/init.lua +++ b/mods/ITEMS/mcl_buckets/init.lua @@ -207,6 +207,9 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", { -- Fill bucket, but not in Creative Mode if not minetest.is_creative_enabled(user:get_player_name()) then 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 minetest.add_node(pointed_thing.under, {name="air"}) diff --git a/mods/ITEMS/mcl_core/nodes_base.lua b/mods/ITEMS/mcl_core/nodes_base.lua index f4fe12155..4477f0377 100644 --- a/mods/ITEMS/mcl_core/nodes_base.lua +++ b/mods/ITEMS/mcl_core/nodes_base.lua @@ -33,6 +33,11 @@ minetest.register_node("mcl_core:stone", { _mcl_blast_resistance = 6, _mcl_hardness = 1.5, _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", { @@ -814,6 +819,11 @@ minetest.register_node("mcl_core:obsidian", { groups = {pickaxey=5, building_block=1, material_stone=1}, _mcl_blast_resistance = 1200, _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", { From c7389dc0a439364a214ff268005343428df4f533 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sun, 28 Mar 2021 08:13:24 +0200 Subject: [PATCH 08/18] add basic API to mcl_item_entity --- mods/ENTITIES/mcl_item_entity/init.lua | 39 ++++++++++++++++++++------ 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index d1d337a9c..95b90e546 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -1,3 +1,7 @@ +local has_awards = minetest.get_modpath("awards") + +mcl_item_entity = {} + --basic settings 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 @@ -16,16 +20,33 @@ local get_gravity = function() return tonumber(minetest.settings:get("movement_gravity")) or 9.81 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 itemname = ItemStack(object:get_luaentity().itemstring):get_name() - if minetest.get_item_group(itemname, "tree") ~= 0 then - awards.unlock(player:get_player_name(), "mcl:mineWood") - elseif itemname == "mcl_mobitems:blaze_rod" then - awards.unlock(player:get_player_name(), "mcl:blazeRod") - elseif itemname == "mcl_mobitems:leather" then - awards.unlock(player:get_player_name(), "mcl:killCow") - elseif itemname == "mcl_core:diamond" then - awards.unlock(player:get_player_name(), "mcl:diamonds") + if has_awards then + local itemname = ItemStack(object:get_luaentity().itemstring):get_name() + local playername = player:get_player_name() + for name,award in pairs(registered_pickup_achievement) do + if itemname == name or minetest.get_item_group(itemname, name) ~= 0 then + awards.unlock(playername, award) + end + end end end From 628ca226a611b470bb0fb4f684d48f469968c9f4 Mon Sep 17 00:00:00 2001 From: kay27 Date: Sun, 28 Mar 2021 20:36:35 +0400 Subject: [PATCH 09/18] [mcl_portals] Additionally index source Nether portals from 0.71 and earlier before teleporting, to make possible returning through them --- mods/ITEMS/mcl_portals/portal_nether.lua | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index 29368af30..1fe9e26b7 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -381,6 +381,12 @@ local function finalize_teleport(obj, exit) 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 + -- 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 teleport_cooloff(obj) @@ -436,7 +442,8 @@ local function ecb_scan_area_2(blockpos, action, calls_remaining, param) local pos0, distance 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}) if portals and #portals>0 then for _, p in pairs(portals) do From cb2aae5a55549e6644b3ad76f467917c600d33cf Mon Sep 17 00:00:00 2001 From: kay27 Date: Sun, 28 Mar 2021 22:56:51 +0400 Subject: [PATCH 10/18] [mcl_mapgen_core] Redesign, mostly to remove water from End and restore static lvm_buffer to speed it up --- mods/CORE/mcl_init/init.lua | 83 ++++++++++++++++ mods/ITEMS/mcl_portals/portal_nether.lua | 17 +--- mods/MAPGEN/mcl_dungeons/init.lua | 26 ++--- mods/MAPGEN/mcl_mapgen_core/init.lua | 118 ++++------------------- mods/MAPGEN/mcl_structures/init.lua | 2 +- mods/MAPGEN/mcl_villages/buildings.lua | 2 +- mods/MAPGEN/mcl_villages/foundation.lua | 2 +- mods/MAPGEN/mcl_villages/utils.lua | 35 ++----- 8 files changed, 127 insertions(+), 158 deletions(-) diff --git a/mods/CORE/mcl_init/init.lua b/mods/CORE/mcl_init/init.lua index ca510b74f..014a30d1e 100644 --- a/mods/CORE/mcl_init/init.lua +++ b/mods/CORE/mcl_init/init.lua @@ -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) 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 diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index 1fe9e26b7..7d28c921a 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -66,12 +66,7 @@ minetest.register_on_shutdown(function() storage:set_string("nether_exits_keys", minetest.serialize(keys)) end) -mcl_portals.get_node = function(pos) - 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 get_node = mcl_vars.get_node local set_node = minetest.set_node local registered_nodes = minetest.registered_nodes 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. -- If the verification passes - position adds to the table and saves to mod storage on exit. 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 local x, y, z = floor(p.x), floor(p.y), floor(p.z) local p = {x = x, y = y, z = z} @@ -202,7 +196,6 @@ local function destroy_nether_portal(pos, node) local nn, orientation = node.name, node.param2 local obsidian = nn == OBSIDIAN - local get_node = mcl_portals.get_node local check_remove = function(pos, orientation) local node = get_node(pos) if node and (node.name == PORTAL and (orientation == nil or (node.param2 == orientation))) then @@ -315,8 +308,6 @@ function build_nether_portal(pos, width, height, orientation, name) light_frame(pos.x, pos.y, pos.z, pos.x + (1 - orientation) * (width - 1), pos.y + height - 1, pos.z + orientation * (width - 1)) - local get_node = mcl_portals.get_node - -- Build obsidian platform: for x = pos.x - orientation, pos.x + orientation + (width - 1) * (1 - orientation), 1 + orientation do for z = pos.z - 1 + orientation, pos.z + 1 - orientation + (width - 1) * orientation, 2 - orientation do @@ -379,7 +370,7 @@ 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 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: @@ -529,7 +520,7 @@ local function create_portal(pos, limit1, limit2, name, obj) end 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 if nn ~= "air" and minetest.get_item_group(nn, "fire") ~= 1 then return false, obsidian @@ -636,7 +627,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 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) if not target then return end diff --git a/mods/MAPGEN/mcl_dungeons/init.lua b/mods/MAPGEN/mcl_dungeons/init.lua index 05d82c3e9..5c15d6309 100644 --- a/mods/MAPGEN/mcl_dungeons/init.lua +++ b/mods/MAPGEN/mcl_dungeons/init.lua @@ -12,6 +12,8 @@ end 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 get_node = mcl_vars.get_node + -- Calculate the number of dungeon spawn attempts -- 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. @@ -49,8 +51,8 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) local y_floor = y 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 not minetest.registered_nodes[mcl_mapgen_core.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 + if not minetest.registered_nodes[get_node({x = tx, y = y_floor , z = tz}).name].walkable + or not minetest.registered_nodes[get_node({x = tx, y = y_ceiling, z = tz}).name].walkable then return false end end end end -- 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 - 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 if not openings[x] then openings[x]={} end openings[x][z] = true table.insert(corners, {x=x, z=z}) 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 if not openings[x2] then openings[x2]={} end openings[x2][z] = true table.insert(corners, {x=x2, z=z}) 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 if not openings[x] then openings[x]={} end openings[x][z2] = true table.insert(corners, {x=x, z=z2}) 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 if not openings[x2] then openings[x2]={} end openings[x2][z2] = true @@ -89,13 +91,13 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) end 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 if check and openings_counter > 5 then return end if not openings[wx] then openings[wx]={} end openings[wx][z] = true 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 if check and openings_counter > 5 then return 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 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 if check and openings_counter > 5 then return end if not openings[x] then openings[x]={} end openings[x][wz] = true 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 if check and openings_counter > 5 then return 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 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 table.insert(spawner_posses, sp) 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) -- 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 -- Floor if ty == y then diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index 496b2e222..63256ec7a 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -1,45 +1,8 @@ mcl_mapgen_core = {} -mcl_mapgen_core.registered_generators = {} +local registered_generators = {} local lvm, nodes, param2 = 0, 0, 0 - -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 +local lvm_buffer = {} -- -- Aliases for map generator outputs @@ -1850,24 +1813,22 @@ end 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)) - add_chunk(minp) 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 local lvm_used, shadow = false, false - local lb = {} -- buffer local lb2 = {} -- param2 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 data2 - local data = vm:get_data(lb) + local data = vm:get_data(lvm_buffer) if param2 > 0 then data2 = vm:get_param2_data(lb2) end 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 - 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 lvm_used = true end @@ -1890,18 +1851,18 @@ minetest.register_on_generated(function(minp, maxp, blockseed) end 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 rec.nf(p1, p2, blockseed) end end end --- add_chunk(minp) + mcl_vars.add_chunk(minp) end) 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 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, } - mcl_mapgen_core.registered_generators[id] = new_record + registered_generators[id] = new_record table.sort( - mcl_mapgen_core.registered_generators, + registered_generators, function(a, b) return (a.i < b.i) or ((a.i == b.i) and (a.vf ~= nil) and (b.vf == nil)) end) end function mcl_mapgen_core.unregister_generator(id) - if not mcl_mapgen_core.registered_generators[id] then return end - local rec = mcl_mapgen_core.registered_generators[id] - mcl_mapgen_core.registered_generators[id] = nil + if not registered_generators[id] then return end + local rec = registered_generators[id] + registered_generators[id] = nil if rec.vf then lvm = lvm - 1 end if rev.nf then nodes = nodes - 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: -- * Replace water with Nether lava. -- * 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 - 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 local p_pos = area:index(nodes[n].x, nodes[n].y, nodes[n].z) if data[p_pos] == c_water then @@ -2151,7 +2112,7 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed) end end else - minetest.emerge_area(minp, maxp, function(blockpos, action, calls_remaining, param) + minetest.emerge_area(emin, emax, function(blockpos, action, calls_remaining, param) if calls_remaining > 0 then return end -- local nodes = minetest.find_nodes_in_area(param.minp, param.maxp, {"mcl_core:water_source"}) local nodes = minetest.find_nodes_in_area(param.minp, param.maxp, {"group:water"}) @@ -2160,7 +2121,7 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed) for _, n in pairs(nodes) do sn(n, l) end - end, {minp=vector.new(minp), maxp=vector.new(maxp)}) + end, {minp=vector.new(emin), maxp=vector.new(emax)}) end -- End block fixes: @@ -2231,48 +2192,3 @@ end 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 diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index 0d6bc62ab..f6317bdeb 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -272,7 +272,7 @@ local function hut_placement_callback(p1, p2, size, orientation, pr) if not p1 or not p2 then return end local legs = minetest.find_nodes_in_area(p1, p2, "mcl_core:tree") for i = 1, #legs do - while minetest.get_item_group(mcl_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 minetest.swap_node(legs[i], {name = "mcl_core:tree", param2 = 2}) end diff --git a/mods/MAPGEN/mcl_villages/buildings.lua b/mods/MAPGEN/mcl_villages/buildings.lua index 18d6c1e0b..e43db6d98 100644 --- a/mods/MAPGEN/mcl_villages/buildings.lua +++ b/mods/MAPGEN/mcl_villages/buildings.lua @@ -4,7 +4,7 @@ ------------------------------------------------------------------------------- function settlements.build_schematic(vm, data, va, pos, building, replace_wall, name) -- 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 return end diff --git a/mods/MAPGEN/mcl_villages/foundation.lua b/mods/MAPGEN/mcl_villages/foundation.lua index 67a2385f7..038a2f202 100644 --- a/mods/MAPGEN/mcl_villages/foundation.lua +++ b/mods/MAPGEN/mcl_villages/foundation.lua @@ -52,7 +52,7 @@ function settlements.terraform(settlement_info, pr) else -- write ground -- 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 -- minetest.swap_node(p,{name="air"}) -- end diff --git a/mods/MAPGEN/mcl_villages/utils.lua b/mods/MAPGEN/mcl_villages/utils.lua index 2d96ba26f..d7617541d 100644 --- a/mods/MAPGEN/mcl_villages/utils.lua +++ b/mods/MAPGEN/mcl_villages/utils.lua @@ -1,28 +1,5 @@ -local c_dirt_with_grass = minetest.get_content_id("mcl_core:dirt_with_grass") -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") +local get_node = mcl_vars.get_node + ------------------------------------------------------------------------------- -- function to copy tables ------------------------------------------------------------------------------- @@ -53,9 +30,9 @@ function settlements.find_surface(pos, wait) -- check, in which direction to look for surface local surface_node if wait then - surface_node = mcl_mapgen_core.get_node(p6, true, 10000000) + surface_node = get_node(p6, true, 10000000) else - surface_node = mcl_mapgen_core.get_node(p6) + surface_node = get_node(p6) end if surface_node.name=="air" or surface_node.name=="ignore" then itter = -1 @@ -65,7 +42,7 @@ function settlements.find_surface(pos, wait) -- Check Surface_node and Node above -- 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 (string.find(surface_node_plus_1.name,"air") or string.find(surface_node_plus_1.name,"snow") or @@ -90,7 +67,7 @@ function settlements.find_surface(pos, wait) return nil end cnt = cnt+1 - surface_node = mcl_mapgen_core.get_node(p6) + surface_node = get_node(p6) end settlements.debug("find_surface5: cnt_max overflow") return nil From 05260d03d595d31e0061854987ea1bc95a63821e Mon Sep 17 00:00:00 2001 From: kay27 Date: Mon, 29 Mar 2021 01:33:01 +0400 Subject: [PATCH 11/18] [mcl_portals] Fix crash on access empty index trying to find portal after its destruction --- mods/ITEMS/mcl_portals/portal_nether.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index 7d28c921a..5bb226408 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -103,7 +103,7 @@ local function add_exit(p) local e = exits[k] for i = 1, #e do 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 end end From bbd52043f11656c91dee07063bae1f56703c6dd9 Mon Sep 17 00:00:00 2001 From: kay27 Date: Mon, 29 Mar 2021 02:17:32 +0400 Subject: [PATCH 12/18] [mcl_portals] Make '/spawnstruct nether_portal' chat command work in obsidian nodes (immediate destruction triggered) --- mods/ITEMS/mcl_portals/portal_nether.lua | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index 5bb226408..6e2d1e7b6 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -278,12 +278,14 @@ minetest.register_node(PORTAL, { _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 if x1 == x2 then orientation = 1 end 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 pos.x = x for z = z1 - orientation, z2 + orientation do @@ -292,9 +294,9 @@ local function light_frame(x1, y1, z1, x2, y2, z2, name) pos.y = y local frame = (x < x1) or (x > x2) or (y < y1) or (y > y2) or (z < z1) or (z > z2) if frame then - set_node(pos, {name = OBSIDIAN}) + set_node(pos, node_frame) else - set_node(pos, {name = PORTAL, param2 = orientation}) + set_node(pos, node) add_exit({x=pos.x, y=pos.y-1, z=pos.z}) end end @@ -303,10 +305,13 @@ local function light_frame(x1, y1, z1, x2, y2, z2, name) end --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) - 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"}) + 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: for x = pos.x - orientation, pos.x + orientation + (width - 1) * (1 - orientation), 1 + orientation do @@ -336,7 +341,7 @@ function mcl_portals.spawn_nether_portal(pos, rot, pr, name) o = random(0,1) end end - build_nether_portal(pos, nil, nil, o, name) + build_nether_portal(pos, nil, nil, o, name, true) end -- Teleportation cooloff for some seconds, to prevent back-and-forth teleportation From 1818fcf5929f51b1d57a57b9880e2a01f1fda390 Mon Sep 17 00:00:00 2001 From: kay27 Date: Mon, 29 Mar 2021 02:43:08 +0400 Subject: [PATCH 13/18] [mcl_mapgen_core] Remove water from End, fix https://git.minetest.land/MineClone2/MineClone2/issues/1394 --- mods/MAPGEN/mcl_mapgen_core/init.lua | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index 63256ec7a..1a2abf3f9 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -2129,17 +2129,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. -- * Generate spawn platform (End portal destination) 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 - 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 - 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 if #nodes > 0 then lvm_used = true - for n=1, #nodes do - node = nodes[n] - data[area:index(node.x, node.y, node.z)] = c_air + for _, n in pairs(nodes) do + data[area:index(n.x, n.y, n.z)] = c_air end end From b587b1f2a5ace2acb8d7912ac2bbd1a619cc60dd Mon Sep 17 00:00:00 2001 From: kay27 Date: Mon, 29 Mar 2021 02:48:45 +0400 Subject: [PATCH 14/18] [mcl_spawn] Cleanup --- mods/PLAYER/mcl_spawn/init.lua | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/mods/PLAYER/mcl_spawn/init.lua b/mods/PLAYER/mcl_spawn/init.lua index 6a3d543d3..55329c104 100644 --- a/mods/PLAYER/mcl_spawn/init.lua +++ b/mods/PLAYER/mcl_spawn/init.lua @@ -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 emerge_pos1, emerge_pos2 --- Get world 'mapgen_limit' and 'chunksize' to calculate 'spawn_limit'. --- 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) +local spawn_limit = mcl_vars.mapgen_edge_max --Functions From 2e3a5efaf90d9812b98726d46630433c29144dba Mon Sep 17 00:00:00 2001 From: kay27 Date: Mon, 29 Mar 2021 03:08:21 +0400 Subject: [PATCH 15/18] [mcl_spawn] Ignore 'ignore' nodes when checking the point, fix https://git.minetest.land/MineClone2/MineClone2/issues/1230 --- mods/PLAYER/mcl_spawn/init.lua | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/mods/PLAYER/mcl_spawn/init.lua b/mods/PLAYER/mcl_spawn/init.lua index 55329c104..fe88cf3de 100644 --- a/mods/PLAYER/mcl_spawn/init.lua +++ b/mods/PLAYER/mcl_spawn/init.lua @@ -497,10 +497,17 @@ function mcl_spawn.shadow_worker() mcl_spawn.search() minetest.log("action", "[mcl_spawn] Started world spawn point search") end - if success and ((not good_for_respawn(wsp)) or (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() + + if success then + local wsp_node = minetest.get_node(wsp) + 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 minetest.after(respawn_search_interval, mcl_spawn.shadow_worker) From 80d845adb678e568ed67d081771b04cc0dd85ef5 Mon Sep 17 00:00:00 2001 From: kay27 Date: Mon, 29 Mar 2021 03:18:17 +0400 Subject: [PATCH 16/18] [mcl_mapgen_core] Fix Nether generation chain reaction --- mods/ITEMS/mcl_portals/portal_nether.lua | 1 - mods/MAPGEN/mcl_mapgen_core/init.lua | 14 ++++---------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index 6e2d1e7b6..e842edf81 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -466,7 +466,6 @@ local function ecb_scan_area_2(blockpos, action, calls_remaining, param) local nodes2 = find_nodes_in_area(node1, node2, {"air"}) if nodes2 then local nc2 = #nodes2 - log("action", "[mcl_portals] nc2=" .. tostring(nc2)) if nc2 == 27 and not is_area_protected(node, node2, name) then local distance0 = dist(pos, node) if distance0 < 2 then diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index 1a2abf3f9..e08b55ba3 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -2112,16 +2112,10 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed) end end else - minetest.emerge_area(emin, emax, function(blockpos, action, calls_remaining, param) - if calls_remaining > 0 then return end - -- local nodes = minetest.find_nodes_in_area(param.minp, param.maxp, {"mcl_core:water_source"}) - local nodes = minetest.find_nodes_in_area(param.minp, param.maxp, {"group:water"}) - 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(emin), maxp=vector.new(emax)}) + local nodes = minetest.find_nodes_in_area(emin, emax, {"group:water"}) + for _, n in pairs(nodes) do + data[area:index(n.x, n.y, n.z)] = c_nether_lava + end end -- End block fixes: From d1a0299b9202d501c21851c9beb9c82b63a15cbe Mon Sep 17 00:00:00 2001 From: kay27 Date: Mon, 29 Mar 2021 03:34:41 +0400 Subject: [PATCH 17/18] [mcl_dungeons] Remove empty code section, add debug info --- mods/MAPGEN/mcl_dungeons/init.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mods/MAPGEN/mcl_dungeons/init.lua b/mods/MAPGEN/mcl_dungeons/init.lua index 5c15d6309..dc9c6d619 100644 --- a/mods/MAPGEN/mcl_dungeons/init.lua +++ b/mods/MAPGEN/mcl_dungeons/init.lua @@ -247,7 +247,7 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) if forChest and (currentChest < totalChests + 1) and (chestSlots[currentChest] == chestSlotCounter) then currentChest = currentChest + 1 table.insert(chests, {x=tx, y=ty, z=tz}) - else + -- else --minetest.swap_node(p, {name = "air"}) end if forChest then @@ -265,8 +265,8 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) -- Detect the 4 horizontal neighbors local spos = vector.add(pos, surround_vectors[s]) local wpos = vector.subtract(pos, surround_vectors[s]) - local nodename = minetest.get_node(spos).name - local nodename2 = minetest.get_node(wpos).name + local nodename = get_node(spos).name + local nodename2 = get_node(wpos).name local nodedef = minetest.registered_nodes[nodename] local nodedef2 = minetest.registered_nodes[nodename2] -- The chest needs an open space in front of it and a walkable node (except chest) behind it @@ -347,6 +347,7 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) }) 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) end From 1b9737b4312d566cd05768e28cadf0ea386f0c6b Mon Sep 17 00:00:00 2001 From: ArTee3 Date: Mon, 29 Mar 2021 18:13:10 +0200 Subject: [PATCH 18/18] Prevent beds from appearing and disappearing if they cannot be placed, fix #1419 --- mods/ITEMS/mcl_beds/api.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/mods/ITEMS/mcl_beds/api.lua b/mods/ITEMS/mcl_beds/api.lua index c274a29a0..a2df1bdf3 100644 --- a/mods/ITEMS/mcl_beds/api.lua +++ b/mods/ITEMS/mcl_beds/api.lua @@ -89,6 +89,7 @@ function mcl_beds.register_bed(name, def) selection_box = selection_box_bottom, collision_box = collision_box_bottom, drop = "", + node_placement_prediction = "", on_place = function(itemstack, placer, pointed_thing) local under = pointed_thing.under