2022-07-05 19:14:48 +02:00
--|||||||||||||||||||||||
--||||| STONECUTTER |||||
--|||||||||||||||||||||||
2023-07-30 22:58:42 +02:00
local S = minetest.get_translator ( " mcl_stonecutter " )
2022-07-05 19:14:48 +02:00
2023-11-13 17:01:37 +01:00
mcl_stonecutter = { }
mcl_stonecutter.registered_recipes = { }
-- API
-- input - string - name of a registered item
-- output - string - name of a registered item
-- count - int - number of the output -
-- - defaults to 1
-- - non-int rounded down
function mcl_stonecutter . register_recipe ( input , output , count )
2023-11-13 21:13:16 +01:00
if mcl_stonecutter.registered_recipes [ input ] and mcl_stonecutter.registered_recipes [ input ] [ output ] then return end
if not minetest.registered_items [ input ] then
error ( " Input is not a registered item: " .. input )
end
if not minetest.registered_items [ output ] then
error ( " Output is not a registered item: " .. output )
2023-11-13 17:01:37 +01:00
end
local n = count
if type ( count ) ~= " number " then
n = 1
end
n = math.floor ( n )
if not mcl_stonecutter.registered_recipes [ input ] then
mcl_stonecutter.registered_recipes [ input ] = { }
end
mcl_stonecutter.registered_recipes [ input ] [ output ] = n
2023-11-13 21:13:16 +01:00
local fallthrough = mcl_stonecutter.registered_recipes [ output ]
if fallthrough then
for o , c in pairs ( fallthrough ) do
mcl_stonecutter.register_recipe ( input , o , c )
end
end
for i , recipes in pairs ( mcl_stonecutter.registered_recipes ) do
for name , c in pairs ( recipes ) do
if name == input then
mcl_stonecutter.register_recipe ( i , output , c * n )
end
end
end
2023-11-13 17:01:37 +01:00
end
2023-08-01 19:17:48 +02:00
-- formspecs
2023-07-30 19:25:48 +02:00
local function show_stonecutter_formspec ( items , input )
local cut_items = { }
local x_len = 0
local y_len = 0.5
2023-08-01 19:17:48 +02:00
-- This loops through all the items that can be made and inserted into the formspec
2023-07-30 19:25:48 +02:00
if items ~= nil then
2023-11-13 17:01:37 +01:00
for name , count in pairs ( items ) do
2023-07-30 19:25:48 +02:00
x_len = x_len + 1
if x_len > 5 then
y_len = y_len + 1
x_len = 1
end
2023-11-13 17:01:37 +01:00
table.insert ( cut_items , string.format ( " item_image_button[%f,%f;%f,%f;%s;%s;%s] " , x_len + 1 , y_len , 1 , 1 , name , name , tostring ( count ) ) )
2023-07-30 19:25:48 +02:00
end
end
local formspec = " size[9,8.75] " ..
" label[0,4.0; " .. minetest.formspec_escape ( minetest.colorize ( " #313131 " , S ( " Inventory " ) ) ) .. " ] " ..
2023-08-06 14:07:32 +02:00
" label[1,0.1; " .. minetest.formspec_escape ( minetest.colorize ( " #313131 " , S ( " Stone Cutter " ) ) ) .. " ] " ..
2023-07-30 19:25:48 +02:00
" list[current_player;main;0,4.5;9,3;9] " ..
mcl_formspec.get_itemslot_bg ( 0 , 4.5 , 9 , 3 ) ..
" list[current_player;main;0,7.74;9,1;] " ..
mcl_formspec.get_itemslot_bg ( 0 , 7.74 , 9 , 1 ) ..
" list[context;input;0.5,1.7;1,1;] " ..
mcl_formspec.get_itemslot_bg ( 0.5 , 1.7 , 1 , 1 ) ..
" list[context;output;7.5,1.7;1,1;] " ..
mcl_formspec.get_itemslot_bg ( 7.5 , 1.7 , 1 , 1 ) ..
table.concat ( cut_items ) ..
" listring[context;output] " ..
" listring[current_player;main] " ..
" listring[context;input] " ..
" listring[current_player;main] "
return formspec
end
2023-08-01 19:17:48 +02:00
-- Updates the formspec
2023-11-13 17:01:37 +01:00
local function update_stonecutter_slots ( pos , str )
2023-08-06 22:42:34 +02:00
local meta = minetest.get_meta ( pos )
2023-07-30 19:25:48 +02:00
local inv = meta : get_inventory ( )
local input = inv : get_stack ( " input " , 1 )
local name = input : get_name ( )
2023-11-13 17:01:37 +01:00
local recipes = mcl_stonecutter.registered_recipes [ name ]
2023-08-01 19:17:48 +02:00
2023-11-13 17:01:37 +01:00
if recipes then
meta : set_string ( " formspec " , show_stonecutter_formspec ( recipes ) )
if str then
local recipe = recipes [ str ]
if not recipe then return end
local cut_item = ItemStack ( str )
cut_item : set_count ( recipe )
inv : set_stack ( " output " , 1 , cut_item )
2023-08-01 19:05:01 +02:00
else
2023-11-13 17:01:37 +01:00
inv : set_stack ( " output " , 1 , " " )
2023-08-01 19:05:01 +02:00
end
2023-08-01 23:39:24 +02:00
else
2023-11-13 17:01:37 +01:00
meta : set_string ( " formspec " , show_stonecutter_formspec ( nil ) )
2023-11-13 21:13:16 +01:00
inv : set_stack ( " output " , 1 , " " )
2023-07-30 23:41:19 +02:00
end
end
2023-07-30 19:25:48 +02:00
2023-08-01 19:17:48 +02:00
-- Only drop the items that were in the input slot
local function drop_stonecutter_items ( pos , meta )
2023-08-20 18:02:55 +02:00
local meta = minetest.get_meta ( pos )
2023-08-01 19:17:48 +02:00
local inv = meta : get_inventory ( )
for i = 1 , inv : get_size ( " input " ) do
local stack = inv : get_stack ( " input " , i )
if not stack : is_empty ( ) then
local p = { x = pos.x + math.random ( 0 , 10 ) / 10 - 0.5 , y = pos.y , z = pos.z + math.random ( 0 , 10 ) / 10 - 0.5 }
minetest.add_item ( p , stack )
2023-11-13 17:01:37 +01:00
-- inv:set_stack("input", i, ItemStack())
2023-08-01 19:17:48 +02:00
end
end
end
2022-07-05 19:14:48 +02:00
minetest.register_node ( " mcl_stonecutter:stonecutter " , {
description = S ( " Stone Cutter " ) ,
_tt_help = S ( " Used to cut stone like materials. " ) ,
_doc_items_longdesc = S ( " Stonecutters are used to create stairs and slabs from stone like materials. It is also the jobsite for the Stone Mason Villager. " ) ,
tiles = {
" mcl_stonecutter_top.png " ,
" mcl_stonecutter_bottom.png " ,
" mcl_stonecutter_side.png " ,
" mcl_stonecutter_side.png " ,
2023-11-13 17:01:37 +01:00
{ name = " mcl_stonecutter_saw.png " ,
2022-07-05 19:14:48 +02:00
animation = {
2023-11-13 17:01:37 +01:00
type = " vertical_frames " ,
aspect_w = 16 ,
aspect_h = 16 ,
2022-07-05 19:14:48 +02:00
length = 1
} } ,
2023-11-13 17:01:37 +01:00
{ name = " mcl_stonecutter_saw.png " ,
2022-07-05 19:14:48 +02:00
animation = {
2023-11-13 17:01:37 +01:00
type = " vertical_frames " ,
aspect_w = 16 ,
aspect_h = 16 ,
2022-07-05 19:14:48 +02:00
length = 1
} }
} ,
2022-08-07 04:38:15 +02:00
use_texture_alpha = " clip " ,
2022-07-05 19:14:48 +02:00
drawtype = " nodebox " ,
paramtype = " light " ,
paramtype2 = " facedir " ,
groups = { pickaxey = 1 , material_stone = 1 } ,
node_box = {
type = " fixed " ,
fixed = {
{ - 0.5 , - 0.5 , - 0.5 , 0.5 , 0.0625 , 0.5 } , -- NodeBox1
{ - 0.4375 , 0.0625 , 0 , 0.4375 , 0.5 , 0 } , -- NodeBox2
}
} ,
_mcl_blast_resistance = 3.5 ,
_mcl_hardness = 3.5 ,
sounds = mcl_sounds.node_sound_stone_defaults ( ) ,
2023-08-20 18:02:55 +02:00
on_destruct = drop_stonecutter_items ,
2023-07-30 19:25:48 +02:00
allow_metadata_inventory_take = function ( pos , listname , index , stack , player )
local name = player : get_player_name ( )
if minetest.is_protected ( pos , name ) then
minetest.record_protection_violation ( pos , name )
return 0
else
return stack : get_count ( )
end
end ,
2023-08-01 19:17:48 +02:00
allow_metadata_inventory_move = function ( pos , from_list , from_index , to_list , to_index , count , player )
local name = player : get_player_name ( )
if minetest.is_protected ( pos , name ) then
minetest.record_protection_violation ( pos , name )
return 0
elseif to_list == " output " then
return 0
elseif from_list == " output " and to_list == " input " then
local meta = minetest.get_meta ( pos )
local inv = meta : get_inventory ( )
if inv : get_stack ( to_list , to_index ) : is_empty ( ) then
return count
else
return 0
end
else
return count
end
end ,
2023-07-30 19:25:48 +02:00
on_metadata_inventory_move = function ( pos , from_list , from_index , to_list , to_index , count , player )
local meta = minetest.get_meta ( pos )
if from_list == " output " and to_list == " input " then
local inv = meta : get_inventory ( )
for i = 1 , inv : get_size ( " input " ) do
if i ~= to_index then
local istack = inv : get_stack ( " input " , i )
istack : set_count ( math.max ( 0 , istack : get_count ( ) - count ) )
inv : set_stack ( " input " , i , istack )
end
end
end
2023-08-06 22:42:34 +02:00
update_stonecutter_slots ( pos )
2023-07-30 19:25:48 +02:00
end ,
allow_metadata_inventory_put = function ( pos , listname , index , stack , player )
local name = player : get_player_name ( )
if minetest.is_protected ( pos , name ) then
minetest.record_protection_violation ( pos , name )
return 0
elseif listname == " output " then
return 0
else
return stack : get_count ( )
end
end ,
on_metadata_inventory_put = function ( pos , listname , index , stack , player )
2023-08-06 22:42:34 +02:00
update_stonecutter_slots ( pos )
2023-07-30 19:25:48 +02:00
end ,
2023-07-30 22:58:42 +02:00
on_metadata_inventory_take = function ( pos , listname , index , stack , player )
local meta = minetest.get_meta ( pos )
2023-07-30 23:41:19 +02:00
if listname == " output " then
local inv = meta : get_inventory ( )
local input = inv : get_stack ( " input " , 1 )
input : take_item ( )
inv : set_stack ( " input " , 1 , input )
2023-08-01 23:48:45 +02:00
if input : get_count ( ) == 0 then
meta : set_string ( " cut_stone " , nil )
end
else
meta : set_string ( " cut_stone " , nil )
2023-07-30 22:58:42 +02:00
end
2023-08-06 22:42:34 +02:00
update_stonecutter_slots ( pos )
2023-07-30 22:58:42 +02:00
end ,
2023-07-30 19:25:48 +02:00
on_construct = function ( pos )
local meta = minetest.get_meta ( pos )
local inv = meta : get_inventory ( )
inv : set_size ( " input " , 1 )
inv : set_size ( " output " , 1 )
local form = show_stonecutter_formspec ( )
meta : set_string ( " formspec " , form )
end ,
on_rightclick = function ( pos , node , player , itemstack )
if not player : get_player_control ( ) . sneak then
2023-08-06 22:42:34 +02:00
update_stonecutter_slots ( pos )
2023-07-30 19:25:48 +02:00
end
end ,
2023-07-30 22:58:42 +02:00
on_receive_fields = function ( pos , formname , fields , sender )
local sender_name = sender : get_player_name ( )
if minetest.is_protected ( pos , sender_name ) then
minetest.record_protection_violation ( pos , sender_name )
return
end
2023-08-06 22:42:34 +02:00
if fields then
for field_name , value in pairs ( fields ) do
local item_name = tostring ( field_name )
if item_name then
update_stonecutter_slots ( pos , item_name )
end
end
2023-07-30 22:58:42 +02:00
end
end ,
2022-07-05 19:14:48 +02:00
} )
minetest.register_craft ( {
output = " mcl_stonecutter:stonecutter " ,
recipe = {
{ " " , " " , " " } ,
{ " " , " mcl_core:iron_ingot " , " " } ,
{ " mcl_core:stone " , " mcl_core:stone " , " mcl_core:stone " } ,
}
} )