mirror of
https://github.com/Uberi/Minetest-WorldEdit.git
synced 2024-11-15 23:20:16 +01:00
wip
This commit is contained in:
parent
f6298d7b87
commit
eb1627ca99
|
@ -1,9 +1,7 @@
|
||||||
--- Schematic serialization and deserialiation.
|
--- Schematic serialization and deserialiation.
|
||||||
-- @module worldedit.serialization
|
-- @module worldedit.serialization
|
||||||
|
|
||||||
worldedit.LATEST_SERIALIZATION_VERSION = 5
|
worldedit.LATEST_SERIALIZATION_VERSION = 6
|
||||||
local LATEST_SERIALIZATION_HEADER = worldedit.LATEST_SERIALIZATION_VERSION .. ":"
|
|
||||||
|
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
Serialization version history:
|
Serialization version history:
|
||||||
|
@ -15,6 +13,7 @@ Serialization version history:
|
||||||
`name`, `param1`, `param2`, and `meta` fields.
|
`name`, `param1`, `param2`, and `meta` fields.
|
||||||
5: Added header and made `param1`, `param2`, and `meta` fields optional.
|
5: Added header and made `param1`, `param2`, and `meta` fields optional.
|
||||||
Header format: <Version>,<ExtraHeaderField1>,...:<Content>
|
Header format: <Version>,<ExtraHeaderField1>,...:<Content>
|
||||||
|
6: Much more complicated but also better format
|
||||||
--]]
|
--]]
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,52 +65,101 @@ function worldedit.serialize(pos1, pos2)
|
||||||
has_meta[hash_node_position(meta_positions[i])] = true
|
has_meta[hash_node_position(meta_positions[i])] = true
|
||||||
end
|
end
|
||||||
|
|
||||||
local pos = {x=pos1.x, y=0, z=0}
|
-- Decide axis of saved rows
|
||||||
|
local dim = vector.add(vector.subtract(pos2, pos1), 1)
|
||||||
|
local axis
|
||||||
|
if dim.x * dim.y < math.min(dim.y * dim.z, dim.x * dim.z) then
|
||||||
|
axis = "z"
|
||||||
|
elseif dim.x * dim.z < math.min(dim.x * dim.y, dim.y * dim.z) then
|
||||||
|
axis = "y"
|
||||||
|
elseif dim.y * dim.z < math.min(dim.x * dim.y, dim.x * dim.z) then
|
||||||
|
axis = "x"
|
||||||
|
else
|
||||||
|
axis = "x" -- X or Z are usually most efficient
|
||||||
|
end
|
||||||
|
local other1, other2 = worldedit.get_axis_others(axis)
|
||||||
|
|
||||||
|
-- Helper functions
|
||||||
|
local function cur_new(pos, pos1)
|
||||||
|
return {
|
||||||
|
a = axis,
|
||||||
|
p = {pos.x - pos1.x, pos.y - pos1.y, pos.z - pos1.z},
|
||||||
|
c = 1,
|
||||||
|
data = {},
|
||||||
|
param1 = {},
|
||||||
|
param2 = {},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
local function try_match(array, value)
|
||||||
|
local match_dist = 8
|
||||||
|
local first = math.max(1, #array - match_dist + 1)
|
||||||
|
local i = #array
|
||||||
|
while i >= first do
|
||||||
|
if array[i] == value then
|
||||||
|
return -(#array - i + 1)
|
||||||
|
end
|
||||||
|
i = i - 1
|
||||||
|
end
|
||||||
|
return value
|
||||||
|
end
|
||||||
|
local function cur_finish(result, cur)
|
||||||
|
if #cur.param1 == 1 and cur.param1[1] == 0 then
|
||||||
|
cur.param1 = nil
|
||||||
|
end
|
||||||
|
if #cur.param2 == 1 and cur.param2[1] == 0 then
|
||||||
|
cur.param2 = nil
|
||||||
|
end
|
||||||
|
result[#result + 1] = cur
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Serialize stuff
|
||||||
|
local pos = {}
|
||||||
local count = 0
|
local count = 0
|
||||||
local result = {}
|
local result = {}
|
||||||
while pos.x <= pos2.x do
|
local cur
|
||||||
pos.y = pos1.y
|
pos[other1] = pos1[other1]
|
||||||
while pos.y <= pos2.y do
|
while pos[other1] <= pos2[other1] do
|
||||||
pos.z = pos1.z
|
pos[other2] = pos1[other2]
|
||||||
while pos.z <= pos2.z do
|
while pos[other2] <= pos2[other2] do
|
||||||
|
pos[axis] = pos1[axis]
|
||||||
|
while pos[axis] <= pos2[axis] do
|
||||||
|
|
||||||
local node = get_node(pos)
|
local node = get_node(pos)
|
||||||
if node.name ~= "air" and node.name ~= "ignore" then
|
if node.name ~= "air" and node.name ~= "ignore" then
|
||||||
count = count + 1
|
if cur == nil then -- Start a new row
|
||||||
|
cur = cur_new(pos, pos1, axis, other1, other2)
|
||||||
local meta
|
cur.data[1] = node.name
|
||||||
if has_meta[hash_node_position(pos)] then
|
cur.param1[1] = node.param1
|
||||||
meta = get_meta(pos):to_table()
|
cur.param2[1] = node.param2
|
||||||
|
else -- Push to existing row
|
||||||
-- Convert metadata item stacks to item strings
|
local next_c = cur.c + 1
|
||||||
for _, invlist in pairs(meta.inventory) do
|
cur.c = next_c
|
||||||
for index = 1, #invlist do
|
cur.data[next_c] = try_match(cur.data, node.name)
|
||||||
local itemstack = invlist[index]
|
cur.param1[next_c] = try_match(cur.param1, node.param1)
|
||||||
if itemstack.to_string then
|
cur.param2[next_c] = try_match(cur.param2, node.param2)
|
||||||
invlist[index] = itemstack:to_string()
|
end
|
||||||
end
|
count = count + 1
|
||||||
end
|
else
|
||||||
end
|
if cur ~= nil then -- Finish row
|
||||||
|
cur_finish(result, cur)
|
||||||
|
cur = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
result[count] = {
|
|
||||||
x = pos.x - pos1.x,
|
|
||||||
y = pos.y - pos1.y,
|
|
||||||
z = pos.z - pos1.z,
|
|
||||||
name = node.name,
|
|
||||||
param1 = node.param1 ~= 0 and node.param1 or nil,
|
|
||||||
param2 = node.param2 ~= 0 and node.param2 or nil,
|
|
||||||
meta = meta,
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
pos.z = pos.z + 1
|
pos[axis] = pos[axis] + 1
|
||||||
|
|
||||||
end
|
end
|
||||||
pos.y = pos.y + 1
|
if cur ~= nil then -- Finish leftover row
|
||||||
|
cur_finish(result, cur)
|
||||||
|
cur = nil
|
||||||
|
end
|
||||||
|
pos[other2] = pos[other2] + 1
|
||||||
end
|
end
|
||||||
pos.x = pos.x + 1
|
pos[other1] = pos[other1] + 1
|
||||||
end
|
end
|
||||||
-- Serialize entries
|
-- Serialize entries
|
||||||
result = minetest.serialize(result)
|
result = minetest.serialize(result)
|
||||||
return LATEST_SERIALIZATION_HEADER .. result, count
|
return tonumber(worldedit.LATEST_SERIALIZATION_VERSION) .. "," ..
|
||||||
|
string.format("%d,%d,%d:", dim.x, dim.y, dim.z) .. result, count
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user