Import source (dev state between 1.2.0 and 1.3.0)
[minetest_tutorial_subgame.git] / mods / default / nodes.lua
blob54e62921640aa03d76c67335d19a371e56b2715c
1 -- mods/default/nodes.lua
3 minetest.register_node("default:stone", {
4 description = "Stone",
5 tiles = {"default_stone.png"},
6 is_ground_content = true,
7 groups = {cracky=3, stone=1},
8 drop = 'default:cobble',
9 legacy_mineral = true,
10 sounds = default.node_sound_stone_defaults(),
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,
17 groups = {cracky=3},
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,
26 groups = {cracky=2},
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,
35 groups = {cracky=2},
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,
44 groups = {cracky=1},
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},
64 }),
67 minetest.register_node("default:dirt", {
68 description = "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", {
76 description = "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", {
84 description = "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",
96 waving = 1,
97 visual_scale = 1.3,
98 tiles = {"default_leaves.png"},
99 paramtype = "light",
100 is_ground_content = false,
101 groups = {immortal=1},
102 drop = {
103 max_items = 1,
104 items = {
106 -- player will get sapling with 1/20 chance
107 items = {'default:sapling'},
108 rarity = 20,
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",
126 paramtype = "light",
127 paramtype2 = "wallmounted",
128 walkable = false,
129 climbable = true,
130 is_ground_content = false,
131 selection_box = {
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"},
154 special_tiles = {
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}
166 alpha = WATER_ALPHA,
167 paramtype = "light",
168 paramtype2 = "flowingliquid",
169 walkable = false,
170 pointable = false,
171 diggable = false,
172 buildable_to = true,
173 drop = "",
174 drowning = 1,
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"),
187 drawtype = "liquid",
188 tiles = {
189 {name="default_water_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}}
191 special_tiles = {
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,
199 alpha = WATER_ALPHA,
200 paramtype = "light",
201 walkable = false,
202 pointable = false,
203 diggable = false,
204 buildable_to = true,
205 drop = "",
206 drowning = 1,
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"},
220 tiles = {
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",
227 paramtype = "light",
228 paramtype2 = "wallmounted",
229 sunlight_propagates = true,
230 is_ground_content = false,
231 walkable = false,
232 light_source = LIGHT_MAX-1,
233 selection_box = {
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 =
245 "size[8,9.1]"..
246 default.gui_bg..
247 default.gui_bg_img..
248 default.gui_slots..
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)
272 end,
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")
277 end,
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))
281 end,
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))
285 end,
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))
289 end,
292 function default.furnace_active(pos, percent, item_percent)
293 local formspec =
294 "size[8,8.5]"..
295 default.gui_bg..
296 default.gui_bg_img..
297 default.gui_slots..
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)
316 return formspec
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")
322 local cooked = nil
323 local aftercooked = nil
324 if srclist then
325 cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
327 local item_percent = 0
328 if cooked then
329 item_percent = meta:get_float("src_time")/cooked.time
332 return default.furnace_active(pos, percent, item_percent)
335 default.furnace_inactive_formspec =
336 "size[8,8.5]"..
337 default.gui_bg..
338 default.gui_bg_img..
339 default.gui_slots..
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)
374 end,
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
379 return false
380 elseif not inv:is_empty("dst") then
381 return false
382 elseif not inv:is_empty("src") then
383 return false
385 return true
386 end,
387 allow_metadata_inventory_put = function(pos, listname, index, stack, player)
388 if minetest.is_protected(pos, player:get_player_name()) then
389 return 0
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()
399 else
400 return 0
402 elseif listname == "src" then
403 return stack:get_count()
404 elseif listname == "dst" then
405 return 0
407 end,
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
410 return 0
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)")
420 return count
421 else
422 return 0
424 elseif to_list == "src" then
425 return count
426 elseif to_list == "dst" then
427 return 0
429 end,
430 allow_metadata_inventory_take = function(pos, listname, index, stack, player)
431 if minetest.is_protected(pos, player:get_player_name()) then
432 return 0
434 return stack:get_count()
435 end,
438 minetest.register_node("default:furnace_active", {
439 description = "Furnace",
440 tiles = {
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,
449 animation = {
450 type = "vertical_frames",
451 aspect_w = 16,
452 aspect_h = 16,
453 length = 1.5
457 paramtype2 = "facedir",
458 light_source = 8,
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)
472 end,
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
477 return false
478 elseif not inv:is_empty("dst") then
479 return false
480 elseif not inv:is_empty("src") then
481 return false
483 return true
484 end,
485 allow_metadata_inventory_put = function(pos, listname, index, stack, player)
486 if minetest.is_protected(pos, player:get_player_name()) then
487 return 0
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()
497 else
498 return 0
500 elseif listname == "src" then
501 return stack:get_count()
502 elseif listname == "dst" then
503 return 0
505 end,
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
508 return 0
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)")
518 return count
519 else
520 return 0
522 elseif to_list == "src" then
523 return count
524 elseif to_list == "dst" then
525 return 0
527 end,
528 allow_metadata_inventory_take = function(pos, listname, index, stack, player)
529 if minetest.is_protected(pos, player:get_player_name()) then
530 return 0
532 return stack:get_count()
533 end,
536 local function swap_node(pos,name)
537 local node = minetest.get_node(pos)
538 if node.name == name then
539 return
541 node.name = name
542 minetest.swap_node(pos,node)
545 minetest.register_abm({
546 nodenames = {"default:furnace","default:furnace_active"},
547 interval = 1.0,
548 chance = 1,
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({
552 "fuel_totaltime",
553 "fuel_time",
554 "src_totaltime",
555 "src_time"
556 }) do
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")
565 local cooked = nil
566 local aftercooked
568 if srclist then
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
575 was_active = true
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])
585 else
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))
598 return
601 local fuel = nil
602 local afterfuel
603 local cooked = nil
604 local fuellist = inv:get_list("fuel")
605 local srclist = inv:get_list("src")
607 if srclist then
608 cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
610 if fuellist then
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)
618 return
621 if cooked.item:is_empty() then
622 if was_active 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)
627 return
630 meta:set_string("fuel_totaltime", fuel.time)
631 meta:set_string("fuel_time", 0)
633 inv:set_stack("fuel", 1, afterfuel.items[1])
634 end,
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",
648 visual_scale = 1.0,
649 tiles = {"default_apple.png"},
650 inventory_image = "default_apple.png",
651 paramtype = "light",
652 sunlight_propagates = true,
653 walkable = false,
654 is_ground_content = true,
655 selection_box = {
656 type = "fixed",
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})
666 end,