made trade list nicer

This commit is contained in:
Sokomine 2022-04-11 22:17:07 +02:00
parent 9aa7d4f8a6
commit c5c7d3391c
2 changed files with 227 additions and 45 deletions

View File

@ -53,7 +53,7 @@ yl_speak_up.max_number_of_options_per_dialog = 15
-- how many rows and cols shall be used for the trade overview list?
yl_speak_up.trade_max_rows = 10
yl_speak_up.trade_max_cols = 4
yl_speak_up.trade_max_cols = 12
-- how many prerequirements can the player define per dialog option?
yl_speak_up.max_prerequirements = 12

View File

@ -34,7 +34,9 @@ yl_speak_up.input_trade_list = function(player, formname, fields)
-- normal mode: the player wants to see a particular trade
for k,v in pairs(dialog.trades) do
if(fields[ k ]) then
-- 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
@ -78,21 +80,152 @@ yl_speak_up.get_fs_trade_list = function(player, show_dialog_option_trades)
local formspec = {}
if(yl_speak_up.may_edit_npc(player, n_id)) then
-- allow players with the right priv to switch view between dialog option trades
-- and those normal ones in the trade list
if(not(show_dialog_option_trades)) then
table.insert(formspec, "button[3.0,-0.5;5.0,0.9;show_dialog_option_trades;"..
"Show trades attached to dialog options]")
else
table.insert(formspec, "button[3.0,-0.5;5.0,0.9;show_trade_list;"..
"Show trade list trades (player view)]")
end
else
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 dialog = yl_speak_up.speak_to[pname].dialog
local portrait = yl_speak_up.calculate_portrait(pname, n_id)
-- show who owns the NPC (and is thus more or less responsible for what it says)
local owner_info = ""
if(yl_speak_up.npc_owner[ n_id ]) then
owner_info = "\n\n(owned by "..minetest.formspec_escape(yl_speak_up.npc_owner[ n_id ])..")"
end
local fs_version = yl_speak_up.fs_version[pname]
formspec = {
"size[57,33]",
"position[0,0.45]",
"anchor[0,0.45]",
"no_prepend[]",
"bgcolor[#00000000;false]",
-- Container
"container[2,0.75]",
-- Background
"background[0,0;20,23;yl_speak_up_bg_dialog.png;false]",
"background[0,24;54.5,7.5;yl_speak_up_bg_dialog.png;false]",
-- Frame Dialog
"image[-0.25,-0.25;1,1;yl_speak_up_bg_dialog_tl.png]",
"image[-0.25,22.25;1,1;yl_speak_up_bg_dialog_bl.png]",
"image[19.25,-0.25;1,1;yl_speak_up_bg_dialog_tr.png]",
"image[19.25,22.25;1,1;yl_speak_up_bg_dialog_br.png]",
"image[-0.25,0.75;1,21.5;yl_speak_up_bg_dialog_hl.png]",
"image[19.25,0.75;1,21.5;yl_speak_up_bg_dialog_hr.png]",
"image[0.75,-0.25;18.5,1;yl_speak_up_bg_dialog_vt.png]",
"image[0.75,22.25;18.5,1;yl_speak_up_bg_dialog_vb.png]",
-- Frame Options
"image[-0.25,23.75;1,1;yl_speak_up_bg_dialog_tl.png]",
"image[-0.25,30.75;1,1;yl_speak_up_bg_dialog_bl.png]",
"image[53.75,23.75;1,1;yl_speak_up_bg_dialog_tr.png]",
"image[53.75,30.75;1,1;yl_speak_up_bg_dialog_br.png]",
"image[-0.25,24.75;1,6;yl_speak_up_bg_dialog_hl.png]",
"image[53.75,24.75;1,6;yl_speak_up_bg_dialog_hr.png]",
"image[0.75,23.75;53,1;yl_speak_up_bg_dialog_vt.png]",
"image[0.75,30.75;53,1;yl_speak_up_bg_dialog_vb.png]",
"label[0.3,0.6;",
minetest.formspec_escape(dialog.n_npc),
"]",
"label[0.3,1.8;",
minetest.formspec_escape(dialog.n_description)..owner_info,
"]",
"image[15.5,0.5;4,4;",
portrait,
"]",
}
-- add those things that only exist in formspec_v >= 4
if(fs_version > 2) then
table.insert(formspec, "style_type[button;bgcolor=#a37e45]")
table.insert(formspec, "style_type[button_exit;bgcolor=#a37e45]") -- Dialog
-- table.insert(formspec, "background[-1,-1;22,25;yl_speak_up_bg_dialog2.png;false]")
-- table.insert(formspec, "background[-1,23;58,10;yl_speak_up_bg_dialog2.png;false]")
-- table.insert(formspec, "style_type[button;bgcolor=#a37e45]")
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. Please "..
"look at all my offers [that is, scroll down a bit]!"..
"\n\n[$NPC_NAME$ looks expectantly at you.]"
local active_dialog = {}
active_dialog.d_text = ""
-- display the window with the text the NPC is saying
if(alternate_text) then
alternate_text = string.gsub(alternate_text, "%$TEXT%$", active_dialog.d_text)
end
-- replace $NPC_NAME$ etc.
local t = minetest.formspec_escape(yl_speak_up.replace_vars_in_text(
(alternate_text or active_dialog.d_text), dialog, pname))
if(fs_version > 2) then
yl_speak_up.add_formspec_element_with_tooltip_if(formspec,
"hypertext", "0.2,5;19.6,17.8", "d_text",
"<normal>"..t.."\n</normal>",
t:trim()..";#000000;#FFFFFF",
true)
else
yl_speak_up.add_formspec_element_with_tooltip_if(formspec,
"textarea", "0.2,5;19.6,17.8", "",
";"..t.."\n",
t:trim(),
true)
end
local pname_for_old_fs = nil
if(fs_version > 2) then
table.insert(formspec, "scrollbaroptions[min=0;max=14;smallstep=1;largestep=2;arrows=show]")
table.insert(formspec, "scrollbar[0.2,24.2;0.2,7;vertical;scr0;0]")
table.insert(formspec, "scroll_container[0,24;56,7;scr0;vertical;1]")
else
if(fs_version < 2) then
-- if the player has an older formspec version
minetest.log( "info",
"[MOD] yl_speak_up: User " .. pname .. " talked to NPC ID n_" .. n_id ..
" with an old formspec version!")
table.insert(formspec,
"box[0.3,20;19,2.6;red]"..
"label[0.7,20.3;"..yl_speak_up.text_version_warning.."]")
-- The up and down buttons are microscopic. Offer some (still small)
-- additional text buttons so that players have a chance to hit them.
table.insert(formspec, "button[49,23.1;6,0.9;button_down;^ Scroll Up ^]")
table.insert(formspec, "button[49,31.5;6,0.9;button_up;v Scroll Down v]")
table.insert(formspec, "button[1,23.1;6,0.9;button_down;^ Scroll Up ^]")
table.insert(formspec, "button[1,31.5;6,0.9;button_up;v Scroll Down v]")
end
-- old formspec versions need to remember somewhere extern how far the player scrolled
pname_for_old_fs = pname
yl_speak_up.speak_to[pname_for_old_fs].counter = 1
table.insert(formspec, "container[0,24]")
if(fs_version < 2) then
-- very small, ugly, and difficult to hit
table.insert(formspec, "button[0.1,0;1,0.9;button_down;^]")
table.insert(formspec, "button[0.1,7.0;1,0.9;button_up;v]")
else
-- somewhat larger and quite usable (v2 is pretty ok)
table.insert(formspec, "button[0.1,0;1,3;button_down;^\nU\np]")
table.insert(formspec, "button[0.1,3.2;1,4.5;button_up;D\no\nw\nn\nv]")
table.insert(formspec, "button[53.5,0;1,3;button_down;^\nU\np]")
table.insert(formspec, "button[53.5,3.2;1,4.5;button_up;D\no\nw\nn\nv]")
end
end
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
@ -107,13 +240,11 @@ yl_speak_up.get_fs_trade_list = function(player, show_dialog_option_trades)
end
table.sort(sorted_trades)
-- TODO: handle multiple pages?
for i, k in ipairs(sorted_trades) do
v = dialog.trades[ k ]
if(col < yl_speak_up.trade_max_cols
-- 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
and (not(show_dialog_option_trades) == not(v.d_id))
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])
@ -125,25 +256,84 @@ yl_speak_up.get_fs_trade_list = function(player, show_dialog_option_trades)
anz_trades = anz_trades + 1
local kstr = tostring(minetest.formspec_escape(k))
table.insert(formspec,
"item_image_button["..tostring(1+(col*4))..","..tostring(1+row)..";1,1;"..
tostring(v.pay[1])..";"..kstr..";]"..
"image_button["..tostring(1.8+(col*4))..","..tostring(1+row)..";1,1;"..
"gui_furnace_arrow_bg.png^[transformR270;"..kstr..";]"..
"item_image_button["..tostring(2.6+(col*4))..","..tostring(1+row)..";1,1;"..
tostring(v.buy[1])..";"..kstr..";]")
if(not(npc_inv:contains_item("npc_main", buy_stack))) then
table.insert(formspec,
"label["..tostring(1.7+(col*4))..","..tostring(1.2+row)..";Sold out]")
local sold_out = not(npc_inv:contains_item("npc_main", buy_stack))
local color = "#777777"
if(sold_out) then
color = "#333333"
-- still needs to contain kstr so that each button has a diffrent text
kstr = "sold out "..kstr
end
row = row + 1
if(row > yl_speak_up.trade_max_rows) then
row = 0
col = col + 1
table.insert(formspec,
"container["..tostring(0.5+(col*4.5))..","..
tostring(0.3+(row*6)).."]"..
"box[0,0;4.2,5.6;"..color.."]"..
"item_image_button[1.0,0.2;3,3;"..
tostring(v.pay[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.buy[1])..";"..kstr.."_;]")
if(sold_out) then
table.insert(formspec, "label[0,1.9;Sold out]\ncontainer_end[]")
else
-- show the price label only when the offer is in stock
table.insert(formspec, "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
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
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
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)
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)
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
h = yl_speak_up.add_edit_button_fs_talkdialog(formspec, h,
"button_exit",
yl_speak_up.message_button_option_exit,
yl_speak_up.message_button_option_exit,
true, nil, true, 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
@ -151,20 +341,12 @@ yl_speak_up.get_fs_trade_list = function(player, show_dialog_option_trades)
"label[1,1;Sorry. There are currently no offers available.]")
end
-- button "add trade" for those who can edit the NPC (entering edit mode is not required)
-- also add a quick way to access the inventory of the npc
if(yl_speak_up.may_edit_npc(player, n_id)) then
table.insert(formspec,
"button["..tostring(yl_speak_up.trade_max_cols * 4 - 2.2)..
",0.2;2.0,0.9;trade_list_add_trade;Add trade]"..
"button["..tostring(yl_speak_up.trade_max_cols * 4 - 4.2)..
",-0.5;4.0,0.9;show_inventory;Show inventory of NPC]")
end
return "size["..
tostring(yl_speak_up.trade_max_cols * 4)..","..
tostring(yl_speak_up.trade_max_rows + 2).."]"..
"button[0.2,0.0;2.0,0.9;finished_trading;Back to talk]"..
"label[3.0,0.2;"..tostring(dialog.n_npc).." offers you these trades:]"..
table.concat(formspec, "")
if(fs_version > 2) then
table.insert(formspec, "scroll_container_end[]")
else
table.insert(formspec, "container_end[]")
end
table.insert(formspec, "container_end[]")
return table.concat(formspec, "")
end