3751cfe93c79436f5e5b7b32a9b40374c803d18b
[oweals/minetest_game.git] / mods / bucket / init.lua
1 -- Minetest 0.4 mod: bucket
2 -- See README.txt for licensing and other information.
3
4 local LIQUID_MAX = 8  --The number of water levels when liquid_finite is enabled
5
6 minetest.register_alias("bucket", "bucket:bucket_empty")
7 minetest.register_alias("bucket_water", "bucket:bucket_water")
8 minetest.register_alias("bucket_lava", "bucket:bucket_lava")
9
10 minetest.register_craft({
11         output = 'bucket:bucket_empty 1',
12         recipe = {
13                 {'default:steel_ingot', '', 'default:steel_ingot'},
14                 {'', 'default:steel_ingot', ''},
15         }
16 })
17
18 bucket = {}
19 bucket.liquids = {}
20
21 local function check_protection(pos, name, text)
22         if minetest.is_protected(pos, name) then
23                 minetest.log("action", (name ~= "" and name or "A mod")
24                         .. " tried to " .. text
25                         .. " at protected position "
26                         .. minetest.pos_to_string(pos)
27                         .. " with a bucket")
28                 minetest.record_protection_violation(pos, name)
29                 return true
30         end
31         return false
32 end
33
34 -- Register a new liquid
35 --   source = name of the source node
36 --   flowing = name of the flowing node
37 --   itemname = name of the new bucket item (or nil if liquid is not takeable)
38 --   inventory_image = texture of the new bucket item (ignored if itemname == nil)
39 -- This function can be called from any mod (that depends on bucket).
40 function bucket.register_liquid(source, flowing, itemname, inventory_image, name)
41         bucket.liquids[source] = {
42                 source = source,
43                 flowing = flowing,
44                 itemname = itemname,
45         }
46         bucket.liquids[flowing] = bucket.liquids[source]
47
48         if itemname ~= nil then
49                 minetest.register_craftitem(itemname, {
50                         description = name,
51                         inventory_image = inventory_image,
52                         stack_max = 1,
53                         liquids_pointable = true,
54                         groups = {not_in_creative_inventory=1},
55                         on_place = function(itemstack, user, pointed_thing)
56                                 -- Must be pointing to node
57                                 if pointed_thing.type ~= "node" then
58                                         return
59                                 end
60                                 
61                                 -- Call on_rightclick if the pointed node defines it
62                                 if user and not user:get_player_control().sneak then
63                                         local n = minetest.get_node(pointed_thing.under)
64                                         local nn = n.name
65                                         local ndef = minetest.registered_nodes[nn]
66                                         if ndef and ndef.on_rightclick then
67                                                 return ndef.on_rightclick(
68                                                         pointed_thing.under,
69                                                         n, user,
70                                                         itemstack) or itemstack
71                                         end
72                                 end
73
74                                 local place_liquid = function(pos, node, source, flowing, fullness)
75                                         if check_protection(pos,
76                                                         user and user:get_player_name() or "",
77                                                         "place "..source) then
78                                                 return
79                                         end
80                                         if math.floor(fullness/128) == 1 or
81                                                 not minetest.setting_getbool("liquid_finite") then
82                                                 minetest.add_node(pos, {name=source,
83                                                                 param2=fullness})
84                                                 return
85                                         elseif node.name == flowing then
86                                                 fullness = fullness + node.param2
87                                         elseif node.name == source then
88                                                 fullness = LIQUID_MAX
89                                         end
90
91                                         if fullness >= LIQUID_MAX then
92                                                 minetest.add_node(pos, {name=source,
93                                                                 param2=LIQUID_MAX})
94                                         else
95                                                 minetest.add_node(pos, {name=flowing,
96                                                                 param2=fullness})
97                                         end
98                                 end
99
100                                 -- Check if pointing to a buildable node
101                                 local node = minetest.get_node(pointed_thing.under)
102                                 local fullness = tonumber(itemstack:get_metadata())
103                                 if not fullness then fullness = LIQUID_MAX end
104
105                                 if minetest.registered_nodes[node.name].buildable_to then
106                                         -- buildable; replace the node
107                                         place_liquid(pointed_thing.under, node,
108                                                         source, flowing, fullness)
109                                 else
110                                         -- not buildable to; place the liquid above
111                                         -- check if the node above can be replaced
112                                         local node = minetest.get_node(pointed_thing.above)
113                                         if minetest.registered_nodes[node.name].buildable_to then
114                                                 place_liquid(pointed_thing.above,
115                                                                 node, source,
116                                                                 flowing, fullness)
117                                         else
118                                                 -- do not remove the bucket with the liquid
119                                                 return
120                                         end
121                                 end
122                                 return {name="bucket:bucket_empty"}
123                         end
124                 })
125         end
126 end
127
128 minetest.register_craftitem("bucket:bucket_empty", {
129         description = "Empty Bucket",
130         inventory_image = "bucket.png",
131         stack_max = 1,
132         liquids_pointable = true,
133         on_use = function(itemstack, user, pointed_thing)
134                 -- Must be pointing to node
135                 if pointed_thing.type ~= "node" then
136                         return
137                 end
138                 -- Check if pointing to a liquid source
139                 node = minetest.get_node(pointed_thing.under)
140                 liquiddef = bucket.liquids[node.name]
141                 if liquiddef ~= nil and liquiddef.itemname ~= nil and
142                         (node.name == liquiddef.source or
143                         (node.name == liquiddef.flowing and
144                                 minetest.setting_getbool("liquid_finite"))) then
145                         if check_protection(pointed_thing.under,
146                                         user:get_player_name(),
147                                         "take ".. node.name) then
148                                 return
149                         end
150
151                         minetest.add_node(pointed_thing.under, {name="air"})
152
153                         if node.name == liquiddef.source then
154                                 node.param2 = LIQUID_MAX
155                         end
156                         return ItemStack({name = liquiddef.itemname,
157                                         metadata = tostring(node.param2)})
158                 end
159         end,
160 })
161
162 bucket.register_liquid(
163         "default:water_source",
164         "default:water_flowing",
165         "bucket:bucket_water",
166         "bucket_water.png",
167         "Water Bucket"
168 )
169
170 bucket.register_liquid(
171         "default:lava_source",
172         "default:lava_flowing",
173         "bucket:bucket_lava",
174         "bucket_lava.png",
175         "Lava Bucket"
176 )
177
178 minetest.register_craft({
179         type = "fuel",
180         recipe = "bucket:bucket_lava",
181         burntime = 60,
182         replacements = {{"bucket:bucket_lava", "bucket:bucket_empty"}},
183 })