Stairs: Improve stair and slab rotation on placement
authorMarkuBu <markus.burrer@gmail.com>
Tue, 11 Apr 2017 06:51:13 +0000 (08:51 +0200)
committerparamat <mat.gregory@virginmedia.com>
Tue, 11 Apr 2017 07:33:30 +0000 (08:33 +0100)
Slabs are placed horizontal instead of vertical, even if they are
placed on a wall.
Slabs are rotated automatically if they are placed to another slab,
no matter which material.
Slabs are placed at the lower position if the placer points into
the lower half of the pointed node and to the upper position if
pointed to the upper half.
Stairs are placed normal if the placer points to the lower half of
the pointed node and rotated upside down if pointed to the upper half.

mods/stairs/init.lua

index 1379c8c0cb45d63c5961b75a71c9c5681972da3e..835b219345ff841f42c46f0b741ca2f5eed28f73 100644 (file)
@@ -17,6 +17,30 @@ minetest.register_alias("stairs:slab_pinewood", "stairs:slab_pine_wood")
 
 local replace = minetest.setting_getbool("enable_stairs_replace_abm")
 
+local function rotate_and_place(itemstack, placer, pointed_thing)
+       local p0 = pointed_thing.under
+       local p1 = pointed_thing.above
+       local param2 = 0
+
+       local placer_pos = placer:getpos()
+       if placer_pos then
+               param2 = minetest.dir_to_facedir(vector.subtract(p1, placer_pos))
+       end
+
+       local finepos = minetest.pointed_thing_to_face_pos(placer, pointed_thing)
+       local fpos = finepos.y % 1
+
+       if p0.y - 1 == p1.y or (fpos > 0 and fpos < 0.5)
+                       or (fpos < -0.5 and fpos > -0.999999999) then
+               param2 = param2 + 20
+               if param2 == 21 then
+                       param2 = 23
+               elseif param2 == 23 then
+                       param2 = 21
+               end
+       end
+       return minetest.item_place(itemstack, placer, pointed_thing, param2)
+end
 
 -- Register stairs.
 -- Node will be called stairs:stair_<subname>
@@ -52,30 +76,7 @@ function stairs.register_stair(subname, recipeitem, groups, images, description,
                                return itemstack
                        end
 
-                       local p0 = pointed_thing.under
-                       local p1 = pointed_thing.above
-                       local param2 = 0
-
-                       local placer_pos = placer:getpos()
-                       if placer_pos then
-                               local dir = {
-                                       x = p1.x - placer_pos.x,
-                                       y = p1.y - placer_pos.y,
-                                       z = p1.z - placer_pos.z
-                               }
-                               param2 = minetest.dir_to_facedir(dir)
-                       end
-
-                       if p0.y - 1 == p1.y then
-                               param2 = param2 + 20
-                               if param2 == 21 then
-                                       param2 = 23
-                               elseif param2 == 23 then
-                                       param2 = 21
-                               end
-                       end
-
-                       return minetest.item_place(itemstack, placer, pointed_thing, param2)
+                       return rotate_and_place(itemstack, placer, pointed_thing)
                end,
        })
 
@@ -126,8 +127,6 @@ end
 
 -- Slab facedir to placement 6d matching table
 local slab_trans_dir = {[0] = 8, 0, 2, 1, 3, 4}
--- Slab facedir when placing initial slab against other surface
-local slab_trans_dir_place = {[0] = 0, 20, 12, 16, 4, 8}
 
 -- Register slabs.
 -- Node will be called stairs:slab_<subname>
@@ -153,7 +152,7 @@ function stairs.register_slab(subname, recipeitem, groups, images, description,
                        local creative_enabled = (creative and creative.is_enabled_for
                                        and creative.is_enabled_for(placer:get_player_name()))
 
-                       if under and wield_item == under.name then
+                       if under and under.name:find("stairs:slab_") then
                                -- place slab using under node orientation
                                local dir = minetest.dir_to_facedir(vector.subtract(
                                        pointed_thing.above, pointed_thing.under), true)
@@ -161,7 +160,9 @@ function stairs.register_slab(subname, recipeitem, groups, images, description,
                                local p2 = under.param2
 
                                -- combine two slabs if possible
-                               if slab_trans_dir[math.floor(p2 / 4)] == dir then
+                               if slab_trans_dir[math.floor(p2 / 4)] == dir
+                                               and wield_item == under.name then
+
                                        if not recipeitem then
                                                return itemstack
                                        end
@@ -194,16 +195,7 @@ function stairs.register_slab(subname, recipeitem, groups, images, description,
                                end
                                return itemstack
                        else
-                               -- place slab using look direction of player
-                               local dir = minetest.dir_to_wallmounted(vector.subtract(
-                                       pointed_thing.above, pointed_thing.under), true)
-
-                               local rot = slab_trans_dir_place[dir]
-                               if rot == 0 or rot == 20 then
-                                       rot = rot + minetest.dir_to_facedir(placer:get_look_dir())
-                               end
-
-                               return minetest.item_place(itemstack, placer, pointed_thing, rot)
+                               return rotate_and_place(itemstack, placer, pointed_thing)
                        end
                end,
        })