bank_accounts/wtm.lua

197 lines
9.2 KiB
Lua

--[[
Wire Transfer Machine (WTM) Node
--------------------------------
This file defines the WTM, which allows players to securely transfer
money from their balance or credit line to another player's account.
--]]
-- Uses the global 'pos_info' variable for consistency.
-- Shows the account statement form.
-- This function is identical to the one in atm.lua but is kept here
-- in case of future WTM-specific modifications.
local function show_wtm_statement_form(player, account_type)
local player_name = player:get_player_name()
local data = bank_accounts.get_account_data(player_name)
local history = data.history
local lines = {}
local current_total_label = ""
table.insert(lines, minetest.formspec_escape(string.format("%-11s | %-13s | %-13s | %-20s | %-20s | %s", S("Date"), S("Amount"), S("New Balance"), S("Method"), S("Purpose"), S("Partner"))))
table.insert(lines, minetest.formspec_escape("-----------------------------------------------------------------------------------------"))
if history then
for _, t in ipairs(history) do
if t.account == account_type then
local parts = {}
table.insert(parts, string.format("%-11s", os.date("%Y-%m-%d", t.timestamp)))
table.insert(parts, string.format("%12s", string.format("%+.2f", t.amount) .. " MG"))
table.insert(parts, string.format("%12s", string.format("%.2f", t.new_total).." MG"))
table.insert(parts, string.format("%-20s", S(t.type)))
local purpose = t.purpose or ""
local partner = t.other or ""
if purpose ~= "" or partner ~= "" then
table.insert(parts, string.format("%-20s", purpose))
if partner ~= "" then
table.insert(parts, partner)
end
end
table.insert(lines, minetest.formspec_escape(table.concat(parts, " | ")))
end
end
end
if account_type == "balance" then
current_total_label = S("Current Balance: @1", string.format("%.2f", data.balance) .. " MG")
else
current_total_label = S("Current Credit Debt: @1", string.format("%.2f", data.credit) .. " MG")
end
local form_name = "bank_accounts:wtm_statement@" .. player_name
local formspec = "size[13,9]"..
"label[0,0;"..S("Account Statement for @1", player_name).."]"..
"button_exit[0,0.5;2,1;view_balance;"..S("Balance").."]"..
"button_exit[2,0.5;2,1;view_credit;"..S("Credit").."]"..
"textlist[0,1.2;13,7;statement_list;"..table.concat(lines,",").."]"..
"label[0,8.4;"..current_total_label.."]"..
"button_exit[11,8.4;2,1;back;"..S("Back").."]"
minetest.show_formspec(player_name, form_name, formspec)
end
-- Shows the main menu for the WTM.
function wtm_main_form(player, pos)
local player_name = player:get_player_name()
local data = bank_accounts.get_account_data(player_name)
minetest.show_formspec(player_name, "bank_accounts:wtm_options",
"size[8,8]" ..
"button_exit[0.5,1;3.5,1;transfer_balance;"..S("Transfer from Balance").."]" ..
"button_exit[0.5,2.0;3.5,1;transfer_credit;"..S("Transfer from Credit").."]" ..
"button_exit[5,2.5;2.4,1;statement;"..S("Account Statement").."]" ..
"label[5,1;"..S("Balance: @1", string.format("%.2f", data.balance) .. " MG").."]" ..
"label[5,1.5;"..S("Credit Debt: @1", string.format("%.2f", data.credit) .. " MG").."]" ..
"button_exit[0.5,6;3,1;credit_card;"..S("Get Credit Card").."]" ..
"button_exit[0.5,7;3,1;debit_card;"..S("Get Debit Card").."]" ..
"button_exit[5,7;2,1;exit;"..S("Close").."]")
end
-- Node definition for the Wire Transfer Machine.
minetest.register_node("bank_accounts:wtm", {
description = S("Wire Transfer Machine"),
drawtype = "mesh",
mesh = "atm.obj", -- Uses ATM model as a base
paramtype = "light",
paramtype2 = "facedir",
tiles = {"wtm_col.png"}, -- Custom texture
groups = {cracky=3, crumbly=3, oddly_breakable_by_hand=2},
-- Standard right-click function for PIN entry.
on_rightclick = function(pos, node, player, itemstack, pointed_thing)
pos_info = pos
if itemstack:get_name() ~= "bank_accounts:atm_card" then
minetest.chat_send_player(player:get_player_name(), S("[WTM] Must use ATM card."))
return
end
minetest.show_formspec(player:get_player_name(), "bank_accounts:wtm_home",
"size[8,8]" ..
"pwdfield[2,4;4,1;fourdigitpin;"..S("Four Digit Pin:").."]" ..
"button_exit[5,6;2,1;enter;"..S("Enter").."]" ..
"button_exit[3,6;2,1;exit;"..S("Cancel").."]")
end,
})
-- Central handler for all formspec interactions related to the WTM.
minetest.register_on_player_receive_fields(function(player, formname, fields)
if not formname:find("bank_accounts:wtm") then
return
end
local player_name = player:get_player_name()
local pos = pos_info
if not pos then
return
end
-- Handle PIN entry form.
if formname == "bank_accounts:wtm_home" then
if fields.enter then
if bank_accounts.get_pin(player_name) == fields.fourdigitpin then
wtm_main_form(player, pos)
else
minetest.chat_send_player(player_name, S("[WTM] Invalid Pin."))
end
end
-- Handle main menu options.
elseif formname == "bank_accounts:wtm_options" then
if fields.statement then
show_wtm_statement_form(player, "balance")
elseif fields.transfer_balance or fields.transfer_credit then
local source_account = fields.transfer_balance and "balance" or "credit"
local source_label = ""
if source_account == "balance" then
source_label = S("Transfer from Balance (Available: @1 MG)", string.format("%.2f", bank_accounts.get_balance(player_name)))
else
source_label = S("Transfer from Credit (Debt: @1 MG)", string.format("%.2f", bank_accounts.get_credit(player_name)))
end
minetest.show_formspec(player_name, "bank_accounts:wtm_transfer@"..source_account,
"size[8,8]" ..
"label[0,0;"..source_label.."]" ..
"field[0.5,1.5;7.5,1;recipient;"..S("Recipient:")..";]" ..
"field[0.5,2.5;7.5,1;amount;"..S("Amount:")..";]" ..
"field[0.5,3.5;7.5,1;purpose;"..S("Purpose:")..";]" ..
"button_exit[4,7;2,1;send;"..S("Send").."]" ..
"button_exit[2,7;2,1;cancel;"..S("Cancel").."]")
elseif fields.credit_card then
player:get_inventory():add_item("main", "bank_accounts:credit_card")
wtm_main_form(player, pos)
elseif fields.debit_card then
player:get_inventory():add_item("main", "bank_accounts:debit_card")
wtm_main_form(player, pos)
end
-- Handle the transfer form itself.
elseif formname:find("bank_accounts:wtm_transfer@") then
if fields.send then
local source_account = formname:match("bank_accounts:wtm_transfer@(.*)")
local recipient = fields.recipient
local amount = normalize_and_tonumber(fields.amount)
local purpose = fields.purpose
-- Validation checks
if not recipient or recipient == "" or not bank_accounts.player_has_account(recipient) then
minetest.chat_send_player(player_name, S("[WTM] Recipient not found or has no account."))
elseif not amount or amount <= 0 then
minetest.chat_send_player(player_name, S("[WTM] Invalid amount."))
elseif source_account == "balance" and bank_accounts.get_balance(player_name) < amount then
minetest.chat_send_player(player_name, S("[WTM] Insufficient funds."))
else
-- Process the transaction
if source_account == "balance" then
bank_accounts.add_balance(player_name, -amount, "Transfer Sent", purpose, recipient)
else -- source is "credit"
bank_accounts.add_credit(player_name, amount, "Transfer Sent (Credit)", purpose, recipient)
end
bank_accounts.add_balance(recipient, amount, "Transfer Received", purpose, player_name)
-- Send chat notifications
minetest.chat_send_player(player_name, S("[WTM] Successfully transferred @1 MG to @2.", string.format("%.2f", amount), recipient))
minetest.chat_send_player(recipient, S("[WTM] You received a transfer of @1 MG from @2.", string.format("%.2f", amount), player_name))
end
end
wtm_main_form(player, pos) -- Always return to the main menu
-- Handle the statement form.
elseif formname:find("bank_accounts:wtm_statement@") then
local target_name = formname:match("bank_accounts:wtm_statement@(.*)")
if not target_name then return end
if fields.back then
wtm_main_form(player, pos)
else
show_wtm_statement_form(player, fields.view_credit and "credit" or "balance")
end
end
end)