diff --git a/nodes.lua b/nodes.lua index ad890ef..adad455 100644 --- a/nodes.lua +++ b/nodes.lua @@ -100,6 +100,51 @@ handle_schematics.place_node_using_support_setup = function(pos, node, clicker, end +-- right-clicking a dig_here-indicator ought to dig the next node below it that needs digging and place appropriate scaffolding +handle_schematics.dig_node_indicator_clicked = function(pos, node, clicker, itemstack, pointed_thing ) + if not( default.can_interact_with_node(clicker, pos)) then + return itemstack; + end + + local meta = minetest.get_meta( pos ); + local nodes_wanted_str = meta:get_string( "node_wanted_down_there"); + if( not( nodes_wanted_str )) then + return itemstack; + end + local nodes_wanted = minetest.deserialize( nodes_wanted_str ); + + for i=1,table.getn( nodes_wanted ) do + local p = {x=pos.x, y=pos.y-i, z=pos.z}; + local node = minetest.get_node( p ); + -- found a node that is not yet scaffolding + if( node and node.name and (node.name ~= "handle_schematics:support_setup" and node.name ~= "air")) then + for j,v in ipairs( nodes_wanted ) do + -- get the entry at the right position + if( v and v[1] == p.y ) then + -- dig the old node and add it to the inventory + minetest.node_dig(p, node, clicker); + if( v[2] ~= minetest.get_content_id("air")) then + -- place the scaffolding node + minetest.set_node( p, {name="handle_schematics:support_setup"}); + -- configure the scaffolding node + handle_schematics.setup_scaffolding( { x=p.x, y=p.y, z=p.z, node_wanted=v[2], param2_wanted=v[3] }); + -- we are done + end + -- TODO: if the digged node is the first that is to go into this itemstack it won't end up in the player's inventory + return itemstack; + end + end + end + end + + -- we are done; the dig_here-indicator can be removed + minetest.set_node( pos, {name="air"}); + return itemstack; +end + + + + -- this node will only be placed by spawning a house with handle_schematics minetest.register_node("handle_schematics:support_setup", { description = "support structure for buildings (configured)", @@ -141,5 +186,8 @@ minetest.register_node("handle_schematics:dig_here", { type = "fixed", fixed = {-2 / 16, -0.5, -2 / 16, 2 / 16, 6 / 16, 2 / 16} }, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + handle_schematics.dig_node_indicator_clicked(pos, node, clicker, itemstack, pointed_thing ); + end }) diff --git a/place_buildings.lua b/place_buildings.lua index 7c964f1..3d21b42 100644 --- a/place_buildings.lua +++ b/place_buildings.lua @@ -618,7 +618,14 @@ local function generate_building(pos, minp, maxp, data, param2_data, a, extranod local node_here = data[ a:index(ax, h, az)]; if( node_here == cid.c_air or node_here == c_dig_here or node_here == c_scaffolding or node_here == c_scaffolding_empty ) then if( data[ a:index(ax, h, az)] ~= c_dig_here ) then - table.insert( extra_calls.scaffolding, {x=ax, y=h, z=az, dig_down = h-ay}); + table.insert( extra_calls.scaffolding, {x=ax, y=h, z=az, dig_down = h-ay, what_where = {{ ay, new_content, param2}}}); + else + -- store which node needs to be placed at which height + for i,v in ipairs( extra_calls.scaffolding ) do + if( v.x==ax and v.y==h and v.z==az ) then + table.insert( v.what_where, { ay, new_content, param2}); + end + end end data[ a:index(ax, h, az)] = c_dig_here; -- how much is to be digged is counted later on (when evaluating extra_calls.scaffolding) @@ -904,6 +911,32 @@ end +-- helper function for handle_schematics.place_building_from_file; also used +-- when digging below a dig_here indicator +handle_schematics.setup_scaffolding = function( v ) + + local node_name = minetest.get_name_from_content_id(v.node_wanted); + local descr = tostring(node_name); + if( node_name and minetest.registered_nodes[ node_name ] ) then + if( minetest.registered_nodes[ node_name ].drop + -- the drop can be a craftitem + and minetest.registered_items[ minetest.registered_nodes[ node_name ].drop ] + and not( handle_schematics.direct_instead_of_drop[ node_name ])) then + descr = minetest.registered_items[ minetest.registered_nodes[ node_name ].drop ].description; + elseif( minetest.registered_nodes[ node_name ].description ) then + descr = minetest.registered_nodes[ node_name ].description; + else + descr = "- ? -"; + end + end + + local meta = minetest.get_meta( v ); + meta:set_string( "node_wanted", node_name ); + meta:set_int( "param2_wanted", v.param2_wanted ); + meta:set_string( "infotext", "Needed: "..descr ); +end + + -- places a building read from file "building_name" on the map between start_pos and end_pos using luavoxelmanip -- returns error message on failure and nil on success handle_schematics.place_building_from_file = function( start_pos, end_pos, building_name, replacement_list, rotate, axis, mirror, no_plotmarker, keep_ground, scaffolding_only, plotmarker_pos ) @@ -1013,25 +1046,8 @@ handle_schematics.place_building_from_file = function( start_pos, end_pos, build for k, v in pairs( res.extra_calls.scaffolding ) do if( v.node_wanted) then - local node_name = minetest.get_name_from_content_id(v.node_wanted); - local descr = tostring(node_name); - if( node_name and minetest.registered_nodes[ node_name ] ) then - if( minetest.registered_nodes[ node_name ].drop - -- the drop can be a craftitem - and minetest.registered_items[ minetest.registered_nodes[ node_name ].drop ] - and not( handle_schematics.direct_instead_of_drop[ node_name ])) then - descr = minetest.registered_items[ minetest.registered_nodes[ node_name ].drop ].description; - elseif( minetest.registered_nodes[ node_name ].description ) then - descr = minetest.registered_nodes[ node_name ].description; - else - descr = "- ? -"; - end - end + handle_schematics.setup_scaffolding( v ); - local meta = minetest.get_meta( v ); - meta:set_string( "node_wanted", node_name ); - meta:set_int( "param2_wanted", v.param2_wanted ); - meta:set_string( "infotext", "Needed: "..descr ); elseif( v.dig_down ) then local meta = minetest.get_meta( v ); if( v.dig_down > 1 ) then @@ -1039,6 +1055,9 @@ handle_schematics.place_building_from_file = function( start_pos, end_pos, build else meta:set_string( "infotext", "Dig the block below."); end + meta:set_string( "dig_down", v.dig_down ); + -- structure of what_where = { pos_y, new_content, param2}} + meta:set_string( "node_wanted_down_there", minetest.serialize( v.what_where )); -- store the position of the build chest so that npc can locate it more easily if( plotmarker_pos ) then meta:set_string( "chest_pos", minetest.pos_to_string( plotmarker_pos, 0 ));