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