From ecdbc30b63998e4fdcb3004ca892707b54bd7d2f Mon Sep 17 00:00:00 2001 From: iliekprogrammar Date: Mon, 29 Mar 2021 14:09:09 +0800 Subject: [PATCH] Overhaul kelp interactions. Highlights: - Added locking system to drops. Will be removed after testing. - Expose more variables and functions. Will be finalized soon. - Implement MC-like age and natural growth mechanics. - Implement correct piston interactions with kelp and its surface. - Implement correct falling node interactions for its surface. - ABMs are now nonfunction. Will be fixed. - Various optimizations and fixes. --- mods/ITEMS/mcl_ocean/init.lua | 2 + mods/ITEMS/mcl_ocean/kelp.lua | 484 ++++++++++++++++++++++------------ 2 files changed, 320 insertions(+), 166 deletions(-) diff --git a/mods/ITEMS/mcl_ocean/init.lua b/mods/ITEMS/mcl_ocean/init.lua index 2a103b8d05..f723a1f3ff 100644 --- a/mods/ITEMS/mcl_ocean/init.lua +++ b/mods/ITEMS/mcl_ocean/init.lua @@ -1,3 +1,5 @@ +mcl_ocean = {} + -- Prismarine (includes sea lantern) dofile(minetest.get_modpath(minetest.get_current_modname()).."/prismarine.lua") diff --git a/mods/ITEMS/mcl_ocean/kelp.lua b/mods/ITEMS/mcl_ocean/kelp.lua index a4de943b71..741d9e59aa 100644 --- a/mods/ITEMS/mcl_ocean/kelp.lua +++ b/mods/ITEMS/mcl_ocean/kelp.lua @@ -3,9 +3,6 @@ -- -- TODO: In MC, you can't actually destroy kelp by bucket'ing water in the middle. -- However, because of the plantlike_rooted hack, we'll just allow it for now. --- --- TODO: Currently, you lose kelp if the kelp is placed on a block and then falls. --- This is most relevant for (red)sand and gravel. local S = minetest.get_translator("mcl_ocean") local mod_doc = minetest.get_modpath("doc") ~= nil @@ -14,19 +11,28 @@ local mod_doc = minetest.get_modpath("doc") ~= nil -- local-ify runtime functions -------------------------------------------------------------------------------- -- objects -local registered_items = minetest.registered_items -local registered_nodes = minetest.registered_nodes +local mt_registered_items = minetest.registered_items +local mt_registered_nodes = minetest.registered_nodes -- functions +local mt_add_item = minetest.add_item local mt_get_item_group = minetest.get_item_group local mt_get_node = minetest.get_node -local mt_set_node = minetest.set_node -local mt_add_item = minetest.add_item -local mt_sound_play = minetest.sound_play -local mt_is_creative_enabled = minetest.is_creative_enabled -local mt_is_protected = minetest.is_protected -local mt_hash_node_position = minetest.hash_node_position +local mt_get_node_level = minetest.get_node_level +local mt_get_node_max_level = minetest.get_node_max_level +local mt_get_node_or_nil = minetest.get_node_or_nil local mt_get_node_timer = minetest.get_node_timer +local mt_hash_node_position = minetest.hash_node_position +local mt_is_protected = minetest.is_protected +local mt_set_node = minetest.set_node +local mt_get_meta = minetest.get_meta + +local mt_is_creative_enabled = minetest.is_creative_enabled +local mt_sound_play = minetest.sound_play + +local math_floor = math.floor +local math_random = math.random +local string_format = string.format -- DEBUG: functions local log = minetest.log @@ -36,109 +42,218 @@ local chatlog = minetest.chat_send_all -- Kelp API -------------------------------------------------------------------------------- -kelp = {} +local kelp = {} +mcl_ocean.kelp = kelp + +kelp.MAX_AGE = 25 +kelp.TIMER_INTERVAL = 0.2 + +-- The average amount of growth for kelp in a day is 2.16 (https://youtu.be/5Bp4lAjAk3I) +-- Normally, a day lasts 20 minutes, meaning this nodetimer is executed 24000 times. +-- Calculate probability via 2.16/24000 and we get the probability 9/100'000 or 9.0e-5 +-- NOTE: currently, we can't exactly use the same type of randomness MC does, +-- because it has multiple complicated sets of PRNGs. +-- kelp.RANDOM_NUMERATOR = 9 +kelp.RANDOM_NUMERATOR = 100 +kelp.RANDOM_DENOMINATOR = 100000 + +kelp.leaf_sounds = mcl_sounds.node_sound_leaves_defaults() + +-- TODO: is this really necessary +-- Lock drops to avoid duplicate drops, set after dropping detached kelp. +kelp.lock_drop = 0 + +-- Registrar of nodetimers, indexed by pos_hash. +kelp.registered_nodetimers = {} + +-- Pool storing age, indexed by pos_hash. +kelp.age_pool = {} + + +-- is age in the growable range? +function kelp.is_age_growable(age) + return age >= 0 and age < kelp.MAX_AGE +end + -- Is this water? -- Returns the liquidtype, if indeed water. -local function is_submerged(node, nodedef) +function kelp.is_submerged(node, def) if mt_get_item_group(node.name, "water") ~= 0 then - return nodedef.liquidtype -- Expected only "source" and "flowing" from water liquids + return def.liquidtype -- Expected only "source" and "flowing" from water liquids end return false end -kelp.is_submerged = is_submerged -- Is the water downward flowing? -- (kelp can grow/be placed inside downward flowing water) -local function is_downward_flowing(pos, node, nodedef, is_above) - local result = (math.floor(node.param2 / 8) % 2) == 1 +function kelp.is_downward_flowing(pos, node, def, is_above) + local result = (math_floor(node.param2 / 8) % 2) == 1 if not (result or is_above) then -- If not, also check node above. -- (this is needed due a weird quirk in the definition of "downwards flowing" -- liquids in Minetest) local node_above = mt_get_node({x=pos.x,y=pos.y+1,z=pos.z}) - local nodedef_above = registered_nodes[node_above.name] - result = is_submerged(node_above, nodedef_above) - or is_downward_flowing(pos, node_above, nodedef_above, true) + local def_above = mt_registered_nodes[node_above.name] + result = kelp.is_submerged(node_above, def_above) + or kelp.is_downward_flowing(pos, node_above, def_above, true) end return result end -kelp.is_downward_flowing = is_downward_flowing + + +-- Will node fall at that position? +-- This only checks if a node would fall, meaning that node need not be at pos. +function kelp.is_falling(pos, node) + -- NOTE: Modified from check_single_for_falling in builtin. + -- Please update as necessary. + local nodename = node.name + + if mt_get_item_group(nodename, "falling_node") == 0 then + return false + end + + local pos_bottom = {x = pos.x, y = pos.y - 1, z = pos.z} + -- get_node_or_nil: Only fall if node below is loaded + local node_bottom = mt_get_node_or_nil(pos_bottom) + local nodename_bottom = node_bottom.name + local def_bottom = node_bottom and mt_registered_nodes[nodename_bottom] + if not def_bottom then + return false + end + + local same = nodename == nodename_bottom + -- Let leveled nodes fall if it can merge with the bottom node + if same and def_bottom.paramtype2 == "leveled" and + mt_get_node_level(pos_bottom) < + mt_get_node_max_level(pos_bottom) then + return true + end + + -- Otherwise only if the bottom node is considered "fall through" + if not same and + (not def_bottom.walkable or def_bottom.buildable_to) and + (mt_get_item_group(nodename, "float") == 0 or + def_bottom.liquidtype == "none") then + return true + end + + return false +end -- Converts param2 to kelp height. -local function get_height(param2) - return math.floor(param2 / 16) +function kelp.get_height(param2) + return math_floor(param2 / 16) end -kelp.get_height = get_height --- Obtain pos and node of the top of kelp. -local function get_tip(pos, node) +-- Obtain pos and node of the tip of kelp. +function kelp.get_tip(pos, node) local size = math.ceil(node.param2 / 16) - local pos_top = table.copy(pos) - pos_top.y = pos_top.y + size - return pos_top, mt_get_node(pos_top) + local pos_tip = table.copy(pos) + pos_tip.y = pos_tip.y + size + return pos_tip, mt_get_node(pos_tip) end -kelp.get_tip = get_tip -- Obtain position of the first kelp unsubmerged. -local function find_unsubmerged(pos, node) +function kelp.find_unsubmerged(pos, node) + local x,y,z = pos.x, pos.y, pos.z - local height = get_height(node.param2) + local height = kelp.get_height(node.param2) + local walk_pos = {x=x, z=z} for i=1,height do - local walk_pos = {x=x, y=y + i, z=z} - if mt_get_item_group(mt_get_node(walk_pos).name, "water") == 0 then - return walk_pos + walk_pos.y = y + i + local walk_node = mt_get_node(walk_pos) + if mt_get_item_group(walk_node.name, "water") == 0 then + return walk_pos, walk_node end end return nil end -kelp.find_unsubmerged = find_unsubmerged -- Obtain next param2. -local function next_param2(param2) - local old_param2 = param2 - param2 = param2+16 - param2 % 16 - return param2, param2 ~= old_param2 +function kelp.next_param2(param2) + return param2+16 - param2 % 16 end -kelp.next_param2 = next_param2 -- Grow next kelp. -local function next_grow(pos, node, pos_top, def_top, is_downward_flowing) +function kelp.next_grow(pos, node, pos_tip, def_tip, downward_flowing) + -- Optional parameters + local pos_tip, def_tip = pos_tip, def_tip + local downward_flowing = downward_flowing + if pos_tip == nil and def_tip == nil then + local node_tip + pos_tip, node_tip = kelp.get_tip(pos, node) + def_tip = mt_registered_nodes[node_tip.name] + downward_flowing = kelp.is_submerged(pos_tip, node_tip) + and kelp.is_downward_flowing(pos_tip, node_tip, def_tip) + end + -- Liquid source: Grow normally. + local node = table.copy(node) + node.param2 = kelp.next_param2(node.param2) mt_set_node(pos, node) - -- Flowing liquid: Grow 1 step, but also turn the top node into a liquid source. - if is_downward_flowing then - local alt_liq = def_top.liquid_alternative_source + -- Flowing liquid: Grow 1 step, but also turn the tip node into a liquid source. + if downward_flowing then + local alt_liq = def_tip.liquid_alternative_source if alt_liq then - mt_set_node(pos_top, {name=alt_liq}) + mt_set_node(pos_tip, {name=alt_liq}) end end end -kelp.next_grow = next_grow + + +-- Naturally grow next kelp. +function kelp.natural_grow(pos, node, age, pos_hash, meta) + -- Must grow first, then get the new meta + kelp.next_grow(pos, node) + + -- Optional params + local meta = meta or mt_get_meta(pos) + local pos_hash = pos_hash or mt_hash_node_position(pos) + + local age = age + 1 + kelp.age_pool[pos_hash] = age + meta:set_int("mcl_ocean:kelp_age", age) + +end -- Drops the items for detached kelps. -local function detach_drop(pos, height) +function kelp.detach_drop(pos, height, pos_hash) + local pos_hash = pos_hash or mt_hash_node_position(pos) -- Optional params + + if kelp.lock_drop > 0 then + minetest.log("error", + string_format("Duplicate drop prevented at (%d, %d, %d) with lock level %d! Please report this.", + pos.x, pos.y, pos.z, kelp.lock_drop)) + return + end + local x,y,z = pos.x,pos.y,pos.z for i=1,height do mt_add_item({x=x, y=y+i, z=z}, "mcl_ocean:kelp") end + + -- Locks drop. + kelp.lock_drop = kelp.lock_drop + 1 + return true end -kelp.detach_drop = detach_drop -- Detach the kelp at dig_pos, and drop their items. -- Synonymous to digging the kelp. -- NOTE: this is intended for whenever kelp truly becomes segmented plants -- instead of rooted to the floor. Don't try to remove dig_pos. -local function detach_dig(dig_pos, pos, node, is_drop) +function kelp.detach_dig(dig_pos, pos, node, is_drop, pos_hash) + local pos_hash = pos_hash or mt_hash_node_position(pos) + local param2 = node.param2 -- pos.y points to the surface, offset needed to point to the first kelp. local new_height = dig_pos.y - (pos.y+1) @@ -146,52 +261,77 @@ local function detach_dig(dig_pos, pos, node, is_drop) -- Digs the entire kelp: invoke after_dig_node to mt_set_node. if new_height <= 0 then if is_drop then - detach_drop(dig_pos, get_height(param2)) + kelp.detach_drop(dig_pos, kelp.get_height(param2), pos_hash) end mt_set_node(pos, { - name=registered_nodes[node.name].node_dig_prediction, + name=mt_registered_nodes[node.name].node_dig_prediction, param=node.param, param2=0 }) -- Digs the kelp beginning at a height else if is_drop then - detach_drop(dig_pos, get_height(param2) - new_height) + kelp.detach_drop(dig_pos, kelp.get_height(param2) - new_height, pos_hash) end mt_set_node(pos, {name=node.name, param=node.param, param2=16*new_height}) end end -kelp.detach_dig = detach_dig + -------------------------------------------------------------------------------- -- Kelp callback functions -------------------------------------------------------------------------------- -local function surface_on_dig(pos, node, digger) - -- NOTE: if instead, kelp shouldn't drop in creative: use this instead - -- detach_dig(pos, pos, node, - -- not (digger and mt_is_creative_enabled(digger:get_player_name()))) - detach_dig(pos, pos, node, true) +-- Set this to drop kelps when +function kelp.surface_on_dig(pos, node, digger) + kelp.detach_dig(pos, pos, node, true) end -kelp.surface_on_dig = surface_on_dig -local function surface_after_dig_node(pos, node) +function kelp.surface_after_dig_node(pos, node) return mt_set_node(pos, {name=registred_nodes[node.name].node_dig_prediction}) end -kelp.surface_after_dig_node = surface_after_dig_node -local kelp_timers = {} -local kelp_timers_counter = 0 -local function surface_on_timer(pos, elapsed) +function kelp.surface_on_timer(pos, elapsed) local node = mt_get_node(pos) - local dig_pos = find_unsubmerged(pos, node) + local dig_pos = kelp.find_unsubmerged(pos, node) + local pos_hash = mt_hash_node_position(pos) if dig_pos then - detach_dig(dig_pos, pos, node, true) + kelp.detach_dig(dig_pos, pos, node, true, pos_hash) end + + -- Grow kelp on chance + if math_random(kelp.RANDOM_DENOMINATOR) - kelp.RANDOM_NUMERATOR < 0 then + local age = kelp.age_pool[pos_hash] + if kelp.is_age_growable(age) then + kelp.natural_grow(pos, node, age, pos_hash) + end + end + return true end +function kelp.surface_on_destruct(pos) + local node = mt_get_node(pos) + local pos_hash = mt_hash_node_position(pos) + + -- on_falling callback. Activated by pistons for falling nodes too. + if kelp.is_falling(pos, node) then + kelp.detach_drop(pos, kelp.get_height(node.param2), pos_hash) + end + + -- Unlocks drops. + if kelp.lock_drop > 0 then + kelp.lock_drop = kelp.lock_drop - 1 + end +end + + +function kelp.surface_on_mvps_move(pos, node, oldpos, nodemeta) + -- Pistons moving falling nodes will have already activated on_falling callback. + kelp.detach_dig(pos, pos, node, mt_get_item_group(node.name, "falling_node") ~= 1) +end + -- NOTE: Uncomment this to use ABMs -- local function surface_unsubmerged_abm(pos, node) @@ -204,35 +344,52 @@ end -- NOTE: Uncomment this to use nodetimers -local function surface_register_nodetimer(pos, node) - local pos_hash = mt_hash_node_position(pos) - if kelp_timers[pos_hash] then - return +function kelp.surface_register_nodetimer(pos, node, pos_hash, meta, age) + -- Optional params + local pos_hash,meta,age = pos_hash,meta,age + local timer = kelp.registered_nodetimers[pos_hash] + + if not timer then + pos_hash = pos_hash or mt_hash_node_position(pos) + + timer = mt_get_node_timer(pos) + kelp.registered_nodetimers[pos_hash] = timer + + -- Pool age to avoid meta:get* operations + meta = meta or mt_get_meta(pos) + if not age then + if not meta:contains("mcl_ocean:kelp_age") then + age = math_random(0, kelp.MAX_AGE-1) + else + age = meta:get_int("mcl_ocean:kelp_age") + end + end + kelp.age_pool[pos_hash] = age + meta:set_int("mcl_ocean:kelp_age", age) end - local timer = mt_get_node_timer(pos) - kelp_timers[pos_hash] = timer - timer:start(0.5) - kelp_timers_counter = kelp_timers_counter + 1 - chatlog("added a timer. Currently " ..tostring(kelp_timers_counter) .." timers") -end -kelp.surface_register_nodetiemr = surface_register_nodetimer - -local function grow_kelp(pos, node) - local grow - -- Grow kelp by 1 node length if it would grow inside water - node.param2, grow = next_param2(node.param2) - local pos_top, node_top = get_tip(pos, node) - local def_top = registered_nodes[node_top.name] - if grow and is_submerged(node_top, def_top) then - next_grow(pos, node, pos_top, def_top, - is_downward_flowing(pos_top, node_top, def_top)) + if not timer:is_started() then + timer:start(kelp.TIMER_INTERVAL) end + + return pos_hash, meta, age end -kelp.grow_kelp = grow_kelp -local function kelp_on_place(itemstack, placer, pointed_thing) +-- NOTE: Uncomment this to use ABMs +-- function kelp.grow_abm(pos, node) +-- -- Grow kelp by 1 node length if it would grow inside water +-- node.param2 = next_param2(node.param2) +-- local pos_tip, node_tip = get_tip(pos, node) +-- local def_tip = mt_registered_nodes[node_tip.name] +-- if is_submerged(node_tip, def_tip) then +-- kelp.next_grow(pos, node, pos_tip, def_tip, +-- is_downward_flowing(pos_tip, node_tip, def_tip)) +-- end +-- end + + +function kelp.kelp_on_place(itemstack, placer, pointed_thing) if pointed_thing.type ~= "node" or not placer then return itemstack end @@ -242,14 +399,15 @@ local function kelp_on_place(itemstack, placer, pointed_thing) local pos_above = pointed_thing.above local node_under = mt_get_node(pos_under) local nu_name = node_under.name - local def_under = registered_nodes[nu_name] + local def_under = mt_registered_nodes[nu_name] - -- Allow rightclick override. + -- Allow rightclick to override place. if def_under and def_under.on_rightclick and not placer:get_player_control().sneak then return def_under.on_rightclick(pos_under, node_under, placer, itemstack, pointed_thing) or itemstack end + -- Protection if mt_is_protected(pos_under, player_name) or mt_is_protected(pos_above, player_name) then minetest.log("action", player_name @@ -260,86 +418,89 @@ local function kelp_on_place(itemstack, placer, pointed_thing) return itemstack end - local new_kelp = false - local downward_flowing = false - local pos_top, node_top, def_top + + local pos_tip, node_tip, def_tip + local pos_hash, meta + + + -- Kelp must also be placed on the top/tip side of the surface/kelp + if pos_under.y >= pos_above.y then + return itemstack + end -- When placed on kelp. if mt_get_item_group(nu_name, "kelp") == 1 then - node_under.param2, new_kelp = next_param2(node_under.param2) - -- Kelp must not reach the height limit. - -- Kelp must also be placed on top of kelp to add kelp. - if not new_kelp or pos_under.y >= pos_above.y then - return itemstack - end - pos_top, node_top = get_tip(pos_under, node_under) - def_top = registered_nodes[node_top.name] + pos_tip, node_tip = kelp.get_tip(pos_under, node_under) + def_tip = mt_registered_nodes[node_tip.name] + + pos_hash = mt_hash_node_position(pos_under) + meta = mt_get_meta(pos_under) -- When placed on surface. else - local surfaces = kelp.surfaces or surfaces - for _,surface in pairs(surfaces) do - -- Surface must support kelp + local new_kelp = false + for _,surface in pairs(kelp.surfaces) do if nu_name == surface.nodename then node_under.name = "mcl_ocean:kelp_" ..surface.name - node_under.param2 = registered_items[nu_name].place_param2 or 16 + node_under.param2 = 0 new_kelp = true break end end - - -- Kelp must also be placed on top of surface to add new kelp. - if not new_kelp or pos_under.y >= pos_above.y then + -- Surface must support kelp + if not new_kelp then return itemstack end - pos_top = pos_above - node_top = mt_get_node(pos_above) - def_top = registered_nodes[node_top.name] - -- NOTE: Uncomment this to use nodetimers -- Register nodetimer - surface_register_nodetimer(pos_under, node_under) + pos_hash, meta = kelp.surface_register_nodetimer(pos_under) + + pos_tip = pos_above + node_tip = mt_get_node(pos_above) + def_tip = mt_registered_nodes[node_tip.name] end -- New kelp must also be submerged in water. - downward_flowing = is_downward_flowing(pos_top, node_top, def_top) - if not (is_submerged(node_top, def_top) or downward_flowing) then + local downward_flowing = kelp.is_downward_flowing(pos_tip, node_tip, def_tip) + if not (kelp.is_submerged(node_tip, def_tip) or downward_flowing) then return itemstack end -- Play sound, place surface/kelp and take away an item - local def_node = registered_items[nu_name] + local def_node = mt_registered_items[nu_name] if def_node.sounds then mt_sound_play(def_node.sounds.place, { gain = 0.5, pos = pos_under }, true) end - next_grow(pos_under, node_under, pos_top, def_top, downward_flowing) + kelp.next_grow(pos_under, node_under, pos_tip, def_tip, downward_flowing) if not mt_is_creative_enabled(player_name) then itemstack:take_item() end + -- Reroll age + local age = math_random(0, kelp.MAX_AGE-1) + meta:set_int("mcl_ocean:kelp_age", age) + kelp.age_pool[pos_hash] = age + return itemstack end -kelp.kelp_on_place = kelp_on_place -------------------------------------------------------------------------------- -- Kelp registration API -------------------------------------------------------------------------------- -- List of supported surfaces for seagrass and kelp. -local surfaces = { +kelp.surfaces = { { name="dirt", nodename="mcl_core:dirt", }, { name="sand", nodename="mcl_core:sand", }, { name="redsand", nodename="mcl_core:redsand", }, { name="gravel", nodename="mcl_core:gravel", }, } -kelp.surfaces = surfaces -local registered_surfaces = {} -kelp.registered_surfaces = registered_surfaces +kelp.registered_surfaces = {} -- Commented properties are the ones obtained using register_kelp_surface. -- If you define your own properties, it overrides the default ones. -local surface_deftemplate = { +kelp.surface_deftemplate = { drawtype = "plantlike_rooted", paramtype = "light", paramtype2 = "leveled", @@ -365,55 +526,46 @@ local surface_deftemplate = { groups = { dig_immediate = 3, deco_block = 1, plant = 1, kelp = 1, }, --sounds = sounds, --node_dig_prediction = nodename, - after_dig_node = surface_after_dig_node, - on_dig = surface_on_dig, - on_timer = surface_on_timer, + after_dig_node = kelp.surface_after_dig_node, + on_destruct = kelp.surface_on_destruct, + on_dig = kelp.surface_on_dig, + on_timer = kelp.surface_on_timer, + mesecon = { on_mvps_move = kelp.surface_on_mvps_move, }, drop = "", -- drops are handled in on_dig --_mcl_falling_node_alternative = is_falling and nodename or nil, _mcl_hardness = 0, _mcl_blast_resistance = 0, } -kelp.surface_deftemplate = surface_deftemplate -- Commented properties are the ones obtained using register_kelp_surface. -local surface_docs = { +kelp.surface_docs = { -- entry_id_orig = nodename, _doc_items_entry_name = S("Kelp"), _doc_items_longdesc = S("Kelp grows inside water on top of dirt, sand or gravel."), --_doc_items_create_entry = doc_create, _doc_items_image = "mcl_ocean_kelp_item.png", } -kelp.surface_docs = surface_docs ---[==[-- -register_kelp_surface(surface[, surface_deftemplate[, surface_docs]]) - -surface: table with its specific properties. See also kelp.surface. - -surface_deftemplate: modifiable nodedef template. See also kelp.surface_deftempate. -DO NOT RE-USE THE SAME DEFTEMPLATE. create copies. - -surface_docs: table with properties related to docs. See also kelp.surface_docs. ---]==]-- -local leaf_sounds = mcl_sounds.node_sound_leaves_defaults() -local function register_kelp_surface(surface, surface_deftemplate, surface_docs) +-- Creates new surfaces. +-- NOTE: surface_deftemplate will be modified in-place. +function kelp.register_kelp_surface(surface, surface_deftemplate, surface_docs) local name = surface.name local nodename = surface.nodename - local def = registered_nodes[nodename] + local def = mt_registered_nodes[nodename] local def_tiles = def.tiles local surfacename = "mcl_ocean:kelp_"..name - local surface_deftemplate = surface_deftemplate or kelp.surface_deftemplate -- optional param + local surface_deftemplate = surface_deftemplate or kelp.surface_deftemplate -- Optional param local doc_create = surface.doc_create or false - local surface_docs = surface_docs or kelp.surface_docs + local surface_docs = surface_docs or kelp.surface_docs -- Optional param if doc_create then surface_deftemplate._doc_items_entry_name = surface_docs._doc_items_entry_name surface_deftemplate._doc_items_longdesc = surface_docs._doc_items_longdesc surface_deftemplate._doc_items_create_entry = true surface_deftemplate._doc_items_image = surface_docs._doc_items_image - -- Takes the first surface with docs + -- Sets the first surface as the docs' entry ID if not surface_docs.entry_id_orig then surface_docs.entry_id_orig = nodename end @@ -422,9 +574,9 @@ local function register_kelp_surface(surface, surface_deftemplate, surface_docs) end local sounds = table.copy(def.sounds) - sounds.dig = leaf_sounds.dig - sounds.dug = leaf_sounds.dug - sounds.place = leaf_sounds.place + sounds.dig = kelp.leaf_sounds.dig + sounds.dug = kelp.leaf_sounds.dug + sounds.place = kelp.leaf_sounds.place surface_deftemplate.tiles = surface_deftemplate.tiles or def_tiles surface_deftemplate.inventory_image = surface_deftemplate.inventory_image or "("..def_tiles[1]..")^mcl_ocean_kelp_item.png" @@ -440,9 +592,9 @@ end -- Kelp surfaces nodes --------------------------------------------------------- -- Dirt must be registered first, for the docs -register_kelp_surface(surfaces[1], table.copy(surface_deftemplate), surface_docs) -for i=2, #surfaces do - register_kelp_surface(surfaces[i], table.copy(surface_deftemplate), surface_docs) +kelp.register_kelp_surface(kelp.surfaces[1], table.copy(kelp.surface_deftemplate), kelp.surface_docs) +for i=2, #kelp.surfaces do + kelp.register_kelp_surface(kelp.surfaces[i], table.copy(kelp.surface_deftemplate), kelp.surface_docs) end -- Kelp item ------------------------------------------------------------------- @@ -453,12 +605,12 @@ minetest.register_craftitem("mcl_ocean:kelp", { _doc_items_create_entry = false, inventory_image = "mcl_ocean_kelp_item.png", wield_image = "mcl_ocean_kelp_item.png", - on_place = kelp_on_place, + on_place = kelp.kelp_on_place, groups = { deco_block = 1 }, }) if mod_doc then - doc.add_entry_alias("nodes", surface_docs.entry_id_orig, "craftitems", "mcl_ocean:kelp") + doc.add_entry_alias("nodes", kelp.surface_docs.entry_id_orig, "craftitems", "mcl_ocean:kelp") end -- Dried kelp ------------------------------------------------------------------ @@ -523,26 +675,17 @@ minetest.register_craft({ }) -- ABMs ------------------------------------------------------------------------ -minetest.register_abm({ - label = "Kelp growth", - nodenames = { "group:kelp" }, - interval = 45, - chance = 12, - catch_up = false, - action = grow_kelp, -}) -- NOTE: Uncomment this to use nodetimers minetest.register_lbm({ label = "Kelp timer registration", name = "mcl_ocean:kelp_timer_registration", nodenames = { "group:kelp" }, - run_at_every_load = false, - action = surface_register_nodetimer, + run_at_every_load = true, -- so old kelps are also registered + action = kelp.surface_register_nodetimer, }) -- NOTE: Uncomment this to use ABMs --- Break kelp not underwater. -- minetest.register_abm({ -- label = "Kelp drops", -- nodenames = { "group:kelp" }, @@ -551,3 +694,12 @@ minetest.register_lbm({ -- catch_up = false, -- action = surface_unsubmerged_abm, -- }) +-- +-- minetest.register_abm({ +-- label = "Kelp growth", +-- nodenames = { "group:kelp" }, +-- interval = 45, +-- chance = 12, +-- catch_up = false, +-- action = grow_abm, +-- })