Page 1 of 1

Ability to stack empty buckets...

PostPosted: Sat Feb 14, 2015 21:00
by TenPlus1
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: (added to github as feature issue)

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
-- Minetest 0.4 mod: bucket
-- See README.txt for licensing and other information.

minetest.register_alias("bucket", "bucket:bucket_empty")
minetest.register_alias("bucket_water", "bucket:bucket_water")
minetest.register_alias("bucket_lava", "bucket:bucket_lava")

minetest.register_craft({
   output = 'bucket:bucket_empty 1',
   recipe = {
      {'default:steel_ingot', '', 'default:steel_ingot'},
      {'', 'default:steel_ingot', ''},
   }
})

bucket = {}
bucket.liquids = {}

local function check_protection(pos, name, text)
   if minetest.is_protected(pos, name) then
      minetest.log("action", (name ~= "" and name or "A mod")
         .. " tried to " .. text
         .. " at protected position "
         .. minetest.pos_to_string(pos)
         .. " with a bucket")
      minetest.record_protection_violation(pos, name)
      return true
   end
   return false
end

-- Register a new liquid
--   source = name of the source node
--   flowing = name of the flowing node
--   itemname = name of the new bucket item (or nil if liquid is not takeable)
--   inventory_image = texture of the new bucket item (ignored if itemname == nil)
-- This function can be called from any mod (that depends on bucket).
function bucket.register_liquid(source, flowing, itemname, inventory_image, name)
   bucket.liquids[source] = {
      source = source,
      flowing = flowing,
      itemname = itemname,
   }
   bucket.liquids[flowing] = bucket.liquids[source]

   if itemname ~= nil then
      minetest.register_craftitem(itemname, {
         description = name,
         inventory_image = inventory_image,
         stack_max = 1,
         liquids_pointable = true,
         on_place = function(itemstack, user, pointed_thing)
            -- Must be pointing to node
            if pointed_thing.type ~= "node" then
               return
            end
            
            local node = minetest.get_node_or_nil(pointed_thing.under)
            local ndef
            if node then
               ndef = minetest.registered_nodes[node.name]
            end
            -- Call on_rightclick if the pointed node defines it
            if ndef and ndef.on_rightclick and
               user and not user:get_player_control().sneak then
               return ndef.on_rightclick(
                  pointed_thing.under,
                  node, user,
                  itemstack) or itemstack
            end

            local place_liquid = function(pos, node, source, flowing)
               if check_protection(pos,
                     user and user:get_player_name() or "",
                     "place "..source) then
                  return
               end
               minetest.add_node(pos, {name=source})
            end

            -- Check if pointing to a buildable node
            if ndef and ndef.buildable_to then
               -- buildable; replace the node
               place_liquid(pointed_thing.under, node,
                     source, flowing)
            else
               -- not buildable to; place the liquid above
               -- check if the node above can be replaced
               local node = minetest.get_node_or_nil(pointed_thing.above)
               if node and minetest.registered_nodes[node.name].buildable_to then
                  place_liquid(pointed_thing.above,
                        node, source,
                        flowing)
               else
                  -- do not remove the bucket with the liquid
                  return
               end
            end
            return {name="bucket:bucket_empty"}
         end
      })
   end
end

minetest.register_craftitem("bucket:bucket_empty", {
   description = "Empty Bucket",
   inventory_image = "bucket.png",
   stack_max = 99,
   liquids_pointable = true,
   on_use = function(itemstack, user, pointed_thing)
      -- Must be pointing to node
      if pointed_thing.type ~= "node" then
         return
      end
      -- Check if pointing to a liquid source
      local node = minetest.get_node(pointed_thing.under)
      local liquiddef = bucket.liquids[node.name]
      local item_count = user:get_wielded_item():get_count()

      if liquiddef ~= nil
      and liquiddef.itemname ~= nil
      and node.name == liquiddef.source then
         if check_protection(pointed_thing.under,
               user:get_player_name(),
               "take ".. node.name) then
            return
         end

         -- default set to return filled bucket
         local giving_back = liquiddef.itemname

         -- check if holding more than 1 empty bucket
         if item_count > 1 then

            -- if space in inventory add filled bucked, otherwise drop as item
            local inv = user:get_inventory()
            if inv:room_for_item("main", {name=liquiddef.itemname}) then
               inv:add_item("main", liquiddef.itemname)
            else
               local pos = user:getpos()
               pos.y = math.floor(pos.y + 0.5)
               core.add_item(pos, liquiddef.itemname)
            end

            -- set to return empty buckets minus 1
            giving_back = "bucket:bucket_empty "..tostring(item_count-1)

         end

         minetest.add_node(pointed_thing.under, {name="air"})

         return ItemStack(giving_back)
      end
   end,
})

bucket.register_liquid(
   "default:water_source",
   "default:water_flowing",
   "bucket:bucket_water",
   "bucket_water.png",
   "Water Bucket"
)

bucket.register_liquid(
   "default:lava_source",
   "default:lava_flowing",
   "bucket:bucket_lava",
   "bucket_lava.png",
   "Lava Bucket"
)

minetest.register_craft({
   type = "fuel",
   recipe = "bucket:bucket_lava",
   burntime = 60,
   replacements = {{"bucket:bucket_lava", "bucket:bucket_empty"}},
})

Re: Ability to stack empty buckets...

PostPosted: Sat Feb 14, 2015 22:39
by rubenwardy
+1

Re: Ability to stack empty buckets...

PostPosted: Sun Feb 15, 2015 07:37
by Krock
I mostly use lava buckets as fuel and this is a great help to keep the overview.
It saves many useless clicks :)
EDIT: https://github.com/SmallJoker/base_game ... t/init.lua

Re: Ability to stack empty buckets...

PostPosted: Sun Feb 15, 2015 15:48
by Casimir
There should be a better search for the forum, so people don't reinvent things that often.
My version (from almost a year ago): https://github.com/CasimirKaPazi/Voxelg ... t.lua#L121

Re: Ability to stack empty buckets...

PostPosted: Mon Feb 16, 2015 02:02
by philipbenr
+1

Re: Ability to stack empty buckets...

PostPosted: Mon Feb 16, 2015 09:07
by TenPlus1
Casimir: it's not a bad thing to have diversity in code and do a similar task a different way...

Re: Ability to stack empty buckets...

PostPosted: Wed Feb 18, 2015 22:13
by Wuzzy
TenPlus1 wrote:Casimir: it's not a bad thing to have diversity in code and do a similar task a different way...


Oh, so it's not called “redundancy” anymore, it is “diversity in code”. An interesting change of terminology. ;-)

Re: Ability to stack empty buckets...

PostPosted: Thu Feb 19, 2015 12:26
by srifqi
+1
Thanks for code, TenPlus1!

Hope your code gets merged!