mirror of
https://github.com/appgurueu/modlib.git
synced 2024-11-26 09:13:53 +01:00
Experimental schematic format
This commit is contained in:
parent
4bf8d23917
commit
db08d8bbde
@ -234,6 +234,12 @@ Dumps local variables, upvalues and the function environment of the function at
|
|||||||
|
|
||||||
Dumps function info & variables for all functions in stack, starting with stacklevel (default `1`).
|
Dumps function info & variables for all functions in stack, starting with stacklevel (default `1`).
|
||||||
|
|
||||||
|
## `minetest`
|
||||||
|
|
||||||
|
### `schematic`
|
||||||
|
|
||||||
|
A schematic format with support for metadata and baked light data. **Experimental.**
|
||||||
|
|
||||||
## Release Notes
|
## Release Notes
|
||||||
|
|
||||||
### `rolling-68`
|
### `rolling-68`
|
||||||
|
3
init.lua
3
init.lua
@ -65,7 +65,8 @@ if minetest then
|
|||||||
"liquid",
|
"liquid",
|
||||||
"raycast",
|
"raycast",
|
||||||
"wielditem_change",
|
"wielditem_change",
|
||||||
"colorspec"
|
"colorspec",
|
||||||
|
"schematic"
|
||||||
}
|
}
|
||||||
for _, file in pairs{
|
for _, file in pairs{
|
||||||
"data",
|
"data",
|
||||||
|
110
minetest/schematic.lua
Normal file
110
minetest/schematic.lua
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
schematic = {}
|
||||||
|
local metatable = {__index = schematic}
|
||||||
|
|
||||||
|
function schematic.setmetatable(self)
|
||||||
|
return setmetatable(self, metatable)
|
||||||
|
end
|
||||||
|
|
||||||
|
function schematic.create(self, pos_min, pos_max)
|
||||||
|
-- Don't use the metatable for the defaults to force a serialization
|
||||||
|
self.baked_light = self.backed_light or false
|
||||||
|
self.meta_data = self.meta_data or true
|
||||||
|
self.size = vector.subtract(pos_max, pos_min)
|
||||||
|
local voxelmanip = minetest.get_voxel_manip(pos_min, pos_max)
|
||||||
|
local emin, emax = voxelmanip:read_from_map(pos_min, pos_max)
|
||||||
|
local voxelarea = VoxelArea:new{ MinEdge = emin, MaxEdge = emax }
|
||||||
|
local meta_data = {}
|
||||||
|
for _, pos in ipairs(minetest.find_nodes_with_meta(pos_min, pos_max)) do
|
||||||
|
local meta = minetest.get_meta(pos):to_table()
|
||||||
|
if next(meta.fields) ~= nil or next(meta.inventory) ~= nil then
|
||||||
|
meta_data[voxelarea:indexp(pos)] = meta
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local data, light_data, param2_data = voxelmanip:get_data(), self.baked_light and voxelmanip:get_light_data() or {}, voxelmanip:get_param2_data()
|
||||||
|
local nodes = {}
|
||||||
|
for index in voxelarea:iterp(pos_min, pos_max) do
|
||||||
|
table.insert(nodes, {
|
||||||
|
name = minetest.get_name_from_content_id(data[index]),
|
||||||
|
light = light_data[index],
|
||||||
|
param2 = param2_data[index],
|
||||||
|
meta = meta_data[index]
|
||||||
|
})
|
||||||
|
end
|
||||||
|
self.nodes = nodes
|
||||||
|
return schematic.setmetatable(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
function schematic:write_to_voxelmanip(voxelmanip, pos_min)
|
||||||
|
local pos_max = vector.add(pos_min, self.size)
|
||||||
|
local emin, emax = voxelmanip:read_from_map(pos_min, pos_max)
|
||||||
|
local voxelarea = VoxelArea:new{ MinEdge = emin, MaxEdge = emax }
|
||||||
|
local data, light_data, param2_data = voxelmanip:get_data(), self.baked_light and voxelmanip:get_light_data(), voxelmanip:get_param2_data()
|
||||||
|
for _, pos in ipairs(minetest.find_nodes_with_meta(pos_min, pos_max)) do
|
||||||
|
-- Clear all metadata. Due to an engine bug, nodes will actually have empty metadata.
|
||||||
|
minetest.get_meta(pos):from_table{}
|
||||||
|
end
|
||||||
|
local i = 1
|
||||||
|
for index in voxelarea:iterp(pos_min, pos_max) do
|
||||||
|
local node = self.nodes[i]
|
||||||
|
i = i + 1
|
||||||
|
data[index] = minetest.get_content_id(node.name)
|
||||||
|
if data[index] == nil then
|
||||||
|
error(("unknown node %q"):format(node.name))
|
||||||
|
end
|
||||||
|
if self.baked_light then
|
||||||
|
light_data[index] = node.light
|
||||||
|
end
|
||||||
|
param2_data[index] = node.param2
|
||||||
|
if node.meta then
|
||||||
|
-- TODO consider removing this check by using a separate table [index] = meta for node meta
|
||||||
|
minetest.get_meta(voxelarea:position(index)):from_table(node.meta)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
voxelmanip:set_data(data)
|
||||||
|
if self.baked_light then
|
||||||
|
voxelmanip:set_light_data(light_data)
|
||||||
|
end
|
||||||
|
voxelmanip:set_param2_data(param2_data)
|
||||||
|
end
|
||||||
|
|
||||||
|
function schematic:place(pos_min)
|
||||||
|
local pos_max = vector.add(pos_min, self.size)
|
||||||
|
local voxelmanip = minetest.get_voxel_manip(pos_min, pos_max)
|
||||||
|
self:write_to_voxelmanip(voxelmanip, pos_min)
|
||||||
|
voxelmanip:write_to_map(not self.baked_light)
|
||||||
|
return voxelmanip
|
||||||
|
end
|
||||||
|
|
||||||
|
function schematic:write_bluon(path)
|
||||||
|
local file = io.open(path, "w")
|
||||||
|
-- Header, short for "ModLib Bluon Schematic"
|
||||||
|
file:write"MLBS"
|
||||||
|
modlib.bluon:write(self, file)
|
||||||
|
file:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function schematic.read_bluon(path)
|
||||||
|
local file = io.open(path, "r")
|
||||||
|
assert(file:read(4) == "MLBS", "not a modlib bluon schematic")
|
||||||
|
local self = modlib.bluon:read(file)
|
||||||
|
assert(not file:read(), "expected EOF")
|
||||||
|
return schematic.setmetatable(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
function schematic:write_zlib_bluon(path, compression)
|
||||||
|
local file = io.open(path, "w")
|
||||||
|
-- Header, short for "ModLib Zlib-compressed-bluon Schematic"
|
||||||
|
file:write"MLZS"
|
||||||
|
local rope = modlib.table.rope{}
|
||||||
|
modlib.bluon:write(self, rope)
|
||||||
|
local text = rope:to_text()
|
||||||
|
file:write(minetest.compress(text, "deflate", compression or 9))
|
||||||
|
file:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function schematic.read_zlib_bluon(path)
|
||||||
|
local file = io.open(path, "r")
|
||||||
|
assert(file:read(4) == "MLZS", "not a modlib zlib compressed bluon schematic")
|
||||||
|
local self = modlib.bluon:read(modlib.text.inputstream(minetest.decompress(file:read"*a", "deflate")))
|
||||||
|
return schematic.setmetatable(self)
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user