1 -- Minetest 0.4 mod: stairs
2 -- See README.txt for licensing and other information.
5 -- Global namespace for functions
10 -- Register aliases for new pine node names
12 minetest.register_alias("stairs:stair_pinewood", "stairs:stair_pine_wood")
13 minetest.register_alias("stairs:slab_pinewood", "stairs:slab_pine_wood")
16 -- Get setting for replace ABM
18 local replace = minetest.setting_getbool("enable_stairs_replace_abm")
20 local function rotate_and_place(itemstack, placer, pointed_thing)
21 local p0 = pointed_thing.under
22 local p1 = pointed_thing.above
25 local placer_pos = placer:getpos()
27 param2 = minetest.dir_to_facedir(vector.subtract(p1, placer_pos))
30 local finepos = minetest.pointed_thing_to_face_pos(placer, pointed_thing)
31 local fpos = finepos.y % 1
33 if p0.y - 1 == p1.y or (fpos > 0 and fpos < 0.5)
34 or (fpos < -0.5 and fpos > -0.999999999) then
38 elseif param2 == 23 then
42 return minetest.item_place(itemstack, placer, pointed_thing, param2)
46 -- Node will be called stairs:stair_<subname>
48 function stairs.register_stair(subname, recipeitem, groups, images, description, sounds)
50 minetest.register_node(":stairs:stair_" .. subname, {
51 description = description,
53 mesh = "stairs_stair.obj",
56 paramtype2 = "facedir",
57 is_ground_content = false,
63 {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
64 {-0.5, 0, 0, 0.5, 0.5, 0.5},
70 {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
71 {-0.5, 0, 0, 0.5, 0.5, 0.5},
74 on_place = function(itemstack, placer, pointed_thing)
75 if pointed_thing.type ~= "node" then
79 return rotate_and_place(itemstack, placer, pointed_thing)
85 minetest.register_node(":stairs:stair_" .. subname .. "upside_down", {
86 replace_name = "stairs:stair_" .. subname,
87 groups = {slabs_replace = 1},
92 minetest.register_craft({
93 output = 'stairs:stair_' .. subname .. ' 8',
96 {recipeitem, recipeitem, ""},
97 {recipeitem, recipeitem, recipeitem},
101 -- Flipped recipe for the silly minecrafters
102 minetest.register_craft({
103 output = 'stairs:stair_' .. subname .. ' 8',
105 {"", "", recipeitem},
106 {"", recipeitem, recipeitem},
107 {recipeitem, recipeitem, recipeitem},
112 local baseburntime = minetest.get_craft_result({
117 if baseburntime > 0 then
118 minetest.register_craft({
120 recipe = 'stairs:stair_' .. subname,
121 burntime = math.floor(baseburntime * 0.75),
128 -- Slab facedir to placement 6d matching table
129 local slab_trans_dir = {[0] = 8, 0, 2, 1, 3, 4}
132 -- Node will be called stairs:slab_<subname>
134 function stairs.register_slab(subname, recipeitem, groups, images, description, sounds)
136 minetest.register_node(":stairs:slab_" .. subname, {
137 description = description,
138 drawtype = "nodebox",
141 paramtype2 = "facedir",
142 is_ground_content = false,
147 fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
149 on_place = function(itemstack, placer, pointed_thing)
150 local under = minetest.get_node(pointed_thing.under)
151 local wield_item = itemstack:get_name()
152 local creative_enabled = (creative and creative.is_enabled_for
153 and creative.is_enabled_for(placer:get_player_name()))
155 if under and under.name:find("stairs:slab_") then
156 -- place slab using under node orientation
157 local dir = minetest.dir_to_facedir(vector.subtract(
158 pointed_thing.above, pointed_thing.under), true)
160 local p2 = under.param2
162 -- combine two slabs if possible
163 if slab_trans_dir[math.floor(p2 / 4)] == dir
164 and wield_item == under.name then
166 if not recipeitem then
169 local player_name = placer:get_player_name()
170 if minetest.is_protected(pointed_thing.under, player_name) and not
171 minetest.check_player_privs(placer, "protection_bypass") then
172 minetest.record_protection_violation(pointed_thing.under,
176 minetest.set_node(pointed_thing.under, {name = recipeitem, param2 = p2})
177 if not creative_enabled then
178 itemstack:take_item()
183 -- Placing a slab on an upside down slab should make it right-side up.
184 if p2 >= 20 and dir == 8 then
186 -- same for the opposite case: slab below normal slab
187 elseif p2 <= 3 and dir == 4 then
191 -- else attempt to place node with proper param2
192 minetest.item_place_node(ItemStack(wield_item), placer, pointed_thing, p2)
193 if not creative_enabled then
194 itemstack:take_item()
198 return rotate_and_place(itemstack, placer, pointed_thing)
205 minetest.register_node(":stairs:slab_" .. subname .. "upside_down", {
206 replace_name = "stairs:slab_".. subname,
207 groups = {slabs_replace = 1},
212 minetest.register_craft({
213 output = 'stairs:slab_' .. subname .. ' 6',
215 {recipeitem, recipeitem, recipeitem},
220 local baseburntime = minetest.get_craft_result({
225 if baseburntime > 0 then
226 minetest.register_craft({
228 recipe = 'stairs:slab_' .. subname,
229 burntime = math.floor(baseburntime * 0.5),
236 -- Optionally replace old "upside_down" nodes with new param2 versions.
237 -- Disabled by default.
240 minetest.register_abm({
241 label = "Slab replace",
242 nodenames = {"group:slabs_replace"},
245 action = function(pos, node)
246 node.name = minetest.registered_nodes[node.name].replace_name
247 node.param2 = node.param2 + 20
248 if node.param2 == 21 then
250 elseif node.param2 == 23 then
253 minetest.set_node(pos, node)
259 -- Stair/slab registration function.
260 -- Nodes will be called stairs:{stair,slab}_<subname>
262 function stairs.register_stair_and_slab(subname, recipeitem,
263 groups, images, desc_stair, desc_slab, sounds)
264 stairs.register_stair(subname, recipeitem, groups, images, desc_stair, sounds)
265 stairs.register_slab(subname, recipeitem, groups, images, desc_slab, sounds)
269 -- Register default stairs and slabs
271 stairs.register_stair_and_slab(
274 {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
275 {"default_wood.png"},
278 default.node_sound_wood_defaults()
281 stairs.register_stair_and_slab(
283 "default:junglewood",
284 {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
285 {"default_junglewood.png"},
288 default.node_sound_wood_defaults()
291 stairs.register_stair_and_slab(
294 {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3},
295 {"default_pine_wood.png"},
298 default.node_sound_wood_defaults()
301 stairs.register_stair_and_slab(
303 "default:acacia_wood",
304 {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
305 {"default_acacia_wood.png"},
308 default.node_sound_wood_defaults()
311 stairs.register_stair_and_slab(
313 "default:aspen_wood",
314 {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3},
315 {"default_aspen_wood.png"},
318 default.node_sound_wood_defaults()
321 stairs.register_stair_and_slab(
325 {"default_stone.png"},
328 default.node_sound_stone_defaults()
331 stairs.register_stair_and_slab(
335 {"default_cobble.png"},
338 default.node_sound_stone_defaults()
341 stairs.register_stair_and_slab(
345 {"default_mossycobble.png"},
346 "Mossy Cobblestone Stair",
347 "Mossy Cobblestone Slab",
348 default.node_sound_stone_defaults()
351 stairs.register_stair_and_slab(
353 "default:stonebrick",
355 {"default_stone_brick.png"},
358 default.node_sound_stone_defaults()
361 stairs.register_stair_and_slab(
363 "default:stone_block",
365 {"default_stone_block.png"},
368 default.node_sound_stone_defaults()
371 stairs.register_stair_and_slab(
373 "default:desert_stone",
375 {"default_desert_stone.png"},
376 "Desert Stone Stair",
378 default.node_sound_stone_defaults()
381 stairs.register_stair_and_slab(
383 "default:desert_cobble",
385 {"default_desert_cobble.png"},
386 "Desert Cobblestone Stair",
387 "Desert Cobblestone Slab",
388 default.node_sound_stone_defaults()
391 stairs.register_stair_and_slab(
393 "default:desert_stonebrick",
395 {"default_desert_stone_brick.png"},
396 "Desert Stone Brick Stair",
397 "Desert Stone Brick Slab",
398 default.node_sound_stone_defaults()
401 stairs.register_stair_and_slab(
402 "desert_stone_block",
403 "default:desert_stone_block",
405 {"default_desert_stone_block.png"},
406 "Desert Stone Block Stair",
407 "Desert Stone Block Slab",
408 default.node_sound_stone_defaults()
411 stairs.register_stair_and_slab(
414 {crumbly = 1, cracky = 3},
415 {"default_sandstone.png"},
418 default.node_sound_stone_defaults()
421 stairs.register_stair_and_slab(
423 "default:sandstonebrick",
425 {"default_sandstone_brick.png"},
426 "Sandstone Brick Stair",
427 "Sandstone Brick Slab",
428 default.node_sound_stone_defaults()
431 stairs.register_stair_and_slab(
433 "default:sandstone_block",
435 {"default_sandstone_block.png"},
436 "Sandstone Block Stair",
437 "Sandstone Block Slab",
438 default.node_sound_stone_defaults()
441 stairs.register_stair_and_slab(
443 "default:desert_sandstone",
444 {crumbly = 1, cracky = 3},
445 {"default_desert_sandstone.png"},
446 "Desert Sandstone Stair",
447 "Desert Sandstone Slab",
448 default.node_sound_stone_defaults()
451 stairs.register_stair_and_slab(
452 "desert_sandstone_brick",
453 "default:desert_sandstone_brick",
455 {"default_desert_sandstone_brick.png"},
456 "Desert Sandstone Brick Stair",
457 "Desert Sandstone Brick Slab",
458 default.node_sound_stone_defaults()
461 stairs.register_stair_and_slab(
462 "desert_sandstone_block",
463 "default:desert_sandstone_block",
465 {"default_desert_sandstone_block.png"},
466 "Desert Sandstone Block Stair",
467 "Desert Sandstone Block Slab",
468 default.node_sound_stone_defaults()
471 stairs.register_stair_and_slab(
473 "default:silver_sandstone",
474 {crumbly = 1, cracky = 3},
475 {"default_silver_sandstone.png"},
476 "Silver Sandstone Stair",
477 "Silver Sandstone Slab",
478 default.node_sound_stone_defaults()
481 stairs.register_stair_and_slab(
482 "silver_sandstone_brick",
483 "default:silver_sandstone_brick",
485 {"default_silver_sandstone_brick.png"},
486 "Silver Sandstone Brick Stair",
487 "Silver Sandstone Brick Slab",
488 default.node_sound_stone_defaults()
491 stairs.register_stair_and_slab(
492 "silver_sandstone_block",
493 "default:silver_sandstone_block",
495 {"default_silver_sandstone_block.png"},
496 "Silver Sandstone Block Stair",
497 "Silver Sandstone Block Slab",
498 default.node_sound_stone_defaults()
501 stairs.register_stair_and_slab(
504 {cracky = 1, level = 2},
505 {"default_obsidian.png"},
508 default.node_sound_stone_defaults()
511 stairs.register_stair_and_slab(
513 "default:obsidianbrick",
514 {cracky = 1, level = 2},
515 {"default_obsidian_brick.png"},
516 "Obsidian Brick Stair",
517 "Obsidian Brick Slab",
518 default.node_sound_stone_defaults()
521 stairs.register_stair_and_slab(
523 "default:obsidian_block",
524 {cracky = 1, level = 2},
525 {"default_obsidian_block.png"},
526 "Obsidian Block Stair",
527 "Obsidian Block Slab",
528 default.node_sound_stone_defaults()
531 stairs.register_stair_and_slab(
535 {"default_brick.png"},
538 default.node_sound_stone_defaults()
541 stairs.register_stair_and_slab(
544 {snappy = 3, flammable = 4},
545 {"farming_straw.png"},
548 default.node_sound_leaves_defaults()
551 stairs.register_stair_and_slab(
553 "default:steelblock",
554 {cracky = 1, level = 2},
555 {"default_steel_block.png"},
558 default.node_sound_metal_defaults()
561 stairs.register_stair_and_slab(
563 "default:copperblock",
564 {cracky = 1, level = 2},
565 {"default_copper_block.png"},
566 "Copper Block Stair",
568 default.node_sound_metal_defaults()
571 stairs.register_stair_and_slab(
573 "default:bronzeblock",
574 {cracky = 1, level = 2},
575 {"default_bronze_block.png"},
576 "Bronze Block Stair",
578 default.node_sound_metal_defaults()
581 stairs.register_stair_and_slab(
585 {"default_gold_block.png"},
588 default.node_sound_metal_defaults()