{"action":"created","issue":{"url":"https://api.github.com/repos/minetest/minetest_game/issues/430","labels_url":"https://api.github.com/repos/minetest/minetest_game/issues/430/labels{/name}","comments_url":"https://api.github.com/repos/minetest/minetest_game/issues/430/comments","events_url":"https://api.github.com/repos/minetest/minetest_game/issues/430/events","html_url":"https://github.com/minetest/minetest_game/issues/430","id":57706184,"number":430,"title":"Ability to stack empty buckets","user":{"login":"tenplus1","id":8145060,"avatar_url":"https://avatars.githubusercontent.com/u/8145060?v=3","gravatar_id":"","url":"https://api.github.com/users/tenplus1","html_url":"https://github.com/tenplus1","followers_url":"https://api.github.com/users/tenplus1/followers","following_url":"https://api.github.com/users/tenplus1/following{/other_user}","gists_url":"https://api.github.com/users/tenplus1/gists{/gist_id}","starred_url":"https://api.github.com/users/tenplus1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tenplus1/subscriptions","organizations_url":"https://api.github.com/users/tenplus1/orgs","repos_url":"https://api.github.com/users/tenplus1/repos","events_url":"https://api.github.com/users/tenplus1/events{/privacy}","received_events_url":"https://api.github.com/users/tenplus1/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/minetest/minetest_game/labels/invalid","name":"invalid","color":"e6e6e6"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2015-02-14T20:54:23Z","updated_at":"2015-02-14T22:47:00Z","closed_at":null,"body":"It can be very handy being able to stack empty buckets and being able to fill one of the stack without losing them all, here's my code to do just that:\r\n\r\n```\r\n-- Minetest 0.4 mod: bucket\r\n-- See README.txt for licensing and other information.\r\n\r\nminetest.register_alias(\"bucket\", \"bucket:bucket_empty\")\r\nminetest.register_alias(\"bucket_water\", \"bucket:bucket_water\")\r\nminetest.register_alias(\"bucket_lava\", \"bucket:bucket_lava\")\r\n\r\nminetest.register_craft({\r\n\toutput = 'bucket:bucket_empty 1',\r\n\trecipe = {\r\n\t\t{'default:steel_ingot', '', 'default:steel_ingot'},\r\n\t\t{'', 'default:steel_ingot', ''},\r\n\t}\r\n})\r\n\r\nbucket = {}\r\nbucket.liquids = {}\r\n\r\nlocal function check_protection(pos, name, text)\r\n\tif minetest.is_protected(pos, name) then\r\n\t\tminetest.log(\"action\", (name ~= \"\" and name or \"A mod\")\r\n\t\t\t.. \" tried to \" .. text\r\n\t\t\t.. \" at protected position \"\r\n\t\t\t.. minetest.pos_to_string(pos)\r\n\t\t\t.. \" with a bucket\")\r\n\t\tminetest.record_protection_violation(pos, name)\r\n\t\treturn true\r\n\tend\r\n\treturn false\r\nend\r\n\r\n-- Register a new liquid\r\n--   source = name of the source node\r\n--   flowing = name of the flowing node\r\n--   itemname = name of the new bucket item (or nil if liquid is not takeable)\r\n--   inventory_image = texture of the new bucket item (ignored if itemname == nil)\r\n-- This function can be called from any mod (that depends on bucket).\r\nfunction bucket.register_liquid(source, flowing, itemname, inventory_image, name)\r\n\tbucket.liquids[source] = {\r\n\t\tsource = source,\r\n\t\tflowing = flowing,\r\n\t\titemname = itemname,\r\n\t}\r\n\tbucket.liquids[flowing] = bucket.liquids[source]\r\n\r\n\tif itemname ~= nil then\r\n\t\tminetest.register_craftitem(itemname, {\r\n\t\t\tdescription = name,\r\n\t\t\tinventory_image = inventory_image,\r\n\t\t\tstack_max = 1,\r\n\t\t\tliquids_pointable = true,\r\n\t\t\ton_place = function(itemstack, user, pointed_thing)\r\n\t\t\t\t-- Must be pointing to node\r\n\t\t\t\tif pointed_thing.type ~= \"node\" then\r\n\t\t\t\t\treturn\r\n\t\t\t\tend\r\n\t\t\t\t\r\n\t\t\t\tlocal node = minetest.get_node_or_nil(pointed_thing.under)\r\n\t\t\t\tlocal ndef\r\n\t\t\t\tif node then\r\n\t\t\t\t\tndef = minetest.registered_nodes[node.name]\r\n\t\t\t\tend\r\n\t\t\t\t-- Call on_rightclick if the pointed node defines it\r\n\t\t\t\tif ndef and ndef.on_rightclick and\r\n\t\t\t\t   user and not user:get_player_control().sneak then\r\n\t\t\t\t\treturn ndef.on_rightclick(\r\n\t\t\t\t\t\tpointed_thing.under,\r\n\t\t\t\t\t\tnode, user,\r\n\t\t\t\t\t\titemstack) or itemstack\r\n\t\t\t\tend\r\n\r\n\t\t\t\tlocal place_liquid = function(pos, node, source, flowing)\r\n\t\t\t\t\tif check_protection(pos,\r\n\t\t\t\t\t\t\tuser and user:get_player_name() or \"\",\r\n\t\t\t\t\t\t\t\"place \"..source) then\r\n\t\t\t\t\t\treturn\r\n\t\t\t\t\tend\r\n\t\t\t\t\tminetest.add_node(pos, {name=source})\r\n\t\t\t\tend\r\n\r\n\t\t\t\t-- Check if pointing to a buildable node\r\n\t\t\t\tif ndef and ndef.buildable_to then\r\n\t\t\t\t\t-- buildable; replace the node\r\n\t\t\t\t\tplace_liquid(pointed_thing.under, node,\r\n\t\t\t\t\t\t\tsource, flowing)\r\n\t\t\t\telse\r\n\t\t\t\t\t-- not buildable to; place the liquid above\r\n\t\t\t\t\t-- check if the node above can be replaced\r\n\t\t\t\t\tlocal node = minetest.get_node_or_nil(pointed_thing.above)\r\n\t\t\t\t\tif node and minetest.registered_nodes[node.name].buildable_to then\r\n\t\t\t\t\t\tplace_liquid(pointed_thing.above,\r\n\t\t\t\t\t\t\t\tnode, source,\r\n\t\t\t\t\t\t\t\tflowing)\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\t-- do not remove the bucket with the liquid\r\n\t\t\t\t\t\treturn\r\n\t\t\t\t\tend\r\n\t\t\t\tend\r\n\t\t\t\treturn {name=\"bucket:bucket_empty\"}\r\n\t\t\tend\r\n\t\t})\r\n\tend\r\nend\r\n\r\nminetest.register_craftitem(\"bucket:bucket_empty\", {\r\n\tdescription = \"Empty Bucket\",\r\n\tinventory_image = \"bucket.png\",\r\n\tstack_max = 99,\r\n\tliquids_pointable = true,\r\n\ton_use = function(itemstack, user, pointed_thing)\r\n\t\t-- Must be pointing to node\r\n\t\tif pointed_thing.type ~= \"node\" then\r\n\t\t\treturn\r\n\t\tend\r\n\t\t-- Check if pointing to a liquid source\r\n\t\tlocal node = minetest.get_node(pointed_thing.under)\r\n\t\tlocal liquiddef = bucket.liquids[node.name]\r\n\t\tlocal item_count = user:get_wielded_item():get_count()\r\n\r\n\t\tif liquiddef ~= nil\r\n\t\tand liquiddef.itemname ~= nil\r\n\t\tand node.name == liquiddef.source then\r\n\t\t\tif check_protection(pointed_thing.under,\r\n\t\t\t\t\tuser:get_player_name(),\r\n\t\t\t\t\t\"take \".. node.name) then\r\n\t\t\t\treturn\r\n\t\t\tend\r\n\r\n\t\t\t-- default set to return filled bucket\r\n\t\t\tlocal giving_back = liquiddef.itemname\r\n\r\n\t\t\t-- check if holding more than 1 empty bucket\r\n\t\t\tif item_count > 1 then\r\n\r\n\t\t\t\t-- if space in inventory add filled bucked, otherwise drop as item\r\n\t\t\t\tlocal inv = user:get_inventory()\r\n\t\t\t\tif inv:room_for_item(\"main\", {name=liquiddef.itemname}) then\r\n\t\t\t\t\tinv:add_item(\"main\", liquiddef.itemname)\r\n\t\t\t\telse\r\n\t\t\t\t\tlocal pos = user:getpos()\r\n\t\t\t\t\tpos.y = math.floor(pos.y + 0.5)\r\n\t\t\t\t\tcore.add_item(pos, liquiddef.itemname)\r\n\t\t\t\tend\r\n\r\n\t\t\t\t-- set to return empty buckets minus 1\r\n\t\t\t\tgiving_back = \"bucket:bucket_empty \"..tostring(item_count-1)\r\n\r\n\t\t\tend\r\n\r\n\t\t\tminetest.add_node(pointed_thing.under, {name=\"air\"})\r\n\r\n\t\t\treturn ItemStack(giving_back)\r\n\t\tend\r\n\tend,\r\n})\r\n\r\nbucket.register_liquid(\r\n\t\"default:water_source\",\r\n\t\"default:water_flowing\",\r\n\t\"bucket:bucket_water\",\r\n\t\"bucket_water.png\",\r\n\t\"Water Bucket\"\r\n)\r\n\r\nbucket.register_liquid(\r\n\t\"default:lava_source\",\r\n\t\"default:lava_flowing\",\r\n\t\"bucket:bucket_lava\",\r\n\t\"bucket_lava.png\",\r\n\t\"Lava Bucket\"\r\n)\r\n\r\nminetest.register_craft({\r\n\ttype = \"fuel\",\r\n\trecipe = \"bucket:bucket_lava\",\r\n\tburntime = 60,\r\n\treplacements = {{\"bucket:bucket_lava\", \"bucket:bucket_empty\"}},\r\n})"},"comment":{"url":"https://api.github.com/repos/minetest/minetest_game/issues/comments/74395349","html_url":"https://github.com/minetest/minetest_game/issues/430#issuecomment-74395349","issue_url":"https://api.github.com/repos/minetest/minetest_game/issues/430","id":74395349,"user":{"login":"rubenwardy","id":2122943,"avatar_url":"https://avatars.githubusercontent.com/u/2122943?v=3","gravatar_id":"","url":"https://api.github.com/users/rubenwardy","html_url":"https://github.com/rubenwardy","followers_url":"https://api.github.com/users/rubenwardy/followers","following_url":"https://api.github.com/users/rubenwardy/following{/other_user}","gists_url":"https://api.github.com/users/rubenwardy/gists{/gist_id}","starred_url":"https://api.github.com/users/rubenwardy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rubenwardy/subscriptions","organizations_url":"https://api.github.com/users/rubenwardy/orgs","repos_url":"https://api.github.com/users/rubenwardy/repos","events_url":"https://api.github.com/users/rubenwardy/events{/privacy}","received_events_url":"https://api.github.com/users/rubenwardy/received_events","type":"User","site_admin":false},"created_at":"2015-02-14T22:47:00Z","updated_at":"2015-02-14T22:47:00Z","body":"Did you create a tag just for this issue?"}}