added option for global replacements

master
Sokomine 2017-06-26 23:26:36 +02:00
parent 7e8c47032a
commit 782184f032
15 changed files with 138 additions and 82 deletions

View File

@ -93,12 +93,13 @@ handle_schematics.analyze_mts_file = function( path )
local name_text = file:read( name_length );
table.insert( nodenames, name_text );
local node_def = handle_schematics.node_defined( name_text );
-- in order to get this information, the node has to be defined and loaded
if( minetest.registered_nodes[ name_text ] and minetest.registered_nodes[ name_text ].on_construct) then
if( node_def and node_def.on_construct) then
table.insert( on_constr, name_text );
end
-- some nodes need after_place_node to be called for initialization
if( minetest.registered_nodes[ name_text ] and minetest.registered_nodes[ name_text ].after_place_node) then
if( node_def and node_def.after_place_node) then
table.insert( after_place_node, name_text );
end
end
@ -127,16 +128,9 @@ handle_schematics.analyze_mts_file = function( path )
local data_string = minetest.decompress(compressed_data, "deflate" );
file.close(file)
local ids = {};
local needs_on_constr = {};
-- find out which id air has in this particular schematic
local is_air = 0;
-- translate nodenames to ids
for i,v in ipairs( nodenames ) do
ids[ i ] = minetest.get_content_id( v );
needs_on_constr[ i ] = false;
if( minetest.registered_nodes[ v ] and minetest.registered_nodes[ v ].on_construct ) then
needs_on_constr[ i ] = true;
end
if( v == 'air' ) then
is_air = i;
end
@ -164,8 +158,7 @@ handle_schematics.analyze_mts_file = function( path )
if( id ~= is_air ) then
scm[y][x][z] = {id, p2};
-- id is a relative id; ids[id] contains the "real" content_id
if( handle_schematics.bed_content_ids[ ids[ id]]) then
if( handle_schematics.bed_node_names[ nodenames[ id ]]) then
bed_count = bed_count + 1;
end
end
@ -173,6 +166,7 @@ handle_schematics.analyze_mts_file = function( path )
end
end
--print( "MTS FILE "..tostring(path)..": "..tostring( bed_count ).." beds.");
return { size = { x=size.x, y=size.y, z=size.z}, nodenames = nodenames, on_constr = on_constr, after_place_node = after_place_node, rotated=rotated, burried=burried, scm_data_cache = scm, bed_count = bed_count };
end

View File

@ -1,6 +1,4 @@
handle_schematics.analyze_we_file = function(scm, we_origin)
local c_ignore = minetest.get_content_id("ignore")
-- this table will contain the nodes read
local nodes = {}

View File

