From 87f502a2592bbd41e99df9009a966111156f0181 Mon Sep 17 00:00:00 2001 From: Zefram Date: Fri, 13 Jun 2014 15:04:20 +0100 Subject: [PATCH] Show item usages in craft guide When the craft guide is showing a craft, the output slot is now a button, which causes the craft guide to show ways in which that output can be used. This mirrors the way input slots are buttons that show recipes for the selected ingredient. Usages of an item can be iterated through in the same way as recipes for the item. This incidentally offers some ability to retrace one's steps through a crafting chain, without storing actual history. --- api.lua | 25 ++++++++++++-- callbacks.lua | 31 ++++++----------- group.lua | 22 ++++++++++++ init.lua | 5 +-- internal.lua | 6 ++-- register.lua | 59 +++++++++++++++++++------------- textures/ui_craftguide_form.png | Bin 13594 -> 13755 bytes 7 files changed, 97 insertions(+), 51 deletions(-) diff --git a/api.lua b/api.lua index 882971e..23dd6d4 100644 --- a/api.lua +++ b/api.lua @@ -42,6 +42,25 @@ minetest.after(0.01, function() end end end + for _, recipes in pairs(unified_inventory.crafts_for.recipe) do + for _, recipe in ipairs(recipes) do + local ingredient_items = {} + for _, spec in ipairs(recipe.items) do + local matches_spec = unified_inventory.canonical_item_spec_matcher(spec) + for _, name in ipairs(unified_inventory.items_list) do + if matches_spec(name) then + ingredient_items[name] = true + end + end + end + for name, _ in pairs(ingredient_items) do + if unified_inventory.crafts_for.usage[name] == nil then + unified_inventory.crafts_for.usage[name] = {} + end + table.insert(unified_inventory.crafts_for.usage[name], recipe) + end + end + end end) @@ -101,10 +120,10 @@ function unified_inventory.register_craft(options) if options.type == "normal" and options.width == 0 then options = { type = "shapeless", items = options.items, output = options.output, width = 0 } end - if unified_inventory.crafts_table[itemstack:get_name()] == nil then - unified_inventory.crafts_table[itemstack:get_name()] = {} + if unified_inventory.crafts_for.recipe[itemstack:get_name()] == nil then + unified_inventory.crafts_for.recipe[itemstack:get_name()] = {} end - table.insert(unified_inventory.crafts_table[itemstack:get_name()],options) + table.insert(unified_inventory.crafts_for.recipe[itemstack:get_name()],options) end diff --git a/callbacks.lua b/callbacks.lua index ad7c1ed..605d8e5 100644 --- a/callbacks.lua +++ b/callbacks.lua @@ -14,28 +14,15 @@ minetest.register_on_joinplayer(function(player) unified_inventory.filtered_items_list[player_name] = unified_inventory.items_list unified_inventory.activefilter[player_name] = "" - unified_inventory.apply_filter(player, "") + unified_inventory.active_search_direction[player_name] = "nochange" + unified_inventory.apply_filter(player, "", "nochange") unified_inventory.current_searchbox[player_name] = "" unified_inventory.alternate[player_name] = 1 unified_inventory.current_item[player_name] = nil + unified_inventory.current_craft_direction[player_name] = "recipe" unified_inventory.set_inventory_formspec(player, unified_inventory.default) - -- Crafting guide inventories - local inv = minetest.create_detached_inventory(player_name.."craftrecipe", { - allow_put = function(inv, listname, index, stack, player) - return 0 - end, - allow_take = function(inv, listname, index, stack, player) - return 0 - end, - allow_move = function(inv, from_list, from_index, to_list, - to_index, count, player) - return 0 - end, - }) - inv:set_size("output", 1) - -- Refill slot local refill = minetest.create_detached_inventory(player_name.."refill", { allow_put = function(inv, listname, index, stack, player) @@ -122,12 +109,16 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) local clicked_item = nil for name, value in pairs(fields) do if string.sub(name, 1, 12) == "item_button_" then - clicked_item = unified_inventory.demangle_for_formspec(string.sub(name, 13)) + local new_dir, mangled_item = string.match(name, "^item_button_([a-z]+)_(.*)$") + clicked_item = unified_inventory.demangle_for_formspec(mangled_item) if string.sub(clicked_item, 1, 6) == "group:" then minetest.sound_play("click", {to_player=player_name, gain = 0.1}) - unified_inventory.apply_filter(player, clicked_item) + unified_inventory.apply_filter(player, clicked_item, new_dir) return end + if new_dir == "recipe" or new_dir == "usage" then + unified_inventory.current_craft_direction[player_name] = new_dir + end break end end @@ -156,7 +147,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end if fields.searchbutton then - unified_inventory.apply_filter(player, unified_inventory.current_searchbox[player_name]) + unified_inventory.apply_filter(player, unified_inventory.current_searchbox[player_name], "nochange") unified_inventory.current_searchbox[player_name] = "" unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name]) @@ -172,7 +163,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) if item_name then local alternates = 0 local alternate = unified_inventory.alternate[player_name] - local crafts = unified_inventory.crafts_table[item_name] + local crafts = unified_inventory.crafts_for[unified_inventory.current_craft_direction[player_name]][item_name] if crafts ~= nil then alternates = #crafts end diff --git a/group.lua b/group.lua index e509006..9bf6895 100644 --- a/group.lua +++ b/group.lua @@ -1,3 +1,25 @@ +function unified_inventory.canonical_item_spec_matcher(spec) + local specname = ItemStack(spec):get_name() + if specname:sub(1, 6) == "group:" then + local group_names = specname:sub(7):split(",") + return function (itemname) + local itemdef = minetest.registered_items[itemname] + for _, group_name in ipairs(group_names) do + if (itemdef.groups[group_name] or 0) == 0 then + return false + end + end + return true + end + else + return function (itemname) return itemname == specname end + end +end + +function unified_inventory.item_matches_spec(item, spec) + local itemname = ItemStack(item):get_name() + return unified_inventory.canonical_item_spec_matcher(spec)(itemname) +end unified_inventory.registered_group_items = { mesecon_conductor_craftable = "mesecons:wire_00000000_off", diff --git a/init.lua b/init.lua index f91e048..0542e36 100644 --- a/init.lua +++ b/init.lua @@ -6,14 +6,15 @@ local worldpath = minetest.get_worldpath() -- Data tables definitions unified_inventory = {} unified_inventory.activefilter = {} +unified_inventory.active_search_direction = {} unified_inventory.alternate = {} unified_inventory.current_page = {} unified_inventory.current_searchbox = {} unified_inventory.current_index = {} unified_inventory.current_item = {} +unified_inventory.current_craft_direction = {} unified_inventory.registered_craft_types = {} -unified_inventory.crafts_table = {} -unified_inventory.crafts_table_count = 0 +unified_inventory.crafts_for = { usage = {}, recipe = {} } unified_inventory.players = {} unified_inventory.items_list_size = 0 unified_inventory.items_list = {} diff --git a/internal.lua b/internal.lua index 2323e07..4d9c10b 100644 --- a/internal.lua +++ b/internal.lua @@ -71,6 +71,7 @@ function unified_inventory.get_formspec(player, page) if #unified_inventory.filtered_items_list[player_name] == 0 then formspec = formspec.."label[8.2,0;No matching items]" else + local dir = unified_inventory.active_search_direction[player_name] local list_index = unified_inventory.current_index[player_name] local page = math.floor(list_index / (80) + 1) local pagemax = math.floor( @@ -84,7 +85,7 @@ function unified_inventory.get_formspec(player, page) formspec = formspec.."item_image_button[" ..(8.2 + x * 0.7).."," ..(1 + y * 0.7)..";.81,.81;" - ..name..";item_button_" + ..name..";item_button_"..dir.."_" ..unified_inventory.mangle_for_formspec(name)..";]" list_index = list_index + 1 end @@ -108,7 +109,7 @@ function unified_inventory.set_inventory_formspec(player, page) end --apply filter to the inventory list (create filtered copy of full one) -function unified_inventory.apply_filter(player, filter) +function unified_inventory.apply_filter(player, filter, search_dir) local player_name = player:get_player_name() local lfilter = string.lower(filter) local ffilter @@ -139,6 +140,7 @@ function unified_inventory.apply_filter(player, filter) unified_inventory.filtered_items_list_size[player_name] = #unified_inventory.filtered_items_list[player_name] unified_inventory.current_index[player_name] = 1 unified_inventory.activefilter[player_name] = filter + unified_inventory.active_search_direction[player_name] = search_dir unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name]) end diff --git a/register.lua b/register.lua index 3815f05..1c8eb54 100644 --- a/register.lua +++ b/register.lua @@ -169,6 +169,23 @@ local function stack_image_button(x, y, w, h, buttonname_prefix, item) label) end +local recipe_text = { + recipe = "Recipe", + usage = "Usage", +} +local no_recipe_text = { + recipe = "No recipes", + usage = "No usages", +} +local role_text = { + recipe = "Result", + usage = "Ingredient", +} +local other_dir = { + recipe = "usage", + usage = "recipe", +} + unified_inventory.register_page("craftguide", { get_formspec = function(player) local player_name = player:get_player_name() @@ -179,36 +196,33 @@ unified_inventory.register_page("craftguide", { local item_name = unified_inventory.current_item[player_name] if not item_name then return {formspec=formspec} end - formspec = formspec.."background[0,1;8,3;ui_craftguide_form.png]" - formspec = formspec.."textarea[0.3,0.6;10,1;;Result: "..minetest.formspec_escape(item_name)..";]" - formspec = formspec.."list[detached:"..minetest.formspec_escape(player_name).."craftrecipe;output;6,1;1,1;]" - local craftinv = minetest.get_inventory({ - type = "detached", - name = player_name.."craftrecipe" - }) - - local alternate, alternates, craft, craft_type - alternate = unified_inventory.alternate[player_name] - local crafts = unified_inventory.crafts_table[item_name] + local dir = unified_inventory.current_craft_direction[player_name] + local crafts = unified_inventory.crafts_for[dir][item_name] + local alternate = unified_inventory.alternate[player_name] + local alternates, craft if crafts ~= nil and #crafts > 0 then alternates = #crafts craft = crafts[alternate] end + formspec = formspec.."background[0,1;8,3;ui_craftguide_form.png]" + formspec = formspec.."textarea[0.3,0.6;10,1;;"..minetest.formspec_escape(role_text[dir]..": "..item_name)..";]" + if not craft then - craftinv:set_stack("output", 1, item_name) - craft_type = unified_inventory.craft_type_defaults("", {}) - formspec = formspec.."label[6,3.35;No recipes]" - formspec = formspec.."image[4,1;1.1,1.1;ui_no.png]" + formspec = formspec.."label[6,3.35;"..minetest.formspec_escape(no_recipe_text[dir]).."]" + local no_pos = dir == "recipe" and 4 or 6 + local item_pos = dir == "recipe" and 6 or 4 + formspec = formspec.."image["..no_pos..",1;1.1,1.1;ui_no.png]" + formspec = formspec..stack_image_button(item_pos, 1, 1.1, 1.1, "item_button_"..other_dir[dir].."_", ItemStack(item_name)) return {formspec = formspec} end - craftinv:set_stack("output", 1, craft.output) - craft_type = unified_inventory.registered_craft_types[craft.type] or + local craft_type = unified_inventory.registered_craft_types[craft.type] or unified_inventory.craft_type_defaults(craft.type, {}) formspec = formspec.."label[6,3.35;Method:]" formspec = formspec.."label[6,3.75;" ..minetest.formspec_escape(craft_type.description).."]" + formspec = formspec..stack_image_button(6, 1, 1.1, 1.1, "item_button_usage_", ItemStack(craft.output)) local display_size = craft_type.dynamic_display_size and craft_type.dynamic_display_size(craft) or { width = craft_type.width, height = craft_type.height } local craft_width = craft_type.get_shaped_craft_width and craft_type.get_shaped_craft_width(craft) or display_size.width @@ -224,7 +238,8 @@ unified_inventory.register_page("craftguide", { if item then formspec = formspec..stack_image_button( xoffset + x, y, 1.1, 1.1, - "item_button_", ItemStack(item)) + "item_button_recipe_", + ItemStack(item)) else -- Fake buttons just to make grid formspec = formspec.."image_button[" @@ -242,7 +257,7 @@ unified_inventory.register_page("craftguide", { end if alternates and alternates > 1 then - formspec = formspec.."label[0,2.6;Recipe " + formspec = formspec.."label[0,2.6;"..recipe_text[dir].." " ..tostring(alternate).." of " ..tostring(alternates).."]" .."button[0,3.15;2,1;alternate;Alternate]" @@ -259,17 +274,13 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end if not amount then return end local player_name = player:get_player_name() - local recipe_inv = minetest.get_inventory({ - type="detached", - name=player_name.."craftrecipe", - }) local output = unified_inventory.current_item[player_name] if (not output) or (output == "") then return end local player_inv = player:get_inventory() - local crafts = unified_inventory.crafts_table[output] + local crafts = unified_inventory.crafts_for[unified_inventory.current_craft_direction[player_name]][output] if (not crafts) or (#crafts == 0) then return end local alternate = unified_inventory.alternate[player_name] diff --git a/textures/ui_craftguide_form.png b/textures/ui_craftguide_form.png index e103c049e3def96934b3b2bf9fb9318cf59a39ed..72572b5b0f438e9a2e19b9a08813751e50b9b7f8 100644 GIT binary patch literal 13755 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 T#vlkEvqE$=uW6L1*@XNr2srVr literal 13594 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