diff --git a/basis/pack_lib.lua b/basis/pack_lib.lua index 3b3c4a8..83f5033 100644 --- a/basis/pack_lib.lua +++ b/basis/pack_lib.lua @@ -69,7 +69,7 @@ end -- on_pack/on_unpack fallback functions local function on_pack_fallback_(pos, node) - print("on_pack_fallback_",P2S(pos), node.name) + --print("on_pack_fallback_",P2S(pos), node.name) local smeta = techage.pack_meta(pos) local snvm = techage.pack_nvm(pos) minetest.remove_node(pos) @@ -77,7 +77,7 @@ local function on_pack_fallback_(pos, node) end local function on_unpack_fallback(pos, name, param2, data) - print("on_unpack_fallback",P2S(pos), name) + --print("on_unpack_fallback",P2S(pos), name) minetest.add_node(pos, {name = name, param2 = param2}) techage.unpack_meta(pos, data.smeta) if data.snvm then @@ -85,57 +85,94 @@ local function on_unpack_fallback(pos, name, param2, data) end end --- cpos is the center pos --- npos the the node pos --- turn is one of "l", "r", "2l", "2r" -local function get_new_node_pos(cpos, npos, turn, item) - item.param2 = techage.rotate_param2(item, turn) - return techage.rotate_around_axis(npos, cpos, turn) -end - +------------------------------------------------------------------------------- -- pack/unpack API functions -function techage.pack_nodes(pos, pos_list) - print("pack_nodes", P2S(pos), #pos_list) - local tbl = {} - for idx, rpos in ipairs(pos_list or {}) do - local pos2 = vector.add(pos, rpos) +------------------------------------------------------------------------------- +-- pos_list is a list of node positions +function techage.pack_nodes(pos_list) + local pack_tbl = {} + for _, pos2 in ipairs(pos_list or {}) do local node = minetest.get_node(pos2) - --print("node", node.name, P2S(pos)) local ndef = minetest.registered_nodes[node.name] if ndef and ndef.on_pack then - tbl[rpos] = {name = node.name, param2 = node.param2, data = ndef.on_pack(pos2, node)} + pack_tbl[pos2] = {name = node.name, param2 = node.param2, data = ndef.on_pack(pos2, node)} else - tbl[rpos] = {name = node.name, param2 = node.param2, data = on_pack_fallback_(pos2, node)} + pack_tbl[pos2] = {name = node.name, param2 = node.param2, data = on_pack_fallback_(pos2, node)} end end - return tbl + return pack_tbl end -function techage.unpack_nodes(pos, tbl, turn) - print("unpack_nodes", P2S(pos), turn) +function techage.unpack_nodes(pack_tbl) -- Check positions - for rpos, item in pairs(tbl or {}) do - local pos2 = vector.add(pos, rpos) - pos2 = techage.rotate_around_axis(pos2, pos, turn) + for pos2, _ in pairs(pack_tbl or {}) do local node = minetest.get_node(pos2) if not techage.is_air_like(node.name) then return false end end -- Place nodes - local out = {} - for rpos, item in pairs(tbl or {}) do - local pos2 = vector.add(pos, rpos) - item.param2 = techage.rotate_param2(item, turn) - pos2 = techage.rotate_around_axis(pos2, pos, turn) + for pos2, item in pairs(pack_tbl or {}) do local ndef = minetest.registered_nodes[item.name] if ndef and ndef.on_unpack then ndef.on_unpack(pos2, item.name, item.param2, item.data) else on_unpack_fallback(pos2, item.name, item.param2, item.data) end - -- Because of the rotated arrangement, generate a new rel-pos table - table.insert(out, vector.subtract(pos2, pos)) + end + return true +end + +------------------------------------------------------------------------------- +-- move/turn API functions +------------------------------------------------------------------------------- +function techage.determine_turn_rotation(old_param2, new_param2) + local offs = new_param2 - old_param2 + if offs == -1 or offs == 3 then return "l" + elseif offs == 1 or offs == -3 then return "r" + elseif offs == 2 or offs == -2 then return "2r" + else return "" end +end + +-- move is the distance between old and new pos as vector +function techage.adjust_pos_list_move(pos_list, move) + local out = {} + for idx, pos in ipairs(pos_list or {}) do + local pos2 = vector.add(pos, move) + out[idx] = pos2 + end + return out +end + +-- Adjust the data for a turn of all nodes around cpos +-- turn is one of "l", "r", "2l", "2r" +function techage.adjust_pos_list_turn(cpos, pos_list, turn) + local out = {} + for idx, npos in ipairs(pos_list or {}) do + local pos2 = techage.rotate_around_axis(npos, cpos, turn) + out[idx] = pos2 + end + return out +end + +-- move is the distance between old and new pos as vector +function techage.adjust_pack_tbl_move(pack_tbl, move) + local out = {} + for pos, item in pairs(pack_tbl or {}) do + local pos2 = vector.add(pos, move) + out[pos2] = item + end + return out +end + +-- Adjust the data for a turn of all nodes around cpos +-- turn is one of "l", "r", "2l", "2r" +function techage.adjust_pack_tbl_turn(cpos, pack_tbl, turn) + local out = {} + for npos, item in pairs(pack_tbl or {}) do + item.param2 = techage.rotate_param2(item, turn) + local pos2 = techage.rotate_around_axis(npos, cpos, turn) + out[pos2] = item end return out end diff --git a/move_controller/packcontainer.lua b/move_controller/packcontainer.lua index e707424..a3b9e62 100644 --- a/move_controller/packcontainer.lua +++ b/move_controller/packcontainer.lua @@ -43,15 +43,6 @@ local function formspec(nvm, meta) "label[0.3,3.9;" .. status .. "]" end -local function get_rposlist(pos, pos_list) - local lst = {} - for _,item_pos in ipairs(pos_list or {}) do - local rpos = vector.subtract(item_pos, pos) - table.insert(lst, rpos) - end - return lst -end - local function set_storage_pos(pos, oldnode, oldmetadata, drops) if oldmetadata.data_stored == "1" then local meta = drops[1]:get_meta() @@ -63,48 +54,55 @@ local function set_storage_pos(pos, oldnode, oldmetadata, drops) end end -local function get_storage_pos(pos, nvm, itemstack) +local function get_storage_pos(pos, itemstack) local imeta = itemstack:get_meta() if imeta then local meta = M(pos) meta:set_string("node_name", imeta:get_string("node_name")) meta:set_string("status", imeta:get_string("status")) meta:set_int("data_stored", imeta:get_int("data_stored")) - nvm.storage_pos = S2P(imeta:get_string("storage_pos")) - return nvm.storage_pos ~= nil + local pos2 = S2P(imeta:get_string("storage_pos")) + if pos2 then + local node = techage.get_node_lvm(pos2) + if node.name == "techage:ta5_packcontainer_storage" then + return pos2, node.param2 + end + end end end -local function copy_data_and_remove_node(mypos, rmtpos) - local nvm1 = techage.get_nvm(mypos) - local nvm2 = techage.get_nvm(rmtpos) - nvm1.lrpos = nvm2.lrpos - nvm1.pack_tbl = nvm2.pack_tbl - minetest.remove_node(rmtpos) - techage.del_mem(rmtpos) +local function takeover_data(old_pos, new_pos) + local nvm1 = techage.get_nvm(old_pos) + local nvm2 = techage.get_nvm(new_pos) + nvm2.pos_list = nvm1.pos_list + nvm2.pack_tbl = nvm1.pack_tbl end -local function determine_rotation(old_param2, new_param2) - local offs = new_param2 - old_param2 - print("determine_rotation", offs) - if offs == 0 then return "" - elseif offs == -1 then return "l" - elseif offs == 1 then return "r" - else return "2r" end +local function remove_storage_node(old_pos) + minetest.remove_node(old_pos) + techage.del_mem(old_pos) +end + +local function adjust_database(pos, nvm, move, turn) + nvm.pos_list = techage.adjust_pos_list_move(nvm.pos_list, move) + nvm.pos_list = techage.adjust_pos_list_turn(pos, nvm.pos_list, turn) + nvm.pack_tbl = techage.adjust_pack_tbl_move(nvm.pack_tbl, move) + nvm.pack_tbl = techage.adjust_pack_tbl_turn(pos, nvm.pack_tbl, turn) end local function after_place_node(pos, placer, itemstack) - local meta = M(pos) local nvm = techage.get_nvm(pos) + local meta = M(pos) meta:set_string("infotext", DESCRIPTION) meta:set_string("owner", placer:get_player_name()) - if get_storage_pos(pos, nvm, itemstack) then - local node = techage.get_node_lvm(nvm.storage_pos) - if node.name == "techage:ta5_packcontainer_storage" then - nvm.turn = determine_rotation(node.param2, minetest.get_node(pos).param2) - copy_data_and_remove_node(pos, nvm.storage_pos) - nvm.storage_pos = nil - end + local old_pos, old_param2 = get_storage_pos(pos, itemstack) + if old_pos then + local new_param2 = minetest.get_node(pos).param2 + local turn = techage.determine_turn_rotation(old_param2, new_param2) + local move = vector.subtract(pos, old_pos) + takeover_data(old_pos, pos) + adjust_database(pos, nvm, move, turn) + remove_storage_node(old_pos) end meta:set_string("formspec", formspec(nvm, meta)) end @@ -119,7 +117,7 @@ local function on_receive_fields(pos, formname, fields, player) local data_stored = meta:get_int("data_stored") == 1 if fields.record and not data_stored then - nvm.lrpos = nil + nvm.pos_list = nil meta:set_string("status", S("Recording...")) local name = player:get_player_name() minetest.chat_send_player(name, S("Click on all blocks that shall be turned")) @@ -130,31 +128,26 @@ local function on_receive_fields(pos, formname, fields, player) meta:set_string("formspec", formspec(nvm, meta)) elseif fields.done and not data_stored then local name = player:get_player_name() - local pos_list = mark.get_poslist(name) - local text = #pos_list.." "..S("block positions are stored.") + nvm.pos_list = mark.get_poslist(name) or {} + local text = #(nvm.pos_list).." "..S("block positions are stored.") meta:set_string("status", text) meta:set_string("node_name", fields.node_name) - nvm.lrpos = get_rposlist(pos, pos_list) mark.unmark_all(name) mark.stop(name) meta:set_string("formspec", formspec(nvm, meta)) - elseif fields.pack and nvm.lrpos and #nvm.lrpos > 0 and not data_stored then - nvm.pack_tbl = techage.pack_nodes(pos, nvm.lrpos or {}) + elseif fields.pack and nvm.pos_list and #nvm.pos_list > 0 and not data_stored then + nvm.pack_tbl = techage.pack_nodes(nvm.pos_list) meta:set_string("status", S("Blocks stored")) meta:set_string("formspec", formspec(nvm, meta)) meta:set_int("data_stored", 1) - elseif fields.unpack and data_stored then - local tbl = techage.unpack_nodes(pos, nvm.pack_tbl, nvm.turn or "") - if tbl then - nvm.lrpos = tbl + elseif fields.unpack and data_stored and nvm.pack_tbl then + if techage.unpack_nodes(nvm.pack_tbl) then meta:set_string("status", S("Blocks placed")) - meta:set_string("formspec", formspec(nvm, meta)) meta:set_int("data_stored", 0) - nvm.turn = "" else meta:set_string("status", S("Position(s) occupied")) - meta:set_string("formspec", formspec(nvm, meta)) end + meta:set_string("formspec", formspec(nvm, meta)) end end