-- show a list of all trades -- the player is accessing the trade list yl_speak_up.input_trade_list = function(player, formname, fields) local pname = player:get_player_name() local d_id = yl_speak_up.speak_to[pname].d_id local n_id = yl_speak_up.speak_to[pname].n_id local dialog = yl_speak_up.speak_to[pname].dialog if(not(dialog.trades)) then dialog.trades = {} end -- the player wants to add a new trade if(fields.trade_list_add_trade) then -- show the trade config dialog for a new trade yl_speak_up.show_fs(player, "add_trade_simple", "new") return end if(fields.trade_limit) then -- show a list of how much the NPC can buy and sell yl_speak_up.show_fs(player, "trade_limit") return end -- toggle between view of dialog option trades and trade list trades if(fields.show_dialog_option_trades or fields.show_trade_list) then yl_speak_up.show_fs(player, "trade_list", fields.show_dialog_option_trades) return end -- go back to the main dialog if(fields.finished_trading) then yl_speak_up.show_fs(player, "talk", {n_id = n_id, d_id = d_id}) return end -- normal mode: the player wants to see a particular trade for k,v in pairs(dialog.trades) do -- the "_" is necessary for the price button so that offer and price -- button can each have their tooltip *and* lead to the same dialog if(fields[ k ] or fields[ k.."_" ]) then yl_speak_up.show_fs(player, "trade_simple", k) return end end -- show the inventory of the NPC if(fields.show_inventory) then yl_speak_up.show_fs(player, "inventory") return end -- TODO: and otherwise? end -- show a list of all trades the NPC has to offer -- if show_dialog_option_trades is set: show only those trades that are attached to options of dialogs; -- otherwise show only those trades attached to the trade list yl_speak_up.get_fs_trade_list = function(player, show_dialog_option_trades) if(not(player)) then return "" end local pname = player:get_player_name() -- which NPC is the player talking to? local n_id = yl_speak_up.speak_to[pname].n_id local dialog = yl_speak_up.speak_to[pname].dialog -- do we have all the necessary data? if(not(n_id) or not(dialog.n_npc)) then return "size[6,2]".. "label[0.2,0.5;Ups! This NPC lacks ID or name.]".. "button_exit[2,1.5;1,0.9;exit;Exit]" end -- make sure the NPC has that table defined if(not(dialog.trades)) then dialog.trades = {} end yl_speak_up.load_npc_inventory(n_id) local npc_inv = minetest.get_inventory({type="detached", name="yl_speak_up_npc_"..tostring(n_id)}) if(not(yl_speak_up.may_edit_npc(player, n_id))) then -- do not show trades attached to dialog options for players who cannot edit the NPC show_dialog_option_trades = false end local alternate_text = " I can offer you these trades.\n\n".. "Select one trade and then choose \"buy\" to actually buy something.".. "\n\nThere may be more trades then those shown in the first row.".. "\nPlease look at all my offers [that is, scroll down a bit]!".. "\n\n[$NPC_NAME$ looks expectantly at you.]" local pname_for_old_fs = yl_speak_up.get_pname_for_old_fs(pname) local formspec = {} local h = -0.8 -- arrange the offers in yl_speak_up.trade_max_cols columns horizontally -- and yl_speak_up.trade_max_rows row vertically local row = 0 local col = 0 local anz_trades = 0 -- the order in which the trades appear shall not change each time; -- but lua cannot sort the keys of a table by itself... local sorted_trades = {} for k in pairs(dialog.trades) do table.insert(sorted_trades, k) end table.sort(sorted_trades) for i, k in ipairs(sorted_trades) do local v = dialog.trades[ k ] -- needs both to be negated because show_dialog_option_trades will most of the time be nil -- and the actual value of v.d_id isn't of intrest here either if( (not(show_dialog_option_trades) == not(v.d_id)) and v.pay and v.pay[1] and v.pay[1] ~= "" and v.buy and v.buy[1] and v.buy[1] ~= "") then local pay_stack = ItemStack(v.pay[1]) local buy_stack = ItemStack(v.buy[1]) -- do not show trades with nonexistant items if( not(minetest.registered_items[ pay_stack:get_name() ]) or not(minetest.registered_items[ buy_stack:get_name() ])) then break end anz_trades = anz_trades + 1 local kstr = tostring(minetest.formspec_escape(k)) local sold_out = not(npc_inv:contains_item("npc_main", buy_stack)) local color = "#a37e45" --"#777777" if(sold_out) then color = "#663333" -- still needs to contain kstr so that each button has a diffrent text -- kstr = "sold out "..kstr end table.insert(formspec, "container["..tostring(0.5+(col*4.5))..",".. tostring(0.3+(row*6)).."]".. "style_type[button;bgcolor=#FF4444]".. "box[0,0;4.2,5.6;"..color.."]".. "item_image_button[1.0,0.2;3,3;".. tostring(v.buy[1])..";"..kstr..";]".. "item_image_button[2.0,3.4;2,2;".. -- the "_" at the end is necessary; we need a diffrent name -- here than kstr as that was used for another button (leading -- to the same result) just above tostring(v.pay[1])..";"..kstr.."_;]") if(sold_out) then -- table.insert(formspec, "label[0,1.9;Sold out]\ncontainer_end[]") table.insert(formspec, "button[0,1.0;4.3,1.0;"..kstr.."__;Sold out]".. "\ncontainer_end[]") else -- show the price label only when the offer is in stock table.insert(formspec, "label[0,1.9;->]".. "label[0,4.4;Price:]\ncontainer_end[]") end col = col + 1 if(col >= yl_speak_up.trade_max_cols) then col = 0 row = row + 1 end end end -- set button background color back to golden/brownish table.insert(formspec, "style_type[button;bgcolor=#a37e45]") h = (row+1) * 6 - 0.6 h = yl_speak_up.add_edit_button_fs_talkdialog(formspec, h, "show_inventory", "Access and manage the inventory of the NPC. This is used for adding trade ".. "items, getting collected payments and managing quest items.", "Show your inventory (only accessible to owner)!", true, nil, nil, pname_for_old_fs) -- allow players with the right priv to switch view between dialog option trades -- and those normal ones in the trade list if(yl_speak_up.may_edit_npc(player, n_id)) then if(not(show_dialog_option_trades)) then local text = "This is the trade list view (player view). ".. "Show trades attached to dialog options." h = yl_speak_up.add_edit_button_fs_talkdialog(formspec, h, "show_dialog_option_trades", text, text, true, nil, nil, pname_for_old_fs) else local text = "These are trades attached to dialog options. ".. "Show trade list trades (player view)." h = yl_speak_up.add_edit_button_fs_talkdialog(formspec, h, "show_trade_list", text, text, true, nil, nil, pname_for_old_fs) end -- button "add trade" for those who can edit the NPC (entering edit mode is not required) local text = "Add a new trade." h = yl_speak_up.add_edit_button_fs_talkdialog(formspec, h, "trade_list_add_trade", text, text, true, nil, nil, pname_for_old_fs) -- show a list of how much the NPC will buy and sell text = "Do not buy or sell more than what I will tell you." h = yl_speak_up.add_edit_button_fs_talkdialog(formspec, h, "trade_limit", text, text, true, nil, nil, pname_for_old_fs) end local text = "That was all. Let's continue talking." h = yl_speak_up.add_edit_button_fs_talkdialog(formspec, h, "finished_trading", text, text, true, nil, nil, pname_for_old_fs) -- button_exit -- if there are no trades, at least print a hint that there could be some here -- (a mostly empty formspec looks too boring and could irritate players) if(anz_trades == 0) then table.insert(formspec, "label[1,1;Sorry. There are currently no offers available.]") end -- edit mode makes no sense here in the trade list return yl_speak_up.show_fs_decorated(pname, nil, h, alternate_text, "", table.concat(formspec, "\n"), nil, h) end