2017-01-17 16:50:56 +00:00
2017-01-27 11:42:05 +00:00
local chest = minetest.get_content_id ( " mcl_chests:chest " )
2017-01-17 16:50:56 +00:00
2017-01-17 17:41:25 +00:00
local mcl_hoppers_formspec =
2017-01-17 17:17:53 +00:00
" size[9,7] " ..
2017-01-17 17:41:25 +00:00
" background[-0.19,-0.25;9.41,10.48;mcl_hoppers_inventory.png] " ..
2017-02-17 22:06:52 +00:00
mcl_vars.inventory_header ..
2017-01-17 17:17:53 +00:00
" list[current_name;main;2,0.5;5,1;] " ..
" list[current_player;main;0,2.5;9,3;9] " ..
" list[current_player;main;0,5.74;9,1;] " ..
" listring[current_name;main] " ..
" listring[current_player;main] "
2017-01-17 16:50:56 +00:00
2017-01-17 17:41:25 +00:00
minetest.register_node ( " mcl_hoppers:hopper " , {
2017-02-22 13:00:58 +00:00
description = " Hopper " ,
inventory_image = " mcl_hoppers_item.png " ,
2017-03-10 22:31:57 +00:00
_doc_items_longdesc = [ [ Hoppers are containers with 5 inventory slots . They collect dropped items from above , take items from a container above and attempts to put its items it into an adjacent container . Hoppers can go either downwards or sideways . Hoppers interact with chests , droppers , dispensers , shulker boxes , furnaces and hoppers .
Hoppers interact with containers the following way :
• Furnaces : Hoppers from above will put items into the source slot . Hoppers from below take items from the output slot . They also take items from the fuel slot when they can ' t be used as a fuel. Sideway hoppers put items into the fuel slot
• Ender chests : Hoppers don ' t interact with ender chests
• Other containers : Hoppers interact with them normally ] ] ,
_doc_items_usagehelp = " To place a hopper vertically, place it on the floor or a ceiling. To place it sideways, place it at the side of a block. Remember you can place at usable blocks (such as chests) with sneak + right-click. The hopper will keep its orientation when the blocks around it are changed. To access the hopper's inventory, rightclick it. " ,
2017-02-22 13:00:58 +00:00
wield_image = " mcl_hoppers_item.png " ,
2017-02-27 00:33:34 +00:00
groups = { pickaxey = 1 , container = 2 , deco_block = 1 , } ,
2017-01-17 16:50:56 +00:00
drawtype = " nodebox " ,
paramtype = " light " ,
2017-03-20 19:06:24 +00:00
sunlight_propagates = true ,
2017-02-06 16:33:43 +00:00
tiles = { " mcl_hoppers_hopper_inside.png^mcl_hoppers_hopper_top.png " , " mcl_hoppers_hopper_outside.png " , " mcl_hoppers_hopper_outside.png " , " mcl_hoppers_hopper_inside.png " , " mcl_hoppers_hopper_outside.png " , " mcl_hoppers_hopper_outside.png " } ,
2017-01-17 16:50:56 +00:00
node_box = {
2017-11-22 23:41:26 +00:00
type = " fixed " ,
fixed = {
2017-01-17 16:50:56 +00:00
--funnel walls
{ - 0.5 , 0.0 , 0.4 , 0.5 , 0.5 , 0.5 } ,
{ 0.4 , 0.0 , - 0.5 , 0.5 , 0.5 , 0.5 } ,
{ - 0.5 , 0.0 , - 0.5 , - 0.4 , 0.5 , 0.5 } ,
{ - 0.5 , 0.0 , - 0.5 , 0.5 , 0.5 , - 0.4 } ,
--funnel base
{ - 0.5 , 0.0 , - 0.5 , 0.5 , 0.1 , 0.5 } ,
--spout
{ - 0.3 , - 0.3 , - 0.3 , 0.3 , 0.0 , 0.3 } ,
2017-07-08 17:10:41 +00:00
{ - 0.1 , - 0.3 , - 0.1 , 0.1 , - 0.5 , 0.1 } ,
2017-01-17 16:50:56 +00:00
} ,
2017-11-22 23:41:26 +00:00
} ,
selection_box = {
type = " fixed " ,
fixed = {
--funnel
{ - 0.5 , 0.0 , - 0.5 , 0.5 , 0.5 , 0.5 } ,
--spout
{ - 0.3 , - 0.3 , - 0.3 , 0.3 , 0.0 , 0.3 } ,
{ - 0.1 , - 0.3 , - 0.1 , 0.1 , - 0.5 , 0.1 } ,
} ,
} ,
2017-03-11 15:36:05 +00:00
is_ground_content = false ,
2017-01-17 16:50:56 +00:00
on_construct = function ( pos )
local meta = minetest.get_meta ( pos )
2017-01-17 17:41:25 +00:00
meta : set_string ( " formspec " , mcl_hoppers_formspec )
2017-01-17 16:50:56 +00:00
local inv = meta : get_inventory ( )
2017-01-17 17:17:53 +00:00
inv : set_size ( " main " , 5 )
2017-01-17 16:50:56 +00:00
end ,
2017-02-22 13:00:58 +00:00
2017-02-22 13:15:06 +00:00
on_place = function ( itemstack , placer , pointed_thing )
local upos = pointed_thing.under
local apos = pointed_thing.above
2017-02-22 13:00:58 +00:00
2017-03-02 15:09:13 +00:00
local uposnode = minetest.get_node ( upos )
local uposnodedef = minetest.registered_nodes [ uposnode.name ]
2017-06-29 11:02:53 +00:00
if not uposnodedef then return itemstack end
2017-03-02 15:09:13 +00:00
-- Use pointed node's on_rightclick function first, if present
if placer and not placer : get_player_control ( ) . sneak then
if uposnodedef and uposnodedef.on_rightclick then
return uposnodedef.on_rightclick ( pointed_thing.under , uposnode , placer , itemstack ) or itemstack
end
end
2017-02-22 13:15:06 +00:00
local bpos
if uposnodedef.buildable_to then
bpos = upos
else
local aposnodedef = minetest.registered_nodes [ minetest.get_node ( apos ) . name ]
2017-06-29 11:02:53 +00:00
if not aposnodedef then return itemstack end
2017-02-22 13:15:06 +00:00
if aposnodedef.buildable_to then
bpos = apos
end
end
if bpos == nil then
return itemstack
end
local x = upos.x - apos.x
local y = upos.y - apos.y
local z = upos.z - apos.z
2017-02-22 13:00:58 +00:00
if x == - 1 then
2017-02-22 13:15:06 +00:00
minetest.set_node ( bpos , { name = " mcl_hoppers:hopper_side " , param2 = 0 } )
2017-02-22 13:00:58 +00:00
elseif x == 1 then
2017-02-22 13:15:06 +00:00
minetest.set_node ( bpos , { name = " mcl_hoppers:hopper_side " , param2 = 2 } )
2017-02-22 13:00:58 +00:00
elseif z == - 1 then
2017-02-22 13:15:06 +00:00
minetest.set_node ( bpos , { name = " mcl_hoppers:hopper_side " , param2 = 3 } )
2017-02-22 13:00:58 +00:00
elseif z == 1 then
2017-02-22 13:15:06 +00:00
minetest.set_node ( bpos , { name = " mcl_hoppers:hopper_side " , param2 = 1 } )
else
minetest.set_node ( bpos , { name = " mcl_hoppers:hopper " , param2 = 0 } )
end
2017-08-09 14:17:00 +00:00
if not minetest.settings : get_bool ( " creative_mode " ) then
2017-02-22 13:15:06 +00:00
itemstack : take_item ( )
2017-02-22 13:00:58 +00:00
end
2017-02-22 13:15:06 +00:00
return itemstack
2017-02-22 13:00:58 +00:00
end ,
2017-01-17 17:30:35 +00:00
after_dig_node = function ( pos , oldnode , oldmetadata , digger )
local meta = minetest.get_meta ( pos )
local meta2 = meta
meta : from_table ( oldmetadata )
2017-01-17 16:50:56 +00:00
local inv = meta : get_inventory ( )
2017-01-17 17:30:35 +00:00
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 ( ) )
2017-01-17 16:50:56 +00:00
end ,
on_metadata_inventory_move = function ( pos , from_list , from_index , to_list , to_index , count , player )
minetest.log ( " action " , player : get_player_name ( ) ..
2017-01-17 17:41:25 +00:00
" moves stuff in mcl_hoppers at " .. minetest.pos_to_string ( pos ) )
2017-01-17 16:50:56 +00:00
end ,
on_metadata_inventory_put = function ( pos , listname , index , stack , player )
minetest.log ( " action " , player : get_player_name ( ) ..
2017-01-17 17:41:25 +00:00
" moves stuff to mcl_hoppers at " .. minetest.pos_to_string ( pos ) )
2017-01-17 16:50:56 +00:00
end ,
on_metadata_inventory_take = function ( pos , listname , index , stack , player )
minetest.log ( " action " , player : get_player_name ( ) ..
2017-01-17 17:41:25 +00:00
" takes stuff from mcl_hoppers at " .. minetest.pos_to_string ( pos ) )
2017-01-17 16:50:56 +00:00
end ,
2017-02-11 17:46:23 +00:00
sounds = mcl_sounds.node_sound_metal_defaults ( ) ,
2017-02-22 15:03:59 +00:00
_mcl_blast_resistance = 24 ,
2017-02-27 00:33:34 +00:00
_mcl_hardness = 3 ,
2017-01-17 16:50:56 +00:00
} )
2017-01-17 17:41:25 +00:00
minetest.register_node ( " mcl_hoppers:hopper_side " , {
2017-01-17 16:56:18 +00:00
description = " Hopper (Side) " ,
2017-03-02 18:53:53 +00:00
_doc_items_create_entry = false ,
2017-02-22 13:00:58 +00:00
drop = " mcl_hoppers:hopper " ,
2017-02-27 00:33:34 +00:00
groups = { pickaxey = 1 , container = 2 , not_in_creative_inventory = 1 } ,
2017-01-17 16:50:56 +00:00
drawtype = " nodebox " ,
paramtype = " light " ,
2017-03-20 19:06:24 +00:00
sunlight_propagates = true ,
2017-01-17 16:50:56 +00:00
paramtype2 = " facedir " ,
2017-02-06 16:33:43 +00:00
tiles = { " mcl_hoppers_hopper_inside.png^mcl_hoppers_hopper_top.png " , " mcl_hoppers_hopper_outside.png " , " mcl_hoppers_hopper_outside.png " , " mcl_hoppers_hopper_inside.png " , " mcl_hoppers_hopper_outside.png " , " mcl_hoppers_hopper_outside.png " } ,
2017-01-17 16:50:56 +00:00
node_box = {
2017-11-22 23:41:26 +00:00
type = " fixed " ,
fixed = {
2017-01-17 16:50:56 +00:00
--funnel walls
{ - 0.5 , 0.0 , 0.4 , 0.5 , 0.5 , 0.5 } ,
{ 0.4 , 0.0 , - 0.5 , 0.5 , 0.5 , 0.5 } ,
{ - 0.5 , 0.0 , - 0.5 , - 0.4 , 0.5 , 0.5 } ,
{ - 0.5 , 0.0 , - 0.5 , 0.5 , 0.5 , - 0.4 } ,
--funnel base
{ - 0.5 , 0.0 , - 0.5 , 0.5 , 0.1 , 0.5 } ,
--spout
{ - 0.3 , - 0.3 , - 0.3 , 0.3 , 0.0 , 0.3 } ,
2017-07-08 17:10:41 +00:00
{ - 0.5 , - 0.3 , - 0.1 , 0.1 , - 0.1 , 0.1 } ,
2017-01-17 16:50:56 +00:00
} ,
2017-11-22 23:41:26 +00:00
} ,
selection_box = {
type = " fixed " ,
fixed = {
--funnel
{ - 0.5 , 0.0 , - 0.5 , 0.5 , 0.5 , 0.5 } ,
--spout
{ - 0.3 , - 0.3 , - 0.3 , 0.3 , 0.0 , 0.3 } ,
{ - 0.5 , - 0.3 , - 0.1 , 0.1 , - 0.1 , 0.1 } ,
} ,
} ,
2017-03-11 15:36:05 +00:00
is_ground_content = false ,
2017-01-17 16:50:56 +00:00
on_construct = function ( pos )
local meta = minetest.get_meta ( pos )
2017-01-17 17:41:25 +00:00
meta : set_string ( " formspec " , mcl_hoppers_formspec )
2017-01-17 16:50:56 +00:00
local inv = meta : get_inventory ( )
2017-01-17 17:17:53 +00:00
inv : set_size ( " main " , 5 )
2017-01-17 16:50:56 +00:00
end ,
2017-02-22 13:00:58 +00:00
2017-01-17 17:30:35 +00:00
after_dig_node = function ( pos , oldnode , oldmetadata , digger )
local meta = minetest.get_meta ( pos )
local meta2 = meta
meta : from_table ( oldmetadata )
2017-01-17 16:50:56 +00:00
local inv = meta : get_inventory ( )
2017-01-17 17:30:35 +00:00
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 ( ) )
2017-01-17 16:50:56 +00:00
end ,
on_metadata_inventory_move = function ( pos , from_list , from_index , to_list , to_index , count , player )
minetest.log ( " action " , player : get_player_name ( ) ..
2017-01-17 17:41:25 +00:00
" moves stuff in mcl_hoppers at " .. minetest.pos_to_string ( pos ) )
2017-01-17 16:50:56 +00:00
end ,
on_metadata_inventory_put = function ( pos , listname , index , stack , player )
minetest.log ( " action " , player : get_player_name ( ) ..
2017-01-17 17:41:25 +00:00
" moves stuff to mcl_hoppers at " .. minetest.pos_to_string ( pos ) )
2017-01-17 16:50:56 +00:00
end ,
on_metadata_inventory_take = function ( pos , listname , index , stack , player )
minetest.log ( " action " , player : get_player_name ( ) ..
2017-01-17 17:41:25 +00:00
" takes stuff from mcl_hoppers at " .. minetest.pos_to_string ( pos ) )
2017-01-17 16:50:56 +00:00
end ,
2017-02-11 17:46:23 +00:00
sounds = mcl_sounds.node_sound_metal_defaults ( ) ,
2017-02-22 15:03:59 +00:00
_mcl_blast_resistance = 24 ,
2017-02-27 00:33:34 +00:00
_mcl_hardness = 3 ,
2017-01-17 16:50:56 +00:00
} )
2017-02-14 00:37:30 +00:00
-- Make hoppers suck in dropped items
2017-01-17 16:50:56 +00:00
minetest.register_abm ( {
2017-05-14 22:45:54 +00:00
label = " Hoppers suck in dropped items " ,
2017-01-17 17:41:25 +00:00
nodenames = { " mcl_hoppers:hopper " , " mcl_hoppers:hopper_side " } ,
2017-01-17 16:50:56 +00:00
interval = 1.0 ,
chance = 1 ,
action = function ( pos , node , active_object_count , active_object_count_wider )
2017-02-14 00:37:30 +00:00
local abovenode = minetest.get_node ( { x = pos.x , y = pos.y + 1 , z = pos.z } )
2017-06-29 11:02:53 +00:00
if not minetest.registered_items [ abovenode.name ] then return end
2017-02-14 00:37:30 +00:00
-- Don't bother checking item enties if node above is a container (should save some CPU)
if minetest.registered_items [ abovenode.name ] . groups.container then
return
end
local meta = minetest.get_meta ( pos )
2017-01-17 16:50:56 +00:00
local inv = meta : get_inventory ( )
2017-03-15 17:33:16 +00:00
for _ , object in ipairs ( minetest.get_objects_inside_radius ( pos , 2 ) ) do
2017-01-17 16:50:56 +00:00
if not object : is_player ( ) and object : get_luaentity ( ) and object : get_luaentity ( ) . name == " __builtin:item " then
if inv and inv : room_for_item ( " main " , ItemStack ( object : get_luaentity ( ) . itemstring ) ) then
2017-03-15 17:33:16 +00:00
-- Item must get sucked in when the item just TOUCHES the block above the hopper
-- This is the reason for the Y calculation.
-- Test: Items on farmland and slabs get sucked, but items on full blocks don't
2017-01-17 16:50:56 +00:00
local posob = object : getpos ( )
2017-03-15 17:33:16 +00:00
local posob_miny = posob.y + object : get_properties ( ) . collisionbox [ 2 ]
if math.abs ( posob.x - pos.x ) <= 0.5 and ( posob_miny - pos.y < 1.5 and posob.y - pos.y >= 0.3 ) then
2017-01-17 16:50:56 +00:00
inv : add_item ( " main " , ItemStack ( object : get_luaentity ( ) . itemstring ) )
object : get_luaentity ( ) . itemstring = " "
object : remove ( )
end
end
end
end
end ,
} )
2017-06-12 17:06:33 +00:00
-- Returns true if itemstack is fuel, but not for lava bucket if destination already has one
local is_transferrable_fuel = function ( itemstack , src_inventory , src_list , dst_inventory , dst_list )
if mcl_util.is_fuel ( itemstack ) then
2017-08-03 14:36:55 +00:00
if itemstack : get_name ( ) == " mcl_buckets:bucket_lava " then
2017-06-12 17:06:33 +00:00
return dst_inventory : is_empty ( dst_list )
else
return true
end
else
return false
end
end
2017-01-17 16:50:56 +00:00
minetest.register_abm ( {
2017-05-14 22:45:54 +00:00
label = " Hopper/container item exchange " ,
2017-01-17 17:41:25 +00:00
nodenames = { " mcl_hoppers:hopper " } ,
2017-02-14 00:32:13 +00:00
neighbors = { " group:container " } ,
2017-01-17 16:50:56 +00:00
interval = 1.0 ,
chance = 1 ,
action = function ( pos , node , active_object_count , active_object_count_wider )
2017-02-14 00:25:02 +00:00
-- Get node pos' for item transfer
local uppos = { x = pos.x , y = pos.y + 1 , z = pos.z }
local downpos = { x = pos.x , y = pos.y - 1 , z = pos.z }
2017-01-17 16:50:56 +00:00
2017-02-14 00:25:02 +00:00
-- Suck an item from the container above into the hopper
local upnode = minetest.get_node ( uppos )
2017-06-29 11:02:53 +00:00
if not minetest.registered_nodes [ upnode.name ] then return end
2017-02-14 00:25:02 +00:00
local g = minetest.registered_nodes [ upnode.name ] . groups.container
2017-08-04 01:42:24 +00:00
local sucked = mcl_util.move_item_container ( uppos , pos )
2017-03-02 22:45:42 +00:00
2017-08-04 00:19:47 +00:00
-- Also suck in non-fuel items from furnace fuel slot
2017-08-04 01:42:24 +00:00
if not sucked and g == 4 then
2017-03-02 22:45:42 +00:00
local finv = minetest.get_inventory ( { type = " node " , pos = uppos } )
if finv and not mcl_util.is_fuel ( finv : get_stack ( " fuel " , 1 ) ) then
2017-08-04 00:19:47 +00:00
mcl_util.move_item_container ( uppos , pos , " fuel " )
2017-03-02 22:45:42 +00:00
end
2017-01-17 16:50:56 +00:00
end
2017-02-14 00:25:02 +00:00
2017-02-14 00:31:24 +00:00
-- Move an item from the hopper into container below
2017-02-21 02:38:24 +00:00
local downnode = minetest.get_node ( downpos )
2017-06-29 11:02:53 +00:00
if not minetest.registered_nodes [ downnode.name ] then return end
2017-02-21 02:38:24 +00:00
g = minetest.registered_nodes [ downnode.name ] . groups.container
2017-08-04 01:00:33 +00:00
mcl_util.move_item_container ( pos , downpos )
2017-01-17 16:50:56 +00:00
end ,
} )
minetest.register_abm ( {
2017-05-14 22:45:54 +00:00
label = " Side-hopper/container item exchange " ,
2017-01-17 17:41:25 +00:00
nodenames = { " mcl_hoppers:hopper_side " } ,
2017-02-14 00:32:13 +00:00
neighbors = { " group:container " } ,
2017-01-17 16:50:56 +00:00
interval = 1.0 ,
chance = 1 ,
action = function ( pos , node , active_object_count , active_object_count_wider )
2017-02-14 00:25:02 +00:00
-- Determine to which side the hopper is facing, get nodes
local face = minetest.get_node ( pos ) . param2
2017-01-17 16:50:56 +00:00
local front = { }
if face == 0 then
front = { x = pos.x - 1 , y = pos.y , z = pos.z }
elseif face == 1 then
front = { x = pos.x , y = pos.y , z = pos.z + 1 }
elseif face == 2 then
front = { x = pos.x + 1 , y = pos.y , z = pos.z }
elseif face == 3 then
front = { x = pos.x , y = pos.y , z = pos.z - 1 }
end
2017-02-14 00:25:02 +00:00
local above = { x = pos.x , y = pos.y + 1 , z = pos.z }
2017-01-17 16:50:56 +00:00
2017-02-14 00:25:02 +00:00
local frontnode = minetest.get_node ( front )
2017-06-29 11:02:53 +00:00
if not minetest.registered_nodes [ frontnode.name ] then return end
2017-02-22 13:00:58 +00:00
2017-02-14 00:25:02 +00:00
-- Suck an item from the container above into the hopper
local abovenode = minetest.get_node ( above )
2017-06-29 11:02:53 +00:00
if not minetest.registered_nodes [ abovenode.name ] then return end
2017-02-14 00:25:02 +00:00
local g = minetest.registered_nodes [ abovenode.name ] . groups.container
2017-08-04 00:19:47 +00:00
mcl_util.move_item_container ( above , pos )
2017-02-14 00:31:24 +00:00
-- Move an item from the hopper into the container to which the hopper points to
2017-02-21 01:09:34 +00:00
local g = minetest.registered_nodes [ frontnode.name ] . groups.container
2017-08-04 01:00:33 +00:00
if g == 2 or g == 3 or g == 5 or g == 6 then
2017-08-04 00:19:47 +00:00
mcl_util.move_item_container ( pos , front )
2017-02-21 01:09:34 +00:00
elseif g == 4 then
2017-02-21 02:22:25 +00:00
-- Put fuel into fuel slot
2017-02-21 02:38:24 +00:00
local sinv = minetest.get_inventory ( { type = " node " , pos = pos } )
2017-06-12 17:06:33 +00:00
local dinv = minetest.get_inventory ( { type = " node " , pos = front } )
2017-08-04 01:00:33 +00:00
local slot_id , stack = mcl_util.get_eligible_transfer_item_slot ( sinv , " main " , dinv , " fuel " , is_transferrable_fuel )
2017-02-21 02:22:25 +00:00
if slot_id then
2017-08-04 00:19:47 +00:00
mcl_util.move_item_container ( pos , front , nil , slot_id , " fuel " )
2017-02-21 02:22:25 +00:00
end
2017-02-21 01:09:34 +00:00
end
2017-02-14 00:25:02 +00:00
end
2017-01-17 16:50:56 +00:00
} )
minetest.register_craft ( {
2017-02-22 13:00:58 +00:00
output = " mcl_hoppers:hopper " ,
2017-01-17 16:50:56 +00:00
recipe = {
2017-02-11 20:14:40 +00:00
{ " mcl_core:iron_ingot " , " " , " mcl_core:iron_ingot " } ,
{ " mcl_core:iron_ingot " , " mcl_chests:chest " , " mcl_core:iron_ingot " } ,
{ " " , " mcl_core:iron_ingot " , " " } ,
2017-01-17 16:50:56 +00:00
}
} )
2017-02-22 13:00:58 +00:00
2017-03-20 17:12:05 +00:00
-- Add entry aliases for the Help
if minetest.get_modpath ( " doc " ) then
doc.add_entry_alias ( " nodes " , " mcl_hoppers:hopper " , " nodes " , " mcl_hoppers:hopper_side " )
end
2017-02-22 13:00:58 +00:00
-- Legacy
minetest.register_alias ( " mcl_hoppers:hopper_item " , " mcl_hoppers:hopper " )