Merge pull request 'Update trapdoor climbable behavior' (#3938) from Dehydrate6684/MineClone2:trapdoor-ladder into master

Reviewed-on: https://git.minetest.land/MineClone2/MineClone2/pulls/3938
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
This commit is contained in:
the-real-herowl 2023-11-06 20:29:23 +00:00
commit fdf823fff6
3 changed files with 164 additions and 50 deletions

@ -11,12 +11,39 @@ local function rotate_climbable(pos, node, user, mode)
return false return false
end end
---Updates the trapdoor above (if any).
---
---@param pos mt.Vector The position of the ladder.
---@param event "place" | "destruct" The place or destruct event.
function mcl_core.update_trapdoor(pos, event)
local top_pos = vector.offset(pos, 0, 1, 0)
local top_node = minetest.get_node_or_nil(top_pos)
if top_node and minetest.get_item_group(top_node.name, "trapdoor") == 2 then
local new_name = top_node.name
if event == "place" then
new_name = string.gsub(new_name, "open$", "ladder")
elseif event == "destruct" then
new_name = string.gsub(new_name, "ladder$", "open")
end
-- If node above is an opened trapdoor
minetest.swap_node(top_pos, {
name = new_name,
param1 = top_node.param1,
param2 = top_node.param2,
})
end
end
-- TODO: Move ladders into their own API.
minetest.register_node("mcl_core:ladder", { minetest.register_node("mcl_core:ladder", {
description = S("Ladder"), description = S("Ladder"),
_doc_items_longdesc = S("A piece of ladder which allows you to climb vertically. Ladders can only be placed on the side of solid blocks and not on glass, leaves, ice, slabs, glowstone, nor sea lanterns."), _doc_items_longdesc = S(
"A piece of ladder which allows you to climb vertically. Ladders can only be placed on the side of solid blocks and not on glass, leaves, ice, slabs, glowstone, nor sea lanterns."),
drawtype = "signlike", drawtype = "signlike",
is_ground_content = false, is_ground_content = false,
tiles = {"default_ladder.png"}, tiles = { "default_ladder.png" },
inventory_image = "default_ladder.png", inventory_image = "default_ladder.png",
wield_image = "default_ladder.png", wield_image = "default_ladder.png",
paramtype = "light", paramtype = "light",
@ -26,14 +53,21 @@ minetest.register_node("mcl_core:ladder", {
climbable = true, climbable = true,
node_box = { node_box = {
type = "wallmounted", type = "wallmounted",
wall_side = { -0.5, -0.5, -0.5, -7/16, 0.5, 0.5 }, wall_side = { -0.5, -0.5, -0.5, -7 / 16, 0.5, 0.5 },
}, },
selection_box = { selection_box = {
type = "wallmounted", type = "wallmounted",
wall_side = { -0.5, -0.5, -0.5, -7/16, 0.5, 0.5 }, wall_side = { -0.5, -0.5, -0.5, -7 / 16, 0.5, 0.5 },
}, },
stack_max = 64, stack_max = 64,
groups = {handy=1,axey=1, attached_node=1, deco_block=1, dig_by_piston=1}, groups = {
handy = 1,
axey = 1,
attached_node = 1,
deco_block = 1,
dig_by_piston = 1,
ladder = 1
},
sounds = mcl_sounds.node_sound_wood_defaults(), sounds = mcl_sounds.node_sound_wood_defaults(),
node_placement_prediction = "", node_placement_prediction = "",
-- Restrict placement of ladders -- Restrict placement of ladders
@ -53,7 +87,7 @@ minetest.register_node("mcl_core:ladder", {
-- Don't allow to place the ladder at particular nodes -- Don't allow to place the ladder at particular nodes
if (groups and (groups.glass or groups.leaves or groups.slab)) or if (groups and (groups.glass or groups.leaves or groups.slab)) or
node.name == "mcl_core:ladder" or node.name == "mcl_core:ice" or node.name == "mcl_nether:glowstone" or node.name == "mcl_ocean:sea_lantern" then node.name == "mcl_core:ladder" or node.name == "mcl_core:ice" or node.name == "mcl_nether:glowstone" or node.name == "mcl_ocean:sea_lantern" then
return itemstack return itemstack
end end
@ -75,12 +109,17 @@ minetest.register_node("mcl_core:ladder", {
if success then if success then
if idef.sounds and idef.sounds.place then if idef.sounds and idef.sounds.place then
minetest.sound_play(idef.sounds.place, {pos=above, gain=1}, true) minetest.sound_play(idef.sounds.place, { pos = above, gain = 1 }, true)
end end
end end
return itemstack return itemstack
end, end,
after_destruct = function(pos, old)
mcl_core.update_trapdoor(pos, "destruct")
end,
after_place_node = function(pos)
mcl_core.update_trapdoor(pos, "place")
end,
_mcl_blast_resistance = 0.4, _mcl_blast_resistance = 0.4,
_mcl_hardness = 0.4, _mcl_hardness = 0.4,
on_rotate = rotate_climbable, on_rotate = rotate_climbable,
@ -89,9 +128,10 @@ minetest.register_node("mcl_core:ladder", {
minetest.register_node("mcl_core:vine", { minetest.register_node("mcl_core:vine", {
description = S("Vines"), description = S("Vines"),
_doc_items_longdesc = S("Vines are climbable blocks which can be placed on the sides of solid full-cube blocks. Vines slowly grow and spread."), _doc_items_longdesc = S(
"Vines are climbable blocks which can be placed on the sides of solid full-cube blocks. Vines slowly grow and spread."),
drawtype = "signlike", drawtype = "signlike",
tiles = {"mcl_core_vine.png"}, tiles = { "mcl_core_vine.png" },
color = "#48B518", color = "#48B518",
inventory_image = "mcl_core_vine.png", inventory_image = "mcl_core_vine.png",
wield_image = "mcl_core_vine.png", wield_image = "mcl_core_vine.png",
@ -107,9 +147,19 @@ minetest.register_node("mcl_core:vine", {
}, },
stack_max = 64, stack_max = 64,
groups = { groups = {
handy = 1, axey = 1, shearsy = 1, swordy = 1, deco_block = 1, handy = 1,
dig_by_piston = 1, destroy_by_lava_flow = 1, compostability = 50, axey = 1,
flammable = 2, fire_encouragement = 15, fire_flammability = 100, foliage_palette_wallmounted = 1 shearsy = 1,
swordy = 1,
deco_block = 1,
dig_by_piston = 1,
destroy_by_lava_flow = 1,
compostability = 50,
flammable = 2,
fire_encouragement = 15,
fire_flammability = 100,
foliage_palette_wallmounted = 1,
ladder = 1
}, },
sounds = mcl_sounds.node_sound_leaves_defaults(), sounds = mcl_sounds.node_sound_leaves_defaults(),
drop = "", drop = "",
@ -151,7 +201,7 @@ minetest.register_node("mcl_core:vine", {
if success then if success then
if idef.sounds and idef.sounds.place then if idef.sounds and idef.sounds.place then
minetest.sound_play(idef.sounds.place, {pos=above, gain=1}, true) minetest.sound_play(idef.sounds.place, { pos = above, gain = 1 }, true)
end end
end end
return itemstack return itemstack
@ -174,13 +224,19 @@ minetest.register_node("mcl_core:vine", {
-- If dug, also dig a “dependant” vine below it. -- If dug, also dig a “dependant” vine below it.
-- A vine is dependant if it hangs from this node and has no supporting block. -- A vine is dependant if it hangs from this node and has no supporting block.
on_dig = function(pos, node, digger) on_dig = function(pos, node, digger)
local below = vector.offset(pos,0,-1,0) local below = vector.offset(pos, 0, -1, 0)
local belownode = minetest.get_node(below) local belownode = minetest.get_node(below)
minetest.node_dig(pos, node, digger) minetest.node_dig(pos, node, digger)
if belownode.name == node.name and (not mcl_core.check_vines_supported(below, belownode)) then if belownode.name == node.name and (not mcl_core.check_vines_supported(below, belownode)) then
minetest.registered_nodes[node.name].on_dig(below, node, digger) minetest.registered_nodes[node.name].on_dig(below, node, digger)
end end
end, end,
after_destruct = function(pos, old)
mcl_core.update_trapdoor(pos, "destruct")
end,
after_place_node = function(pos)
mcl_core.update_trapdoor(pos, "place")
end,
_mcl_blast_resistance = 0.2, _mcl_blast_resistance = 0.2,

@ -67,12 +67,23 @@ function mcl_doors:register_trapdoor(name, def)
local tmp_node local tmp_node
-- Close -- Close
if minetest.get_item_group(me.name, "trapdoor") == 2 then if minetest.get_item_group(me.name, "trapdoor") == 2 then
minetest.sound_play(def.sound_close, {pos = pos, gain = 0.3, max_hear_distance = 16}, true) minetest.sound_play(def.sound_close, { pos = pos, gain = 0.3, max_hear_distance = 16 }, true)
tmp_node = {name=name, param1=me.param1, param2=me.param2} tmp_node = { name = name, param1 = me.param1, param2 = me.param2 }
-- Open -- Open
else else
minetest.sound_play(def.sound_open, {pos = pos, gain = 0.3, max_hear_distance = 16}, true) minetest.sound_play(def.sound_open, { pos = pos, gain = 0.3, max_hear_distance = 16 }, true)
tmp_node = {name=name.."_open", param1=me.param1, param2=me.param2}
local bottom_node = minetest.get_node_or_nil(vector.offset(pos, 0, -1, 0))
local name_end = "_open"
-- Checking if there is something underneath the trapdoor
if bottom_node then
local is_ladder = minetest.get_item_group(bottom_node.name, "ladder")
if is_ladder > 0 then
name_end = "_ladder"
end
end
tmp_node = { name = name .. name_end, param1 = me.param1, param2 = me.param2 }
end end
minetest.set_node(pos, tmp_node) minetest.set_node(pos, tmp_node)
end end
@ -89,20 +100,22 @@ function mcl_doors:register_trapdoor(name, def)
longdesc = def._doc_items_longdesc longdesc = def._doc_items_longdesc
if not longdesc then if not longdesc then
if def.only_redstone_can_open then if def.only_redstone_can_open then
longdesc = S("Trapdoors are horizontal barriers which can be opened or closed and climbed like a ladder when open. They occupy the upper or lower part of a block, depending on how they have been placed. This trapdoor can only be opened or closed by redstone power.") longdesc = S(
"Trapdoors are horizontal barriers which can be opened or closed and climbed like a ladder when open. They occupy the upper or lower part of a block, depending on how they have been placed. This trapdoor can only be opened or closed by redstone power.")
else else
longdesc = S("Trapdoors are horizontal barriers which can be opened or closed and climbed like a ladder when open. They occupy the upper or lower part of a block, depending on how they have been placed. This trapdoor can be opened or closed by hand or redstone power.") longdesc = S(
"Trapdoors are horizontal barriers which can be opened or closed and climbed like a ladder when open. They occupy the upper or lower part of a block, depending on how they have been placed. This trapdoor can be opened or closed by hand or redstone power.")
end end
end end
usagehelp = def._doc_items_usagehelp usagehelp = def._doc_items_usagehelp
if not usagehelp and not def.only_redstone_can_open then if not usagehelp and not def.only_redstone_can_open then
usagehelp = S("To open or close this trapdoor, rightclick it or send a redstone signal to it.") usagehelp = S("To open or close this trapdoor, rightclick it or send a redstone signal to it.")
end end
if def.only_redstone_can_open then if def.only_redstone_can_open then
tt_help = S("Openable by redstone power") tt_help = S("Openable by redstone power")
else else
tt_help = S("Openable by players and redstone power") tt_help = S("Openable by players and redstone power")
end end
-- Closed trapdoor -- Closed trapdoor
@ -128,7 +141,7 @@ function mcl_doors:register_trapdoor(name, def)
_doc_items_usagehelp = usagehelp, _doc_items_usagehelp = usagehelp,
drawtype = "nodebox", drawtype = "nodebox",
tiles = tiles_closed, tiles = tiles_closed,
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, use_texture_alpha = "clip",
inventory_image = def.inventory_image, inventory_image = def.inventory_image,
wield_image = def.wield_image, wield_image = def.wield_image,
is_ground_content = false, is_ground_content = false,
@ -143,13 +156,15 @@ function mcl_doors:register_trapdoor(name, def)
node_box = { node_box = {
type = "fixed", type = "fixed",
fixed = { fixed = {
{-8/16, -8/16, -8/16, 8/16, -5/16, 8/16},}, { -8 / 16, -8 / 16, -8 / 16, 8 / 16, -5 / 16, 8 / 16 }, },
},
mesecons = {
effector = {
action_on = (function(pos, node)
punch(pos)
end),
}
}, },
mesecons = {effector = {
action_on = (function(pos, node)
punch(pos)
end),
}},
on_place = function(itemstack, placer, pointed_thing) on_place = function(itemstack, placer, pointed_thing)
local p0 = pointed_thing.under local p0 = pointed_thing.under
local p1 = pointed_thing.above local p1 = pointed_thing.above
@ -164,7 +179,7 @@ function mcl_doors:register_trapdoor(name, def)
--local origname = itemstack:get_name() --local origname = itemstack:get_name()
if p0.y - 1 == p1.y or (fpos > 0 and fpos < 0.5) if p0.y - 1 == p1.y or (fpos > 0 and fpos < 0.5)
or (fpos < -0.5 and fpos > -0.999999999) then or (fpos < -0.5 and fpos > -0.999999999) then
param2 = param2 + 20 param2 = param2 + 20
if param2 == 21 then if param2 == 21 then
param2 = 23 param2 = 23
@ -193,16 +208,44 @@ function mcl_doors:register_trapdoor(name, def)
groups_open.trapdoor = 2 groups_open.trapdoor = 2
groups_open.not_in_creative_inventory = 1 groups_open.not_in_creative_inventory = 1
minetest.register_node(name.."_open", { -- Non-climbable opened
minetest.register_node(name .. "_open", {
drawtype = "nodebox", drawtype = "nodebox",
tiles = tiles_open, tiles = tiles_open,
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, use_texture_alpha = "clip",
is_ground_content = false,
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = true,
pointable = true,
groups = groups_open,
_mcl_hardness = def._mcl_hardness,
_mcl_blast_resistance = def._mcl_blast_resistance,
sounds = def.sounds,
drop = name,
node_box = {
type = "fixed",
fixed = { -0.5, -0.5, 5 / 16, 0.5, 0.5, 0.5 }
},
on_rightclick = on_rightclick,
mesecons = {
effector = {
action_off = (function(pos, node)
punch(pos)
end),
}
},
on_rotate = on_rotate,
})
-- Climbable opened
minetest.register_node(name .. "_ladder", {
drawtype = "nodebox",
tiles = tiles_open,
use_texture_alpha = "clip",
is_ground_content = false, is_ground_content = false,
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
-- TODO: Implement Minecraft behaviour: Climbable if directly above
-- ladder w/ matching orientation.
-- Current behavour: Always climbable
climbable = true, climbable = true,
sunlight_propagates = true, sunlight_propagates = true,
pointable = true, pointable = true,
@ -213,19 +256,20 @@ function mcl_doors:register_trapdoor(name, def)
drop = name, drop = name,
node_box = { node_box = {
type = "fixed", type = "fixed",
fixed = {-0.5, -0.5, 5/16, 0.5, 0.5, 0.5} fixed = { -0.5, -0.5, 5 / 16, 0.5, 0.5, 0.5 }
}, },
on_rightclick = on_rightclick, on_rightclick = on_rightclick,
mesecons = {effector = { mesecons = {
action_off = (function(pos, node) effector = {
punch(pos) action_off = (function(pos, node)
end), punch(pos)
}}, end),
}
},
on_rotate = on_rotate, on_rotate = on_rotate,
}) })
if minetest.get_modpath("doc") then if minetest.get_modpath("doc") then
doc.add_entry_alias("nodes", name, "nodes", name.."_open") doc.add_entry_alias("nodes", name, "nodes", name .. "_open")
end end
end end

@ -215,9 +215,23 @@ minetest.register_node("mcl_sculk:vein", {
type = "wallmounted", type = "wallmounted",
}, },
groups = { groups = {
handy = 1, axey = 1, shearsy = 1, swordy = 1, deco_block = 1, handy = 1,
dig_by_piston = 1, destroy_by_lava_flow = 1, sculk = 1, dig_by_water = 1, axey = 1,
shearsy = 1,
swordy = 1,
deco_block = 1,
dig_by_piston = 1,
destroy_by_lava_flow = 1,
sculk = 1,
dig_by_water = 1,
ladder = 1
}, },
after_destruct = function(pos, old)
mcl_core.update_trapdoor(pos, "destruct")
end,
after_place_node = function(pos)
mcl_core.update_trapdoor(pos, "place")
end,
sounds = sounds, sounds = sounds,
drop = "", drop = "",
_mcl_shears_drop = true, _mcl_shears_drop = true,