forked from minetest-mods/unified_inventory
		
	Compare commits
	
		
			2 Commits
		
	
	
		
			cb6e602497
			...
			match_copy
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 88b3033477 | ||
|  | 19e14aa21e | 
							
								
								
									
										55
									
								
								api.lua
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								api.lua
									
									
									
									
									
								
							| @@ -145,50 +145,18 @@ minetest.after(0.01, function() | ||||
| 		end | ||||
| 	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 | ||||
| 	-- Step 1: Initialize cache for looking up groups | ||||
| 	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 get_matching_spec_items = unified_inventory.get_matching_items | ||||
|  | ||||
| 		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 outputitemname, recipes in pairs(ui.crafts_for.recipe) do | ||||
| 		-- List of crafts that return this item string (variable "_") | ||||
|  | ||||
| 		-- Problem: The group cache must be initialized after all mods finished loading | ||||
| 		-- thus, invalid recipes might be indexed. Hence perform filtering with `new_recipe_list` | ||||
| 		local new_recipe_list = {} | ||||
| 		for _, recipe in ipairs(recipes) do | ||||
| 			local ingredient_items = {} | ||||
| 			for _, spec in pairs(recipe.items) do | ||||
| @@ -204,7 +172,14 @@ minetest.after(0.01, function() | ||||
| 				end | ||||
| 				table.insert(ui.crafts_for.usage[name], recipe) | ||||
| 			end | ||||
|  | ||||
| 			if next(ingredient_items) then | ||||
| 				-- There's at least one known ingredient: mark as good recipe | ||||
| 				-- PS: What whatll be done about partially incomplete recipes? | ||||
| 				table.insert(new_recipe_list, recipe) | ||||
| 			end | ||||
| 		end | ||||
| 		ui.crafts_for.recipe[outputitemname] = new_recipe_list | ||||
| 	end | ||||
|  | ||||
| 	for _, callback in ipairs(ui.initialized_callbacks) do | ||||
|   | ||||
| @@ -24,7 +24,9 @@ Grouped by use-case, afterwards sorted alphabetically. | ||||
| Callbacks | ||||
| --------- | ||||
|  | ||||
| Register a callback that will be run whenever a craft is registered via unified_inventory.register_craft: | ||||
| Register a callback that will be run whenever a craft is registered via unified_inventory.register_craft. | ||||
| This callback is run before any recipe ingredients checks, hence it is also executed on recipes that are | ||||
| purged after all mods finished loading. | ||||
|  | ||||
| 	unified_inventory.register_on_craft_registered( | ||||
| 		function (item_name, options) | ||||
|   | ||||
							
								
								
									
										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 | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user