3 -- Wrapper around mintest.pointed_thing_to_face_pos.
4 local function get_fpos(placer
, pointed_thing
)
6 -- Workaround: minetest.pointed_thing_to_face_pos crashes in MT 0.4.16 if
7 -- pointed_thing.under and pointed_thing.above are equal
8 -- FIXME: Remove this when MT got fixed.
9 if not vector
.equals(pointed_thing
.under
, pointed_thing
.above
) then
10 -- The happy case: Everything is normal
11 local finepos
= minetest
.pointed_thing_to_face_pos(placer
, pointed_thing
)
14 -- Fallback if both above and under are equal
20 local function place_slab_normal(itemstack
, placer
, pointed_thing
)
21 -- Use pointed node's on_rightclick function first, if present
22 local node
= minetest
.get_node(pointed_thing
.under
)
23 if placer
and not placer
:get_player_control().sneak
then
24 if minetest
.registered_nodes
[node
.name
] and minetest
.registered_nodes
[node
.name
].on_rightclick
then
25 return minetest
.registered_nodes
[node
.name
].on_rightclick(pointed_thing
.under
, node
, placer
, itemstack
) or itemstack
29 local p0
= pointed_thing
.under
30 local p1
= pointed_thing
.above
32 local placer_pos
= placer
:get_pos()
34 local fpos
= get_fpos(placer
, pointed_thing
)
36 local place
= ItemStack(itemstack
)
37 local origname
= itemstack
:get_name()
38 if p0
.y
- 1 == p1
.y
or (fpos
> 0 and fpos
< 0.5)
39 or (fpos
< -0.5 and fpos
> -0.999999999) then
40 place
:set_name(origname
.. "_top")
42 local ret
= minetest
.item_place(place
, placer
, pointed_thing
, 0)
43 ret
:set_name(origname
)
47 local function place_stair(itemstack
, placer
, pointed_thing
)
48 -- Use pointed node's on_rightclick function first, if present
49 local node
= minetest
.get_node(pointed_thing
.under
)
50 if placer
and not placer
:get_player_control().sneak
then
51 if minetest
.registered_nodes
[node
.name
] and minetest
.registered_nodes
[node
.name
].on_rightclick
then
52 return minetest
.registered_nodes
[node
.name
].on_rightclick(pointed_thing
.under
, node
, placer
, itemstack
) or itemstack
56 local p0
= pointed_thing
.under
57 local p1
= pointed_thing
.above
60 local placer_pos
= placer
:get_pos()
62 param2
= minetest
.dir_to_facedir(vector
.subtract(p1
, placer_pos
))
65 local fpos
= get_fpos(placer
, pointed_thing
)
67 if p0
.y
- 1 == p1
.y
or (fpos
> 0 and fpos
< 0.5)
68 or (fpos
< -0.5 and fpos
> -0.999999999) then
72 elseif param2
== 23 then
76 return minetest
.item_place(itemstack
, placer
, pointed_thing
, param2
)
80 -- Node will be called mcl_stairs:stair_<subname>
82 function mcl_stairs
.register_stair(subname
, recipeitem
, groups
, images
, description
, sounds
, hardness
, corner_stair_texture_override
)
84 groups
.building_block
= 1
88 images
= minetest
.registered_items
[recipeitem
].tiles
91 groups
= minetest
.registered_items
[recipeitem
].groups
94 sounds
= minetest
.registered_items
[recipeitem
].sounds
97 hardness
= minetest
.registered_items
[recipeitem
]._mcl_hardness
101 minetest
.register_node(":mcl_stairs:stair_" .. subname
, {
102 description
= description
,
103 _doc_items_longdesc
= "Stairs are useful to reach higher places by walking over them; jumping is not required. Placing stairs in a corner pattern will create corner stairs. Stairs placed on the bottom or at the upper half of the side of a block will be placed upside down.",
105 mesh
= "stairs_stair.obj",
108 paramtype2
= "facedir",
109 is_ground_content
= false,
115 {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
116 {-0.5, 0, 0, 0.5, 0.5, 0.5},
122 {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
123 {-0.5, 0, 0, 0.5, 0.5, 0.5},
126 on_place
= function(itemstack
, placer
, pointed_thing
)
127 if pointed_thing
.type ~= "node" then
131 return place_stair(itemstack
, placer
, pointed_thing
)
133 _mcl_hardness
= hardness
,
137 minetest
.register_craft({
138 output
= 'mcl_stairs:stair_' .. subname
.. ' 4',
140 {recipeitem
, "", ""},
141 {recipeitem
, recipeitem
, ""},
142 {recipeitem
, recipeitem
, recipeitem
},
147 minetest
.register_craft({
148 output
= 'mcl_stairs:stair_' .. subname
.. ' 4',
150 {"", "", recipeitem
},
151 {"", recipeitem
, recipeitem
},
152 {recipeitem
, recipeitem
, recipeitem
},
157 mcl_stairs
.cornerstair
.add("mcl_stairs:stair_"..subname
, corner_stair_texture_override
)
161 -- Slab facedir to placement 6d matching table
162 local slab_trans_dir
= {[0] = 8, 0, 2, 1, 3, 4}
165 -- Node will be called mcl_stairs:slab_<subname>
167 -- double_description: NEW argument, not supported in Minetest Game
168 -- double_description: Description of double slab
169 function mcl_stairs
.register_slab(subname
, recipeitem
, groups
, images
, description
, sounds
, hardness
, double_description
)
170 local lower_slab
= "mcl_stairs:slab_"..subname
171 local upper_slab
= lower_slab
.."_top"
172 local double_slab
= lower_slab
.."_double"
176 images
= minetest
.registered_items
[recipeitem
].tiles
179 groups
= minetest
.registered_items
[recipeitem
].groups
182 sounds
= minetest
.registered_items
[recipeitem
].sounds
185 hardness
= minetest
.registered_items
[recipeitem
]._mcl_hardness
189 -- Automatically generate double slab description
190 if not double_description
then
191 double_description
= string.format("Double %s", description
)
192 minetest
.log("warning", "[stairs] No explicit description for double slab '"..double_slab
.."' added. Using auto-generated description.")
196 groups
.building_block
= 1
197 local longdesc
= "Slabs are half as high as their full block counterparts and occupy either the lower or upper part of a block, depending on how it was placed. Slabs can be easily stepped on without needing to jump. When a slab is placed on another slab of the same type, a double slab is created."
200 description
= description
,
201 _doc_items_longdesc
= longdesc
,
202 drawtype
= "nodebox",
205 -- Facedir intentionally left out (see below)
206 is_ground_content
= false,
211 fixed
= {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
213 on_place
= function(itemstack
, placer
, pointed_thing
)
214 local under
= minetest
.get_node(pointed_thing
.under
)
215 local wield_item
= itemstack
:get_name()
216 local creative_enabled
= minetest
.settings
:get_bool("creative_mode")
218 -- place slab using under node orientation
219 local dir
= vector
.subtract(pointed_thing
.above
, pointed_thing
.under
)
221 local p2
= under
.param2
223 -- combine two slabs if possible
224 -- Requirements: Same slab material, must be placed on top of lower slab, or on bottom of upper slab
225 if (wield_item
== under
.name
or (minetest
.registered_nodes
[under
.name
] and wield_item
== minetest
.registered_nodes
[under
.name
]._mcl_other_slab_half
)) and
226 not ((dir
.y
>= 0 and minetest
.get_item_group(under
.name
, "slab_top") == 1) or
227 (dir
.y
<= 0 and minetest
.get_item_group(under
.name
, "slab_top") == 0)) then
229 local player_name
= placer
:get_player_name()
230 if minetest
.is_protected(pointed_thing
.under
, player_name
) and not
231 minetest
.check_player_privs(placer
, "protection_bypass") then
232 minetest
.record_protection_violation(pointed_thing
.under
,
236 local newnode
= double_slab
237 minetest
.set_node(pointed_thing
.under
, {name
= newnode
, param2
= p2
})
238 if not creative_enabled
then
239 itemstack
:take_item()
242 -- No combination possible: Place slab normally
244 return place_slab_normal(itemstack
, placer
, pointed_thing
)
247 _mcl_hardness
= hardness
,
248 _mcl_other_slab_half
= upper_slab
,
251 minetest
.register_node(":"..lower_slab
, slabdef
)
253 -- Register the upper slab.
254 -- Using facedir is not an option, as this would rotate the textures as well and would make
255 -- e.g. upper sandstone slabs look completely wrong.
256 local topdef
= table.copy(slabdef
)
257 topdef
.groups
.slab
= 1
258 topdef
.groups
.slab_top
= 1
259 topdef
.groups
.not_in_creative_inventory
= 1
260 topdef
.groups
.not_in_craft_guide
= 1
261 topdef
.description
= string.format("Upper %s", description
)
262 topdef
._doc_items_create_entry
= false
263 topdef
._doc_items_longdesc
= nil
264 topdef
._doc_items_usagehelp
= nil
265 topdef
.drop
= lower_slab
266 topdef
._mcl_other_slab_half
= lower_slab
269 fixed
= {-0.5, 0, -0.5, 0.5, 0.5, 0.5},
271 topdef
.selection_box
= {
273 fixed
= {-0.5, 0, -0.5, 0.5, 0.5, 0.5},
275 minetest
.register_node(":"..upper_slab
, topdef
)
279 local dgroups
= table.copy(groups
)
280 dgroups
.not_in_creative_inventory
= 1
281 dgroups
.not_in_craft_guide
= 1
283 dgroups
.double_slab
= 1
284 minetest
.register_node(":"..double_slab
, {
285 description
= double_description
,
286 _doc_items_longdesc
= "Double slabs are full blocks which are created by placing two slabs of the same kind on each other.",
288 is_ground_content
= false,
291 drop
= lower_slab
.. " 2",
292 _mcl_hardness
= hardness
,
296 minetest
.register_craft({
297 output
= lower_slab
.. " 6",
299 {recipeitem
, recipeitem
, recipeitem
},
305 -- Help alias for the upper slab
306 if minetest
.get_modpath("doc") then
307 doc
.add_entry_alias("nodes", lower_slab
, "nodes", upper_slab
)
312 -- Stair/slab registration function.
313 -- Nodes will be called mcl_stairs:{stair,slab}_<subname>
315 function mcl_stairs
.register_stair_and_slab(subname
, recipeitem
,
316 groups
, images
, desc_stair
, desc_slab
, sounds
, hardness
,
317 double_description
, corner_stair_texture_override
)
318 mcl_stairs
.register_stair(subname
, recipeitem
, groups
, images
, desc_stair
, sounds
, hardness
, corner_stair_texture_override
)
319 mcl_stairs
.register_slab(subname
, recipeitem
, groups
, images
, desc_slab
, sounds
, hardness
, double_description
)
322 -- Very simple registration function
323 -- Makes stair and slab out of a source node
324 function mcl_stairs
.register_stair_and_slab_simple(subname
, sourcenode
, desc_stair
, desc_slab
, desc_double_slab
, corner_stair_texture_override
)
325 local def
= minetest
.registered_nodes
[sourcenode
]
327 -- Only allow a strict set of groups to be added to stairs and slabs for more predictable results
328 local allowed_groups
= { "dig_immediate", "handy", "pickaxey", "axey", "shovely", "shearsy", "shearsy_wool", "swordy", "swordy_wool" }
329 for a
=1, #allowed_groups
do
330 if def
.groups
[allowed_groups
[a]]
then
331 groups
[allowed_groups
[a]]
= def
.groups
[allowed_groups
[a]]
334 mcl_stairs
.register_stair_and_slab(subname
, sourcenode
, groups
, def
.tiles
, desc_stair
, desc_slab
, def
.sounds
, def
._mcl_hardness
, desc_double_slab
, corner_stair_texture_override
)