working pick and place
This commit is contained in:
parent
e85e401f91
commit
cc995a8700
@ -24,8 +24,13 @@ function pick_and_place.configure(pos1, pos2)
|
||||
if node.name == "air" then
|
||||
minetest.set_node(cpos, { name = "pick_and_place:handle" })
|
||||
local meta = minetest.get_meta(cpos)
|
||||
meta:set_string("pos1", minetest.pos_to_string(pos1))
|
||||
meta:set_string("pos2", minetest.pos_to_string(pos2))
|
||||
|
||||
-- relative positions
|
||||
local rel_pos1 = vector.subtract(pos1, cpos)
|
||||
local rel_pos2 = vector.subtract(pos2, cpos)
|
||||
|
||||
meta:set_string("pos1", minetest.pos_to_string(rel_pos1))
|
||||
meta:set_string("pos2", minetest.pos_to_string(rel_pos2))
|
||||
end
|
||||
end
|
||||
end
|
@ -5,15 +5,25 @@ local function on_rightclick(pos, _, _, itemstack)
|
||||
end
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
local pos1 = minetest.string_to_pos(meta:get_string("pos1"))
|
||||
local pos2 = minetest.string_to_pos(meta:get_string("pos2"))
|
||||
local size = vector.add(vector.subtract(pos2, pos1), 1)
|
||||
|
||||
-- relative positions
|
||||
local rel_pos1 = minetest.string_to_pos(meta:get_string("pos1"))
|
||||
local rel_pos2 = minetest.string_to_pos(meta:get_string("pos2"))
|
||||
|
||||
-- absolute positions
|
||||
local pos1 = vector.add(pos, rel_pos1)
|
||||
local pos2 = vector.add(pos, rel_pos2)
|
||||
|
||||
local size = vector.add(vector.subtract(pos2, pos1), 1)
|
||||
|
||||
local tool = ItemStack("pick_and_place:place 1")
|
||||
local tool_meta = tool:get_meta()
|
||||
tool_meta:set_string("size", minetest.pos_to_string(size))
|
||||
|
||||
-- serialize schematic
|
||||
local schematic = pick_and_place.serialize(pos1, pos2)
|
||||
tool_meta:set_string("schematic", schematic)
|
||||
|
||||
return tool
|
||||
end
|
||||
|
||||
|
@ -6,7 +6,10 @@ minetest.register_tool("pick_and_place:place", {
|
||||
on_use = function(itemstack, player)
|
||||
print("on_use: " .. itemstack:get_name() .. ", " .. player:get_player_name())
|
||||
|
||||
|
||||
local pointed_pos = pick_and_place.get_pointed_position(player)
|
||||
local meta = itemstack:get_meta()
|
||||
local schematic = meta:get_string("schematic")
|
||||
pick_and_place.deserialize(pointed_pos, schematic)
|
||||
end,
|
||||
on_secondary_use = function(itemstack, player)
|
||||
print("on_secondary_use: " .. itemstack:get_name() .. ", " .. player:get_player_name())
|
||||
|
@ -1,8 +1,96 @@
|
||||
|
||||
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)
|
||||
|
||||
-- TODO
|
||||
print(dump({
|
||||
fn = "pick_and_place.serialize",
|
||||
size = data.size,
|
||||
serialized_data_len = #serialized_data,
|
||||
compressed_data_len = #compressed_data,
|
||||
encoded_data_len = #encoded_data
|
||||
}))
|
||||
|
||||
return encoded_data
|
||||
end
|
||||
|
||||
function pick_and_place.deserialize(origin, data, rotation)
|
||||
-- TODO
|
||||
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user