Initial work on Wireless Access Pad

This commit is contained in:
Zenon Seth 2023-11-21 22:48:29 +00:00
parent c2904e7717
commit 7976793d69
8 changed files with 197 additions and 71 deletions

View File

@ -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 = {}
}

View File

@ -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)

View File

@ -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("<NONE>")
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

View File

@ -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)

BIN
textures/logistica_wap.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

40
tools/misc.lua Normal file
View File

@ -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("<NONE>")
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
})

View File

@ -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("<NONE>")
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")

View File

@ -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,
})