mirror of
https://git.minetest.land/VoxeLibre/VoxeLibre.git
synced 2024-12-23 16:39:33 +01:00
c03f9abd18
The old code takes the first return val of `minetest.item_place_node' which is `itemstack'. Therefore, the variable `success' in the old code is always true. The new code takes the second val which will be nil if an invalid node placement occured. This check is necessary since the ladder may be placed in the front of pointed block while there is a node with hole (slabs, fences etc.) at the same place resulting an invalid placement and sound played when it shouldn't be played.
245 lines
6.9 KiB
Lua
245 lines
6.9 KiB
Lua
-- Climbable nodes
|
|
local S = minetest.get_translator(minetest.get_current_modname())
|
|
|
|
local function rotate_climbable(pos, node, user, mode)
|
|
if mode == screwdriver.ROTATE_FACE then
|
|
local r = screwdriver.rotate.wallmounted(pos, node, mode)
|
|
node.param2 = r
|
|
minetest.swap_node(pos, node)
|
|
return true
|
|
end
|
|
return false
|
|
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", {
|
|
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."),
|
|
drawtype = "signlike",
|
|
is_ground_content = false,
|
|
tiles = { "default_ladder.png" },
|
|
inventory_image = "default_ladder.png",
|
|
wield_image = "default_ladder.png",
|
|
paramtype = "light",
|
|
sunlight_propagates = true,
|
|
paramtype2 = "wallmounted",
|
|
walkable = true,
|
|
climbable = true,
|
|
node_box = {
|
|
type = "wallmounted",
|
|
wall_side = { -0.5, -0.5, -0.5, -7 / 16, 0.5, 0.5 },
|
|
},
|
|
selection_box = {
|
|
type = "wallmounted",
|
|
wall_side = { -0.5, -0.5, -0.5, -7 / 16, 0.5, 0.5 },
|
|
},
|
|
stack_max = 64,
|
|
groups = {
|
|
handy = 1,
|
|
axey = 1,
|
|
attached_node = 1,
|
|
deco_block = 1,
|
|
dig_by_piston = 1,
|
|
ladder = 1
|
|
},
|
|
sounds = mcl_sounds.node_sound_wood_defaults(),
|
|
node_placement_prediction = "",
|
|
-- Restrict placement of ladders
|
|
on_place = function(itemstack, placer, pointed_thing)
|
|
if pointed_thing.type ~= "node" then
|
|
-- no interaction possible with entities
|
|
return itemstack
|
|
end
|
|
|
|
local under = pointed_thing.under
|
|
local node = minetest.get_node(under)
|
|
local def = minetest.registered_nodes[node.name]
|
|
if not def then
|
|
return itemstack
|
|
end
|
|
local groups = def.groups
|
|
|
|
-- Don't allow to place the ladder at non-solid nodes
|
|
if (groups and (not groups.solid)) then
|
|
return itemstack
|
|
end
|
|
|
|
-- Check special rightclick action of pointed node
|
|
if def and def.on_rightclick then
|
|
if not placer:get_player_control().sneak then
|
|
return def.on_rightclick(under, node, placer, itemstack,
|
|
pointed_thing) or itemstack, false
|
|
end
|
|
end
|
|
local above = pointed_thing.above
|
|
|
|
-- Ladders may not be placed on ceiling or floor
|
|
if under.y ~= above.y then
|
|
return itemstack
|
|
end
|
|
local idef = itemstack:get_definition()
|
|
local itemstack, pos = minetest.item_place_node(itemstack, placer, pointed_thing)
|
|
|
|
-- A non-nil pos indicates the node was placed in a valid position.
|
|
if pos then
|
|
if idef.sounds and idef.sounds.place then
|
|
minetest.sound_play(idef.sounds.place, { pos = above, gain = 1 }, true)
|
|
end
|
|
end
|
|
return itemstack
|
|
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_hardness = 0.4,
|
|
on_rotate = rotate_climbable,
|
|
})
|
|
|
|
|
|
minetest.register_node("mcl_core:vine", {
|
|
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."),
|
|
drawtype = "signlike",
|
|
tiles = { "mcl_core_vine.png" },
|
|
color = "#48B518",
|
|
inventory_image = "mcl_core_vine.png",
|
|
wield_image = "mcl_core_vine.png",
|
|
paramtype = "light",
|
|
sunlight_propagates = true,
|
|
paramtype2 = "colorwallmounted",
|
|
palette = "[combine:16x2:0,0=mcl_core_palette_foliage.png",
|
|
walkable = false,
|
|
climbable = true,
|
|
buildable_to = true,
|
|
selection_box = {
|
|
type = "wallmounted",
|
|
},
|
|
stack_max = 64,
|
|
groups = {
|
|
handy = 1,
|
|
axey = 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(),
|
|
drop = "",
|
|
_mcl_shears_drop = true,
|
|
node_placement_prediction = "",
|
|
-- Restrict placement of vines
|
|
on_place = function(itemstack, placer, pointed_thing)
|
|
if pointed_thing.type ~= "node" then
|
|
-- no interaction possible with entities
|
|
return itemstack
|
|
end
|
|
|
|
local under = pointed_thing.under
|
|
local node = minetest.get_node(under)
|
|
local def = minetest.registered_nodes[node.name]
|
|
if not def then return itemstack end
|
|
|
|
-- Check special rightclick action of pointed node
|
|
if def and def.on_rightclick then
|
|
if not placer:get_player_control().sneak then
|
|
return def.on_rightclick(under, node, placer, itemstack,
|
|
pointed_thing) or itemstack, false
|
|
end
|
|
end
|
|
|
|
-- Only place on full cubes
|
|
if not mcl_core.supports_vines(node.name) then
|
|
return itemstack
|
|
end
|
|
|
|
local above = pointed_thing.above
|
|
|
|
-- Vines may not be placed on top or below another block
|
|
if under.y ~= above.y then
|
|
return itemstack
|
|
end
|
|
local idef = itemstack:get_definition()
|
|
local itemstack, success = minetest.item_place_node(itemstack, placer, pointed_thing)
|
|
|
|
if success then
|
|
if idef.sounds and idef.sounds.place then
|
|
minetest.sound_play(idef.sounds.place, { pos = above, gain = 1 }, true)
|
|
end
|
|
end
|
|
return itemstack
|
|
end,
|
|
|
|
on_construct = function(pos)
|
|
local node = minetest.get_node(pos)
|
|
local foliage_palette_index = mcl_util.get_palette_indexes_from_pos(pos).foliage_palette_index
|
|
if node.name == "mcl_core:vine" then
|
|
local biome_param2 = foliage_palette_index
|
|
local rotation_param2 = node.param2
|
|
local final_param2 = (biome_param2 * 8) + rotation_param2
|
|
if node.param2 ~= final_param2 and rotation_param2 < 6 then
|
|
node.param2 = final_param2
|
|
minetest.swap_node(pos, node)
|
|
end
|
|
end
|
|
end,
|
|
|
|
-- If dug, also dig a “dependant” vine below it.
|
|
-- A vine is dependant if it hangs from this node and has no supporting block.
|
|
on_dig = function(pos, node, digger)
|
|
local below = vector.offset(pos, 0, -1, 0)
|
|
local belownode = minetest.get_node(below)
|
|
minetest.node_dig(pos, node, digger)
|
|
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)
|
|
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_hardness = 0.2,
|
|
on_rotate = false,
|
|
})
|