2017-02-14 03:15:51 +02:00
--[[ This mod registers 3 nodes:
2017-02-14 03:33:58 +02:00
- One node for the horizontal - facing dropper ( mcl_droppers : dropper )
- One node for the upwards - facing droppers ( mcl_droppers : dropper_up )
- One node for the downwards - facing droppers ( mcl_droppers : dropper_down )
2017-02-14 03:15:51 +02:00
3 node definitions are needed because of the way the textures are defined .
All node definitions share a lot of code , so this is the reason why there
are so many weird tables below .
] ]
2019-03-08 02:07:41 +02:00
local S = minetest.get_translator ( " mcl_droppers " )
2017-02-14 03:20:40 +02:00
-- For after_place_node
2017-02-14 03:15:51 +02:00
local setup_dropper = function ( pos )
2017-02-14 03:20:40 +02:00
-- Set formspec and inventory
2017-02-14 03:15:51 +02:00
local form = " size[9,8.75] " ..
" background[-0.19,-0.25;9.41,9.49;crafting_inventory_9_slots.png] " ..
2019-03-07 13:42:08 +02:00
mcl_vars.inventory_header ..
2019-03-16 06:21:27 +02:00
" label[0,4.0; " .. minetest.formspec_escape ( minetest.colorize ( " #313131 " , S ( " Inventory " ) ) ) .. " ] " ..
2017-02-14 03:15:51 +02:00
" list[current_player;main;0,4.5;9,3;9] " ..
" list[current_player;main;0,7.74;9,1;] " ..
2019-03-16 06:21:27 +02:00
" label[3,0; " .. minetest.formspec_escape ( minetest.colorize ( " #313131 " , S ( " Dropper " ) ) ) .. " ] " ..
2017-02-14 03:15:51 +02:00
" list[current_name;main;3,0.5;3,3;] " ..
" listring[current_name;main] " ..
" listring[current_player;main] "
local meta = minetest.get_meta ( pos )
meta : set_string ( " formspec " , form )
local inv = meta : get_inventory ( )
inv : set_size ( " main " , 9 )
end
2018-01-11 02:28:36 +02:00
local orientate_dropper = function ( pos , placer )
-- Not placed by player
if not placer then return end
-- Pitch in degrees
local pitch = placer : get_look_vertical ( ) * ( 180 / math.pi )
if pitch > 55 then
minetest.swap_node ( pos , { name = " mcl_droppers:dropper_up " } )
elseif pitch < - 55 then
minetest.swap_node ( pos , { name = " mcl_droppers:dropper_down " } )
end
end
2017-12-05 15:09:39 +02:00
local on_rotate
if minetest.get_modpath ( " screwdriver " ) then
on_rotate = screwdriver.rotate_simple
end
2017-02-14 03:15:51 +02:00
-- Shared core definition table
local dropperdef = {
2017-02-13 19:25:11 +02:00
is_ground_content = false ,
sounds = mcl_sounds.node_sound_stone_defaults ( ) ,
after_dig_node = function ( pos , oldnode , oldmetadata , digger )
local meta = minetest.get_meta ( pos )
local meta2 = meta
meta : from_table ( oldmetadata )
local inv = meta : get_inventory ( )
for i = 1 , inv : get_size ( " main " ) do
local stack = inv : get_stack ( " main " , 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
meta : from_table ( meta2 : to_table ( ) )
end ,
2019-02-08 22:59:01 +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
else
return count
end
end ,
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 ,
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
else
return stack : get_count ( )
end
end ,
2017-02-22 17:22:28 +02:00
_mcl_blast_resistance = 17.5 ,
2017-02-27 02:52:24 +02:00
_mcl_hardness = 3.5 ,
2017-02-13 19:25:11 +02:00
mesecons = { effector = {
-- Drop random item when triggered
action_on = function ( pos , node )
local meta = minetest.get_meta ( pos )
local inv = meta : get_inventory ( )
2017-02-14 03:15:51 +02:00
local droppos
2017-02-14 03:33:58 +02:00
if node.name == " mcl_droppers:dropper " then
2017-02-14 03:15:51 +02:00
droppos = vector.subtract ( pos , minetest.facedir_to_dir ( node.param2 ) )
2017-02-14 03:33:58 +02:00
elseif node.name == " mcl_droppers:dropper_up " then
2017-02-14 03:15:51 +02:00
droppos = { x = pos.x , y = pos.y + 1 , z = pos.z }
2017-02-14 03:33:58 +02:00
elseif node.name == " mcl_droppers:dropper_down " then
2017-02-14 03:15:51 +02:00
droppos = { x = pos.x , y = pos.y - 1 , z = pos.z }
end
2017-02-13 19:25:11 +02:00
local dropnode = minetest.get_node ( droppos )
2017-02-14 01:10:37 +02:00
-- Do not drop into solid nodes, unless they are containers
local dropnodedef = minetest.registered_nodes [ dropnode.name ]
if dropnodedef.walkable and not dropnodedef.groups . container then
2017-02-13 19:25:11 +02:00
return
end
local stacks = { }
for i = 1 , inv : get_size ( " main " ) do
local stack = inv : get_stack ( " main " , i )
if not stack : is_empty ( ) then
table.insert ( stacks , { stack = stack , stackpos = i } )
end
end
if # stacks >= 1 then
local r = math.random ( 1 , # stacks )
local stack = stacks [ r ] . stack
2017-06-12 23:27:37 +03:00
local dropitem = ItemStack ( stack )
dropitem : set_count ( 1 )
2017-02-14 01:10:37 +02:00
local stack_id = stacks [ r ] . stackpos
2017-02-14 01:44:23 +02:00
-- If it's a container, attempt to put it into the container
2017-08-04 03:19:47 +03:00
local dropped = mcl_util.move_item_container ( pos , droppos , nil , stack_id )
2017-02-14 01:44:23 +02:00
-- No container?
if not dropped and not dropnodedef.groups . container then
-- Drop item normally
2017-02-14 01:10:37 +02:00
minetest.add_item ( droppos , dropitem )
stack : take_item ( )
inv : set_stack ( " main " , stack_id , stack )
end
2017-02-13 19:25:11 +02:00
end
2017-09-14 03:20:47 +03:00
end ,
rules = mesecon.rules . alldirs ,
2017-12-05 15:09:39 +02:00
} } ,
on_rotate = on_rotate ,
2017-02-14 03:15:51 +02:00
}
-- Horizontal dropper
local horizontal_def = table.copy ( dropperdef )
2019-03-08 02:07:41 +02:00
horizontal_def.description = S ( " Dropper " )
horizontal_def._doc_items_longdesc = S ( " A dropper is a redstone component and a container with 9 inventory slots which, when supplied with redstone power, drops an item or puts it into a container in front of it. " )
2019-03-16 03:00:48 +02:00
horizontal_def._doc_items_usagehelp = S ( " Droppers can be placed in 6 possible directions, items will be dropped out of the hole. Use the dropper to access its inventory. Supply it with redstone energy once to make the dropper drop or transfer a random item. " )
2017-02-14 03:15:51 +02:00
horizontal_def.after_place_node = function ( pos , placer , itemstack , pointed_thing )
setup_dropper ( pos )
2018-01-11 02:28:36 +02:00
orientate_dropper ( pos , placer )
2017-02-14 03:15:51 +02:00
end
horizontal_def.tiles = {
" default_furnace_top.png " , " default_furnace_bottom.png " ,
" default_furnace_side.png " , " default_furnace_side.png " ,
2017-02-14 03:33:58 +02:00
" default_furnace_side.png " , " mcl_droppers_dropper_front_horizontal.png "
2017-02-14 03:15:51 +02:00
}
horizontal_def.paramtype2 = " facedir "
2017-03-11 06:34:58 +02:00
horizontal_def.groups = { pickaxey = 1 , container = 2 , material_stone = 1 }
2017-02-14 03:15:51 +02:00
2017-02-14 03:33:58 +02:00
minetest.register_node ( " mcl_droppers:dropper " , horizontal_def )
2017-02-14 03:15:51 +02:00
-- Down dropper
local down_def = table.copy ( dropperdef )
2019-03-08 02:07:41 +02:00
down_def.description = S ( " Downwards-Facing Dropper " )
2017-02-14 03:15:51 +02:00
down_def.after_place_node = setup_dropper
down_def.tiles = {
2017-02-14 03:33:58 +02:00
" default_furnace_top.png " , " mcl_droppers_dropper_front_vertical.png " ,
2017-02-14 03:15:51 +02:00
" default_furnace_side.png " , " default_furnace_side.png " ,
" default_furnace_side.png " , " default_furnace_side.png "
}
2017-03-11 06:34:58 +02:00
down_def.groups = { pickaxey = 1 , container = 2 , not_in_creative_inventory = 1 , material_stone = 1 }
2017-03-02 20:53:53 +02:00
down_def._doc_items_create_entry = false
2017-02-14 03:33:58 +02:00
down_def.drop = " mcl_droppers:dropper "
minetest.register_node ( " mcl_droppers:dropper_down " , down_def )
2017-02-13 19:25:11 +02:00
2017-02-14 03:15:51 +02:00
-- Up dropper
-- The up dropper is almost identical to the down dropper, it only differs in textures
2017-08-02 02:34:12 +03:00
local up_def = table.copy ( down_def )
2019-03-08 02:07:41 +02:00
up_def.description = S ( " Upwards-Facing Dropper " )
2017-02-14 03:15:51 +02:00
up_def.tiles = {
2017-02-14 03:33:58 +02:00
" mcl_droppers_dropper_front_vertical.png " , " default_furnace_bottom.png " ,
2017-02-14 03:15:51 +02:00
" default_furnace_side.png " , " default_furnace_side.png " ,
" default_furnace_side.png " , " default_furnace_side.png "
}
2017-02-14 03:33:58 +02:00
minetest.register_node ( " mcl_droppers:dropper_up " , up_def )
2017-02-14 03:20:40 +02:00
-- Ladies and gentlemen, I present to you: the crafting recipe!
minetest.register_craft ( {
2017-02-14 03:33:58 +02:00
output = ' mcl_droppers:dropper ' ,
2017-02-14 03:20:40 +02:00
recipe = {
{ " mcl_core:cobble " , " mcl_core:cobble " , " mcl_core:cobble " , } ,
{ " mcl_core:cobble " , " " , " mcl_core:cobble " , } ,
{ " mcl_core:cobble " , " mesecons:redstone " , " mcl_core:cobble " , } ,
}
} )
2017-03-21 05:27:50 +02:00
-- Add entry aliases for the Help
if minetest.get_modpath ( " doc " ) then
doc.add_entry_alias ( " nodes " , " mcl_droppers:dropper " , " nodes " , " mcl_droppers:dropper_down " )
doc.add_entry_alias ( " nodes " , " mcl_droppers:dropper " , " nodes " , " mcl_droppers:dropper_up " )
end
2019-03-21 17:08:29 +02:00
minetest.register_lbm ( {
label = " Update dropper formspecs (0.51.0) " ,
name = " mcl_droppers:update_formspecs_0_51_0 " ,
nodenames = { " mcl_droppers:dropper " , " mcl_droppers:dropper_down " , " mcl_droppers:dropper_up " } ,
action = function ( pos , node )
setup_dropper ( pos )
minetest.log ( " action " , " [mcl_droppers] Node formspec updated at " .. minetest.pos_to_string ( pos ) )
end ,
} )