2 -- This file contains built-in stuff in Minetest implemented in Lua.
4 -- It is always loaded and executed after registration of the C API,
5 -- before loading and running any mods.
8 function basic_dump2(o)
9 if type(o) == "number" then
11 elseif type(o) == "string" then
12 return string.format("%q", o)
13 elseif type(o) == "boolean" then
15 elseif type(o) == "function" then
17 elseif type(o) == "userdata" then
19 elseif type(o) == "nil" then
22 error("cannot dump a " .. type(o))
27 function dump2(o, name, dumped)
31 if type(o) == "number" or type(o) == "string" or type(o) == "boolean"
32 or type(o) == "function" or type(o) == "nil"
33 or type(o) == "userdata" then
34 io.write(basic_dump2(o), "\n")
35 elseif type(o) == "table" then
37 io.write(dumped[o], "\n")
40 io.write("{}\n") -- new table
41 for k,v in pairs(o) do
42 local fieldname = string.format("%s[%s]", name, basic_dump2(k))
43 dump2(v, fieldname, dumped)
47 error("cannot dump a " .. type(o))
52 function dump(o, dumped)
54 if type(o) == "number" then
56 elseif type(o) == "string" then
57 return string.format("%q", o)
58 elseif type(o) == "table" then
60 return "<circular reference>"
64 for k,v in pairs(o) do
65 t[#t+1] = "" .. k .. " = " .. dump(v, dumped)
67 return "{" .. table.concat(t, ", ") .. "}"
68 elseif type(o) == "boolean" then
70 elseif type(o) == "function" then
72 elseif type(o) == "userdata" then
74 elseif type(o) == "nil" then
77 error("cannot dump a " .. type(o))
83 -- Built-in node definitions. Also defined in C.
86 minetest.register_nodedef_defaults({
87 -- name intentionally not defined here
90 tile_images = {"unknown_block.png"},
91 inventory_image = "unknown_block.png",
93 {image="", backface_culling=true},
94 {image="", backface_culling=true},
97 post_effect_color = {a=0, r=0, g=0, b=0},
99 is_ground_content = false,
100 light_propagates = false,
101 sunlight_propagates = false,
106 buildable_to = false,
107 wall_mounted = false,
108 often_contains_mineral = false,
111 extra_dug_item_rarity = 2,
114 liquid_alternative_flowing = "",
115 liquid_alternative_source = "",
116 liquid_viscosity = 0,
118 damage_per_second = 0,
119 selection_box = {type="regular"},
121 diggablity = "normal",
128 cookresult_item = "", -- Cannot be cooked
129 furnace_cooktime = 3.0,
130 furnace_burntime = -1, -- Cannot be used as fuel
133 minetest.register_node("air", {
134 drawtype = "airlike",
136 light_propagates = true,
137 sunlight_propagates = true,
142 air_equivalent = true,
145 minetest.register_node("ignore", {
146 drawtype = "airlike",
148 light_propagates = false,
149 sunlight_propagates = false,
153 buildable_to = true, -- A way to remove accidentally placed ignores
154 air_equivalent = true,
158 -- stackstring manipulation functions
159 -- example stackstring: 'craft "apple" 4'
160 -- example item: {type="craft", name="apple"}
161 -- example item: {type="tool", name="SteelPick", wear="23272"}
164 function stackstring_take_item(stackstring)
165 if stackstring == nil then
168 local stacktype = nil
169 stacktype = string.match(stackstring,
171 if stacktype == "node" or stacktype == "craft" then
174 local itemcount = nil
175 itemtype, itemname, itemcount = string.match(stackstring,
176 '([%a%d]+) "([^"]*)" (%d+)')
177 itemcount = tonumber(itemcount)
178 if itemcount == 0 then
180 elseif itemcount == 1 then
181 return '', {type=itemtype, name=itemname}
183 return itemtype.." \""..itemname.."\" "..(itemcount-1),
184 {type=itemtype, name=itemname}
186 elseif stacktype == "tool" then
190 itemtype, itemname, itemwear = string.match(stackstring,
191 '([%a%d]+) "([^"]*)" (%d+)')
192 itemwear = tonumber(itemwear)
193 return '', {type=itemtype, name=itemname, wear=itemwear}
197 function stackstring_put_item(stackstring, item)
199 return stackstring, false
201 stackstring = stackstring or ''
202 local stacktype = nil
203 stacktype = string.match(stackstring,
205 stacktype = stacktype or ''
206 if stacktype ~= '' and stacktype ~= item.type then
207 return stackstring, false
209 if item.type == "node" or item.type == "craft" then
212 local itemcount = nil
213 itemtype, itemname, itemcount = string.match(stackstring,
214 '([%a%d]+) "([^"]*)" (%d+)')
215 itemtype = itemtype or item.type
216 itemname = itemname or item.name
217 if itemcount == nil then
220 itemcount = itemcount + 1
221 return itemtype.." \""..itemname.."\" "..itemcount, true
222 elseif item.type == "tool" then
223 if stacktype ~= nil then
224 return stackstring, false
229 itemtype, itemname, itemwear = string.match(stackstring,
230 '([%a%d]+) "([^"]*)" (%d+)')
231 itemwear = tonumber(itemwear)
232 return itemtype.." \""..itemname.."\" "..itemwear, true
234 return stackstring, false
237 function stackstring_put_stackstring(stackstring, src)
239 --print("src="..dump(src))
240 src, item = stackstring_take_item(src)
241 --print("src="..dump(src).." item="..dump(item))
243 stackstring, success = stackstring_put_item(stackstring, item)
245 return stackstring, false
248 return stackstring, true
251 function test_stackstring()
256 stack, item = stackstring_take_item('node "TNT" 3')
257 assert(stack == 'node "TNT" 2')
258 assert(item.type == 'node')
259 assert(item.name == 'TNT')
261 stack, item = stackstring_take_item('craft "with spaces" 2')
262 assert(stack == 'craft "with spaces" 1')
263 assert(item.type == 'craft')
264 assert(item.name == 'with spaces')
266 stack, item = stackstring_take_item('craft "with spaces" 1')
268 assert(item.type == 'craft')
269 assert(item.name == 'with spaces')
271 stack, item = stackstring_take_item('craft "s8df2kj3" 0')
275 stack, item = stackstring_take_item('tool "With Spaces" 32487')
277 assert(item.type == 'tool')
278 assert(item.name == 'With Spaces')
279 assert(item.wear == 32487)
281 stack, success = stackstring_put_item('node "With Spaces" 40',
282 {type='node', name='With Spaces'})
283 assert(stack == 'node "With Spaces" 41')
284 assert(success == true)
286 stack, success = stackstring_put_item('craft "With Spaces" 40',
287 {type='craft', name='With Spaces'})
288 assert(stack == 'craft "With Spaces" 41')
289 assert(success == true)
291 stack, success = stackstring_put_item('tool "With Spaces" 32487',
292 {type='tool', name='With Spaces'})
293 assert(stack == 'tool "With Spaces" 32487')
294 assert(success == false)
296 stack, success = stackstring_put_item('node "With Spaces" 40',
297 {type='tool', name='With Spaces'})
298 assert(stack == 'node "With Spaces" 40')
299 assert(success == false)
301 assert(stackstring_put_stackstring('node "With Spaces" 2',
302 'node "With Spaces" 1') == 'node "With Spaces" 3')
310 minetest.craftitem_place_item = function(item, placer, pos)
311 --print("craftitem_place_item")
312 --print("item: " .. dump(item))
313 --print("placer: " .. dump(placer))
314 --print("pos: " .. dump(pos))
315 minetest.env:add_item(pos, 'craft "' .. item .. '" 1')
319 minetest.craftitem_eat = function(hp_change)
320 return function(item, user, pointed_thing) -- closure
321 --print("craftitem_eat(" .. hp_change .. ")")
322 --print("item: " .. dump(item))
323 --print("user: " .. dump(user))
324 --print("pointed_thing: " .. dump(pointed_thing))
325 user:set_hp(user:get_hp() + hp_change)
331 -- Creative inventory
334 minetest.creative_inventory = {}
336 minetest.add_to_creative_inventory = function(itemstring)
337 table.insert(minetest.creative_inventory, itemstring)
341 -- Callback registration
344 function make_registration()
346 local registerfunc = function(func) table.insert(t, func) end
347 return t, registerfunc
350 minetest.registered_on_chat_messages, minetest.register_on_chat_message = make_registration()
351 minetest.registered_globalsteps, minetest.register_globalstep = make_registration()
352 minetest.registered_on_placenodes, minetest.register_on_placenode = make_registration()
353 minetest.registered_on_dignodes, minetest.register_on_dignode = make_registration()
354 minetest.registered_on_punchnodes, minetest.register_on_punchnode = make_registration()
355 minetest.registered_on_generateds, minetest.register_on_generated = make_registration()
356 minetest.registered_on_newplayers, minetest.register_on_newplayer = make_registration()
357 minetest.registered_on_respawnplayers, minetest.register_on_respawnplayer = make_registration()