mirror of
https://github.com/minetest-mods/unified_inventory.git
synced 2024-12-26 10:40:28 +01:00
Improve group matching for 'copy to craft'
This commit is contained in:
parent
b590764026
commit
bda9f2598f
40
api.lua
40
api.lua
@ -146,46 +146,10 @@ minetest.after(0.01, function()
|
||||
end
|
||||
|
||||
-- Step 1: group-indexed lookup table for items
|
||||
local spec_matcher = {}
|
||||
for _, name in ipairs(ui.items_list) do
|
||||
-- we only need to care about groups, exact items are handled separately
|
||||
for group, value in pairs(minetest.registered_items[name].groups) do
|
||||
if value and value ~= 0 then
|
||||
if not spec_matcher[group] then
|
||||
spec_matcher[group] = {}
|
||||
end
|
||||
spec_matcher[group][name] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
unified_inventory.init_matching_cache()
|
||||
|
||||
-- Step 2: Find all matching items for the given spec (groups)
|
||||
local function get_matching_spec_items(specname)
|
||||
if specname:sub(1,6) ~= "group:" then
|
||||
return { [specname] = true }
|
||||
end
|
||||
|
||||
local accepted = {}
|
||||
for i, group in ipairs(specname:sub(7):split(",")) do
|
||||
if i == 1 then
|
||||
-- First step: Copy all possible item names in this group
|
||||
for name, _ in pairs(spec_matcher[group] or {}) do
|
||||
accepted[name] = true
|
||||
end
|
||||
else
|
||||
-- Perform filtering
|
||||
if spec_matcher[group] then
|
||||
for name, _ in pairs(accepted) do
|
||||
accepted[name] = spec_matcher[group][name]
|
||||
end
|
||||
else
|
||||
-- No matching items
|
||||
return {}
|
||||
end
|
||||
end
|
||||
end
|
||||
return accepted
|
||||
end
|
||||
local get_matching_spec_items = unified_inventory.get_matching_items
|
||||
|
||||
for _, recipes in pairs(ui.crafts_for.recipe) do
|
||||
-- List of crafts that return this item string (variable "_")
|
||||
|
60
group.lua
60
group.lua
@ -1,4 +1,5 @@
|
||||
local S = minetest.get_translator("unified_inventory")
|
||||
local ui = unified_inventory
|
||||
|
||||
function unified_inventory.extract_groupnames(groupname)
|
||||
local specname = ItemStack(groupname):get_name()
|
||||
@ -26,6 +27,7 @@ end
|
||||
-- It may be a comma-separated list of group names. This is really a
|
||||
-- "group:..." ingredient specification, minus the "group:" prefix.
|
||||
|
||||
-- TODO Replace this with the more efficient spec matcher (below)
|
||||
local function compute_group_item(group_name_list)
|
||||
local group_names = group_name_list:split(",")
|
||||
local candidate_items = {}
|
||||
@ -84,3 +86,61 @@ function unified_inventory.get_group_item(group_name)
|
||||
return group_item_cache[group_name]
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
This is for filtering known items by groups
|
||||
e.g. find all items that match "group:flower,yellow" (flower AND yellow groups)
|
||||
]]
|
||||
local spec_matcher = {}
|
||||
function unified_inventory.init_matching_cache()
|
||||
for _, name in ipairs(ui.items_list) do
|
||||
-- we only need to care about groups, exact items are handled separately
|
||||
for group, value in pairs(minetest.registered_items[name].groups) do
|
||||
if value and value ~= 0 then
|
||||
if not spec_matcher[group] then
|
||||
spec_matcher[group] = {}
|
||||
end
|
||||
spec_matcher[group][name] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
Retrieves all matching items
|
||||
|
||||
Arguments:
|
||||
specname (string): Item name or group(s) to filter
|
||||
|
||||
Output:
|
||||
{
|
||||
matchingitem1 = true,
|
||||
...
|
||||
}
|
||||
]]
|
||||
function unified_inventory.get_matching_items(specname)
|
||||
if specname:sub(1,6) ~= "group:" then
|
||||
return { [specname] = true }
|
||||
end
|
||||
|
||||
local accepted = {}
|
||||
for i, group in ipairs(specname:sub(7):split(",")) do
|
||||
if i == 1 then
|
||||
-- First step: Copy all possible item names in this group
|
||||
for name, _ in pairs(spec_matcher[group] or {}) do
|
||||
accepted[name] = true
|
||||
end
|
||||
else
|
||||
-- Perform filtering
|
||||
if spec_matcher[group] then
|
||||
for name, _ in pairs(accepted) do
|
||||
accepted[name] = spec_matcher[group][name]
|
||||
end
|
||||
else
|
||||
-- No matching items
|
||||
return {}
|
||||
end
|
||||
end
|
||||
end
|
||||
return accepted
|
||||
end
|
||||
|
@ -126,25 +126,18 @@ Example output:
|
||||
}
|
||||
--]]
|
||||
function unified_inventory.find_usable_items(inv_items, craft_items)
|
||||
local get_group = minetest.get_item_group
|
||||
local result = {}
|
||||
|
||||
for craft_item in pairs(craft_items) do
|
||||
local group = craft_item:match("^group:(.+)")
|
||||
local found = {}
|
||||
-- may specify group:type1,type2
|
||||
local items = unified_inventory.get_matching_items(craft_item)
|
||||
|
||||
if group ~= nil then
|
||||
for inv_item in pairs(inv_items) do
|
||||
if get_group(inv_item, group) > 0 then
|
||||
found[inv_item] = true
|
||||
end
|
||||
end
|
||||
else
|
||||
if inv_items[craft_item] ~= nil then
|
||||
found[craft_item] = true
|
||||
local found = {}
|
||||
for itemname, _ in pairs(items) do
|
||||
if inv_items[itemname] then
|
||||
found[itemname] = true
|
||||
end
|
||||
end
|
||||
|
||||
result[craft_item] = found
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user