[MIRROR] Convert ATM to TGUI (#9212)

Co-authored-by: ShadowLarkens <shadowlarkens@gmail.com>
Co-authored-by: CHOMPStation2 <chompsation2@gmail.com>
This commit is contained in:
CHOMPStation2
2024-10-12 06:03:24 -07:00
committed by GitHub
parent 8b58d2c577
commit ffb65bbc3e
4 changed files with 1061 additions and 319 deletions

View File

@@ -123,330 +123,327 @@ log transactions
else
..()
/obj/machinery/atm/tgui_status(mob/user)
. = ..()
if(issilicon(user))
return STATUS_CLOSE
/obj/machinery/atm/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui, custom_state)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "AutomatedTellerMachine", name)
ui.open()
/obj/machinery/atm/tgui_static_data(mob/user)
var/list/data = ..()
data["machine_id"] = machine_id
return data
/obj/machinery/atm/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = ..()
data["emagged"] = emagged
if(emagged > 0)
return data
data["held_card"] = held_card
data["locked_down"] = ticks_left_locked_down
if(ticks_left_locked_down > 0)
return data
data["authenticated_account"] = null
data["suspended"] = FALSE
if(authenticated_account)
if(authenticated_account.suspended)
data["suspended"] = TRUE
return data
var/list/transactions = list()
for(var/datum/transaction/T as anything in authenticated_account.transaction_log)
UNTYPED_LIST_ADD(transactions, list(
"date" = T.date,
"time" = T.time,
"target_name" = T.target_name,
"purpose" = T.purpose,
"amount" = T.amount,
"source_terminal" = T.source_terminal
))
data["authenticated_account"] = list(
"owner_name" = authenticated_account.owner_name,
"money" = authenticated_account.money,
"security_level" = authenticated_account.security_level,
"transactions" = transactions,
)
return data
/obj/machinery/atm/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
. = ..()
if(.)
return
switch(action)
// This is also a logout
if("insert_card")
if(held_card)
release_held_id(usr)
else
if(emagged > 0)
to_chat(usr, span_red("[icon2html(src, usr.client)] The ATM card reader rejected your ID because this machine has been sabotaged!"))
else
var/obj/item/I = usr.get_active_hand()
if(istype(I, /obj/item/card/id))
usr.drop_item(src)
held_card = I
. = TRUE
if("logout")
if(held_card)
release_held_id(usr)
authenticated_account = null
. = TRUE
// Balance statement
if("balance_statement")
if(!authenticated_account)
return
var/obj/item/paper/R = new(loc)
R.name = "Account balance: [authenticated_account.owner_name]"
R.info = "<b>NT Automated Teller Account Statement</b><br><br>"
R.info += "<i>Account holder:</i> [authenticated_account.owner_name]<br>"
R.info += "<i>Account number:</i> [authenticated_account.account_number]<br>"
R.info += "<i>Balance:</i> $[authenticated_account.money]<br>"
R.info += "<i>Date and time:</i> [stationtime2text()], [current_date_string]<br><br>"
R.info += "<i>Service terminal ID:</i> [machine_id]<br>"
//stamp the paper
var/image/stampoverlay = image('icons/obj/bureaucracy.dmi')
stampoverlay.icon_state = "paper_stamp-cent"
if(!R.stamped)
R.stamped = new
R.stamped += /obj/item/stamp
R.add_overlay(stampoverlay)
R.stamps += "<HR><i>This paper has been stamped by the Automatic Teller Machine.</i>"
if(prob(50))
playsound(src, 'sound/items/polaroid1.ogg', 50, 1)
else
playsound(src, 'sound/items/polaroid2.ogg', 50, 1)
. = TRUE
// Transaction logs
if("print_transaction")
if(!authenticated_account)
return
var/obj/item/paper/R = new(loc)
R.name = "Transaction logs: [authenticated_account.owner_name]"
R.info = "<b>Transaction logs</b><br>"
R.info += "<i>Account holder:</i> [authenticated_account.owner_name]<br>"
R.info += "<i>Account number:</i> [authenticated_account.account_number]<br>"
R.info += "<i>Date and time:</i> [stationtime2text()], [current_date_string]<br><br>"
R.info += "<i>Service terminal ID:</i> [machine_id]<br>"
R.info += "<table border=1 style='width:100%'>"
R.info += "<tr>"
R.info += "<td><b>Date</b></td>"
R.info += "<td><b>Time</b></td>"
R.info += "<td><b>Target</b></td>"
R.info += "<td><b>Purpose</b></td>"
R.info += "<td><b>Value</b></td>"
R.info += "<td><b>Source terminal ID</b></td>"
R.info += "</tr>"
for(var/datum/transaction/T in authenticated_account.transaction_log)
R.info += "<tr>"
R.info += "<td>[T.date]</td>"
R.info += "<td>[T.time]</td>"
R.info += "<td>[T.target_name]</td>"
R.info += "<td>[T.purpose]</td>"
R.info += "<td>$[T.amount]</td>"
R.info += "<td>[T.source_terminal]</td>"
R.info += "</tr>"
R.info += "</table>"
//stamp the paper
var/image/stampoverlay = image('icons/obj/bureaucracy.dmi')
stampoverlay.icon_state = "paper_stamp-cent"
if(!R.stamped)
R.stamped = new
R.stamped += /obj/item/stamp
R.add_overlay(stampoverlay)
R.stamps += "<HR><i>This paper has been stamped by the Automatic Teller Machine.</i>"
if(prob(50))
playsound(src, 'sound/items/polaroid1.ogg', 50, 1)
else
playsound(src, 'sound/items/polaroid2.ogg', 50, 1)
. = TRUE
if("change_security_level")
if(authenticated_account)
var/new_sec_level = clamp(text2num(params["new_security_level"]), 0, 2)
authenticated_account.security_level = new_sec_level
. = TRUE
if("attempt_auth")
if(ticks_left_locked_down)
return
var/tried_account_num = held_card ? held_card.associated_account_number : text2num(params["account_num"])
var/tried_pin = text2num(params["account_pin"])
// check if they have low security enabled
if(!tried_account_num)
scan_user(usr)
else
authenticated_account = attempt_account_access(tried_account_num, tried_pin, held_card && held_card.associated_account_number == tried_account_num ? 2 : 1)
if(!authenticated_account)
number_incorrect_tries++
if(previous_account_number == tried_account_num)
if(number_incorrect_tries > max_pin_attempts)
//lock down the atm
ticks_left_locked_down = 30
playsound(src, 'sound/machines/buzz-two.ogg', 50, 1)
//create an entry in the account transaction log
var/datum/money_account/failed_account = get_account(tried_account_num)
if(failed_account)
var/datum/transaction/T = new()
T.target_name = failed_account.owner_name
T.purpose = "Unauthorised login attempt"
T.source_terminal = machine_id
T.date = current_date_string
T.time = stationtime2text()
failed_account.transaction_log.Add(T)
else
to_chat(usr, span_red("[icon2html(src, usr.client)] Incorrect pin/account combination entered, [max_pin_attempts - number_incorrect_tries] attempts remaining."))
previous_account_number = tried_account_num
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 1)
else
to_chat(usr, span_red("[icon2html(src, usr.client)] incorrect pin/account combination entered."))
number_incorrect_tries = 0
else
playsound(src, 'sound/machines/twobeep.ogg', 50, 1)
ticks_left_timeout = 120
view_screen = NO_SCREEN
//create a transaction log entry
var/datum/transaction/T = new()
T.target_name = authenticated_account.owner_name
T.purpose = "Remote terminal access"
T.source_terminal = machine_id
T.date = current_date_string
T.time = stationtime2text()
authenticated_account.transaction_log.Add(T)
to_chat(usr, span_blue("[icon2html(src, usr.client)] Access granted. Welcome user '[authenticated_account.owner_name].'"))
previous_account_number = tried_account_num
. = TRUE
if("transfer")
if(!authenticated_account)
return
var/transfer_amount = text2num(params["funds_amount"])
transfer_amount = round(transfer_amount, 0.01)
if(transfer_amount <= 0)
tgui_alert_async(usr, "That is not a valid amount.")
else if(transfer_amount <= authenticated_account.money)
var/target_account_number = text2num(params["target_acc_number"])
var/transfer_purpose = params["purpose"]
if(charge_to_account(target_account_number, authenticated_account.owner_name, transfer_purpose, machine_id, transfer_amount))
to_chat(usr, "[icon2html(src, usr.client)]<span class='info'>Funds transfer successful.</span>")
authenticated_account.money -= transfer_amount
//create an entry in the account transaction log
var/datum/transaction/T = new()
T.target_name = "Account #[target_account_number]"
T.purpose = transfer_purpose
T.source_terminal = machine_id
T.date = current_date_string
T.time = stationtime2text()
T.amount = "([transfer_amount])"
authenticated_account.transaction_log.Add(T)
else
to_chat(usr, "[icon2html(src, usr.client)]<span class='warning'>Funds transfer failed.</span>")
else
to_chat(usr, "[icon2html(src, usr.client)]<span class='warning'>You don't have enough funds to do that!</span>")
. = TRUE
if("e_withdrawal")
var/amount = max(text2num(params["funds_amount"]),0)
amount = round(amount, 0.01)
if(amount <= 0)
tgui_alert_async(usr, "That is not a valid amount.")
return
if(!authenticated_account)
return
if(amount <= authenticated_account.money)
playsound(src, 'sound/machines/chime.ogg', 50, 1)
//remove the money
authenticated_account.money -= amount
// spawn_money(amount,src.loc)
spawn_ewallet(amount,src.loc,usr)
//create an entry in the account transaction log
var/datum/transaction/T = new()
T.target_name = authenticated_account.owner_name
T.purpose = "Credit withdrawal"
T.amount = "([amount])"
T.source_terminal = machine_id
T.date = current_date_string
T.time = stationtime2text()
authenticated_account.transaction_log.Add(T)
else
to_chat(usr, "[icon2html(src, usr.client)]<span class='warning'>You don't have enough funds to do that!</span>")
. = TRUE
if("withdrawal")
var/amount = max(text2num(params["funds_amount"]),0)
amount = round(amount, 0.01)
if(amount <= 0)
tgui_alert_async(usr, "That is not a valid amount.")
return
if(!authenticated_account)
return
if(amount <= authenticated_account.money)
playsound(src, 'sound/machines/chime.ogg', 50, 1)
//remove the money
authenticated_account.money -= amount
spawn_money(amount,src.loc,usr)
//create an entry in the account transaction log
var/datum/transaction/T = new()
T.target_name = authenticated_account.owner_name
T.purpose = "Credit withdrawal"
T.amount = "([amount])"
T.source_terminal = machine_id
T.date = current_date_string
T.time = stationtime2text()
authenticated_account.transaction_log.Add(T)
else
to_chat(usr, "[icon2html(src, usr.client)]<span class='warning'>You don't have enough funds to do that!</span>")
. = TRUE
if(.)
playsound(src, "keyboard", 50, TRUE)
/obj/machinery/atm/attack_hand(mob/user as mob)
if(istype(user, /mob/living/silicon))
to_chat (user, span_warning("A firewall prevents you from interfacing with this device!"))
return
if(get_dist(src,user) <= 1)
//js replicated from obj/machinery/computer/card
var/dat = "<h1>Automatic Teller Machine</h1>"
dat += "For all your monetary needs!<br>"
dat += "<i>This terminal is</i> [machine_id]. <i>Report this code when contacting IT Support</i><br/>"
if(emagged > 0)
dat += "Card: <span style='color: red;'>LOCKED</span><br><br><span style='color: red;'>Unauthorized terminal access detected! This ATM has been locked. Please contact IT Support.</span>"
else
dat += "Card: <a href='?src=\ref[src];choice=insert_card'>[held_card ? held_card.name : "------"]</a><br><br>"
if(ticks_left_locked_down > 0)
dat += span_warning("Maximum number of pin attempts exceeded! Access to this ATM has been temporarily disabled.")
else if(authenticated_account)
if(authenticated_account.suspended)
dat += span_red(span_bold("Access to this account has been suspended, and the funds within frozen."))
else
switch(view_screen)
if(CHANGE_SECURITY_LEVEL)
dat += "Select a new security level for this account:<br><hr>"
var/text = "Zero - Either the account number or card is required to access this account. EFTPOS transactions will require a card and ask for a pin, but not verify the pin is correct."
if(authenticated_account.security_level != 0)
text = "<A href='?src=\ref[src];choice=change_security_level;new_security_level=0'>[text]</a>"
dat += "[text]<hr>"
text = "One - An account number and pin must be manually entered to access this account and process transactions."
if(authenticated_account.security_level != 1)
text = "<A href='?src=\ref[src];choice=change_security_level;new_security_level=1'>[text]</a>"
dat += "[text]<hr>"
text = "Two - In addition to account number and pin, a card is required to access this account and process transactions."
if(authenticated_account.security_level != 2)
text = "<A href='?src=\ref[src];choice=change_security_level;new_security_level=2'>[text]</a>"
dat += "[text]<hr><br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=0'>Back</a>"
if(VIEW_TRANSACTION_LOGS)
dat += "<b>Transaction logs</b><br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=0'>Back</a>"
dat += "<table border=1 style='width:100%'>"
dat += "<tr>"
dat += "<td><b>Date</b></td>"
dat += "<td><b>Time</b></td>"
dat += "<td><b>Target</b></td>"
dat += "<td><b>Purpose</b></td>"
dat += "<td><b>Value</b></td>"
dat += "<td><b>Source terminal ID</b></td>"
dat += "</tr>"
for(var/datum/transaction/T in authenticated_account.transaction_log)
dat += "<tr>"
dat += "<td>[T.date]</td>"
dat += "<td>[T.time]</td>"
dat += "<td>[T.target_name]</td>"
dat += "<td>[T.purpose]</td>"
dat += "<td>$[T.amount]</td>"
dat += "<td>[T.source_terminal]</td>"
dat += "</tr>"
dat += "</table>"
dat += "<A href='?src=\ref[src];choice=print_transaction'>Print</a><br>"
if(TRANSFER_FUNDS)
dat += "<b>Account balance:</b> $[authenticated_account.money]<br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=0'>Back</a><br><br>"
dat += "<form name='transfer' action='?src=\ref[src]' method='get'>"
dat += "<input type='hidden' name='src' value='\ref[src]'>"
dat += "<input type='hidden' name='choice' value='transfer'>"
dat += "Target account number: <input type='text' name='target_acc_number' value='' style='width:200px; background-color:white;'><br>"
dat += "Funds to transfer: <input type='text' name='funds_amount' value='' style='width:200px; background-color:white;'><br>"
dat += "Transaction purpose: <input type='text' name='purpose' value='Funds transfer' style='width:200px; background-color:white;'><br>"
dat += "<input type='submit' value='Transfer funds'><br>"
dat += "</form>"
else
dat += "Welcome, <b>[authenticated_account.owner_name].</b><br/>"
dat += "<b>Account balance:</b> $[authenticated_account.money]"
dat += "<form name='withdrawal' action='?src=\ref[src]' method='get'>"
dat += "<input type='hidden' name='src' value='\ref[src]'>"
dat += "<input type='radio' name='choice' value='withdrawal' checked> Cash <input type='radio' name='choice' value='e_withdrawal'> Chargecard<br>"
dat += "<input type='text' name='funds_amount' value='' style='width:200px; background-color:white;'><input type='submit' value='Withdraw'>"
dat += "</form>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=1'>Change account security level</a><br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=2'>Make transfer</a><br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=3'>View transaction log</a><br>"
dat += "<A href='?src=\ref[src];choice=balance_statement'>Print balance statement</a><br>"
dat += "<A href='?src=\ref[src];choice=logout'>Logout</a><br>"
else
dat += "<form name='atm_auth' action='?src=\ref[src]' method='get'>"
dat += "<input type='hidden' name='src' value='\ref[src]'>"
dat += "<input type='hidden' name='choice' value='attempt_auth'>"
dat += "<b>Account:</b> <input type='text' id='account_num' name='account_num' style='width:250px; background-color:white;'><br>"
dat += "<b>PIN:</b> <input type='text' id='account_pin' name='account_pin' style='width:250px; background-color:white;'><br>"
dat += "<input type='submit' value='Submit'><br>"
dat += "</form>"
user << browse(dat,"window=atm;size=550x650")
else
user << browse(null,"window=atm")
/obj/machinery/atm/Topic(var/href, var/href_list)
if(href_list["choice"])
switch(href_list["choice"])
if("transfer")
if(authenticated_account)
var/transfer_amount = text2num(href_list["funds_amount"])
transfer_amount = round(transfer_amount, 0.01)
if(transfer_amount <= 0)
tgui_alert_async(usr, "That is not a valid amount.")
else if(transfer_amount <= authenticated_account.money)
var/target_account_number = text2num(href_list["target_acc_number"])
var/transfer_purpose = href_list["purpose"]
if(charge_to_account(target_account_number, authenticated_account.owner_name, transfer_purpose, machine_id, transfer_amount))
to_chat(usr, "[icon2html(src, usr.client)]<span class='info'>Funds transfer successful.</span>")
authenticated_account.money -= transfer_amount
//create an entry in the account transaction log
var/datum/transaction/T = new()
T.target_name = "Account #[target_account_number]"
T.purpose = transfer_purpose
T.source_terminal = machine_id
T.date = current_date_string
T.time = stationtime2text()
T.amount = "([transfer_amount])"
authenticated_account.transaction_log.Add(T)
else
to_chat(usr, "[icon2html(src, usr.client)]<span class='warning'>Funds transfer failed.</span>")
else
to_chat(usr, "[icon2html(src, usr.client)]<span class='warning'>You don't have enough funds to do that!</span>")
if("view_screen")
view_screen = text2num(href_list["view_screen"])
if("change_security_level")
if(authenticated_account)
var/new_sec_level = max( min(text2num(href_list["new_security_level"]), 2), 0)
authenticated_account.security_level = new_sec_level
if("attempt_auth")
if(!ticks_left_locked_down)
var/tried_account_num = held_card ? held_card.associated_account_number : text2num(href_list["account_num"])
var/tried_pin = text2num(href_list["account_pin"])
// check if they have low security enabled
if (!tried_account_num)
scan_user(usr)
else
authenticated_account = attempt_account_access(tried_account_num, tried_pin, held_card && held_card.associated_account_number == tried_account_num ? 2 : 1)
if(!authenticated_account)
number_incorrect_tries++
if(previous_account_number == tried_account_num)
if(number_incorrect_tries > max_pin_attempts)
//lock down the atm
ticks_left_locked_down = 30
playsound(src, 'sound/machines/buzz-two.ogg', 50, 1)
//create an entry in the account transaction log
var/datum/money_account/failed_account = get_account(tried_account_num)
if(failed_account)
var/datum/transaction/T = new()
T.target_name = failed_account.owner_name
T.purpose = "Unauthorised login attempt"
T.source_terminal = machine_id
T.date = current_date_string
T.time = stationtime2text()
failed_account.transaction_log.Add(T)
else
to_chat(usr, span_red("[icon2html(src, usr.client)] Incorrect pin/account combination entered, [max_pin_attempts - number_incorrect_tries] attempts remaining."))
previous_account_number = tried_account_num
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 1)
else
to_chat(usr, span_red("[icon2html(src, usr.client)] incorrect pin/account combination entered."))
number_incorrect_tries = 0
else
playsound(src, 'sound/machines/twobeep.ogg', 50, 1)
ticks_left_timeout = 120
view_screen = NO_SCREEN
//create a transaction log entry
var/datum/transaction/T = new()
T.target_name = authenticated_account.owner_name
T.purpose = "Remote terminal access"
T.source_terminal = machine_id
T.date = current_date_string
T.time = stationtime2text()
authenticated_account.transaction_log.Add(T)
to_chat(usr, span_blue("[icon2html(src, usr.client)] Access granted. Welcome user '[authenticated_account.owner_name].'"))
previous_account_number = tried_account_num
if("e_withdrawal")
var/amount = max(text2num(href_list["funds_amount"]),0)
amount = round(amount, 0.01)
if(amount <= 0)
tgui_alert_async(usr, "That is not a valid amount.")
else if(authenticated_account && amount > 0)
if(amount <= authenticated_account.money)
playsound(src, 'sound/machines/chime.ogg', 50, 1)
//remove the money
authenticated_account.money -= amount
// spawn_money(amount,src.loc)
spawn_ewallet(amount,src.loc,usr)
//create an entry in the account transaction log
var/datum/transaction/T = new()
T.target_name = authenticated_account.owner_name
T.purpose = "Credit withdrawal"
T.amount = "([amount])"
T.source_terminal = machine_id
T.date = current_date_string
T.time = stationtime2text()
authenticated_account.transaction_log.Add(T)
else
to_chat(usr, "[icon2html(src, usr.client)]<span class='warning'>You don't have enough funds to do that!</span>")
if("withdrawal")
var/amount = max(text2num(href_list["funds_amount"]),0)
amount = round(amount, 0.01)
if(amount <= 0)
tgui_alert_async(usr, "That is not a valid amount.")
else if(authenticated_account && amount > 0)
if(amount <= authenticated_account.money)
playsound(src, 'sound/machines/chime.ogg', 50, 1)
//remove the money
authenticated_account.money -= amount
spawn_money(amount,src.loc,usr)
//create an entry in the account transaction log
var/datum/transaction/T = new()
T.target_name = authenticated_account.owner_name
T.purpose = "Credit withdrawal"
T.amount = "([amount])"
T.source_terminal = machine_id
T.date = current_date_string
T.time = stationtime2text()
authenticated_account.transaction_log.Add(T)
else
to_chat(usr, "[icon2html(src, usr.client)]<span class='warning'>You don't have enough funds to do that!</span>")
if("balance_statement")
if(authenticated_account)
var/obj/item/paper/R = new(src.loc)
R.name = "Account balance: [authenticated_account.owner_name]"
R.info = "<b>NT Automated Teller Account Statement</b><br><br>"
R.info += "<i>Account holder:</i> [authenticated_account.owner_name]<br>"
R.info += "<i>Account number:</i> [authenticated_account.account_number]<br>"
R.info += "<i>Balance:</i> $[authenticated_account.money]<br>"
R.info += "<i>Date and time:</i> [stationtime2text()], [current_date_string]<br><br>"
R.info += "<i>Service terminal ID:</i> [machine_id]<br>"
//stamp the paper
var/image/stampoverlay = image('icons/obj/bureaucracy.dmi')
stampoverlay.icon_state = "paper_stamp-cent"
if(!R.stamped)
R.stamped = new
R.stamped += /obj/item/stamp
R.add_overlay(stampoverlay)
R.stamps += "<HR><i>This paper has been stamped by the Automatic Teller Machine.</i>"
if(prob(50))
playsound(src, 'sound/items/polaroid1.ogg', 50, 1)
else
playsound(src, 'sound/items/polaroid2.ogg', 50, 1)
if ("print_transaction")
if(authenticated_account)
var/obj/item/paper/R = new(src.loc)
R.name = "Transaction logs: [authenticated_account.owner_name]"
R.info = "<b>Transaction logs</b><br>"
R.info += "<i>Account holder:</i> [authenticated_account.owner_name]<br>"
R.info += "<i>Account number:</i> [authenticated_account.account_number]<br>"
R.info += "<i>Date and time:</i> [stationtime2text()], [current_date_string]<br><br>"
R.info += "<i>Service terminal ID:</i> [machine_id]<br>"
R.info += "<table border=1 style='width:100%'>"
R.info += "<tr>"
R.info += "<td><b>Date</b></td>"
R.info += "<td><b>Time</b></td>"
R.info += "<td><b>Target</b></td>"
R.info += "<td><b>Purpose</b></td>"
R.info += "<td><b>Value</b></td>"
R.info += "<td><b>Source terminal ID</b></td>"
R.info += "</tr>"
for(var/datum/transaction/T in authenticated_account.transaction_log)
R.info += "<tr>"
R.info += "<td>[T.date]</td>"
R.info += "<td>[T.time]</td>"
R.info += "<td>[T.target_name]</td>"
R.info += "<td>[T.purpose]</td>"
R.info += "<td>$[T.amount]</td>"
R.info += "<td>[T.source_terminal]</td>"
R.info += "</tr>"
R.info += "</table>"
//stamp the paper
var/image/stampoverlay = image('icons/obj/bureaucracy.dmi')
stampoverlay.icon_state = "paper_stamp-cent"
if(!R.stamped)
R.stamped = new
R.stamped += /obj/item/stamp
R.add_overlay(stampoverlay)
R.stamps += "<HR><i>This paper has been stamped by the Automatic Teller Machine.</i>"
if(prob(50))
playsound(src, 'sound/items/polaroid1.ogg', 50, 1)
else
playsound(src, 'sound/items/polaroid2.ogg', 50, 1)
if("insert_card")
if(!held_card)
//this might happen if the user had the browser window open when somebody emagged it
if(emagged > 0)
to_chat(usr, span_red("[icon2html(src, usr.client)] The ATM card reader rejected your ID because this machine has been sabotaged!"))
else
var/obj/item/I = usr.get_active_hand()
if (istype(I, /obj/item/card/id))
usr.drop_item()
I.loc = src
held_card = I
else
release_held_id(usr)
if("logout")
authenticated_account = null
//usr << browse(null,"window=atm")
src.attack_hand(usr)
tgui_interact(user)
//stolen wholesale and then edited a bit from newscasters, which are awesome and by Agouri
/obj/machinery/atm/proc/scan_user(mob/living/carbon/human/human_user as mob)