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:stone_with_coal", {
14 description
= "Coal Ore",
15 tiles
= {"default_stone.png^default_mineral_coal.png"},
16 is_ground_content
= true,
18 drop
= 'default:coal_lump',
19 sounds
= default
.node_sound_stone_defaults(),
22 minetest
.register_node("default:stone_with_iron", {
23 description
= "Iron Ore",
24 tiles
= {"default_stone.png^default_mineral_iron.png"},
25 is_ground_content
= true,
27 drop
= 'default:iron_lump',
28 sounds
= default
.node_sound_stone_defaults(),
31 minetest
.register_node("default:stone_with_gold", {
32 description
= "Gold Ore",
33 tiles
= {"default_stone.png^default_mineral_gold.png"},
34 is_ground_content
= true,
36 drop
= "default:gold_lump",
37 sounds
= default
.node_sound_stone_defaults(),
40 minetest
.register_node("default:stone_with_diamond", {
41 description
= "Diamond Ore",
42 tiles
= {"default_stone.png^default_mineral_diamond.png"},
43 is_ground_content
= true,
45 drop
= "default:diamond",
46 sounds
= default
.node_sound_stone_defaults(),
49 minetest
.register_node("default:stonebrick", {
50 description
= "Stone Brick",
51 tiles
= {"default_stone_brick.png"},
52 groups
= {cracky
=2, stone
=1},
53 sounds
= default
.node_sound_stone_defaults(),
56 minetest
.register_node("default:dirt_with_grass", {
57 description
= "Dirt with Grass",
58 tiles
= {"default_grass.png", "default_dirt.png", "default_dirt.png^default_grass_side.png"},
59 is_ground_content
= true,
60 groups
= {immortal
=1},
61 drop
= 'default:dirt',
62 sounds
= default
.node_sound_dirt_defaults({
63 footstep
= {name
="default_grass_footstep", gain
=0.25},
67 minetest
.register_node("default:dirt", {
69 tiles
= {"default_dirt.png"},
70 is_ground_content
= true,
71 groups
= {immortal
=1},
72 sounds
= default
.node_sound_dirt_defaults(),
75 minetest
.register_node("default:sand", {
77 tiles
= {"default_sand.png"},
78 is_ground_content
= true,
79 groups
= {crumbly
=3, falling_node
=1, sand
=1},
80 sounds
= default
.node_sound_sand_defaults(),
83 minetest
.register_node("default:tree", {
85 tiles
= {"default_tree_top.png", "default_tree_top.png", "default_tree.png"},
86 paramtype2
= "facedir",
87 is_ground_content
= false,
88 groups
= {immortal
=1},
89 sounds
= default
.node_sound_wood_defaults(),
90 on_place
= minetest
.rotate_node
93 minetest
.register_node("default:leaves", {
94 description
= "Leaves",
95 drawtype
= "allfaces_optional",
98 tiles
= {"default_leaves.png"},
100 is_ground_content
= false,
101 groups
= {immortal
=1},
106 -- player will get sapling with 1/20 chance
107 items
= {'default:sapling'},
111 -- player will get leaves only if he get no saplings,
112 -- this is because max_items is 1
113 items
= {'default:leaves'},
117 sounds
= default
.node_sound_leaves_defaults(),
120 minetest
.register_node("default:ladder", {
121 description
= "Ladder",
122 drawtype
= "signlike",
123 tiles
= {"default_ladder.png"},
124 inventory_image
= "default_ladder.png",
125 wield_image
= "default_ladder.png",
127 paramtype2
= "wallmounted",
130 is_ground_content
= false,
132 type = "wallmounted",
133 --wall_top = = <default>
134 --wall_bottom = = <default>
135 --wall_side = = <default>
137 groups
= {choppy
=2,flammable
=2},
138 legacy_wallmounted
= true,
139 sounds
= default
.node_sound_wood_defaults(),
142 minetest
.register_node("default:wood", {
143 description
= "Wooden Planks",
144 tiles
= {"default_wood.png"},
145 groups
= {choppy
=2,flammable
=3,wood
=1},
146 sounds
= default
.node_sound_wood_defaults(),
149 minetest
.register_node("default:water_flowing", {
150 description
= "Flowing Water",
151 inventory_image
= minetest
.inventorycube("default_water.png"),
152 drawtype
= "flowingliquid",
153 tiles
= {"default_water.png"},
156 image
="default_water_flowing_animated.png",
157 backface_culling
=false,
158 animation
={type="vertical_frames", aspect_w
=16, aspect_h
=16, length
=0.8}
161 image
="default_water_flowing_animated.png",
162 backface_culling
=true,
163 animation
={type="vertical_frames", aspect_w
=16, aspect_h
=16, length
=0.8}
168 paramtype2
= "flowingliquid",
175 liquidtype
= "flowing",
176 liquid_alternative_flowing
= "default:water_flowing",
177 liquid_alternative_source
= "default:water_source",
178 liquid_viscosity
= WATER_VISC
,
179 freezemelt
= "default:snow",
180 post_effect_color
= {a
=64, r
=100, g
=100, b
=200},
181 groups
= {water
=3, liquid
=3, puts_out_fire
=1, not_in_creative_inventory
=1, freezes
=1, melt_around
=1},
184 minetest
.register_node("default:water_source", {
185 description
= "Water Source",
186 inventory_image
= minetest
.inventorycube("default_water.png"),
189 {name
="default_water_source_animated.png", animation
={type="vertical_frames", aspect_w
=16, aspect_h
=16, length
=2.0}}
192 -- New-style water source material (mostly unused)
194 name
="default_water_source_animated.png",
195 animation
={type="vertical_frames", aspect_w
=16, aspect_h
=16, length
=2.0},
196 backface_culling
= false,
207 liquidtype
= "source",
208 liquid_alternative_flowing
= "default:water_flowing",
209 liquid_alternative_source
= "default:water_source",
210 liquid_viscosity
= WATER_VISC
,
211 freezemelt
= "default:ice",
212 post_effect_color
= {a
=64, r
=100, g
=100, b
=200},
213 groups
= {water
=3, liquid
=3, puts_out_fire
=1, freezes
=1},
216 minetest
.register_node("default:torch", {
217 description
= "Torch",
218 drawtype
= "torchlike",
219 --tiles = {"default_torch_on_floor.png", "default_torch_on_ceiling.png", "default_torch.png"},
221 {name
="default_torch_on_floor_animated.png", animation
={type="vertical_frames", aspect_w
=16, aspect_h
=16, length
=3.0}},
222 {name
="default_torch_on_ceiling_animated.png", animation
={type="vertical_frames", aspect_w
=16, aspect_h
=16, length
=3.0}},
223 {name
="default_torch_animated.png", animation
={type="vertical_frames", aspect_w
=16, aspect_h
=16, length
=3.0}}
225 inventory_image
= "default_torch_on_floor.png",
226 wield_image
= "default_torch_on_floor.png",
228 paramtype2
= "wallmounted",
229 sunlight_propagates
= true,
230 is_ground_content
= false,
232 light_source
= LIGHT_MAX
-1,
234 type = "wallmounted",
235 wall_top
= {-0.1, 0.5-0.6, -0.1, 0.1, 0.5, 0.1},
236 wall_bottom
= {-0.1, -0.5, -0.1, 0.1, -0.5+0.6, 0.1},
237 wall_side
= {-0.5, -0.3, -0.1, -0.5+0.3, 0.3, 0.1},
239 groups
= {immortal
= 1},
240 legacy_wallmounted
= true,
241 sounds
= default
.node_sound_defaults(),
244 default
.chest_formspec
=
249 "label[0,-0.2;Chest inventory:]"..
250 "list[current_name;main;0,0.3;8,4;]"..
251 "label[0,4.35;Player inventory:]"..
252 "list[current_player;main;0,4.85;8,1;]"..
253 "list[current_player;main;0,6.08;8,3;8]"..
254 "label[0,8.8;"..default
.gui_controls
.."]"..
255 default
.get_hotbar_bg(0,4.85)
257 minetest
.register_node("default:chest", {
258 description
= "Chest",
259 tiles
= {"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
260 "default_chest_side.png", "default_chest_side.png", "default_chest_front.png"},
261 paramtype2
= "facedir",
262 groups
= {immortal
=1},
263 legacy_facedir_simple
= true,
264 is_ground_content
= false,
265 sounds
= default
.node_sound_wood_defaults(),
266 on_construct
= function(pos
)
267 local meta
= minetest
.get_meta(pos
)
268 meta
:set_string("formspec",default
.chest_formspec
)
269 meta
:set_string("infotext", "Chest (Rightclick to open)")
270 local inv
= meta
:get_inventory()
271 inv
:set_size("main", 8*4)
273 can_dig
= function(pos
,player
)
274 local meta
= minetest
.get_meta(pos
);
275 local inv
= meta
:get_inventory()
276 return inv
:is_empty("main")
278 on_metadata_inventory_move
= function(pos
, from_list
, from_index
, to_list
, to_index
, count
, player
)
279 minetest
.log("action", player
:get_player_name()..
280 " moves stuff in chest at "..minetest
.pos_to_string(pos
))
282 on_metadata_inventory_put
= function(pos
, listname
, index
, stack
, player
)
283 minetest
.log("action", player
:get_player_name()..
284 " moves stuff to chest at "..minetest
.pos_to_string(pos
))
286 on_metadata_inventory_take
= function(pos
, listname
, index
, stack
, player
)
287 minetest
.log("action", player
:get_player_name()..
288 " takes stuff from chest at "..minetest
.pos_to_string(pos
))
292 function default
.furnace_active(pos
, percent
, item_percent
)
298 "label[-0.1,-0.4;This furnace is active and constantly burning its fuel.]"..
299 "label[2.75,0;Source:]"..
300 "list[current_name;src;2.75,0.5;1,1;]"..
301 "label[2.75,2.4;Fuel:]"..
302 "list[current_name;fuel;2.75,2.9;1,1;]"..
303 "label[2.75,1.2;Flame:]"..
304 "image[2.75,1.7;1,1;default_furnace_fire_bg.png^[lowpart:"..
305 (100-percent
)..":default_furnace_fire_fg.png]"..
306 "label[3.75,1.2;Progress:]"..
307 "image[3.75,1.7;1,1;gui_furnace_arrow_bg.png^[lowpart:"..
308 (item_percent
*100)..":gui_furnace_arrow_fg.png^[transformR270]"..
309 "label[4.75,0.66;Output slots:]"..
310 "list[current_name;dst;4.75,1.16;2,2;]"..
311 "label[0,3.75;Player inventory:]"..
312 "list[current_player;main;0,4.25;8,1;]"..
313 "list[current_player;main;0,5.5;8,3;8]"..
314 "label[0,8.2;"..default
.gui_controls
.."]"..
315 default
.get_hotbar_bg(0,4.25)
319 function default
.get_furnace_active_formspec(pos
, percent
)
320 local meta
= minetest
.get_meta(pos
)local inv
= meta
:get_inventory()
321 local srclist
= inv
:get_list("src")
323 local aftercooked
= nil
325 cooked
, aftercooked
= minetest
.get_craft_result({method
= "cooking", width
= 1, items
= srclist
})
327 local item_percent
= 0
329 item_percent
= meta
:get_float("src_time")/cooked
.time
332 return default
.furnace_active(pos
, percent
, item_percent
)
335 default
.furnace_inactive_formspec
=
340 "label[-0.1,-0.4;This furnace is inactive. Read the instructions to learn how to activate it.]"..
341 "label[2.75,0;Source:]"..
342 "list[current_name;src;2.75,0.5;1,1;]"..
343 "label[2.75,2.4;Fuel:]"..
344 "list[current_name;fuel;2.75,2.9;1,1;]"..
345 "label[2.75,1.2;Flame:]"..
346 "image[2.75,1.7;1,1;default_furnace_fire_bg.png]"..
347 "label[3.75,1.2;Progress:]"..
348 "image[3.75,1.7;1,1;gui_furnace_arrow_bg.png^[transformR270]"..
349 "label[4.75,0.66;Output slots:]"..
350 "list[current_name;dst;4.75,1.16;2,2;]"..
351 "label[0,3.75;Player inventory:]"..
352 "list[current_player;main;0,4.25;8,1;]"..
353 "list[current_player;main;0,5.5;8,3;8]"..
354 "label[0,8.2;"..default
.gui_controls
.."]"..
355 default
.get_hotbar_bg(0,4.25)
357 minetest
.register_node("default:furnace", {
358 description
= "Furnace",
359 tiles
= {"default_furnace_top.png", "default_furnace_bottom.png", "default_furnace_side.png",
360 "default_furnace_side.png", "default_furnace_side.png", "default_furnace_front.png"},
361 paramtype2
= "facedir",
362 groups
= {immortal
=1},
363 legacy_facedir_simple
= true,
364 is_ground_content
= false,
365 sounds
= default
.node_sound_stone_defaults(),
366 on_construct
= function(pos
)
367 local meta
= minetest
.get_meta(pos
)
368 meta
:set_string("formspec", default
.furnace_inactive_formspec
)
369 meta
:set_string("infotext", "Inactive furnace (Rightclick to examine)")
370 local inv
= meta
:get_inventory()
371 inv
:set_size("fuel", 1)
372 inv
:set_size("src", 1)
373 inv
:set_size("dst", 4)
375 can_dig
= function(pos
,player
)
376 local meta
= minetest
.get_meta(pos
);
377 local inv
= meta
:get_inventory()
378 if not inv
:is_empty("fuel") then
380 elseif not inv
:is_empty("dst") then
382 elseif not inv
:is_empty("src") then
387 allow_metadata_inventory_put
= function(pos
, listname
, index
, stack
, player
)
388 if minetest
.is_protected(pos
, player
:get_player_name()) then
391 local meta
= minetest
.get_meta(pos
)
392 local inv
= meta
:get_inventory()
393 if listname
== "fuel" then
394 if minetest
.get_craft_result({method
="fuel",width
=1,items
={stack
}}).time
~= 0 then
395 if inv
:is_empty("src") then
396 meta
:set_string("infotext","Empty furnace (Rightclick to examine)")
398 return stack
:get_count()
402 elseif listname
== "src" then
403 return stack
:get_count()
404 elseif listname
== "dst" then
408 allow_metadata_inventory_move
= function(pos
, from_list
, from_index
, to_list
, to_index
, count
, player
)
409 if minetest
.is_protected(pos
, player
:get_player_name()) then
412 local meta
= minetest
.get_meta(pos
)
413 local inv
= meta
:get_inventory()
414 local stack
= inv
:get_stack(from_list
, from_index
)
415 if to_list
== "fuel" then
416 if minetest
.get_craft_result({method
="fuel",width
=1,items
={stack
}}).time
~= 0 then
417 if inv
:is_empty("src") then
418 meta
:set_string("infotext","Empty furnace (Rightclick to examine)")
424 elseif to_list
== "src" then
426 elseif to_list
== "dst" then
430 allow_metadata_inventory_take
= function(pos
, listname
, index
, stack
, player
)
431 if minetest
.is_protected(pos
, player
:get_player_name()) then
434 return stack
:get_count()
438 minetest
.register_node("default:furnace_active", {
439 description
= "Furnace",
441 "default_furnace_top.png",
442 "default_furnace_bottom.png",
443 "default_furnace_side.png",
444 "default_furnace_side.png",
445 "default_furnace_side.png",
447 image
= "default_furnace_front_active.png",
448 backface_culling
= false,
450 type = "vertical_frames",
457 paramtype2
= "facedir",
459 drop
= "default:furnace",
460 groups
= {immortal
=1,not_in_creative_inventory
=1,hot
=1},
461 legacy_facedir_simple
= true,
462 is_ground_content
= false,
463 sounds
= default
.node_sound_stone_defaults(),
464 on_construct
= function(pos
)
465 local meta
= minetest
.get_meta(pos
)
466 meta
:set_string("formspec", default
.furnace_inactive_formspec
)
467 meta
:set_string("infotext", "Inactive furnace (Rightclick to examine)");
468 local inv
= meta
:get_inventory()
469 inv
:set_size("fuel", 1)
470 inv
:set_size("src", 1)
471 inv
:set_size("dst", 4)
473 can_dig
= function(pos
,player
)
474 local meta
= minetest
.get_meta(pos
);
475 local inv
= meta
:get_inventory()
476 if not inv
:is_empty("fuel") then
478 elseif not inv
:is_empty("dst") then
480 elseif not inv
:is_empty("src") then
485 allow_metadata_inventory_put
= function(pos
, listname
, index
, stack
, player
)
486 if minetest
.is_protected(pos
, player
:get_player_name()) then
489 local meta
= minetest
.get_meta(pos
)
490 local inv
= meta
:get_inventory()
491 if listname
== "fuel" then
492 if minetest
.get_craft_result({method
="fuel",width
=1,items
={stack
}}).time
~= 0 then
493 if inv
:is_empty("src") then
494 meta
:set_string("infotext","Empty furnace (Rightclick to examine)")
496 return stack
:get_count()
500 elseif listname
== "src" then
501 return stack
:get_count()
502 elseif listname
== "dst" then
506 allow_metadata_inventory_move
= function(pos
, from_list
, from_index
, to_list
, to_index
, count
, player
)
507 if minetest
.is_protected(pos
, player
:get_player_name()) then
510 local meta
= minetest
.get_meta(pos
)
511 local inv
= meta
:get_inventory()
512 local stack
= inv
:get_stack(from_list
, from_index
)
513 if to_list
== "fuel" then
514 if minetest
.get_craft_result({method
="fuel",width
=1,items
={stack
}}).time
~= 0 then
515 if inv
:is_empty("src") then
516 meta
:set_string("infotext","Empty furnace (Rightclick to examine)")
522 elseif to_list
== "src" then
524 elseif to_list
== "dst" then
528 allow_metadata_inventory_take
= function(pos
, listname
, index
, stack
, player
)
529 if minetest
.is_protected(pos
, player
:get_player_name()) then
532 return stack
:get_count()
536 local function swap_node(pos
,name
)
537 local node
= minetest
.get_node(pos
)
538 if node
.name
== name
then
542 minetest
.swap_node(pos
,node
)
545 minetest
.register_abm({
546 nodenames
= {"default:furnace","default:furnace_active"},
549 action
= function(pos
, node
, active_object_count
, active_object_count_wider
)
550 local meta
= minetest
.get_meta(pos
)
551 for i
, name
in ipairs({
557 if meta
:get_string(name
) == "" then
558 meta
:set_float(name
, 0.0)
562 local inv
= meta
:get_inventory()
564 local srclist
= inv
:get_list("src")
569 cooked
, aftercooked
= minetest
.get_craft_result({method
= "cooking", width
= 1, items
= srclist
})
572 local was_active
= false
574 if meta
:get_float("fuel_time") < meta
:get_float("fuel_totaltime") then
576 meta
:set_float("fuel_time", meta
:get_float("fuel_time") + 1)
577 meta
:set_float("src_time", meta
:get_float("src_time") + 1)
578 if cooked
and cooked
.item
and meta
:get_float("src_time") >= cooked
.time
then
579 -- check if there's room for output in "dst" list
580 if inv
:room_for_item("dst",cooked
.item
) then
581 -- Put result in "dst" list
582 inv
:add_item("dst", cooked
.item
)
583 -- take stuff from "src" list
584 inv
:set_stack("src", 1, aftercooked
.items
[1])
586 --print("Could not insert '"..cooked.item:to_string().."'")
588 meta
:set_string("src_time", 0)
592 if meta
:get_float("fuel_time") < meta
:get_float("fuel_totaltime") then
593 local percent
= math
.floor(meta
:get_float("fuel_time") /
594 meta
:get_float("fuel_totaltime") * 100)
595 meta
:set_string("infotext","Active furnace (Flame used: "..percent
.."%) (Rightclick to examine)")
596 swap_node(pos
,"default:furnace_active")
597 meta
:set_string("formspec",default
.get_furnace_active_formspec(pos
, percent
))
604 local fuellist
= inv
:get_list("fuel")
605 local srclist
= inv
:get_list("src")
608 cooked
= minetest
.get_craft_result({method
= "cooking", width
= 1, items
= srclist
})
611 fuel
, afterfuel
= minetest
.get_craft_result({method
= "fuel", width
= 1, items
= fuellist
})
614 if not fuel
or fuel
.time
<= 0 then
615 meta
:set_string("infotext","Furnace without fuel (Rightclick to examine)")
616 swap_node(pos
,"default:furnace")
617 meta
:set_string("formspec", default
.furnace_inactive_formspec
)
621 if cooked
.item
:is_empty() then
623 meta
:set_string("infotext","Empty furnace (Rightclick to examine)")
624 swap_node(pos
,"default:furnace")
625 meta
:set_string("formspec", default
.furnace_inactive_formspec
)
630 meta
:set_string("fuel_totaltime", fuel
.time
)
631 meta
:set_string("fuel_time", 0)
633 inv
:set_stack("fuel", 1, afterfuel
.items
[1])
637 minetest
.register_node("default:cobble", {
638 description
= "Cobblestone",
639 tiles
= {"default_cobble.png"},
640 is_ground_content
= true,
641 groups
= {cracky
=3, stone
=2},
642 sounds
= default
.node_sound_stone_defaults(),
645 minetest
.register_node("default:apple", {
646 description
= "Apple",
647 drawtype
= "plantlike",
649 tiles
= {"default_apple.png"},
650 inventory_image
= "default_apple.png",
652 sunlight_propagates
= true,
654 is_ground_content
= true,
657 fixed
= {-0.2, -0.5, -0.2, 0.2, 0, 0.2}
659 groups
= {fleshy
=3,dig_immediate
=3,flammable
=2,leafdecay
=3,leafdecay_drop
=1},
660 on_use
= minetest
.item_eat(1),
661 sounds
= default
.node_sound_leaves_defaults(),
662 after_place_node
= function(pos
, placer
, itemstack
)
663 if placer
:is_player() then
664 minetest
.set_node(pos
, {name
="default:apple", param2
=1})