diff --git a/build_chest.lua b/build_chest.lua index 8fe918f..d1b62af 100644 --- a/build_chest.lua +++ b/build_chest.lua @@ -116,7 +116,8 @@ build_chest.get_start_pos = function( pos ) -- save the data for later removal/improvement of the building in the chest meta:set_string( 'start_pos', minetest.serialize( param2_rotated.start_pos )); - meta:set_string( 'end_pos', minetest.serialize( param2_rotated.end_pos )); + -- one higher so that there is place for "dig here" indicators + meta:set_string( 'end_pos', minetest.serialize( {x=param2_rotated.end_pos.x, y=param2_rotated.end_pos.y+1, z=param2_rotated.end_pos.z} )); meta:set_string( 'rotate', tostring(param2_rotated.rotate )); meta:set_int( 'mirror', mirror ); -- no replacements yet @@ -571,7 +572,7 @@ build_chest.on_receive_fields = function(pos, formname, fields, player) local building_name = meta:get_string('building_name' ); -- the statistic is needed for all the replacements later on as it also contains the list of nodenames - if( building_name and building_name~="" and not( build_chest.building[ building_name ].size )) then + if( building_name and building_name~="" and (not( build_chest.building[ building_name ]) or not( build_chest.building[ building_name ].size ))) then build_chest.read_building( building_name ); end @@ -673,7 +674,6 @@ build_chest.on_receive_fields = function(pos, formname, fields, player) minetest.chat_send_player( pname, 'CREATING backup schematic for this place in \"schems/'..base_filename..'.mts\".'); end --- TODO: use scaffolding here (exchange some replacements) local replacement_list = build_chest.replacements_get_current( meta, village_id ); local rotate = meta:get_string('rotate'); local mirror = meta:get_string('mirror'); @@ -682,7 +682,13 @@ build_chest.on_receive_fields = function(pos, formname, fields, player) -- actually place the building --minetest.place_schematic( start_pos, building_name..'.mts', rotate, replacement_list, true ); mirror = nil; - fields.error_msg = handle_schematics.place_building_from_file( start_pos, end_pos, building_name, replacement_list, rotate, axis, mirror, no_plotmarker, false ); + + -- players who do not have the creative priv cannot produce nodes out of thin air + local use_scaffolding = false; + if( not( minetest.check_player_privs( pname, {creative=true}))) then + use_scaffolding = true; + end + fields.error_msg = handle_schematics.place_building_from_file( start_pos, end_pos, building_name, replacement_list, rotate, axis, mirror, no_plotmarker, false, use_scaffolding ); if( fields.error_msg ) then fields.error_msg = 'Error: '..tostring( fields.error_msg ); end diff --git a/place_buildings.lua b/place_buildings.lua index 32b6968..bcb5aa5 100644 --- a/place_buildings.lua +++ b/place_buildings.lua @@ -270,7 +270,7 @@ local function generate_building_translate_nodenames( nodenames, replacements, c end -local function generate_building(pos, minp, maxp, data, param2_data, a, extranodes, replacements, cid, extra_calls, building_nr_in_bpos, village_id, binfo_extra, road_node, keep_ground) +local function generate_building(pos, minp, maxp, data, param2_data, a, extranodes, replacements, cid, extra_calls, building_nr_in_bpos, village_id, binfo_extra, road_node, keep_ground, scaffolding_only) local binfo = binfo_extra; if( not( binfo ) and mg_villages) then @@ -338,6 +338,9 @@ local function generate_building(pos, minp, maxp, data, param2_data, a, extranod local c_dirt_with_grass = minetest.get_content_id( "default:dirt_with_grass" ); local c_dirt_with_snow = minetest.get_content_id( "default:dirt_with_snow" ); + local c_scaffolding = minetest.get_content_id( "handle_schematics:support" ); + local c_dig_here = minetest.get_content_id( "handle_schematics:dig_here" ); + local scm_x = 0; local scm_z = 0; local step_x = 1; @@ -428,7 +431,6 @@ local function generate_building(pos, minp, maxp, data, param2_data, a, extranod local new_content = c_air; local t = scm[y+1][xoff][zoff]; - local node_content = data[a:index(ax, ay, az)]; if( binfo.yoff+y == 0 ) then -- no snow on the gravel roads if( node_content == c_dirt_with_snow or data[a:index(ax, ay+1, az)]==c_snow) then @@ -438,7 +440,30 @@ local function generate_building(pos, minp, maxp, data, param2_data, a, extranod ground_type = node_content; end - if( not( t )) then + -- scaffolding nodes are only placed when there is air and there ought to be some node + if( scaffolding_only ) then + local current_content = data[a:index(ax, ay, az)]; + + -- there is air there right now, but there ought to be a node from the building + if( current_content == cid.c_air and t) then + data[ a:index(ax, ay, az)] = c_scaffolding; + + -- we have the wrong node there + elseif( ((not(t) and current_content ~= cid.c_air) + or (t and new_nodes[t[1]] and not(new_nodes[t[1]].ignore) and current_content ~= new_nodes[ t[1]].new_content)) + -- TODO: detect wrong rotation (param2) + + and current_content ~= c_scaffolding + and current_content ~= c_dig_here + and ay place dirt nodes instead of trying to keep the ground nodes - generate_building(pos, minp, maxp, data, param2_data, a, extranodes, replacements, cid, extra_calls, pos.building_nr, pos.village_id, binfo, cid.c_gravel, keep_ground); + generate_building(pos, minp, maxp, data, param2_data, a, extranodes, replacements, cid, extra_calls, pos.building_nr, pos.village_id, binfo, cid.c_gravel, keep_ground, scaffolding_only); -- store the changed map data vm:set_data(data); @@ -718,7 +747,7 @@ 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 ) +handle_schematics.place_building_from_file = function( start_pos, end_pos, building_name, replacement_list, rotate, axis, mirror, no_plotmarker, keep_ground, scaffolding_only ) if( not( building_name )) then return "No file name given. Cannot find the schematic."; end @@ -768,7 +797,7 @@ handle_schematics.place_building_from_file = function( start_pos, end_pos, build start_pos.no_plotmarker = no_plotmarker; -- all those calls to on_construct need to be done now - local res = handle_schematics.place_building_using_voxelmanip( start_pos, binfo, replacement_list, keep_ground); + local res = handle_schematics.place_building_using_voxelmanip( start_pos, binfo, replacement_list, keep_ground, scaffolding_only); if( not(res) or not( res.extra_calls )) then return; end