-- Minetest mod: bucket -- See "LICENSE" for licenses and related information. -- =================================================================== local bucket_gels_lava = ocutil.bool_default ("bucket_gels_lava" , true ) local bucket_gels_water = ocutil.bool_default ("bucket_gels_water" , false ) -- =================================================================== minetest.register_alias ( "bucket" , "bucket:empty" ) minetest.register_alias ( "bucket_empty" , "bucket:empty" ) minetest.register_alias ("bucket:bucket_empty" , "bucket:empty" ) minetest.register_alias ( "bucket_lava" , "bucket:lava" ) minetest.register_alias ("bucket:bucket_lava" , "bucket:lava" ) minetest.register_alias ( "bucket_bluelava" , "bucket:bluelava" ) minetest.register_alias ("bucket:bucket_bluelava" , "bucket:bluelava" ) minetest.register_alias ( "bucket_greenlava" , "bucket:greenlava" ) minetest.register_alias ("bucket:bucket_greenlava" , "bucket:greenlava" ) minetest.register_alias ( "bucket_water" , "bucket:water" ) minetest.register_alias ("bucket:bucket_water" , "bucket:water" ) -- =================================================================== minetest.register_craft ({ output = '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 -- =================================================================== -- "bucket.register_bucket_hash" registers a new liquid at the bucket -- level. -- Note: See also "default.register_node_bucketable", a function that -- can be used to register solids at the bucket level. -- ------------------------------------------------------------------- -- "bucket.register_bucket_hash" takes one parameter, bh (short for -- "bucket hash"). This is a table that contains the following ele- -- ments: -- source_node = Name of the source node. For example: "default: -- soda_pop_source". -- -- This parameter is required and is used for multiple purposes. -- ------------------------------------------------------------------- -- bucket_node = Name of the new bucket item (or nil if liquid is not -- takeable). Example: "bucket:soda_pop". -- ------------------------------------------------------------------- -- invsource_image = Name of a PNG file (including ".png") that shows -- the contents of the bucket. Not the bucket itself. Examples would -- include "default_water.png" and "default_lava.png". -- If "bucket_node" is not nil and "inventory_image" is nil, a small -- part of the image specified by "invsource_image" is copied into a -- bucket image. The result becomes an inventory image for the new -- bucket node. -- ------------------------------------------------------------------- -- inventory_image = PNG-file inventory image for the new bucket node. -- Ignored if "bucket_node" is nil. Takes precedence over "invsource_ -- image". -- If "invsource_image" and "inventory_image" are both nil, "inven- -- tory_image" defaults to "bucket_lava.png" if "source_node" contains -- the string "lava" and to "bucket_water.png" otherwise. -- ------------------------------------------------------------------- -- desc = Text description of the bucket node. For example: "Soda Pop -- Bucket". -- ------------------------------------------------------------------- -- groups = (Optional) Group table for the bucket node. For example: -- { water_bucket = 1 } -- ------------------------------------------------------------------- -- The following two parameters may be set, and are set in a few pla- -- ces, but they are't used by Bucket Game. They are, however, record- -- ed in an internal data structure that is available for use by ex- -- ternal mods. -- -- The data structure is a legacy hold-over from Old MT that remains -- for compatibility with non-Bucket Game mods. -- -- flowing_node = Name of associated "flowing" node. -- force_renew = (optional) Boolean flag. -- =================================================================== function bucket.register_bucket_hash (bh) local bucket_node = bh.bucket_node local desc = bh.desc local flowing_node = bh.flowing_node local force_renew = bh.force_renew local groups = bh.groups local inventory_image = bh.inventory_image local invsource_image = bh.invsource_image local source_node = bh.source_node if ocutil.node_missing (source_node) then return end if inventory_image == nil and invsource_image ~= nil then inventory_image = invsource_image .. "^bucket_extmask.png^[makealpha:128,0,0^bucket_overlay.png" end if inventory_image == nil then if string.match (source_node, "lava") then inventory_image = "bucket_lava.png" else inventory_image = "bucket_water.png" end end bucket.liquids [source_node] = { source = source_node , itemname = bucket_node , force_renew = force_renew , } if flowing_node ~= nil and bucket.liquids [flowing_node ] == nil then bucket.liquids [source_node ]["flowing"] = flowing_node bucket.liquids [flowing_node ] = bucket.liquids [source_node ] end if bucket_node == nil then return end if groups == nil then groups = {} end groups = ocutil.clone_table (groups) groups.not_in_creative_inventory = 1 minetest.register_craftitem (":" .. bucket_node, { description = desc, inventory_image = inventory_image , stack_max = 1, liquids_pointable = true, groups = groups, 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 = node and minetest.registered_nodes [node.name] -- 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) end local lpos -- Check if pointing to a buildable node if ndef and ndef.buildable_to then -- buildable; replace the node lpos = pointed_thing.under else -- not buildable to; place the liquid above -- check if the node above can be replaced lpos = pointed_thing.above node = minetest.get_node_or_nil (lpos) local above_ndef = node and minetest.registered_nodes [node.name] if not above_ndef or not above_ndef.buildable_to then -- do not remove the bucket with the liquid return itemstack end end if check_protection (lpos, user and user:get_player_name() or "", "place " .. source_node) then return end minetest.set_node (lpos, { name = source_node }) return ItemStack ("bucket:empty") end }) end -- =================================================================== minetest.register_craftitem ("bucket:empty", { description = "Empty Bucket", inventory_image = "bucket.png", stack_max = 99, liquids_pointable = true, on_use = function(itemstack, user, pointed_thing) if pointed_thing.type == "object" then pointed_thing.ref:punch(user, 1.0, { full_punch_interval=1.0 }, nil) return user:get_wielded_item() elseif pointed_thing.type ~= "node" then -- do nothing if it's neither object nor node 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 bucket, -- 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) minetest.add_item (pos, liquiddef.itemname) end -- set to return empty buckets minus 1 giving_back = "bucket:empty " .. tostring (item_count-1) end -- force_renew requires a source neighbour local source_neighbor = false if liquiddef.force_renew then source_neighbor = minetest.find_node_near (pointed_thing.under, 1, liquiddef.source) end if not (source_neighbor and liquiddef.force_renew) then minetest.add_node (pointed_thing.under, {name = "air"}) end return ItemStack(giving_back) else -- non-liquid nodes will have their on_punch triggered local node_def = minetest.registered_nodes[node.name] if node_def then node_def.on_punch (pointed_thing.under, node, user, pointed_thing) end return user:get_wielded_item() end end , }) -- =================================================================== -- This is a wrapper for "bucket.register_bucket_hash" that is provid- -- ed solely for historical reasons. No Bucket Game mod calls this -- routine but external mods may do so. -- For more information, see "bucket.register_bucket_hash". -- =================================================================== function bucket.register_liquid (source_node, flowing_node, bucket_node, inventory_image, desc, groups, force_renew) local bh = {} bh.source_node = source_node bh.flowing_node = flowing_node bh.bucket_node = bucket_node bh.inventory_image = inventory_image bh.desc = desc bh.groups = groups bh.force_renew = force_renew return bucket.register_bucket_hash (bh) end -- =================================================================== bucket.register_bucket_hash ({ source_node = "default:water_source" , flowing_node = "default:water_flowing" , bucket_node = "bucket:water" , desc = "Water Bucket" , groups = { water_bucket = 1 } , }) if bucket_gels_water then bucket.register_bucket_hash ({ source_node = "default:water_gel" , bucket_node = "bucket:water" , desc = "Water Gel Bucket" , groups = { water_bucket = 1 } , }) end -- =================================================================== bucket.register_bucket_hash ({ source_node = "default:water_gel" , bucket_node = "bucket:water_gel" , desc = "Water Gel Bucket" , groups = { water_bucket = 1 } , }) bucket.register_bucket_hash ({ source_node = "default:water_gel_slope" , bucket_node = "bucket:water_gel_slope" , desc = "Water Gel Slope Bucket" , groups = { water_bucket = 1 } , }) -- =================================================================== bucket.register_bucket_hash ({ source_node = "default:lava_source" , bucket_node = "bucket:lava" , desc = "Lava Bucket" , }) bucket.register_bucket_hash ({ source_node = "bluelava:lava_source" , bucket_node = "bucket:bluelava" , desc = "Blue Lava Bucket" , invsource_image = "blue_lava.png" , }) bucket.register_bucket_hash ({ source_node = "greenlava:lava_source" , bucket_node = "bucket:greenlava" , desc = "Green Lava Bucket" , invsource_image = "green_lava.png" , }) -- =================================================================== if bucket_gels_lava then bucket.register_bucket_hash ({ source_node = "default:lava_gel" , bucket_node = "bucket:lava" , desc = "Lava Gel Bucket" , }) bucket.register_bucket_hash ({ source_node = "bluelava:lava_gel" , bucket_node = "bucket:bluelava" , desc = "Blue Lava Gel Bucket" , invsource_image = "blue_lava.png" , }) bucket.register_bucket_hash ({ source_node = "greenlava:lava_gel" , bucket_node = "bucket:greenlava" , desc = "Green Lava Gel Bucket" , invsource_image = "green_lava.png" , }) end -- =================================================================== bucket.register_bucket_hash ({ source_node = "default:lava_gel" , bucket_node = "bucket:lava_gel" , desc = "Lava Gel Bucket" , }) bucket.register_bucket_hash ({ source_node = "default:lava_gel_slope" , bucket_node = "bucket:lava_gel_slope" , desc = "Lava Gel Slope Bucket" , }) -- =================================================================== bucket.register_bucket_hash ({ source_node = "bluelava:lava_gel" , bucket_node = "bucket:bluelava_gel" , desc = "Blue Lava Gel Bucket" , invsource_image = "blue_lava.png" , }) bucket.register_bucket_hash ({ source_node = "bluelava:lava_gel_slope" , bucket_node = "bucket:bluelava_gel_slope" , desc = "Blue Lava Gel Slope Bucket" , invsource_image = "blue_lava.png" , }) -- =================================================================== bucket.register_bucket_hash ({ source_node = "greenlava:lava_gel" , bucket_node = "bucket:greenlava_gel" , desc = "Green Lava Gel Bucket" , invsource_image = "green_lava.png" , }) bucket.register_bucket_hash ({ source_node = "greenlava:lava_gel_slope" , bucket_node = "bucket:greenlava_gel_slope" , desc = "Green Lava Gel Slope Bucket" , invsource_image = "green_lava.png" , }) -- =================================================================== bucket.register_bucket_hash ({ source_node = "default:lava_crust_source" , bucket_node = "bucket:lava_crust" , inventory_image = "bucket_lava_crust.png" , desc = "Lava Crust Bucket" , }) -- =================================================================== bucket.register_bucket_hash ({ source_node = "default:river_water_source" , flowing_node = "default:river_water_flowing" , bucket_node = "bucket:river_water" , inventory_image = "bucket_river_water.png" , desc = "River Water Bucket" , groups = { water_bucket = 1 } , force_renew = true , }) -- =================================================================== minetest.register_craft ({ type = "fuel", recipe = "bucket:lava" , burntime = 60 , replacements = {{ "bucket:lava", "bucket:empty" }} , }) -- =================================================================== minetest.register_craft ({ type = "fuel", recipe = "bucket:bluelava" , burntime = 30 , replacements = {{ "bucket:bluelava", "bucket:empty" }} , }) -- =================================================================== minetest.register_craft ({ type = "fuel", recipe = "bucket:greenlava" , burntime = 30 , replacements = {{ "bucket:greenlava", "bucket:empty" }} , }) -- =================================================================== for name, ucname in pairs (default.waters) do local dename = "default:" .. name local bcname = "bucket:" .. name local img = "default_" .. name .. ".png" bucket.register_bucket_hash ({ source_node = dename .. "_source" , bucket_node = bcname , invsource_image = img , desc = ucname .. " Bucket" , groups = { water_bucket = 1 } , }) if bucket_gels_water then bucket.register_bucket_hash ({ source_node = dename .. "_gel" , bucket_node = bcname , invsource_image = img , desc = ucname .. " Gel Bucket" , groups = { water_bucket = 1 } , }) end bucket.register_bucket_hash ({ source_node = dename .. "_gel" , bucket_node = bcname .. "_gel" , invsource_image = img , desc = ucname .. " Gel Bucket" , groups = { water_bucket = 1 } , }) bucket.register_bucket_hash ({ source_node = dename .. "_gel_slope" , bucket_node = bcname .. "_gel_slope" , invsource_image = img , desc = ucname .. " Gel Slope Bucket" , groups = { water_bucket = 1 } , }) end -- =================================================================== -- "bucket.empty_autobucket" goes through a list of node types regis- -- tered previously using "default.register_node_bucketable", creates -- a bucket type for each node type, and resets the list in question -- to empty. -- This routine is called at the end of the "bucket"-mod load stage. -- Additionally, if the "bucket" mod has been loaded and this routine -- is therefore defined, "default.register_node_bucketable" calls this -- routine directly. -- =================================================================== bucket.empty_autobucket = function() for name, def in pairs (default.autobucket) do bucket.register_bucket_hash (def) end default.autobucket = {} end -- =================================================================== ocutil.bucket_loaded = true bucket.empty_autobucket()