2017-10-23 03:50:11 +02:00
-- internationalization boilerplate
local MP = minetest.get_modpath ( minetest.get_current_modname ( ) )
local S , NS = dofile ( MP .. " /intllib.lua " )
2022-03-22 22:13:47 +01:00
local inventory_formspec_string =
2017-10-23 03:50:11 +02:00
" size[9,9.3] " ..
default.gui_bg ..
default.gui_bg_img ..
default.gui_slots ..
" label[0,0; " .. S ( " Digtron components " ) .. " ] " ..
" list[current_name;main;0,0.6;8,4;] " ..
" list[current_player;main;0,5.15;8,1;] " ..
" list[current_player;main;0,6.38;8,3;8] " ..
" listring[current_name;main] " ..
" listring[current_player;main] " ..
default.get_hotbar_bg ( 0 , 5.15 ) ..
" button_exit[8,3.5;1,1;duplicate; " .. S ( " Duplicate " ) .. " ] " ..
" tooltip[duplicate; " .. S ( " Puts a copy of the adjacent Digtron into an empty crate \n located at the output side of the duplicator, \n using components from the duplicator's inventory. " ) .. " ] "
if minetest.get_modpath ( " doc " ) then
inventory_formspec_string = inventory_formspec_string ..
" button_exit[8,4.5;1,1;help; " .. S ( " Help " ) .. " ] " ..
" tooltip[help; " .. S ( " Show documentation about this block " ) .. " ] "
end
2022-03-22 22:13:47 +01:00
2017-10-23 03:50:11 +02:00
minetest.register_node ( " digtron:duplicator " , {
description = S ( " Digtron Duplicator " ) ,
_doc_items_longdesc = digtron.doc . duplicator_longdesc ,
_doc_items_usagehelp = digtron.doc . duplicator_usagehelp ,
groups = { cracky = 3 , oddly_breakable_by_hand = 3 } ,
sounds = digtron.metal_sounds ,
tiles = { " digtron_plate.png^(digtron_axel_side.png^[transformR90) " ,
" digtron_plate.png^(digtron_axel_side.png^[transformR270) " ,
" digtron_plate.png^digtron_axel_side.png " ,
" digtron_plate.png^(digtron_axel_side.png^[transformR180) " ,
" digtron_plate.png^digtron_builder.png " ,
" digtron_plate.png " ,
} ,
paramtype = " light " ,
paramtype2 = " facedir " ,
2022-03-22 22:13:47 +01:00
is_ground_content = false ,
2017-10-23 03:50:11 +02:00
drawtype = " nodebox " ,
node_box = {
type = " fixed " ,
fixed = {
{ - 0.5 , 0.3125 , 0.3125 , 0.5 , 0.5 , 0.5 } , -- FrontFrame_top
{ - 0.5 , - 0.5 , 0.3125 , 0.5 , - 0.3125 , 0.5 } , -- FrontFrame_bottom
{ 0.3125 , - 0.3125 , 0.3125 , 0.5 , 0.3125 , 0.5 } , -- FrontFrame_right
{ - 0.5 , - 0.3125 , 0.3125 , - 0.3125 , 0.3125 , 0.5 } , -- FrontFrame_left
{ - 0.0625 , - 0.3125 , 0.3125 , 0.0625 , 0.3125 , 0.375 } , -- frontcross_vertical
{ - 0.3125 , - 0.0625 , 0.3125 , 0.3125 , 0.0625 , 0.375 } , -- frontcross_horizontal
{ - 0.4375 , - 0.4375 , - 0.4375 , 0.4375 , 0.4375 , 0.3125 } , -- Body
{ - 0.5 , - 0.3125 , - 0.5 , - 0.3125 , 0.3125 , - 0.3125 } , -- backframe_vertical
{ 0.3125 , - 0.3125 , - 0.5 , 0.5 , 0.3125 , - 0.3125 } , -- backframe_left
{ - 0.5 , 0.3125 , - 0.5 , 0.5 , 0.5 , - 0.3125 } , -- backframe_top
{ - 0.5 , - 0.5 , - 0.5 , 0.5 , - 0.3125 , - 0.3125 } , -- backframe_bottom
{ - 0.0625 , - 0.0625 , - 0.5625 , 0.0625 , 0.0625 , - 0.4375 } , -- back_probe
} ,
} ,
selection_box = {
type = " regular "
} ,
2022-03-22 22:13:47 +01:00
2017-10-23 03:50:11 +02:00
on_construct = function ( pos )
local meta = minetest.get_meta ( pos )
meta : set_string ( " formspec " , inventory_formspec_string )
local inv = meta : get_inventory ( )
inv : set_size ( " main " , 8 * 4 )
end ,
2022-03-22 22:13:47 +01:00
2017-10-23 03:50:11 +02:00
can_dig = function ( pos , player )
local meta = minetest.get_meta ( pos )
local inv = meta : get_inventory ( )
return inv : is_empty ( " main " )
end ,
2022-03-22 22:13:47 +01:00
2017-10-23 03:50:11 +02:00
allow_metadata_inventory_put = function ( pos , listname , index , stack , player )
if minetest.get_item_group ( stack : get_name ( ) , " digtron " ) > 0 then
return stack : get_count ( )
else
return 0
end
end ,
2022-03-22 22:13:47 +01:00
2017-10-23 03:50:11 +02:00
on_receive_fields = function ( pos , formname , fields , sender )
2022-03-22 22:13:47 +01:00
local player_name = sender : get_player_name ( )
2017-10-23 03:50:11 +02:00
if fields.help then
2022-03-22 22:13:47 +01:00
minetest.after ( 0.5 , doc.show_entry , player_name , " nodes " , " digtron:duplicator " , true )
return
2017-10-23 03:50:11 +02:00
end
2022-03-22 22:13:47 +01:00
2017-10-23 03:50:11 +02:00
if fields.duplicate then
local node = minetest.get_node ( pos )
local meta = minetest.get_meta ( pos )
local inv = meta : get_inventory ( )
local target_pos = vector.add ( pos , minetest.facedir_to_dir ( node.param2 ) )
local target_node = minetest.get_node ( target_pos )
2022-03-22 22:13:47 +01:00
local target_name
2017-10-23 03:50:11 +02:00
2022-03-22 22:13:47 +01:00
if target_node.name == " digtron:empty_crate " then
target_name = " digtron:loaded_crate "
elseif target_node.name == " digtron:empty_locked_crate " then
if minetest.get_meta ( target_pos ) : get_string ( " owner " ) ~= player_name then
minetest.sound_play ( " buzzer " , { gain = 0.5 , pos = pos } )
meta : set_string ( " infotext " , S ( " The empty locked crate needs to be owned by you. " ) )
return
end
target_name = " digtron:loaded_locked_crate "
end
if not target_name then
2017-10-23 03:50:11 +02:00
minetest.sound_play ( " buzzer " , { gain = 0.5 , pos = pos } )
meta : set_string ( " infotext " , S ( " Needs an empty crate in output position to store duplicate " ) )
return
end
2022-03-22 22:13:47 +01:00
2023-05-24 08:09:42 +02:00
local layout = digtron.DigtronLayout . create ( pos , sender )
2022-03-22 22:13:47 +01:00
2017-10-23 03:50:11 +02:00
if layout.contains_protected_node then
minetest.sound_play ( " buzzer " , { gain = 0.5 , pos = pos } )
meta : set_string ( " infotext " , S ( " Digtron can't be duplicated, it contains protected blocks " ) )
return
end
2022-03-22 22:13:47 +01:00
2017-10-23 03:50:11 +02:00
if # layout.all == 1 then
minetest.sound_play ( " buzzer " , { gain = 0.5 , pos = pos } )
meta : set_string ( " infotext " , S ( " No Digtron components adjacent to duplicate " ) )
return
end
2022-03-22 22:13:47 +01:00
layout.all [ 1 ] = { node = { name = target_node.name } , meta = { fields = { } , inventory = { } } , pos = { x = pos.x , y = pos.y , z = pos.z } } -- replace the duplicator's image with the empty crate image
2017-10-23 03:50:11 +02:00
-- count required nodes, skipping node 1 since it's the crate and we already know it's present in-world
local required_count = { }
for i = 2 , # layout.all do
local nodename = layout.all [ i ] . node.name
required_count [ nodename ] = ( required_count [ nodename ] or 0 ) + 1
end
2022-03-22 22:13:47 +01:00
2017-10-23 03:50:11 +02:00
-- check that there's enough in the duplicator's inventory
local unsatisfied = { }
for name , count in pairs ( required_count ) do
if not inv : contains_item ( " main " , ItemStack ( { name = name , count = count } ) ) then
table.insert ( unsatisfied , tostring ( count ) .. " " .. minetest.registered_nodes [ name ] . description )
end
2022-03-22 22:13:47 +01:00
end
2017-10-23 03:50:11 +02:00
if # unsatisfied > 0 then
minetest.sound_play ( " dingding " , { gain = 1.0 , pos = pos } ) -- Insufficient inventory
meta : set_string ( " infotext " , S ( " Duplicator requires: \n @1 " , table.concat ( unsatisfied , " \n " ) ) )
return
end
2022-03-22 22:13:47 +01:00
2017-10-23 03:50:11 +02:00
meta : set_string ( " infotext " , " " ) -- clear infotext, we're good to go.
2022-03-22 22:13:47 +01:00
2017-10-23 03:50:11 +02:00
-- deduct nodes from duplicator inventory
for name , count in pairs ( required_count ) do
inv : remove_item ( " main " , ItemStack ( { name = name , count = count } ) )
end
2022-03-22 22:13:47 +01:00
-- clear inventories of image's nodes
2019-01-05 06:06:12 +01:00
if layout.inventories ~= nil then
for _ , node_image in pairs ( layout.inventories ) do
local main_inventory = node_image.meta . inventory.main
if type ( main_inventory ) ~= " table " then
main_inventory = { }
end
for index , _ in pairs ( main_inventory ) do
main_inventory [ index ] = ItemStack ( nil )
end
2017-10-23 03:50:11 +02:00
end
end
2019-01-05 06:06:12 +01:00
if layout.fuelstores ~= nil then
for _ , node_image in pairs ( layout.fuelstores ) do
local fuel_inventory = node_image.meta . inventory.fuel
for index , _ in pairs ( fuel_inventory ) do
fuel_inventory [ index ] = ItemStack ( nil )
end
2017-10-23 03:50:11 +02:00
end
end
2019-01-05 06:06:12 +01:00
if layout.battery_holders ~= nil then
for _ , node_image in pairs ( layout.battery_holders ) do
local battery_inventory = node_image.meta . inventory.batteries
for index , _ in pairs ( battery_inventory ) do
battery_inventory [ index ] = ItemStack ( nil )
end
2017-10-23 03:50:11 +02:00
end
end
-- replace empty crate with loaded crate and write image to its metadata
local layout_string = layout : serialize ( )
2022-03-22 22:13:47 +01:00
minetest.set_node ( target_pos , { name = target_name , param1 = node.param1 , param2 = node.param2 } )
2017-10-23 03:50:11 +02:00
local target_meta = minetest.get_meta ( target_pos )
target_meta : set_string ( " crated_layout " , layout_string )
2022-03-22 22:13:47 +01:00
2019-01-09 08:39:40 +01:00
local titlestring = S ( " Crated @1-block Digtron " , tostring ( # layout.all - 1 ) )
target_meta : set_string ( " title " , titlestring )
2022-03-22 22:13:47 +01:00
if target_name == " digtron:loaded_locked_crate " then
target_meta : set_string ( " owner " , player_name )
target_meta : set_string ( " infotext " , titlestring .. " \n " .. S ( " Owned by @1 " , player_name ) )
else
target_meta : set_string ( " infotext " , titlestring )
end
2017-10-23 03:50:11 +02:00
minetest.sound_play ( " machine1 " , { gain = 1.0 , pos = pos } )
end
end ,
2018-01-11 20:13:10 +01:00
} )