Make open trapdoor climbable
[oweals/minetest_game.git] / mods / xpanes / init.lua
1 xpanes = {}
2
3 local function rshift(x, by)
4         return math.floor(x / 2 ^ by)
5 end
6
7 local directions = {
8         {x = 1, y = 0, z = 0},
9         {x = 0, y = 0, z = 1},
10         {x = -1, y = 0, z = 0},
11         {x = 0, y = 0, z = -1},
12 }
13
14 local function update_pane(pos, name)
15         if not minetest.get_node(pos).name:find("^xpanes:"..name) then
16                 return
17         end
18         local sum = 0
19         for i, dir in pairs(directions) do
20                 local node = minetest.get_node({
21                         x = pos.x + dir.x,
22                         y = pos.y + dir.y,
23                         z = pos.z + dir.z
24                 })
25                 local def = minetest.registered_nodes[node.name]
26                 local pane_num = def and def.groups.pane or 0
27                 if pane_num > 0 or not def or (def.walkable ~= false and
28                                 def.drawtype ~= "nodebox") then
29                         sum = sum + 2 ^ (i - 1)
30                 end
31         end
32         if sum == 0 then
33                 sum = 15
34         end
35         minetest.set_node(pos, {name = "xpanes:"..name.."_"..sum})
36 end
37
38 local function update_nearby(pos, node)
39         node = node or minetest.get_node(pos)
40         if node.name:sub(1, 7) ~= "xpanes:" then return end
41         local underscore_pos = node.name:find("_") or 0
42         local name = node.name:sub(8, underscore_pos - 1)
43         for i, dir in pairs(directions) do
44                 update_pane({
45                         x = pos.x + dir.x,
46                         y = pos.y + dir.y,
47                         z = pos.z + dir.z
48                 }, name)
49         end
50 end
51
52 local half_boxes = {
53         {0,     -0.5, -1/32, 0.5,  0.5, 1/32},
54         {-1/32, -0.5, 0,     1/32, 0.5, 0.5},
55         {-0.5,  -0.5, -1/32, 0,    0.5, 1/32},
56         {-1/32, -0.5, -0.5,  1/32, 0.5, 0}
57 }
58
59 local full_boxes = {
60         {-0.5,  -0.5, -1/32, 0.5,  0.5, 1/32},
61         {-1/32, -0.5, -0.5,  1/32, 0.5, 0.5}
62 }
63
64 local sb_half_boxes = {
65         {0,     -0.5, -0.06, 0.5,  0.5, 0.06},
66         {-0.06, -0.5, 0,     0.06, 0.5, 0.5},
67         {-0.5,  -0.5, -0.06, 0,    0.5, 0.06},
68         {-0.06, -0.5, -0.5,  0.06, 0.5, 0}
69 }
70
71 local sb_full_boxes = {
72         {-0.5,  -0.5, -0.06, 0.5,  0.5, 0.06},
73         {-0.06, -0.5, -0.5,  0.06, 0.5, 0.5}
74 }
75
76 function xpanes.register_pane(name, def)
77         for i = 1, 15 do
78                 local need = {}
79                 local cnt = 0
80                 for j = 1, 4 do
81                         if rshift(i, j - 1) % 2 == 1 then
82                                 need[j] = true
83                                 cnt = cnt + 1
84                         end
85                 end
86                 local take = {}
87                 local take2 = {}
88                 if need[1] == true and need[3] == true then
89                         need[1] = nil
90                         need[3] = nil
91                         table.insert(take, full_boxes[1])
92                         table.insert(take2, sb_full_boxes[1])
93                 end
94                 if need[2] == true and need[4] == true then
95                         need[2] = nil
96                         need[4] = nil
97                         table.insert(take, full_boxes[2])
98                         table.insert(take2, sb_full_boxes[2])
99                 end
100                 for k in pairs(need) do
101                         table.insert(take, half_boxes[k])
102                         table.insert(take2, sb_half_boxes[k])
103                 end
104                 local texture = def.textures[1]
105                 if cnt == 1 then
106                         texture = def.textures[1].."^"..def.textures[2]
107                 end
108                 minetest.register_node("xpanes:"..name.."_"..i, {
109                         drawtype = "nodebox",
110                         tiles = {def.textures[3], def.textures[3], texture},
111                         paramtype = "light",
112                         groups = def.groups,
113                         drop = "xpanes:"..name,
114                         sounds = def.sounds,
115                         node_box = {
116                                 type = "fixed",
117                                 fixed = take
118                         },
119                         selection_box = {
120                                 type = "fixed",
121                                 fixed = take2
122                         }
123                 })
124         end
125
126         minetest.register_node("xpanes:"..name, def)
127
128         minetest.register_craft({
129                 output = "xpanes:"..name.." 16",
130                 recipe = def.recipe
131         })
132 end
133
134 minetest.register_on_placenode(update_nearby)
135 minetest.register_on_dignode(update_nearby)
136
137 xpanes.register_pane("pane", {
138         description = "Glass Pane",
139         tiles = {"xpanes_space.png"},
140         drawtype = "airlike",
141         paramtype = "light",
142         sunlight_propagates = true,
143         walkable = false,
144         pointable = false,
145         diggable = false,
146         buildable_to = true,
147         air_equivalent = true,
148         textures = {"default_glass.png","xpanes_pane_half.png","xpanes_white.png"},
149         inventory_image = "default_glass.png",
150         wield_image = "default_glass.png",
151         sounds = default.node_sound_glass_defaults(),
152         groups = {snappy=2, cracky=3, oddly_breakable_by_hand=3, pane=1},
153         on_construct = function(pos)
154                 update_pane(pos, "pane")
155         end,
156         recipe = {
157                 {'default:glass', 'default:glass', 'default:glass'},
158                 {'default:glass', 'default:glass', 'default:glass'}
159         }
160 })
161
162 xpanes.register_pane("bar", {
163         description = "Iron bar",
164         tiles = {"xpanes_space.png"},
165         drawtype = "airlike",
166         paramtype = "light",
167         sunlight_propagates = true,
168         walkable = false,
169         pointable = false,
170         diggable = false,
171         buildable_to = true,
172         air_equivalent = true,
173         textures = {"xpanes_bar.png","xpanes_bar.png","xpanes_space.png"},
174         inventory_image = "xpanes_bar.png",
175         wield_image = "xpanes_bar.png",
176         groups = {snappy=2, cracky=3, oddly_breakable_by_hand=3, pane=1},
177         sounds = default.node_sound_stone_defaults(),
178         on_construct = function(pos)
179                 update_pane(pos, "bar")
180         end,
181         recipe = {
182                 {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
183                 {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'}
184         }
185 })
186