88 lines
2.2 KiB
Lua
88 lines
2.2 KiB
Lua
|
|
local char, byte = string.char, string.byte
|
|
|
|
local function encode_uint16(int)
|
|
local a, b = int % 0x100, int / 0x100
|
|
return char(a, b)
|
|
end
|
|
|
|
local function decode_uint16(str, ofs)
|
|
ofs = ofs or 1
|
|
local a = byte(str, ofs)
|
|
local b = byte(str, ofs + 1)
|
|
return a + b * 0x100
|
|
end
|
|
|
|
function pick_and_place.serialize(pos1, pos2)
|
|
local manip = minetest.get_voxel_manip()
|
|
local e1, e2 = manip:read_from_map(pos1, pos2)
|
|
local area = VoxelArea:new({MinEdge=e1, MaxEdge=e2})
|
|
|
|
local node_data = manip:get_data()
|
|
local param2 = manip:get_param2_data()
|
|
|
|
local mapdata = {}
|
|
local metadata = {}
|
|
|
|
for z=pos1.z,pos2.z do
|
|
for x=pos1.x,pos2.x do
|
|
for y=pos1.y,pos2.y do
|
|
local i = area:index(x,y,z)
|
|
table.insert(mapdata, encode_uint16(node_data[i]))
|
|
table.insert(mapdata, char(param2[i]))
|
|
end
|
|
end
|
|
end
|
|
|
|
-- TODO: metadata
|
|
|
|
local size = vector.add(vector.subtract(pos2, pos1), 1)
|
|
|
|
local data = {
|
|
mapdata = table.concat(mapdata),
|
|
metadata = metadata,
|
|
size = size
|
|
}
|
|
|
|
local serialized_data = minetest.serialize(data)
|
|
local compressed_data = minetest.compress(serialized_data, "deflate")
|
|
local encoded_data = minetest.encode_base64(compressed_data)
|
|
|
|
return encoded_data
|
|
end
|
|
|
|
|
|
function pick_and_place.deserialize(pos1, encoded_data)
|
|
|
|
local compressed_data = minetest.decode_base64(encoded_data)
|
|
local serialized_data = minetest.decompress(compressed_data, "deflate")
|
|
local data = minetest.deserialize(serialized_data)
|
|
|
|
local pos2 = vector.add(pos1, vector.subtract(data.size, 1))
|
|
|
|
local manip = minetest.get_voxel_manip()
|
|
local e1, e2 = manip:read_from_map(pos1, pos2)
|
|
local area = VoxelArea:new({MinEdge=e1, MaxEdge=e2})
|
|
|
|
local node_data = manip:get_data()
|
|
local param2 = manip:get_param2_data()
|
|
|
|
local j = 1
|
|
|
|
for z=pos1.z,pos2.z do
|
|
for x=pos1.x,pos2.x do
|
|
for y=pos1.y,pos2.y do
|
|
local i = area:index(x,y,z)
|
|
node_data[i] = decode_uint16(data.mapdata, j)
|
|
j = j + 2
|
|
param2[i] = byte(data.mapdata, j)
|
|
j = j + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
manip:set_data(node_data)
|
|
manip:set_param2_data(param2)
|
|
manip:write_to_map()
|
|
end
|