From cea1d54240514e4c46ddf1ed2614dfeb4bf8c5a3 Mon Sep 17 00:00:00 2001 From: osmarks Date: Fri, 27 Jul 2018 13:59:32 +0100 Subject: [PATCH] Make search nicer --- backend-chests.lua | 16 ++++++++++++---- lib.lua | 20 +++++++++++++++++++- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/backend-chests.lua b/backend-chests.lua index d1eb64f..9c3f6b1 100644 --- a/backend-chests.lua +++ b/backend-chests.lua @@ -83,11 +83,12 @@ local function find_space() end end -local function find_by_ID_meta(id, meta) +local function find_by_ID_meta_NBT(ID, meta, NBT) return find(function(item) return (not meta or item.damage == meta) and -- if metadata provided, ensure match - (not id or item.name == id) -- if internal name provided, ensure match + (not id or item.name == ID) and -- if internal name provided, ensure match + (not NBT or item.nbtHash == NBT) -- if NBT hash provided, ensure match end) end @@ -125,7 +126,7 @@ local function server(command) elseif command.type == "reindex" then os.queueEvent "reindex" elseif command.type == "extract" then - local result = find_by_ID_meta(command.ID, command.meta) + local result = find_by_ID_meta(command.ID, command.meta, command.NBT) local first_available = result[1] -- Check if we have an item, and its stack is big enough; otherwise, send back an error. @@ -164,7 +165,14 @@ local function server(command) return { moved = moved } elseif command.type == "search" then - return d.map(search(command.query, command.threshold), function(x) return x.item end) + local matching_items = d.map(search(command.query, command.threshold), function(x) return x.item end) + local out = {} + for _, stack in pairs(matching_items) do + local i = w.get_internal_identifier(stack) + if out[i] then out[i] = out[i] + stack.count + else out[i] = stack.count end + end + return matching_items end end diff --git a/lib.lua b/lib.lua index e54b3ee..e60d9f1 100644 --- a/lib.lua +++ b/lib.lua @@ -173,6 +173,24 @@ end -- GENERAL STUFF +-- Converts a table of the form {"x", "x", "y"} into {x = 2, y = 1} +local function collate(items) + local ret = {} + for _, i in pairs(items) do + ret[i] = (ret[i] or 0) + 1 + end + return ret +end + +-- Checks whether "needs"'s (a collate-formatted table) values are all greater than those of "has" +local function satisfied(needs, has) + local good = true + for k, qty in pairs(needs) do + if qty > (has[k] or 0) then good = false end + end + return good +end + -- Loads a config file (in serialized-table format) from "filename" or wyvern_config.tbl -- "required_data" is a list of keys which must be in the config file's data -- "defaults" is a map of keys and default values for them, which will be used if there is no matching key in the data @@ -211,4 +229,4 @@ local function init() d.map(find_peripherals(function(type, name, wrapped) return type == "modem" end), function(p) rednet.open(p.name) end) end -return { errors = errors, serve = serve, query_by_ID = query_by_ID, query_by_type = query_by_type, get_internal_identifier = get_internal_identifier, load_config = load_config, find_peripherals = find_peripherals, init = init } \ No newline at end of file +return { errors = errors, serve = serve, query_by_ID = query_by_ID, query_by_type = query_by_type, get_internal_identifier = get_internal_identifier, load_config = load_config, find_peripherals = find_peripherals, init = init, collate = collate, satisfied = satisfied } \ No newline at end of file