Skip to content

Commit 54235f3

Browse files
sofarparamat
authored andcommittedSep 10, 2016
Xpanes: Convert to connected nodeboxes
I've rewritten this to use connected nodeboxes, but with a caveat. In order to make flat nodes look better, I'm keeping one non-connected pane that is flat around to convert flat sections to the flat nodes instead of connected, as these look better and are easier to work with. Once more sides are needed we convert the panes on the fly to connected nodes and recalculate the shape. We don't paint any of the half-panes that the previous generation of xpanes did. There's no need and it's harder to work with. Updating the nodes also seems more natural and placement and removal works straight forward. The conversion of old panes relies on an LBM, and does a reasonable conversion job, but it's not exact, since the panes behave slightly different now. The game API documentation was wrong to begin with. We discard param nr. 2 of the API entirely, and correct the tile usage text.
1 parent 992f295 commit 54235f3

File tree

4 files changed

+136
-133
lines changed

4 files changed

+136
-133
lines changed
 

‎game_api.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ Creates panes that automatically connect to each other
421421
### Pane definition
422422

423423
{
424-
textures = {"texture_Bottom_top", "texture_left_right", "texture_front_back"}, -- More tiles aren't supported
424+
textures = {"texture for sides", (unused), "texture for top and bottom"}, -- More tiles aren't supported
425425
groups = {group = rating}, -- Uses the known node groups, see [Known damage and digging time defining groups]
426426
sounds = SoundSpec, -- See [#Default sounds]
427427
recipe = {{"","","","","","","","",""}}, -- Recipe field only

‎mods/xpanes/README.txt

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Authors of source code
66
----------------------
77
Originally by xyz (MIT)
88
BlockMen (MIT)
9+
sofar (MIT)
910
Various Minetest developers and contributors (MIT)
1011

1112
Authors of media (textures)

‎mods/xpanes/init.lua

+133-132
Original file line numberDiff line numberDiff line change
@@ -1,156 +1,146 @@
1-
xpanes = {}
21

3-
local function rshift(x, by)
4-
return math.floor(x / 2 ^ by)
2+
local function is_pane(pos)
3+
return minetest.get_item_group(minetest.get_node(pos).name, "pane") > 0
54
end
65

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
6+
local function connects_dir(pos, name, dir)
7+
local aside = vector.add(pos, minetest.facedir_to_dir(dir))
8+
if is_pane(aside) then
9+
return true
1710
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
11+
12+
local connects_to = minetest.registered_nodes[name].connects_to
13+
if not connects_to then
14+
return false
2715
end
28-
if sum == 0 then
29-
sum = 15
16+
local list = minetest.find_nodes_in_area(aside, aside, connects_to)
17+
18+
if #list > 0 then
19+
return true
3020
end
31-
minetest.set_node(pos, {name = "xpanes:"..name.."_"..sum})
21+
22+
return false
3223
end
3324

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
25+
local function swap(pos, node, name, param2)
26+
if node.name == name and node.param2 == param2 then
3827
return
3928
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
29+
30+
minetest.set_node(pos, {name = name, param2 = param2})
5131
end
5232

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-
}
33+
local function update_pane(pos)
34+
if not is_pane(pos) then
35+
return
36+
end
37+
local node = minetest.get_node(pos)
38+
local name = node.name
39+
if name:sub(-5) == "_flat" then
40+
name = name:sub(1, -6)
41+
end
9142

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])
43+
local any = node.param2
44+
local c = {}
45+
local count = 0
46+
for dir = 0, 3 do
47+
c[dir] = connects_dir(pos, name, dir)
48+
if c[dir] then
49+
any = dir
50+
count = count + 1
10951
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]
52+
end
53+
54+
if count == 0 then
55+
swap(pos, node, name .. "_flat", any)
56+
elseif count == 1 then
57+
swap(pos, node, name .. "_flat", (any + 1) % 4)
58+
elseif count == 2 then
59+
if (c[0] and c[2]) or (c[1] and c[3]) then
60+
swap(pos, node, name .. "_flat", (any + 1) % 4)
61+
else
62+
swap(pos, node, name, 0)
12363
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-
})
64+
else
65+
swap(pos, node, name, 0)
66+
end
67+
end
68+
69+
minetest.register_on_placenode(function(pos, node)
70+
if minetest.get_item_group(node, "pane") then
71+
update_pane(pos)
72+
end
73+
for i = 0, 3 do
74+
local dir = minetest.facedir_to_dir(i)
75+
update_pane(vector.add(pos, dir))
14076
end
77+
end)
14178

142-
for k, v in pairs(pane_def_fields) do
143-
def[k] = def[k] or v
79+
minetest.register_on_dignode(function(pos)
80+
for i = 0, 3 do
81+
local dir = minetest.facedir_to_dir(i)
82+
update_pane(vector.add(pos, dir))
14483
end
84+
end)
14585

