2017-07-07 16:52:28 +02:00
-- Climbable nodes
2021-05-29 16:12:33 +02:00
local S = minetest.get_translator ( minetest.get_current_modname ( ) )
2017-07-07 16:52:28 +02:00
2021-05-26 19:54:58 +02:00
local function rotate_climbable ( pos , node , user , mode )
2019-12-09 17:51:35 +01:00
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
2023-09-17 11:03:04 +02:00
---Checks the direction (param2) of a ladder and a trapdoor and determine if they are
---facing the same direction.
---
---@param ladder integer The param2 value of the ladder.
---@param trapdoor integer The param2 value of the trapdoor.
---@return boolean If the ladder and trapdoor are in the same direction.
2023-10-09 07:55:08 +02:00
function mcl_core . check_direction ( ladder , trapdoor )
local convert_table = {
{ 1 , 23 } ,
{ 3 , 21 } ,
{ 0 , 20 } ,
{ 2 , 22 } ,
}
2023-09-17 11:03:04 +02:00
2023-10-18 02:04:54 +02:00
local conversion = convert_table [ ladder - 1 ] ;
2023-10-09 07:55:08 +02:00
if not conversion then
2023-09-17 11:03:04 +02:00
return false
elseif conversion [ 1 ] == trapdoor or conversion [ 2 ] == trapdoor then
return true
end
return false
end
---Updates the trapdoor above (if any).
---
---@param pos mt.Vector The position of the ladder.
---@param ladder integer The param2 value of the ladder.
---@param event "place" | "destruct" The place or destruct event.
local function update_trapdoor ( pos , ladder , event )
2023-10-10 03:39:16 +02:00
local top_pos = vector.offset ( pos , 0 , 1 , 0 )
2023-09-17 11:03:04 +02:00
local top_node = minetest.get_node_or_nil ( top_pos )
2023-10-09 07:55:08 +02:00
if top_node and minetest.get_item_group ( top_node.name , " trapdoor " ) == 2
and mcl_core.check_direction ( ladder , top_node.param2 ) then
2023-09-17 11:03:04 +02:00
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
2023-10-09 07:55:08 +02:00
minetest.swap_node ( top_pos , {
name = new_name ,
param1 = top_node.param1 ,
param2 = top_node.param2 ,
} )
2023-09-17 11:03:04 +02:00
end
end
-- TODO: Move ladders into their own API.
2017-07-07 16:52:28 +02:00
minetest.register_node ( " mcl_core:ladder " , {
2019-03-07 23:40:43 +01:00
description = S ( " Ladder " ) ,
2023-10-09 07:55:08 +02:00
_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. " ) ,
2017-07-07 16:52:28 +02:00
drawtype = " signlike " ,
is_ground_content = false ,
2023-10-09 07:55:08 +02:00
tiles = { " default_ladder.png " } ,
2017-07-07 16:52:28 +02:00
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 " ,
2023-10-09 07:55:08 +02:00
wall_side = { - 0.5 , - 0.5 , - 0.5 , - 7 / 16 , 0.5 , 0.5 } ,
2017-07-07 16:52:28 +02:00
} ,
selection_box = {
type = " wallmounted " ,
2023-10-09 07:55:08 +02:00
wall_side = { - 0.5 , - 0.5 , - 0.5 , - 7 / 16 , 0.5 , 0.5 } ,
2017-07-07 16:52:28 +02:00
} ,
stack_max = 64 ,
2023-09-16 07:16:49 +02:00
groups = {
handy = 1 ,
axey = 1 ,
attached_node = 1 ,
deco_block = 1 ,
dig_by_piston = 1 ,
ladder = 1
} ,
2017-07-07 16:52:28 +02:00
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 particular nodes
if ( groups and ( groups.glass or groups.leaves or groups.slab ) ) or
2023-10-09 07:55:08 +02:00
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
2017-07-07 16:52:28 +02:00
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 success = minetest.item_place_node ( itemstack , placer , pointed_thing )
if success then
if idef.sounds and idef.sounds . place then
2023-10-09 07:55:08 +02:00
minetest.sound_play ( idef.sounds . place , { pos = above , gain = 1 } , true )
2017-07-07 16:52:28 +02:00
end
end
return itemstack
end ,
2023-09-17 11:03:04 +02:00
after_destruct = function ( pos , old )
update_trapdoor ( pos , old.param2 , " destruct " )
2023-09-16 07:16:49 +02:00
end ,
2023-09-17 11:03:04 +02:00
after_place_node = function ( pos )
local me = minetest.get_node ( pos )
update_trapdoor ( pos , me.param2 , " place " )
2023-09-16 07:16:49 +02:00
end ,
2020-04-15 13:27:29 +02:00
_mcl_blast_resistance = 0.4 ,
2017-07-07 16:52:28 +02:00
_mcl_hardness = 0.4 ,
2019-12-09 17:51:35 +01:00
on_rotate = rotate_climbable ,
2017-07-07 16:52:28 +02:00
} )
minetest.register_node ( " mcl_core:vine " , {
2019-03-07 23:40:43 +01:00
description = S ( " Vines " ) ,
2023-10-09 07:55:08 +02:00
_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. " ) ,
2017-07-07 16:52:28 +02:00
drawtype = " signlike " ,
2023-10-09 07:55:08 +02:00
tiles = { " mcl_core_vine.png " } ,
2023-02-08 17:11:38 +01:00
color = " #48B518 " ,
2017-07-07 16:52:28 +02:00
inventory_image = " mcl_core_vine.png " ,
wield_image = " mcl_core_vine.png " ,
paramtype = " light " ,
sunlight_propagates = true ,
2023-02-08 17:11:38 +01:00
paramtype2 = " colorwallmounted " ,
palette = " [combine:16x2:0,0=mcl_core_palette_foliage.png " ,
2017-07-07 16:52:28 +02:00
walkable = false ,
climbable = true ,
buildable_to = true ,
selection_box = {
type = " wallmounted " ,
} ,
stack_max = 64 ,
Add `compostability` to node definition group.
* mcl_cake/init.lua (cake);
* mcl_core/craftitems.lua (apple);
* mcl_core/nodes_base.lua (dirt with grass);
* mcl_core/nodes_cactuscane.lua (cactus, sugarcane);
* mcl_core/nodes_climb.lua (vines);
* mcl_core/nodes_trees.lua (leaves, saplings);
* mcl_dye/init.lua (cocoa beans);
* mcl_farming/beetroot.lua (beetroot, & seeds);
* mcl_farming/carrots.lua (carrot);
* mcl_farming/melon.lua (melon, & slice, & seeds);
* mcl_farming/potatoes.lua (potato, baked potato);
* mcl_farming/pumpkin.lua (pumpkin, carved &, & seeds, & pie);
* mcl_farming/wheat.lua (wheat, cookie, bread, hay block);
* mcl_flowers/init.lua (flowers, ferns, grass, & tall variants);
* mcl_mushrooms/small.lua (red and brown mushrooms);
* mcl_mushrooms/huge.lua (red and brown huge mushrooms);
* mcl_nether/init.lua (nether wart block);
* mcl_nether/nether_wart.lua (nether wart);
* mcl_ocean/kelp.lua (kelp, dried &, & block);
* mcl_ocean/sea_pickle.lua (sea pickle);
* mcl_ocean/seagrass.lua (seagrass).
2022-03-29 12:54:51 +02:00
groups = {
2023-10-09 07:55:08 +02:00
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
Add `compostability` to node definition group.
* mcl_cake/init.lua (cake);
* mcl_core/craftitems.lua (apple);
* mcl_core/nodes_base.lua (dirt with grass);
* mcl_core/nodes_cactuscane.lua (cactus, sugarcane);
* mcl_core/nodes_climb.lua (vines);
* mcl_core/nodes_trees.lua (leaves, saplings);
* mcl_dye/init.lua (cocoa beans);
* mcl_farming/beetroot.lua (beetroot, & seeds);
* mcl_farming/carrots.lua (carrot);
* mcl_farming/melon.lua (melon, & slice, & seeds);
* mcl_farming/potatoes.lua (potato, baked potato);
* mcl_farming/pumpkin.lua (pumpkin, carved &, & seeds, & pie);
* mcl_farming/wheat.lua (wheat, cookie, bread, hay block);
* mcl_flowers/init.lua (flowers, ferns, grass, & tall variants);
* mcl_mushrooms/small.lua (red and brown mushrooms);
* mcl_mushrooms/huge.lua (red and brown huge mushrooms);
* mcl_nether/init.lua (nether wart block);
* mcl_nether/nether_wart.lua (nether wart);
* mcl_ocean/kelp.lua (kelp, dried &, & block);
* mcl_ocean/sea_pickle.lua (sea pickle);
* mcl_ocean/seagrass.lua (seagrass).
2022-03-29 12:54:51 +02:00
} ,
2017-07-07 16:52:28 +02:00
sounds = mcl_sounds.node_sound_leaves_defaults ( ) ,
drop = " " ,
2017-08-03 02:27:55 +02:00
_mcl_shears_drop = true ,
2017-07-07 16:52:28 +02:00
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
2017-11-02 23:21:04 +01:00
return itemstack
2017-07-07 16:52:28 +02:00
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
2023-10-09 07:55:08 +02:00
minetest.sound_play ( idef.sounds . place , { pos = above , gain = 1 } , true )
2017-07-07 16:52:28 +02:00
end
end
return itemstack
end ,
2023-02-08 17:11:38 +01:00
on_construct = function ( pos )
2023-02-12 09:22:07 +01:00
local node = minetest.get_node ( pos )
2023-02-14 19:11:43 +01:00
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
2023-02-12 09:22:07 +01:00
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 )
2023-02-13 16:46:45 +01:00
end
2023-02-08 17:11:38 +01:00
end
2023-02-13 16:46:45 +01:00
end ,
2023-02-08 17:11:38 +01:00
2019-02-22 06:08:48 +01:00
-- If dug, also dig a “dependant” vine below it.
2017-08-12 04:11:07 +02:00
-- A vine is dependant if it hangs from this node and has no supporting block.
2019-02-22 06:08:48 +01:00
on_dig = function ( pos , node , digger )
2023-10-09 07:55:08 +02:00
local below = vector.offset ( pos , 0 , - 1 , 0 )
2017-08-12 04:11:07 +02:00
local belownode = minetest.get_node ( below )
2019-02-22 06:08:48 +01:00
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 )
2017-08-12 04:11:07 +02:00
end
end ,
2017-07-07 16:52:28 +02:00
2020-04-15 13:27:29 +02:00
_mcl_blast_resistance = 0.2 ,
2017-07-07 16:52:28 +02:00
_mcl_hardness = 0.2 ,
2019-12-09 17:51:35 +01:00
on_rotate = false ,
2017-07-07 16:52:28 +02:00
} )