1 function basic_dump2(o)
2 if type(o) == "number" then
4 elseif type(o) == "string" then
5 return string.format("%q", o)
6 elseif type(o) == "boolean" then
8 elseif type(o) == "function" then
10 elseif type(o) == "userdata" then
12 elseif type(o) == "nil" then
15 error("cannot dump a " .. type(o))
20 function dump2(o, name, dumped)
24 if type(o) == "number" or type(o) == "string" or type(o) == "boolean"
25 or type(o) == "function" or type(o) == "nil"
26 or type(o) == "userdata" then
27 io.write(basic_dump2(o), "\n")
28 elseif type(o) == "table" then
30 io.write(dumped[o], "\n")
33 io.write("{}\n") -- new table
34 for k,v in pairs(o) do
35 local fieldname = string.format("%s[%s]", name, basic_dump2(k))
36 dump2(v, fieldname, dumped)
40 error("cannot dump a " .. type(o))
45 function dump(o, dumped)
47 if type(o) == "number" then
49 elseif type(o) == "string" then
50 return string.format("%q", o)
51 elseif type(o) == "table" then
53 return "<circular reference>"
57 for k,v in pairs(o) do
58 t[#t+1] = "" .. k .. " = " .. dump(v, dumped)
60 return "{" .. table.concat(t, ", ") .. "}"
61 elseif type(o) == "boolean" then
63 elseif type(o) == "function" then
65 elseif type(o) == "userdata" then
67 elseif type(o) == "nil" then
70 error("cannot dump a " .. type(o))
76 -- Built-in node definitions. Also defined in C.
79 minetest.register_nodedef_defaults({
80 -- name intentionally not defined here
83 tile_images = {"unknown_block.png"},
84 inventory_image = "unknown_block.png",
86 {image="", backface_culling=true},
87 {image="", backface_culling=true},
90 post_effect_color = {a=0, r=0, g=0, b=0},
92 is_ground_content = false,
93 light_propagates = false,
94 sunlight_propagates = false,
100 wall_mounted = false,
101 often_contains_mineral = false,
104 extra_dug_item_rarity = 2,
107 liquid_alternative_flowing = "",
108 liquid_alternative_source = "",
109 liquid_viscosity = 0,
111 damage_per_second = 0,
112 selection_box = {type="regular"},
114 diggablity = "normal",
121 cookresult_item = "", -- Cannot be cooked
122 furnace_cooktime = 3.0,
123 furnace_burntime = -1, -- Cannot be used as fuel
126 minetest.register_node("air", {
127 drawtype = "airlike",
129 light_propagates = true,
130 sunlight_propagates = true,
135 air_equivalent = true,
138 minetest.register_node("ignore", {
139 drawtype = "airlike",
141 light_propagates = false,
142 sunlight_propagates = false,
146 buildable_to = true, -- A way to remove accidentally placed ignores
147 air_equivalent = true,
151 -- stackstring manipulation functions
152 -- example stackstring: 'CraftItem "apple" 4'
153 -- example item: {type="CraftItem", name="apple"}
154 -- example item: {type="ToolItem", name="SteelPick", wear="23272"}
157 function stackstring_take_item(stackstring)
158 if stackstring == nil then
161 local stacktype = nil
162 stacktype = string.match(stackstring,
163 '([%a%d]+Item[%a%d]*)')
164 if stacktype == "NodeItem" or stacktype == "CraftItem" then
167 local itemcount = nil
168 itemtype, itemname, itemcount = string.match(stackstring,
169 '([%a%d]+Item[%a%d]*) "([^"]*)" (%d+)')
170 itemcount = tonumber(itemcount)
171 if itemcount == 0 then
173 elseif itemcount == 1 then
174 return '', {type=itemtype, name=itemname}
176 return itemtype.." \""..itemname.."\" "..(itemcount-1),
177 {type=itemtype, name=itemname}
179 elseif stacktype == "ToolItem" then
183 itemtype, itemname, itemwear = string.match(stackstring,
184 '([%a%d]+Item[%a%d]*) "([^"]*)" (%d+)')
185 itemwear = tonumber(itemwear)
186 return '', {type=itemtype, name=itemname, wear=itemwear}
190 function stackstring_put_item(stackstring, item)
192 return stackstring, false
194 stackstring = stackstring or ''
195 local stacktype = nil
196 stacktype = string.match(stackstring,
197 '([%a%d]+Item[%a%d]*)')
198 stacktype = stacktype or ''
199 if stacktype ~= '' and stacktype ~= item.type then
200 return stackstring, false
202 if item.type == "NodeItem" or item.type == "CraftItem" then
205 local itemcount = nil
206 itemtype, itemname, itemcount = string.match(stackstring,
207 '([%a%d]+Item[%a%d]*) "([^"]*)" (%d+)')
208 itemtype = itemtype or item.type
209 itemname = itemname or item.name
210 if itemcount == nil then
213 itemcount = itemcount + 1
214 return itemtype.." \""..itemname.."\" "..itemcount, true
215 elseif item.type == "ToolItem" then
216 if stacktype ~= nil then
217 return stackstring, false
222 itemtype, itemname, itemwear = string.match(stackstring,
223 '([%a%d]+Item[%a%d]*) "([^"]*)" (%d+)')
224 itemwear = tonumber(itemwear)
225 return itemtype.." \""..itemname.."\" "..itemwear, true
227 return stackstring, false
230 function stackstring_put_stackstring(stackstring, src)
232 --print("src="..dump(src))
233 src, item = stackstring_take_item(src)
234 --print("src="..dump(src).." item="..dump(item))
236 stackstring, success = stackstring_put_item(stackstring, item)
238 return stackstring, false
241 return stackstring, true
244 function test_stackstring()
249 stack, item = stackstring_take_item('NodeItem "TNT" 3')
250 assert(stack == 'NodeItem "TNT" 2')
251 assert(item.type == 'NodeItem')
252 assert(item.name == 'TNT')
254 stack, item = stackstring_take_item('CraftItem "with spaces" 2')
255 assert(stack == 'CraftItem "with spaces" 1')
256 assert(item.type == 'CraftItem')
257 assert(item.name == 'with spaces')
259 stack, item = stackstring_take_item('CraftItem "with spaces" 1')
261 assert(item.type == 'CraftItem')
262 assert(item.name == 'with spaces')
264 stack, item = stackstring_take_item('CraftItem "s8df2kj3" 0')
268 stack, item = stackstring_take_item('ToolItem "With Spaces" 32487')
270 assert(item.type == 'ToolItem')
271 assert(item.name == 'With Spaces')
272 assert(item.wear == 32487)
274 stack, success = stackstring_put_item('NodeItem "With Spaces" 40',
275 {type='NodeItem', name='With Spaces'})
276 assert(stack == 'NodeItem "With Spaces" 41')
277 assert(success == true)
279 stack, success = stackstring_put_item('CraftItem "With Spaces" 40',
280 {type='CraftItem', name='With Spaces'})
281 assert(stack == 'CraftItem "With Spaces" 41')
282 assert(success == true)
284 stack, success = stackstring_put_item('ToolItem "With Spaces" 32487',
285 {type='ToolItem', name='With Spaces'})
286 assert(stack == 'ToolItem "With Spaces" 32487')
287 assert(success == false)
289 stack, success = stackstring_put_item('NodeItem "With Spaces" 40',
290 {type='ToolItem', name='With Spaces'})
291 assert(stack == 'NodeItem "With Spaces" 40')
292 assert(success == false)
294 assert(stackstring_put_stackstring('NodeItem "With Spaces" 2',
295 'NodeItem "With Spaces" 1') == 'NodeItem "With Spaces" 3')
300 -- Callback registration
303 function make_registration()
305 local registerfunc = function(func) table.insert(t, func) end
306 return t, registerfunc
309 minetest.registered_on_chat_messages, minetest.register_on_chat_message = make_registration()
310 minetest.registered_globalsteps, minetest.register_globalstep = make_registration()
311 minetest.registered_on_placenodes, minetest.register_on_placenode = make_registration()
312 minetest.registered_on_dignodes, minetest.register_on_dignode = make_registration()
313 minetest.registered_on_punchnodes, minetest.register_on_punchnode = make_registration()
314 minetest.registered_on_generateds, minetest.register_on_generated = make_registration()
315 minetest.registered_on_newplayers, minetest.register_on_newplayer = make_registration()
316 minetest.registered_on_respawnplayers, minetest.register_on_respawnplayer = make_registration()