diff --git a/code/modules/economy/cash.dm b/code/modules/economy/cash.dm index 8f694611d2..c3d2e21b53 100644 --- a/code/modules/economy/cash.dm +++ b/code/modules/economy/cash.dm @@ -20,15 +20,7 @@ if(istype(W, /obj/item/weapon/spacecash)) if(istype(W, /obj/item/weapon/spacecash/ewallet)) return 0 - var/obj/item/weapon/spacecash/bundle/bundle - if(!istype(W, /obj/item/weapon/spacecash/bundle)) - var/obj/item/weapon/spacecash/cash = W - user.drop_from_inventory(cash) - bundle = new (src.loc) - bundle.worth += cash.worth - qdel(cash) - else //is bundle - bundle = W + var/obj/item/weapon/spacecash/bundle = W bundle.worth += src.worth bundle.update_icon() if(istype(user, /mob/living/carbon/human)) @@ -36,7 +28,7 @@ h_user.drop_from_inventory(src) h_user.drop_from_inventory(bundle) h_user.put_in_hands(bundle) - user << "You add [src.worth] Thalers worth of money to the bundles.
It holds [bundle.worth] Thalers now.
" + user << "You combine the Thalers to a bundle of [bundle.worth] Thalers." qdel(src) /obj/item/weapon/spacecash/bundle @@ -45,8 +37,13 @@ desc = "They are worth 0 Thalers." worth = 0 -/obj/item/weapon/spacecash/bundle/update_icon() +/obj/item/weapon/spacecash/update_icon() overlays.Cut() + name = "[worth] Thaler\s" + if(worth in list(1000,500,200,100,50,20,10,1)) + icon_state = "spacecash[worth]" + desc = "It's worth [worth] Thalers." + return var/sum = src.worth var/num = 0 for(var/i in list(1000,500,200,100,50,20,10,1)) @@ -68,7 +65,7 @@ src.overlays += banknote src.desc = "They are worth [worth] Thalers." -/obj/item/weapon/spacecash/bundle/attack_self() +/obj/item/weapon/spacecash/attack_self() var/amount = input(usr, "How many Thalers do you want to take? (0 to [src.worth])", "Take Money", 20) as num amount = round(Clamp(amount, 0, src.worth)) if(amount==0) return 0 @@ -78,7 +75,7 @@ if(!worth) usr.drop_from_inventory(src) if(amount in list(1000,500,200,100,50,20,1)) - var/cashtype = text2path("/obj/item/weapon/spacecash/bundle/c[amount]") + var/cashtype = text2path("/obj/item/weapon/spacecash/c[amount]") var/obj/cash = new cashtype (usr.loc) usr.put_in_hands(cash) else @@ -89,66 +86,60 @@ if(!worth) qdel(src) -/obj/item/weapon/spacecash/bundle/c1 +/obj/item/weapon/spacecash/c1 name = "1 Thaler" icon_state = "spacecash1" desc = "It's worth 1 credit." worth = 1 -/obj/item/weapon/spacecash/bundle/c10 +/obj/item/weapon/spacecash/c10 name = "10 Thaler" icon_state = "spacecash10" desc = "It's worth 10 Thalers." worth = 10 -/obj/item/weapon/spacecash/bundle/c20 +/obj/item/weapon/spacecash/c20 name = "20 Thaler" icon_state = "spacecash20" desc = "It's worth 20 Thalers." worth = 20 -/obj/item/weapon/spacecash/bundle/c50 +/obj/item/weapon/spacecash/c50 name = "50 Thaler" icon_state = "spacecash50" desc = "It's worth 50 Thalers." worth = 50 -/obj/item/weapon/spacecash/bundle/c100 +/obj/item/weapon/spacecash/c100 name = "100 Thaler" icon_state = "spacecash100" desc = "It's worth 100 Thalers." worth = 100 -/obj/item/weapon/spacecash/bundle/c200 +/obj/item/weapon/spacecash/c200 name = "200 Thaler" icon_state = "spacecash200" desc = "It's worth 200 Thalers." worth = 200 -/obj/item/weapon/spacecash/bundle/c500 +/obj/item/weapon/spacecash/c500 name = "500 Thaler" icon_state = "spacecash500" desc = "It's worth 500 Thalers." worth = 500 -/obj/item/weapon/spacecash/bundle/c1000 +/obj/item/weapon/spacecash/c1000 name = "1000 Thaler" icon_state = "spacecash1000" desc = "It's worth 1000 Thalers." worth = 1000 proc/spawn_money(var/sum, spawnloc, mob/living/carbon/human/human_user as mob) - if(sum in list(1000,500,200,100,50,20,10,1)) - var/cash_type = text2path("/obj/item/weapon/spacecash/bundle/c[sum]") - var/obj/cash = new cash_type (usr.loc) - if(ishuman(human_user) && !human_user.get_active_hand()) - human_user.put_in_hands(cash) - else - var/obj/item/weapon/spacecash/bundle/bundle = new (spawnloc) - bundle.worth = sum - bundle.update_icon() - if (ishuman(human_user) && !human_user.get_active_hand()) - human_user.put_in_hands(bundle) + var/obj/item/weapon/spacecash/bundle/bundle = new (spawnloc) + bundle.worth = sum + bundle.update_icon() + if (ishuman(human_user) && !human_user.get_active_hand()) + human_user.put_in_hands(bundle) return /obj/item/weapon/spacecash/ewallet @@ -156,6 +147,9 @@ proc/spawn_money(var/sum, spawnloc, mob/living/carbon/human/human_user as mob) icon_state = "efundcard" desc = "A card that holds an amount of money." var/owner_name = "" //So the ATM can set it so the EFTPOS can put a valid name on transactions. + attack_self() return //Don't act + attackby() return //like actual + update_icon() return //space cash /obj/item/weapon/spacecash/ewallet/examine(mob/user) ..(user) diff --git a/code/modules/economy/cash_register.dm b/code/modules/economy/cash_register.dm new file mode 100644 index 0000000000..a191e3e615 --- /dev/null +++ b/code/modules/economy/cash_register.dm @@ -0,0 +1,452 @@ +/obj/machinery/cash_register + name = "retail scanner" + desc = "Swipe your ID card to make purchases electronically." + icon = 'icons/obj/stationobjs.dmi' + icon_state = "register_idle" + flags = NOBLUDGEON + req_access = list(access_heads) + anchored = 1 + + var/locked = 1 + var/cash_locked = 1 + var/cash_open = 0 + var/machine_id = "" + var/transaction_amount = 0 // cumulatd amount of money to pay in a single purchase + var/transaction_purpose = null // text that gets used in ATM transaction logs + var/list/transaction_logs = list() // list of strings using html code to visualise data + var/list/item_list = list() // entities and according + var/list/price_list = list() // prices for each purchase + var/manipulating = 0 + + var/cash_stored = 0 + var/obj/item/confirm_item + var/datum/money_account/linked_account + + +// Claim machine ID +/obj/machinery/cash_register/New() + machine_id = "[station_name()] RETAIL #[num_financial_terminals++]" + cash_stored = rand(10, 70)*10 + + +/obj/machinery/cash_register/examine(mob/user as mob) + ..(user) + if(cash_open) + if(cash_stored) + user << "It holds [cash_stored] Thaler\s of money." + else + user << "It's completely empty." + + +/obj/machinery/cash_register/attack_hand(mob/user as mob) + if(cash_open) + if(cash_stored) + spawn_money(cash_stored, loc, user) + cash_stored = 0 + overlays -= "register_cash" + else + open_cash_box() + // Reset if necessary + else if(transaction_amount) + reset_memory() + user << "You reset the memory." + else + custom_interface(user) + + +/obj/machinery/cash_register/AltClick(mob/user) + if(Adjacent(user)) + open_cash_box() + + +/obj/machinery/cash_register/proc/custom_interface(mob/user as mob) + var/dat = "