@ -145,10 +145,10 @@ build_chest.replacements_get_list_formspec = function( pos, selected_row, allow_
end
formspec = formspec..'#fff,'..tostring( anz )..',';
if( name == repl and repl and minetest.registered_nodes[ repl ]) then
if( name == repl and handle_schematics.node_defined( repl )) then
formspec = formspec.."#0ff,,#fff,,";
else
if( name and minetest.registered_nodes[ name ] ) then
if( name and handle_schematics.node_defined( name )) then
formspec = formspec.."#0f0,"; -- green
else
formspec = formspec.."#ff0,"; -- yellow
@ -156,7 +156,7 @@ build_chest.replacements_get_list_formspec = function( pos, selected_row, allow_
formspec = formspec..name..',#fff,'..minetest.formspec_escape('-->')..',';
end
if( repl and (minetest.registered_nodes[ repl ] or repl=='air') ) then
if( handle_schematics.node_defined( repl ) or repl=='air') then
formspec = formspec.."#0f0,"..repl; -- green
else
formspec = formspec.."#ff0,?"; -- yellow
@ -232,14 +232,14 @@ build_chest.replacements_replace_rest_with_air = function( pos, meta )
if( r and r[1]==name ) then
repl = r[2];
-- set replacements for inexisting nodes to air
if( not( minetest.registered_nodes[ repl ] )) then
if( not( handle_schematics.node_defined( repl ))) then
r[2] = 'air';
end
end
end
-- replace nodes that do not exist with air
if( not( repl ) or not( minetest.registered_nodes[ repl ])) then
if( not( repl ) or not( handle_schematics.node_defined( repl ))) then
table.insert( replacements_orig, { name, 'air' });
end
end
@ -255,7 +255,7 @@ build_chest.replacements_apply = function( pos, meta, old_material, new_material
meta:set_int('replace_row', 0 );
local found = false;
-- only accept replacements which can actually be placed
if( new_material=='air' or minetest.registered_nodes[ new_material ] ) then
if( new_material=='air' or handle_schematics.node_defined( new_material )) then
local replacements_orig = build_chest.replacements_get_current( meta, village_id );
for i,v in ipairs(replacements_orig) do
if( v and v[1]==old_material ) then

View File

@ -5,7 +5,7 @@ build_chest.preview_image_draw_tile = function( content_id, image, x, z, dx, dz,
if( not( node_name )) then
return '';
end
local node_def = minetest.registered_nodes[ node_name ];
local node_def = handle_schematics.node_defined( node_name );
if( not( node_def )) then
return '';
end
@ -159,13 +159,13 @@ build_chest.preview_image_formspec = function( building_name, replacements, side
for j,w in ipairs( replacements ) do
if( w and w[1] and w[1]==v) then
found = true;
if( minetest.registered_nodes[ w[2]] ) then
if( handle_schematics.node_defined( w[2] )) then
content_ids[ i ] = minetest.get_content_id( w[2] );
end
end
end
if( not( found )) then
if( minetest.registered_nodes[ v ]) then
if( handle_schematics.node_defined( v )) then
content_ids[ i ] = minetest.get_content_id( v );
elseif( v ~= 'air' ) then
content_ids[ i ] = -1;

View File

@ -5,8 +5,8 @@ handle_schematics.also_acceptable = {};
handle_schematics.add_also_acceptable = function( name1, name2 )
-- only add entry if both nodes exist
if( not( name1 ) or not( name2 ) or name1==name2
or not( minetest.registered_nodes[ name1 ] )
or not( minetest.registered_nodes[ name2 ] )
or not( handle_schematics.node_defined( name1 ))
or not( handle_schematics.node_defined( name2 ))
or handle_schematics.direct_instead_of_drop[ name1 ]
or handle_schematics.direct_instead_of_drop[ name2 ]) then
return;
@ -70,7 +70,7 @@ handle_schematics.enable_doors_open_closed = function()
and type( v.drop )=='string'
and v.drop ~= k ) then
if( minetest.registered_nodes[ v.drop ]
if( handle_schematics.node_defined( v.drop )
-- stone and desert_stone need to be handled diffrently;
-- some dirt and grass types etc. are also handled
and not(handle_schematics.direct_instead_of_drop[ k ])) then

View File

@ -13,6 +13,19 @@ end
handle_schematics.modpath = minetest.get_modpath( "handle_schematics");
-- realtest handles some things diffrently without beeing easy to identify
handle_schematics.is_realtest = nil;
if( minetest.registered_nodes["oven:oven"]
and not( minetest.registered_nodes["default:furnace"])
and minetest.registered_nodes["grounds:clay"]
and not( minetest.registered_nodes["default:clay"])) then
handle_schematics.is_realtest = true;
end
-- globally change nodes from the schematics into others; useful if you
-- i.e. do not have default installed
dofile(handle_schematics.modpath.."/replacements_global.lua")
-- populate handle_schematics.bed_node_names and handle_schematics.bed_content_ids
dofile(handle_schematics.modpath.."/mob_bed_detection.lua")

View File

@ -10,7 +10,7 @@ handle_schematics.bed_node_names['beds:fancy_bed_top'] = 1;
-- content ids of nodes that are beds
handle_schematics.bed_content_ids = {};
for k,v in pairs( handle_schematics.bed_node_names ) do
if( minetest.registered_nodes[ k ] and minetest.get_content_id( k )>0) then
if( handle_schematics.node_defined( k ) and minetest.get_content_id( k )>0) then
handle_schematics.bed_content_ids[ minetest.get_content_id( k ) ] = 1;
end
end

View File

@ -84,11 +84,12 @@ handle_schematics.place_node_using_support_setup = function(pos, clicker, itemst
return itemstack;
end
-- give the player some feedback (might scroll a bit..)
local node_def = handle_schematics.node_defined( node_really_wanted );
if( clicker:is_player()
and minetest.registered_nodes[ node_really_wanted ]
and minetest.registered_nodes[ node_really_wanted ].description) then
and node_def
and node_def.description) then
minetest.chat_send_player( clicker:get_player_name(),
"Placed "..( minetest.registered_nodes[ node_really_wanted ].description or node_really_wanted)..".");
"Placed "..( node_def.description or node_really_wanted)..".");
end
-- take the item from the player (provided it actually is a player and not a mob)
if( clicker.get_inventory ) then
@ -114,12 +115,13 @@ handle_schematics.dig_node_using_dig_here_indicator = function(pos, clicker, ite
return itemstack;
end
local nodes_wanted = minetest.deserialize( nodes_wanted_str );
local cid_air = minetest.get_content_id("air");
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
if( node and node.name and node.name ~= "handle_schematics:support_setup") then
for j,v in ipairs( nodes_wanted ) do
-- get the entry at the right position
if( v and v[1] == p.y ) then
@ -127,16 +129,19 @@ handle_schematics.dig_node_using_dig_here_indicator = function(pos, clicker, ite
-- TODO: can mobs dig that way?
-- TODO: require suitable tools
-- TODO: tools ought to get dammaged a bit by digging
minetest.node_dig(p, node, clicker);
if( v[2] ~= minetest.get_content_id("air")) then
if( node.name ~= "air") then
minetest.node_dig(p, node, clicker);
-- 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
if( v[2] ~= cid_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
return itemstack;
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

View File

@ -26,7 +26,7 @@ end
-- "drop" moresnow snow on diffrent shapes; works for voxelmanip and node-based setting
handle_schematics.mg_drop_moresnow = function( x, z, y_top, y_bottom, a, data, param2_data)
handle_schematics.mg_drop_moresnow = function( x, z, y_top, y_bottom, a, data, param2_data, cid)
-- this only works if moresnow is installed
if( not( handle_schematics.moresnow_installed )) then
@ -45,15 +45,15 @@ handle_schematics.mg_drop_moresnow = function( x, z, y_top, y_bottom, a, data, p
and node_below.content ~= moresnow.c_air ) then
-- turn water into ice, but don't drop snow on it
if( node_below.content == minetest.get_content_id("default:water_source")
or node_below.content == minetest.get_content_id("default:river_water_source")) then
return { height = y, suggested = {new_id = minetest.get_content_id('default:ice'), param2 = 0 }};
if( node_below.content == cid.c_water_source
or node_below.content == cid.c_river_water_source) then
return { height = y, suggested = {new_id = cid.c_ice, param2 = 0 }};
end
-- if the node below drops snow when digged (i.e. is either snow or a moresnow node), we're finished
local get_drop = minetest.get_name_from_content_id( node_below.content );
if( get_drop ) then
get_drop = minetest.registered_nodes[ get_drop ];
get_drop = handle_schematics.node_defined( get_drop );
if( get_drop and get_drop.drop and type( get_drop.drop )=='string' and get_drop.drop == 'default:snow') then
return;
end
@ -138,21 +138,23 @@ handle_schematics.get_pos_in_front_of_house = function( pos, bed_nr )
local p = {x=pos.x, y=pos.y+1, z=pos.z, yaw = 0};
if( pos.o == 0 ) then
p.x = p.x - 1;
p.z = p.z + pos.bsizez - 1;
p.z = p.z - math.floor(pos.bsizex/2+0.5) - bed_nr;
p.z = p.z + pos.bsizez - 1 - bed_nr;
-- p.z = p.z - math.floor(pos.bsizex/2+0.5) - bed_nr;
p.yaw = 90;
elseif( pos.o == 2 ) then
p.x = p.x + pos.bsizex;
p.z = p.z + math.floor(pos.bsizex/2+0.5) + bed_nr;
-- p.z = p.z + math.floor(pos.bsizex/2+0.5) + bed_nr;
p.z = p.z + bed_nr;
p.yaw = 270;
elseif( pos.o == 1 ) then
p.z = p.z + pos.bsizez;
p.x = p.x + pos.bsizex - 1;
p.x = p.x - math.floor(pos.bsizez/2+0.5) - bed_nr;
p.x = p.x + pos.bsizex - 1 - bed_nr;
-- p.x = p.x - math.floor(pos.bsizez/2+0.5) - bed_nr;
p.yaw = 0;
elseif( pos.o == 3 ) then
p.z = p.z - 1;
p.x = p.x + math.floor(pos.bsizez/2+0.5) + bed_nr;
-- p.x = p.x + math.floor(pos.bsizez/2+0.5) + bed_nr;
p.x = p.x + bed_nr;
p.yaw = 180;
end
return p;
@ -230,9 +232,13 @@ local function generate_building_translate_nodenames( nodenames, replacements, c
end
-- only existing nodes can be placed
if( new_node_name and minetest.registered_nodes[ new_node_name ]) then
local regnode = minetest.registered_nodes[ new_node_name ];
local regnode = handle_schematics.node_defined( new_node_name );
if( new_node_name and regnode) then
-- apply global replacements
if( handle_schematics.global_replacement_table[ new_node_name ]) then
new_node_name = handle_schematics.global_replacement_table[ new_node_name ];
end
new_nodes[ i ].new_node_name = new_node_name;
new_nodes[ i ].new_content = minetest.get_content_id( new_node_name );
@ -296,7 +302,7 @@ local function generate_building_translate_nodenames( nodenames, replacements, c
-- handle_schematics.get_param2_rotated( 'facedir', param2 ) needs to be called for nodes
-- which use either facedir or wallmounted;
-- realtest rotates some nodes diffrently and does not come with default:ladder
if( node_name == 'default:ladder' and not( minetest.registered_nodes[ node_name ])) then
if( node_name == 'default:ladder' and handle_schematics.is_realtest) then
new_nodes[ i ].change_param2 = {}; --{ 2->1, 5->2, 3->3, 4->0 }
new_nodes[ i ].change_param2[2] = 1;
new_nodes[ i ].change_param2[5] = 2;
@ -496,6 +502,11 @@ local function generate_building(pos, minp, maxp, data, param2_data, a, extranod
local c_scaffolding = minetest.get_content_id( "handle_schematics:support_setup" );
local c_dig_here = minetest.get_content_id( "handle_schematics:dig_here" );
-- freeze water if there is moresnow on top
cid.c_water_source = minetest.get_content_id( "default:water_source");
cid.c_river_water_source = minetest.get_content_id( "default:river_water_source");
cid.c_ice = minetest.get_content_id( "default:ice");
local scm_x = 0;
local scm_z = 0;
local step_x = 1;
@ -776,7 +787,7 @@ local function generate_building(pos, minp, maxp, data, param2_data, a, extranod
y_bottom = minp.y;
end
if( has_snow and ax >= minp.x and ax <= maxp.x and az >= minp.z and az <= maxp.z ) then
local res = handle_schematics.mg_drop_moresnow( ax, az, y_top, y_bottom-1, a, data, param2_data);
local res = handle_schematics.mg_drop_moresnow( ax, az, y_top, y_bottom-1, a, data, param2_data, cid);
if( res and (data[ a:index(ax, res.height, az)]==cid.c_air
or data[ a:index(ax, res.height, az)]==cid.c_water )) then
data[ a:index(ax, res.height, az)] = res.suggested.new_id;
@ -975,17 +986,16 @@ 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
local node_def = handle_schematics.node_defined( node_name );
if( node_def and node_def.drop
-- the drop can be a craftitem
and minetest.registered_items[ node_def.drop ]
and not( handle_schematics.direct_instead_of_drop[ node_name ])) then
descr = minetest.registered_items[ node_def.drop ].description;
elseif( node_def and node_def.description ) then
descr = node_def.description;
else
descr = "- ? -";
end
local meta = minetest.get_meta( v );
@ -1065,9 +1075,10 @@ handle_schematics.place_building_from_file = function( start_pos, end_pos, build
-- trees, chests and signs receive no special treatment here
for k, v in pairs( res.extra_calls.on_constr ) do
local node_name = minetest.get_name_from_content_id( k );
if( minetest.registered_nodes[ node_name ].on_construct ) then
local node_def = handle_schematics.node_defined( node_name );
if( node_def and node_def.on_construct ) then
for _, pos in ipairs(v) do
minetest.registered_nodes[ node_name ].on_construct( pos );
node_def.on_construct( pos );
end
end
end

View File

@ -1,4 +1,3 @@
-- if the player builds a house manually, there are some nodes the players cannot
-- supply as the nodes are not obtainable (only their drop) - thus, in most cases,
-- the drop is what we ask for; except for these nodes where the origianl node
@ -45,12 +44,13 @@ handle_schematics.get_what_player_can_provide = function( node_wanted )
-- some nodes like i.e. dirt with grass or stone with coal cannot be obtained;
-- in such a case we ask for the drop; this is also useful for doors etc.
if( minetest.registered_nodes[ node_wanted ]
local node_def = handle_schematics.node_defined( node_wanted );
if( node_def
-- provided the drop actually exists
and minetest.registered_nodes[ node_wanted ].drop
and minetest.registered_items[ minetest.registered_nodes[ node_wanted ].drop ]) then
and node_def.drop
and minetest.registered_items[ node_def.drop ]) then
return minetest.registered_nodes[ node_wanted ].drop;
return node_def.drop;
end
-- the player ought to be able to come up with this node (or we need to define more exceptions)

View File

@ -24,7 +24,7 @@ replacements_group['discontinued_nodes'].replace = function( replacements )
replacements_group['discontinued_nodes'].doors( repl, 'obsidian_glass');
for i,v in ipairs( repl ) do
if( v and v[2] and minetest.registered_nodes[ v[2]] ) then
if( v and v[2] and handle_schematics.node_defined( v[2]) ) then
local found = false;
for j,w in ipairs( replacements ) do
if( w and w[1] and w[1]==v[1] ) then

View File

@ -26,7 +26,7 @@ replacements_group['farming'].replace_material = function( replacements, old_mat
for i=1,#old_nodes do
local old = old_nodes[i];
local new = old;
if( i<=#new_nodes and new_nodes[i] and minetest.registered_nodes[ new_nodes[i]] ) then
if( i<=#new_nodes and new_nodes[i] and handle_schematics.node_defined( new_nodes[i]) ) then
new = new_nodes[i];
local found = false;
for i,v in ipairs(replacements) do
@ -39,7 +39,7 @@ replacements_group['farming'].replace_material = function( replacements, old_mat
table.insert( replacements, { old, new });
end
-- default to the last growth stage
elseif( i>#new_nodes and minetest.registered_nodes[ new_nodes[ #new_nodes ]]) then
elseif( i>#new_nodes and handle_schematics.node_defined( new_nodes[ #new_nodes ])) then
table.insert( replacements, { old, new_nodes[ #new_nodes ] });
end
end
@ -54,7 +54,7 @@ replacements_group['farming'].add_material = function( fruit, fruit_item, prefix
local is_loaded = false;
if( minetest.registered_items[ fruit_item ]
and minetest.registered_nodes[ prefix..fruit..seperator.."1"..postfix ] ) then
and handle_schematics.node_defined( prefix..fruit..seperator.."1"..postfix ) ) then
is_loaded = true;
table.insert( replacements_group['farming'].found, fruit_item );
end
@ -71,7 +71,7 @@ replacements_group['farming'].add_material = function( fruit, fruit_item, prefix
end
for i=1,8 do
local node_name = prefix..fruit..seperator..tostring(i)..postfix;
if( is_loaded and minetest.registered_nodes[ node_name ]) then
if( is_loaded and handle_schematics.node_defined( node_name) ) then
table.insert( data, node_name );
-- if the mod is not loaded, we do not know how many growth stages it has;
-- in order to be on the safe side, store them all
@ -81,7 +81,7 @@ replacements_group['farming'].add_material = function( fruit, fruit_item, prefix
end
-- the last plant stage (the one that gives the fruit) usually has no number
local node_name = prefix..fruit;
if( is_loaded and minetest.registered_nodes[ node_name ]) then
if( is_loaded and handle_schematics.node_defined( node_name)) then
table.insert( data, node_name );
elseif( not( is_loaded )) then
table.insert( data, node_name );
@ -151,9 +151,9 @@ replacements_group['farming'].construct_farming_type_list = function()
'tomato', 'corn'
};
for i,fruit in ipairs( fruits ) do
if( minetest.registered_nodes[ 'farming_plus:'..fruit ]
and minetest.registered_nodes[ 'farming_plus:'..fruit..'_1' ]
and minetest.registered_items[ 'farming_plus:'..fruit..'_item' ] ) then
if( handle_schematics.node_defined( 'farming_plus:'..fruit )
and handle_schematics.node_defined( 'farming_plus:'..fruit..'_1' )
and handle_schematics.node_defined( 'farming_plus:'..fruit..'_item' )) then
replacements_group['farming'].add_material( fruit, 'farming_plus:'..fruit..'_item', 'farming_plus:', '_', '' );
end
end

35
replacements_global.lua Normal file
View File

@ -0,0 +1,35 @@
-- Note: If you are using handle_schematics.global_replacement_table, please also take into
-- account that you might have to add nodes to other tables, in particular:
-- * handle_schematics.direct_instead_of_drop
-- * handle_schematics.player_can_provide
-- * handle_schematics.bed_node_namess
-- * call handle_schematics.add_mirrored_node_type(..) where needed
-- allows to store global replacements (needed for subgames that do not provide a default mod)
handle_schematics.global_replacement_table = {};
handle_schematics.replace_global = function( node_name )
if( not( node_name )) then
return;
end
if( handle_schematics.global_replacement_table[ node_name ] ) then
return handle_schematics.global_replacement_table[ node_name ];
end
return node_name;
end
handle_schematics.node_defined = function( node_name )
if( not( node_name ) or node_name == "" ) then
return;
end
if( handle_schematics.global_replacement_table[ node_name ] ) then
return minetest.registered_nodes[ handle_schematics.global_replacement_table[ node_name ]];
end
return minetest.registered_nodes[ node_name ];
end
-- just some examples for testing:
--handle_schematics.global_replacement_table[ 'default:wood' ] = 'default:mese';
--handle_schematics.global_replacement_table[ 'stairs:stair_wood' ] = 'default:diamondblock';

View File

@ -23,7 +23,7 @@ replacements_group['roof'].replace_material = function( replacements, old_materi
for i=1,#old_nodes do
local old = old_nodes[i];
local new = old;
if( i<=#new_nodes and new_nodes[i] and minetest.registered_nodes[ new_nodes[i]] ) then
if( i<=#new_nodes and new_nodes[i] and handle_schematics.node_defined( new_nodes[i] )) then
new = new_nodes[i];
local found = false;
for i,v in ipairs(replacements) do
@ -47,7 +47,7 @@ end
replacements_group['roof'].add_material = function( nodelist )
local is_loaded = false;
if( minetest.registered_items[ nodelist[1] ] ) then
if( handle_schematics.node_defined( nodelist[1] )) then
is_loaded = true;
table.insert( replacements_group['roof'].found, nodelist[1] );
end

View File

@ -30,7 +30,7 @@ replacements_group['wood'].replace_material = function( replacements, old_wood,
for i=3,#old_nodes do
local old = old_nodes[i];
local new = old;
if( i<=#new_nodes and new_nodes[i] and minetest.registered_nodes[ new_nodes[i]] ) then
if( i<=#new_nodes and new_nodes[i] and handle_schematics.node_defined( new_nodes[i])) then
new = new_nodes[i];
local found = false;
for i,v in ipairs(replacements) do
@ -65,7 +65,7 @@ replacements_group['wood'].add_material = function( candidate_list, mod_prefix,
-- create a complete list of all possible wood names
table.insert( replacements_group['wood'].all, wood_name );
-- create a list of all *installed* wood types
if( minetest.registered_nodes[ wood_name ]) then
if( handle_schematics.node_defined( wood_name )) then
table.insert( replacements_group['wood'].found, wood_name );
is_loaded = true;
end