From 7976793d69c0c8cbea7caa048b237474500f9caa Mon Sep 17 00:00:00 2001 From: Zenon Seth Date: Tue, 21 Nov 2023 22:48:29 +0000 Subject: [PATCH] Initial work on Wireless Access Pad --- api/access_point.lua | 14 +++--- logic/access_point.lua | 8 ++-- logic/access_point_formspec.lua | 82 ++++++++++++++++++++++++-------- logic/groups.lua | 2 + textures/logistica_wap.png | Bin 0 -> 1991 bytes tools/misc.lua | 40 ++++++++++++++++ tools/tools.lua | 42 ++-------------- tools/wireless_access_pad.lua | 80 +++++++++++++++++++++++++++++++ 8 files changed, 197 insertions(+), 71 deletions(-) create mode 100644 textures/logistica_wap.png create mode 100644 tools/misc.lua create mode 100644 tools/wireless_access_pad.lua diff --git a/api/access_point.lua b/api/access_point.lua index 5f7ad16..e7fdda9 100644 --- a/api/access_point.lua +++ b/api/access_point.lua @@ -68,7 +68,7 @@ function logistica.register_access_point(desc, name, tiles) local lname = string.lower(name:gsub(" ", "_")) local access_point_name = "logistica:"..lname logistica.misc_machines[access_point_name] = true - local grps = {oddly_breakable_by_hand = 3, cracky = 3 } + local grps = {oddly_breakable_by_hand = 3, cracky = 3, [logistica.TIER_ACCESS_POINT] = 1 } grps[logistica.TIER_ALL] = 1 local def = { description = desc, @@ -85,12 +85,12 @@ function logistica.register_access_point(desc, name, tiles) after_place_node = after_place_access_point, after_dig_node = logistica.on_access_point_change, on_rightclick = on_access_point_rightclick, - on_metadata_inventory_move = on_access_point_inv_move, - on_metadata_inventory_put = on_access_point_inv_put, - on_metadata_inventory_take = on_access_point_inv_take, - allow_metadata_inventory_put = allow_access_point_inv_put, - allow_metadata_inventory_take = allow_access_point_inv_take, - allow_metadata_inventory_move = allow_access_point_inv_move, + -- on_metadata_inventory_move = on_access_point_inv_move, + -- on_metadata_inventory_put = on_access_point_inv_put, + -- on_metadata_inventory_take = on_access_point_inv_take, + -- allow_metadata_inventory_put = allow_access_point_inv_put, + -- allow_metadata_inventory_take = allow_access_point_inv_take, + -- allow_metadata_inventory_move = allow_access_point_inv_move, logistica = {} } diff --git a/logic/access_point.lua b/logic/access_point.lua index 28c7dc4..ec932d9 100644 --- a/logic/access_point.lua +++ b/logic/access_point.lua @@ -135,9 +135,9 @@ function logistica.access_point_on_player_close(playerName) fakeInvMap[playerName] = nil end -function logistica.update_fake_inv(pos, listName, listSize, playerName) +function logistica.update_fake_inv(pos, invName, listName, listSize, playerName) local meta = get_meta(pos) - local inv = meta:get_inventory() + local inv = minetest.get_inventory({type = "detached", name = invName}) local pageInfo = logistica.access_point_get_current_page_info(pos, playerName, listSize, meta) if pageInfo.max == 0 then inv:set_list(listName, {}) ; return end local startingPos = (pageInfo.curr - 1) * listSize + 1 @@ -216,10 +216,10 @@ function logistica.access_point_get_sort_highlight_images(meta, highlightImg, bl } end -function logistica.access_point_refresh_fake_inv(pos, listName, listSize, playerName) +function logistica.access_point_refresh_fake_inv(pos, invName, listName, listSize, playerName) local listInfo = build_stack_list(pos) fakeInvMap[playerName] = listInfo - logistica.update_fake_inv(pos, listName, listSize, playerName) + logistica.update_fake_inv(pos, invName, listName, listSize, playerName) end function logistica.access_point_set_filter_method(pos, playerName, method) diff --git a/logic/access_point_formspec.lua b/logic/access_point_formspec.lua index d685313..1f8811e 100644 --- a/logic/access_point_formspec.lua +++ b/logic/access_point_formspec.lua @@ -52,15 +52,41 @@ local STR_CLEAR_DESC = S("Clear search") local accessPointForms = {} +-- creates the inv and returns the inv name +local function get_or_create_detached_inventory(pos, playerName) + if accessPointForms[playerName] and accessPointForms[playerName].invName then + return accessPointForms[playerName].invName + end + local invName = playerName.."_LAP_"..logistica.get_rand_string_for(pos) + local inv = minetest.create_detached_inventory(invName, { + allow_move = logistica.access_point_allow_move, + allow_put = logistica.access_point_allow_put, + allow_take = logistica.access_point_allow_take, + on_move = logistica.access_point_on_inv_move, + on_put = logistica.access_point_on_put, + on_take = logistica.access_point_on_take, + }, playerName) + inv:set_size(INV_FAKE, FAKE_INV_SIZE) + inv:set_size(INV_INSERT, 1) + return invName +end + +local function get_curr_pos(player) + if not player or not player:is_player() then return end + local playerName = player:get_player_name() + if not accessPointForms[playerName] or not accessPointForms[playerName].position then return end + return accessPointForms[playerName].position +end + ---------------------------------------------------------------- -- formspec ---------------------------------------------------------------- -local function get_listrings(posForm) return +local function get_listrings(invName) return "listring[current_player;main]".. - "listring["..posForm..";"..INV_INSERT.."]".. + "listring[detached:"..invName..";"..INV_INSERT.."]".. "listring[current_player;main]".. - "listring["..posForm..";"..INV_FAKE.."]".. + "listring[detached:"..invName..";"..INV_FAKE.."]".. "listring[current_player;main]".. "listring[current_player;craft]".. "listring[current_player;main]".. @@ -118,8 +144,8 @@ local function get_search_and_page_section(searchTerm, pageInfo) return "image_button[13.9,6.5;0.8,0.8;logistica_icon_last.png;"..LAST_BTN..";;false;false;]" end -local function get_access_point_formspec(pos, optMeta, playerName) - local posForm = "nodemeta:"..pos.x..","..pos.y..","..pos.z +local function get_access_point_formspec(pos, invName, optMeta, playerName) + --local posForm = "nodemeta:"..pos.x..","..pos.y..","..pos.z local meta = optMeta or minetest.get_meta(pos) local currentNetwork = logistica.get_network_name_or_nil(pos) or S("") local filterHighImg = logistica.access_point_get_filter_highlight_images(meta, IMG_HIGHLGIHT, IMG_BLANK) @@ -131,14 +157,14 @@ local function get_access_point_formspec(pos, optMeta, playerName) return "formspec_version[4]".. "size[15.2,12.5]".. logistica.ui.background.. - "list["..posForm..";"..INV_FAKE..";0.2,0.2;"..FAKE_INV_W..","..FAKE_INV_H..";0]".. + "list[detached:"..invName..";"..INV_FAKE..";0.2,0.2;"..FAKE_INV_W..","..FAKE_INV_H..";0]".. "image[2.8,6.4;1,1;logistica_icon_input.png]".. - "list["..posForm..";"..INV_INSERT..";3.8,6.4;1,1;0]".. + "list[detached:"..invName..";"..INV_INSERT..";3.8,6.4;1,1;0]".. "list[current_player;main;5.2,7.5;8.0,4.0;0]".. "label[1.4,12.2;"..S("Crafting").."]".. "list[current_player;craft;0.2,8.4;3,3;]".. "list[current_player;craftpreview;3.9,8.4;1,1;]".. - get_listrings(posForm).. + get_listrings(invName).. get_filter_section(usesMetaStr, filterHighImg).. get_tooltips().. get_sort_section(sortHighImg).. @@ -148,12 +174,16 @@ end local function show_access_point_formspec(pos, playerName, optMeta) local meta = optMeta or minetest.get_meta(pos) - accessPointForms[playerName] = { position = pos } - logistica.access_point_refresh_fake_inv(pos, INV_FAKE, FAKE_INV_SIZE, playerName) + local invName = get_or_create_detached_inventory(pos, playerName) + accessPointForms[playerName] = { + position = pos, + invName = invName, + } + logistica.access_point_refresh_fake_inv(pos, invName, INV_FAKE, FAKE_INV_SIZE, playerName) minetest.show_formspec( playerName, FORMSPEC_NAME, - get_access_point_formspec(pos, meta, playerName) + get_access_point_formspec(pos, invName, meta, playerName) ) end @@ -211,17 +241,19 @@ end function logistica.access_point_after_place(pos, meta) local inv = meta:get_inventory() - inv:set_size(INV_FAKE, FAKE_INV_SIZE) - inv:set_size(INV_INSERT, 1) end -function logistica.access_point_allow_put(pos, listname, index, stack, player) +function logistica.access_point_allow_put(inv, listname, index, stack, player) if listname == INV_FAKE then return 0 end return stack:get_count() end -function logistica.access_point_allow_take(pos, listname, index, _stack, player) +function logistica.access_point_allow_take(inv, listname, index, _stack, player) local stack = ItemStack(_stack) + local pos = get_curr_pos(player) + if not pos then return 0 end + + logistica.load_position(pos) if listname == INV_FAKE then local network = logistica.get_network_or_nil(pos) if not network then @@ -255,19 +287,21 @@ function logistica.access_point_allow_take(pos, listname, index, _stack, player) return stack:get_count() end -function logistica.access_point_allow_move(pos, from_list, from_index, to_list, to_index, count, player) +function logistica.access_point_allow_move(inv, from_list, from_index, to_list, to_index, count, player) if from_list == INV_FAKE or to_list == INV_FAKE then return 0 end return count end -function logistica.access_point_on_inv_move(pos, from_list, from_index, to_list, to_index, count, player) +function logistica.access_point_on_inv_move(inv, from_list, from_index, to_list, to_index, count, player) end -function logistica.access_point_on_put(pos, listname, index, stack, player) +function logistica.access_point_on_put(inv, listname, index, stack, player) + local pos = get_curr_pos(player) + if not pos then return 0 end + logistica.load_position(pos) local networkId = logistica.get_network_id_or_nil(pos) if not networkId then show_access_point_formspec(pos, player:get_player_name()) ; return end if listname == INV_INSERT then - local inv = minetest.get_meta(pos):get_inventory() local stackToAdd = inv:get_stack(listname, index) local leftover = logistica.insert_item_in_network(stackToAdd, networkId) stack:set_count(leftover) @@ -276,10 +310,16 @@ function logistica.access_point_on_put(pos, listname, index, stack, player) end end -function logistica.access_point_on_take(pos, listname, index, stack, player) +function logistica.access_point_on_take(inv, listname, index, stack, player) if listname == INV_FAKE then + local pos = get_curr_pos(player) + if not pos then return 0 end + local invName = accessPointForms[player:get_player_name()].invName + if not invName then return 0 end + + logistica.load_position(pos) -- refresh the page in case we had to swap out a fake item or a stack is gone - logistica.access_point_refresh_fake_inv(pos, listname, FAKE_INV_SIZE, player:get_player_name()) + logistica.access_point_refresh_fake_inv(pos, invName, listname, FAKE_INV_SIZE, player:get_player_name()) end end diff --git a/logic/groups.lua b/logic/groups.lua index 95db607..b771e2c 100644 --- a/logic/groups.lua +++ b/logic/groups.lua @@ -14,6 +14,8 @@ logistica.GROUP_ALL = "group:" .. logistica.TIER_ALL logistica.TIER_CONTROLLER = "logistica_controller" logistica.TIER_CABLE_OFF = "logistica_cable_off" logistica.GROUP_CABLE_OFF = "group:" .. logistica.TIER_CABLE_OFF +logistica.TIER_ACCESS_POINT = "logistica_acspt" +logistica.GROUP_ACCESS_POINT = "group:" .. logistica.TIER_ACCESS_POINT function logistica.is_machine(name) return logistica.is_requester(name) or logistica.is_supplier(name) or logistica.is_mass_storage(name) diff --git a/textures/logistica_wap.png b/textures/logistica_wap.png new file mode 100644 index 0000000000000000000000000000000000000000..661a552354ad0949870596640d76b7b932a98f49 GIT binary patch literal 1991 zcmaJ?2}~4c6dp8yV9>Uba#UnGwDo9rXLk@R;|^pGgtaUJa_p{(3^TLKxU)OkomuyY zX=s%m#9B2bZ9OUoSS!Y;)udJpTUxJ>n$)Uk>|vs!E#8D!kD~o&78h2~N#^+f@4fH6 z|6TJ*S!q#HVtOJ3K}p79Lj`!l(mf##JcVFz0D@w5Y^7N=n@VtscPdGmuV<8gryJl9 zq$%*bNy@>9a6MyZT?BILP!|HTG=bFQm{caWo@roC0B~9y_Ye%gaMm7>Z#EAfXTfE|K&rTtb#a5#}&30_9=dBFnpAiIc47 zy&{1i0EdUjX)40)_Ify(nWj*NW1Ngj6i~HNjgFLO{OqtdE@3EKAaJOJ0C826xX9X` zAub`K#N7?N$O{d;JK|K7i3mJO5rlhe6+h`7OW0(3zPQsFbqql)Tn+*^l!Pdso){1+ z18xSbU#$|sRkUZnOQYloqSa6oGeObpmj1kBj3>{&{GA0zs11@`K z;%VSqw(Q(6WYp`+JiLwN047uv>0o1_K3AQWo2$T-VGAH>IM8Kn0Rt%lDNKcBE7WQQ zrmn;=9LvMAXIo`bSrD`hO^W1mM5VfiH8h2btjIC)D%=NJP7JTYOOBO_ALmGyok08w znz4~yPDJu44`~yZvLfRYG^o@s96LlJub!}I&?plc;GM~Y7qf!Mdjcb@E@a+~wko$B z49mrYla!PT0&#nI+DkFCd{E$j7!`P%=p#Lh)(+~3K(sa+3$hk~%cKT@K~t)fxzQTF z1_rQ=8A5dADV}(xK}Y!=KJJd^hDOF3SVRUR;{wyr1IAuL&aM&&ig}*} zi65142%53ZyRPdUU3v2Hf@Kx$vS+aKjxy5HH`f+sp>-~#w9^Cry$knMgiIiRIRvt~DuVtZ?+*N$mP!^Um9!pR~S~3^_LKnOpVao%HI{)@pO@n(3Qn z&glAAz4T(qx;bY8T<4sUz8J*Yd^{&zxJTC?r(&BAqYYF=et%K+uL{JpZfc4$5y&? zr!3)q8b2>X)z?@azZ$PQ6Vo=SPMh+b`bJiDQ@Z89w|k3Y!0TQ{NV;aNTK3B=pS*eE zN+{G=^h4uZ$dOz(aaR519T%YigKpQwBb-wif NH5Qf{cI)as_#fM#vvvRg literal 0 HcmV?d00001 diff --git a/tools/misc.lua b/tools/misc.lua new file mode 100644 index 0000000..73a6b87 --- /dev/null +++ b/tools/misc.lua @@ -0,0 +1,40 @@ +local S = logistica.TRANSLATOR + +minetest.register_craftitem("logistica:hyperspanner",{ + description = S("Hyperspanner\nA multipurpose engineering tool\nUse on nodes for network info.\nCan also reverse poliarity."), + short_description = S("Hyperspanner"), + inventory_image = "logistica_hyperspanner.png", + wield_image = "logistica_hyperspanner.png", + stack_max = 1, + on_place = function(itemstack, placer, pointed_thing) + local pos = pointed_thing.under + if not placer or not pos then return end + local node = minetest.get_node_or_nil(pos) + if not node or not logistica.is_machine(node.name) then return end + local network = logistica.get_network_name_or_nil(pos) or S("") + logistica.show_popup( + placer:get_player_name(), + "("..pos.x..","..pos.y..","..pos.z..") "..S("Network")..": "..network + ) + end +}) + +minetest.register_craftitem("logistica:wand",{ + description = S("Inv List Scanner"), + inventory_image = "logistica_wand.png", + wield_image = "logistica_wand.png", + stack_max = 1, + on_place = function(itemstack, placer, pointed_thing) + local pos = pointed_thing.under + if not placer or not pos then return end + local inv = minetest.get_meta(pos):get_inventory() + + local lists = inv:get_lists() + local names = "" + for name, _ in pairs(lists) do + names = names..name..", " + end + + logistica.show_popup(placer:get_player_name(), names) + end +}) diff --git a/tools/tools.lua b/tools/tools.lua index 73a6b87..2225944 100644 --- a/tools/tools.lua +++ b/tools/tools.lua @@ -1,40 +1,4 @@ -local S = logistica.TRANSLATOR +local path = logistica.MODPATH.."/tools" -minetest.register_craftitem("logistica:hyperspanner",{ - description = S("Hyperspanner\nA multipurpose engineering tool\nUse on nodes for network info.\nCan also reverse poliarity."), - short_description = S("Hyperspanner"), - inventory_image = "logistica_hyperspanner.png", - wield_image = "logistica_hyperspanner.png", - stack_max = 1, - on_place = function(itemstack, placer, pointed_thing) - local pos = pointed_thing.under - if not placer or not pos then return end - local node = minetest.get_node_or_nil(pos) - if not node or not logistica.is_machine(node.name) then return end - local network = logistica.get_network_name_or_nil(pos) or S("") - logistica.show_popup( - placer:get_player_name(), - "("..pos.x..","..pos.y..","..pos.z..") "..S("Network")..": "..network - ) - end -}) - -minetest.register_craftitem("logistica:wand",{ - description = S("Inv List Scanner"), - inventory_image = "logistica_wand.png", - wield_image = "logistica_wand.png", - stack_max = 1, - on_place = function(itemstack, placer, pointed_thing) - local pos = pointed_thing.under - if not placer or not pos then return end - local inv = minetest.get_meta(pos):get_inventory() - - local lists = inv:get_lists() - local names = "" - for name, _ in pairs(lists) do - names = names..name..", " - end - - logistica.show_popup(placer:get_player_name(), names) - end -}) +dofile(path.."/misc.lua") +dofile(path.."/wireless_access_pad.lua") diff --git a/tools/wireless_access_pad.lua b/tools/wireless_access_pad.lua new file mode 100644 index 0000000..c013777 --- /dev/null +++ b/tools/wireless_access_pad.lua @@ -0,0 +1,80 @@ +local S = logistica.TRANSLATOR + +local META_ACCESS_POINT_POSITION = "logacptps" +local WAP_MAX_DIST_DEF = 200 -- in nodes + +-- we need this because default tostring(number) function returns scientific representation which loses accuracy +local str = function(anInt) return string.format("%.0f", anInt) end + +-- local forms = {} + +local function on_wireless_pad_primary(itemstack, user, pointed_thing) + local pos = pointed_thing.under + if not pos or not user or not user:is_player() or not user:get_player_control().sneak then return end + + local node = minetest.get_node(pos) + if minetest.get_item_group(node.name, logistica.TIER_ACCESS_POINT) <= 0 then return end + + local playerName = user:get_player_name() + if minetest.is_protected(pos, playerName) then + logistica.show_popup(playerName, S("This Access Point is in a protected area!")) + return + end + + local itemMeta = itemstack:get_meta() + local posHashStr = str(minetest.hash_node_position(pos)) + itemMeta:set_string(META_ACCESS_POINT_POSITION, posHashStr) + + logistica.show_popup(playerName, S("Synced to Access Point at").." ("..pos.x..","..pos.y..","..pos.z..")") + + return itemstack +end + +local function on_wireless_pad_secondary(itemstack, placer, pointed_thing) + if not placer or not placer:is_player() then return end + + local playerName = placer:get_player_name() + local itemMeta = itemstack:get_meta() + local posHashStr = itemMeta:get_string(META_ACCESS_POINT_POSITION) + + if posHashStr == "" then + logistica.show_popup(playerName, S("This WAP is not synced to any Access Point.")) + return + end + + local targetPos = minetest.get_position_from_hash(tonumber(posHashStr)) + logistica.load_position(targetPos) + local node = minetest.get_node(targetPos) + + if minetest.get_item_group(node.name, logistica.TIER_ACCESS_POINT) <= 0 then + logistica.show_popup(playerName, S("The synced Access Point no longer exists!")) + return + end + + if minetest.is_protected(targetPos, playerName) then + logistica.show_popup(playerName, S("The synced Access Point is in a protected area! How did you manage that?")) + return + end + + local nodeDef = minetest.registered_nodes[node.name] + nodeDef.on_rightclick(targetPos, node, placer, itemstack, pointed_thing) + + -- logistica.access_point_on_rightclick(targetPos, node, placer, itemstack, pointed_thing) +end + +-- registration + +-- minetest.register_on_leaveplayer(function(objRef, timed_out) +-- if objRef:is_player() then +-- forms[objRef:get_player_name()] = nil +-- end +-- end) + +minetest.register_craftitem("logistica:wireless_access_pad",{ + description = S("Wireless Access Pad\nSneak+Punch an Access Point to Sync"), + inventory_image = "logistica_wap.png", + wield_image = "logistica_wap.png", + stack_max = 1, + on_use = on_wireless_pad_primary, + on_secondary_use = on_wireless_pad_secondary, +})