8f9c316b1e2127bbb4f7913028a19c2aefcfb512
[oweals/minetest_game.git] / mods / stairs / init.lua
1 -- Minetest 0.4 mod: stairs
2 -- See README.txt for licensing and other information.
3
4
5 -- Global namespace for functions
6
7 stairs = {}
8
9
10 -- Register aliases for new pine node names
11
12 minetest.register_alias("stairs:stair_pinewood", "stairs:stair_pine_wood")
13 minetest.register_alias("stairs:slab_pinewood", "stairs:slab_pine_wood")
14
15
16 -- Get setting for replace ABM
17
18 local replace = minetest.settings:get_bool("enable_stairs_replace_abm")
19
20 local function rotate_and_place(itemstack, placer, pointed_thing)
21         local p0 = pointed_thing.under
22         local p1 = pointed_thing.above
23         local param2 = 0
24
25         if placer then
26                 local placer_pos = placer:get_pos()
27                 if placer_pos then
28                         param2 = minetest.dir_to_facedir(vector.subtract(p1, placer_pos))
29                 end
30
31                 local finepos = minetest.pointed_thing_to_face_pos(placer, pointed_thing)
32                 local fpos = finepos.y % 1
33
34                 if p0.y - 1 == p1.y or (fpos > 0 and fpos < 0.5)
35                                 or (fpos < -0.5 and fpos > -0.999999999) then
36                         param2 = param2 + 20
37                         if param2 == 21 then
38                                 param2 = 23
39                         elseif param2 == 23 then
40                                 param2 = 21
41                         end
42                 end
43         end
44         return minetest.item_place(itemstack, placer, pointed_thing, param2)
45 end
46
47 local function warn_if_exists(nodename)
48         if minetest.registered_nodes[nodename] then
49                 minetest.log("warning", "Overwriting stairs node: " .. nodename)
50         end
51 end
52
53
54 -- Register stair
55 -- Node will be called stairs:stair_<subname>
56
57 function stairs.register_stair(subname, recipeitem, groups, images, description,
58                 sounds, worldaligntex)
59         -- Set backface culling and world-aligned textures
60         local stair_images = {}
61         for i, image in ipairs(images) do
62                 if type(image) == "string" then
63                         stair_images[i] = {
64                                 name = image,
65                                 backface_culling = true,
66                         }
67                         if worldaligntex then
68                                 stair_images[i].align_style = "world"
69                         end
70                 else
71                         stair_images[i] = table.copy(image)
72                         if stair_images[i].backface_culling == nil then
73                                 stair_images[i].backface_culling = true
74                         end
75                         if worldaligntex and stair_images[i].align_style == nil then
76                                 stair_images[i].align_style = "world"
77                         end
78                 end
79         end
80         local new_groups = table.copy(groups)
81         new_groups.stair = 1
82         warn_if_exists("stairs:stair_" .. subname)
83         minetest.register_node(":stairs:stair_" .. subname, {
84                 description = description,
85                 drawtype = "nodebox",
86                 tiles = stair_images,
87                 paramtype = "light",
88                 paramtype2 = "facedir",
89                 is_ground_content = false,
90                 groups = new_groups,
91                 sounds = sounds,
92                 node_box = {
93                         type = "fixed",
94                         fixed = {
95                                 {-0.5, -0.5, -0.5, 0.5, 0.0, 0.5},
96                                 {-0.5, 0.0, 0.0, 0.5, 0.5, 0.5},
97                         },
98                 },
99                 on_place = function(itemstack, placer, pointed_thing)
100                         if pointed_thing.type ~= "node" then
101                                 return itemstack
102                         end
103
104                         return rotate_and_place(itemstack, placer, pointed_thing)
105                 end,
106         })
107
108         -- for replace ABM
109         if replace then
110                 minetest.register_node(":stairs:stair_" .. subname .. "upside_down", {
111                         replace_name = "stairs:stair_" .. subname,
112                         groups = {slabs_replace = 1},
113                 })
114         end
115
116         if recipeitem then
117                 -- Recipe matches appearence in inventory
118                 minetest.register_craft({
119                         output = "stairs:stair_" .. subname .. " 8",
120                         recipe = {
121                                 {"", "", recipeitem},
122                                 {"", recipeitem, recipeitem},
123                                 {recipeitem, recipeitem, recipeitem},
124                         },
125                 })
126
127                 -- Use stairs to craft full blocks again (1:1)
128                 minetest.register_craft({
129                         output = recipeitem .. " 3",
130                         recipe = {
131                                 {"stairs:stair_" .. subname, "stairs:stair_" .. subname},
132                                 {"stairs:stair_" .. subname, "stairs:stair_" .. subname},
133                         },
134                 })
135
136                 -- Fuel
137                 local baseburntime = minetest.get_craft_result({
138                         method = "fuel",
139                         width = 1,
140                         items = {recipeitem}
141                 }).time
142                 if baseburntime > 0 then
143                         minetest.register_craft({
144                                 type = "fuel",
145                                 recipe = "stairs:stair_" .. subname,
146                                 burntime = math.floor(baseburntime * 0.75),
147                         })
148                 end
149         end
150 end
151
152
153 -- Register slab
154 -- Node will be called stairs:slab_<subname>
155
156 function stairs.register_slab(subname, recipeitem, groups, images, description,
157                 sounds, worldaligntex)
158         -- Set world-aligned textures
159         local slab_images = {}
160         for i, image in ipairs(images) do
161                 if type(image) == "string" then
162                         slab_images[i] = {
163                                 name = image,
164                         }
165                         if worldaligntex then
166                                 slab_images[i].align_style = "world"
167                         end
168                 else
169                         slab_images[i] = table.copy(image)
170                         if worldaligntex and image.align_style == nil then
171                                 slab_images[i].align_style = "world"
172                         end
173                 end
174         end
175         local new_groups = table.copy(groups)
176         new_groups.slab = 1
177         warn_if_exists("stairs:slab_" .. subname)
178         minetest.register_node(":stairs:slab_" .. subname, {
179                 description = description,
180                 drawtype = "nodebox",
181                 tiles = slab_images,
182                 paramtype = "light",
183                 paramtype2 = "facedir",
184                 is_ground_content = false,
185                 groups = new_groups,
186                 sounds = sounds,
187                 node_box = {
188                         type = "fixed",
189                         fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
190                 },
191                 on_place = function(itemstack, placer, pointed_thing)
192                         local under = minetest.get_node(pointed_thing.under)
193                         local wield_item = itemstack:get_name()
194                         local player_name = placer and placer:get_player_name() or ""
195                         local creative_enabled = (creative and creative.is_enabled_for
196                                         and creative.is_enabled_for(player_name))
197
198                         if under and under.name:find("^stairs:slab_") then
199                                 -- place slab using under node orientation
200                                 local dir = minetest.dir_to_facedir(vector.subtract(
201                                         pointed_thing.above, pointed_thing.under), true)
202
203                                 local p2 = under.param2
204
205                                 -- Placing a slab on an upside down slab should make it right-side up.
206                                 if p2 >= 20 and dir == 8 then
207                                         p2 = p2 - 20
208                                 -- same for the opposite case: slab below normal slab
209                                 elseif p2 <= 3 and dir == 4 then
210                                         p2 = p2 + 20
211                                 end
212
213                                 -- else attempt to place node with proper param2
214                                 minetest.item_place_node(ItemStack(wield_item), placer, pointed_thing, p2)
215                                 if not creative_enabled then
216                                         itemstack:take_item()
217                                 end
218                                 return itemstack
219                         else
220                                 return rotate_and_place(itemstack, placer, pointed_thing)
221                         end
222                 end,
223         })
224
225         -- for replace ABM
226         if replace then
227                 minetest.register_node(":stairs:slab_" .. subname .. "upside_down", {
228                         replace_name = "stairs:slab_".. subname,
229                         groups = {slabs_replace = 1},
230                 })
231         end
232
233         if recipeitem then
234                 minetest.register_craft({
235                         output = "stairs:slab_" .. subname .. " 6",
236                         recipe = {
237                                 {recipeitem, recipeitem, recipeitem},
238                         },
239                 })
240
241                 -- Use 2 slabs to craft a full block again (1:1)
242                 minetest.register_craft({
243                         output = recipeitem,
244                         recipe = {
245                                 {"stairs:slab_" .. subname},
246                                 {"stairs:slab_" .. subname},
247                         },
248                 })
249
250                 -- Fuel
251                 local baseburntime = minetest.get_craft_result({
252                         method = "fuel",
253                         width = 1,
254                         items = {recipeitem}
255                 }).time
256                 if baseburntime > 0 then
257                         minetest.register_craft({
258                                 type = "fuel",
259                                 recipe = "stairs:slab_" .. subname,
260                                 burntime = math.floor(baseburntime * 0.5),
261                         })
262                 end
263         end
264 end
265
266
267 -- Optionally replace old "upside_down" nodes with new param2 versions.
268 -- Disabled by default.
269
270 if replace then
271         minetest.register_abm({
272                 label = "Slab replace",
273                 nodenames = {"group:slabs_replace"},
274                 interval = 16,
275                 chance = 1,
276                 action = function(pos, node)
277                         node.name = minetest.registered_nodes[node.name].replace_name
278                         node.param2 = node.param2 + 20
279                         if node.param2 == 21 then
280                                 node.param2 = 23
281                         elseif node.param2 == 23 then
282                                 node.param2 = 21
283                         end
284                         minetest.set_node(pos, node)
285                 end,
286         })
287 end
288
289
290 -- Register inner stair
291 -- Node will be called stairs:stair_inner_<subname>
292
293 function stairs.register_stair_inner(subname, recipeitem, groups, images,
294                 description, sounds, worldaligntex)
295         -- Set backface culling and world-aligned textures
296         local stair_images = {}
297         for i, image in ipairs(images) do
298                 if type(image) == "string" then
299                         stair_images[i] = {
300                                 name = image,
301                                 backface_culling = true,
302                         }
303                         if worldaligntex then
304                                 stair_images[i].align_style = "world"
305                         end
306                 else
307                         stair_images[i] = table.copy(image)
308                         if stair_images[i].backface_culling == nil then
309                                 stair_images[i].backface_culling = true
310                         end
311                         if worldaligntex and stair_images[i].align_style == nil then
312                                 stair_images[i].align_style = "world"
313                         end
314                 end
315         end
316         local new_groups = table.copy(groups)
317         new_groups.stair = 1
318         warn_if_exists("stairs:stair_inner_" .. subname)
319         minetest.register_node(":stairs:stair_inner_" .. subname, {
320                 description = "Inner " .. description,
321                 drawtype = "nodebox",
322                 tiles = stair_images,
323                 paramtype = "light",
324                 paramtype2 = "facedir",
325                 is_ground_content = false,
326                 groups = new_groups,
327                 sounds = sounds,
328                 node_box = {
329                         type = "fixed",
330                         fixed = {
331                                 {-0.5, -0.5, -0.5, 0.5, 0.0, 0.5},
332                                 {-0.5, 0.0, 0.0, 0.5, 0.5, 0.5},
333                                 {-0.5, 0.0, -0.5, 0.0, 0.5, 0.0},
334                         },
335                 },
336                 on_place = function(itemstack, placer, pointed_thing)
337                         if pointed_thing.type ~= "node" then
338                                 return itemstack
339                         end
340
341                         return rotate_and_place(itemstack, placer, pointed_thing)
342                 end,
343         })
344
345         if recipeitem then
346                 minetest.register_craft({
347                         output = "stairs:stair_inner_" .. subname .. " 7",
348                         recipe = {
349                                 {"", recipeitem, ""},
350                                 {recipeitem, "", recipeitem},
351                                 {recipeitem, recipeitem, recipeitem},
352                         },
353                 })
354
355                 -- Fuel
356                 local baseburntime = minetest.get_craft_result({
357                         method = "fuel",
358                         width = 1,
359                         items = {recipeitem}
360                 }).time
361                 if baseburntime > 0 then
362                         minetest.register_craft({
363                                 type = "fuel",
364                                 recipe = "stairs:stair_inner_" .. subname,
365                                 burntime = math.floor(baseburntime * 0.875),
366                         })
367                 end
368         end
369 end
370
371
372 -- Register outer stair
373 -- Node will be called stairs:stair_outer_<subname>
374
375 function stairs.register_stair_outer(subname, recipeitem, groups, images,
376                 description, sounds, worldaligntex)
377         -- Set backface culling and world-aligned textures
378         local stair_images = {}
379         for i, image in ipairs(images) do
380                 if type(image) == "string" then
381                         stair_images[i] = {
382                                 name = image,
383                                 backface_culling = true,
384                         }
385                         if worldaligntex then
386                                 stair_images[i].align_style = "world"
387                         end
388                 else
389                         stair_images[i] = table.copy(image)
390                         if stair_images[i].backface_culling == nil then
391                                 stair_images[i].backface_culling = true
392                         end
393                         if worldaligntex and stair_images[i].align_style == nil then
394                                 stair_images[i].align_style = "world"
395                         end
396                 end
397         end
398         local new_groups = table.copy(groups)
399         new_groups.stair = 1
400         warn_if_exists("stairs:stair_outer_" .. subname)
401         minetest.register_node(":stairs:stair_outer_" .. subname, {
402                 description = "Outer " .. description,
403                 drawtype = "nodebox",
404                 tiles = stair_images,
405                 paramtype = "light",
406                 paramtype2 = "facedir",
407                 is_ground_content = false,
408                 groups = new_groups,
409                 sounds = sounds,
410                 node_box = {
411                         type = "fixed",
412                         fixed = {
413                                 {-0.5, -0.5, -0.5, 0.5, 0.0, 0.5},
414                                 {-0.5, 0.0, 0.0, 0.0, 0.5, 0.5},
415                         },
416                 },
417                 on_place = function(itemstack, placer, pointed_thing)
418                         if pointed_thing.type ~= "node" then
419                                 return itemstack
420                         end
421
422                         return rotate_and_place(itemstack, placer, pointed_thing)
423                 end,
424         })
425
426         if recipeitem then
427                 minetest.register_craft({
428                         output = "stairs:stair_outer_" .. subname .. " 6",
429                         recipe = {
430                                 {"", recipeitem, ""},
431                                 {recipeitem, recipeitem, recipeitem},
432                         },
433                 })
434
435                 -- Fuel
436                 local baseburntime = minetest.get_craft_result({
437                         method = "fuel",
438                         width = 1,
439                         items = {recipeitem}
440                 }).time
441                 if baseburntime > 0 then
442                         minetest.register_craft({
443                                 type = "fuel",
444                                 recipe = "stairs:stair_outer_" .. subname,
445                                 burntime = math.floor(baseburntime * 0.625),
446                         })
447                 end
448         end
449 end
450
451
452 -- Stair/slab registration function.
453 -- Nodes will be called stairs:{stair,slab}_<subname>
454
455 function stairs.register_stair_and_slab(subname, recipeitem, groups, images,
456                 desc_stair, desc_slab, sounds, worldaligntex)
457         stairs.register_stair(subname, recipeitem, groups, images, desc_stair,
458                 sounds, worldaligntex)
459         stairs.register_stair_inner(subname, recipeitem, groups, images, desc_stair,
460                 sounds, worldaligntex)
461         stairs.register_stair_outer(subname, recipeitem, groups, images, desc_stair,
462                 sounds, worldaligntex)
463         stairs.register_slab(subname, recipeitem, groups, images, desc_slab,
464                 sounds, worldaligntex)
465 end
466
467
468 -- Register default stairs and slabs
469
470 stairs.register_stair_and_slab(
471         "wood",
472         "default:wood",
473         {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
474         {"default_wood.png"},
475         "Wooden Stair",
476         "Wooden Slab",
477         default.node_sound_wood_defaults(),
478         false
479 )
480
481 stairs.register_stair_and_slab(
482         "junglewood",
483         "default:junglewood",
484         {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
485         {"default_junglewood.png"},
486         "Jungle Wood Stair",
487         "Jungle Wood Slab",
488         default.node_sound_wood_defaults(),
489         false
490 )
491
492 stairs.register_stair_and_slab(
493         "pine_wood",
494         "default:pine_wood",
495         {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3},
496         {"default_pine_wood.png"},
497         "Pine Wood Stair",
498         "Pine Wood Slab",
499         default.node_sound_wood_defaults(),
500         false
501 )
502
503 stairs.register_stair_and_slab(
504         "acacia_wood",
505         "default:acacia_wood",
506         {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
507         {"default_acacia_wood.png"},
508         "Acacia Wood Stair",
509         "Acacia Wood Slab",
510         default.node_sound_wood_defaults(),
511         false
512 )
513
514 stairs.register_stair_and_slab(
515         "aspen_wood",
516         "default:aspen_wood",
517         {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3},
518         {"default_aspen_wood.png"},
519         "Aspen Wood Stair",
520         "Aspen Wood Slab",
521         default.node_sound_wood_defaults(),
522         false
523 )
524
525 stairs.register_stair_and_slab(
526         "stone",
527         "default:stone",
528         {cracky = 3},
529         {"default_stone.png"},
530         "Stone Stair",
531         "Stone Slab",
532         default.node_sound_stone_defaults(),
533         true
534 )
535
536 stairs.register_stair_and_slab(
537         "cobble",
538         "default:cobble",
539         {cracky = 3},
540         {"default_cobble.png"},
541         "Cobblestone Stair",
542         "Cobblestone Slab",
543         default.node_sound_stone_defaults(),
544         true
545 )
546
547 stairs.register_stair_and_slab(
548         "mossycobble",
549         "default:mossycobble",
550         {cracky = 3},
551         {"default_mossycobble.png"},
552         "Mossy Cobblestone Stair",
553         "Mossy Cobblestone Slab",
554         default.node_sound_stone_defaults(),
555         true
556 )
557
558 stairs.register_stair_and_slab(
559         "stonebrick",
560         "default:stonebrick",
561         {cracky = 2},
562         {"default_stone_brick.png"},
563         "Stone Brick Stair",
564         "Stone Brick Slab",
565         default.node_sound_stone_defaults(),
566         false
567 )
568
569 stairs.register_stair_and_slab(
570         "stone_block",
571         "default:stone_block",
572         {cracky = 2},
573         {"default_stone_block.png"},
574         "Stone Block Stair",
575         "Stone Block Slab",
576         default.node_sound_stone_defaults(),
577         true
578 )
579
580 stairs.register_stair_and_slab(
581         "desert_stone",
582         "default:desert_stone",
583         {cracky = 3},
584         {"default_desert_stone.png"},
585         "Desert Stone Stair",
586         "Desert Stone Slab",
587         default.node_sound_stone_defaults(),
588         true
589 )
590
591 stairs.register_stair_and_slab(
592         "desert_cobble",
593         "default:desert_cobble",
594         {cracky = 3},
595         {"default_desert_cobble.png"},
596         "Desert Cobblestone Stair",
597         "Desert Cobblestone Slab",
598         default.node_sound_stone_defaults(),
599         true
600 )
601
602 stairs.register_stair_and_slab(
603         "desert_stonebrick",
604         "default:desert_stonebrick",
605         {cracky = 2},
606         {"default_desert_stone_brick.png"},
607         "Desert Stone Brick Stair",
608         "Desert Stone Brick Slab",
609         default.node_sound_stone_defaults(),
610         false
611 )
612
613 stairs.register_stair_and_slab(
614         "desert_stone_block",
615         "default:desert_stone_block",
616         {cracky = 2},
617         {"default_desert_stone_block.png"},
618         "Desert Stone Block Stair",
619         "Desert Stone Block Slab",
620         default.node_sound_stone_defaults(),
621         true
622 )
623
624 stairs.register_stair_and_slab(
625         "sandstone",
626         "default:sandstone",
627         {crumbly = 1, cracky = 3},
628         {"default_sandstone.png"},
629         "Sandstone Stair",
630         "Sandstone Slab",
631         default.node_sound_stone_defaults(),
632         true
633 )
634
635 stairs.register_stair_and_slab(
636         "sandstonebrick",
637         "default:sandstonebrick",
638         {cracky = 2},
639         {"default_sandstone_brick.png"},
640         "Sandstone Brick Stair",
641         "Sandstone Brick Slab",
642         default.node_sound_stone_defaults(),
643         false
644 )
645
646 stairs.register_stair_and_slab(
647         "sandstone_block",
648         "default:sandstone_block",
649         {cracky = 2},
650         {"default_sandstone_block.png"},
651         "Sandstone Block Stair",
652         "Sandstone Block Slab",
653         default.node_sound_stone_defaults(),
654         true
655 )
656
657 stairs.register_stair_and_slab(
658         "desert_sandstone",
659         "default:desert_sandstone",
660         {crumbly = 1, cracky = 3},
661         {"default_desert_sandstone.png"},
662         "Desert Sandstone Stair",
663         "Desert Sandstone Slab",
664         default.node_sound_stone_defaults(),
665         true
666 )
667
668 stairs.register_stair_and_slab(
669         "desert_sandstone_brick",
670         "default:desert_sandstone_brick",
671         {cracky = 2},
672         {"default_desert_sandstone_brick.png"},
673         "Desert Sandstone Brick Stair",
674         "Desert Sandstone Brick Slab",
675         default.node_sound_stone_defaults(),
676         false
677 )
678
679 stairs.register_stair_and_slab(
680         "desert_sandstone_block",
681         "default:desert_sandstone_block",
682         {cracky = 2},
683         {"default_desert_sandstone_block.png"},
684         "Desert Sandstone Block Stair",
685         "Desert Sandstone Block Slab",
686         default.node_sound_stone_defaults(),
687         true
688 )
689
690 stairs.register_stair_and_slab(
691         "silver_sandstone",
692         "default:silver_sandstone",
693         {crumbly = 1, cracky = 3},
694         {"default_silver_sandstone.png"},
695         "Silver Sandstone Stair",
696         "Silver Sandstone Slab",
697         default.node_sound_stone_defaults(),
698         true
699 )
700
701 stairs.register_stair_and_slab(
702         "silver_sandstone_brick",
703         "default:silver_sandstone_brick",
704         {cracky = 2},
705         {"default_silver_sandstone_brick.png"},
706         "Silver Sandstone Brick Stair",
707         "Silver Sandstone Brick Slab",
708         default.node_sound_stone_defaults(),
709         false
710 )
711
712 stairs.register_stair_and_slab(
713         "silver_sandstone_block",
714         "default:silver_sandstone_block",
715         {cracky = 2},
716         {"default_silver_sandstone_block.png"},
717         "Silver Sandstone Block Stair",
718         "Silver Sandstone Block Slab",
719         default.node_sound_stone_defaults(),
720         true
721 )
722
723 stairs.register_stair_and_slab(
724         "obsidian",
725         "default:obsidian",
726         {cracky = 1, level = 2},
727         {"default_obsidian.png"},
728         "Obsidian Stair",
729         "Obsidian Slab",
730         default.node_sound_stone_defaults(),
731         true
732 )
733
734 stairs.register_stair_and_slab(
735         "obsidianbrick",
736         "default:obsidianbrick",
737         {cracky = 1, level = 2},
738         {"default_obsidian_brick.png"},
739         "Obsidian Brick Stair",
740         "Obsidian Brick Slab",
741         default.node_sound_stone_defaults(),
742         false
743 )
744
745 stairs.register_stair_and_slab(
746         "obsidian_block",
747         "default:obsidian_block",
748         {cracky = 1, level = 2},
749         {"default_obsidian_block.png"},
750         "Obsidian Block Stair",
751         "Obsidian Block Slab",
752         default.node_sound_stone_defaults(),
753         true
754 )
755
756 stairs.register_stair_and_slab(
757         "brick",
758         "default:brick",
759         {cracky = 3},
760         {"default_brick.png"},
761         "Brick Stair",
762         "Brick Slab",
763         default.node_sound_stone_defaults(),
764         false
765 )
766
767 stairs.register_stair_and_slab(
768         "steelblock",
769         "default:steelblock",
770         {cracky = 1, level = 2},
771         {"default_steel_block.png"},
772         "Steel Block Stair",
773         "Steel Block Slab",
774         default.node_sound_metal_defaults(),
775         true
776 )
777
778 stairs.register_stair_and_slab(
779         "tinblock",
780         "default:tinblock",
781         {cracky = 1, level = 2},
782         {"default_tin_block.png"},
783         "Tin Block Stair",
784         "Tin Block Slab",
785         default.node_sound_metal_defaults(),
786         true
787 )
788
789 stairs.register_stair_and_slab(
790         "copperblock",
791         "default:copperblock",
792         {cracky = 1, level = 2},
793         {"default_copper_block.png"},
794         "Copper Block Stair",
795         "Copper Block Slab",
796         default.node_sound_metal_defaults(),
797         true
798 )
799
800 stairs.register_stair_and_slab(
801         "bronzeblock",
802         "default:bronzeblock",
803         {cracky = 1, level = 2},
804         {"default_bronze_block.png"},
805         "Bronze Block Stair",
806         "Bronze Block Slab",
807         default.node_sound_metal_defaults(),
808         true
809 )
810
811 stairs.register_stair_and_slab(
812         "goldblock",
813         "default:goldblock",
814         {cracky = 1},
815         {"default_gold_block.png"},
816         "Gold Block Stair",
817         "Gold Block Slab",
818         default.node_sound_metal_defaults(),
819         true
820 )
821
822 stairs.register_stair_and_slab(
823         "ice",
824         "default:ice",
825         {cracky = 3, cools_lava = 1, slippery = 3},
826         {"default_ice.png"},
827         "Ice Stair",
828         "Ice Slab",
829         default.node_sound_glass_defaults(),
830         true
831 )
832
833 stairs.register_stair_and_slab(
834         "snowblock",
835         "default:snowblock",
836         {crumbly = 3, cools_lava = 1, snowy = 1},
837         {"default_snow.png"},
838         "Snow Block Stair",
839         "Snow Block Slab",
840         default.node_sound_snow_defaults(),
841         true
842 )
843
844 -- Glass stair nodes need to be registered individually to utilize specialized textures.
845
846 stairs.register_stair(
847         "glass",
848         "default:glass",
849         {cracky = 3},
850         {"stairs_glass_split.png", "default_glass.png",
851         "stairs_glass_stairside.png^[transformFX", "stairs_glass_stairside.png",
852         "default_glass.png", "stairs_glass_split.png"},
853         "Glass Stair",
854         default.node_sound_glass_defaults(),
855         false
856 )
857
858 stairs.register_slab(
859         "glass",
860         "default:glass",
861         {cracky = 3},
862         {"default_glass.png", "default_glass.png", "stairs_glass_split.png"},
863         "Glass Slab",
864         default.node_sound_glass_defaults(),
865         false
866 )
867
868 stairs.register_stair_inner(
869         "glass",
870         "default:glass",
871         {cracky = 3},
872         {"stairs_glass_stairside.png^[transformR270", "default_glass.png",
873         "stairs_glass_stairside.png^[transformFX", "default_glass.png",
874         "default_glass.png", "stairs_glass_stairside.png"},
875         "Glass Stair",
876         default.node_sound_glass_defaults(),
877         false
878 )
879
880 stairs.register_stair_outer(
881         "glass",
882         "default:glass",
883         {cracky = 3},
884         {"stairs_glass_stairside.png^[transformR90", "default_glass.png",
885         "stairs_glass_outer_stairside.png", "stairs_glass_stairside.png",
886         "stairs_glass_stairside.png^[transformR90","stairs_glass_outer_stairside.png"},
887         "Glass Stair",
888         default.node_sound_glass_defaults(),
889         false
890 )
891
892 stairs.register_stair(
893         "obsidian_glass",
894         "default:obsidian_glass",
895         {cracky = 3},
896         {"stairs_obsidian_glass_split.png", "default_obsidian_glass.png",
897         "stairs_obsidian_glass_stairside.png^[transformFX", "stairs_obsidian_glass_stairside.png",
898         "default_obsidian_glass.png", "stairs_obsidian_glass_split.png"},
899         "Obsidian Glass Stair",
900         default.node_sound_glass_defaults(),
901         false
902 )
903
904 stairs.register_slab(
905         "obsidian_glass",
906         "default:obsidian_glass",
907         {cracky = 3},
908         {"default_obsidian_glass.png", "default_obsidian_glass.png", "stairs_obsidian_glass_split.png"},
909         "Obsidian Glass Slab",
910         default.node_sound_glass_defaults(),
911         false
912 )
913
914 stairs.register_stair_inner(
915         "obsidian_glass",
916         "default:obsidian_glass",
917         {cracky = 3},
918         {"stairs_obsidian_glass_stairside.png^[transformR270", "default_obsidian_glass.png",
919         "stairs_obsidian_glass_stairside.png^[transformFX", "default_obsidian_glass.png",
920         "default_obsidian_glass.png", "stairs_obsidian_glass_stairside.png"},
921         "Obsidian Glass Stair",
922         default.node_sound_glass_defaults(),
923         false
924 )
925
926 stairs.register_stair_outer(
927         "obsidian_glass",
928         "default:obsidian_glass",
929         {cracky = 3},
930         {"stairs_obsidian_glass_stairside.png^[transformR90", "default_obsidian_glass.png",
931         "stairs_obsidian_glass_outer_stairside.png", "stairs_obsidian_glass_stairside.png",
932         "stairs_obsidian_glass_stairside.png^[transformR90","stairs_obsidian_glass_outer_stairside.png"},
933         "Obsidian Glass Stair",
934         default.node_sound_glass_defaults(),
935         false
936 )