summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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