summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--callbacks.lua2
-rw-r--r--group.lua31
-rw-r--r--internal.lua16
-rw-r--r--register.lua2
4 files changed, 41 insertions, 10 deletions
diff --git a/callbacks.lua b/callbacks.lua
index f1646ed..ad7c1ed 100644
--- a/callbacks.lua
+++ b/callbacks.lua
@@ -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)
diff --git a/group.lua b/group.lua
index 594bed2..e509006 100644
--- a/group.lua
+++ b/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
diff --git a/internal.lua b/internal.lua
index 7724c9d..2323e07 100644
--- a/internal.lua
+++ b/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
diff --git a/register.lua b/register.lua
index 131cbe2..aac5342 100644
--- a/register.lua
+++ b/register.lua
@@ -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