Retail Scanner

" + if (locked) + dat += "Unlock
" + dat += "Linked account: [linked_account ? linked_account.owner_name : "None"]
" + dat += "[cash_locked? "Unlock" : "Lock"] Cash Box | " + else + dat += "Lock
" + dat += "Linked account: [linked_account ? linked_account.owner_name : "None"]
" + dat += "[cash_locked? "Unlock" : "Lock"] Cash Box | " + dat += "Custom Order
" + for(var/i=1, i<=transaction_logs.len, i++) + dat += "[transaction_logs[i]]
" + + if(transaction_logs.len) + dat += locked ? "
" : "Reset Log
" + dat += "
" + dat += "Device ID: [machine_id]" + user << browse(dat, "window=retail;size=350x500") + + +/obj/machinery/cash_register/Topic(var/href, var/href_list) + if(href_list["choice"]) + switch(href_list["choice"]) + if("toggle_lock") + if(allowed(usr)) + locked = !locked + else + usr << "\icon[src]Insufficient access." + if("toggle_cash_lock") + cash_locked = !cash_locked + if("link_account") + var/attempt_account_num = input("Enter account number", "New account number") as num + var/attempt_pin = input("Enter PIN", "Account PIN") as num + linked_account = attempt_account_access(attempt_account_num, attempt_pin, 1) + if(linked_account) + if(linked_account.suspended) + linked_account = null + src.visible_message("\icon[src]Account has been suspended.") + else + usr << "\icon[src]Account not found." + if("custom_order") + var/t_purpose = sanitize(input("Enter purpose", "New purpose") as text) + if (!t_purpose || !Adjacent(usr)) return + transaction_purpose = t_purpose + item_list += t_purpose + var/t_amount = input("Enter price", "New price") as num + if (!t_amount || !Adjacent(usr)) return + transaction_amount += t_amount + price_list += t_amount + playsound(src, 'sound/machines/twobeep.ogg', 25) + src.visible_message("\icon[src][transaction_purpose]: [transaction_amount] Thaler\s.") + if("reset_log") + transaction_logs.Cut() + usr << "\icon[src]Transaction log reset." + custom_interface(usr) + + + +/obj/machinery/cash_register/attackby(obj/O as obj, user as mob) + // Check for a method of paying (ID, PDA, e-wallet, cash, ect.) + var/obj/item/weapon/card/id/I = O.GetID() + if(I) + scan_card(I, O) + else if (istype(O, /obj/item/weapon/spacecash/ewallet)) + var/obj/item/weapon/spacecash/ewallet/E = O + scan_wallet(E) + else if (istype(O, /obj/item/weapon/spacecash)) + var/obj/item/weapon/spacecash/SC = O + if(cash_open) + user << "You neatly sort the cash into the box." + cash_stored += SC.worth + overlays |= "register_cash" + if(ishuman(user)) + var/mob/living/carbon/human/H = user + H.drop_from_inventory(SC) + qdel(SC) + else + scan_cash(SC) + else if(istype(O, /obj/item/weapon/card/emag)) + return ..() + else if(istype(O, /obj/item/weapon/wrench)) + var/obj/item/weapon/wrench/W = O + toggle_anchors(W, user) + // Not paying: Look up price and add it to transaction_amount + else + scan_item_price(O) + + +/obj/machinery/cash_register/MouseDrop_T(atom/dropping, mob/user) + if(Adjacent(dropping) && Adjacent(user) && !user.stat) + attackby(dropping, user) + + +/obj/machinery/cash_register/proc/confirm(obj/item/I) + if(confirm_item == I) + return 1 + else + confirm_item = I + src.visible_message("\icon[src]Total price: [transaction_amount] Thaler\s. Swipe again to confirm.") + playsound(src, 'sound/machines/twobeep.ogg', 25) + return 0 + + +/obj/machinery/cash_register/proc/scan_card(obj/item/weapon/card/id/I, obj/item/ID_container) + if (!transaction_amount) + return + + if(!confirm(I)) + return + + if (!linked_account) + usr.visible_message("\icon[src]Unable to connect to linked account.") + return + + // Access account for transaction + if(check_account()) + var/datum/money_account/D = get_account(I.associated_account_number) + var/attempt_pin = "" + if(D && D.security_level) + attempt_pin = input("Enter PIN", "Transaction") as num + D = null + D = attempt_account_access(I.associated_account_number, attempt_pin, 2) + + if(!D) + src.visible_message("\icon[src]Unable to access account. Check security settings and try again.") + else + if(D.suspended) + src.visible_message("\icon[src]Your account has been suspended.") + else + if(transaction_amount > D.money) + src.visible_message("\icon[src]Not enough funds.") + else + // Transfer the money + D.money -= transaction_amount + linked_account.money += transaction_amount + + // Create log entry in client's account + var/datum/transaction/T = new() + T.target_name = "[linked_account.owner_name]" + T.purpose = transaction_purpose + T.amount = "([transaction_amount])" + T.source_terminal = machine_id + T.date = current_date_string + T.time = worldtime2text() + D.transaction_log.Add(T) + + // Create log entry in owner's account + T = new() + T.target_name = D.owner_name + T.purpose = transaction_purpose + T.amount = "[transaction_amount]" + T.source_terminal = machine_id + T.date = current_date_string + T.time = worldtime2text() + linked_account.transaction_log.Add(T) + + // Save log + add_transaction_log(I.registered_name ? I.registered_name : "n/A", "ID Card", transaction_amount) + + // Confirm and reset + transaction_complete() + + +/obj/machinery/cash_register/proc/scan_wallet(obj/item/weapon/spacecash/ewallet/E) + if (!transaction_amount) + return + + if(!confirm(E)) + return + + // Access account for transaction + if(check_account()) + if(transaction_amount > E.worth) + src.visible_message("\icon[src]Not enough funds.") + else + // Transfer the money + E.worth -= transaction_amount + linked_account.money += transaction_amount + + // Create log entry in owner's account + var/datum/transaction/T = new() + T.target_name = E.owner_name + T.purpose = transaction_purpose + T.amount = "[transaction_amount]" + T.source_terminal = machine_id + T.date = current_date_string + T.time = worldtime2text() + linked_account.transaction_log.Add(T) + + // Save log + add_transaction_log(E.owner_name, "E-Wallet", transaction_amount) + + // Confirm and reset + transaction_complete() + + +/obj/machinery/cash_register/proc/scan_cash(obj/item/weapon/spacecash/SC) + if (!transaction_amount) + return + + if(!confirm(SC)) + return + + // Access account for transaction + if(check_account()) + if(transaction_amount > SC.worth) + src.visible_message("\icon[src]Not enough money.") + else + // Insert cash into magical slot + SC.worth -= transaction_amount + SC.update_icon() + if(!SC.worth) + if(ishuman(SC.loc)) + var/mob/living/carbon/human/H = SC.loc + H.drop_from_inventory(SC) + qdel(SC) + cash_stored += transaction_amount + + // Save log + add_transaction_log("n/A", "Cash", transaction_amount) + + // Confirm and reset + transaction_complete() + + +/obj/machinery/cash_register/proc/scan_item_price(obj/O) + if(!istype(O)) return + // First check if item has a valid price + var/price = O.get_item_cost() + if(isnull(price)) + src.visible_message("\icon[src]Unable to find item in database.") + return + // Call out item cost + src.visible_message("\icon[src]\A [O]: [price ? "[price] Thaler\s" : "free of charge"].") + // Note the transaction purpose for later use + if(transaction_purpose) + transaction_purpose += "
" + transaction_purpose += "[O]: [price] Thaler\s" + transaction_amount += price + item_list += "[O]" + price_list += "[price] þ" + // Animation and sound + playsound(src, 'sound/machines/twobeep.ogg', 25) + // Reset confirmation + confirm_item = null + + +/obj/machinery/cash_register/proc/add_transaction_log(var/c_name, var/p_method, var/t_amount) + var/dat = {" + + + + + + + +
Transaction #[transaction_logs.len+1]
Customer[c_name]
Pay Method[p_method]
Station Time[worldtime2text()]
+ + "} + for(var/i=1, i<=item_list.len, i++) + dat += "" + dat += "" + dat += "
[item_list[i]][price_list[i]]
Total Amount: [transaction_amount] þ
" + + transaction_logs += dat + + +/obj/machinery/cash_register/proc/check_account() + if (!linked_account) + usr.visible_message("\icon[src]Unable to connect to linked account.") + return 0 + + if(linked_account.suspended) + src.visible_message("\icon[src]Connected account has been suspended.") + return 0 + return 1 + + +/obj/machinery/cash_register/proc/transaction_complete() + /// Visible confirmation + playsound(src, 'sound/machines/chime.ogg', 25) + src.visible_message("\icon[src]Transaction complete.") + flick("register_approve", src) + reset_memory() + +/obj/machinery/cash_register/proc/reset_memory() + transaction_amount = null + transaction_purpose = "" + item_list.Cut() + price_list.Cut() + confirm_item = null + + +/obj/machinery/cash_register/verb/open_cash_box() + set category = "Object" + set name = "Open Cash Box" + set desc = "Open/closes the register's cash box." + set src in view(1) + + if(usr.stat) return + + if(cash_locked) + usr << "The cash box is locked." + else if(cash_open) + cash_open = 0 + overlays -= "register_open" + overlays -= "register_cash" + else + cash_open = 1 + overlays += "register_open" + if(cash_stored) + overlays += "register_cash" + + +/obj/machinery/cash_register/proc/toggle_anchors(obj/item/weapon/wrench/W, mob/user) + if(manipulating) return + manipulating = 1 + if(!anchored) + user.visible_message("\The [user] begins securing \the [src] to the floor.", + "You begin securing \the [src] to the floor.") + else + user.visible_message("\The [user] begins unsecuring \the [src] from the floor.", + "You begin unsecuring \the [src] from the floor.") + playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) + if(!do_after(user, 20)) + manipulating = 0 + return + if(!anchored) + user.visible_message("\The [user] has secured \the [src] to the floor.", + "You have secured \the [src] to the floor.") + else + user.visible_message("\The [user] has unsecured \the [src] from the floor.", + "You have unsecured \the [src] from the floor.") + anchored = !anchored + manipulating = 0 + return + + + +/obj/machinery/cash_register/emag_act(var/remaining_charges, var/mob/user) + if(!emagged) + src.visible_message("The [src]'s cash box springs open as [user] swipes the card through the scanner!") + playsound(src, "sparks", 50, 1) + req_access = list() + emagged = 1 + locked = 0 + cash_locked = 0 + open_cash_box() + +//--Premades--// + +/obj/machinery/cash_register/command + New() + linked_account = department_accounts["Command"] + ..() + /obj/machinery/cash_register/medical + + New() + linked_account = department_accounts["Medical"] + ..() + +/obj/machinery/cash_register/engineering + New() + linked_account = department_accounts["Engineering"] + ..() + +/obj/machinery/cash_register/science + New() + linked_account = department_accounts["Science"] + ..() + +/obj/machinery/cash_register/security + New() + linked_account = department_accounts["Security"] + ..() + +/obj/machinery/cash_register/cargo + New() + linked_account = department_accounts["Cargo"] + ..() + +/obj/machinery/cash_register/civilian + New() + linked_account = department_accounts["Civilian"] + ..() \ No newline at end of file diff --git a/code/modules/economy/price_list.dm b/code/modules/economy/price_list.dm new file mode 100644 index 0000000000..babe5cce34 --- /dev/null +++ b/code/modules/economy/price_list.dm @@ -0,0 +1,4 @@ +/atom/movable/var/price_tag = null //cost + +/atom/movable/proc/get_item_cost() + return price_tag \ No newline at end of file diff --git a/code/modules/economy/retail_scanner.dm b/code/modules/economy/retail_scanner.dm new file mode 100644 index 0000000000..f76cc1494d --- /dev/null +++ b/code/modules/economy/retail_scanner.dm @@ -0,0 +1,348 @@ +/obj/item/device/retail_scanner + name = "retail scanner" + desc = "Swipe your ID card to make purchases electronically." + icon = 'icons/obj/device.dmi' + icon_state = "retail_idle" + flags = NOBLUDGEON + req_access = list(access_heads) + + var/locked = 1 + var/emagged = 0 + var/machine_id = "" + var/transaction_amount = 0 // cumulatd amount of money to pay in a single purchase + var/transaction_purpose = null // text that gets used in ATM transaction logs + var/list/transaction_logs = list() // list of strings using html code to visualise data + var/list/item_list = list() // entities and according + var/list/price_list = list() // prices for each purchase + + var/obj/item/confirm_item + var/datum/money_account/linked_account + + +// Claim machine ID +/obj/item/device/retail_scanner/New() + machine_id = "[station_name()] RETAIL #[num_financial_terminals++]" + + +// Always face the user when put on a table +/obj/item/device/retail_scanner/afterattack(atom/movable/AM, mob/user, proximity) + if(!proximity) return + if(istype(AM, /obj/structure/table)) + src.pixel_y = 3 // Shift it up slightly to look better on table + src.dir = get_dir(src, user) + else + scan_item_price(AM) + +// Reset dir when picked back up +/obj/item/device/retail_scanner/pickup(mob/user) + src.dir = SOUTH + src.pixel_y = 0 + + +/obj/item/device/retail_scanner/attack_self(mob/user as mob) + // Reset if necessary + if(transaction_amount) + reset_memory() + user << "You reset the device." + else + custom_interface(user) + + +/obj/item/device/retail_scanner/AltClick(var/mob/user) + if(Adjacent(user)) + custom_interface(user) + + +/obj/item/device/retail_scanner/proc/custom_interface(mob/user as mob) + var/dat = "

