mirror of
https://github.com/minetest-mods/unified_inventory.git
synced 2024-12-27 19:20:27 +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
|
end
|
||||||
|
|
||||||
-- Step 1: group-indexed lookup table for items
|
-- Step 1: group-indexed lookup table for items
|
||||||
local spec_matcher = {}
|
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
|
|
||||||
|
|
||||||
-- Step 2: Find all matching items for the given spec (groups)
|
-- Step 2: Find all matching items for the given spec (groups)
|
||||||
local function get_matching_spec_items(specname)
|
local get_matching_spec_items = unified_inventory.get_matching_items
|
||||||
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
|
|
||||||
|
|
||||||
for _, recipes in pairs(ui.crafts_for.recipe) do
|
for _, recipes in pairs(ui.crafts_for.recipe) do
|
||||||
-- List of crafts that return this item string (variable "_")
|
-- 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 S = minetest.get_translator("unified_inventory")
|
||||||
|
local ui = unified_inventory
|
||||||
|
|
||||||
function unified_inventory.extract_groupnames(groupname)
|
function unified_inventory.extract_groupnames(groupname)
|
||||||
local specname = ItemStack(groupname):get_name()
|
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
|
-- It may be a comma-separated list of group names. This is really a
|
||||||
-- "group:..." ingredient specification, minus the "group:" prefix.
|
-- "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 function compute_group_item(group_name_list)
|
||||||
local group_names = group_name_list:split(",")
|
local group_names = group_name_list:split(",")
|
||||||
local candidate_items = {}
|
local candidate_items = {}
|
||||||
@ -84,3 +86,61 @@ function unified_inventory.get_group_item(group_name)
|
|||||||
return group_item_cache[group_name]
|
return group_item_cache[group_name]
|
||||||
end
|
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)
|
function unified_inventory.find_usable_items(inv_items, craft_items)
|
||||||
local get_group = minetest.get_item_group
|
|
||||||
local result = {}
|
local result = {}
|
||||||
|
|
||||||
for craft_item in pairs(craft_items) do
|
for craft_item in pairs(craft_items) do
|
||||||
local group = craft_item:match("^group:(.+)")
|
-- may specify group:type1,type2
|
||||||
|
local items = unified_inventory.get_matching_items(craft_item)
|
||||||
|
|
||||||
local found = {}
|
local found = {}
|
||||||
|
for itemname, _ in pairs(items) do
|
||||||
if group ~= nil then
|
if inv_items[itemname] then
|
||||||
for inv_item in pairs(inv_items) do
|
found[itemname] = true
|
||||||
if get_group(inv_item, group) > 0 then
|
|
||||||
found[inv_item] = true
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
|
||||||
if inv_items[craft_item] ~= nil then
|
|
||||||
found[craft_item] = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
result[craft_item] = found
|
result[craft_item] = found
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user