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