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