c2547935e2cf35abe45c53d653a9d46539ca8c31
[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
5 -- Global namespace for functions
6
7 stairs = {}
8
9
10 -- Get setting for replace ABM
11
12 local replace = minetest.setting_getbool("enable_stairs_replace_abm")
13
14
15 -- Register stairs.
16 -- Node will be called stairs:stair_<subname>
17
18 function stairs.register_stair(subname, recipeitem, groups, images, description, sounds)
19         minetest.register_node(":stairs:stair_" .. subname, {
20                 description = description,
21                 drawtype = "mesh",
22                 mesh = "stairs_stair.obj",
23                 tiles = images,
24                 paramtype = "light",
25                 paramtype2 = "facedir",
26                 is_ground_content = false,
27                 groups = groups,
28                 sounds = sounds,
29                 selection_box = {
30                         type = "fixed",
31                         fixed = {
32                                 {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
33                                 {-0.5, 0, 0, 0.5, 0.5, 0.5},
34                         },
35                 },
36                 collision_box = {
37                         type = "fixed",
38                         fixed = {
39                                 {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
40                                 {-0.5, 0, 0, 0.5, 0.5, 0.5},
41                         },
42                 },
43                 on_place = function(itemstack, placer, pointed_thing)
44                         if pointed_thing.type ~= "node" then
45                                 return itemstack
46                         end
47
48                         local p0 = pointed_thing.under
49                         local p1 = pointed_thing.above
50                         local param2 = 0
51
52                         local placer_pos = placer:getpos()
53                         if placer_pos then
54                                 local dir = {
55                                         x = p1.x - placer_pos.x,
56                                         y = p1.y - placer_pos.y,
57                                         z = p1.z - placer_pos.z
58                                 }
59                                 param2 = minetest.dir_to_facedir(dir)
60                         end
61
62                         if p0.y - 1 == p1.y then
63                                 param2 = param2 + 20
64                                 if param2 == 21 then
65                                         param2 = 23
66                                 elseif param2 == 23 then
67                                         param2 = 21
68                                 end
69                         end
70
71                         return minetest.item_place(itemstack, placer, pointed_thing, param2)
72                 end,
73         })
74
75         -- for replace ABM
76         if replace then
77                 minetest.register_node(":stairs:stair_" .. subname .. "upside_down", {
78                         replace_name = "stairs:stair_" .. subname,
79                         groups = {slabs_replace = 1},
80                 })
81         end
82
83         minetest.register_craft({
84                 output = 'stairs:stair_' .. subname .. ' 6',
85                 recipe = {
86                         {recipeitem, "", ""},
87                         {recipeitem, recipeitem, ""},
88                         {recipeitem, recipeitem, recipeitem},
89                 },
90         })
91
92         -- Flipped recipe for the silly minecrafters
93         minetest.register_craft({
94                 output = 'stairs:stair_' .. subname .. ' 6',
95                 recipe = {
96                         {"", "", recipeitem},
97                         {"", recipeitem, recipeitem},
98                         {recipeitem, recipeitem, recipeitem},
99                 },
100         })
101 end
102
103
104 -- Register slabs.
105 -- Node will be called stairs:slab_<subname>
106
107 function stairs.register_slab(subname, recipeitem, groups, images, description, sounds)
108         minetest.register_node(":stairs:slab_" .. subname, {
109                 description = description,
110                 drawtype = "nodebox",
111                 tiles = images,
112                 paramtype = "light",
113                 paramtype2 = "facedir",
114                 is_ground_content = false,
115                 groups = groups,
116                 sounds = sounds,
117                 node_box = {
118                         type = "fixed",
119                         fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
120                 },
121                 on_place = function(itemstack, placer, pointed_thing)
122                         if pointed_thing.type ~= "node" then
123                                 return itemstack
124                         end
125
126                         -- If it's being placed on an another similar one, replace it with
127                         -- a full block
128                         local slabpos = nil
129                         local slabnode = nil
130                         local p0 = pointed_thing.under
131                         local p1 = pointed_thing.above
132                         local n0 = minetest.get_node(p0)
133                         local n1 = minetest.get_node(p1)
134                         local param2 = 0
135
136                         local n0_is_upside_down = (n0.name == "stairs:slab_" .. subname and
137                                         n0.param2 >= 20)
138
139                         if n0.name == "stairs:slab_" .. subname and not n0_is_upside_down and
140                                         p0.y + 1 == p1.y then
141                                 slabpos = p0
142                                 slabnode = n0
143                         elseif n1.name == "stairs:slab_" .. subname then
144                                 slabpos = p1
145                                 slabnode = n1
146                         end
147                         if slabpos then
148                                 -- Remove the slab at slabpos
149                                 minetest.remove_node(slabpos)
150                                 -- Make a fake stack of a single item and try to place it
151                                 local fakestack = ItemStack(recipeitem)
152                                 fakestack:set_count(itemstack:get_count())
153
154                                 pointed_thing.above = slabpos
155                                 local success
156                                 fakestack, success = minetest.item_place(fakestack, placer,
157                                         pointed_thing)
158                                 -- If the item was taken from the fake stack, decrement original
159                                 if success then
160                                         itemstack:set_count(fakestack:get_count())
161                                 -- Else put old node back
162                                 else
163                                         minetest.set_node(slabpos, slabnode)
164                                 end
165                                 return itemstack
166                         end
167                         
168                         -- Upside down slabs
169                         if p0.y - 1 == p1.y then
170                                 -- Turn into full block if pointing at a existing slab
171                                 if n0_is_upside_down  then
172                                         -- Remove the slab at the position of the slab
173                                         minetest.remove_node(p0)
174                                         -- Make a fake stack of a single item and try to place it
175                                         local fakestack = ItemStack(recipeitem)
176                                         fakestack:set_count(itemstack:get_count())
177
178                                         pointed_thing.above = p0
179                                         local success
180                                         fakestack, success = minetest.item_place(fakestack, placer,
181                                                 pointed_thing)
182                                         -- If the item was taken from the fake stack, decrement original
183                                         if success then
184                                                 itemstack:set_count(fakestack:get_count())
185                                         -- Else put old node back
186                                         else
187                                                 minetest.set_node(p0, n0)
188                                         end
189                                         return itemstack
190                                 end
191
192                                 -- Place upside down slab
193                                 param2 = 20
194                         end
195
196                         -- If pointing at the side of a upside down slab
197                         if n0_is_upside_down and p0.y + 1 ~= p1.y then
198                                 param2 = 20
199                         end
200
201                         return minetest.item_place(itemstack, placer, pointed_thing, param2)
202                 end,
203         })
204
205         -- for replace ABM
206         if replace then
207                 minetest.register_node(":stairs:slab_" .. subname .. "upside_down", {
208                         replace_name = "stairs:slab_".. subname,
209                         groups = {slabs_replace = 1},
210                 })
211         end
212
213         minetest.register_craft({
214                 output = 'stairs:slab_' .. subname .. ' 6',
215                 recipe = {
216                         {recipeitem, recipeitem, recipeitem},
217                 },
218         })
219 end
220
221
222 -- Optionally replace old "upside_down" nodes with new param2 versions.
223 -- Disabled by default.
224
225 if replace then
226         minetest.register_abm({
227                 nodenames = {"group:slabs_replace"},
228                 interval = 8,
229                 chance = 1,
230                 action = function(pos, node)
231                         node.name = minetest.registered_nodes[node.name].replace_name
232                         node.param2 = node.param2 + 20
233                         if node.param2 == 21 then
234                                 node.param2 = 23
235                         elseif node.param2 == 23 then
236                                 node.param2 = 21
237                         end
238                         minetest.set_node(pos, node)
239                 end,
240         })
241 end
242
243
244 -- Stair/slab registration function.
245 -- Nodes will be called stairs:{stair,slab}_<subname>
246
247 function stairs.register_stair_and_slab(subname, recipeitem, groups, images,
248                 desc_stair, desc_slab, sounds)
249         stairs.register_stair(subname, recipeitem, groups, images, desc_stair, sounds)
250         stairs.register_slab(subname, recipeitem, groups, images, desc_slab, sounds)
251 end
252
253
254 -- Register default stairs and slabs
255
256 stairs.register_stair_and_slab("wood", "default:wood",
257                 {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3},
258                 {"default_wood.png"},
259                 "Wooden Stair",
260                 "Wooden Slab",
261                 default.node_sound_wood_defaults())
262
263 stairs.register_stair_and_slab("junglewood", "default:junglewood",
264                 {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3},
265                 {"default_junglewood.png"},
266                 "Junglewood Stair",
267                 "Junglewood Slab",
268                 default.node_sound_wood_defaults())
269
270 stairs.register_stair_and_slab("pine_wood", "default:pine_wood",
271                 {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3},
272                 {"default_pine_wood.png"},
273                 "Pine Wood Stair",
274                 "Pine Wood Slab",
275                 default.node_sound_wood_defaults())
276
277 stairs.register_stair_and_slab("acacia_wood", "default:acacia_wood",
278                 {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3},
279                 {"default_acacia_wood.png"},
280                 "Acacia Wood Stair",
281                 "Acacia Wood Slab",
282                 default.node_sound_wood_defaults())
283
284 stairs.register_stair_and_slab("stone", "default:stone",
285                 {cracky = 3},
286                 {"default_stone.png"},
287                 "Stone Stair",
288                 "Stone Slab",
289                 default.node_sound_stone_defaults())
290
291 stairs.register_stair_and_slab("cobble", "default:cobble",
292                 {cracky = 3},
293                 {"default_cobble.png"},
294                 "Cobblestone Stair",
295                 "Cobblestone Slab",
296                 default.node_sound_stone_defaults())
297
298 stairs.register_stair_and_slab("stonebrick", "default:stonebrick",
299                 {cracky = 3},
300                 {"default_stone_brick.png"},
301                 "Stone Brick Stair",
302                 "Stone Brick Slab",
303                 default.node_sound_stone_defaults())
304
305 stairs.register_stair_and_slab("desert_stone", "default:desert_stone",
306                 {cracky = 3},
307                 {"default_desert_stone.png"},
308                 "Desertstone Stair",
309                 "Desertstone Slab",
310                 default.node_sound_stone_defaults())
311
312 stairs.register_stair_and_slab("desert_cobble", "default:desert_cobble",
313                 {cracky = 3},
314                 {"default_desert_cobble.png"},
315                 "Desert Cobblestone Stair",
316                 "Desert Cobblestone Slab",
317                 default.node_sound_stone_defaults())
318
319 stairs.register_stair_and_slab("desert_stonebrick", "default:desert_stonebrick",
320                 {cracky = 3},
321                 {"default_desert_stone_brick.png"},
322                 "Desert Stone Brick Stair",
323                 "Desert Stone Brick Slab",
324                 default.node_sound_stone_defaults())
325
326 stairs.register_stair_and_slab("sandstone", "default:sandstone",
327                 {crumbly = 2, cracky = 2},
328                 {"default_sandstone.png"},
329                 "Sandstone Stair",
330                 "Sandstone Slab",
331                 default.node_sound_stone_defaults())
332                 
333 stairs.register_stair_and_slab("sandstonebrick", "default:sandstonebrick",
334                 {crumbly = 2, cracky = 2},
335                 {"default_sandstone_brick.png"},
336                 "Sandstone Brick Stair",
337                 "Sandstone Brick Slab",
338                 default.node_sound_stone_defaults())
339
340 stairs.register_stair_and_slab("obsidian", "default:obsidian",
341                 {cracky = 1, level = 2},
342                 {"default_obsidian.png"},
343                 "Obsidian Stair",
344                 "Obsidian Slab",
345                 default.node_sound_stone_defaults())
346
347 stairs.register_stair_and_slab("obsidianbrick", "default:obsidianbrick",
348                 {cracky = 1, level = 2},
349                 {"default_obsidian_brick.png"},
350                 "Obsidian Brick Stair",
351                 "Obsidian Brick Slab",
352                 default.node_sound_stone_defaults())
353
354 stairs.register_stair_and_slab("brick", "default:brick",
355                 {cracky = 3},
356                 {"default_brick.png"},
357                 "Brick Stair",
358                 "Brick Slab",
359                 default.node_sound_stone_defaults())
360
361 stairs.register_stair_and_slab("straw", "farming:straw",
362                 {snappy = 3, flammable = 4},
363                 {"farming_straw.png"},
364                 "Straw Stair",
365                 "Straw Slab",
366                 default.node_sound_leaves_defaults())
367
368 stairs.register_stair_and_slab("steelblock", "default:steelblock",
369                 {cracky = 1, level = 2},
370                 {"default_steel_block.png"},
371                 "Steel Block Stair",
372                 "Steel Block Slab",
373                 default.node_sound_stone_defaults())
374
375 stairs.register_stair_and_slab("copperblock", "default:copperblock",
376                 {cracky = 1, level = 2},
377                 {"default_copper_block.png"},
378                 "Copper Block Stair",
379                 "Copper Block Slab",
380                 default.node_sound_stone_defaults())
381
382 stairs.register_stair_and_slab("bronzeblock", "default:bronzeblock",
383                 {cracky = 1, level = 2},
384                 {"default_bronze_block.png"},
385                 "Bronze Block Stair",
386                 "Bronze Block Slab",
387                 default.node_sound_stone_defaults())
388
389 stairs.register_stair_and_slab("goldblock", "default:goldblock",
390                 {cracky = 1},
391                 {"default_gold_block.png"},
392                 "Gold Block Stair",
393                 "Gold Block Slab",
394                 default.node_sound_stone_defaults())