Electronic trading exchange in Minetest
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

131 lines
3.0 KiB

  1. local exchange, formlib = ...
  2. local mailbox_form = "global_exchange:digital_mailbox"
  3. local mailbox_contents = {}
  4. local selected_index = {}
  5. -- Map from player names to their most recent search result
  6. local function get_mail(p_name)
  7. local mail_maybe = mailbox_contents[p_name]
  8. if not mail_maybe then
  9. local _,res = exchange:view_inbox(p_name)
  10. mail_maybe = res or {}
  11. mailbox_contents[p_name] = mail_maybe
  12. selected_index[p_name] = math.min(selected_index[p_name] or 0, #mail_maybe)
  13. end
  14. return mail_maybe
  15. end
  16. local function wear_string(wear)
  17. return "-" .. math.ceil(100 * wear / 65535) .. "%"
  18. end
  19. local function mk_inbox_list(fs, results, x, y, w, h)
  20. fs:textlist(x,y, w,h, "result_list", function(add_row)
  21. for i, row in ipairs(results) do
  22. local wear_suffix = nil
  23. if row.Wear > 0 then
  24. wear_suffix = " (" .. wear_string(row.Wear) .. ")"
  25. end
  26. add_row(row.Amount, " ", row.Item, wear_suffix)
  27. end
  28. end)
  29. end
  30. local function mk_mail_fs(fs, p_name, results, err_str)
  31. fs:size(8,8)
  32. fs:label(0,0, "Inbox")
  33. if err_str then
  34. fs:label(3,0, "Error: " .. err_str)
  35. end
  36. mk_inbox_list(fs, results, 0, 1, 7.75, 6.25)
  37. fs:button(3,7.35, 2,1, "claim", "Claim")
  38. end
  39. local function show_mail(p_name, err_str)
  40. local fs = formlib.Builder()
  41. mk_mail_fs(fs, p_name, get_mail(p_name), err_str)
  42. minetest.show_formspec(p_name, mailbox_form, tostring(fs))
  43. end
  44. minetest.register_on_player_receive_fields(function(player, formname, fields)
  45. if formname ~= mailbox_form then return end
  46. if fields.quit then return true end
  47. local p_name = player:get_player_name()
  48. if fields.result_list then
  49. local event = minetest.explode_textlist_event(fields.result_list)
  50. if event.type == "CHG" then
  51. selected_index[p_name] = event.index
  52. end
  53. end
  54. if fields.claim then
  55. local idx = selected_index[p_name]
  56. local row = get_mail(p_name)[idx]
  57. if row then
  58. local stack = ItemStack(row.Item)
  59. stack:set_count(row.Amount)
  60. stack:set_wear(row.Wear)
  61. local p_inv = player:get_inventory()
  62. local leftover = p_inv:add_item("main", stack)
  63. local took_amount = row.Amount - leftover:get_count()
  64. mailbox_contents[p_name] = nil
  65. local succ, res = exchange:take_inbox(row.Id, took_amount)
  66. if succ then
  67. show_mail(p_name)
  68. else
  69. show_mail(p_name, res)
  70. end
  71. end
  72. end
  73. return true
  74. end)
  75. minetest.register_node("global_exchange:mailbox", {
  76. description = "Digital Mailbox",
  77. tiles = {
  78. "global_exchange_box.png",
  79. "global_exchange_box.png",
  80. "global_exchange_box.png^global_exchange_mailbox_side.png",
  81. },
  82. is_ground_content = false,
  83. stack_max = 1,
  84. groups = {cracky=2},
  85. on_rightclick = function(pos, node, clicker)
  86. local p_name = clicker:get_player_name()
  87. mailbox_contents[p_name] = nil
  88. show_mail(p_name)
  89. end,
  90. })
  91. minetest.register_craft( {
  92. output = "global_exchange:mailbox",
  93. recipe = {
  94. { "default:stone", "default:gold_ingot", "default:stone" },
  95. { "default:stone", "default:chest", "default:stone" },
  96. { "default:stone", "default:stone", "default:stone" },
  97. }
  98. })
  99. -- vim:set ts=4 sw=4 noet: