Fix bug with favs

This commit is contained in:
Jean-Patrick Guerrero 2022-06-23 02:30:54 +02:00
parent 5d6ce3be18
commit f2b4c960ad
2 changed files with 459 additions and 458 deletions

View File

@ -1,456 +1,456 @@
local set_fs = i3.set_fs local set_fs = i3.set_fs
IMPORT("vec_eq", "vec_round") IMPORT("vec_eq", "vec_round")
IMPORT("reg_items", "reg_aliases") IMPORT("reg_items", "reg_aliases")
IMPORT("S", "random", "translate", "ItemStack") IMPORT("S", "random", "translate", "ItemStack")
IMPORT("sort", "copy", "insert", "remove", "indexof") IMPORT("sort", "copy", "insert", "remove", "indexof")
IMPORT("fmt", "find", "match", "sub", "lower", "split", "toupper") IMPORT("fmt", "find", "match", "sub", "lower", "split", "toupper")
IMPORT("msg", "is_fav", "pos_to_str", "str_to_pos", "add_hud_waypoint", "play_sound", "reset_data") IMPORT("msg", "is_fav", "pos_to_str", "str_to_pos", "add_hud_waypoint", "play_sound", "reset_data")
IMPORT("search", "get_sorting_idx", "sort_inventory", "sort_by_category", "get_recipes", "get_detached_inv") IMPORT("search", "get_sorting_idx", "sort_inventory", "sort_by_category", "get_recipes", "get_detached_inv")
IMPORT("valid_item", "get_stack", "craft_stack", "clean_name", "compressible", "check_privs", "safe_teleport") IMPORT("valid_item", "get_stack", "craft_stack", "clean_name", "compressible", "check_privs", "safe_teleport")
local function inv_fields(player, data, fields) local function inv_fields(player, data, fields)
local name = data.player_name local name = data.player_name
local inv = player:get_inventory() local inv = player:get_inventory()
local sb_inv = fields.scrbar_inv local sb_inv = fields.scrbar_inv
if sb_inv and sub(sb_inv, 1, 3) == "CHG" then if sb_inv and sub(sb_inv, 1, 3) == "CHG" then
data.scrbar_inv = tonumber(match(sb_inv, "%d+")) data.scrbar_inv = tonumber(match(sb_inv, "%d+"))
return return
end end
if fields.drop_items then if fields.drop_items then
local items = split(fields.drop_items, ",") local items = split(fields.drop_items, ",")
data.drop_items = items data.drop_items = items
end end
for field in pairs(fields) do for field in pairs(fields) do
if sub(field, 1, 4) == "btn_" then if sub(field, 1, 4) == "btn_" then
data.subcat = indexof(i3.categories, sub(field, 5)) data.subcat = indexof(i3.categories, sub(field, 5))
break break
elseif sub(field, 1, 3) == "cb_" then elseif sub(field, 1, 3) == "cb_" then
local str = sub(field, 4) local str = sub(field, 4)
data[str] = false data[str] = false
if fields[field] == "true" then if fields[field] == "true" then
data[str] = true data[str] = true
end end
elseif sub(field, 1, 8) == "setting_" then elseif sub(field, 1, 8) == "setting_" then
data.show_setting = match(field, "_(%w+)$") data.show_setting = match(field, "_(%w+)$")
elseif sub(field, 1, 9) == "skin_btn_" then elseif sub(field, 1, 9) == "skin_btn_" then
local id = tonumber(field:match("%d+")) local id = tonumber(field:match("%d+"))
local _skins = skins.get_skinlist_for_player(name) local _skins = skins.get_skinlist_for_player(name)
skins.set_player_skin(player, _skins[id]) skins.set_player_skin(player, _skins[id])
elseif find(field, "waypoint_%d+") then elseif find(field, "waypoint_%d+") then
local id, action = match(field, "_(%d+)_(%w+)$") local id, action = match(field, "_(%d+)_(%w+)$")
id = tonumber(id) id = tonumber(id)
local waypoint = data.waypoints[id] local waypoint = data.waypoints[id]
if not waypoint then return end if not waypoint then return end
if action == "see" then if action == "see" then
if data.waypoint_see and data.waypoint_see == id then if data.waypoint_see and data.waypoint_see == id then
data.waypoint_see = nil data.waypoint_see = nil
else else
data.waypoint_see = id data.waypoint_see = id
end end
elseif action == "delete" then elseif action == "delete" then
player:hud_remove(waypoint.id) player:hud_remove(waypoint.id)
remove(data.waypoints, id) remove(data.waypoints, id)
elseif action == "teleport" then elseif action == "teleport" then
local pos = str_to_pos(waypoint.pos) local pos = str_to_pos(waypoint.pos)
safe_teleport(player, pos) safe_teleport(player, pos)
msg(name, S("Teleported to: @1", waypoint.name)) msg(name, S("Teleported to: @1", waypoint.name))
elseif action == "refresh" then elseif action == "refresh" then
local color = random(0xffffff) local color = random(0xffffff)
waypoint.color = color waypoint.color = color
player:hud_change(waypoint.id, "number", color) player:hud_change(waypoint.id, "number", color)
elseif action == "hide" then elseif action == "hide" then
if waypoint.hide then if waypoint.hide then
local new_id = add_hud_waypoint( local new_id = add_hud_waypoint(
player, waypoint.name, str_to_pos(waypoint.pos), waypoint.color) player, waypoint.name, str_to_pos(waypoint.pos), waypoint.color)
waypoint.id = new_id waypoint.id = new_id
waypoint.hide = nil waypoint.hide = nil
else else
player:hud_remove(waypoint.id) player:hud_remove(waypoint.id)
waypoint.hide = true waypoint.hide = true
end end
end end
break break
end end
end end
if fields.quit then if fields.quit then
data.confirm_trash = nil data.confirm_trash = nil
data.show_settings = nil data.show_settings = nil
data.waypoint_see = nil data.waypoint_see = nil
data.bag_rename = nil data.bag_rename = nil
elseif fields.trash then elseif fields.trash then
data.show_settings = nil data.show_settings = nil
data.confirm_trash = true data.confirm_trash = true
elseif fields.settings then elseif fields.settings then
if not data.show_settings then if not data.show_settings then
data.confirm_trash = nil data.confirm_trash = nil
data.show_settings = true data.show_settings = true
else else
data.show_settings = nil data.show_settings = nil
end end
elseif fields.confirm_trash_yes or fields.confirm_trash_no then elseif fields.confirm_trash_yes or fields.confirm_trash_no then
if fields.confirm_trash_yes then if fields.confirm_trash_yes then
inv:set_list("main", {}) inv:set_list("main", {})
inv:set_list("craft", {}) inv:set_list("craft", {})
end end
data.confirm_trash = nil data.confirm_trash = nil
elseif fields.close_settings then elseif fields.close_settings then
data.show_settings = nil data.show_settings = nil
elseif fields.close_preview then elseif fields.close_preview then
data.waypoint_see = nil data.waypoint_see = nil
elseif fields.sort then elseif fields.sort then
sort_inventory(player, data) sort_inventory(player, data)
elseif fields.prev_sort or fields.next_sort then elseif fields.prev_sort or fields.next_sort then
local idx = get_sorting_idx(data.sort) local idx = get_sorting_idx(data.sort)
local tot = #i3.sorting_methods local tot = #i3.sorting_methods
idx -= (fields.prev_sort and 1 or -1) idx -= (fields.prev_sort and 1 or -1)
if idx > tot then if idx > tot then
idx = 1 idx = 1
elseif idx == 0 then elseif idx == 0 then
idx = tot idx = tot
end end
data.sort = i3.sorting_methods[idx].name data.sort = i3.sorting_methods[idx].name
elseif fields.home then elseif fields.home then
if not data.home then if not data.home then
return msg(name, "No home set") return msg(name, "No home set")
elseif not check_privs(name, {home = true}) then elseif not check_privs(name, {home = true}) then
return msg(name, "'home' privilege missing") return msg(name, "'home' privilege missing")
end end
safe_teleport(player, str_to_pos(data.home)) safe_teleport(player, str_to_pos(data.home))
msg(name, S"Welcome back home!") msg(name, S"Welcome back home!")
elseif fields.set_home then elseif fields.set_home then
data.home = pos_to_str(player:get_pos(), 1) data.home = pos_to_str(player:get_pos(), 1)
elseif fields.bag_rename then elseif fields.bag_rename then
data.bag_rename = true data.bag_rename = true
elseif fields.confirm_rename then elseif fields.confirm_rename then
local bag = get_detached_inv("bag", name) local bag = get_detached_inv("bag", name)
local bagstack = bag:get_stack("main", 1) local bagstack = bag:get_stack("main", 1)
local meta = bagstack:get_meta() local meta = bagstack:get_meta()
local desc = translate(data.lang_code, bagstack:get_description()) local desc = translate(data.lang_code, bagstack:get_description())
local fill = split(desc, "(")[2] local fill = split(desc, "(")[2]
local newname = fields.bag_newname:gsub("([%(%)])", "") local newname = fields.bag_newname:gsub("([%(%)])", "")
newname = toupper(newname:trim()) newname = toupper(newname:trim())
if fill then if fill then
newname = fmt("%s (%s", newname, fill) newname = fmt("%s (%s", newname, fill)
end end
meta:set_string("description", newname) meta:set_string("description", newname)
bag:set_stack("main", 1, bagstack) bag:set_stack("main", 1, bagstack)
data.bag = bagstack:to_string() data.bag = bagstack:to_string()
data.bag_rename = nil data.bag_rename = nil
elseif fields.waypoint_add then elseif fields.waypoint_add then
local max_waypoints = i3.settings.max_waypoints local max_waypoints = i3.settings.max_waypoints
if #data.waypoints >= max_waypoints then if #data.waypoints >= max_waypoints then
play_sound(name, "i3_cannot", 0.8) play_sound(name, "i3_cannot", 0.8)
return msg(name, fmt("Waypoints limit reached (%u)", max_waypoints)) return msg(name, fmt("Waypoints limit reached (%u)", max_waypoints))
end end
local pos = player:get_pos() local pos = player:get_pos()
for _, v in ipairs(data.waypoints) do for _, v in ipairs(data.waypoints) do
if vec_eq(vec_round(pos), vec_round(str_to_pos(v.pos))) then if vec_eq(vec_round(pos), vec_round(str_to_pos(v.pos))) then
play_sound(name, "i3_cannot", 0.8) play_sound(name, "i3_cannot", 0.8)
return msg(name, S"You already set a waypoint at this position") return msg(name, S"You already set a waypoint at this position")
end end
end end
local waypoint = fields.waypoint_name local waypoint = fields.waypoint_name
if fields.waypoint_name == "" then if fields.waypoint_name == "" then
waypoint = "Waypoint" waypoint = "Waypoint"
end end
local color = random(0xffffff) local color = random(0xffffff)
local id = add_hud_waypoint(player, waypoint, pos, color) local id = add_hud_waypoint(player, waypoint, pos, color)
insert(data.waypoints, { insert(data.waypoints, {
name = waypoint, name = waypoint,
pos = pos_to_str(pos, 1), pos = pos_to_str(pos, 1),
color = color, color = color,
id = id, id = id,
}) })
data.scrbar_inv += 1000 data.scrbar_inv += 1000
elseif fields.hide_debug_grid then elseif fields.hide_debug_grid then
data.hide_debug_grid = not data.hide_debug_grid data.hide_debug_grid = not data.hide_debug_grid
end end
return set_fs(player) return set_fs(player)
end end
local function select_item(player, data, fields) local function select_item(player, data, fields)
local item local item
for field in pairs(fields) do for field in pairs(fields) do
if find(field, ":") then if find(field, ":") then
item = field item = field
break break
end end
end end
if not item then return end if not item then return end
if compressible(item, data) then if compressible(item, data) then
local idx local idx
for i = 1, #data.items do for i = 1, #data.items do
local it = data.items[i] local it = data.items[i]
if it == item then if it == item then
idx = i idx = i
break break
end end
end end
if data.expand ~= "" then if data.expand ~= "" then
data.alt_items = nil data.alt_items = nil
if item == data.expand then if item == data.expand then
data.expand = nil data.expand = nil
return return
end end
end end
if idx and item ~= data.expand then if idx and item ~= data.expand then
data.alt_items = copy(data.items) data.alt_items = copy(data.items)
data.expand = item data.expand = item
if i3.compress_groups[item] then if i3.compress_groups[item] then
local items = copy(i3.compress_groups[item]) local items = copy(i3.compress_groups[item])
insert(items, fmt("_%s", item)) insert(items, fmt("_%s", item))
sort(items, function(a, b) sort(items, function(a, b)
if a:sub(1, 1) == "_" then if a:sub(1, 1) == "_" then
a = a:sub(2) a = a:sub(2)
end end
return a < b return a < b
end) end)
local i = 1 local i = 1
for _, v in ipairs(items) do for _, v in ipairs(items) do
if valid_item(reg_items[clean_name(v)]) then if valid_item(reg_items[clean_name(v)]) then
insert(data.alt_items, idx + i, v) insert(data.alt_items, idx + i, v)
i++ i++
end end
end end
end end
end end
else else
if sub(item, 1, 1) == "_" then if sub(item, 1, 1) == "_" then
item = sub(item, 2) item = sub(item, 2)
elseif sub(item, 1, 6) == "group!" then elseif sub(item, 1, 6) == "group!" then
item = match(item, "([%w:_]+)$") item = match(item, "([%w:_]+)$")
end end
item = reg_aliases[item] or item item = reg_aliases[item] or item
if not reg_items[item] then return end if not reg_items[item] then return end
if core.is_creative_enabled(data.player_name) then if core.is_creative_enabled(data.player_name) then
local stack = ItemStack(item) local stack = ItemStack(item)
local stackmax = stack:get_stack_max() local stackmax = stack:get_stack_max()
stack = fmt("%s %s", item, stackmax) stack = fmt("%s %s", item, stackmax)
return get_stack(player, stack) return get_stack(player, stack)
end end
if item == data.query_item then return end if item == data.query_item then return end
local recipes, usages = get_recipes(player, item) local recipes, usages = get_recipes(player, item)
data.query_item = item data.query_item = item
data.recipes = recipes data.recipes = recipes
data.usages = usages data.usages = usages
data.rnum = 1 data.rnum = 1
data.unum = 1 data.unum = 1
data.scrbar_rcp = 1 data.scrbar_rcp = 1
data.scrbar_usg = 1 data.scrbar_usg = 1
data.export_rcp = nil data.export_rcp = nil
data.export_usg = nil data.export_usg = nil
end end
end end
local function rcp_fields(player, data, fields) local function rcp_fields(player, data, fields)
local sb_rcp, sb_usg = fields.scrbar_rcp, fields.scrbar_usg local sb_rcp, sb_usg = fields.scrbar_rcp, fields.scrbar_usg
if fields.cancel then if fields.cancel then
reset_data(data) reset_data(data)
elseif fields.exit then elseif fields.exit then
data.query_item = nil data.query_item = nil
elseif fields.key_enter_field == "filter" or fields.search then elseif fields.key_enter_field == "filter" or fields.search then
if fields.filter == "" then if fields.filter == "" then
reset_data(data) reset_data(data)
return set_fs(player) return set_fs(player)
end end
local str = lower(fields.filter) local str = lower(fields.filter)
if data.filter == str then return end if data.filter == str then return end
data.filter = str data.filter = str
data.pagenum = 1 data.pagenum = 1
search(data) search(data)
if data.itab > 1 then if data.itab > 1 then
sort_by_category(data) sort_by_category(data)
end end
elseif fields.prev_page or fields.next_page then elseif fields.prev_page or fields.next_page then
if data.pagemax == 1 then return end if data.pagemax == 1 then return end
data.pagenum -= (fields.prev_page and 1 or -1) data.pagenum -= (fields.prev_page and 1 or -1)
if data.pagenum > data.pagemax then if data.pagenum > data.pagemax then
data.pagenum = 1 data.pagenum = 1
elseif data.pagenum == 0 then elseif data.pagenum == 0 then
data.pagenum = data.pagemax data.pagenum = data.pagemax
end end
elseif fields.prev_skin or fields.next_skin then elseif fields.prev_skin or fields.next_skin then
if data.skin_pagemax == 1 then return end if data.skin_pagemax == 1 then return end
data.skin_pagenum -= (fields.prev_skin and 1 or -1) data.skin_pagenum -= (fields.prev_skin and 1 or -1)
if data.skin_pagenum > data.skin_pagemax then if data.skin_pagenum > data.skin_pagemax then
data.skin_pagenum = 1 data.skin_pagenum = 1
elseif data.skin_pagenum == 0 then elseif data.skin_pagenum == 0 then
data.skin_pagenum = data.skin_pagemax data.skin_pagenum = data.skin_pagemax
end end
elseif fields.prev_recipe or fields.next_recipe then elseif fields.prev_recipe or fields.next_recipe then
local num = data.rnum + (fields.prev_recipe and -1 or 1) local num = data.rnum + (fields.prev_recipe and -1 or 1)
data.rnum = data.recipes[num] and num or (fields.prev_recipe and #data.recipes or 1) data.rnum = data.recipes[num] and num or (fields.prev_recipe and #data.recipes or 1)
data.export_rcp = nil data.export_rcp = nil
data.scrbar_rcp = 1 data.scrbar_rcp = 1
elseif fields.prev_usage or fields.next_usage then elseif fields.prev_usage or fields.next_usage then
local num = data.unum + (fields.prev_usage and -1 or 1) local num = data.unum + (fields.prev_usage and -1 or 1)
data.unum = data.usages[num] and num or (fields.prev_usage and #data.usages or 1) data.unum = data.usages[num] and num or (fields.prev_usage and #data.usages or 1)
data.export_usg = nil data.export_usg = nil
data.scrbar_usg = 1 data.scrbar_usg = 1
elseif fields.fav then elseif fields.fav then
local fav = is_fav(data) local fav = is_fav(data)
if #data.favs < i3.settings.max_favs and not fav then if #data.favs < i3.settings.max_favs and not fav then
insert(data.favs, data.query_item) insert(data.favs, fmt("_%s", data.query_item))
elseif fav then elseif fav then
remove(data.favs, fav) remove(data.favs, fav)
end end
elseif fields.export_rcp or fields.export_usg then elseif fields.export_rcp or fields.export_usg then
if fields.export_rcp then if fields.export_rcp then
data.export_rcp = not data.export_rcp data.export_rcp = not data.export_rcp
if not data.export_rcp then if not data.export_rcp then
data.scrbar_rcp = 1 data.scrbar_rcp = 1
end end
else else
data.export_usg = not data.export_usg data.export_usg = not data.export_usg
if not data.export_usg then if not data.export_usg then
data.scrbar_usg = 1 data.scrbar_usg = 1
end end
end end
elseif (sb_rcp and sub(sb_rcp, 1, 3) == "CHG") or (sb_usg and sub(sb_usg, 1, 3) == "CHG") then elseif (sb_rcp and sub(sb_rcp, 1, 3) == "CHG") or (sb_usg and sub(sb_usg, 1, 3) == "CHG") then
data.scrbar_rcp = sb_rcp and tonumber(match(sb_rcp, "%d+")) data.scrbar_rcp = sb_rcp and tonumber(match(sb_rcp, "%d+"))
data.scrbar_usg = sb_usg and tonumber(match(sb_usg, "%d+")) data.scrbar_usg = sb_usg and tonumber(match(sb_usg, "%d+"))
elseif fields.craft_rcp or fields.craft_usg then elseif fields.craft_rcp or fields.craft_usg then
craft_stack(player, data, fields.craft_rcp) craft_stack(player, data, fields.craft_rcp)
if fields.craft_rcp then if fields.craft_rcp then
data.export_rcp = nil data.export_rcp = nil
data.scrbar_rcp = 1 data.scrbar_rcp = 1
else else
data.export_usg = nil data.export_usg = nil
data.scrbar_usg = 1 data.scrbar_usg = 1
end end
else else
select_item(player, data, fields) select_item(player, data, fields)
end end
end end
core.register_on_player_receive_fields(function(player, formname, fields) core.register_on_player_receive_fields(function(player, formname, fields)
local name = player:get_player_name() local name = player:get_player_name()
if formname == "i3_outdated" then if formname == "i3_outdated" then
return false, core.kick_player(name, return false, core.kick_player(name,
S"Come back when your Minetest client is up-to-date (www.minetest.net).") S"Come back when your Minetest client is up-to-date (www.minetest.net).")
elseif formname ~= "" then elseif formname ~= "" then
return false return false
end end
-- No-op buttons -- No-op buttons
if fields.player_name or fields.awards or fields.home_pos or fields.pagenum or if fields.player_name or fields.awards or fields.home_pos or fields.pagenum or
fields.no_item or fields.no_rcp or fields.select_sorting or fields.sort_method or fields.no_item or fields.no_rcp or fields.select_sorting or fields.sort_method or
fields.bg_content then fields.bg_content then
return false return false
end end
--print(dump(fields)) --print(dump(fields))
local data = i3.data[name] local data = i3.data[name]
if not data then return end if not data then return end
for f in pairs(fields) do for f in pairs(fields) do
if sub(f, 1, 4) == "tab_" then if sub(f, 1, 4) == "tab_" then
local tabname = sub(f, 5) local tabname = sub(f, 5)
i3.set_tab(player, tabname) i3.set_tab(player, tabname)
break break
elseif sub(f, 1, 5) == "itab_" then elseif sub(f, 1, 5) == "itab_" then
data.pagenum = 1 data.pagenum = 1
data.itab = tonumber(f:sub(-1)) data.itab = tonumber(f:sub(-1))
sort_by_category(data) sort_by_category(data)
break break
end end
end end
rcp_fields(player, data, fields) rcp_fields(player, data, fields)
local tab = i3.tabs[data.tab] local tab = i3.tabs[data.tab]
if tab and tab.fields then if tab and tab.fields then
return true, tab.fields(player, data, fields) return true, tab.fields(player, data, fields)
end end
return true, set_fs(player) return true, set_fs(player)
end) end)
return inv_fields return inv_fields

View File

@ -1398,7 +1398,8 @@ local function get_favs(fs, data)
label(data.inv_width + 0.4, data.yoffset + 0.4, ES"Bookmarks") label(data.inv_width + 0.4, data.yoffset + 0.4, ES"Bookmarks")
for i = 1, #data.favs do for i = 1, #data.favs do
local item = data.favs[i] local name = data.favs[i]
local item = sub(name, 2)
local X = data.inv_width - 0.7 + (i * 1.2) local X = data.inv_width - 0.7 + (i * 1.2)
local Y = data.yoffset + 0.8 local Y = data.yoffset + 0.8
@ -1406,7 +1407,7 @@ local function get_favs(fs, data)
image(X, Y, btn_size, btn_size, PNG.slot) image(X, Y, btn_size, btn_size, PNG.slot)
end end
item_image_button(X, Y, btn_size, btn_size, item, item, "") item_image_button(X, Y, btn_size, btn_size, item, name, "")
end end
end end