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_stone',
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",
259 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",
303 tiles = {"default_junglegrass.png"},
304 inventory_image = "default_junglegrass.png",
305 wield_image = "default_junglegrass.png",
309 is_ground_content = true,
310 groups = {snappy=3,flammable=2,flora=1,attached_node=1},
311 sounds = default.node_sound_leaves_defaults(),
314 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
318 minetest.register_node("default:leaves", {
319 description = "Leaves",
320 drawtype = "allfaces_optional",
322 tiles = {"default_leaves.png"},
325 is_ground_content = false,
326 groups = {snappy=3, leafdecay=3, flammable=2, leaves=1},
331 -- player will get sapling with 1/20 chance
332 items = {'default:sapling'},
336 -- player will get leaves only if he get no saplings,
337 -- this is because max_items is 1
338 items = {'default:leaves'},
342 sounds = default.node_sound_leaves_defaults(),
345 minetest.register_node("default:cactus", {
346 description = "Cactus",
347 tiles = {"default_cactus_top.png", "default_cactus_top.png", "default_cactus_side.png"},
348 paramtype2 = "facedir",
349 is_ground_content = true,
350 groups = {snappy=1,choppy=3,flammable=2},
351 sounds = default.node_sound_wood_defaults(),
352 on_place = minetest.rotate_node
355 minetest.register_node("default:papyrus", {
356 description = "Papyrus",
357 drawtype = "plantlike",
358 tiles = {"default_papyrus.png"},
359 inventory_image = "default_papyrus.png",
360 wield_image = "default_papyrus.png",
363 is_ground_content = true,
366 fixed = {-0.3, -0.5, -0.3, 0.3, 0.5, 0.3}
368 groups = {snappy=3,flammable=2},
369 sounds = default.node_sound_leaves_defaults(),
372 minetest.register_node("default:bookshelf", {
373 description = "Bookshelf",
374 tiles = {"default_wood.png", "default_wood.png", "default_bookshelf.png"},
375 is_ground_content = false,
376 groups = {choppy=3,oddly_breakable_by_hand=2,flammable=3},
377 sounds = default.node_sound_wood_defaults(),
380 minetest.register_node("default:glass", {
381 description = "Glass",
382 drawtype = "glasslike",
383 tiles = {"default_glass.png"},
384 inventory_image = minetest.inventorycube("default_glass.png"),
386 sunlight_propagates = true,
387 is_ground_content = false,
388 groups = {cracky=3,oddly_breakable_by_hand=3},
389 sounds = default.node_sound_glass_defaults(),
392 minetest.register_node("default:fence_wood", {
393 description = "Wooden Fence",
394 drawtype = "fencelike",
395 tiles = {"default_wood.png"},
396 inventory_image = "default_fence.png",
397 wield_image = "default_fence.png",
399 is_ground_content = false,
402 fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
404 groups = {choppy=2,oddly_breakable_by_hand=2,flammable=2},
405 sounds = default.node_sound_wood_defaults(),
408 minetest.register_node("default:rail", {
409 description = "Rail",
410 drawtype = "raillike",
411 tiles = {"default_rail.png", "default_rail_curved.png", "default_rail_t_junction.png", "default_rail_crossing.png"},
412 inventory_image = "default_rail.png",
413 wield_image = "default_rail.png",
416 is_ground_content = false,
419 -- but how to specify the dimensions for curved and sideways rails?
420 fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
422 groups = {bendy=2,dig_immediate=2,attached_node=1},
425 minetest.register_node("default:ladder", {
426 description = "Ladder",
427 drawtype = "signlike",
428 tiles = {"default_ladder.png"},
429 inventory_image = "default_ladder.png",
430 wield_image = "default_ladder.png",
432 paramtype2 = "wallmounted",
435 is_ground_content = false,
437 type = "wallmounted",
438 --wall_top = = <default>
439 --wall_bottom = = <default>
440 --wall_side = = <default>
442 groups = {choppy=2,oddly_breakable_by_hand=3,flammable=2},
443 legacy_wallmounted = true,
444 sounds = default.node_sound_wood_defaults(),
447 minetest.register_node("default:wood", {
448 description = "Wooden Planks",
449 tiles = {"default_wood.png"},
450 groups = {choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1},
451 sounds = default.node_sound_wood_defaults(),
454 minetest.register_node("default:cloud", {
455 description = "Cloud",
456 tiles = {"default_cloud.png"},
457 sounds = default.node_sound_defaults(),
458 groups = {not_in_creative_inventory=1},
461 minetest.register_node("default:water_flowing", {
462 description = "Flowing Water",
463 inventory_image = minetest.inventorycube("default_water.png"),
464 drawtype = "flowingliquid",
465 tiles = {"default_water.png"},
468 image="default_water_flowing_animated.png",
469 backface_culling=false,
470 animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=0.8}
473 image="default_water_flowing_animated.png",
474 backface_culling=true,
475 animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=0.8}
480 paramtype2 = "flowingliquid",
487 liquidtype = "flowing",
488 liquid_alternative_flowing = "default:water_flowing",
489 liquid_alternative_source = "default:water_source",
490 liquid_viscosity = WATER_VISC,
491 freezemelt = "default:snow",
492 post_effect_color = {a=64, r=100, g=100, b=200},
493 groups = {water=3, liquid=3, puts_out_fire=1, not_in_creative_inventory=1, freezes=1, melt_around=1},
496 minetest.register_node("default:water_source", {
497 description = "Water Source",
498 inventory_image = minetest.inventorycube("default_water.png"),
501 {name="default_water_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}}
504 -- New-style water source material (mostly unused)
506 name="default_water_source_animated.png",
507 animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0},
508 backface_culling = false,
519 liquidtype = "source",
520 liquid_alternative_flowing = "default:water_flowing",
521 liquid_alternative_source = "default:water_source",
522 liquid_viscosity = WATER_VISC,
523 freezemelt = "default:ice",
524 post_effect_color = {a=64, r=100, g=100, b=200},
525 groups = {water=3, liquid=3, puts_out_fire=1, freezes=1},
528 minetest.register_node("default:lava_flowing", {
529 description = "Flowing Lava",
530 inventory_image = minetest.inventorycube("default_lava.png"),
531 drawtype = "flowingliquid",
532 tiles = {"default_lava.png"},
535 image="default_lava_flowing_animated.png",
536 backface_culling=false,
537 animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3}
540 image="default_lava_flowing_animated.png",
541 backface_culling=true,
542 animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3}
546 paramtype2 = "flowingliquid",
547 light_source = LIGHT_MAX - 1,
554 liquidtype = "flowing",
555 liquid_alternative_flowing = "default:lava_flowing",
556 liquid_alternative_source = "default:lava_source",
557 liquid_viscosity = LAVA_VISC,
558 liquid_renewable = false,
559 damage_per_second = 4*2,
560 post_effect_color = {a=192, r=255, g=64, b=0},
561 groups = {lava=3, liquid=2, hot=3, igniter=1, not_in_creative_inventory=1},
564 minetest.register_node("default:lava_source", {
565 description = "Lava Source",
566 inventory_image = minetest.inventorycube("default_lava.png"),
569 {name="default_lava_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}}
572 -- New-style lava source material (mostly unused)
574 name="default_lava_source_animated.png",
575 animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0},
576 backface_culling = false,
580 light_source = LIGHT_MAX - 1,
587 liquidtype = "source",
588 liquid_alternative_flowing = "default:lava_flowing",
589 liquid_alternative_source = "default:lava_source",
590 liquid_viscosity = LAVA_VISC,
591 liquid_renewable = false,
592 damage_per_second = 4*2,
593 post_effect_color = {a=192, r=255, g=64, b=0},
594 groups = {lava=3, liquid=2, hot=3, igniter=1},
597 minetest.register_node("default:torch", {
598 description = "Torch",
599 drawtype = "torchlike",
600 --tiles = {"default_torch_on_floor.png", "default_torch_on_ceiling.png", "default_torch.png"},
602 {name="default_torch_on_floor_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}},
603 {name="default_torch_on_ceiling_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}},
604 {name="default_torch_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}}
606 inventory_image = "default_torch_on_floor.png",
607 wield_image = "default_torch_on_floor.png",
609 paramtype2 = "wallmounted",
610 sunlight_propagates = true,
611 is_ground_content = false,
613 light_source = LIGHT_MAX-1,
615 type = "wallmounted",
616 wall_top = {-0.1, 0.5-0.6, -0.1, 0.1, 0.5, 0.1},
617 wall_bottom = {-0.1, -0.5, -0.1, 0.1, -0.5+0.6, 0.1},
618 wall_side = {-0.5, -0.3, -0.1, -0.5+0.3, 0.3, 0.1},
620 groups = {choppy=2,dig_immediate=3,flammable=1,attached_node=1,hot=2},
621 legacy_wallmounted = true,
622 sounds = default.node_sound_defaults(),
625 minetest.register_node("default:sign_wall", {
626 description = "Sign",
627 drawtype = "signlike",
628 tiles = {"default_sign_wall.png"},
629 inventory_image = "default_sign_wall.png",
630 wield_image = "default_sign_wall.png",
632 paramtype2 = "wallmounted",
633 sunlight_propagates = true,
634 is_ground_content = false,
637 type = "wallmounted",
638 --wall_top = <default>
639 --wall_bottom = <default>
640 --wall_side = <default>
642 groups = {choppy=2,dig_immediate=2,attached_node=1},
643 legacy_wallmounted = true,
644 sounds = default.node_sound_defaults(),
645 on_construct = function(pos)
646 --local n = minetest.get_node(pos)
647 local meta = minetest.get_meta(pos)
648 meta:set_string("formspec", "field[text;;${text}]")
649 meta:set_string("infotext", "\"\"")
651 on_receive_fields = function(pos, formname, fields, sender)
652 --print("Sign at "..minetest.pos_to_string(pos).." got "..dump(fields))
653 if minetest.is_protected(pos, sender:get_player_name()) then
654 minetest.record_protection_violation(pos, sender:get_player_name())
657 local meta = minetest.get_meta(pos)
658 fields.text = fields.text or ""
659 minetest.log("action", (sender:get_player_name() or "").." wrote \""..fields.text..
660 "\" to sign at "..minetest.pos_to_string(pos))
661 meta:set_string("text", fields.text)
662 meta:set_string("infotext", '"'..fields.text..'"')
666 default.chest_formspec =
668 "list[current_name;main;0,0;8,4;]"..
669 "list[current_player;main;0,5;8,4;]"
671 function default.get_locked_chest_formspec(pos)
672 local spos = pos.x .. "," .. pos.y .. "," ..pos.z
675 "list[nodemeta:".. spos .. ";main;0,0;8,4;]"..
676 "list[current_player;main;0,5;8,4;]"
681 minetest.register_node("default:chest", {
682 description = "Chest",
683 tiles = {"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
684 "default_chest_side.png", "default_chest_side.png", "default_chest_front.png"},
685 paramtype2 = "facedir",
686 groups = {choppy=2,oddly_breakable_by_hand=2},
687 legacy_facedir_simple = true,
688 is_ground_content = false,
689 sounds = default.node_sound_wood_defaults(),
690 on_construct = function(pos)
691 local meta = minetest.get_meta(pos)
692 meta:set_string("formspec",default.chest_formspec)
693 meta:set_string("infotext", "Chest")
694 local inv = meta:get_inventory()
695 inv:set_size("main", 8*4)
697 can_dig = function(pos,player)
698 local meta = minetest.get_meta(pos);
699 local inv = meta:get_inventory()
700 return inv:is_empty("main")
702 on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
703 minetest.log("action", player:get_player_name()..
704 " moves stuff in chest at "..minetest.pos_to_string(pos))
706 on_metadata_inventory_put = function(pos, listname, index, stack, player)
707 minetest.log("action", player:get_player_name()..
708 " moves stuff to chest at "..minetest.pos_to_string(pos))
710 on_metadata_inventory_take = function(pos, listname, index, stack, player)
711 minetest.log("action", player:get_player_name()..
712 " takes stuff from chest at "..minetest.pos_to_string(pos))
716 local function has_locked_chest_privilege(meta, player)
717 if player:get_player_name() ~= meta:get_string("owner") then
723 minetest.register_node("default:chest_locked", {
724 description = "Locked Chest",
725 tiles = {"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
726 "default_chest_side.png", "default_chest_side.png", "default_chest_lock.png"},
727 paramtype2 = "facedir",
728 groups = {choppy=2,oddly_breakable_by_hand=2},
729 legacy_facedir_simple = true,
730 is_ground_content = false,
731 sounds = default.node_sound_wood_defaults(),
732 after_place_node = function(pos, placer)
733 local meta = minetest.get_meta(pos)
734 meta:set_string("owner", placer:get_player_name() or "")
735 meta:set_string("infotext", "Locked Chest (owned by "..
736 meta:get_string("owner")..")")
738 on_construct = function(pos)
739 local meta = minetest.get_meta(pos)
740 meta:set_string("infotext", "Locked Chest")
741 meta:set_string("owner", "")
742 local inv = meta:get_inventory()
743 inv:set_size("main", 8*4)
745 can_dig = function(pos,player)
746 local meta = minetest.get_meta(pos);
747 local inv = meta:get_inventory()
748 return inv:is_empty("main") and has_locked_chest_privilege(meta, player)
750 allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
751 local meta = minetest.get_meta(pos)
752 if not has_locked_chest_privilege(meta, player) then
753 minetest.log("action", player:get_player_name()..
754 " tried to access a locked chest belonging to "..
755 meta:get_string("owner").." at "..
756 minetest.pos_to_string(pos))
761 allow_metadata_inventory_put = function(pos, listname, index, stack, player)
762 local meta = minetest.get_meta(pos)
763 if not has_locked_chest_privilege(meta, player) then
764 minetest.log("action", player:get_player_name()..
765 " tried to access a locked chest belonging to "..
766 meta:get_string("owner").." at "..
767 minetest.pos_to_string(pos))
770 return stack:get_count()
772 allow_metadata_inventory_take = function(pos, listname, index, stack, player)
773 local meta = minetest.get_meta(pos)
774 if not has_locked_chest_privilege(meta, player) then
775 minetest.log("action", player:get_player_name()..
776 " tried to access a locked chest belonging to "..
777 meta:get_string("owner").." at "..
778 minetest.pos_to_string(pos))
781 return stack:get_count()
783 on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
784 minetest.log("action", player:get_player_name()..
785 " moves stuff in locked chest at "..minetest.pos_to_string(pos))
787 on_metadata_inventory_put = function(pos, listname, index, stack, player)
788 minetest.log("action", player:get_player_name()..
789 " moves stuff to locked chest at "..minetest.pos_to_string(pos))
791 on_metadata_inventory_take = function(pos, listname, index, stack, player)
792 minetest.log("action", player:get_player_name()..
793 " takes stuff from locked chest at "..minetest.pos_to_string(pos))
795 on_rightclick = function(pos, node, clicker)
796 local meta = minetest.get_meta(pos)
797 if has_locked_chest_privilege(meta, clicker) then
798 minetest.show_formspec(
799 clicker:get_player_name(),
800 "default:chest_locked",
801 default.get_locked_chest_formspec(pos)
807 function default.get_furnace_active_formspec(pos, percent)
810 "image[2,2;1,1;default_furnace_fire_bg.png^[lowpart:"..
811 (100-percent)..":default_furnace_fire_fg.png]"..
812 "list[current_name;fuel;2,3;1,1;]"..
813 "list[current_name;src;2,1;1,1;]"..
814 "list[current_name;dst;5,1;2,2;]"..
815 "list[current_player;main;0,5;8,4;]"
819 default.furnace_inactive_formspec =
821 "image[2,2;1,1;default_furnace_fire_bg.png]"..
822 "list[current_name;fuel;2,3;1,1;]"..
823 "list[current_name;src;2,1;1,1;]"..
824 "list[current_name;dst;5,1;2,2;]"..
825 "list[current_player;main;0,5;8,4;]"
827 minetest.register_node("default:furnace", {
828 description = "Furnace",
829 tiles = {"default_furnace_top.png", "default_furnace_bottom.png", "default_furnace_side.png",
830 "default_furnace_side.png", "default_furnace_side.png", "default_furnace_front.png"},
831 paramtype2 = "facedir",
833 legacy_facedir_simple = true,
834 is_ground_content = false,
835 sounds = default.node_sound_stone_defaults(),
836 on_construct = function(pos)
837 local meta = minetest.get_meta(pos)
838 meta:set_string("formspec", default.furnace_inactive_formspec)
839 meta:set_string("infotext", "Furnace")
840 local inv = meta:get_inventory()
841 inv:set_size("fuel", 1)
842 inv:set_size("src", 1)
843 inv:set_size("dst", 4)
845 can_dig = function(pos,player)
846 local meta = minetest.get_meta(pos);
847 local inv = meta:get_inventory()
848 if not inv:is_empty("fuel") then
850 elseif not inv:is_empty("dst") then
852 elseif not inv:is_empty("src") then
857 allow_metadata_inventory_put = function(pos, listname, index, stack, player)
858 local meta = minetest.get_meta(pos)
859 local inv = meta:get_inventory()
860 if listname == "fuel" then
861 if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
862 if inv:is_empty("src") then
863 meta:set_string("infotext","Furnace is empty")
865 return stack:get_count()
869 elseif listname == "src" then
870 return stack:get_count()
871 elseif listname == "dst" then
875 allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
876 local meta = minetest.get_meta(pos)
877 local inv = meta:get_inventory()
878 local stack = inv:get_stack(from_list, from_index)
879 if to_list == "fuel" then
880 if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
881 if inv:is_empty("src") then
882 meta:set_string("infotext","Furnace is empty")
888 elseif to_list == "src" then
890 elseif to_list == "dst" then
896 minetest.register_node("default:furnace_active", {
897 description = "Furnace",
898 tiles = {"default_furnace_top.png", "default_furnace_bottom.png", "default_furnace_side.png",
899 "default_furnace_side.png", "default_furnace_side.png", "default_furnace_front_active.png"},
900 paramtype2 = "facedir",
902 drop = "default:furnace",
903 groups = {cracky=2, not_in_creative_inventory=1,hot=1},
904 legacy_facedir_simple = true,
905 is_ground_content = false,
906 sounds = default.node_sound_stone_defaults(),
907 on_construct = function(pos)
908 local meta = minetest.get_meta(pos)
909 meta:set_string("formspec", default.furnace_inactive_formspec)
910 meta:set_string("infotext", "Furnace");
911 local inv = meta:get_inventory()
912 inv:set_size("fuel", 1)
913 inv:set_size("src", 1)
914 inv:set_size("dst", 4)
916 can_dig = function(pos,player)
917 local meta = minetest.get_meta(pos);
918 local inv = meta:get_inventory()
919 if not inv:is_empty("fuel") then
921 elseif not inv:is_empty("dst") then
923 elseif not inv:is_empty("src") then
928 allow_metadata_inventory_put = function(pos, listname, index, stack, player)
929 local meta = minetest.get_meta(pos)
930 local inv = meta:get_inventory()
931 if listname == "fuel" then
932 if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
933 if inv:is_empty("src") then
934 meta:set_string("infotext","Furnace is empty")
936 return stack:get_count()
940 elseif listname == "src" then
941 return stack:get_count()
942 elseif listname == "dst" then
946 allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
947 local meta = minetest.get_meta(pos)
948 local inv = meta:get_inventory()
949 local stack = inv:get_stack(from_list, from_index)
950 if to_list == "fuel" then
951 if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
952 if inv:is_empty("src") then
953 meta:set_string("infotext","Furnace is empty")
959 elseif to_list == "src" then
961 elseif to_list == "dst" then
967 local function swap_node(pos,name)
968 local node = minetest.get_node(pos)
969 if node.name == name then
973 minetest.swap_node(pos,node)
976 minetest.register_abm({
977 nodenames = {"default:furnace","default:furnace_active"},
980 action = function(pos, node, active_object_count, active_object_count_wider)
981 local meta = minetest.get_meta(pos)
982 for i, name in ipairs({
988 if meta:get_string(name) == "" then
989 meta:set_float(name, 0.0)
993 local inv = meta:get_inventory()
995 local srclist = inv:get_list("src")
1000 cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
1003 local was_active = false
1005 if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
1007 meta:set_float("fuel_time", meta:get_float("fuel_time") + 1)
1008 meta:set_float("src_time", meta:get_float("src_time") + 1)
1009 if cooked and cooked.item and meta:get_float("src_time") >= cooked.time then
1010 -- check if there's room for output in "dst" list
1011 if inv:room_for_item("dst",cooked.item) then
1012 -- Put result in "dst" list
1013 inv:add_item("dst", cooked.item)
1014 -- take stuff from "src" list
1015 inv:set_stack("src", 1, aftercooked.items[1])
1017 --print("Could not insert '"..cooked.item:to_string().."'")
1019 meta:set_string("src_time", 0)
1023 if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
1024 local percent = math.floor(meta:get_float("fuel_time") /
1025 meta:get_float("fuel_totaltime") * 100)
1026 meta:set_string("infotext","Furnace active: "..percent.."%")
1027 swap_node(pos,"default:furnace_active")
1028 meta:set_string("formspec",default.get_furnace_active_formspec(pos, percent))
1035 local fuellist = inv:get_list("fuel")
1036 local srclist = inv:get_list("src")
1039 cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
1042 fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
1045 if fuel.time <= 0 then
1046 meta:set_string("infotext","Furnace out of fuel")
1047 swap_node(pos,"default:furnace")
1048 meta:set_string("formspec", default.furnace_inactive_formspec)
1052 if cooked.item:is_empty() then
1054 meta:set_string("infotext","Furnace is empty")
1055 swap_node(pos,"default:furnace")
1056 meta:set_string("formspec", default.furnace_inactive_formspec)
1061 meta:set_string("fuel_totaltime", fuel.time)
1062 meta:set_string("fuel_time", 0)
1064 inv:set_stack("fuel", 1, afterfuel.items[1])
1068 minetest.register_node("default:cobble", {
1069 description = "Cobblestone",
1070 tiles = {"default_cobble.png"},
1071 is_ground_content = true,
1072 groups = {cracky=3, stone=2},
1073 sounds = default.node_sound_stone_defaults(),
1076 minetest.register_node("default:mossycobble", {
1077 description = "Mossy Cobblestone",
1078 tiles = {"default_mossycobble.png"},
1079 is_ground_content = true,
1080 groups = {cracky=3},
1081 sounds = default.node_sound_stone_defaults(),
1084 minetest.register_node("default:coalblock", {
1085 description = "Coal Block",
1086 tiles = {"default_coal_block.png"},
1087 is_ground_content = true,
1088 groups = {cracky=3},
1089 sounds = default.node_sound_stone_defaults(),
1092 minetest.register_node("default:steelblock", {
1093 description = "Steel Block",
1094 tiles = {"default_steel_block.png"},
1095 is_ground_content = true,
1096 groups = {cracky=1,level=2},
1097 sounds = default.node_sound_stone_defaults(),
1100 minetest.register_node("default:copperblock", {
1101 description = "Copper Block",
1102 tiles = {"default_copper_block.png"},
1103 is_ground_content = true,
1104 groups = {cracky=1,level=2},
1105 sounds = default.node_sound_stone_defaults(),
1108 minetest.register_node("default:bronzeblock", {
1109 description = "Bronze Block",
1110 tiles = {"default_bronze_block.png"},
1111 is_ground_content = true,
1112 groups = {cracky=1,level=2},
1113 sounds = default.node_sound_stone_defaults(),
1116 minetest.register_node("default:mese", {
1117 description = "Mese Block",
1118 tiles = {"default_mese_block.png"},
1119 is_ground_content = true,
1120 groups = {cracky=1,level=2},
1121 sounds = default.node_sound_stone_defaults(),
1123 minetest.register_alias("default:mese_block", "default:mese")
1125 minetest.register_node("default:goldblock", {
1126 description = "Gold Block",
1127 tiles = {"default_gold_block.png"},
1128 is_ground_content = true,
1129 groups = {cracky=1},
1130 sounds = default.node_sound_stone_defaults(),
1133 minetest.register_node("default:diamondblock", {
1134 description = "Diamond Block",
1135 tiles = {"default_diamond_block.png"},
1136 is_ground_content = true,
1137 groups = {cracky=1,level=3},
1138 sounds = default.node_sound_stone_defaults(),
1141 minetest.register_node("default:obsidian_glass", {
1142 description = "Obsidian Glass",
1143 drawtype = "glasslike",
1144 tiles = {"default_obsidian_glass.png"},
1145 paramtype = "light",
1146 is_ground_content = false,
1147 sunlight_propagates = true,
1148 sounds = default.node_sound_glass_defaults(),
1149 groups = {cracky=3,oddly_breakable_by_hand=3},
1152 minetest.register_node("default:obsidian", {
1153 description = "Obsidian",
1154 tiles = {"default_obsidian.png"},
1155 is_ground_content = true,
1156 sounds = default.node_sound_stone_defaults(),
1157 groups = {cracky=1,level=2},
1160 minetest.register_node("default:nyancat", {
1161 description = "Nyan Cat",
1162 tiles = {"default_nc_side.png", "default_nc_side.png", "default_nc_side.png",
1163 "default_nc_side.png", "default_nc_back.png", "default_nc_front.png"},
1164 paramtype2 = "facedir",
1165 groups = {cracky=2},
1166 is_ground_content = false,
1167 legacy_facedir_simple = true,
1168 sounds = default.node_sound_defaults(),
1171 minetest.register_node("default:nyancat_rainbow", {
1172 description = "Nyan Cat Rainbow",
1173 tiles = {"default_nc_rb.png^[transformR90", "default_nc_rb.png^[transformR90",
1174 "default_nc_rb.png", "default_nc_rb.png"},
1175 paramtype2 = "facedir",
1176 groups = {cracky=2},
1177 is_ground_content = false,
1178 sounds = default.node_sound_defaults(),
1181 minetest.register_node("default:sapling", {
1182 description = "Sapling",
1183 drawtype = "plantlike",
1185 tiles = {"default_sapling.png"},
1186 inventory_image = "default_sapling.png",
1187 wield_image = "default_sapling.png",
1188 paramtype = "light",
1190 is_ground_content = true,
1193 fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
1195 groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1},
1196 sounds = default.node_sound_leaves_defaults(),
1199 minetest.register_node("default:apple", {
1200 description = "Apple",
1201 drawtype = "plantlike",
1203 tiles = {"default_apple.png"},
1204 inventory_image = "default_apple.png",
1205 paramtype = "light",
1206 sunlight_propagates = true,
1208 is_ground_content = true,
1211 fixed = {-0.2, -0.5, -0.2, 0.2, 0, 0.2}
1213 groups = {fleshy=3,dig_immediate=3,flammable=2,leafdecay=3,leafdecay_drop=1},
1214 on_use = minetest.item_eat(1),
1215 sounds = default.node_sound_leaves_defaults(),
1216 after_place_node = function(pos, placer, itemstack)
1217 if placer:is_player() then
1218 minetest.set_node(pos, {name="default:apple", param2=1})
1223 minetest.register_node("default:dry_shrub", {
1224 description = "Dry Shrub",
1225 drawtype = "plantlike",
1227 tiles = {"default_dry_shrub.png"},
1228 inventory_image = "default_dry_shrub.png",
1229 wield_image = "default_dry_shrub.png",
1230 paramtype = "light",
1233 is_ground_content = true,
1234 buildable_to = true,
1235 groups = {snappy=3,flammable=3,attached_node=1},
1236 sounds = default.node_sound_leaves_defaults(),
1239 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1243 minetest.register_node("default:grass_1", {
1244 description = "Grass",
1245 drawtype = "plantlike",
1246 tiles = {"default_grass_1.png"},
1247 -- use a bigger inventory image
1248 inventory_image = "default_grass_3.png",
1249 wield_image = "default_grass_3.png",
1250 paramtype = "light",
1252 is_ground_content = true,
1253 buildable_to = true,
1254 groups = {snappy=3,flammable=3,flora=1,attached_node=1},
1255 sounds = default.node_sound_leaves_defaults(),
1258 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1260 on_place = function(itemstack, placer, pointed_thing)
1261 -- place a random grass node
1262 local stack = ItemStack("default:grass_"..math.random(1,5))
1263 local ret = minetest.item_place(stack, placer, pointed_thing)
1264 return ItemStack("default:grass_1 "..itemstack:get_count()-(1-ret:get_count()))
1268 minetest.register_node("default:grass_2", {
1269 description = "Grass",
1270 drawtype = "plantlike",
1271 tiles = {"default_grass_2.png"},
1272 inventory_image = "default_grass_2.png",
1273 wield_image = "default_grass_2.png",
1274 paramtype = "light",
1276 buildable_to = true,
1277 is_ground_content = true,
1278 drop = "default:grass_1",
1279 groups = {snappy=3,flammable=3,flora=1,attached_node=1,not_in_creative_inventory=1},
1280 sounds = default.node_sound_leaves_defaults(),
1283 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1286 minetest.register_node("default:grass_3", {
1287 description = "Grass",
1288 drawtype = "plantlike",
1289 tiles = {"default_grass_3.png"},
1290 inventory_image = "default_grass_3.png",
1291 wield_image = "default_grass_3.png",
1292 paramtype = "light",
1294 buildable_to = true,
1295 is_ground_content = true,
1296 drop = "default:grass_1",
1297 groups = {snappy=3,flammable=3,flora=1,attached_node=1,not_in_creative_inventory=1},
1298 sounds = default.node_sound_leaves_defaults(),
1301 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1305 minetest.register_node("default:grass_4", {
1306 description = "Grass",
1307 drawtype = "plantlike",
1308 tiles = {"default_grass_4.png"},
1309 inventory_image = "default_grass_4.png",
1310 wield_image = "default_grass_4.png",
1311 paramtype = "light",
1313 buildable_to = true,
1314 is_ground_content = true,
1315 drop = "default:grass_1",
1316 groups = {snappy=3,flammable=3,flora=1,attached_node=1,not_in_creative_inventory=1},
1317 sounds = default.node_sound_leaves_defaults(),
1320 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1324 minetest.register_node("default:grass_5", {
1325 description = "Grass",
1326 drawtype = "plantlike",
1327 tiles = {"default_grass_5.png"},
1328 inventory_image = "default_grass_5.png",
1329 wield_image = "default_grass_5.png",
1330 paramtype = "light",
1332 buildable_to = true,
1333 is_ground_content = true,
1334 drop = "default:grass_1",
1335 groups = {snappy=3,flammable=3,flora=1,attached_node=1,not_in_creative_inventory=1},
1336 sounds = default.node_sound_leaves_defaults(),
1339 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
1343 minetest.register_node("default:ice", {
1344 description = "Ice",
1345 tiles = {"default_ice.png"},
1346 is_ground_content = true,
1347 paramtype = "light",
1348 freezemelt = "default:water_source",
1349 groups = {cracky=3, melts=1},
1350 sounds = default.node_sound_glass_defaults(),
1353 minetest.register_node("default:snow", {
1354 description = "Snow",
1355 tiles = {"default_snow.png"},
1356 inventory_image = "default_snowball.png",
1357 wield_image = "default_snowball.png",
1358 is_ground_content = true,
1359 paramtype = "light",
1360 buildable_to = true,
1362 drawtype = "nodebox",
1363 freezemelt = "default:water_flowing",
1367 {-0.5, -0.5, -0.5, 0.5, -0.5+2/16, 0.5},
1370 groups = {crumbly=3,falling_node=1, melts=1, float=1},
1371 sounds = default.node_sound_dirt_defaults({
1372 footstep = {name="default_snow_footstep", gain=0.25},
1373 dug = {name="default_snow_footstep", gain=0.75},
1375 on_construct = function(pos)
1377 if minetest.get_node(pos).name == "default:dirt_with_grass" then
1378 minetest.set_node(pos, {name="default:dirt_with_snow"})
1382 minetest.register_alias("snow", "default:snow")
1384 minetest.register_node("default:snowblock", {
1385 description = "Snow Block",
1386 tiles = {"default_snow.png"},
1387 is_ground_content = true,
1388 freezemelt = "default:water_source",
1389 groups = {crumbly=3, melts=1},
1390 sounds = default.node_sound_dirt_defaults({
1391 footstep = {name="default_snow_footstep", gain=0.25},
1392 dug = {name="default_snow_footstep", gain=0.75},