Show group ingredients visually in craft guide

Where a recipe specifies an ingredient by group, show a typical group
item pictorially, with a label flag to indicate that it's a group rather
than the single item.  This is the inverse of the previous arrangement,
which identified the group by label and dipicted groupiness pictorially.
The new arrangement is easier to interpret, and if the labels are ignored
it actually shows a correct input to the crafting grid.
This commit is contained in:
Zefram 2014-05-01 16:08:24 +01:00 committed by RealBadAngel
parent 5d34b235dd
commit b492701915
3 changed files with 91 additions and 13 deletions

View File

@ -147,6 +147,10 @@ unified_inventory.register_craft_type("digging", {
height = 1,
})
function unified_inventory.register_group_representative_item(groupname, itemname)
unified_inventory.registered_group_representative_items[groupname] = itemname
end
function unified_inventory.register_page(name, def)
unified_inventory.pages[name] = def
end

View File

@ -12,6 +12,7 @@ unified_inventory.current_searchbox = {}
unified_inventory.current_index = {}
unified_inventory.current_item = {}
unified_inventory.registered_craft_types = {}
unified_inventory.registered_group_representative_items = {}
unified_inventory.crafts_table = {}
unified_inventory.crafts_table_count = 0
unified_inventory.players = {}

View File

@ -134,6 +134,74 @@ unified_inventory.register_page("craft", {
end,
})
-- group_representative_item(): select representative item for a group
--
-- This is used when displaying craft recipes, where an ingredient is
-- specified by group rather than as a specific item. A single-item group
-- is represented by that item, with the single-item status signalled
-- so that stack_image_button() can treat it as just the item. If the
-- group contains no items at all, it will be treated as containing a
-- single unknown item.
--
-- Within a multiple-item group, we prefer to use an item that has the
-- same specific name as the group, and if there are more than one of
-- those items we prefer the one specified by the default mod if there
-- is one. If this produces a bad result, the mod defining a group can
-- register its preference for which item should represent the group,
-- and we'll use that instead if possible. Also, for a handful of groups
-- (predating this registration system) we have built-in preferences
-- that are used like registered preferences. Among equally-preferred
-- items, we just pick the one with the lexicographically earliest name,
-- for determinism.
local builtin_group_representative_items = {
mesecon_conductor_craftable = "mesecons:wire_00000000_off",
stone = "default:cobble",
wool = "wool:white",
}
local function compute_group_representative_item(groupspec)
local groupname = string.sub(groupspec, 7)
local candidate_items = {}
for itemname, itemdef in pairs(minetest.registered_items) do
if itemdef.groups[groupname] and itemdef.groups[groupname] ~= 0 then
table.insert(candidate_items, itemname)
end
end
print("group spec "..groupspec.." has "..#candidate_items.." candidates")
for _, i in ipairs(candidate_items) do
print(" ", i)
end
if #candidate_items == 0 then return { item = "unobtainium!", sole = true } end
if #candidate_items == 1 then return { item = candidate_items[1], sole = true } end
local bestitem = ""
local bestpref = 0
for _, item in ipairs(candidate_items) do
local pref
if item == unified_inventory.registered_group_representative_items[groupname] then
pref = 5
elseif item == builtin_group_representative_items[groupname] then
pref = 4
elseif item == "default:"..groupname then
pref = 3
elseif item:gsub("^[^:]*:", "") == groupname then
pref = 2
else
pref = 1
end
if pref > bestpref or (pref == bestpref and item < bestitem) then
bestitem = item
bestpref = pref
end
end
return { item = bestitem, sole = false }
end
local group_representative_item_cache = {}
local function group_representative_item(groupspec)
if not group_representative_item_cache[groupspec] then
group_representative_item_cache[groupspec] = compute_group_representative_item(groupspec)
end
return group_representative_item_cache[groupspec]
end
-- stack_image_button(): generate a form button displaying a stack of items
--
-- Normally a simple item_image_button[] is used. If the stack contains
@ -147,24 +215,29 @@ unified_inventory.register_page("craft", {
-- replaced as soon as the engine adds support for a proper item count,
-- or at least label placement control, on buttons.
--
-- The specified item may be a group. In that case, an image_button[]
-- is used, displaying an image that just indicates grouping, with a
-- label giving the name of the specific group. It very often happens
-- that the group name doesn't fit within the confines of the button and
-- gets cropped. Group names are also not brilliantly readable against
-- the background of the group image.
-- The specified item may be a group. In that case, the group will be
-- represented by some item in the group, along with a flag indicating
-- that it's a group. If the group contains only one item, it will be
-- treated as if that item had been specified directly.
local function stack_image_button(x, y, w, h, buttonname_prefix, stackstring)
local st = ItemStack(stackstring)
local n = st:get_name()
local specitem = st:get_name()
local c = st:get_count()
local clab = c == 1 and "" or string.format("%9d", c)
local buttonname = buttonname_prefix..n
local xywh = x..","..y..";"..w..","..h
if string.sub(n, 1, 6) == "group:" then
return "image_button["..xywh..";".."ui_group.png;"..minetest.formspec_escape(buttonname)..";"..minetest.formspec_escape(string.sub(n, 7)).."\n\n"..clab.."]"
local clab = c == 1 and " " or string.format("%7d", c)
local gflag, displayitem, selectitem
if string.sub(specitem, 1, 6) == "group:" then
local gri = group_representative_item(specitem)
gflag = not gri.sole
displayitem = gri.item
selectitem = gri.sole and gri.item or specitem
else
return "item_image_button["..xywh..";"..minetest.formspec_escape(n)..";"..minetest.formspec_escape(buttonname_prefix..n)..";\n\n"..clab.."]"
gflag = false
displayitem = specitem
selectitem = specitem
end
local label = string.format("\n\n%s%7d", gflag and "G" or " ", c):gsub(" 1$", " .")
if label == "\n\n ." then label = "" end
return "item_image_button["..x..","..y..";"..w..","..h..";"..minetest.formspec_escape(displayitem)..";"..minetest.formspec_escape(buttonname_prefix..selectitem)..";"..label.."]"
end
unified_inventory.register_page("craftguide", {