summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZefram <zefram@fysh.org>2014-06-13 15:04:20 +0100
committerDiego Martinez <kaeza@users.sf.net>2014-06-13 11:30:09 -0300
commit87f502a2592bbd41e99df9009a966111156f0181 (patch)
treea142488895cf47cc39aa072697f701cbde3cb34c
parentc33efe86316342c491267c5f5d8b8fa2cdc58747 (diff)
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.
-rw-r--r--api.lua25
-rw-r--r--callbacks.lua31
-rw-r--r--group.lua22
-rw-r--r--init.lua5
-rw-r--r--internal.lua6
-rw-r--r--register.lua59
-rw-r--r--textures/ui_craftguide_form.pngbin13594 -> 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 e103c04..72572b5 100644
--- a/textures/ui_craftguide_form.png
+++ b/textures/ui_craftguide_form.png
Binary files differ