2017-02-14 01:15:51 +00:00
--[[ This mod registers 3 nodes:
2017-02-14 01:33:58 +00: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 01:15:51 +00: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 .
] ]
2021-05-29 14:12:33 +00:00
local S = minetest.get_translator ( minetest.get_current_modname ( ) )
2022-09-10 09:39:10 +00:00
local C = minetest.colorize
local F = minetest.formspec_escape
2019-03-08 00:07:41 +00:00
2022-09-10 09:39:10 +00:00
local dropper_formspec = table.concat ( {
" formspec_version[4] " ,
" size[11.75,10.425] " ,
" label[4.125,0.375; " .. F ( C ( mcl_formspec.label_color , S ( " Dropper " ) ) ) .. " ] " ,
mcl_formspec.get_itemslot_bg_v4 ( 4.125 , 0.75 , 3 , 3 ) ,
" list[context;main;4.125,0.75;3,3;] " ,
" label[0.375,4.7; " .. F ( C ( mcl_formspec.label_color , S ( " Inventory " ) ) ) .. " ] " ,
mcl_formspec.get_itemslot_bg_v4 ( 0.375 , 5.1 , 9 , 3 ) ,
" list[current_player;main;0.375,5.1;9,3;9] " ,
mcl_formspec.get_itemslot_bg_v4 ( 0.375 , 9.05 , 9 , 1 ) ,
" list[current_player;main;0.375,9.05;9,1;] " ,
" listring[context;main] " ,
" listring[current_player;main] " ,
} )
---For after_place_node
---@param pos Vector
2021-05-29 14:12:33 +00:00
local function setup_dropper ( pos )
2017-02-14 01:20:40 +00:00
-- Set formspec and inventory
2017-02-14 01:15:51 +00:00
local meta = minetest.get_meta ( pos )
2022-09-10 09:39:10 +00:00
meta : set_string ( " formspec " , dropper_formspec )
2017-02-14 01:15:51 +00:00
local inv = meta : get_inventory ( )
inv : set_size ( " main " , 9 )
end
2021-05-29 14:12:33 +00:00
local function orientate_dropper ( pos , placer )
2018-01-11 00:28:36 +00:00
-- 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
2022-09-10 09:39:10 +00:00
minetest.swap_node ( pos , { name = " mcl_droppers:dropper_up " } )
2018-01-11 00:28:36 +00:00
elseif pitch < - 55 then
2022-09-10 09:39:10 +00:00
minetest.swap_node ( pos , { name = " mcl_droppers:dropper_down " } )
2018-01-11 00:28:36 +00:00
end
end
2017-12-05 13:09:39 +00:00
local on_rotate
if minetest.get_modpath ( " screwdriver " ) then
on_rotate = screwdriver.rotate_simple
end
2017-02-14 01:15:51 +00:00
-- Shared core definition table
local dropperdef = {
2017-02-13 17:25:11 +00: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 )
2021-11-29 18:12:49 +00:00
local meta2 = meta : to_table ( )
2017-02-13 17:25:11 +00:00
meta : from_table ( oldmetadata )
local inv = meta : get_inventory ( )
2022-09-10 09:39:10 +00:00
for i = 1 , inv : get_size ( " main " ) do
2017-02-13 17:25:11 +00:00
local stack = inv : get_stack ( " main " , i )
if not stack : is_empty ( ) then
2023-08-19 16:27:00 +00:00
minetest.add_item ( vector.offset ( pos , math.random ( 0 , 10 ) / 10 - 0.5 , 0 , math.random ( 0 , 10 ) / 10 - 0.5 ) , stack )
2017-02-13 17:25:11 +00:00
end
end
2021-11-29 18:12:49 +00:00
meta : from_table ( meta2 )
2017-02-13 17:25:11 +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 ,
2020-04-17 19:40:13 +00:00
_mcl_blast_resistance = 3.5 ,
2017-02-27 00:52:24 +00:00
_mcl_hardness = 3.5 ,
2022-09-10 09:39:10 +00:00
mesecons = { effector = {
2017-02-13 17:25:11 +00:00
-- Drop random item when triggered
2021-05-29 14:12:33 +00:00
action_on = function ( pos , node )
2023-03-24 23:16:12 +00:00
if not pos then return end
2017-02-13 17:25:11 +00:00
local meta = minetest.get_meta ( pos )
local inv = meta : get_inventory ( )
2017-02-14 01:15:51 +00:00
local droppos
2017-02-14 01:33:58 +00:00
if node.name == " mcl_droppers:dropper " then
2022-09-10 09:39:10 +00:00
droppos = vector.subtract ( pos , minetest.facedir_to_dir ( node.param2 ) )
2017-02-14 01:33:58 +00:00
elseif node.name == " mcl_droppers:dropper_up " then
2023-08-19 16:27:00 +00:00
droppos = vector.offset ( pos , 0 , 1 , 0 )
2017-02-14 01:33:58 +00:00
elseif node.name == " mcl_droppers:dropper_down " then
2023-08-19 16:27:00 +00:00
droppos = vector.offset ( pos , 0 , - 1 , 0 )
2017-02-14 01:15:51 +00:00
end
2017-02-13 17:25:11 +00:00
local dropnode = minetest.get_node ( droppos )
2017-02-13 23:10:37 +00: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 17:25:11 +00:00
return
end
local stacks = { }
2022-09-10 09:39:10 +00:00
for i = 1 , inv : get_size ( " main " ) do
2017-02-13 17:25:11 +00:00
local stack = inv : get_stack ( " main " , i )
if not stack : is_empty ( ) then
2022-09-10 09:39:10 +00:00
table.insert ( stacks , { stack = stack , stackpos = i } )
2017-02-13 17:25:11 +00:00
end
end
if # stacks >= 1 then
local r = math.random ( 1 , # stacks )
local stack = stacks [ r ] . stack
2017-06-12 20:27:37 +00:00
local dropitem = ItemStack ( stack )
dropitem : set_count ( 1 )
2017-02-13 23:10:37 +00:00
local stack_id = stacks [ r ] . stackpos
2017-02-13 23:44:23 +00:00
-- If it's a container, attempt to put it into the container
2017-08-04 00:19:47 +00:00
local dropped = mcl_util.move_item_container ( pos , droppos , nil , stack_id )
2017-02-13 23:44:23 +00:00
-- No container?
if not dropped and not dropnodedef.groups . container then
-- Drop item normally
2022-07-22 12:38:36 +00:00
local pos_variation = 100
2023-08-19 16:27:00 +00:00
droppos = vector.offset ( droppos ,
math.random ( - pos_variation , pos_variation ) / 1000 ,
math.random ( - pos_variation , pos_variation ) / 1000 ,
math.random ( - pos_variation , pos_variation ) / 1000
)
2022-07-22 12:38:36 +00:00
local item_entity = minetest.add_item ( droppos , dropitem )
local drop_vel = vector.subtract ( droppos , pos )
local speed = 3
2022-09-10 09:39:10 +00:00
item_entity : set_velocity ( vector.multiply ( drop_vel , speed ) )
2017-02-13 23:10:37 +00:00
stack : take_item ( )
inv : set_stack ( " main " , stack_id , stack )
end
2017-02-13 17:25:11 +00:00
end
2017-09-14 00:20:47 +00:00
end ,
rules = mesecon.rules . alldirs ,
2022-09-10 09:39:10 +00:00
} } ,
2017-12-05 13:09:39 +00:00
on_rotate = on_rotate ,
2017-02-14 01:15:51 +00:00
}
-- Horizontal dropper
local horizontal_def = table.copy ( dropperdef )
2019-03-08 00:07:41 +00:00
horizontal_def.description = S ( " Dropper " )
2022-09-10 09:39:10 +00:00
horizontal_def._tt_help = S ( " 9 inventory slots " ) .. " \n " .. S ( " Drops item when powered by redstone power " )
2019-03-08 00:07:41 +00:00
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 01:00:48 +00: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. " )
2021-05-29 14:12:33 +00:00
function horizontal_def . after_place_node ( pos , placer , itemstack , pointed_thing )
2017-02-14 01:15:51 +00:00
setup_dropper ( pos )
2018-01-11 00:28:36 +00:00
orientate_dropper ( pos , placer )
2017-02-14 01:15:51 +00:00
end
2022-09-10 09:39:10 +00:00
2017-02-14 01:15:51 +00:00
horizontal_def.tiles = {
" default_furnace_top.png " , " default_furnace_bottom.png " ,
" default_furnace_side.png " , " default_furnace_side.png " ,
2017-02-14 01:33:58 +00:00
" default_furnace_side.png " , " mcl_droppers_dropper_front_horizontal.png "
2017-02-14 01:15:51 +00:00
}
horizontal_def.paramtype2 = " facedir "
2022-09-10 09:39:10 +00:00
horizontal_def.groups = { pickaxey = 1 , container = 2 , material_stone = 1 }
2017-02-14 01:15:51 +00:00
2017-02-14 01:33:58 +00:00
minetest.register_node ( " mcl_droppers:dropper " , horizontal_def )
2017-02-14 01:15:51 +00:00
-- Down dropper
local down_def = table.copy ( dropperdef )
2019-03-08 00:07:41 +00:00
down_def.description = S ( " Downwards-Facing Dropper " )
2017-02-14 01:15:51 +00:00
down_def.after_place_node = setup_dropper
down_def.tiles = {
2017-02-14 01:33:58 +00:00
" default_furnace_top.png " , " mcl_droppers_dropper_front_vertical.png " ,
2017-02-14 01:15:51 +00:00
" default_furnace_side.png " , " default_furnace_side.png " ,
" default_furnace_side.png " , " default_furnace_side.png "
}
2022-09-10 09:39:10 +00:00
down_def.groups = { pickaxey = 1 , container = 2 , not_in_creative_inventory = 1 , material_stone = 1 }
2017-03-02 18:53:53 +00:00
down_def._doc_items_create_entry = false
2017-02-14 01:33:58 +00:00
down_def.drop = " mcl_droppers:dropper "
minetest.register_node ( " mcl_droppers:dropper_down " , down_def )
2017-02-13 17:25:11 +00:00
2017-02-14 01:15:51 +00:00
-- Up dropper
-- The up dropper is almost identical to the down dropper, it only differs in textures
2017-08-01 23:34:12 +00:00
local up_def = table.copy ( down_def )
2019-03-08 00:07:41 +00:00
up_def.description = S ( " Upwards-Facing Dropper " )
2017-02-14 01:15:51 +00:00
up_def.tiles = {
2017-02-14 01:33:58 +00:00
" mcl_droppers_dropper_front_vertical.png " , " default_furnace_bottom.png " ,
2017-02-14 01:15:51 +00:00
" default_furnace_side.png " , " default_furnace_side.png " ,
" default_furnace_side.png " , " default_furnace_side.png "
}
2017-02-14 01:33:58 +00:00
minetest.register_node ( " mcl_droppers:dropper_up " , up_def )
2017-02-14 01:20:40 +00:00
-- Ladies and gentlemen, I present to you: the crafting recipe!
minetest.register_craft ( {
2021-05-29 14:12:33 +00:00
output = " mcl_droppers:dropper " ,
2017-02-14 01:20:40 +00:00
recipe = {
2022-09-10 09:39:10 +00:00
{ " mcl_core:cobble " , " mcl_core:cobble " , " mcl_core:cobble " , } ,
{ " mcl_core:cobble " , " " , " mcl_core:cobble " , } ,
{ " mcl_core:cobble " , " mesecons:redstone " , " mcl_core:cobble " , } ,
2017-02-14 01:20:40 +00:00
}
} )
2017-03-21 03:27:50 +00: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 15:08:29 +00:00
2020-03-29 12:35:01 +00:00
-- Legacy
2019-03-21 15:08:29 +00:00
minetest.register_lbm ( {
2020-03-29 12:35:01 +00:00
label = " Update dropper formspecs (0.60.0) " ,
name = " mcl_droppers:update_formspecs_0_60_0 " ,
2019-03-21 15:08:29 +00:00
nodenames = { " mcl_droppers:dropper " , " mcl_droppers:dropper_down " , " mcl_droppers:dropper_up " } ,
action = function ( pos , node )
setup_dropper ( pos )
2022-09-10 09:39:10 +00:00
minetest.log ( " action " , " [mcl_droppers] Node formspec updated at " .. minetest.pos_to_string ( pos ) )
2019-03-21 15:08:29 +00:00
end ,
} )