-- computer.lua (Zurückgesetzt auf stabile Basis + Nur "System is busy" Logik hinzugefügt) minetest.register_privilege("bank_teller", { description = S("Qualified Bank Teller"), }) pos_data = {} local function show_teller_form(player, pos, customer_name) local list_name = "nodemeta:" .. pos.x .. "," .. pos.y .. "," .. pos.z local data = {balance = 0, credit = 0} if customer_name and customer_name ~= "" and bank_accounts.player_has_account(customer_name) then data = bank_accounts.get_account_data(customer_name) end local formspec = "size[8,9.5]" .. "label[0,-.25;"..S("Deposit:").."]" .. "list["..list_name..";ones;0,.25;1,1]" .. "list["..list_name..";fives;1.25,.25;1,1]" .. "list["..list_name..";tens;2.5,.25;1,1]" .. "label[0.25,1.2;1 MG]" .. "label[1.5,1.2;5 MG]" .. "label[2.75,1.2;10 MG]" .. "field[4,.5;4,1;playername;"..S("Player:")..";"..minetest.formspec_escape(customer_name or "").."]" .. "field[.3,2.25;4,1;withdrawal;"..S("Withdraw:")..";]" .. "field[.3,3.25;4,1;credit_debt;"..S("Credit Payment:")..";]" .. "label[.5,4.5;"..S("Balance: @1", string.format("%.2f", data.balance).." MG").."]" .. "label[.5,4.75;"..S("Credit Debt: @1", string.format("%.2f", data.credit).." MG").."]" .. "button_exit[5.5,1;2,1;stats;"..S("Show Account").."]" .. "button_exit[5.5,2;2,1;statement;"..S("Account Statement").."]" .. "button_exit[5.5,3;2,1;wipe;"..S("Wipe Account").."]" .. "button_exit[5.5,4;2,1;reset_pin;"..S("Reset PIN").."]" .. "button_exit[3,5.5;2,1;exit;"..S("Cancel").."]" .. "button_exit[5.5,5.5;2,1;enter;"..S("Enter").."]" .. "list[current_player;main;0,7;8,2.5;]" minetest.show_formspec(player:get_player_name(), "bank_accounts:teller", formspec) end local function show_statement_form(player, pos, customer_name, account_type) local data = bank_accounts.get_account_data(customer_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:statement@" .. customer_name local formspec = "size[13,9]".."label[0,0;"..S("Account Statement for @1",customer_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:get_player_name(), form_name, formspec) end minetest.register_node("bank_accounts:teller_computer", { description = S("Bank Teller's Computer"), drawtype = "mesh", mesh = "computer.obj", paramtype = "light", paramtype2 = "facedir", light_source = 5, tiles = {{name="computer.png"},{name="computer_screen.png"}}, groups = {cracky=3, crumbly=3, oddly_breakable_by_hand=2}, selection_box = {type="fixed",fixed={-0.5,-0.5,-0.5,0.5,0.4,0.2}}, collision_box = {type="fixed",fixed={-0.5,-0.5,-0.5,0.5,0.4,0.2}}, on_construct = function(pos) local meta = minetest.get_meta(pos); local inv = meta:get_inventory(); inv:set_size("ones", 1); inv:set_size("fives", 1); inv:set_size("tens", 1) end, on_rightclick = function(pos, node, player, itemstack, pointed_thing) pos_info = pos local player_name = player:get_player_name() if player:get_player_control().aux1 and minetest.check_player_privs(player_name, {server=true}) then minetest.show_formspec(player_name, "bank_accounts:admin_teller", "size[8,4]" .. "field[.5,.5;4,1;search;"..S("Search:")..";]" .. "button_exit[4.5,.22;2,1;search_button;"..S("Search").."]" .. "label[.5,1.25;"..S("Player:").."]".. "label[3.5,1.25;"..S("Seized:").."]") elseif minetest.check_player_privs(player_name, {bank_teller=true}) then show_teller_form(player, pos, "") else minetest.chat_send_player(player_name, S("[Bank] Insufficient privileges.")) end end, allow_metadata_inventory_put = function(pos, listname, index, stack, player) if listname=="ones" and stack:get_name()~="currency:minegeld" then return 0 end; if listname=="fives" and stack:get_name()~="currency:minegeld_5" then return 0 end; if listname=="tens" and stack:get_name()~="currency:minegeld_10" then return 0 end; return stack:get_count() end, allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) local inv=minetest.get_meta(pos):get_inventory(); local stack=inv:get_stack(from_list, from_index); if to_list=="ones" and stack:get_name()~="currency:minegeld" then return 0 end; if to_list=="fives" and stack:get_name()~="currency:minegeld_5" then return 0 end; if to_list=="tens" and stack:get_name()~="currency:minegeld_10" then return 0 end; return count end, }) minetest.register_on_player_receive_fields(function(player, formname, fields) if not formname:find("bank_accounts:teller") and not formname:find("bank_accounts:admin_teller") and not formname:find("bank_accounts:statement") then return end local player_name = player:get_player_name(); local pos = pos_info; if not pos then return end local function on_fail() minetest.chat_send_player(player_name, S("[Bank] System is busy, please try again in a moment.")) end if formname == "bank_accounts:admin_teller" then if fields.search_button and fields.search and fields.search ~= "" then local search_name=fields.search; local status; if not bank_accounts.player_has_account(search_name) then status=S("No Account") elseif minetest.check_player_privs(search_name,{seized=true}) then status=S("Yes") else status=S("No") end; minetest.show_formspec(player_name,formname,"size[8,4]".."field[.5,.5;4,1;search;"..S("Search:")..";"..minetest.formspec_escape(search_name).."]".."button_exit[4.5,.22;2,1;search_button;"..S("Search").."]".."label[.5,1.25;"..S("Player:").."]".."label[3.5,1.25;"..S("Seized:").."]".."label[.5,1.75;"..minetest.formspec_escape(search_name).."]".."label[3.5,1.75;"..status.."]") end; return end if formname == "bank_accounts:teller" then local customer_name = fields.playername -- Die "seltsame", aber für dich funktionierende Validierungslogik. Unverändert. if (not customer_name or customer_name=="") and not fields.exit then minetest.chat_send_player(player_name, S("[Bank] Must enter a player name.")); return end if (customer_name and customer_name~="" and not bank_accounts.player_has_account(customer_name)) and not fields.exit then minetest.chat_send_player(player_name, S("[Bank] Invalid player name entered.")); return end -- Funktions-Wrapper beibehalten, da er in der funktionierenden Basis war. local function show_updated_form(p, a_pos, c_name) show_teller_form(p, a_pos, c_name) end if fields.stats then show_updated_form(player, pos, customer_name) elseif fields.statement then show_statement_form(player, pos, customer_name, "balance") elseif fields.wipe then if not bank_accounts.set_balance(customer_name, 0, "Teller Wipe", S("Teller: @1", player_name), player_name) then on_fail() end show_updated_form(player, pos, customer_name) elseif fields.reset_pin then if not bank_accounts.set_pin(customer_name, "0000") then on_fail() end show_updated_form(player, pos, customer_name) elseif fields.enter then local meta=minetest.get_meta(pos); local inv=meta:get_inventory(); local total_deposit=inv:get_stack("ones",1):get_count()+inv:get_stack("fives",1):get_count()*5+inv:get_stack("tens",1):get_count()*10 if total_deposit>0 then if not bank_accounts.add_balance(customer_name,total_deposit,"Teller Deposit",S("Teller: @1",player_name),player_name) then on_fail() end end local withdrawal = tonumber(fields.withdrawal); if withdrawal and withdrawal>0 then if withdrawal%1~=0 then minetest.chat_send_player(player_name,S("[Bank] Withdrawal amount must be a whole number.")) elseif bank_accounts.get_balance(customer_name)>=withdrawal then if not bank_accounts.add_balance(customer_name,-withdrawal,"Teller Withdrawal",S("Teller: @1",player_name),player_name) then on_fail() else local tens=math.floor(withdrawal/10);local rem=withdrawal%10;local fives=math.floor(rem/5);local ones=rem%5;player:get_inventory():add_item("main",{name="currency:minegeld_10",count=tens});player:get_inventory():add_item("main",{name="currency:minegeld_5",count=fives});player:get_inventory():add_item("main",{name="currency:minegeld",count=ones}) end else minetest.chat_send_player(player_name,S("[Bank] Player has insufficient funds for withdrawal.")) end end local credit_payment = normalize_and_tonumber(fields.credit_debt); if credit_payment and credit_payment>0 then if bank_accounts.get_balance(customer_name)>=credit_payment then if bank_accounts.get_credit(customer_name)>=credit_payment then local s1 = bank_accounts.add_balance(customer_name,-credit_payment,"Teller Credit Payment",S("Teller: @1",player_name),player_name) local s2 = bank_accounts.add_credit(customer_name,-credit_payment,"Teller Credit Payment",S("Teller: @1",player_name),player_name) if not s1 or not s2 then on_fail() end else minetest.chat_send_player(player_name,S("[Bank] Player does not have that much credit debt.")) end else minetest.chat_send_player(player_name,S("[Bank] Player has insufficient funds for credit payment.")) end end inv:set_stack("ones",1,nil);inv:set_stack("fives",1,nil);inv:set_stack("tens",1,nil); show_updated_form(player,pos,customer_name) end end if formname:find("bank_accounts:statement@") then local customer_name=formname:match("bank_accounts:statement@(.*)"); if not customer_name then return end if fields.view_balance then show_statement_form(player, pos, customer_name, "balance") elseif fields.view_credit then show_statement_form(player, pos, customer_name, "credit") elseif fields.back then show_teller_form(player, pos, customer_name) end end end)