146-
def.on_construct = function(pos)
147-
update_pane(pos, name)
86+
xpanes = {}
87+
function xpanes.register_pane(name, def)
88+
for i = 1, 15 do
89+
minetest.register_alias("xpanes:" .. name .. "_" .. i, "xpanes:" .. name .. "_flat")
14890
end
14991

150-
minetest.register_node(":xpanes:"..name, def)
92+
local flatgroups = table.copy(def.groups)
93+
flatgroups.pane = 1
94+
minetest.register_node(":xpanes:" .. name .. "_flat", {
95+
description = def.description,
96+
drawtype = "nodebox",
97+
paramtype = "light",
98+
is_ground_content = false,
99+
sunlight_propagates = true,
100+
inventory_image = def.inventory_image,
101+
wield_image = def.wield_image,
102+
paramtype2 = "facedir",
103+
tiles = {def.textures[3], def.textures[3], def.textures[1]},
104+
groups = flatgroups,
105+
drop = "xpanes:" .. name .. "_flat",
106+
sounds = def.sounds,
107+
node_box = {
108+
type = "fixed",
109+
fixed = {{-1/2, -1/2, -1/32, 1/2, 1/2, 1/32}},
110+
},
111+
selection_box = {
112+
type = "fixed",
113+
fixed = {{-1/2, -1/2, -1/32, 1/2, 1/2, 1/32}},
114+
},
115+
connect_sides = { "left", "right" },
116+
})
117+
118+
local groups = table.copy(def.groups)
119+
groups.pane = 1
120+
groups.not_in_creative_inventory = 1
121+
minetest.register_node(":xpanes:" .. name, {
122+
drawtype = "nodebox",
123+
paramtype = "light",
124+
is_ground_content = false,
125+
sunlight_propagates = true,
126+
description = def.description,
127+
tiles = {def.textures[3], def.textures[3], def.textures[1]},
128+
groups = groups,
129+
drop = "xpanes:" .. name .. "_flat",
130+
sounds = def.sounds,
131+
node_box = {
132+
type = "connected",
133+
fixed = {{-1/32, -1/2, -1/32, 1/32, 1/2, 1/32}},
134+
connect_front = {{-1/32, -1/2, -1/2, 1/32, 1/2, -1/32}},
135+
connect_left = {{-1/2, -1/2, -1/32, -1/32, 1/2, 1/32}},
136+
connect_back = {{-1/32, -1/2, 1/32, 1/32, 1/2, 1/2}},
137+
connect_right = {{1/32, -1/2, -1/32, 1/2, 1/2, 1/32}},
138+
},
139+
connects_to = {"group:pane", "group:stone", "group:glass", "group:wood", "group:tree"},
140+
})
151141

152142
minetest.register_craft({
153-
output = "xpanes:"..name.." 16",
143+
output = "xpanes:" .. name .. "_flat 16",
154144
recipe = def.recipe
155145
})
156146
end
@@ -161,7 +151,7 @@ xpanes.register_pane("pane", {
161151
inventory_image = "default_glass.png",
162152
wield_image = "default_glass.png",
163153
sounds = default.node_sound_glass_defaults(),
164-
groups = {snappy=2, cracky=3, oddly_breakable_by_hand=3, pane=1},
154+
groups = {snappy=2, cracky=3, oddly_breakable_by_hand=3},
165155
recipe = {
166156
{"default:glass", "default:glass", "default:glass"},
167157
{"default:glass", "default:glass", "default:glass"}
@@ -173,11 +163,22 @@ xpanes.register_pane("bar", {
173163
textures = {"xpanes_bar.png","xpanes_bar.png","xpanes_space.png"},
174164
inventory_image = "xpanes_bar.png",
175165
wield_image = "xpanes_bar.png",
176-
groups = {cracky=2, pane=1},
166+
groups = {cracky=2},
177167
sounds = default.node_sound_stone_defaults(),
178168
recipe = {
179169
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
180170
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}
181171
}
182172
})
183173

174+
minetest.register_lbm({
175+
name = "xpanes:gen2",
176+
nodenames = {"group:pane"},
177+
action = function(pos, node)
178+
update_pane(pos)
179+
for i = 0, 3 do
180+
local dir = minetest.facedir_to_dir(i)
181+
update_pane(vector.add(pos, dir))
182+
end
183+
end
184+
})

‎mods/xpanes/license.txt

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ License of source code
44
The MIT License (MIT)
55
Copyright (C) 2014-2016 xyz
66
Copyright (C) 2014-2016 BlockMen
7+
Copyright (C) 2016 Auke Kok <sofar@foo-projects.org>
78
Copyright (C) 2014-2016 Various Minetest developers and contributors
89

910
Permission is hereby granted, free of charge, to any person obtaining a copy of this

0 commit comments

Comments
 (0)
Please sign in to comment.