1 -- mods/default/nodes.lua
3 minetest.register_node("default:stone", {
5 tiles = {"default_stone.png"},
6 is_ground_content = true,
7 groups = {cracky=3, stone=1},
8 drop = 'default:cobble',
10 sounds = default.node_sound_stone_defaults(),
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(),
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,
28 drop = 'default:coal_lump',
29 sounds = default.node_sound_stone_defaults(),
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,
37 drop = 'default:iron_lump',
38 sounds = default.node_sound_stone_defaults(),
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,
46 drop = 'default:copper_lump',
47 sounds = default.node_sound_stone_defaults(),
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,
55 drop = "default:mese_crystal",
56 sounds = default.node_sound_stone_defaults(),
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,
64 drop = "default:gold_lump",
65 sounds = default.node_sound_stone_defaults(),
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,
73 drop = "default:diamond",
74 sounds = default.node_sound_stone_defaults(),
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(),
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(),
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},
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},
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},
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(),
132 minetest.register_abm({
133 nodenames = {"default:dirt"},
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"})
146 minetest.set_node(pos, {name = "default:dirt_with_grass"})
152 minetest.register_abm({
153 nodenames = {"default:dirt_with_grass"},
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"})
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(),
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(),
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},
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(),
203 minetest.register_node("default:sandstonebrick", {
204 description = "Sandstone Brick",
205 tiles = {"default_sandstone_brick.png"},
206 is_ground_content = true,
208 sounds = default.node_sound_stone_defaults(),
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(),
220 minetest.register_node("default:brick", {
221 description = "Brick Block",
222 tiles = {"default_brick.png"},
223 is_ground_content = false,
225 sounds = default.node_sound_stone_defaults(),
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
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
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(),
255 minetest.register_node("default:jungleleaves", {
256 description = "Jungle Leaves",
257 drawtype = "allfaces_optional",
260 tiles = {"default_jungleleaves.png"},
262 is_ground_content = false,
263 groups = {snappy=3, leafdecay=3, flammable=2, leaves=1},
268 -- player will get sapling with 1/20 chance
269 items = {'default:junglesapling'},
273 -- player will get leaves only if he get no saplings,
274 -- this is because max_items is 1
275 items = {'default:jungleleaves'},
279 sounds = default.node_sound_leaves_defaults(),
282 minetest.register_node("default:junglesapling", {
283 description = "Jungle Sapling",
284 drawtype = "plantlike",
286 tiles = {"default_junglesapling.png"},
287 inventory_image = "default_junglesapling.png",
288 wield_image = "default_junglesapling.png",
293 fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
295 groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1},
296 sounds = default.node_sound_leaves_defaults(),
299 minetest.register_node("default:junglegrass", {
300 description = "Jungle Grass",
301 drawtype = "plantlike",
304 tiles = {"default_junglegrass.png"},
305 inventory_image = "default_junglegrass.png",
306 wield_image = "default_junglegrass.png",
310 is_ground_content = true,
311 groups = {snappy=3,flammable=2,flora=1,attached_node=1},
312 sounds = default.node_sound_leaves_defaults(),
315 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
319 minetest.register_node("default:leaves", {
320 description = "Leaves",
321 drawtype = "allfaces_optional",
324 tiles = {"default_leaves.png"},
326 is_ground_content = false,
327 groups = {snappy=3, leafdecay=3, flammable=2, leaves=1},
332 -- player will get sapling with 1/20 chance
333 items = {'default:sapling'},
337 -- player will get leaves only if he get no saplings,
338 -- this is because max_items is 1
339 items = {'default:leaves'},
343 sounds = default.node_sound_leaves_defaults(),
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)
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",
367 is_ground_content = true,
370 fixed = {-0.3, -0.5, -0.3, 0.3, 0.5, 0.3}
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)
379 minetest.register_node("default:bookshelf", {
380 description = "Bookshelf",
381 tiles = {"default_wood.png", "default_wood.png", "default_bookshelf.png"},
382 is_ground_content = false,
383 groups = {choppy=3,oddly_breakable_by_hand=2,flammable=3},
384 sounds = default.node_sound_wood_defaults(),
387 minetest.register_node("default:glass", {
388 description = "Glass",
389 drawtype = "glasslike",
390 tiles = {"default_glass.png"},
391 inventory_image = minetest.inventorycube("default_glass.png"),
393 sunlight_propagates = true,
394 is_ground_content = false,
395 groups = {cracky=3,oddly_breakable_by_hand=3},
396 sounds = default.node_sound_glass_defaults(),
399 minetest.register_node("default:fence_wood", {
400 description = "Wooden Fence",
401 drawtype = "fencelike",
402 tiles = {"default_wood.png"},
403 inventory_image = "default_fence.png",
404 wield_image = "default_fence.png",
406 is_ground_content = false,
409 fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
411 groups = {choppy=2,oddly_breakable_by_hand=2,flammable=2},
412 sounds = default.node_sound_wood_defaults(),
415 minetest.register_node("default:rail", {
416 description = "Rail",
417 drawtype = "raillike",
418 tiles = {"default_rail.png", "default_rail_curved.png", "default_rail_t_junction.png", "default_rail_crossing.png"},
419 inventory_image = "default_rail.png",
420 wield_image = "default_rail.png",
423 is_ground_content = false,
426 -- but how to specify the dimensions for curved and sideways rails?
427 fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
429 groups = {bendy=2,dig_immediate=2,attached_node=1},
432 minetest.register_node("default:ladder", {
433 description = "Ladder",
434 drawtype = "signlike",
435 tiles = {"default_ladder.png"},
436 inventory_image = "default_ladder.png",
437 wield_image = "default_ladder.png",
439 paramtype2 = "wallmounted",
442 is_ground_content = false,
444 type = "wallmounted",
445 --wall_top = = <default>
446 --wall_bottom = = <default>
447 --wall_side = = <default>
449 groups = {choppy=2,oddly_breakable_by_hand=3,flammable=2},
450 legacy_wallmounted = true,
451 sounds = default.node_sound_wood_defaults(),
454 minetest.register_node("default:wood", {
455 description = "Wooden Planks",
456 tiles = {"default_wood.png"},
457 groups = {choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1},
458 sounds = default.node_sound_wood_defaults(),
461 minetest.register_node("default:cloud", {
462 description = "Cloud",
463 tiles = {"default_cloud.png"},
464 sounds = default.node_sound_defaults(),
465 groups = {not_in_creative_inventory=1},
468 minetest.register_node("default:water_flowing", {
469 description = "Flowing Water",
470 inventory_image = minetest.inventorycube("default_water.png"),
471 drawtype = "flowingliquid",
472 tiles = {"default_water.png"},
475 image="default_water_flowing_animated.png",
476 backface_culling=false,
477 animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=0.8}
480 image="default_water_flowing_animated.png",
481 backface_culling=true,
482 animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=0.8}
487 paramtype2 = "flowingliquid",
494 liquidtype = "flowing",
495 liquid_alternative_flowing = "default:water_flowing",
496 liquid_alternative_source = "default:water_source",
497 liquid_viscosity = WATER_VISC,
498 freezemelt = "default:snow",
499 post_effect_color = {a=64, r=100, g=100, b=200},
500 groups = {water=3, liquid=3, puts_out_fire=1, not_in_creative_inventory=1, freezes=1, melt_around=1},
503 minetest.register_node("default:water_source", {
504 description = "Water Source",
505 inventory_image = minetest.inventorycube("default_water.png"),
508 {name="default_water_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}}
511 -- New-style water source material (mostly unused)
513 name="default_water_source_animated.png",
514 animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0},
515 backface_culling = false,
526 liquidtype = "source",
527 liquid_alternative_flowing = "default:water_flowing",
528 liquid_alternative_source = "default:water_source",
529 liquid_viscosity = WATER_VISC,
530 freezemelt = "default:ice",
531 post_effect_color = {a=64, r=100, g=100, b=200},
532 groups = {water=3, liquid=3, puts_out_fire=1, freezes=1},
535 minetest.register_node("default:lava_flowing", {
536 description = "Flowing Lava",
537 inventory_image = minetest.inventorycube("default_lava.png"),
538 drawtype = "flowingliquid",
539 tiles = {"default_lava.png"},
542 image="default_lava_flowing_animated.png",
543 backface_culling=false,
544 animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3}
547 image="default_lava_flowing_animated.png",
548 backface_culling=true,
549 animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3}
553 paramtype2 = "flowingliquid",
554 light_source = LIGHT_MAX - 1,
561 liquidtype = "flowing",
562 liquid_alternative_flowing = "default:lava_flowing",
563 liquid_alternative_source = "default:lava_source",
564 liquid_viscosity = LAVA_VISC,
565 liquid_renewable = false,
566 damage_per_second = 4*2,
567 post_effect_color = {a=192, r=255, g=64, b=0},
568 groups = {lava=3, liquid=2, hot=3, igniter=1, not_in_creative_inventory=1},
571 minetest.register_node("default:lava_source", {
572 description = "Lava Source",
573 inventory_image = minetest.inventorycube("default_lava.png"),
576 {name="default_lava_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}}
579 -- New-style lava source material (mostly unused)
581 name="default_lava_source_animated.png",
582 animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0},
583 backface_culling = false,
587 light_source = LIGHT_MAX - 1,
594 liquidtype = "source",
595 liquid_alternative_flowing = "default:lava_flowing",
596 liquid_alternative_source = "default:lava_source",
597 liquid_viscosity = LAVA_VISC,
598 liquid_renewable = false,
599 damage_per_second = 4*2,
600 post_effect_color = {a=192, r=255, g=64, b=0},
601 groups = {lava=3, liquid=2, hot=3, igniter=1},
604 minetest.register_node("default:torch", {
605 description = "Torch",
606 drawtype = "torchlike",
607 --tiles = {"default_torch_on_floor.png", "default_torch_on_ceiling.png", "default_torch.png"},
609 {name="default_torch_on_floor_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}},
610 {name="default_torch_on_ceiling_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}},
611 {name="default_torch_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}}
613 inventory_image = "default_torch_on_floor.png",
614 wield_image = "default_torch_on_floor.png",
616 paramtype2 = "wallmounted",
617 sunlight_propagates = true,
618 is_ground_content = false,
620 light_source = LIGHT_MAX-1,
622 type = "wallmounted",
623 wall_top = {-0.1, 0.5-0.6, -0.1, 0.1, 0.5, 0.1},
624 wall_bottom = {-0.1, -0.5, -0.1, 0.1, -0.5+0.6, 0.1},
625 wall_side = {-0.5, -0.3, -0.1, -0.5+0.3, 0.3, 0.1},
627 groups = {choppy=2,dig_immediate=3,flammable=1,attached_node=1,hot=2},
628 legacy_wallmounted = true,
629 sounds = default.node_sound_defaults(),
632 minetest.register_node("default:sign_wall", {
633 description = "Sign",
634 drawtype = "signlike",
635 tiles = {"default_sign_wall.png"},
636 inventory_image = "default_sign_wall.png",
637 wield_image = "default_sign_wall.png",
639 paramtype2 = "wallmounted",
640 sunlight_propagates = true,
641 is_ground_content = false,
644 type = "wallmounted",
645 --wall_top = <default>
646 --wall_bottom = <default>
647 --wall_side = <default>
649 groups = {choppy=2,dig_immediate=2,attached_node=1},
650 legacy_wallmounted = true,
651 sounds = default.node_sound_defaults(),
652 on_construct = function(pos)
653 --local n = minetest.get_node(pos)
654 local meta = minetest.get_meta(pos)
655 meta:set_string("formspec", "field[text;;${text}]")
656 meta:set_string("infotext", "\"\"")
658 on_receive_fields = function(pos, formname, fields, sender)
659 --print("Sign at "..minetest.pos_to_string(pos).." got "..dump(fields))
660 if minetest.is_protected(pos, sender:get_player_name()) then
661 minetest.record_protection_violation(pos, sender:get_player_name())
664 local meta = minetest.get_meta(pos)
665 fields.text = fields.text or ""
666 minetest.log("action", (sender:get_player_name() or "").." wrote \""..fields.text..
667 "\" to sign at "..minetest.pos_to_string(pos))
668 meta:set_string("text", fields.text)
669 meta:set_string("infotext", '"'..fields.text..'"')
673 default.chest_formspec =
675 "list[current_name;main;0,0;8,4;]"..
676 "list[current_player;main;0,5;8,4;]"
678 function default.get_locked_chest_formspec(pos)
679 local spos = pos.x .. "," .. pos.y .. "," ..pos.z
682 "list[nodemeta:".. spos .. ";main;0,0;8,4;]"..
683 "list[current_player;main;0,5;8,4;]"
688 minetest.register_node("default:chest", {
689 description = "Chest",
690 tiles = {"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
691 "default_chest_side.png", "default_chest_side.png", "default_chest_front.png"},
692 paramtype2 = "facedir",
693 groups = {choppy=2,oddly_breakable_by_hand=2},
694 legacy_facedir_simple = true,
695 is_ground_content = false,
696 sounds = default.node_sound_wood_defaults(),
697 on_construct = function(pos)
698 local meta = minetest.get_meta(pos)
699 meta:set_string("formspec",default.chest_formspec)
700 meta:set_string("infotext", "Chest")
701 local inv = meta:get_inventory()
702 inv:set_size("main", 8*4)
704 can_dig = function(pos,player)
705 local meta = minetest.get_meta(pos);
706 local inv = meta:get_inventory()
707 return inv:is_empty("main")
709 on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
710 minetest.log("action", player:get_player_name()..
711 " moves stuff in chest at "..minetest.pos_to_string(pos))
713 on_metadata_inventory_put = function(pos, listname, index, stack, player)
714 minetest.log("action", player:get_player_name()..
715 " moves stuff to chest at "..minetest.pos_to_string(pos))
717 on_metadata_inventory_take = function(pos, listname, index, stack, player)
718 minetest.log("action", player:get_player_name()..
719 " takes stuff from chest at "..minetest.pos_to_string(pos))
723 local function has_locked_chest_privilege(meta, player)
724 if player:get_player_name() ~= meta:get_string("owner") then
730 minetest.register_node("default:chest_locked", {
731 description = "Locked Chest",
732 tiles = {"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
733 "default_chest_side.png", "default_chest_side.png", "default_chest_lock.png"},
734 paramtype2 = "facedir",
735 groups = {choppy=2,oddly_breakable_by_hand=2},
736 legacy_facedir_simple = true,
737 is_ground_content = false,
738 sounds = default.node_sound_wood_defaults(),
739 after_place_node = function(pos, placer)
740 local meta = minetest.get_meta(pos)
741 meta:set_string("owner", placer:get_player_name() or "")
742 meta:set_string("infotext", "Locked Chest (owned by "..
743 meta:get_string("owner")..")")
745 on_construct = function(pos)
746 local meta = minetest.get_meta(pos)
747 meta:set_string("infotext", "Locked Chest")
748 meta:set_string("owner", "")
749 local inv = meta:get_inventory()
750 inv:set_size("main", 8*4)
752 can_dig = function(pos,player)
753 local meta = minetest.get_meta(pos);
754 local inv = meta:get_inventory()
755 return inv:is_empty("main") and has_locked_chest_privilege(meta, player)
757 allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
758 local meta = minetest.get_meta(pos)
759 if not has_locked_chest_privilege(meta, player) then
760 minetest.log("action", player:get_player_name()..
761 " tried to access a locked chest belonging to "..
762 meta:get_string("owner").." at "..
763 minetest.pos_to_string(pos))
768 allow_metadata_inventory_put = function(pos, listname, index, stack, player)
769 local meta = minetest.get_meta(pos)
770 if not has_locked_chest_privilege(meta, player) then
771 minetest.log("action", player:get_player_name()..
772 " tried to access a locked chest belonging to "..
773 meta:get_string("owner").." at "..
774 minetest.pos_to_string(pos))
777 return stack:get_count()
779 allow_metadata_inventory_take = function(pos, listname, index, stack, player)
780 local meta = minetest.get_meta(pos)
781 if not has_locked_chest_privilege(meta, player) then
782 minetest.log("action", player:get_player_name()..
783 " tried to access a locked chest belonging to "..
784 meta:get_string("owner").." at "..
785 minetest.pos_to_string(pos))
788 return stack:get_count()
790 on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
791 minetest.log("action", player:get_player_name()..
792 " moves stuff in locked chest at "..minetest.pos_to_string(pos))
794 on_metadata_inventory_put = function(pos, listname, index, stack, player)
795 minetest.log("action", player:get_player_name()..
796 " moves stuff to locked chest at "..minetest.pos_to_string(pos))
798 on_metadata_inventory_take = function(pos, listname, index, stack, player)
799 minetest.log("action", player:get_player_name()..
800 " takes stuff from locked chest at "..minetest.pos_to_string(pos))
802 on_rightclick = function(pos, node, clicker)
803 local meta = minetest.get_meta(pos)
804 if has_locked_chest_privilege(meta, clicker) then
805 minetest.show_formspec(
806 clicker:get_player_name(),
807 "default:chest_locked",
808 default.get_locked_chest_formspec(pos)
814 function default.get_furnace_active_formspec(pos, percent)
817 "image[2,2;1,1;default_furnace_fire_bg.png^[lowpart:"..
818 (100-percent)..":default_furnace_fire_fg.png]"..
819 "list[current_name;fuel;2,3;1,1;]"..
820 "list[current_name;src;2,1;1,1;]"..
821 "list[current_name;dst;5,1;2,2;]"..
822 "list[current_player;main;0,5;8,4;]"
826 default.furnace_inactive_formspec =
828 "image[2,2;1,1;default_furnace_fire_bg.png]"..
829 "list[current_name;fuel;2,3;1,1;]"..
830 "list[current_name;src;2,1;1,1;]"..
831 "list[current_name;dst;5,1;2,2;]"..
832 "list[current_player;main;0,5;8,4;]"
834 minetest.register_node("default:furnace", {
835 description = "Furnace",
836 tiles = {"default_furnace_top.png", "default_furnace_bottom.png", "default_furnace_side.png",
837 "default_furnace_side.png", "default_furnace_side.png", "default_furnace_front.png"},
838 paramtype2 = "facedir",
840 legacy_facedir_simple = true,
841 is_ground_content = false,
842 sounds = default.node_sound_stone_defaults(),
843 on_construct = function(pos)
844 local meta = minetest.get_meta(pos)
845 meta:set_string("formspec", default.furnace_inactive_formspec)
846 meta:set_string("infotext", "Furnace")
847 local inv = meta:get_inventory()
848 inv:set_size("fuel", 1)
849 inv:set_size("src", 1)
850 inv:set_size("dst", 4)
852 can_dig = function(pos,player)
853 local meta = minetest.get_meta(pos);
854 local inv = meta:get_inventory()
855 if not inv:is_empty("fuel") then
857 elseif not inv:is_empty("dst") then
859 elseif not inv:is_empty("src") then
864 allow_metadata_inventory_put = function(pos, listname, index, stack, player)
865 local meta = minetest.get_meta(pos)
866 local inv = meta:get_inventory()
867 if listname == "fuel" then
868 if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
869 if inv:is_empty("src") then
870 meta:set_string("infotext","Furnace is empty")
872 return stack:get_count()
876 elseif listname == "src" then
877 return stack:get_count()
878 elseif listname == "dst" then
882 allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
883 local meta = minetest.get_meta(pos)
884 local inv = meta:get_inventory()
885 local stack = inv:get_stack(from_list, from_index)
886 if to_list == "fuel" then
887 if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
888 if inv:is_empty("src") then
889 meta:set_string("infotext","Furnace is empty")
895 elseif to_list == "src" then
897 elseif to_list == "dst" then
903 minetest.register_node("default:furnace_active", {
904 description = "Furnace",
906 "default_furnace_top.png",
907 "default_furnace_bottom.png",
908 "default_furnace_side.png",
909 "default_furnace_side.png",
910 "default_furnace_side.png",
912 image = "default_furnace_front_active.png",
913 backface_culling = false,
915 type = "vertical_frames",
922 paramtype2 = "facedir",
924 drop = "default:furnace",
925 groups = {cracky=2, not_in_creative_inventory=1,hot=1},
926 legacy_facedir_simple = true,
927 is_ground_content = false,
928 sounds = default.node_sound_stone_defaults(),
929 on_construct = function(pos)
930 local meta = minetest.get_meta(pos)
931 meta:set_string("formspec", default.furnace_inactive_formspec)
932 meta:set_string("infotext", "Furnace");
933 local inv = meta:get_inventory()
934 inv:set_size("fuel", 1)
935 inv:set_size("src", 1)
936 inv:set_size("dst", 4)
938 can_dig = function(pos,player)
939 local meta = minetest.get_meta(pos);
940 local inv = meta:get_inventory()
941 if not inv:is_empty("fuel") then
943 elseif not inv:is_empty("dst") then
945 elseif not inv:is_empty("src") then
950 allow_metadata_inventory_put = function(pos, listname, index, stack, player)
951 local meta = minetest.get_meta(pos)
952 local inv = meta:get_inventory()
953 if listname == "fuel" then
954 if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
955 if inv:is_empty("src") then
956 meta:set_string("infotext","Furnace is empty")
958 return stack:get_count()
962 elseif listname == "src" then
963 return stack:get_count()
964 elseif listname == "dst" then
968 allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
969 local meta = minetest.get_meta(pos)
970 local inv = meta:get_inventory()
971 local stack = inv:get_stack(from_list, from_index)
972 if to_list == "fuel" then
973 if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
974 if inv:is_empty("src") then
975 meta:set_string("infotext","Furnace is empty")
981 elseif to_list == "src" then
983 elseif to_list == "dst" then
989 local function swap_node(pos,name)
990 local node = minetest.get_node(pos)
991 if node.name == name then
995 minetest.swap_node(pos,node)
998 minetest.register_abm({
999 nodenames = {"default:furnace","default:furnace_active"},
1002 action = function(pos, node, active_object_count, active_object_count_wider)
1003 local meta = minetest.get_meta(pos)
1004 for i, name in ipairs({
1010 if meta:get_string(name) == "" then
1011 meta:set_float(name, 0.0)
1015 local inv = meta:get_inventory()
1017 local srclist = inv:get_list("src")
1022 cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
1025 local was_active = false
1027 if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
1029 meta:set_float("fuel_time", meta:get_float("fuel_time") + 1)
1030 meta:set_float("src_time", meta:get_float("src_time") + 1)
1031 if cooked and cooked.item and meta:get_float("src_time") >= cooked.time then
1032 -- check if there's room for output in "dst" list
1033 if inv:room_for_item("dst",cooked.item) then
1034 -- Put result in "dst" list
1035 inv:add_item("dst", cooked.item)
1036 -- take stuff from "src" list
1037 inv:set_stack("src", 1, aftercooked.items[1])
1039 --print("Could not insert '"..cooked.item:to_string().."'")
1041 meta:set_string("src_time", 0)
1045 if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
1046 local percent = math.floor(meta:get_float("fuel_time") /
1047 meta:get_float("fuel_totaltime") * 100)
1048 meta:set_string("infotext","Furnace active: "..percent.."%")
1049 swap_node(pos,"default:furnace_active")
1050 meta:set_string("formspec",default.get_furnace_active_formspec(pos, percent))
1057 local fuellist = inv:get_list("fuel")
1058 local srclist = inv:get_list("src")
1061 cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
1064 fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
1067 if not fuel or fuel.time <= 0 then
1068 meta:set_string("infotext","Furnace out of fuel")
1069 swap_node(pos,"default:furnace")
1070 meta:set_string("formspec", default.furnace_inactive_formspec)
1074 if cooked.item:is_empty() then
1076 meta:set_string("infotext","Furnace is empty")
1077 swap_node(pos,"default:furnace")
1078 meta:set_string("formspec", default.furnace_inactive_formspec)
1083 meta:set_string("fuel_totaltime", fuel.time)
1084 meta:set_string("fuel_time", 0)
1086 inv:set_stack("fuel", 1, afterfuel.items[1])
1090 minetest.register_node("default:cobble", {
1091 description = "Cobblestone",
1092 tiles = {"default_cobble.png"},
1093 is_ground_content = true,
1094 groups = {cracky=3, stone=2},
1095 sounds = default.node_sound_stone_defaults(),
1098 minetest.register_node("default:desert_cobble", {
1099 description = "Desert Cobblestone",
1100 tiles = {"default_desert_cobble.png"},
1101 is_ground_content = true,
1102 groups = {cracky=3, stone=2},
1103 sounds = default.node_sound_stone_defaults(),
1106 minetest.register_node("default:mossycobble", {
1107 description = "Mossy Cobblestone",
1108 tiles = {"default_mossycobble.png"},
1109 is_ground_content = true,
1110 groups = {cracky=3},
1111 sounds = default.node_sound_stone_defaults(),
1114 minetest.register_node("default:coalblock", {
1115 description = "Coal Block",
1116 tiles = {"default_coal_block.png"},
1117 is_ground_content = true,
1118 groups = {cracky=3},
1119 sounds = default.node_sound_stone_defaults(),
1122 minetest.register_node("default:steelblock", {
1123 description = "Steel Block",
1124 tiles = {"default_steel_block.png"},
1125 is_ground_content = true,
1126 groups = {cracky=1,level=2},
1127 sounds = default.node_sound_stone_defaults(),
1130 minetest.register_node("default:copperblock", {
1131 description = "Copper Block",
1132 tiles = {"default_copper_block.png"},
1133 is_ground_content = true,
1134 groups = {cracky=1,level=2},
1135 sounds = default.node_sound_stone_defaults(),
1138 minetest.register_node("default:bronzeblock", {
1139 description = "Bronze Block",
1140 tiles = {"default_bronze_block.png"},
1141 is_ground_content = true,
1142 groups = {cracky=1,level=2},
1143 sounds = default.node_sound_stone_defaults(),
1146 minetest.register_node("default:mese", {
1147 description = "Mese Block",
1148 tiles = {"default_mese_block.png"},
1149 is_ground_content = true,
1150 groups = {cracky=1,level=2},
1151 sounds = default.node_sound_stone_defaults(),
1153 minetest.register_alias("default:mese_block", "default:mese")
1155 minetest.register_node("default:goldblock", {
1156 description = "Gold Block",
1157 tiles = {"default_gold_block.png"},
1158 is_ground_content = true,
1159 groups = {cracky=1},
1160 sounds = default.node_sound_stone_defaults(),
1163 minetest.register_node("default:diamondblock", {
1164 description = "Diamond Block",
1165 tiles = {"default_diamond_block.png"},
1166 is_ground_content = true,
1167 groups = {cracky=1,level=3},
1168 sounds = default.node_sound_stone_defaults(),
1171 minetest.register_node("default:obsidian_glass", {
1172 description = "Obsidian Glass",
1173 drawtype = "glasslike",
1174 tiles = {"default_obsidian_glass.png"},
1175 paramtype = "light",
1176 is_ground_content = false,
1177 sunlight_propagates = true,
1178 sounds = default.node_sound_glass_defaults(),
1179 groups = {cracky=3,oddly_breakable_by_hand=3},
1182 minetest.register_node("default:obsidian", {
1183 description = "Obsidian",
1184 tiles = {"default_obsidian.png"},
1185 is_ground_content = true,
1186 sounds = default.node_sound_stone_defaults(),
1187 groups = {cracky=1,level=2},
1190 minetest.register_node("default:nyancat", {
1191 description = "Nyan Cat",
1192 tiles = {"default_nc_side.png", "default_nc_side.png", "default_nc_side.png",
1193 "default_nc_side.png", "default_nc_back.png", "default_nc_front.png"},
1194 paramtype2 = "facedir",
1195 groups = {cracky=2},
1196 is_ground_content = false,
1197 legacy_facedir_simple = true,
1198 sounds = default.node_sound_defaults(),
1201 minetest.register_node("default:nyancat_rainbow", {
1202 description = "Nyan Cat Rainbow",
1203 tiles = {"default_nc_rb.png^[transformR90", "default_nc_rb.png^[transformR90",
1204 "default_nc_rb.png", "default_nc_rb.png"},
1205 paramtype2 = "facedir",
1206 groups = {cracky=2},
1207 is_ground_content = false,
1208 sounds = default.node_sound_defaults(),
1211 minetest.register_node("default:sapling", {
1212 description = "Sapling",
1213 drawtype = "plantlike",
1215 tiles = {"default_sapling.png"},
1216 inventory_image = "default_sapling.png",
1217 wield_image = "default_sapling.png",
1218 paramtype = "light",
1220 is_ground_content = true,
1223 fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
1225 groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1},
1226 sounds = default.node_sound_leaves_defaults(),
1229 minetest.register_node("default:apple", {
1230 description = "Apple",
1231 drawtype = "plantlike",
1233 tiles = {"default_apple.png"},
1234 inventory_image = "default_apple.png",
1235 paramtype = "light",
1236 sunlight_propagates = true,
1238 is_ground_content = true,
1241 fixed = {-0.2, -0.5, -0.2, 0.2, 0, 0.2}
1243 groups = {fleshy=3,dig_immediate=3,flammable=2,leafdecay=3,leafdecay_drop=1},
1244 on_use = minetest.item_eat(1),
1245 sounds = default.node_sound_leaves_defaults(),
1246 after_place_node = function(pos, placer, itemstack)
1247 if placer:is_player() then
1248 minetest.set_node(pos, {name="default:apple", param2=1})
1253 minetest.register_node("default:dry_shrub", {
1254 description = "Dry Shrub",
1255 drawtype = "plantlike",
1258 tiles = {"default_dry_shrub.png"},
1259 inventory_image = "default_dry_shrub.png",
1260 wield_image = "default_dry_shrub.png",
1261 paramtype = "light",
1263 is_ground_content = true,
1264 buildable_to = true,
1265 groups = {snappy=3,flammable=3,attached_node=1},
1266 sounds = default.node_sound_leaves_defaults(),
1269 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1273 minetest.register_node("default:grass_1", {
1274 description = "Grass",
1275 drawtype = "plantlike",
1277 tiles = {"default_grass_1.png"},
1278 -- use a bigger inventory image
1279 inventory_image = "default_grass_3.png",
1280 wield_image = "default_grass_3.png",
1281 paramtype = "light",
1283 is_ground_content = true,
1284 buildable_to = true,
1285 groups = {snappy=3,flammable=3,flora=1,attached_node=1},
1286 sounds = default.node_sound_leaves_defaults(),
1289 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1291 on_place = function(itemstack, placer, pointed_thing)
1292 -- place a random grass node
1293 local stack = ItemStack("default:grass_"..math.random(1,5))
1294 local ret = minetest.item_place(stack, placer, pointed_thing)
1295 return ItemStack("default:grass_1 "..itemstack:get_count()-(1-ret:get_count()))
1299 minetest.register_node("default:grass_2", {
1300 description = "Grass",
1301 drawtype = "plantlike",
1303 tiles = {"default_grass_2.png"},
1304 inventory_image = "default_grass_2.png",
1305 wield_image = "default_grass_2.png",
1306 paramtype = "light",
1308 buildable_to = true,
1309 is_ground_content = true,
1310 drop = "default:grass_1",
1311 groups = {snappy=3,flammable=3,flora=1,attached_node=1,not_in_creative_inventory=1},
1312 sounds = default.node_sound_leaves_defaults(),
1315 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1318 minetest.register_node("default:grass_3", {
1319 description = "Grass",
1320 drawtype = "plantlike",
1322 tiles = {"default_grass_3.png"},
1323 inventory_image = "default_grass_3.png",
1324 wield_image = "default_grass_3.png",
1325 paramtype = "light",
1327 buildable_to = true,
1328 is_ground_content = true,
1329 drop = "default:grass_1",
1330 groups = {snappy=3,flammable=3,flora=1,attached_node=1,not_in_creative_inventory=1},
1331 sounds = default.node_sound_leaves_defaults(),
1334 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1338 minetest.register_node("default:grass_4", {
1339 description = "Grass",
1340 drawtype = "plantlike",
1342 tiles = {"default_grass_4.png"},
1343 inventory_image = "default_grass_4.png",
1344 wield_image = "default_grass_4.png",
1345 paramtype = "light",
1347 buildable_to = true,
1348 is_ground_content = true,
1349 drop = "default:grass_1",
1350 groups = {snappy=3,flammable=3,flora=1,attached_node=1,not_in_creative_inventory=1},
1351 sounds = default.node_sound_leaves_defaults(),
1354 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1358 minetest.register_node("default:grass_5", {
1359 description = "Grass",
1360 drawtype = "plantlike",
1362 tiles = {"default_grass_5.png"},
1363 inventory_image = "default_grass_5.png",
1364 wield_image = "default_grass_5.png",
1365 paramtype = "light",
1367 buildable_to = true,
1368 is_ground_content = true,
1369 drop = "default:grass_1",
1370 groups = {snappy=3,flammable=3,flora=1,attached_node=1,not_in_creative_inventory=1},
1371 sounds = default.node_sound_leaves_defaults(),
1374 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1378 minetest.register_node("default:ice", {
1379 description = "Ice",
1380 tiles = {"default_ice.png"},
1381 is_ground_content = true,
1382 paramtype = "light",
1383 freezemelt = "default:water_source",
1384 groups = {cracky=3, melts=1},
1385 sounds = default.node_sound_glass_defaults(),
1388 minetest.register_node("default:snow", {
1389 description = "Snow",
1390 tiles = {"default_snow.png"},
1391 inventory_image = "default_snowball.png",
1392 wield_image = "default_snowball.png",
1393 is_ground_content = true,
1394 paramtype = "light",
1395 buildable_to = true,
1397 drawtype = "nodebox",
1398 freezemelt = "default:water_flowing",
1402 {-0.5, -0.5, -0.5, 0.5, -0.5+2/16, 0.5},
1405 groups = {crumbly=3,falling_node=1, melts=1, float=1},
1406 sounds = default.node_sound_dirt_defaults({
1407 footstep = {name="default_snow_footstep", gain=0.25},
1408 dug = {name="default_snow_footstep", gain=0.75},
1410 on_construct = function(pos)
1412 if minetest.get_node(pos).name == "default:dirt_with_grass" then
1413 minetest.set_node(pos, {name="default:dirt_with_snow"})
1417 minetest.register_alias("snow", "default:snow")
1419 minetest.register_node("default:snowblock", {
1420 description = "Snow Block",
1421 tiles = {"default_snow.png"},
1422 is_ground_content = true,
1423 freezemelt = "default:water_source",
1424 groups = {crumbly=3, melts=1},
1425 sounds = default.node_sound_dirt_defaults({
1426 footstep = {name="default_snow_footstep", gain=0.25},
1427 dug = {name="default_snow_footstep", gain=0.75},