54235f3276
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.
185 lines
4.6 KiB
Lua
185 lines
4.6 KiB
Lua
|
|
local function is_pane(pos)
|
|
return minetest.get_item_group(minetest.get_node(pos).name, "pane") > 0
|
|
end
|
|
|
|
local function connects_dir(pos, name, dir)
|
|
local aside = vector.add(pos, minetest.facedir_to_dir(dir))
|
|
if is_pane(aside) then
|
|
return true
|
|
end
|
|
|
|
local connects_to = minetest.registered_nodes[name].connects_to
|
|
if not connects_to then
|
|
return false
|
|
end
|
|
local list = minetest.find_nodes_in_area(aside, aside, connects_to)
|
|
|
|
if #list > 0 then
|
|
return true
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
local function swap(pos, node, name, param2)
|
|
if node.name == name and node.param2 == param2 then
|
|
return
|
|
end
|
|
|
|
minetest.set_node(pos, {name = name, param2 = param2})
|
|
end
|
|
|
|
local function update_pane(pos)
|
|
if not is_pane(pos) then
|
|
return
|
|
end
|
|
local node = minetest.get_node(pos)
|
|
local name = node.name
|
|
if name:sub(-5) == "_flat" then
|
|
name = name:sub(1, -6)
|
|
end
|
|
|
|
local any = node.param2
|
|
local c = {}
|
|
local count = 0
|
|
for dir = 0, 3 do
|
|
c[dir] = connects_dir(pos, name, dir)
|
|
if c[dir] then
|
|
any = dir
|
|
count = count + 1
|
|
end
|
|
end
|
|
|
|
if count == 0 then
|
|
swap(pos, node, name .. "_flat", any)
|
|
elseif count == 1 then
|
|
swap(pos, node, name .. "_flat", (any + 1) % 4)
|
|
elseif count == 2 then
|
|
if (c[0] and c[2]) or (c[1] and c[3]) then
|
|
swap(pos, node, name .. "_flat", (any + 1) % 4)
|
|
else
|
|
swap(pos, node, name, 0)
|
|
end
|
|
else
|
|
swap(pos, node, name, 0)
|
|
end
|
|
end
|
|
|
|
minetest.register_on_placenode(function(pos, node)
|
|
if minetest.get_item_group(node, "pane") then
|
|
update_pane(pos)
|
|
end
|
|
for i = 0, 3 do
|
|
local dir = minetest.facedir_to_dir(i)
|
|
update_pane(vector.add(pos, dir))
|
|
end
|
|
end)
|
|
|
|
minetest.register_on_dignode(function(pos)
|
|
for i = 0, 3 do
|
|
local dir = minetest.facedir_to_dir(i)
|
|
update_pane(vector.add(pos, dir))
|
|
end
|
|
end)
|
|
|
|
xpanes = {}
|
|
function xpanes.register_pane(name, def)
|
|
for i = 1, 15 do
|
|
minetest.register_alias("xpanes:" .. name .. "_" .. i, "xpanes:" .. name .. "_flat")
|
|
end
|
|
|
|
local flatgroups = table.copy(def.groups)
|
|
flatgroups.pane = 1
|
|
minetest.register_node(":xpanes:" .. name .. "_flat", {
|
|
description = def.description,
|
|
drawtype = "nodebox",
|
|
paramtype = "light",
|
|
is_ground_content = false,
|
|
sunlight_propagates = true,
|
|
inventory_image = def.inventory_image,
|
|
wield_image = def.wield_image,
|
|
paramtype2 = "facedir",
|
|
tiles = {def.textures[3], def.textures[3], def.textures[1]},
|
|
groups = flatgroups,
|
|
drop = "xpanes:" .. name .. "_flat",
|
|
sounds = def.sounds,
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = {{-1/2, -1/2, -1/32, 1/2, 1/2, 1/32}},
|
|
},
|
|
selection_box = {
|
|
type = "fixed",
|
|
fixed = {{-1/2, -1/2, -1/32, 1/2, 1/2, 1/32}},
|
|
},
|
|
connect_sides = { "left", "right" },
|
|
})
|
|
|
|
local groups = table.copy(def.groups)
|
|
groups.pane = 1
|
|
groups.not_in_creative_inventory = 1
|
|
minetest.register_node(":xpanes:" .. name, {
|
|
drawtype = "nodebox",
|
|
paramtype = "light",
|
|
is_ground_content = false,
|
|
sunlight_propagates = true,
|
|
description = def.description,
|
|
tiles = {def.textures[3], def.textures[3], def.textures[1]},
|
|
groups = groups,
|
|
drop = "xpanes:" .. name .. "_flat",
|
|
sounds = def.sounds,
|
|
node_box = {
|
|
type = "connected",
|
|
fixed = {{-1/32, -1/2, -1/32, 1/32, 1/2, 1/32}},
|
|
connect_front = {{-1/32, -1/2, -1/2, 1/32, 1/2, -1/32}},
|
|
connect_left = {{-1/2, -1/2, -1/32, -1/32, 1/2, 1/32}},
|
|
connect_back = {{-1/32, -1/2, 1/32, 1/32, 1/2, 1/2}},
|
|
connect_right = {{1/32, -1/2, -1/32, 1/2, 1/2, 1/32}},
|
|
},
|
|
connects_to = {"group:pane", "group:stone", "group:glass", "group:wood", "group:tree"},
|
|
})
|
|
|
|
minetest.register_craft({
|
|
output = "xpanes:" .. name .. "_flat 16",
|
|
recipe = def.recipe
|
|
})
|
|
end
|
|
|
|
xpanes.register_pane("pane", {
|
|
description = "Glass Pane",
|
|
textures = {"default_glass.png","xpanes_pane_half.png","xpanes_white.png"},
|
|
inventory_image = "default_glass.png",
|
|
wield_image = "default_glass.png",
|
|
sounds = default.node_sound_glass_defaults(),
|
|
groups = {snappy=2, cracky=3, oddly_breakable_by_hand=3},
|
|
recipe = {
|
|
{"default:glass", "default:glass", "default:glass"},
|
|
{"default:glass", "default:glass", "default:glass"}
|
|
}
|
|
})
|
|
|
|
xpanes.register_pane("bar", {
|
|
description = "Iron bar",
|
|
textures = {"xpanes_bar.png","xpanes_bar.png","xpanes_space.png"},
|
|
inventory_image = "xpanes_bar.png",
|
|
wield_image = "xpanes_bar.png",
|
|
groups = {cracky=2},
|
|
sounds = default.node_sound_stone_defaults(),
|
|
recipe = {
|
|
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
|
|
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}
|
|
}
|
|
})
|
|
|
|
minetest.register_lbm({
|
|
name = "xpanes:gen2",
|
|
nodenames = {"group:pane"},
|
|
action = function(pos, node)
|
|
update_pane(pos)
|
|
for i = 0, 3 do
|
|
local dir = minetest.facedir_to_dir(i)
|
|
update_pane(vector.add(pos, dir))
|
|
end
|
|
end
|
|
})
|