Use 6d facedir to place upside down slabs and stairs
[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 stairs = {}
5
6 -- Node will be called stairs:stair_<subname>
7 function stairs.register_stair(subname, recipeitem, groups, images, description, sounds)
8         minetest.register_node(":stairs:stair_" .. subname, {
9                 description = description,
10                 drawtype = "nodebox",
11                 tiles = images,
12                 paramtype = "light",
13                 paramtype2 = "facedir",
14                 is_ground_content = true,
15                 groups = groups,
16                 sounds = sounds,
17                 node_box = {
18                         type = "fixed",
19                         fixed = {
20                                 {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
21                                 {-0.5, 0, 0, 0.5, 0.5, 0.5},
22                         },
23                 },
24                 on_place = function(itemstack, placer, pointed_thing)
25                         if pointed_thing.type ~= "node" then
26                                 return itemstack
27                         end
28                         
29                         local p0 = pointed_thing.under
30                         local p1 = pointed_thing.above
31                         local param2 = 0
32                         
33                         local placer_pos = placer:getpos()
34                         if placer_pos then
35                                 local dir = {
36                                         x = p1.x - placer_pos.x,
37                                         y = p1.y - placer_pos.y,
38                                         z = p1.z - placer_pos.z
39                                 }
40                                 param2 = minetest.dir_to_facedir(dir)
41                         end
42                         
43                         if p0.y-1 == p1.y then
44                                 param2 = param2 + 20
45                                 if param2 == 21 then
46                                         param2 = 23
47                                 elseif param2 == 23 then
48                                         param2 = 21
49                                 end
50                         end
51                         
52                         return minetest.item_place(itemstack, placer, pointed_thing, param2)
53                 end,
54         })
55         
56         -- for replace ABM
57         minetest.register_node(":stairs:stair_" .. subname.."upside_down", {
58                 replace_name = "stairs:stair_" .. subname,
59                 groups = {slabs_replace=1},
60         })
61
62         minetest.register_craft({
63                 output = 'stairs:stair_' .. subname .. ' 4',
64                 recipe = {
65                         {recipeitem, "", ""},
66                         {recipeitem, recipeitem, ""},
67                         {recipeitem, recipeitem, recipeitem},
68                 },
69         })
70
71         -- Flipped recipe for the silly minecrafters
72         minetest.register_craft({
73                 output = 'stairs:stair_' .. subname .. ' 4',
74                 recipe = {
75                         {"", "", recipeitem},
76                         {"", recipeitem, recipeitem},
77                         {recipeitem, recipeitem, recipeitem},
78                 },
79         })
80 end
81
82 -- Node will be called stairs:slab_<subname>
83 function stairs.register_slab(subname, recipeitem, groups, images, description, sounds)
84         minetest.register_node(":stairs:slab_" .. subname, {
85                 description = description,
86                 drawtype = "nodebox",
87                 tiles = images,
88                 paramtype = "light",
89                 paramtype2 = "facedir",
90                 is_ground_content = true,
91                 groups = groups,
92                 sounds = sounds,
93                 node_box = {
94                         type = "fixed",
95                         fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
96                 },
97                 on_place = function(itemstack, placer, pointed_thing)
98                         if pointed_thing.type ~= "node" then
99                                 return itemstack
100                         end
101
102                         -- If it's being placed on an another similar one, replace it with
103                         -- a full block
104                         local slabpos = nil
105                         local slabnode = nil
106                         local p0 = pointed_thing.under
107                         local p1 = pointed_thing.above
108                         local n0 = minetest.get_node(p0)
109                         local n1 = minetest.get_node(p1)
110                         local param2 = 0
111                         
112                         local n0_is_upside_down = (n0.name == "stairs:slab_" .. subname and
113                                         n0.param2 >= 20)
114                         
115                         if n0.name == "stairs:slab_" .. subname and not n0_is_upside_down and p0.y+1 == p1.y then
116                                 slabpos = p0
117                                 slabnode = n0
118                         elseif n1.name == "stairs:slab_" .. subname then
119                                 slabpos = p1
120                                 slabnode = n1
121                         end
122                         if slabpos then
123                                 -- Remove the slab at slabpos
124                                 minetest.remove_node(slabpos)
125                                 -- Make a fake stack of a single item and try to place it
126                                 local fakestack = ItemStack(recipeitem)
127                                 fakestack:set_count(itemstack:get_count())
128                                 
129                                 pointed_thing.above = slabpos
130                                 local success
131                                 fakestack, success = minetest.item_place(fakestack, placer, pointed_thing)
132                                 -- If the item was taken from the fake stack, decrement original
133                                 if success then
134                                         itemstack:set_count(fakestack:get_count())
135                                 -- Else put old node back
136                                 else
137                                         minetest.set_node(slabpos, slabnode)
138                                 end
139                                 return itemstack
140                         end
141                         
142                         -- Upside down slabs
143                         if p0.y-1 == p1.y then
144                                 -- Turn into full block if pointing at a existing slab
145                                 if n0_is_upside_down  then
146                                         -- Remove the slab at the position of the slab
147                                         minetest.remove_node(p0)
148                                         -- Make a fake stack of a single item and try to place it
149                                         local fakestack = ItemStack(recipeitem)
150                                         fakestack:set_count(itemstack:get_count())
151                                         
152                                         pointed_thing.above = p0
153                                         local success
154                                         fakestack, success = minetest.item_place(fakestack, placer, pointed_thing)
155                                         -- If the item was taken from the fake stack, decrement original
156                                         if success then
157                                                 itemstack:set_count(fakestack:get_count())
158                                         -- Else put old node back
159                                         else
160                                                 minetest.set_node(p0, n0)
161                                         end
162                                         return itemstack
163                                 end
164                                 
165                                 -- Place upside down slab
166                                 param2 = 20
167                         end
168                         
169                         -- If pointing at the side of a upside down slab
170                         if n0_is_upside_down and p0.y+1 ~= p1.y then
171                                 param2 = 20
172                         end
173                         
174                         return minetest.item_place(itemstack, placer, pointed_thing, param2)
175                 end,
176         })
177         
178         -- for replace ABM
179         minetest.register_node(":stairs:slab_" .. subname.."upside_down", {
180                 replace_name = "stairs:slab_"..subname,
181                 groups = {slabs_replace=1},
182         })
183
184         minetest.register_craft({
185                 output = 'stairs:slab_' .. subname .. ' 6',
186                 recipe = {
187                         {recipeitem, recipeitem, recipeitem},
188                 },
189         })
190 end
191
192 -- Replace old "upside_down" nodes with new param2 versions
193 minetest.register_abm({
194         nodenames = {"group:slabs_replace"},
195         interval = 1,
196         chance = 1,
197         action = function(pos, node)
198                 node.name = minetest.registered_nodes[node.name].replace_name
199                 node.param2 = node.param2 + 20
200                 if node.param2 == 21 then
201                         node.param2 = 23
202                 elseif node.param2 == 23 then
203                         node.param2 = 21
204                 end
205                 minetest.set_node(pos, node)
206         end,
207 })
208
209 -- Nodes will be called stairs:{stair,slab}_<subname>
210 function stairs.register_stair_and_slab(subname, recipeitem, groups, images, desc_stair, desc_slab, sounds)
211         stairs.register_stair(subname, recipeitem, groups, images, desc_stair, sounds)
212         stairs.register_slab(subname, recipeitem, groups, images, desc_slab, sounds)
213 end
214
215 stairs.register_stair_and_slab("wood", "default:wood",
216                 {snappy=2,choppy=2,oddly_breakable_by_hand=2,flammable=3},
217                 {"default_wood.png"},
218                 "Wooden Stair",
219                 "Wooden Slab",
220                 default.node_sound_wood_defaults())
221
222 stairs.register_stair_and_slab("stone", "default:stone",
223                 {cracky=3},
224                 {"default_stone.png"},
225                 "Stone Stair",
226                 "Stone Slab",
227                 default.node_sound_stone_defaults())
228
229 stairs.register_stair_and_slab("cobble", "default:cobble",
230                 {cracky=3},
231                 {"default_cobble.png"},
232                 "Cobble Stair",
233                 "Cobble Slab",
234                 default.node_sound_stone_defaults())
235
236 stairs.register_stair_and_slab("brick", "default:brick",
237                 {cracky=3},
238                 {"default_brick.png"},
239                 "Brick Stair",
240                 "Brick Slab",
241                 default.node_sound_stone_defaults())
242
243 stairs.register_stair_and_slab("sandstone", "default:sandstone",
244                 {crumbly=2,cracky=2},
245                 {"default_sandstone.png"},
246                 "Sandstone Stair",
247                 "Sandstone Slab",
248                 default.node_sound_stone_defaults())
249
250 stairs.register_stair_and_slab("junglewood", "default:junglewood",
251                 {snappy=2,choppy=2,oddly_breakable_by_hand=2,flammable=3},
252                 {"default_junglewood.png"},
253                 "Junglewood Stair",
254                 "Junglewood Slab",
255                 default.node_sound_wood_defaults())
256
257 stairs.register_stair_and_slab("stonebrick", "default:stonebrick",
258                 {cracky=3},
259                 {"default_stone_brick.png"},
260                 "Stone Brick Stair",
261                 "Stone Brick Slab",
262                 default.node_sound_stone_defaults())