Correctly display multi-group ingredients
Extend the representative-item logic to handle ingredients specified as the intersection of multiple groups. Also add mangling of item button content, because comma for a multi-group ingredient is getting formspec-escaped and then not de-escaped.
This commit is contained in:
parent
dbf98cb694
commit
a8c8ef0890
@ -122,7 +122,7 @@ 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 = string.sub(name, 13)
|
||||
clicked_item = unified_inventory.demangle_for_formspec(string.sub(name, 13))
|
||||
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)
|
||||
|
31
group.lua
31
group.lua
@ -21,13 +21,23 @@ end
|
||||
-- those items we prefer the one registered for the group by a mod.
|
||||
-- Among equally-preferred items, we just pick the one with the
|
||||
-- lexicographically earliest name.
|
||||
--
|
||||
-- The parameter to this function isn't just a single group name.
|
||||
-- It may be a comma-separated list of group names. This is really a
|
||||
-- "group:..." ingredient specification, minus the "group:" prefix.
|
||||
|
||||
local function compute_group_item(group_name)
|
||||
local function compute_group_item(group_name_list)
|
||||
local group_names = group_name_list:split(",")
|
||||
local candidate_items = {}
|
||||
for itemname, itemdef in pairs(minetest.registered_items) do
|
||||
if (itemdef.groups.not_in_creative_inventory or 0) == 0 and
|
||||
(itemdef.groups[group_name] or 0) ~= 0 then
|
||||
table.insert(candidate_items, itemname)
|
||||
if (itemdef.groups.not_in_creative_inventory or 0) == 0 then
|
||||
local all = true
|
||||
for _, group_name in ipairs(group_names) do
|
||||
if (itemdef.groups[group_name] or 0) == 0 then
|
||||
all = false
|
||||
end
|
||||
end
|
||||
if all then table.insert(candidate_items, itemname) end
|
||||
end
|
||||
end
|
||||
local num_candidates = #candidate_items
|
||||
@ -36,15 +46,22 @@ local function compute_group_item(group_name)
|
||||
elseif num_candidates == 1 then
|
||||
return {item = candidate_items[1], sole = true}
|
||||
end
|
||||
local is_group = {}
|
||||
local registered_rep = {}
|
||||
for _, group_name in ipairs(group_names) do
|
||||
is_group[group_name] = true
|
||||
local rep = unified_inventory.registered_group_items[group_name]
|
||||
if rep then registered_rep[rep] = true end
|
||||
end
|
||||
local bestitem = ""
|
||||
local bestpref = 0
|
||||
for _, item in ipairs(candidate_items) do
|
||||
local pref
|
||||
if item == unified_inventory.registered_group_items[group_name] then
|
||||
if registered_rep[item] then
|
||||
pref = 4
|
||||
elseif item == "default:"..group_name then
|
||||
elseif string.sub(item, 1, 8) == "default:" and is_group[string.sub(item, 9)] then
|
||||
pref = 3
|
||||
elseif item:gsub("^[^:]*:", "") == group_name then
|
||||
elseif is_group[item:gsub("^[^:]*:", "")] then
|
||||
pref = 2
|
||||
else
|
||||
pref = 1
|
||||
|
16
internal.lua
16
internal.lua
@ -1,3 +1,17 @@
|
||||
-- This pair of encoding functions is used where variable text must go in
|
||||
-- button names, where the text might contain formspec metacharacters.
|
||||
-- We can escape button names for the formspec, to avoid screwing up
|
||||
-- form structure overall, but they then don't get de-escaped, and so
|
||||
-- the input we get back from the button contains the formspec escaping.
|
||||
-- This is a game engine bug, and in the anticipation that it might be
|
||||
-- fixed some day we don't want to rely on it. So for safety we apply
|
||||
-- an encoding that avoids all formspec metacharacters.
|
||||
function unified_inventory.mangle_for_formspec(str)
|
||||
return string.gsub(str, "([^A-Za-z0-9])", function (c) return string.format("_%d_", string.byte(c)) end)
|
||||
end
|
||||
function unified_inventory.demangle_for_formspec(str)
|
||||
return string.gsub(str, "_([0-9]+)_", function (v) return string.char(v) end)
|
||||
end
|
||||
|
||||
function unified_inventory.get_formspec(player, page)
|
||||
if not player then
|
||||
@ -71,7 +85,7 @@ function unified_inventory.get_formspec(player, page)
|
||||
..(8.2 + x * 0.7)..","
|
||||
..(1 + y * 0.7)..";.81,.81;"
|
||||
..name..";item_button_"
|
||||
..name..";]"
|
||||
..unified_inventory.mangle_for_formspec(name)..";]"
|
||||
list_index = list_index + 1
|
||||
end
|
||||
end
|
||||
|
@ -165,7 +165,7 @@ local function stack_image_button(x, y, w, h, buttonname_prefix, item)
|
||||
return string.format("item_image_button[%u,%u;%u,%u;%s;%s;%s]",
|
||||
x, y, w, h,
|
||||
minetest.formspec_escape(displayitem),
|
||||
minetest.formspec_escape(buttonname_prefix..selectitem),
|
||||
minetest.formspec_escape(buttonname_prefix..unified_inventory.mangle_for_formspec(selectitem)),
|
||||
label)
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user