Add fancy inventory for bookshelves
[oweals/minetest_game.git] / mods / default / nodes.lua
1 -- mods/default/nodes.lua
2
3 minetest.register_node("default:stone", {
4         description = "Stone",
5         tiles = {"default_stone.png"},
6         is_ground_content = true,
7         groups = {cracky=3, stone=1},
8         drop = 'default:cobble',
9         legacy_mineral = true,
10         sounds = default.node_sound_stone_defaults(),
11 })
12
13 minetest.register_node("default:desert_stone", {
14         description = "Desert Stone",
15         tiles = {"default_desert_stone.png"},
16         is_ground_content = true,
17         groups = {cracky=3, stone=1},
18         drop = 'default:desert_cobble',
19         legacy_mineral = true,
20         sounds = default.node_sound_stone_defaults(),
21 })
22
23 minetest.register_node("default:stone_with_coal", {
24         description = "Coal Ore",
25         tiles = {"default_stone.png^default_mineral_coal.png"},
26         is_ground_content = true,
27         groups = {cracky=3},
28         drop = 'default:coal_lump',
29         sounds = default.node_sound_stone_defaults(),
30 })
31
32 minetest.register_node("default:stone_with_iron", {
33         description = "Iron Ore",
34         tiles = {"default_stone.png^default_mineral_iron.png"},
35         is_ground_content = true,
36         groups = {cracky=2},
37         drop = 'default:iron_lump',
38         sounds = default.node_sound_stone_defaults(),
39 })
40
41 minetest.register_node("default:stone_with_copper", {
42         description = "Copper Ore",
43         tiles = {"default_stone.png^default_mineral_copper.png"},
44         is_ground_content = true,
45         groups = {cracky=2},
46         drop = 'default:copper_lump',
47         sounds = default.node_sound_stone_defaults(),
48 })
49
50 minetest.register_node("default:stone_with_mese", {
51         description = "Mese Ore",
52         tiles = {"default_stone.png^default_mineral_mese.png"},
53         is_ground_content = true,
54         groups = {cracky=1},
55         drop = "default:mese_crystal",
56         sounds = default.node_sound_stone_defaults(),
57 })
58
59 minetest.register_node("default:stone_with_gold", {
60         description = "Gold Ore",
61         tiles = {"default_stone.png^default_mineral_gold.png"},
62         is_ground_content = true,
63         groups = {cracky=2},
64         drop = "default:gold_lump",
65         sounds = default.node_sound_stone_defaults(),
66 })
67         
68 minetest.register_node("default:stone_with_diamond", {
69         description = "Diamond Ore",
70         tiles = {"default_stone.png^default_mineral_diamond.png"},
71         is_ground_content = true,
72         groups = {cracky=1},
73         drop = "default:diamond",
74         sounds = default.node_sound_stone_defaults(),
75 })
76
77 minetest.register_node("default:stonebrick", {
78         description = "Stone Brick",
79         tiles = {"default_stone_brick.png"},
80         groups = {cracky=2, stone=1},
81         sounds = default.node_sound_stone_defaults(),
82 })
83
84 minetest.register_node("default:desert_stonebrick", {
85         description = "Desert Stone Brick",
86         tiles = {"default_desert_stone_brick.png"},
87         groups = {cracky=2, stone=1},
88         sounds = default.node_sound_stone_defaults(),
89 })
90
91 minetest.register_node("default:dirt_with_grass", {
92         description = "Dirt with Grass",
93         tiles = {"default_grass.png", "default_dirt.png", "default_dirt.png^default_grass_side.png"},
94         is_ground_content = true,
95         groups = {crumbly=3,soil=1},
96         drop = 'default:dirt',
97         sounds = default.node_sound_dirt_defaults({
98                 footstep = {name="default_grass_footstep", gain=0.25},
99         }),
100 })
101
102 minetest.register_node("default:dirt_with_grass_footsteps", {
103         description = "Dirt with Grass and Footsteps",
104         tiles = {"default_grass_footsteps.png", "default_dirt.png", "default_dirt.png^default_grass_side.png"},
105         is_ground_content = true,
106         groups = {crumbly=3,soil=1,not_in_creative_inventory=1},
107         drop = 'default:dirt',
108         sounds = default.node_sound_dirt_defaults({
109                 footstep = {name="default_grass_footstep", gain=0.25},
110         }),
111 })
112
113 minetest.register_node("default:dirt_with_snow", {
114         description = "Dirt with Snow",
115         tiles = {"default_snow.png", "default_dirt.png", "default_dirt.png^default_snow_side.png"},
116         is_ground_content = true,
117         groups = {crumbly=3},
118         drop = 'default:dirt',
119         sounds = default.node_sound_dirt_defaults({
120                 footstep = {name="default_snow_footstep", gain=0.25},
121         }),
122 })
123
124 minetest.register_node("default:dirt", {
125         description = "Dirt",
126         tiles = {"default_dirt.png"},
127         is_ground_content = true,
128         groups = {crumbly=3,soil=1},
129         sounds = default.node_sound_dirt_defaults(),
130 })
131
132 minetest.register_abm({
133         nodenames = {"default:dirt"},
134         interval = 2,
135         chance = 200,
136         action = function(pos, node)
137                 local above = {x=pos.x, y=pos.y+1, z=pos.z}
138                 local name = minetest.get_node(above).name
139                 local nodedef = minetest.registered_nodes[name]
140                 if nodedef and (nodedef.sunlight_propagates or nodedef.paramtype == "light")
141                                 and nodedef.liquidtype == "none"
142                                 and (minetest.get_node_light(above) or 0) >= 13 then
143                         if name == "default:snow" or name == "default:snowblock" then
144                                 minetest.set_node(pos, {name = "default:dirt_with_snow"})
145                         else
146                                 minetest.set_node(pos, {name = "default:dirt_with_grass"})
147                         end
148                 end
149         end
150 })
151
152 minetest.register_abm({
153         nodenames = {"default:dirt_with_grass"},
154         interval = 2,
155         chance = 20,
156         action = function(pos, node)
157                 local above = {x=pos.x, y=pos.y+1, z=pos.z}
158                 local name = minetest.get_node(above).name
159                 local nodedef = minetest.registered_nodes[name]
160                 if name ~= "ignore" and nodedef
161                                 and not ((nodedef.sunlight_propagates or nodedef.paramtype == "light")
162                                 and nodedef.liquidtype == "none") then
163                         minetest.set_node(pos, {name = "default:dirt"})
164                 end
165         end
166 })
167
168 minetest.register_node("default:sand", {
169         description = "Sand",
170         tiles = {"default_sand.png"},
171         is_ground_content = true,
172         groups = {crumbly=3, falling_node=1, sand=1},
173         sounds = default.node_sound_sand_defaults(),
174 })
175
176 minetest.register_node("default:desert_sand", {
177         description = "Desert Sand",
178         tiles = {"default_desert_sand.png"},
179         is_ground_content = true,
180         groups = {crumbly=3, falling_node=1, sand=1},
181         sounds = default.node_sound_sand_defaults(),
182 })
183
184 minetest.register_node("default:gravel", {
185         description = "Gravel",
186         tiles = {"default_gravel.png"},
187         is_ground_content = true,
188         groups = {crumbly=2, falling_node=1},
189         sounds = default.node_sound_dirt_defaults({
190                 footstep = {name="default_gravel_footstep", gain=0.5},
191                 dug = {name="default_gravel_footstep", gain=1.0},
192         }),
193 })
194
195 minetest.register_node("default:sandstone", {
196         description = "Sandstone",
197         tiles = {"default_sandstone.png"},
198         is_ground_content = true,
199         groups = {crumbly=2,cracky=3},
200         sounds = default.node_sound_stone_defaults(),
201 })
202
203 minetest.register_node("default:sandstonebrick", {
204         description = "Sandstone Brick",
205         tiles = {"default_sandstone_brick.png"},
206         is_ground_content = true,
207         groups = {cracky=2},
208         sounds = default.node_sound_stone_defaults(),
209 })
210
211 minetest.register_node("default:clay", {
212         description = "Clay",
213         tiles = {"default_clay.png"},
214         is_ground_content = true,
215         groups = {crumbly=3},
216         drop = 'default:clay_lump 4',
217         sounds = default.node_sound_dirt_defaults(),
218 })
219
220 minetest.register_node("default:brick", {
221         description = "Brick Block",
222         tiles = {"default_brick.png"},
223         is_ground_content = false,
224         groups = {cracky=3},
225         sounds = default.node_sound_stone_defaults(),
226 })
227
228 minetest.register_node("default:tree", {
229         description = "Tree",
230         tiles = {"default_tree_top.png", "default_tree_top.png", "default_tree.png"},
231         paramtype2 = "facedir",
232         is_ground_content = false,
233         groups = {tree=1,choppy=2,oddly_breakable_by_hand=1,flammable=2},
234         sounds = default.node_sound_wood_defaults(),
235         on_place = minetest.rotate_node
236 })
237
238 minetest.register_node("default:jungletree", {
239         description = "Jungle Tree",
240         tiles = {"default_jungletree_top.png", "default_jungletree_top.png", "default_jungletree.png"},
241         paramtype2 = "facedir",
242         is_ground_content = false,
243         groups = {tree=1,choppy=2,oddly_breakable_by_hand=1,flammable=2},
244         sounds = default.node_sound_wood_defaults(),
245         on_place = minetest.rotate_node
246 })
247
248 minetest.register_node("default:junglewood", {
249         description = "Junglewood Planks",
250         tiles = {"default_junglewood.png"},
251         groups = {choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1},
252         sounds = default.node_sound_wood_defaults(),
253 })
254
255 minetest.register_node("default:jungleleaves", {
256         description = "Jungle Leaves",
257         drawtype = "allfaces_optional",
258         waving = 1,
259         visual_scale = 1.3,
260         tiles = {"default_jungleleaves.png"},
261         paramtype = "light",
262         is_ground_content = false,
263         groups = {snappy=3, leafdecay=3, flammable=2, leaves=1},
264         drop = {
265                 max_items = 1,
266                 items = {
267                         {
268                                 -- player will get sapling with 1/20 chance
269                                 items = {'default:junglesapling'},
270                                 rarity = 20,
271                         },
272                         {
273                                 -- player will get leaves only if he get no saplings,
274                                 -- this is because max_items is 1
275                                 items = {'default:jungleleaves'},
276                         }
277                 }
278         },
279         sounds = default.node_sound_leaves_defaults(),
280 })
281
282 minetest.register_node("default:junglesapling", {
283         description = "Jungle Sapling",
284         drawtype = "plantlike",
285         visual_scale = 1.0,
286         tiles = {"default_junglesapling.png"},
287         inventory_image = "default_junglesapling.png",
288         wield_image = "default_junglesapling.png",
289         paramtype = "light",
290         walkable = false,
291         selection_box = {
292                 type = "fixed",
293                 fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
294         },
295         groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1},
296         sounds = default.node_sound_leaves_defaults(),
297 })
298
299 minetest.register_node("default:junglegrass", {
300         description = "Jungle Grass",
301         drawtype = "plantlike",
302         waving = 1,
303         visual_scale = 1.3,
304         tiles = {"default_junglegrass.png"},
305         inventory_image = "default_junglegrass.png",
306         wield_image = "default_junglegrass.png",
307         paramtype = "light",
308         walkable = false,
309         buildable_to = true,
310         is_ground_content = true,
311         groups = {snappy=3,flammable=2,flora=1,attached_node=1},
312         sounds = default.node_sound_leaves_defaults(),
313         selection_box = {
314                 type = "fixed",
315                 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
316         },
317 })
318
319 minetest.register_node("default:leaves", {
320         description = "Leaves",
321         drawtype = "allfaces_optional",
322         waving = 1,
323         visual_scale = 1.3,
324         tiles = {"default_leaves.png"},
325         paramtype = "light",
326         is_ground_content = false,
327         groups = {snappy=3, leafdecay=3, flammable=2, leaves=1},
328         drop = {
329                 max_items = 1,
330                 items = {
331                         {
332                                 -- player will get sapling with 1/20 chance
333                                 items = {'default:sapling'},
334                                 rarity = 20,
335                         },
336                         {
337                                 -- player will get leaves only if he get no saplings,
338                                 -- this is because max_items is 1
339                                 items = {'default:leaves'},
340                         }
341                 }
342         },
343         sounds = default.node_sound_leaves_defaults(),
344 })
345
346 minetest.register_node("default:cactus", {
347         description = "Cactus",
348         tiles = {"default_cactus_top.png", "default_cactus_top.png", "default_cactus_side.png"},
349         paramtype2 = "facedir",
350         is_ground_content = true,
351         groups = {snappy=1,choppy=3,flammable=2},
352         sounds = default.node_sound_wood_defaults(),
353         on_place = minetest.rotate_node,
354         after_dig_node = function(pos, node, metadata, digger)
355                 default.dig_up(pos, node, digger)
356         end,
357 })
358
359 minetest.register_node("default:papyrus", {
360         description = "Papyrus",
361         drawtype = "plantlike",
362         tiles = {"default_papyrus.png"},
363         inventory_image = "default_papyrus.png",
364         wield_image = "default_papyrus.png",
365         paramtype = "light",
366         walkable = false,
367         is_ground_content = true,
368         selection_box = {
369                 type = "fixed",
370                 fixed = {-0.3, -0.5, -0.3, 0.3, 0.5, 0.3}
371         },
372         groups = {snappy=3,flammable=2},
373         sounds = default.node_sound_leaves_defaults(),
374         after_dig_node = function(pos, node, metadata, digger)
375                 default.dig_up(pos, node, digger)
376         end,
377 })
378
379 default.bookshelf_formspec =
380         "size[8,7;]"..
381         gui_bg..
382         gui_bg_img..
383         gui_slots..
384         "list[context;books;0,0.3;8,2;]"..
385         "list[current_player;main;0,2.85;8,1;]"..
386         "list[current_player;main;0,4.08;8,3;8]"..
387         default.get_hotbar_bg(0,2.85)
388
389 minetest.register_node("default:bookshelf", {
390         description = "Bookshelf",
391         tiles = {"default_wood.png", "default_wood.png", "default_bookshelf.png"},
392         is_ground_content = false,
393         groups = {choppy=3,oddly_breakable_by_hand=2,flammable=3},
394         sounds = default.node_sound_wood_defaults(),
395         on_construct = function(pos)
396                 local meta = minetest.env:get_meta(pos)
397                 meta:set_string("formspec", default.bookshelf_formspec)
398                 local inv = meta:get_inventory()
399                 inv:set_size("books", 8*2)
400         end,
401         can_dig = function(pos,player)
402                 local meta = minetest.env:get_meta(pos);
403                 local inv = meta:get_inventory()
404                 return inv:is_empty("books")
405         end,
406
407         allow_metadata_inventory_put = function(pos, listname, index, stack, player)
408                 local meta = minetest.env:get_meta(pos)
409                 local inv = meta:get_inventory()
410                 if listname == "books" then
411                         if stack:get_name() == "default:book" then
412                                 return 1
413                         else
414                                 return 0
415                         end
416                 end
417         end,
418
419         allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
420                 local meta = minetest.env:get_meta(pos)
421                 local inv = meta:get_inventory()
422                 local stack = inv:get_stack(from_list, from_index)
423                 local to_stack = inv:get_stack(to_list, to_index)
424                 if to_list == "books" then
425                         if stack:get_name() == "default:book" and to_stack:is_empty() then
426                                 return 1
427                         else
428                                 return 0
429                         end
430                 end
431         end,
432
433         on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
434                 minetest.log("action", player:get_player_name()..
435                            " moves stuff in bookshelf at "..minetest.pos_to_string(pos))
436         end,
437         on_metadata_inventory_put = function(pos, listname, index, stack, player)
438                 minetest.log("action", player:get_player_name()..
439                            " moves stuff to bookshelf at "..minetest.pos_to_string(pos))
440         end,
441         on_metadata_inventory_take = function(pos, listname, index, stack, player)
442                 minetest.log("action", player:get_player_name()..
443                            " takes stuff from bookshelf at "..minetest.pos_to_string(pos))
444         end,
445 })
446
447 minetest.register_node("default:glass", {
448         description = "Glass",
449         drawtype = "glasslike",
450         tiles = {"default_glass.png"},
451         inventory_image = minetest.inventorycube("default_glass.png"),
452         paramtype = "light",
453         sunlight_propagates = true,
454         is_ground_content = false,
455         groups = {cracky=3,oddly_breakable_by_hand=3},
456         sounds = default.node_sound_glass_defaults(),
457 })
458
459 minetest.register_node("default:fence_wood", {
460         description = "Wooden Fence",
461         drawtype = "fencelike",
462         tiles = {"default_wood.png"},
463         inventory_image = "default_fence.png",
464         wield_image = "default_fence.png",
465         paramtype = "light",
466         is_ground_content = false,
467         selection_box = {
468                 type = "fixed",
469                 fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
470         },
471         groups = {choppy=2,oddly_breakable_by_hand=2,flammable=2},
472         sounds = default.node_sound_wood_defaults(),
473 })
474
475 minetest.register_node("default:rail", {
476         description = "Rail",
477         drawtype = "raillike",
478         tiles = {"default_rail.png", "default_rail_curved.png", "default_rail_t_junction.png", "default_rail_crossing.png"},
479         inventory_image = "default_rail.png",
480         wield_image = "default_rail.png",
481         paramtype = "light",
482         walkable = false,
483         is_ground_content = false,
484         selection_box = {
485                 type = "fixed",
486                 -- but how to specify the dimensions for curved and sideways rails?
487                 fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
488         },
489         groups = {bendy=2,dig_immediate=2,attached_node=1},
490 })
491
492 minetest.register_node("default:ladder", {
493         description = "Ladder",
494         drawtype = "signlike",
495         tiles = {"default_ladder.png"},
496         inventory_image = "default_ladder.png",
497         wield_image = "default_ladder.png",
498         paramtype = "light",
499         paramtype2 = "wallmounted",
500         walkable = false,
501         climbable = true,
502         is_ground_content = false,
503         selection_box = {
504                 type = "wallmounted",
505                 --wall_top = = <default>
506                 --wall_bottom = = <default>
507                 --wall_side = = <default>
508         },
509         groups = {choppy=2,oddly_breakable_by_hand=3,flammable=2},
510         legacy_wallmounted = true,
511         sounds = default.node_sound_wood_defaults(),
512 })
513
514 minetest.register_node("default:wood", {
515         description = "Wooden Planks",
516         tiles = {"default_wood.png"},
517         groups = {choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1},
518         sounds = default.node_sound_wood_defaults(),
519 })
520
521 minetest.register_node("default:cloud", {
522         description = "Cloud",
523         tiles = {"default_cloud.png"},
524         sounds = default.node_sound_defaults(),
525         groups = {not_in_creative_inventory=1},
526 })
527
528 minetest.register_node("default:water_flowing", {
529         description = "Flowing Water",
530         inventory_image = minetest.inventorycube("default_water.png"),
531         drawtype = "flowingliquid",
532         tiles = {"default_water.png"},
533         special_tiles = {
534                 {
535                         image="default_water_flowing_animated.png",
536                         backface_culling=false,
537                         animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=0.8}
538                 },
539                 {
540                         image="default_water_flowing_animated.png",
541                         backface_culling=true,
542                         animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=0.8}
543                 },
544         },
545         alpha = WATER_ALPHA,
546         paramtype = "light",
547         paramtype2 = "flowingliquid",
548         walkable = false,
549         pointable = false,
550         diggable = false,
551         buildable_to = true,
552         drop = "",
553         drowning = 1,
554         liquidtype = "flowing",
555         liquid_alternative_flowing = "default:water_flowing",
556         liquid_alternative_source = "default:water_source",
557         liquid_viscosity = WATER_VISC,
558         freezemelt = "default:snow",
559         post_effect_color = {a=64, r=100, g=100, b=200},
560         groups = {water=3, liquid=3, puts_out_fire=1, not_in_creative_inventory=1, freezes=1, melt_around=1},
561 })
562
563 minetest.register_node("default:water_source", {
564         description = "Water Source",
565         inventory_image = minetest.inventorycube("default_water.png"),
566         drawtype = "liquid",
567         tiles = {
568                 {name="default_water_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}}
569         },
570         special_tiles = {
571                 -- New-style water source material (mostly unused)
572                 {
573                         name="default_water_source_animated.png",
574                         animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0},
575                         backface_culling = false,
576                 }
577         },
578         alpha = WATER_ALPHA,
579         paramtype = "light",
580         walkable = false,
581         pointable = false,
582         diggable = false,
583         buildable_to = true,
584         drop = "",
585         drowning = 1,
586         liquidtype = "source",
587         liquid_alternative_flowing = "default:water_flowing",
588         liquid_alternative_source = "default:water_source",
589         liquid_viscosity = WATER_VISC,
590         freezemelt = "default:ice",
591         post_effect_color = {a=64, r=100, g=100, b=200},
592         groups = {water=3, liquid=3, puts_out_fire=1, freezes=1},
593 })
594
595 minetest.register_node("default:lava_flowing", {
596         description = "Flowing Lava",
597         inventory_image = minetest.inventorycube("default_lava.png"),
598         drawtype = "flowingliquid",
599         tiles = {"default_lava.png"},
600         special_tiles = {
601                 {
602                         image="default_lava_flowing_animated.png",
603                         backface_culling=false,
604                         animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3}
605                 },
606                 {
607                         image="default_lava_flowing_animated.png",
608                         backface_culling=true,
609                         animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3}
610                 },
611         },
612         paramtype = "light",
613         paramtype2 = "flowingliquid",
614         light_source = LIGHT_MAX - 1,
615         walkable = false,
616         pointable = false,
617         diggable = false,
618         buildable_to = true,
619         drop = "",
620         drowning = 1,
621         liquidtype = "flowing",
622         liquid_alternative_flowing = "default:lava_flowing",
623         liquid_alternative_source = "default:lava_source",
624         liquid_viscosity = LAVA_VISC,
625         liquid_renewable = false,
626         damage_per_second = 4*2,
627         post_effect_color = {a=192, r=255, g=64, b=0},
628         groups = {lava=3, liquid=2, hot=3, igniter=1, not_in_creative_inventory=1},
629 })
630
631 minetest.register_node("default:lava_source", {
632         description = "Lava Source",
633         inventory_image = minetest.inventorycube("default_lava.png"),
634         drawtype = "liquid",
635         tiles = {
636                 {name="default_lava_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}}
637         },
638         special_tiles = {
639                 -- New-style lava source material (mostly unused)
640                 {
641                         name="default_lava_source_animated.png",
642                         animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0},
643                         backface_culling = false,
644                 }
645         },
646         paramtype = "light",
647         light_source = LIGHT_MAX - 1,
648         walkable = false,
649         pointable = false,
650         diggable = false,
651         buildable_to = true,
652         drop = "",
653         drowning = 1,
654         liquidtype = "source",
655         liquid_alternative_flowing = "default:lava_flowing",
656         liquid_alternative_source = "default:lava_source",
657         liquid_viscosity = LAVA_VISC,
658         liquid_renewable = false,
659         damage_per_second = 4*2,
660         post_effect_color = {a=192, r=255, g=64, b=0},
661         groups = {lava=3, liquid=2, hot=3, igniter=1},
662 })
663
664 minetest.register_node("default:torch", {
665         description = "Torch",
666         drawtype = "torchlike",
667         --tiles = {"default_torch_on_floor.png", "default_torch_on_ceiling.png", "default_torch.png"},
668         tiles = {
669                 {name="default_torch_on_floor_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}},
670                 {name="default_torch_on_ceiling_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}},
671                 {name="default_torch_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}}
672         },
673         inventory_image = "default_torch_on_floor.png",
674         wield_image = "default_torch_on_floor.png",
675         paramtype = "light",
676         paramtype2 = "wallmounted",
677         sunlight_propagates = true,
678         is_ground_content = false,
679         walkable = false,
680         light_source = LIGHT_MAX-1,
681         selection_box = {
682                 type = "wallmounted",
683                 wall_top = {-0.1, 0.5-0.6, -0.1, 0.1, 0.5, 0.1},
684                 wall_bottom = {-0.1, -0.5, -0.1, 0.1, -0.5+0.6, 0.1},
685                 wall_side = {-0.5, -0.3, -0.1, -0.5+0.3, 0.3, 0.1},
686         },
687         groups = {choppy=2,dig_immediate=3,flammable=1,attached_node=1,hot=2},
688         legacy_wallmounted = true,
689         sounds = default.node_sound_defaults(),
690 })
691
692 minetest.register_node("default:sign_wall", {
693         description = "Sign",
694         drawtype = "signlike",
695         tiles = {"default_sign_wall.png"},
696         inventory_image = "default_sign_wall.png",
697         wield_image = "default_sign_wall.png",
698         paramtype = "light",
699         paramtype2 = "wallmounted",
700         sunlight_propagates = true,
701         is_ground_content = false,
702         walkable = false,
703         selection_box = {
704                 type = "wallmounted",
705                 --wall_top = <default>
706                 --wall_bottom = <default>
707                 --wall_side = <default>
708         },
709         groups = {choppy=2,dig_immediate=2,attached_node=1},
710         legacy_wallmounted = true,
711         sounds = default.node_sound_defaults(),
712         on_construct = function(pos)
713                 --local n = minetest.get_node(pos)
714                 local meta = minetest.get_meta(pos)
715                 meta:set_string("formspec", "field[text;;${text}]")
716                 meta:set_string("infotext", "\"\"")
717         end,
718         on_receive_fields = function(pos, formname, fields, sender)
719                 --print("Sign at "..minetest.pos_to_string(pos).." got "..dump(fields))
720                 if minetest.is_protected(pos, sender:get_player_name()) then
721                         minetest.record_protection_violation(pos, sender:get_player_name())
722                         return
723                 end
724                 local meta = minetest.get_meta(pos)
725                 fields.text = fields.text or ""
726                 minetest.log("action", (sender:get_player_name() or "").." wrote \""..fields.text..
727                                 "\" to sign at "..minetest.pos_to_string(pos))
728                 meta:set_string("text", fields.text)
729                 meta:set_string("infotext", '"'..fields.text..'"')
730         end,
731 })
732
733 default.chest_formspec = 
734         "size[8,9]"..
735         gui_bg..
736         gui_bg_img..
737         gui_slots..
738         "list[current_name;main;0,0.3;8,4;]"..
739         "list[current_player;main;0,4.85;8,1;]"..
740         "list[current_player;main;0,6.08;8,3;8]"..
741         default.get_hotbar_bg(0,4.85)
742
743 function default.get_locked_chest_formspec(pos)
744         local spos = pos.x .. "," .. pos.y .. "," ..pos.z
745         local formspec =
746                 "size[8,9]"..
747                 gui_bg..
748                 gui_bg_img..
749                 gui_slots..
750                 "list[nodemeta:".. spos .. ";main;0,0.3;8,4;]"..
751                 "list[current_player;main;0,4.85;8,1;]"..
752                 "list[current_player;main;0,6.08;8,3;8]"..
753                 default.get_hotbar_bg(0,4.85)
754  return formspec
755 end
756
757
758 minetest.register_node("default:chest", {
759         description = "Chest",
760         tiles = {"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
761                 "default_chest_side.png", "default_chest_side.png", "default_chest_front.png"},
762         paramtype2 = "facedir",
763         groups = {choppy=2,oddly_breakable_by_hand=2},
764         legacy_facedir_simple = true,
765         is_ground_content = false,
766         sounds = default.node_sound_wood_defaults(),
767         on_construct = function(pos)
768                 local meta = minetest.get_meta(pos)
769                 meta:set_string("formspec",default.chest_formspec)
770                 meta:set_string("infotext", "Chest")
771                 local inv = meta:get_inventory()
772                 inv:set_size("main", 8*4)
773         end,
774         can_dig = function(pos,player)
775                 local meta = minetest.get_meta(pos);
776                 local inv = meta:get_inventory()
777                 return inv:is_empty("main")
778         end,
779         on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
780                 minetest.log("action", player:get_player_name()..
781                                 " moves stuff in chest at "..minetest.pos_to_string(pos))
782         end,
783     on_metadata_inventory_put = function(pos, listname, index, stack, player)
784                 minetest.log("action", player:get_player_name()..
785                                 " moves stuff to chest at "..minetest.pos_to_string(pos))
786         end,
787     on_metadata_inventory_take = function(pos, listname, index, stack, player)
788                 minetest.log("action", player:get_player_name()..
789                                 " takes stuff from chest at "..minetest.pos_to_string(pos))
790         end,
791 })
792
793 local function has_locked_chest_privilege(meta, player)
794         if player:get_player_name() ~= meta:get_string("owner") then
795                 return false
796         end
797         return true
798 end
799
800 minetest.register_node("default:chest_locked", {
801         description = "Locked Chest",
802         tiles = {"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
803                 "default_chest_side.png", "default_chest_side.png", "default_chest_lock.png"},
804         paramtype2 = "facedir",
805         groups = {choppy=2,oddly_breakable_by_hand=2},
806         legacy_facedir_simple = true,
807         is_ground_content = false,
808         sounds = default.node_sound_wood_defaults(),
809         after_place_node = function(pos, placer)
810                 local meta = minetest.get_meta(pos)
811                 meta:set_string("owner", placer:get_player_name() or "")
812                 meta:set_string("infotext", "Locked Chest (owned by "..
813                                 meta:get_string("owner")..")")
814         end,
815         on_construct = function(pos)
816                 local meta = minetest.get_meta(pos)
817                 meta:set_string("infotext", "Locked Chest")
818                 meta:set_string("owner", "")
819                 local inv = meta:get_inventory()
820                 inv:set_size("main", 8*4)
821         end,
822         can_dig = function(pos,player)
823                 local meta = minetest.get_meta(pos);
824                 local inv = meta:get_inventory()
825                 return inv:is_empty("main") and has_locked_chest_privilege(meta, player)
826         end,
827         allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
828                 local meta = minetest.get_meta(pos)
829                 if not has_locked_chest_privilege(meta, player) then
830                         minetest.log("action", player:get_player_name()..
831                                         " tried to access a locked chest belonging to "..
832                                         meta:get_string("owner").." at "..
833                                         minetest.pos_to_string(pos))
834                         return 0
835                 end
836                 return count
837         end,
838     allow_metadata_inventory_put = function(pos, listname, index, stack, player)
839                 local meta = minetest.get_meta(pos)
840                 if not has_locked_chest_privilege(meta, player) then
841                         minetest.log("action", player:get_player_name()..
842                                         " tried to access a locked chest belonging to "..
843                                         meta:get_string("owner").." at "..
844                                         minetest.pos_to_string(pos))
845                         return 0
846                 end
847                 return stack:get_count()
848         end,
849     allow_metadata_inventory_take = function(pos, listname, index, stack, player)
850                 local meta = minetest.get_meta(pos)
851                 if not has_locked_chest_privilege(meta, player) then
852                         minetest.log("action", player:get_player_name()..
853                                         " tried to access a locked chest belonging to "..
854                                         meta:get_string("owner").." at "..
855                                         minetest.pos_to_string(pos))
856                         return 0
857                 end
858                 return stack:get_count()
859         end,
860         on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
861                 minetest.log("action", player:get_player_name()..
862                                 " moves stuff in locked chest at "..minetest.pos_to_string(pos))
863         end,
864     on_metadata_inventory_put = function(pos, listname, index, stack, player)
865                 minetest.log("action", player:get_player_name()..
866                                 " moves stuff to locked chest at "..minetest.pos_to_string(pos))
867         end,
868     on_metadata_inventory_take = function(pos, listname, index, stack, player)
869                 minetest.log("action", player:get_player_name()..
870                                 " takes stuff from locked chest at "..minetest.pos_to_string(pos))
871         end,
872         on_rightclick = function(pos, node, clicker)
873                 local meta = minetest.get_meta(pos)
874                 if has_locked_chest_privilege(meta, clicker) then
875                         minetest.show_formspec(
876                                 clicker:get_player_name(),
877                                 "default:chest_locked",
878                                 default.get_locked_chest_formspec(pos)
879                         )
880                 end
881         end,
882 })
883
884 function default.furnace_active(pos, percent, item_percent)
885     local formspec = 
886         "size[8,8.5]"..
887         gui_bg..
888         gui_bg_img..
889         gui_slots..
890         "list[current_name;src;2.75,0.5;1,1;]"..
891         "list[current_name;fuel;2.75,2.5;1,1;]"..
892         "image[2.75,1.5;1,1;default_furnace_fire_bg.png^[lowpart:"..
893         (100-percent)..":default_furnace_fire_fg.png]"..
894         "image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[lowpart:"..
895         (item_percent*100)..":gui_furnace_arrow_fg.png^[transformR270]"..
896         "list[current_name;dst;4.75,0.96;2,2;]"..
897         "list[current_player;main;0,4.25;8,1;]"..
898         "list[current_player;main;0,5.5;8,3;8]"..
899         default.get_hotbar_bg(0,4.25)
900     return formspec
901   end
902
903 function default.get_furnace_active_formspec(pos, percent)
904         local meta = minetest.get_meta(pos)local inv = meta:get_inventory()
905         local srclist = inv:get_list("src")
906         local cooked = nil
907         local aftercooked = nil
908         if srclist then
909                 cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
910         end
911         local item_percent = 0
912         if cooked then
913                 item_percent = meta:get_float("src_time")/cooked.time
914         end
915        
916         return default.furnace_active(pos, percent, item_percent)
917 end
918
919 default.furnace_inactive_formspec =
920         "size[8,8.5]"..
921         gui_bg..
922         gui_bg_img..
923         gui_slots..
924         "list[current_name;src;2.75,0.5;1,1;]"..
925         "list[current_name;fuel;2.75,2.5;1,1;]"..
926         "image[2.75,1.5;1,1;default_furnace_fire_bg.png]"..
927         "image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[transformR270]"..
928         "list[current_name;dst;4.75,0.96;2,2;]"..
929         "list[current_player;main;0,4.25;8,1;]"..
930         "list[current_player;main;0,5.5;8,3;8]"..
931         default.get_hotbar_bg(0,4.25)
932
933 minetest.register_node("default:furnace", {
934         description = "Furnace",
935         tiles = {"default_furnace_top.png", "default_furnace_bottom.png", "default_furnace_side.png",
936                 "default_furnace_side.png", "default_furnace_side.png", "default_furnace_front.png"},
937         paramtype2 = "facedir",
938         groups = {cracky=2},
939         legacy_facedir_simple = true,
940         is_ground_content = false,
941         sounds = default.node_sound_stone_defaults(),
942         on_construct = function(pos)
943                 local meta = minetest.get_meta(pos)
944                 meta:set_string("formspec", default.furnace_inactive_formspec)
945                 meta:set_string("infotext", "Furnace")
946                 local inv = meta:get_inventory()
947                 inv:set_size("fuel", 1)
948                 inv:set_size("src", 1)
949                 inv:set_size("dst", 4)
950         end,
951         can_dig = function(pos,player)
952                 local meta = minetest.get_meta(pos);
953                 local inv = meta:get_inventory()
954                 if not inv:is_empty("fuel") then
955                         return false
956                 elseif not inv:is_empty("dst") then
957                         return false
958                 elseif not inv:is_empty("src") then
959                         return false
960                 end
961                 return true
962         end,
963         allow_metadata_inventory_put = function(pos, listname, index, stack, player)
964                 local meta = minetest.get_meta(pos)
965                 local inv = meta:get_inventory()
966                 if listname == "fuel" then
967                         if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
968                                 if inv:is_empty("src") then
969                                         meta:set_string("infotext","Furnace is empty")
970                                 end
971                                 return stack:get_count()
972                         else
973                                 return 0
974                         end
975                 elseif listname == "src" then
976                         return stack:get_count()
977                 elseif listname == "dst" then
978                         return 0
979                 end
980         end,
981         allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
982                 local meta = minetest.get_meta(pos)
983                 local inv = meta:get_inventory()
984                 local stack = inv:get_stack(from_list, from_index)
985                 if to_list == "fuel" then
986                         if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
987                                 if inv:is_empty("src") then
988                                         meta:set_string("infotext","Furnace is empty")
989                                 end
990                                 return count
991                         else
992                                 return 0
993                         end
994                 elseif to_list == "src" then
995                         return count
996                 elseif to_list == "dst" then
997                         return 0
998                 end
999         end,
1000 })
1001
1002 minetest.register_node("default:furnace_active", {
1003         description = "Furnace",
1004         tiles = {
1005                 "default_furnace_top.png",
1006                 "default_furnace_bottom.png",
1007                 "default_furnace_side.png",
1008                 "default_furnace_side.png",
1009                 "default_furnace_side.png",
1010                 {
1011                         image = "default_furnace_front_active.png",
1012                         backface_culling = false,
1013                         animation = {
1014                                 type = "vertical_frames",
1015                                 aspect_w = 16,
1016                                 aspect_h = 16,
1017                                 length = 1.5
1018                         },
1019                 }
1020         },
1021         paramtype2 = "facedir",
1022         light_source = 8,
1023         drop = "default:furnace",
1024         groups = {cracky=2, not_in_creative_inventory=1,hot=1},
1025         legacy_facedir_simple = true,
1026         is_ground_content = false,
1027         sounds = default.node_sound_stone_defaults(),
1028         on_construct = function(pos)
1029                 local meta = minetest.get_meta(pos)
1030                 meta:set_string("formspec", default.furnace_inactive_formspec)
1031                 meta:set_string("infotext", "Furnace");
1032                 local inv = meta:get_inventory()
1033                 inv:set_size("fuel", 1)
1034                 inv:set_size("src", 1)
1035                 inv:set_size("dst", 4)
1036         end,
1037         can_dig = function(pos,player)
1038                 local meta = minetest.get_meta(pos);
1039                 local inv = meta:get_inventory()
1040                 if not inv:is_empty("fuel") then
1041                         return false
1042                 elseif not inv:is_empty("dst") then
1043                         return false
1044                 elseif not inv:is_empty("src") then
1045                         return false
1046                 end
1047                 return true
1048         end,
1049         allow_metadata_inventory_put = function(pos, listname, index, stack, player)
1050                 local meta = minetest.get_meta(pos)
1051                 local inv = meta:get_inventory()
1052                 if listname == "fuel" then
1053                         if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
1054                                 if inv:is_empty("src") then
1055                                         meta:set_string("infotext","Furnace is empty")
1056                                 end
1057                                 return stack:get_count()
1058                         else
1059                                 return 0
1060                         end
1061                 elseif listname == "src" then
1062                         return stack:get_count()
1063                 elseif listname == "dst" then
1064                         return 0
1065                 end
1066         end,
1067         allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
1068                 local meta = minetest.get_meta(pos)
1069                 local inv = meta:get_inventory()
1070                 local stack = inv:get_stack(from_list, from_index)
1071                 if to_list == "fuel" then
1072                         if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
1073                                 if inv:is_empty("src") then
1074                                         meta:set_string("infotext","Furnace is empty")
1075                                 end
1076                                 return count
1077                         else
1078                                 return 0
1079                         end
1080                 elseif to_list == "src" then
1081                         return count
1082                 elseif to_list == "dst" then
1083                         return 0
1084                 end
1085         end,
1086 })
1087
1088 local function swap_node(pos,name)
1089         local node = minetest.get_node(pos)
1090         if node.name == name then
1091                 return
1092         end
1093         node.name = name
1094         minetest.swap_node(pos,node)
1095 end
1096
1097 minetest.register_abm({
1098         nodenames = {"default:furnace","default:furnace_active"},
1099         interval = 1.0,
1100         chance = 1,
1101         action = function(pos, node, active_object_count, active_object_count_wider)
1102                 local meta = minetest.get_meta(pos)
1103                 for i, name in ipairs({
1104                                 "fuel_totaltime",
1105                                 "fuel_time",
1106                                 "src_totaltime",
1107                                 "src_time"
1108                 }) do
1109                         if meta:get_string(name) == "" then
1110                                 meta:set_float(name, 0.0)
1111                         end
1112                 end
1113
1114                 local inv = meta:get_inventory()
1115
1116                 local srclist = inv:get_list("src")
1117                 local cooked = nil
1118                 local aftercooked
1119                 
1120                 if srclist then
1121                         cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
1122                 end
1123                 
1124                 local was_active = false
1125                 
1126                 if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
1127                         was_active = true
1128                         meta:set_float("fuel_time", meta:get_float("fuel_time") + 1)
1129                         meta:set_float("src_time", meta:get_float("src_time") + 1)
1130                         if cooked and cooked.item and meta:get_float("src_time") >= cooked.time then
1131                                 -- check if there's room for output in "dst" list
1132                                 if inv:room_for_item("dst",cooked.item) then
1133                                         -- Put result in "dst" list
1134                                         inv:add_item("dst", cooked.item)
1135                                         -- take stuff from "src" list
1136                                         inv:set_stack("src", 1, aftercooked.items[1])
1137                                 else
1138                                         --print("Could not insert '"..cooked.item:to_string().."'")
1139                                 end
1140                                 meta:set_string("src_time", 0)
1141                         end
1142                 end
1143                 
1144                 if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
1145                         local percent = math.floor(meta:get_float("fuel_time") /
1146                                         meta:get_float("fuel_totaltime") * 100)
1147                         meta:set_string("infotext","Furnace active: "..percent.."%")
1148                         swap_node(pos,"default:furnace_active")
1149                         meta:set_string("formspec",default.get_furnace_active_formspec(pos, percent))
1150                         return
1151                 end
1152
1153                 local fuel = nil
1154                 local afterfuel
1155                 local cooked = nil
1156                 local fuellist = inv:get_list("fuel")
1157                 local srclist = inv:get_list("src")
1158                 
1159                 if srclist then
1160                         cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
1161                 end
1162                 if fuellist then
1163                         fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
1164                 end
1165
1166                 if not fuel or fuel.time <= 0 then
1167                         meta:set_string("infotext","Furnace out of fuel")
1168                         swap_node(pos,"default:furnace")
1169                         meta:set_string("formspec", default.furnace_inactive_formspec)
1170                         return
1171                 end
1172
1173                 if cooked.item:is_empty() then
1174                         if was_active then
1175                                 meta:set_string("infotext","Furnace is empty")
1176                                 swap_node(pos,"default:furnace")
1177                                 meta:set_string("formspec", default.furnace_inactive_formspec)
1178                         end
1179                         return
1180                 end
1181
1182                 meta:set_string("fuel_totaltime", fuel.time)
1183                 meta:set_string("fuel_time", 0)
1184                 
1185                 inv:set_stack("fuel", 1, afterfuel.items[1])
1186         end,
1187 })
1188
1189 minetest.register_node("default:cobble", {
1190         description = "Cobblestone",
1191         tiles = {"default_cobble.png"},
1192         is_ground_content = true,
1193         groups = {cracky=3, stone=2},
1194         sounds = default.node_sound_stone_defaults(),
1195 })
1196
1197 minetest.register_node("default:desert_cobble", {
1198         description = "Desert Cobblestone",
1199         tiles = {"default_desert_cobble.png"},
1200         is_ground_content = true,
1201         groups = {cracky=3, stone=2},
1202         sounds = default.node_sound_stone_defaults(),
1203 })
1204
1205 minetest.register_node("default:mossycobble", {
1206         description = "Mossy Cobblestone",
1207         tiles = {"default_mossycobble.png"},
1208         is_ground_content = true,
1209         groups = {cracky=3},
1210         sounds = default.node_sound_stone_defaults(),
1211 })
1212
1213 minetest.register_node("default:coalblock", {
1214         description = "Coal Block",
1215         tiles = {"default_coal_block.png"},
1216         is_ground_content = true,
1217         groups = {cracky=3},
1218         sounds = default.node_sound_stone_defaults(),
1219 })
1220
1221 minetest.register_node("default:steelblock", {
1222         description = "Steel Block",
1223         tiles = {"default_steel_block.png"},
1224         is_ground_content = true,
1225         groups = {cracky=1,level=2},
1226         sounds = default.node_sound_stone_defaults(),
1227 })
1228
1229 minetest.register_node("default:copperblock", {
1230         description = "Copper Block",
1231         tiles = {"default_copper_block.png"},
1232         is_ground_content = true,
1233         groups = {cracky=1,level=2},
1234         sounds = default.node_sound_stone_defaults(),
1235 })
1236
1237 minetest.register_node("default:bronzeblock", {
1238         description = "Bronze Block",
1239         tiles = {"default_bronze_block.png"},
1240         is_ground_content = true,
1241         groups = {cracky=1,level=2},
1242         sounds = default.node_sound_stone_defaults(),
1243 })
1244
1245 minetest.register_node("default:mese", {
1246         description = "Mese Block",
1247         tiles = {"default_mese_block.png"},
1248         is_ground_content = true,
1249         groups = {cracky=1,level=2},
1250         sounds = default.node_sound_stone_defaults(),
1251 })
1252 minetest.register_alias("default:mese_block", "default:mese")
1253
1254 minetest.register_node("default:goldblock", {
1255         description = "Gold Block",
1256         tiles = {"default_gold_block.png"},
1257         is_ground_content = true,
1258         groups = {cracky=1},
1259         sounds = default.node_sound_stone_defaults(),
1260 })
1261
1262 minetest.register_node("default:diamondblock", {
1263         description = "Diamond Block",
1264         tiles = {"default_diamond_block.png"},
1265         is_ground_content = true,
1266         groups = {cracky=1,level=3},
1267         sounds = default.node_sound_stone_defaults(),
1268 })
1269
1270 minetest.register_node("default:obsidian_glass", {
1271         description = "Obsidian Glass",
1272         drawtype = "glasslike",
1273         tiles = {"default_obsidian_glass.png"},
1274         paramtype = "light",
1275         is_ground_content = false,
1276         sunlight_propagates = true,
1277         sounds = default.node_sound_glass_defaults(),
1278         groups = {cracky=3,oddly_breakable_by_hand=3},
1279 })
1280
1281 minetest.register_node("default:obsidian", {
1282         description = "Obsidian",
1283         tiles = {"default_obsidian.png"},
1284         is_ground_content = true,
1285         sounds = default.node_sound_stone_defaults(),
1286         groups = {cracky=1,level=2},
1287 })
1288
1289 minetest.register_node("default:nyancat", {
1290         description = "Nyan Cat",
1291         tiles = {"default_nc_side.png", "default_nc_side.png", "default_nc_side.png",
1292                 "default_nc_side.png", "default_nc_back.png", "default_nc_front.png"},
1293         paramtype2 = "facedir",
1294         groups = {cracky=2},
1295         is_ground_content = false,
1296         legacy_facedir_simple = true,
1297         sounds = default.node_sound_defaults(),
1298 })
1299
1300 minetest.register_node("default:nyancat_rainbow", {
1301         description = "Nyan Cat Rainbow",
1302         tiles = {"default_nc_rb.png^[transformR90", "default_nc_rb.png^[transformR90",
1303                 "default_nc_rb.png", "default_nc_rb.png"},
1304         paramtype2 = "facedir",
1305         groups = {cracky=2},
1306         is_ground_content = false,
1307         sounds = default.node_sound_defaults(),
1308 })
1309
1310 minetest.register_node("default:sapling", {
1311         description = "Sapling",
1312         drawtype = "plantlike",
1313         visual_scale = 1.0,
1314         tiles = {"default_sapling.png"},
1315         inventory_image = "default_sapling.png",
1316         wield_image = "default_sapling.png",
1317         paramtype = "light",
1318         walkable = false,
1319         is_ground_content = true,
1320         selection_box = {
1321                 type = "fixed",
1322                 fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
1323         },
1324         groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1},
1325         sounds = default.node_sound_leaves_defaults(),
1326 })
1327
1328 minetest.register_node("default:apple", {
1329         description = "Apple",
1330         drawtype = "plantlike",
1331         visual_scale = 1.0,
1332         tiles = {"default_apple.png"},
1333         inventory_image = "default_apple.png",
1334         paramtype = "light",
1335         sunlight_propagates = true,
1336         walkable = false,
1337         is_ground_content = true,
1338         selection_box = {
1339                 type = "fixed",
1340                 fixed = {-0.2, -0.5, -0.2, 0.2, 0, 0.2}
1341         },
1342         groups = {fleshy=3,dig_immediate=3,flammable=2,leafdecay=3,leafdecay_drop=1},
1343         on_use = minetest.item_eat(1),
1344         sounds = default.node_sound_leaves_defaults(),
1345         after_place_node = function(pos, placer, itemstack)
1346                 if placer:is_player() then
1347                         minetest.set_node(pos, {name="default:apple", param2=1})
1348                 end
1349         end,
1350 })
1351
1352 minetest.register_node("default:dry_shrub", {
1353         description = "Dry Shrub",
1354         drawtype = "plantlike",
1355         waving = 1,
1356         visual_scale = 1.0,
1357         tiles = {"default_dry_shrub.png"},
1358         inventory_image = "default_dry_shrub.png",
1359         wield_image = "default_dry_shrub.png",
1360         paramtype = "light",
1361         walkable = false,
1362         is_ground_content = true,
1363         buildable_to = true,
1364         groups = {snappy=3,flammable=3,attached_node=1},
1365         sounds = default.node_sound_leaves_defaults(),
1366         selection_box = {
1367                 type = "fixed",
1368                 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1369         },
1370 })
1371
1372 minetest.register_node("default:grass_1", {
1373         description = "Grass",
1374         drawtype = "plantlike",
1375         waving = 1,
1376         tiles = {"default_grass_1.png"},
1377         -- use a bigger inventory image
1378         inventory_image = "default_grass_3.png",
1379         wield_image = "default_grass_3.png",
1380         paramtype = "light",
1381         walkable = false,
1382         is_ground_content = true,
1383         buildable_to = true,
1384         groups = {snappy=3,flammable=3,flora=1,attached_node=1},
1385         sounds = default.node_sound_leaves_defaults(),
1386         selection_box = {
1387                 type = "fixed",
1388                 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1389         },
1390         on_place = function(itemstack, placer, pointed_thing)
1391                 -- place a random grass node
1392                 local stack = ItemStack("default:grass_"..math.random(1,5))
1393                 local ret = minetest.item_place(stack, placer, pointed_thing)
1394                 return ItemStack("default:grass_1 "..itemstack:get_count()-(1-ret:get_count()))
1395         end,
1396 })
1397
1398 minetest.register_node("default:grass_2", {
1399         description = "Grass",
1400         drawtype = "plantlike",
1401         waving = 1,
1402         tiles = {"default_grass_2.png"},
1403         inventory_image = "default_grass_2.png",
1404         wield_image = "default_grass_2.png",
1405         paramtype = "light",
1406         walkable = false,
1407         buildable_to = true,
1408         is_ground_content = true,
1409         drop = "default:grass_1",
1410         groups = {snappy=3,flammable=3,flora=1,attached_node=1,not_in_creative_inventory=1},
1411         sounds = default.node_sound_leaves_defaults(),
1412         selection_box = {
1413                 type = "fixed",
1414                 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1415         },
1416 })
1417 minetest.register_node("default:grass_3", {
1418         description = "Grass",
1419         drawtype = "plantlike",
1420         waving = 1,
1421         tiles = {"default_grass_3.png"},
1422         inventory_image = "default_grass_3.png",
1423         wield_image = "default_grass_3.png",
1424         paramtype = "light",
1425         walkable = false,
1426         buildable_to = true,
1427         is_ground_content = true,
1428         drop = "default:grass_1",
1429         groups = {snappy=3,flammable=3,flora=1,attached_node=1,not_in_creative_inventory=1},
1430         sounds = default.node_sound_leaves_defaults(),
1431         selection_box = {
1432                 type = "fixed",
1433                 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1434         },
1435 })
1436
1437 minetest.register_node("default:grass_4", {
1438         description = "Grass",
1439         drawtype = "plantlike",
1440         waving = 1,
1441         tiles = {"default_grass_4.png"},
1442         inventory_image = "default_grass_4.png",
1443         wield_image = "default_grass_4.png",
1444         paramtype = "light",
1445         walkable = false,
1446         buildable_to = true,
1447         is_ground_content = true,
1448         drop = "default:grass_1",
1449         groups = {snappy=3,flammable=3,flora=1,attached_node=1,not_in_creative_inventory=1},
1450         sounds = default.node_sound_leaves_defaults(),
1451         selection_box = {
1452                 type = "fixed",
1453                 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1454         },
1455 })
1456
1457 minetest.register_node("default:grass_5", {
1458         description = "Grass",
1459         drawtype = "plantlike",
1460         waving = 1,
1461         tiles = {"default_grass_5.png"},
1462         inventory_image = "default_grass_5.png",
1463         wield_image = "default_grass_5.png",
1464         paramtype = "light",
1465         walkable = false,
1466         buildable_to = true,
1467         is_ground_content = true,
1468         drop = "default:grass_1",
1469         groups = {snappy=3,flammable=3,flora=1,attached_node=1,not_in_creative_inventory=1},
1470         sounds = default.node_sound_leaves_defaults(),
1471         selection_box = {
1472                 type = "fixed",
1473                 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1474         },
1475 })
1476
1477 minetest.register_node("default:ice", {
1478         description = "Ice",
1479         tiles = {"default_ice.png"},
1480         is_ground_content = true,
1481         paramtype = "light",
1482         freezemelt = "default:water_source",
1483         groups = {cracky=3, melts=1},
1484         sounds = default.node_sound_glass_defaults(),
1485 })
1486
1487 minetest.register_node("default:snow", {
1488         description = "Snow",
1489         tiles = {"default_snow.png"},
1490         inventory_image = "default_snowball.png",
1491         wield_image = "default_snowball.png",
1492         is_ground_content = true,
1493         paramtype = "light",
1494         buildable_to = true,
1495         leveled = 7,
1496         drawtype = "nodebox",
1497         freezemelt = "default:water_flowing",
1498         node_box = {
1499                 type = "leveled",
1500                 fixed = {
1501                         {-0.5, -0.5, -0.5,  0.5, -0.5+2/16, 0.5},
1502                 },
1503         },
1504         groups = {crumbly=3,falling_node=1, melts=1, float=1},
1505         sounds = default.node_sound_dirt_defaults({
1506                 footstep = {name="default_snow_footstep", gain=0.25},
1507                 dug = {name="default_snow_footstep", gain=0.75},
1508         }),
1509         on_construct = function(pos)
1510                 pos.y = pos.y - 1
1511                 if minetest.get_node(pos).name == "default:dirt_with_grass" then
1512                         minetest.set_node(pos, {name="default:dirt_with_snow"})
1513                 end
1514         end,
1515 })
1516 minetest.register_alias("snow", "default:snow")
1517
1518 minetest.register_node("default:snowblock", {
1519         description = "Snow Block",
1520         tiles = {"default_snow.png"},
1521         is_ground_content = true,
1522         freezemelt = "default:water_source",
1523         groups = {crumbly=3, melts=1},
1524         sounds = default.node_sound_dirt_defaults({
1525                 footstep = {name="default_snow_footstep", gain=0.25},
1526                 dug = {name="default_snow_footstep", gain=0.75},
1527         }),
1528 })