2022-07-05 20:14:48 +03:00
--|||||||||||||||||||||||
--||||| STONECUTTER |||||
--|||||||||||||||||||||||
-- TO-DO:
-- * Add GUI
2023-07-30 23:58:42 +03:00
local S = minetest.get_translator ( " mcl_stonecutter " )
2022-07-05 20:14:48 +03:00
2023-08-01 20:17:48 +03:00
-- compatible items for the stonecutter
2023-07-31 10:56:02 +03:00
local compaitble_items = {
" mcl_core:cobble " ,
" mcl_core:mossycobble " ,
" mcl_core:stone " ,
" mcl_core:stone_smooth " ,
" mcl_core:granite " ,
" mcl_core:granite_smooth " ,
" mcl_core:diorite " ,
" mcl_core:diorite_smooth " ,
" mcl_core:andesite " ,
" mcl_core:andesite_smooth " ,
" mcl_core:stonebrick " ,
" mcl_core:stonebrickmossy " ,
" mcl_core:sandstone " ,
" mcl_core:redsandstone " ,
2023-08-01 11:14:09 +03:00
" mcl_core:brick_block " ,
2023-07-31 10:56:02 +03:00
" mcl_ocean:prismarine " ,
" mcl_ocean:prismarine_brick " ,
" mcl_ocean:prismarine_dark " ,
" mcl_mud:mud_bricks " ,
" mcl_nether:quartzblock " ,
" mcl_nether:quartz_smooth " ,
2023-08-01 11:14:09 +03:00
" mcl_nether:red_nether_brick " ,
" mcl_nether:nether_brick " ,
2023-07-31 10:56:02 +03:00
" mcl_end:purpur_block " ,
" mcl_end:end_bricks " ,
2023-08-01 11:14:09 +03:00
" mcl_blackstone:blackstone " ,
" mcl_blackstone:blackstone_polished "
2023-07-31 10:56:02 +03:00
}
2023-07-30 20:25:48 +03:00
local FMT = {
item_image_button = " item_image_button[%f,%f;%f,%f;%s;%s;%s] " ,
}
2023-08-01 20:17:48 +03:00
-- formspecs
2023-07-30 20:25:48 +03:00
local function show_stonecutter_formspec ( items , input )
local cut_items = { }
local x_len = 0
local y_len = 0.5
2023-08-01 20:17:48 +03:00
-- This loops through all the items that can be made and inserted into the formspec
2023-07-30 20:25:48 +03:00
if items ~= nil then
for index , value in pairs ( items ) do
x_len = x_len + 1
if x_len > 5 then
y_len = y_len + 1
x_len = 1
end
2023-07-30 23:58:42 +03:00
local test = string.format ( FMT.item_image_button , x_len + 1 , y_len , 1 , 1 , value , " item_button " , value )
2023-07-30 20:25:48 +03:00
cut_items [ index ] = test
end
end
local formspec = " size[9,8.75] " ..
" label[0,4.0; " .. minetest.formspec_escape ( minetest.colorize ( " #313131 " , S ( " Inventory " ) ) ) .. " ] " ..
" label[1,0.1; " .. minetest.formspec_escape ( minetest.colorize ( " #313131 " , S ( " Stonecutter " ) ) ) .. " ] " ..
" list[context;main;0,0;8,4;] " ..
" 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 20:17:48 +03:00
-- Strips the start of the item like "mcl_core:" and removes any numbers or whitespaces after it
2023-07-31 10:56:02 +03:00
local function get_item_string_name ( input )
local colonIndex = string.find ( input , " : " )
if colonIndex then
input = string.sub ( input , colonIndex + 1 )
else
return input
end
local whitespaceIndex = string.find ( input , " %s " )
if whitespaceIndex then
return string.sub ( input , 1 , whitespaceIndex - 1 )
else
return input
end
end
2023-08-01 20:17:48 +03:00
-- Simply checks if the item is compaitble with the stonecutter
2023-08-01 11:14:09 +03:00
local function is_input_in_table ( element )
for _ , value in ipairs ( compaitble_items ) do
if value == element then
return true
end
end
return false
end
2023-08-01 20:17:48 +03:00
-- Updates the formspec
2023-07-30 20:25:48 +03:00
local function update_stonecutter_slots ( meta )
local inv = meta : get_inventory ( )
local input = inv : get_stack ( " input " , 1 )
local name = input : get_name ( )
2023-08-01 20:05:01 +03:00
local new_output = meta : get_string ( " cut_stone " )
2023-08-01 11:14:09 +03:00
2023-08-01 20:17:48 +03:00
-- Checks if input is in the array
2023-08-01 11:14:09 +03:00
if is_input_in_table ( name ) then
2023-08-01 20:17:48 +03:00
local cuttable_recipes = { }
local name_stripped = get_item_string_name ( input : to_string ( ) )
2023-08-01 11:14:09 +03:00
if name_stripped ~= " " then
2023-08-01 20:17:48 +03:00
-- Strings for the possible items it can craft into
2023-08-01 11:14:09 +03:00
local stair = " mcl_stairs:stair_ " .. name_stripped
local slab = " mcl_stairs:slab_ " .. name_stripped
local wall = " mcl_walls: " .. name_stripped
local smooth = " mcl_core: " .. name_stripped .. " _smooth "
2023-08-01 20:17:48 +03:00
-- Goes through and checks if the item exists and inserts it into the table
2023-08-01 11:14:09 +03:00
if minetest.registered_items [ slab ] ~= nil then
table.insert ( cuttable_recipes , slab )
end
if minetest.registered_items [ stair ] ~= nil then
table.insert ( cuttable_recipes , stair )
end
if minetest.registered_items [ wall ] ~= nil then
table.insert ( cuttable_recipes , wall )
end
if minetest.registered_items [ smooth ] ~= nil then
local smooth_stair = " mcl_stairs:stair_ " .. name_stripped .. " _smooth "
local smooth_slab = " mcl_stairs:slab_ " .. name_stripped .. " _smooth "
table.insert ( cuttable_recipes , smooth )
if minetest.registered_items [ smooth_slab ] ~= nil then
table.insert ( cuttable_recipes , smooth_slab )
end
if minetest.registered_items [ smooth_stair ] ~= nil then
table.insert ( cuttable_recipes , smooth_stair )
end
2023-07-30 23:58:42 +03:00
end
2023-07-30 20:25:48 +03:00
end
2023-08-01 11:14:09 +03:00
meta : set_string ( " formspec " , show_stonecutter_formspec ( cuttable_recipes ) )
2023-07-30 23:58:42 +03:00
else
meta : set_string ( " formspec " , show_stonecutter_formspec ( nil ) )
2023-07-30 20:25:48 +03:00
end
2023-08-01 20:17:48 +03:00
-- Checks if the chosen item is a slab or not, if it's a slab set the output to be a stack of 2
if new_output ~= ' ' then
2023-08-01 20:05:01 +03:00
cut_item = ItemStack ( new_output )
if string.find ( new_output , " mcl_stairs:slab_ " ) then
cut_item : set_count ( 2 )
else
cut_item : set_count ( 1 )
end
inv : set_stack ( " output " , 1 , cut_item )
2023-07-31 00:41:19 +03:00
end
end
2023-07-30 20:25:48 +03:00
2023-08-01 20:17:48 +03:00
-- Only drop the items that were in the input slot
local function drop_stonecutter_items ( pos , meta )
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 )
end
end
end
2022-07-05 20:14:48 +03: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 " ,
{ name = " mcl_stonecutter_saw.png " ,
animation = {
type = " vertical_frames " ,
aspect_w = 16 ,
aspect_h = 16 ,
length = 1
} } ,
{ name = " mcl_stonecutter_saw.png " ,
animation = {
type = " vertical_frames " ,
aspect_w = 16 ,
aspect_h = 16 ,
length = 1
} }
} ,
2022-08-07 05:38:15 +03:00
use_texture_alpha = " clip " ,
2022-07-05 20:14:48 +03: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-07-30 20:25:48 +03:00
2023-08-01 20:17:48 +03:00
after_dig_node = function ( pos , oldnode , oldmetadata , digger )
local meta = minetest.get_meta ( pos )
local meta2 = meta : to_table ( )
meta : from_table ( oldmetadata )
drop_stonecutter_items ( pos , meta )
meta : from_table ( meta2 )
end ,
2023-07-30 20:25:48 +03: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 20:17:48 +03: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 20:25:48 +03: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
update_stonecutter_slots ( meta )
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 )
local meta = minetest.get_meta ( pos )
update_stonecutter_slots ( meta )
end ,
2023-07-30 23:58:42 +03:00
on_metadata_inventory_take = function ( pos , listname , index , stack , player )
local meta = minetest.get_meta ( pos )
2023-07-31 00:41:19 +03: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-07-30 23:58:42 +03:00
end
2023-07-31 10:56:02 +03:00
meta : set_string ( " cut_stone " , nil )
2023-07-31 00:41:19 +03:00
update_stonecutter_slots ( meta )
2023-07-30 23:58:42 +03:00
end ,
2023-07-30 20:25:48 +03: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 )
local name = player : get_player_name ( )
if not player : get_player_control ( ) . sneak then
local meta = minetest.get_meta ( pos )
update_stonecutter_slots ( meta )
end
end ,
2023-07-30 23:58:42 +03: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
if fields.item_button then
2023-07-31 00:41:19 +03:00
local meta = minetest.get_meta ( pos )
meta : set_string ( " cut_stone " , fields.item_button )
update_stonecutter_slots ( meta )
2023-07-30 23:58:42 +03:00
end
end ,
2022-07-05 20:14:48 +03:00
} )
minetest.register_craft ( {
output = " mcl_stonecutter:stonecutter " ,
recipe = {
{ " " , " " , " " } ,
{ " " , " mcl_core:iron_ingot " , " " } ,
{ " mcl_core:stone " , " mcl_core:stone " , " mcl_core:stone " } ,
}
} )