Default/functions: Reduce lavacooling ABM/sound overload
[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         local name = node.name
41         if not name or node.name:sub(1, 7) ~= "xpanes:" then
42                 return
43         end
44         local underscore_pos = string.find(name, "_[^_]*$") or 0
45         local len = name:len()
46         local num = tonumber(name:sub(underscore_pos+1, len))
47         if not num or num < 1 or num > 15 then
48                 name = name:sub(8)
49         else
50                 name = name:sub(8, underscore_pos - 1)
51         end
52         for i, dir in pairs(directions) do
53                 update_pane({
54                         x = pos.x + dir.x,
55                         y = pos.y + dir.y,
56                         z = pos.z + dir.z
57                 }, name)
58         end
59 end
60
61 local half_boxes = {
62         {0,     -0.5, -1/32, 0.5,  0.5, 1/32},
63         {-1/32, -0.5, 0,     1/32, 0.5, 0.5},
64         {-0.5,  -0.5, -1/32, 0,    0.5, 1/32},
65         {-1/32, -0.5, -0.5,  1/32, 0.5, 0}
66 }
67
68 local full_boxes = {
69         {-0.5,  -0.5, -1/32, 0.5,  0.5, 1/32},
70         {-1/32, -0.5, -0.5,  1/32, 0.5, 0.5}
71 }
72
73 local sb_half_boxes = {
74         {0,     -0.5, -0.06, 0.5,  0.5, 0.06},
75         {-0.06, -0.5, 0,     0.06, 0.5, 0.5},
76         {-0.5,  -0.5, -0.06, 0,    0.5, 0.06},
77         {-0.06, -0.5, -0.5,  0.06, 0.5, 0}
78 }
79
80 local sb_full_boxes = {
81         {-0.5,  -0.5, -0.06, 0.5,  0.5, 0.06},
82         {-0.06, -0.5, -0.5,  0.06, 0.5, 0.5}
83 }
84
85 function xpanes.register_pane(name, def)
86         for i = 1, 15 do
87                 local need = {}
88                 local cnt = 0
89                 for j = 1, 4 do
90                         if rshift(i, j - 1) % 2 == 1 then
91                                 need[j] = true
92                                 cnt = cnt + 1
93                         end
94                 end
95                 local take = {}
96                 local take2 = {}
97                 if need[1] == true and need[3] == true then
98                         need[1] = nil
99                         need[3] = nil
100                         table.insert(take, full_boxes[1])
101                         table.insert(take2, sb_full_boxes[1])
102                 end
103                 if need[2] == true and need[4] == true then
104                         need[2] = nil
105                         need[4] = nil
106                         table.insert(take, full_boxes[2])
107                         table.insert(take2, sb_full_boxes[2])
108                 end
109                 for k in pairs(need) do
110                         table.insert(take, half_boxes[k])
111                         table.insert(take2, sb_half_boxes[k])
112                 end
113                 local texture = def.textures[1]
114                 if cnt == 1 then
115                         texture = def.textures[1].."^"..def.textures[2]
116                 end
117                 minetest.register_node(":xpanes:"..name.."_"..i, {
118                         drawtype = "nodebox",
119                         tiles = {def.textures[3], def.textures[3], texture},
120                         paramtype = "light",
121                         groups = def.groups,
122                         drop = "xpanes:"..name,
123                         sounds = def.sounds,
124                         node_box = {
125                                 type = "fixed",
126                                 fixed = take
127                         },
128                         selection_box = {
129                                 type = "fixed",
130                                 fixed = take2
131                         }
132                 })
133         end
134
135         def.on_construct = function(pos)
136                 update_pane(pos, name)
137         end
138
139         minetest.register_node(":xpanes:"..name, def)
140
141         minetest.register_craft({
142                 output = "xpanes:"..name.." 16",
143                 recipe = def.recipe
144         })
145 end
146
147 minetest.register_on_placenode(update_nearby)
148 minetest.register_on_dignode(update_nearby)
149
150 xpanes.register_pane("pane", {
151         description = "Glass Pane",
152         tiles = {"xpanes_space.png"},
153         drawtype = "airlike",
154         paramtype = "light",
155         is_ground_content = false,
156         sunlight_propagates = true,
157         walkable = false,
158         pointable = false,
159         diggable = false,
160         buildable_to = true,
161         air_equivalent = true,
162         textures = {"default_glass.png","xpanes_pane_half.png","xpanes_white.png"},
163         inventory_image = "default_glass.png",
164         wield_image = "default_glass.png",
165         sounds = default.node_sound_glass_defaults(),
166         groups = {snappy=2, cracky=3, oddly_breakable_by_hand=3, pane=1},
167         recipe = {
168                 {'default:glass', 'default:glass', 'default:glass'},
169                 {'default:glass', 'default:glass', 'default:glass'}
170         }
171 })
172
173 xpanes.register_pane("bar", {
174         description = "Iron bar",
175         tiles = {"xpanes_space.png"},
176         drawtype = "airlike",
177         paramtype = "light",
178         is_ground_content = false,
179         sunlight_propagates = true,
180         walkable = false,
181         pointable = false,
182         diggable = false,
183         buildable_to = true,
184         air_equivalent = true,
185         textures = {"xpanes_bar.png","xpanes_bar.png","xpanes_space.png"},
186         inventory_image = "xpanes_bar.png",
187         wield_image = "xpanes_bar.png",
188         groups = {snappy=2, cracky=3, oddly_breakable_by_hand=3, pane=1},
189         sounds = default.node_sound_stone_defaults(),
190         recipe = {
191                 {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
192                 {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'}
193         }
194 })
195