diff --git a/digital_mailbox.lua b/digital_mailbox.lua new file mode 100644 index 0000000..3f9ebd4 --- /dev/null +++ b/digital_mailbox.lua @@ -0,0 +1,122 @@ + +local exchange = ... + +local mailbox_form = "global_exchange:digital_mailbox" + +local mailbox_contents = {} +local selected_index = {} +-- Map from player names to their most recent search result + +local function get_mail(p_name) + local mail_maybe = mailbox_contents[p_name] + if mail_maybe then + return mail_maybe + else + mailbox_contents[p_name] = {} + return mailbox_contents[p_name] + end +end + + +local function mk_inbox_list(results, x, y, w, h) + local res = {} + table.insert(res, "textlist[") + table.insert(res, tostring(x)) + table.insert(res, ",") + table.insert(res, tostring(y)) + table.insert(res, ";") + table.insert(res, tostring(w)) + table.insert(res, ",") + table.insert(res, tostring(h)) + table.insert(res, ";result_list;") + + for i, row in ipairs(results) do + table.insert(res, row.Amount .. " " .. row.Item) + table.insert(res, ",") + end + table.insert(res, "]") + + return table.concat(res) +end + + +local function mk_mail_fs(p_name, results, err_str) + fs = "size[6,8]" + if err_str then + fs = fs .. "label[0,0;Error: " .. err_str .. "]" + end + fs = fs .. mk_inbox_list(results, 0, 1, 6, 6) + fs = fs .. "button[0,7;2,1;claim;Claim]" + + return fs +end + + +local function show_mail(p_name, results, err_str) + minetest.show_formspec(p_name, mailbox_form, mk_mail_fs(p_name, results, err_str)) +end + + +local function handle_fields(player, formname, fields) + if formname ~= mailbox_form then return end + if fields["quit"] then return true end + + local p_name = player:get_player_name() + local idx = selected_index[p_name] + + if fields["claim"] and idx then + local row = get_mail(p_name)[idx] + + if row then + local stack = ItemStack(row.Item) + stack:set_count(row.Amount) + + local p_inv = player:get_inventory() + if not p_inv:room_for_item("main", stack) then + show_mail(p_name, get_mail(p_name), "Not enough room.") + return true + end + + local succ, res = exchange:take_inbox(row.Id, row.Amount) + if not succ then + show_mail(p_name, get_mail(p_name), res) + end + + stack:set_count(res) + + p_inv:add_item("main", stack) + + table.remove(get_mail(p_name), idx) + show_mail(p_name, get_mail(p_name)) + end + end + + if fields["result_list"] then + local event = minetest.explode_textlist_event(fields["result_list"]) + + if event.type == "CHG" then + selected_index[p_name] = event.index + end + end + + return true +end + + +minetest.register_on_player_receive_fields(handle_fields) + + +minetest.register_node("global_exchange:mailbox", { + description = "Digital Mailbox", + tiles = {"global_exchange_atm_top.png", + "global_exchange_atm_top.png", + "global_exchange_mailbox_side.png", + }, + groups = {cracky=2}, + on_rightclick = function(pos, node, clicker) + local p_name = clicker:get_player_name() + local succ, res = exchange:view_inbox(p_name) + mailbox_contents[p_name] = res + minetest.show_formspec(p_name, mailbox_form, mk_mail_fs(p_name, res)) + end, +}) diff --git a/exchange.lua b/exchange.lua index 1d1a1f7..b9b2b77 100644 --- a/exchange.lua +++ b/exchange.lua @@ -960,7 +960,7 @@ end -- On failure, returns false and an error message. function ex_methods.view_inbox(self, p_name) local db = self.db - local stmt = self.stmt.view_inbox_stmt + local stmt = self.stmts.view_inbox_stmt stmt:bind_values(p_name) diff --git a/init.lua b/init.lua index d3c839b..158b4f6 100644 --- a/init.lua +++ b/init.lua @@ -50,3 +50,4 @@ end) assert(loadfile(modpath .. "atm.lua"))(exchange) assert(loadfile(modpath .. "exchange_machine.lua"))(exchange) +assert(loadfile(modpath .. "digital_mailbox.lua"))(exchange) diff --git a/textures/global_exchange_mailbox_side.png b/textures/global_exchange_mailbox_side.png new file mode 100644 index 0000000..d28f182 Binary files /dev/null and b/textures/global_exchange_mailbox_side.png differ