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