improved dig_here indicator

This commit is contained in:
Sokomine 2017-05-28 23:54:09 +02:00
parent b2ec1adcf3
commit fd0c2a5534
2 changed files with 86 additions and 19 deletions

View File

@ -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
})

View File

@ -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 ));