Retail Scanner

" + if (locked) + dat += "Unlock
" + dat += "Linked account: [linked_account ? linked_account.owner_name : "None"]
" + else + dat += "Lock
" + dat += "Linked account: [linked_account ? linked_account.owner_name : "None"]
" + dat += "Custom Order
" + for(var/i=1, i<=transaction_logs.len, i++) + dat += "[transaction_logs[i]]
" + + if(transaction_logs.len) + dat += locked ? "
" : "Reset Log
" + dat += "
" + dat += "Device ID: [machine_id]" + user << browse(dat, "window=retail;size=350x500") + + +/obj/item/device/retail_scanner/Topic(var/href, var/href_list) + if(href_list["choice"]) + switch(href_list["choice"]) + if("toggle_lock") + if(allowed(usr)) + locked = !locked + else + usr << "\icon[src]Insufficient access." + if("link_account") + var/attempt_account_num = input("Enter account number", "New account number") as num + var/attempt_pin = input("Enter PIN", "Account PIN") as num + linked_account = attempt_account_access(attempt_account_num, attempt_pin, 1) + if(linked_account) + if(linked_account.suspended) + linked_account = null + src.visible_message("\icon[src]Account has been suspended.") + else + usr << "\icon[src]Account not found." + if("custom_order") + var/t_purpose = sanitize(input("Enter purpose", "New purpose") as text) + if (!t_purpose || !Adjacent(usr)) return + transaction_purpose = t_purpose + item_list += t_purpose + var/t_amount = input("Enter price", "New price") as num + if (!t_amount || !Adjacent(usr)) return + transaction_amount += t_amount + price_list += t_amount + playsound(src, 'sound/machines/twobeep.ogg', 25) + src.visible_message("\icon[src][transaction_purpose]: [transaction_amount] Thaler\s.") + if("reset_log") + transaction_logs.Cut() + usr << "\icon[src]Transaction log reset." + custom_interface(usr) + + + +/obj/item/device/retail_scanner/attackby(obj/O as obj, user as mob) + // Check for a method of paying (ID, PDA, e-wallet, cash, ect.) + var/obj/item/weapon/card/id/I = O.GetID() + if(I) + scan_card(I, O) + else if (istype(O, /obj/item/weapon/spacecash/ewallet)) + var/obj/item/weapon/spacecash/ewallet/E = O + scan_wallet(E) + else if (istype(O, /obj/item/weapon/spacecash)) + usr << "This device does not accept cash." + + else if(istype(O, /obj/item/weapon/card/emag)) + return ..() + // Not paying: Look up price and add it to transaction_amount + else + scan_item_price(O) + + +/obj/item/device/retail_scanner/proc/confirm(var/obj/item/I) + if(confirm_item == I) + return 1 + else + confirm_item = I + src.visible_message("\icon[src]Total price: [transaction_amount] Thaler\s. Swipe again to confirm.") + playsound(src, 'sound/machines/twobeep.ogg', 25) + return 0 + + +/obj/item/device/retail_scanner/proc/scan_card(var/obj/item/weapon/card/id/I, var/obj/item/ID_container) + if (!transaction_amount) + return + + if(!confirm(I)) + return + + if (!linked_account) + usr.visible_message("\icon[src]Unable to connect to linked account.") + return + + // Access account for transaction + if(check_account()) + var/datum/money_account/D = get_account(I.associated_account_number) + var/attempt_pin = "" + if(D && D.security_level) + attempt_pin = input("Enter PIN", "Transaction") as num + D = null + D = attempt_account_access(I.associated_account_number, attempt_pin, 2) + + if(!D) + src.visible_message("\icon[src]Unable to access account. Check security settings and try again.") + else + if(D.suspended) + src.visible_message("\icon[src]Your account has been suspended.") + else + if(transaction_amount > D.money) + src.visible_message("\icon[src]Not enough funds.") + else + // Transfer the money + D.money -= transaction_amount + linked_account.money += transaction_amount + + // Create log entry in client's account + var/datum/transaction/T = new() + T.target_name = "[linked_account.owner_name]" + T.purpose = transaction_purpose + T.amount = "([transaction_amount])" + T.source_terminal = machine_id + T.date = current_date_string + T.time = worldtime2text() + D.transaction_log.Add(T) + + // Create log entry in owner's account + T = new() + T.target_name = D.owner_name + T.purpose = transaction_purpose + T.amount = "[transaction_amount]" + T.source_terminal = machine_id + T.date = current_date_string + T.time = worldtime2text() + linked_account.transaction_log.Add(T) + + // Save log + add_transaction_log(I.registered_name ? I.registered_name : "n/A", "ID Card", transaction_amount) + + // Confirm and reset + transaction_complete() + + +/obj/item/device/retail_scanner/proc/scan_wallet(var/obj/item/weapon/spacecash/ewallet/E) + if (!transaction_amount) + return + + if(!confirm(E)) + return + + // Access account for transaction + if(check_account()) + if(transaction_amount > E.worth) + src.visible_message("\icon[src]Not enough funds.") + else + // Transfer the money + E.worth -= transaction_amount + linked_account.money += transaction_amount + + // Create log entry in owner's account + var/datum/transaction/T = new() + T.target_name = E.owner_name + T.purpose = transaction_purpose + T.amount = "[transaction_amount]" + T.source_terminal = machine_id + T.date = current_date_string + T.time = worldtime2text() + linked_account.transaction_log.Add(T) + + // Save log + add_transaction_log(E.owner_name, "E-Wallet", transaction_amount) + + // Confirm and reset + transaction_complete() + + +/obj/item/device/retail_scanner/proc/scan_item_price(var/obj/O) + if(!istype(O)) return + // First check if item has a valid price + var/price = O.get_item_cost() + if(isnull(price)) + src.visible_message("\icon[src]Unable to find item in database.") + return + // Call out item cost + src.visible_message("\icon[src]\A [O]: [price ? "[price] Thaler\s" : "free of charge"].") + // Note the transaction purpose for later use + if(transaction_purpose) + transaction_purpose += "
" + transaction_purpose += "[O]: [price] Thaler\s" + transaction_amount += price + item_list += "[O]" + price_list += "[price] þ" + // Animation and sound + flick("retail_scan", src) + playsound(src, 'sound/machines/twobeep.ogg', 25) + // Reset confirmation + confirm_item = null + + +/obj/item/device/retail_scanner/proc/add_transaction_log(var/c_name, var/p_method, var/t_amount) + var/dat = {" + + + + + + + +
Transaction #[transaction_logs.len+1]
Customer[c_name]
Pay Method[p_method]
Station Time[worldtime2text()]
+ + "} + for(var/i=1, i<=item_list.len, i++) + dat += "" + dat += "" + dat += "
[item_list[i]][price_list[i]]
Total Amount: [transaction_amount] þ
" + + transaction_logs += dat + + +/obj/item/device/retail_scanner/proc/check_account() + if (!linked_account) + usr.visible_message("\icon[src]Unable to connect to linked account.") + return 0 + + if(linked_account.suspended) + src.visible_message("\icon[src]Connected account has been suspended.") + return 0 + return 1 + + +/obj/item/device/retail_scanner/proc/transaction_complete() + /// Visible confirmation + playsound(src, 'sound/machines/chime.ogg', 25) + src.visible_message("\icon[src]Transaction complete.") + flick("retail_approve", src) + reset_memory() + +/obj/item/device/retail_scanner/proc/reset_memory() + transaction_amount = null + transaction_purpose = "" + item_list.Cut() + price_list.Cut() + confirm_item = null + + +/obj/item/device/retail_scanner/emag_act(var/remaining_charges, var/mob/user) + if(!emagged) + user << "You stealthily swipe the cryptographic sequencer through \the [src]." + playsound(src, "sparks", 50, 1) + req_access = list() + emagged = 1 + +//--Premades--// + +/obj/item/device/retail_scanner/command + New() + linked_account = department_accounts["Command"] + ..() + /obj/item/device/retail_scanner/medical + + New() + linked_account = department_accounts["Medical"] + ..() + +/obj/item/device/retail_scanner/engineering + New() + linked_account = department_accounts["Engineering"] + ..() + +/obj/item/device/retail_scanner/science + New() + linked_account = department_accounts["Science"] + ..() + +/obj/item/device/retail_scanner/security + New() + linked_account = department_accounts["Security"] + ..() + +/obj/item/device/retail_scanner/cargo + New() + linked_account = department_accounts["Cargo"] + ..() + +/obj/item/device/retail_scanner/civilian + New() + linked_account = department_accounts["Civilian"] + ..() \ No newline at end of file diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index dfade93ae9..dfa384488e 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/icons/obj/stationobjs.dmi b/icons/obj/stationobjs.dmi index a9998cd624..ffac13cbe2 100644 Binary files a/icons/obj/stationobjs.dmi and b/icons/obj/stationobjs.dmi differ diff --git a/polaris.dme b/polaris.dme index d29063995c..6b4c234095 100644 --- a/polaris.dme +++ b/polaris.dme @@ -5,6 +5,72 @@ // END_INTERNALS // BEGIN_FILE_DIR #define FILE_DIR . +#define FILE_DIR "html" +#define FILE_DIR "html/images" +#define FILE_DIR "icons" +#define FILE_DIR "icons/48x48" +#define FILE_DIR "icons/atmos" +#define FILE_DIR "icons/effects" +#define FILE_DIR "icons/mecha" +#define FILE_DIR "icons/misc" +#define FILE_DIR "icons/mob" +#define FILE_DIR "icons/mob/human_races" +#define FILE_DIR "icons/mob/human_races/cyberlimbs" +#define FILE_DIR "icons/mob/human_races/masks" +#define FILE_DIR "icons/mob/human_races/monkeys" +#define FILE_DIR "icons/mob/human_races/subspecies" +#define FILE_DIR "icons/mob/human_races/xenos" +#define FILE_DIR "icons/mob/items" +#define FILE_DIR "icons/mob/screen" +#define FILE_DIR "icons/mob/species" +#define FILE_DIR "icons/mob/species/seromi" +#define FILE_DIR "icons/mob/species/skrell" +#define FILE_DIR "icons/mob/species/tajaran" +#define FILE_DIR "icons/mob/species/unathi" +#define FILE_DIR "icons/mob/species/vox" +#define FILE_DIR "icons/NTOS" +#define FILE_DIR "icons/NTOS/battery_icons" +#define FILE_DIR "icons/obj" +#define FILE_DIR "icons/obj/assemblies" +#define FILE_DIR "icons/obj/atmospherics" +#define FILE_DIR "icons/obj/clothing" +#define FILE_DIR "icons/obj/clothing/species" +#define FILE_DIR "icons/obj/clothing/species/seromi" +#define FILE_DIR "icons/obj/clothing/species/skrell" +#define FILE_DIR "icons/obj/clothing/species/tajaran" +#define FILE_DIR "icons/obj/clothing/species/unathi" +#define FILE_DIR "icons/obj/doors" +#define FILE_DIR "icons/obj/flora" +#define FILE_DIR "icons/obj/machines" +#define FILE_DIR "icons/obj/pipes" +#define FILE_DIR "icons/pda_icons" +#define FILE_DIR "icons/spideros_icons" +#define FILE_DIR "icons/Testing" +#define FILE_DIR "icons/turf" +#define FILE_DIR "icons/turf/flooring" +#define FILE_DIR "icons/vending_icons" +#define FILE_DIR "maps" +#define FILE_DIR "maps/overmap" +#define FILE_DIR "maps/overmap/bearcat" +#define FILE_DIR "nano" +#define FILE_DIR "nano/images" +#define FILE_DIR "sound" +#define FILE_DIR "sound/AI" +#define FILE_DIR "sound/ambience" +#define FILE_DIR "sound/effects" +#define FILE_DIR "sound/effects/turret" +#define FILE_DIR "sound/effects/wind" +#define FILE_DIR "sound/hallucinations" +#define FILE_DIR "sound/items" +#define FILE_DIR "sound/machines" +#define FILE_DIR "sound/mecha" +#define FILE_DIR "sound/misc" +#define FILE_DIR "sound/music" +#define FILE_DIR "sound/piano" +#define FILE_DIR "sound/violin" +#define FILE_DIR "sound/voice" +#define FILE_DIR "sound/voice/Serithi" +#define FILE_DIR "sound/weapons" // END_FILE_DIR // BEGIN_PREFERENCES #define DEBUG @@ -1099,10 +1165,13 @@ #include "code\modules\economy\Accounts_DB.dm" #include "code\modules\economy\ATM.dm" #include "code\modules\economy\cash.dm" +#include "code\modules\economy\cash_register.dm" #include "code\modules\economy\economy_misc.dm" #include "code\modules\economy\EFTPOS.dm" #include "code\modules\economy\Events.dm" #include "code\modules\economy\Events_Mundane.dm" +#include "code\modules\economy\price_list.dm" +#include "code\modules\economy\retail_scanner.dm" #include "code\modules\economy\TradeDestinations.dm" #include "code\modules\events\apc_damage.dm" #include "code\modules\events\blob.dm"