2021-05-29 14:12:33 +00:00
local S = minetest.get_translator ( minetest.get_current_modname ( ) )
2017-01-17 16:50:56 +00:00
2022-11-13 23:42:41 +00:00
local LOGGING_ON = minetest.settings : get_bool ( " mcl_logging_hoppers " , false )
local function mcl_log ( message )
if LOGGING_ON then
mcl_util.mcl_log ( message , " [Hoppers] " , true )
end
end
2018-01-10 15:44:50 +00:00
--[[ BEGIN OF NODE DEFINITIONS ]]
2017-01-17 17:41:25 +00:00
local mcl_hoppers_formspec =
2017-01-17 17:17:53 +00:00
" size[9,7] " ..
2021-04-19 12:44:20 +00:00
" label[2,0; " .. minetest.formspec_escape ( minetest.colorize ( " #313131 " , S ( " Hopper " ) ) ) .. " ] " ..
2021-06-11 22:09:39 +00:00
" list[context;main;2,0.5;5,1;] " ..
2020-03-24 17:48:14 +00:00
mcl_formspec.get_itemslot_bg ( 2 , 0.5 , 5 , 1 ) ..
2021-04-19 12:44:20 +00:00
" label[0,2; " .. minetest.formspec_escape ( minetest.colorize ( " #313131 " , S ( " Inventory " ) ) ) .. " ] " ..
2017-01-17 17:17:53 +00:00
" list[current_player;main;0,2.5;9,3;9] " ..
2020-03-24 17:48:14 +00:00
mcl_formspec.get_itemslot_bg ( 0 , 2.5 , 9 , 3 ) ..
2017-01-17 17:17:53 +00:00
" list[current_player;main;0,5.74;9,1;] " ..
2020-03-24 17:48:14 +00:00
mcl_formspec.get_itemslot_bg ( 0 , 5.74 , 9 , 1 ) ..
2021-06-11 22:09:39 +00:00
" listring[context;main] " ..
2017-01-17 17:17:53 +00:00
" listring[current_player;main] "
2017-01-17 16:50:56 +00:00
2018-01-10 15:16:34 +00:00
-- Downwards hopper (base definition)
local def_hopper = {
inventory_image = " mcl_hoppers_item.png " ,
2017-02-22 13:00:58 +00:00
wield_image = " mcl_hoppers_item.png " ,
2019-12-13 09:20:08 +00:00
groups = { pickaxey = 1 , container = 2 , deco_block = 1 , hopper = 1 } ,
2017-01-17 16:50:56 +00:00
drawtype = " nodebox " ,
paramtype = " light " ,
2018-01-22 17:06:12 +00:00
-- FIXME: mcl_hoppers_hopper_inside.png is unused by hoppers.
tiles = { " mcl_hoppers_hopper_inside.png^mcl_hoppers_hopper_top.png " , " mcl_hoppers_hopper_outside.png " , " mcl_hoppers_hopper_outside.png " , " mcl_hoppers_hopper_outside.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-01-17 17:30:35 +00:00
after_dig_node = function ( pos , oldnode , oldmetadata , digger )
local meta = minetest.get_meta ( pos )
2021-11-19 14:22:40 +00:00
local meta2 = meta : to_table ( )
2017-01-17 17:30:35 +00:00
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
2021-11-19 14:22:40 +00:00
meta : from_table ( meta2 )
2017-01-17 16:50:56 +00:00
end ,
2019-02-08 20:59:01 +00: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-01-17 16:50:56 +00:00
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 ,
2018-01-10 15:16:34 +00:00
on_metadata_inventory_put = function ( pos , listname , index , stack , player )
2017-01-17 16:50:56 +00:00
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 ,
2018-01-10 15:16:34 +00:00
on_metadata_inventory_take = function ( pos , listname , index , stack , player )
2017-01-17 16:50:56 +00:00
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 ( ) ,
2018-01-10 15:16:34 +00:00
2020-04-17 19:40:13 +00:00
_mcl_blast_resistance = 4.8 ,
2017-02-27 00:33:34 +00:00
_mcl_hardness = 3 ,
2018-01-10 15:16:34 +00:00
}
-- Redstone variants (on/off) of downwards hopper.
-- Note a hopper is enabled when it is *not* supplied with redstone power and disabled when it is supplied with redstone power.
-- Enabled downwards hopper
local def_hopper_enabled = table.copy ( def_hopper )
2019-03-07 23:22:28 +00:00
def_hopper_enabled.description = S ( " Hopper " )
2020-02-19 03:54:17 +00:00
def_hopper_enabled._tt_help = S ( " 5 inventory slots " ) .. " \n " .. S ( " Collects items from above, moves items to container below " ) .. " \n " .. S ( " Can be disabled with redstone power " )
2019-03-15 05:12:03 +00:00
def_hopper_enabled._doc_items_longdesc = S ( " Hoppers are containers with 5 inventory slots. They collect dropped items from above, take items from a container above and attempt 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. " ) .. " \n \n " ..
2018-01-10 15:16:34 +00:00
2019-03-15 05:12:03 +00:00
S ( " Hoppers interact with containers the following way: " ) .. " \n " ..
S ( " • 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 that point to the furnace put items into the fuel slot " ) .. " \n " ..
S ( " • Ender chests: No interaction. " ) .. " \n " ..
S ( " • Other containers: Normal interaction. " ) .. " \n \n " ..
2018-01-10 15:16:34 +00:00
2019-03-15 05:12:03 +00:00
S ( " Hoppers can be disabled when supplied with redstone power. Disabled hoppers don't move items. " )
def_hopper_enabled._doc_items_usagehelp = S ( " 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. Use the hopper to access its inventory. " )
2018-01-10 15:16:34 +00:00
def_hopper_enabled.on_place = function ( itemstack , placer , pointed_thing )
local upos = pointed_thing.under
local apos = pointed_thing.above
local uposnode = minetest.get_node ( upos )
local uposnodedef = minetest.registered_nodes [ uposnode.name ]
if not uposnodedef then return itemstack end
-- 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
local x = upos.x - apos.x
local z = upos.z - apos.z
2018-01-10 15:44:50 +00:00
local fake_itemstack = ItemStack ( itemstack )
2021-04-15 21:41:34 +00:00
local param2
2018-01-10 15:16:34 +00:00
if x == - 1 then
2018-01-10 15:44:50 +00:00
fake_itemstack : set_name ( " mcl_hoppers:hopper_side " )
param2 = 0
2018-01-10 15:16:34 +00:00
elseif x == 1 then
2018-01-10 15:44:50 +00:00
fake_itemstack : set_name ( " mcl_hoppers:hopper_side " )
param2 = 2
2018-01-10 15:16:34 +00:00
elseif z == - 1 then
2018-01-10 15:44:50 +00:00
fake_itemstack : set_name ( " mcl_hoppers:hopper_side " )
param2 = 3
2018-01-10 15:16:34 +00:00
elseif z == 1 then
2018-01-10 15:44:50 +00:00
fake_itemstack : set_name ( " mcl_hoppers:hopper_side " )
param2 = 1
2018-01-10 15:16:34 +00:00
end
2021-04-15 21:41:34 +00:00
local itemstack , _ = minetest.item_place_node ( fake_itemstack , placer , pointed_thing , param2 )
2018-01-10 15:44:50 +00:00
itemstack : set_name ( " mcl_hoppers:hopper " )
2018-01-10 15:16:34 +00:00
return itemstack
end
def_hopper_enabled.mesecons = {
effector = {
action_on = function ( pos , node )
minetest.swap_node ( pos , { name = " mcl_hoppers:hopper_disabled " , param2 = node.param2 } )
end ,
} ,
}
minetest.register_node ( " mcl_hoppers:hopper " , def_hopper_enabled )
-- Disabled downwards hopper
local def_hopper_disabled = table.copy ( def_hopper )
2019-03-07 23:22:28 +00:00
def_hopper_disabled.description = S ( " Disabled Hopper " )
2019-12-09 21:32:40 +00:00
def_hopper_disabled.inventory_image = nil
2018-01-10 15:16:34 +00:00
def_hopper_disabled._doc_items_create_entry = false
def_hopper_disabled.groups . not_in_creative_inventory = 1
def_hopper_disabled.drop = " mcl_hoppers:hopper "
def_hopper_disabled.mesecons = {
effector = {
action_off = function ( pos , node )
minetest.swap_node ( pos , { name = " mcl_hoppers:hopper " , param2 = node.param2 } )
end ,
} ,
}
minetest.register_node ( " mcl_hoppers:hopper_disabled " , def_hopper_disabled )
2017-01-17 16:50:56 +00:00
2017-12-05 13:09:39 +00:00
local on_rotate
if minetest.get_modpath ( " screwdriver " ) then
on_rotate = screwdriver.rotate_simple
end
2018-01-10 15:16:34 +00:00
-- Sidewars hopper (base definition)
local def_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 " ,
2019-12-13 09:20:08 +00:00
groups = { pickaxey = 1 , container = 2 , not_in_creative_inventory = 1 , hopper = 2 } ,
2017-01-17 16:50:56 +00:00
drawtype = " nodebox " ,
paramtype = " light " ,
paramtype2 = " facedir " ,
2018-01-22 17:06:12 +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_outside.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 ,
2019-02-08 20:59:01 +00: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-01-17 16:50:56 +00:00
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 ,
2018-01-10 15:16:34 +00:00
on_metadata_inventory_put = function ( pos , listname , index , stack , player )
2017-01-17 16:50:56 +00:00
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 ,
2018-01-10 15:16:34 +00:00
on_metadata_inventory_take = function ( pos , listname , index , stack , player )
2017-01-17 16:50:56 +00:00
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-12-05 13:09:39 +00:00
on_rotate = on_rotate ,
2017-02-11 17:46:23 +00:00
sounds = mcl_sounds.node_sound_metal_defaults ( ) ,
2018-01-10 15:16:34 +00:00
2020-04-17 19:40:13 +00:00
_mcl_blast_resistance = 4.8 ,
2017-02-27 00:33:34 +00:00
_mcl_hardness = 3 ,
2018-01-10 15:16:34 +00:00
}
local def_hopper_side_enabled = table.copy ( def_hopper_side )
2019-03-07 23:22:28 +00:00
def_hopper_side_enabled.description = S ( " Side Hopper " )
2018-01-10 15:16:34 +00:00
def_hopper_side_enabled.mesecons = {
effector = {
action_on = function ( pos , node )
minetest.swap_node ( pos , { name = " mcl_hoppers:hopper_side_disabled " , param2 = node.param2 } )
end ,
} ,
}
minetest.register_node ( " mcl_hoppers:hopper_side " , def_hopper_side_enabled )
local def_hopper_side_disabled = table.copy ( def_hopper_side )
2019-03-07 23:22:28 +00:00
def_hopper_side_disabled.description = S ( " Disabled Side Hopper " )
2018-01-10 15:16:34 +00:00
def_hopper_side_disabled.mesecons = {
effector = {
action_off = function ( pos , node )
minetest.swap_node ( pos , { name = " mcl_hoppers:hopper_side " , param2 = node.param2 } )
end ,
} ,
}
minetest.register_node ( " mcl_hoppers:hopper_side_disabled " , def_hopper_side_disabled )
--[[ END OF NODE DEFINITIONS ]]
2022-11-13 23:42:41 +00:00
local function hopper_pull_from_mc ( mc_ent , dest_pos )
local inv = mcl_entity_invs.load_inv ( mc_ent , 5 )
if not inv then
mcl_log ( " No inv " )
return false
end
local dest_meta = minetest.get_meta ( dest_pos )
local dest_inv = dest_meta : get_inventory ( )
if not dest_inv then
mcl_log ( " No dest inv " )
return
end
mcl_log ( " inv. size: " .. mc_ent._inv_size )
for i = 1 , mc_ent._inv_size , 1 do
local stack = inv : get_stack ( " main " , i )
mcl_log ( " i: " .. tostring ( i ) )
mcl_log ( " Name: [ " .. tostring ( stack : get_name ( ) ) .. " ] " )
mcl_log ( " Count: " .. tostring ( stack : get_count ( ) ) )
mcl_log ( " stack max: " .. tostring ( stack : get_stack_max ( ) ) )
if not stack : get_name ( ) or stack : get_name ( ) ~= " " then
2022-11-14 02:10:19 +00:00
if dest_inv : room_for_item ( " main " , stack : peek_item ( ) ) then
2022-11-13 23:42:41 +00:00
mcl_log ( " Room so unload " )
2022-11-14 02:10:19 +00:00
dest_inv : add_item ( " main " , stack : take_item ( ) )
inv : set_stack ( " main " , i , stack )
2022-11-13 23:42:41 +00:00
2022-11-14 02:10:19 +00:00
-- Take one item and stop until next time
2022-11-13 23:42:41 +00:00
return
else
mcl_log ( " no Room " )
end
else
mcl_log ( " nothing there " )
end
end
end
2018-01-10 15:16:34 +00:00
--[[ BEGIN OF ABM DEFINITONS ]]
2017-02-14 00:37:30 +00:00
2022-11-13 23:42:41 +00:00
minetest.register_abm ( {
label = " Hoppers pull from minecart hoppers " ,
nodenames = { " mcl_hoppers:hopper " , " mcl_hoppers:hopper_side " } ,
interval = 0.5 ,
chance = 1 ,
action = function ( pos , node , active_object_count , active_object_count_wider )
mcl_log ( " ABM for: " .. minetest.pos_to_string ( pos ) )
local objs = minetest.get_objects_inside_radius ( pos , 3 )
if objs and # objs > 0 then
for k , v in pairs ( objs ) do
local entity = v : get_luaentity ( )
if entity and entity.name then
--mcl_log("Name of object near: " .. tostring(entity.name))
if entity.name == " mcl_minecarts:hopper_minecart " then
local hm_pos = entity.object : get_pos ( )
mcl_log ( " We have a hopper minecart close: " .. minetest.pos_to_string ( hm_pos ) )
--if hm_pos.y == pos.y + 1 then mcl_log("y is correct") end
--if (hm_pos.x >= pos.x - DIST_FROM_MC and hm_pos.x <= pos.x + DIST_FROM_MC) then mcl_log("x is within range") end
--if (hm_pos.z >= pos.z - DIST_FROM_MC and hm_pos.z <= pos.z + DIST_FROM_MC) then mcl_log("z is within range") end
local DIST_FROM_MC = 1.5
if ( hm_pos.y == pos.y + 1 )
and ( hm_pos.x >= pos.x - DIST_FROM_MC and hm_pos.x <= pos.x + DIST_FROM_MC )
and ( hm_pos.z >= pos.z - DIST_FROM_MC and hm_pos.z <= pos.z + DIST_FROM_MC ) then
mcl_log ( " Minecart close enough " )
hopper_pull_from_mc ( entity , pos )
end
end
else
mcl_log ( " no entity " )
end
end
else
mcl_log ( " objs missing " )
end
end ,
} )
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)
2022-02-23 16:39:33 +00:00
if minetest.get_item_group ( abovenode.name , " container " ) ~= 0 then
2017-02-14 00:37:30 +00:00
return
end
local meta = minetest.get_meta ( pos )
2017-01-17 16:50:56 +00:00
local inv = meta : get_inventory ( )
2021-03-16 16:39:06 +00:00
for _ , object in pairs ( minetest.get_objects_inside_radius ( pos , 2 ) ) do
2021-12-09 17:20:24 +00:00
if not object : is_player ( ) and object : get_luaentity ( ) and object : get_luaentity ( ) . name == " __builtin:item " and not object : get_luaentity ( ) . _removed then
2017-01-17 16:50:56 +00:00
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
2019-02-01 05:33:07 +00:00
local posob = object : get_pos ( )
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
2022-02-19 15:15:36 +00:00
local g = minetest.get_item_group ( upnode.name , " 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-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
2022-02-19 15:15:36 +00:00
local g = minetest.get_item_group ( abovenode.name , " container " )
2020-03-29 14:05:30 +00:00
local sucked = mcl_util.move_item_container ( above , pos )
2017-02-14 00:31:24 +00:00
2019-12-09 07:51:25 +00:00
-- Also suck in non-fuel items from furnace fuel slot
if not sucked and g == 4 then
local finv = minetest.get_inventory ( { type = " node " , pos = above } )
if finv and not mcl_util.is_fuel ( finv : get_stack ( " fuel " , 1 ) ) then
mcl_util.move_item_container ( above , pos , " fuel " )
end
end
2017-02-14 00:31:24 +00:00
-- Move an item from the hopper into the container to which the hopper points to
2022-02-19 15:15:36 +00:00
local g = minetest.get_item_group ( frontnode.name , " 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 } )
2021-04-15 21:41:34 +00:00
local slot_id , _ = 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
} )
2022-11-08 01:10:35 +00:00
minetest.register_abm ( {
label = " Bonemeal extraction from composter " ,
nodenames = { " mcl_hoppers:hopper " , " mcl_hoppers:hopper_side " } ,
neighbors = { " mcl_composters:composter_ready " } ,
interval = 1.0 ,
chance = 1 ,
action = function ( pos , node , active_object_count , active_object_count_wider )
local uppos = { x = pos.x , y = pos.y + 1 , z = pos.z }
local downpos = { x = pos.x , y = pos.y - 1 , z = pos.z }
local meta = minetest.get_meta ( pos )
local inv = meta : get_inventory ( )
-- Get bonemeal from composter above
local upnode = minetest.get_node ( uppos )
if upnode.name == " mcl_composters:composter_ready " then
minetest.swap_node ( uppos , { name = " mcl_composters:composter " } )
inv : add_item ( " main " , " mcl_dye:white " )
end
end ,
} )
minetest.register_abm ( {
label = " Add compostable items on composter " ,
nodenames = { " mcl_hoppers:hopper " } ,
neighbors = { " mcl_composters:composter " , " mcl_composters:composter_1 " , " mcl_composters:composter_2 " ,
" mcl_composters:composter_3 " , " mcl_composters:composter_4 " , " mcl_composters:composter_5 " ,
" mcl_composters:composter_6 " , " mcl_composters:composter_7 " , } ,
interval = 1.0 ,
chance = 1 ,
action = function ( pos , node , active_object_count , active_object_count_wider )
2022-11-12 09:28:36 +00:00
local uppos = { x = pos.x , y = pos.y + 1 , z = pos.z }
local downpos = { x = pos.x , y = pos.y - 1 , z = pos.z }
local meta = minetest.get_meta ( pos )
2022-11-08 01:10:35 +00:00
local inv = meta : get_inventory ( )
2022-11-12 09:28:36 +00:00
--Consume compostable items and update composter below
local downnode = minetest.get_node ( downpos )
if downnode.name == " mcl_composters:composter " or downnode.name == " mcl_composters:composter_1 "
or downnode.name == " mcl_composters:composter_2 " or downnode.name == " mcl_composters:composter_3 "
or downnode.name == " mcl_composters:composter_4 " or downnode.name == " mcl_composters:composter_5 "
or downnode.name == " mcl_composters:composter_6 " or downnode.name == " mcl_composters:composter_7 " then
local itemcomp = inv : get_list ( " main " )
local hslot = mcl_util.get_first_occupied_inventory_slot ( minetest.get_inventory ( { type = " node " , pos = pos } ) , " main " )
if hslot == nil then return end
local compchance = minetest.get_item_group ( itemcomp [ hslot ] : get_name ( ) , " compostability " )
if compchance == 0 then
hslot = hslot + 1
if hslot == 6 then return end
compchance = minetest.get_item_group ( itemcomp [ hslot ] : get_name ( ) , " compostability " )
if compchance == 0 then
hslot = hslot + 1
if hslot == 6 then return end
compchance = minetest.get_item_group ( itemcomp [ hslot ] : get_name ( ) , " compostability " )
if compchance == 0 then
hslot = hslot + 1
if hslot == 6 then return end
compchance = minetest.get_item_group ( itemcomp [ hslot ] : get_name ( ) , " compostability " )
2022-11-08 22:18:35 +00:00
if compchance == 0 then
hslot = hslot + 1
2022-11-12 09:28:36 +00:00
if hslot == 6 then return end
compchance = minetest.get_item_group ( itemcomp [ hslot ] : get_name ( ) , " compostability " )
end
end
end
end
2022-11-08 01:10:35 +00:00
if compchance > 0 then
2022-11-12 09:28:36 +00:00
itemcomp [ hslot ] : take_item ( )
inv : set_list ( " main " , itemcomp )
local rand = math.random ( 0 , 100 )
if compchance >= rand then
local level = 0
if downnode.name == " mcl_composters:composter_1 " then
level = 1
elseif downnode.name == " mcl_composters:composter_2 " then
level = 2
elseif downnode.name == " mcl_composters:composter_3 " then
level = 3
elseif downnode.name == " mcl_composters:composter_4 " then
level = 4
elseif downnode.name == " mcl_composters:composter_5 " then
level = 5
elseif downnode.name == " mcl_composters:composter_6 " then
level = 6
elseif downnode.name == " mcl_composters:composter_7 " then
level = 7
end
mcl_dye.add_bone_meal_particle ( vector.offset ( downpos , 0 , level / 8 , 0 ) )
if level < 7 then
level = level + 1
else
level = " ready "
end
minetest.swap_node ( downpos , { name = " mcl_composters:composter_ " .. level } )
2022-11-08 01:10:35 +00:00
end
end
end
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 " )
2020-03-29 12:35:01 +00:00
minetest.register_lbm ( {
label = " Update hopper formspecs (0.60.0 " ,
name = " mcl_hoppers:update_formspec_0_60_0 " ,
nodenames = { " group:hopper " } ,
run_at_every_load = false ,
action = function ( pos , node )
local meta = minetest.get_meta ( pos )
meta : set_string ( " formspec " , mcl_hoppers_formspec )
end ,
} )