From 70715f3b024d76497f38a87da7897172728ff719 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 17 May 2018 14:46:19 +0200 Subject: [PATCH] Implement unique dialog names --- API.md | 8 ++++++-- init.lua | 22 ++++++++++++++-------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/API.md b/API.md index a177270..ffdbfe2 100644 --- a/API.md +++ b/API.md @@ -7,7 +7,7 @@ to check for the mod's existence first (`minetest.get_modpath` returns non-`nil` value). ## Functions -### `select_item.show_dialog(playername, filter)` +### `select_item.show_dialog(playername, dialogname, filter)` Shows an item selection dialog to a player. The player can choose one item (which triggers a callback) or abort selection (in which case nothing happens). @@ -20,9 +20,12 @@ to filter out unwanted items. #### Parameters * `playername`: Name of player to show dialog to +* `dialogname`: Unique identifier of the dialog * `filter`: Optional filter function to narrow down the visible items (see below) +Recommended form of `dialogname` is “`:`”. + #### Filter function The filter function has the function signature `filter(itemstring)`. This function will be called for each item with the itemstring @@ -42,8 +45,9 @@ Whenever a player selects an item or cancels the selection, `callback` is called. #### `callback` function -This has the function signature `callback(playername, itemstring)`. +This has the function signature `callback(identifier, playername, itemstring)`. +* `identifier` is the identifier of the item formspec * `playername` is the name of the player who selected the item, * `itemstring` is the itemstring of the chosen item or `nil` if aborted diff --git a/init.lua b/init.lua index f184854..370003d 100644 --- a/init.lua +++ b/init.lua @@ -68,8 +68,9 @@ local xsize_norm = 12 local ysize_norm = 9 -- Opens the item selection dialog for player with the given filter function at page. +-- The dialog has unique identifier dialogname. -- Returns: Number of items it displays. -local show_dialog_page = function(playername, filter, page) +local show_dialog_page = function(playername, dialogname, filter, page) local items if player_filters[playername] == nil then player_filters[playername] = filter @@ -131,12 +132,12 @@ local show_dialog_page = function(playername, filter, page) form = form .. "label[2,"..ynav..";"..minetest.formspec_escape(string.format("Page %d/%d", page, total_pages)).."]" end form = form .. "button_exit["..(xsize-2)..","..ynav..";2,1;cancel;Cancel]" - minetest.show_formspec(playername, "select_item:page"..page, form) + minetest.show_formspec(playername, "select_item:page"..page.."_"..dialogname, form) return #items end -select_item.show_dialog = function(playername, filter) - show_dialog_page(playername, filter, 1) +select_item.show_dialog = function(playername, dialogname, filter) + show_dialog_page(playername, dialogname, filter, 1) end local callbacks = {} @@ -147,6 +148,12 @@ end minetest.register_on_player_receive_fields(function(player, formname, fields) local playername = player:get_player_name() if string.sub(formname, 1, 16) == "select_item:page" then + -- Parse formname + local rest = string.sub(formname, 17, string.len(formname)) + local split = string.split(rest, "_", true, 2) + local page = tonumber(split[1]) + local dialogname = split[2] + local item for field,_ in pairs(fields) do if string.sub(field, 1, 5) == "item_" then @@ -157,7 +164,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) if item or fields.quit then local close = true for i=1,#callbacks do - local ret = callbacks[i](playername, item) + local ret = callbacks[i](playername, dialogname, item) if ret == false then close = false end @@ -170,14 +177,13 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) if fields.quit or fields.cancel then reset_player_info(playername) end - local page = tonumber(string.sub(formname, 17, string.len(formname))) if page ~= nil then if fields.previous and page > 1 then - show_dialog_page(player:get_player_name(), player_filters[playername], page - 1) + show_dialog_page(player:get_player_name(), dialogname, player_filters[playername], page - 1) elseif fields.next then local maxpage = player_maxpage[playername] if maxpage and (page + 1 <= maxpage) then - show_dialog_page(playername, player_filters[playername], page + 1) + show_dialog_page(playername, dialogname, player_filters[playername], page + 1) end if not maxpage then minetest.log("warning", "[select_item] Player "..playername.." managed to navigate select_item menu without maxpage set!")