diff --git a/aurorastation.dme b/aurorastation.dme index 611dbec244e..a8f148a0ceb 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -484,6 +484,7 @@ #include "code\datums\weakrefs.dm" #include "code\datums\changelog\changelog.dm" #include "code\datums\components\_component.dm" +#include "code\datums\components\commissaryShop.dm" #include "code\datums\components\connect_mob_behalf.dm" #include "code\datums\components\drift.dm" #include "code\datums\components\jukebox.dm" diff --git a/code/__HELPERS/price.dm b/code/__HELPERS/price.dm index 3a5331f3bed..50f53df1d76 100644 --- a/code/__HELPERS/price.dm +++ b/code/__HELPERS/price.dm @@ -11,35 +11,73 @@ /proc/read_paper_price_list(var/obj/item/paper/R) var/text = R.info - // Split on new line + // Split on line breaks var/list/lines = splittext(text, "
") var/list/result = list() - // Skip a header line + // Skip header line for(var/i = 2; i <= lines.len; i++) - var/line = lines[i] + var/line = trim(lines[i]) if(!length(line)) continue - // Split the name and price var/list/split_input = splittext(line, ";") - if(split_input.len < 2) + // category;name;price + if(length(split_input) >= 3) + var/category = trim(split_input[1]) + var/name = trim(split_input[2]) + var/price_text = trim(split_input[3]) + + if(!length(category)) + category = "Uncategorized" + if(!length(name)) + continue + + var/price = text2num(price_text) + + // Reject null prices + if(isnull(price)) + continue + + // Reject invalid prices + if(price == 0 && price_text != "0" && price_text != "0.0" && price_text != "0.00") + continue + + result += list(list( + "name" = name, + "price" = price, + "category" = category + )) continue - var/name = split_input[1] - var/price_text = split_input[2] + // name;price + if(length(split_input) >= 2) + var/name = trim(split_input[1]) + var/price_text = trim(split_input[2]) - var/price = text2num(price_text) + if(!length(name)) + continue - // In case of invalid prices for some reason - if(price == 0 && price_text != "0" && price_text != "0.0") - continue + var/price = text2num(price_text) - result += list(list("name" = name, "price" = price)) + // Reject null prices + if(isnull(price)) + continue + + // Reject invalid prices + if(price == 0 && price_text != "0" && price_text != "0.0" && price_text != "0.00" && price != null) + continue + + result += list(list( + "name" = name, + "price" = price, + "category" = "Uncategorized" + )) return result + // Prints the prices from a register/quikpay into a list that can be used for read_paper_price_list() /proc/print_price_to_paper(var/shop_name, var/list/items, var/paper_loc, mob/user) if(!items || !items.len) @@ -47,12 +85,17 @@ var/obj/item/paper/notepad/receipt/R = new(paper_loc) var/title = "Price List: [shop_name]" - var/text = "name;price
" + var/text = "category;name;price
" for(var/list/L in items) - var/item_name = L["name"] + var/item_category = sanitize_tg(L["category"]) + var/item_name = sanitize_tg(L["name"]) var/item_price = L["price"] - text += "[item_name];[round(item_price, 0.01)]
" + + if(!length(item_category)) + item_category = "Uncategorized" + + text += "[item_category];[item_name];[round(item_price, 0.01)]
" R.set_content(title, text) diff --git a/code/datums/components/commissaryShop.dm b/code/datums/components/commissaryShop.dm new file mode 100644 index 00000000000..6227cdcea27 --- /dev/null +++ b/code/datums/components/commissaryShop.dm @@ -0,0 +1,434 @@ +/datum/component/quikpay_shop + /// The id associated with the quikpay system. Automatically assigned. + var/machine_id = "" + /// The Items for sale, containing name and price + var/list/items = list() + /// The items in the purchase basket, containing name, price and amount + var/list/buying = list() + /// The input field for new item names + var/new_item = "" + /// The input field for new item prices + var/new_price = 0 + /// The input field for new item categories + var/new_category = "" + /// The transaction total for a purchase, 0 when there is no transaction ongoing + var/sum = 0 + /// If the shop can be changed or not, to add new items or change destination account + var/editmode = FALSE + /// Receipt printing info + var/receipt = "" + /// The account to receive funds from card transactions + var/destinationact = "Operations" + /// The credits within the shop object + var/credit = 100 + /// The name used for the shop + var/shop_name = "Commissary" + /// The owner object, also known as parent. Defined to easily do obj specific procs + var/obj/owner + /// If it is possible to pay with physical credits or only card + var/can_use_credits = TRUE + /// The the longer version of the shop name + var/shop_long_name = "Idris Quik-Pay Register" + /// The access types that can configure the shop + var/req_one_access = list(ACCESS_BAR, ACCESS_GALLEY, ACCESS_CARGO) + +/datum/component/quikpay_shop/quikpay + shop_name = "Quik-Pay" + destinationact = "Service" + shop_long_name = "Quik-Pay device" + can_use_credits = FALSE + +/// Add an item by clicking on it with the quikpay +/datum/component/quikpay_shop/quikpay/proc/add_item(atom/target, mob/user) + if(!isobj(target)) + return + if (!editmode) + to_chat(user, SPAN_NOTICE("Unlock \the [owner] to add items.")) + return + + var/obj/O = target + var/name_guess = O.name + var/price_guess = 0 + var/category_guess = "" + + price_guess = text2num(tgui_input_text(user, "Set price for [name_guess]:", "[shop_long_name]", 0, 10)) + if(isnull(price_guess) || price_guess == 0) + return + price_guess = max(0.01, round(price_guess, 0.01)) + + category_guess = tgui_input_text(user, "Set category for [name_guess]:", "[shop_long_name]", "Uncategorized", 32) + if(isnull(category_guess) || !length(category_guess)) + category_guess = "Uncategorized" + + items += list(list( + "name" = "[name_guess]", + "price" = price_guess, + "category" = "[category_guess]" + )) + + to_chat(user, SPAN_NOTICE("[owner]: added '[name_guess]' for [price_guess] in category '[category_guess]'.")) + return TRUE + + +/datum/component/quikpay_shop/Initialize(access = list(ACCESS_BAR, ACCESS_GALLEY, ACCESS_CARGO), destination = "Operations") + . = ..() + machine_id = "[station_name()] [shop_long_name] #[SSeconomy.num_financial_terminals++]" + if(!isobj(parent)) + return + req_one_access = access + destinationact = destination + owner = parent + +/// Put credits in or take them out, assuming the device has credits +/datum/component/quikpay_shop/proc/take_give_credits(mob/user) + if(!can_use_credits) + return + var/item = user.get_active_hand() + + if(istype(item, /obj/item/spacecash) && !istype(item, /obj/item/spacecash/ewallet)) + var/obj/item/spacecash/cashmoney = item + credit += cashmoney.worth + user.drop_from_inventory(cashmoney,get_turf(owner)) + user.visible_message("\The [user] inserts some credits into \the [owner]." ) + qdel(cashmoney) + return + + var/obj/item/card/id/I = user.GetIdCard() + if(istype(I) && has_access(req_one_access = src.req_one_access, accesses = I.access)) + var/price_guess = text2num(tgui_input_text(user, "How much do you wish to withdraw? Remaining credits: [credit]电", "Quik-Pay", 0, 10)) + if(isnull(price_guess) || price_guess == 0) + return + price_guess = max(0, round(price_guess, 0.01)) + if(credit >= price_guess) + spawn_money(price_guess, owner.loc, user) + credit = max(0, credit - price_guess) + user.visible_message("\The [user] remove some credits from \the [owner].", "You hear a drawer being opened and the clinking of coins, followed by a drawer being closed." ) + +/// Print out a relevant receipt +/datum/component/quikpay_shop/proc/print_receipt() + var/obj/item/paper/notepad/receipt/R = new(owner.loc) + var/receiptname = "Receipt: [machine_id]" + R.set_content_unsafe(receiptname, receipt, sum) + stamp_receipt(R) + usr.put_in_any_hand_if_possible(R) + +/// Interact with an object. Papers or payment pethods +/datum/component/quikpay_shop/proc/interact_object(obj/item/attacking_item, mob/user) + if(istype(attacking_item, /obj/item/paper)) + read_paper_list(attacking_item, user) + return + if(sum == 0) + return + if (istype(attacking_item, /obj/item/spacecash/ewallet)) + card_pay(attacking_item, user) + return + else if (istype(attacking_item, /obj/item/card/id)) + ID_pay(attacking_item, user) + return + else if(istype(attacking_item, /obj/item/spacecash) && can_use_credits) + cash_pay(attacking_item, user) + return + +/// Paying with cash +/datum/component/quikpay_shop/proc/cash_pay(obj/item/spacecash/cashmoney, mob/user) + if(!can_use_credits) + return + var/transaction_amount = sum + if(transaction_amount > cashmoney.worth) + to_chat(user, SPAN_WARNING("[icon2html(cashmoney, user)] That is not enough money.")) + return FALSE + if(istype(cashmoney, /obj/item/spacecash/bundle)) + user.visible_message(SPAN_INFO("\The [user] inserts some cash into \the [owner].")) + var/obj/item/spacecash/bundle/cashmoney_bundle = cashmoney + cashmoney_bundle.worth -= transaction_amount + + if(cashmoney_bundle.worth <= 0) + usr.drop_from_inventory(cashmoney_bundle,get_turf(owner)) + qdel(cashmoney_bundle) + else + cashmoney_bundle.update_icon() + else + user.visible_message(SPAN_INFO("\The [user] inserts a bill into \the [owner].")) + var/left = cashmoney.worth - transaction_amount + user.drop_from_inventory(cashmoney,get_turf(owner)) + qdel(cashmoney) + + if(left) + spawn_money(left, get_turf(user), user) + credit += transaction_amount + print_receipt() + clear_order() + +/// Paying with an id card +/datum/component/quikpay_shop/proc/ID_pay(obj/item/attacking_item, mob/user) + var/obj/item/card/id/I = attacking_item.GetID() + var/transaction_amount = sum + var/transaction_purpose = "[destinationact] Payment" + var/transaction_terminal = machine_id + + var/transaction = SSeconomy.transfer_money(I.associated_account_number, SSeconomy.get_department_account(destinationact)?.account_number,transaction_purpose,transaction_terminal,transaction_amount,null,usr) + + if(transaction) + to_chat(user, SPAN_NOTICE("[icon2html(owner, user)][transaction].")) + else + end_transaction(user) + +/// Paying with a charge card +/datum/component/quikpay_shop/proc/card_pay(obj/item/attacking_item, mob/user) + var/obj/item/spacecash/ewallet/E = attacking_item + var/transaction_amount = sum + var/transaction_purpose = "[destinationact] Payment" + var/transaction_terminal = machine_id + + if(transaction_amount <= E.worth) + SSeconomy.charge_to_account(SSeconomy.get_department_account(destinationact)?.account_number, E.owner_name, transaction_purpose, transaction_terminal, transaction_amount) + E.worth -= transaction_amount + + end_transaction(user) + else if (transaction_amount > E.worth) + to_chat(user, SPAN_WARNING("[icon2html(owner, user)]\The [E] doesn't have that much money!")) + +/// Read a paper to get data +/datum/component/quikpay_shop/proc/read_paper_list(obj/item/paper/R, mob/user) + if(!editmode) + owner.balloon_alert(user, "device locked!") + return FALSE + + var/result = read_paper_price_list(R) + for(var/item in result) + items += list(list( + "name" = item["name"], + "price" = item["price"], + "category" = item["category"] || "Uncategorized" + )) + owner.balloon_alert(user, "device set!") + return TRUE + +/// Handles receipt creation +/datum/component/quikpay_shop/proc/buying_receipt(mob/user) + receipt = "" + sum = 0 + var/obj/item/card/id/id_card = user.GetIdCard() + var/cashier = id_card ? id_card.registered_name : "Unknown" + receipt = "

[shop_name] receipt

Today's date: [worlddate2text()]
Cashier: [cashier]

Purchased items:
Total: [sum]电
" + +/datum/component/quikpay_shop/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "QuikPay", "[shop_long_name]", 550, 550) + ui.open() + +/datum/component/quikpay_shop/ui_data(mob/user) + var/list/data = list() + + data["items"] = items + data["buying"] = buying + data["sum"] = sum + data["new_item"] = new_item + data["new_price"] = new_price + data["new_category"] = new_category + data["editmode"] = editmode + data["destinationact"] = destinationact + + return data + +/datum/component/quikpay_shop/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return + switch(action) + if("add") + if(!editmode) + owner.balloon_alert(usr, "device locked!") + return FALSE + + if(!length(new_item)) + return FALSE + + if(!length(new_category)) + new_category = "Uncategorized" + + for(var/list/L in items) + if(L["name"] == new_item) + return FALSE + + items += list(list( + "name" = new_item, + "price" = new_price, + "category" = new_category + )) + + new_item = "" + . = TRUE + + if("remove") + if(!editmode) + owner.balloon_alert(usr, "device locked!") + return FALSE + var/index = 0 + for(var/list/L in items) + index++ + if(L["name"] == params["removing"]) + items.Cut(index, index+1) + break + . = TRUE + + if("set_new_price") + new_price = params["set_new_price"] + . = TRUE + + if("set_new_item") + new_item = params["set_new_item"] + . = TRUE + + if("set_new_category") + new_category = params["set_new_category"] + . = TRUE + + if("clear") + clear_order() + . = TRUE + + if("buy") + for(var/list/L in buying) + if(L["name"] == params["buying"]) + L["amount"]++ + return TRUE + buying += list(list("name" = sanitize_tg(params["buying"]), "amount" = params["amount"], "price" = params["price"])) + + if("removal") + var/index = 0 + for(var/list/L in buying) + index++ + if(L["name"] == params["removal"]) + if(L["amount"] > 1) + L["amount"]-- + else + buying.Cut(index, index+1) + break + . = TRUE + + if("confirm") + buying_receipt(usr) + playsound(owner, 'sound/machines/ping.ogg', 25, TRUE) + owner.audible_message(SPAN_NOTICE("[icon2html(owner, viewers(get_turf(owner)))] \The [owner] pings.")) + . = TRUE + + if("locking") + if(editmode) + editmode = FALSE + owner.balloon_alert(usr, "device locked!") + else + if(!editmode) + var/obj/item/card/id/I = usr.GetIdCard() + if(!istype(I)) + return + if(!has_access(req_one_access = src.req_one_access, accesses = I.access)) + owner.balloon_alert(usr, "no access!") + return + editmode = !editmode + owner.balloon_alert(usr, "device [editmode ? "un" : ""]locked") + . = TRUE + + if("accountselect") + if(!editmode) + owner.balloon_alert(usr, "device locked!") + return FALSE + + var/dest = tgui_input_list(usr, "What account would you like to select?", "Destination Account", assoc_to_keys(SSeconomy.department_accounts)) + if(!dest) + return FALSE + destinationact = dest + . = TRUE + + if("print_dsv") + if(!editmode) + owner.balloon_alert(usr, "device locked!") + return FALSE + print_price_to_paper(shop_name, items, owner.loc, usr) + . = TRUE + +/// Clear the order from the selection +/datum/component/quikpay_shop/proc/clear_order() + buying.Cut() + sum = 0 + receipt = "" + +/// Ends the transaction by using a card, giving a message +/datum/component/quikpay_shop/proc/end_transaction(mob/user) + user.visible_message("\The [user] swipes a card on \the [owner]." ) + owner.audible_message(SPAN_NOTICE("[icon2html(owner, viewers(get_turf(owner)))] \The [owner] chimes.")) + playsound(owner, 'sound/machines/chime.ogg', 50, TRUE) + print_receipt() + to_chat(user, SPAN_NOTICE("Transaction completed, please return to the home screen.")) + clear_order() + +/datum/component/quikpay_shop/orderterminal + shop_name = "Commissary" + shop_long_name = "Self-serve Shop Teller" + can_use_credits = FALSE + +/datum/component/quikpay_shop/orderterminal/food + var/ticket = "" + var/ticket_number = 1 + shop_name = "Service terminal" + shop_long_name = "Idris Food Terminal" + +/datum/component/quikpay_shop/orderterminal/food/buying_receipt(mob/user) + ticket = "" + receipt = "" + sum = 0 + receipt += "
[shop_long_name] Receipt

" + ticket += "
[shop_long_name] Ticket

" + for(var/list/bought_item in buying) + var/item_name = bought_item["name"] + var/item_amount = bought_item["amount"] + var/item_price = bought_item["price"] + sum += item_price * item_amount + + receipt += "
  • [item_name]: [item_amount] x [item_price]电: [item_amount * item_price]电
    " + ticket += "
  • [item_name]: [item_amount] x [item_price]电: [item_amount * item_price]电
    " + receipt += "
    Total: [sum]电" + ticket += "
    Total: [sum]电" + sum = sum + +/// Print the receipt followed by the order ticket +/datum/component/quikpay_shop/orderterminal/food/print_receipt() + var/obj/item/card/id/id_card + if(ishuman(usr)) + id_card = usr.GetIdCard() + ticket += "
    Customer: [id_card ? id_card.registered_name : "Unknown"]" + receipt += "
    Customer: [id_card ? id_card.registered_name : "Unknown"]" + var/obj/item/paper/notepad/receipt/R = new(owner.loc) + var/receiptname = "Receipt: [machine_id]" + R.set_content_unsafe(receiptname, receipt, sum) + stamp_receipt(R) + usr.put_in_any_hand_if_possible(R) + // And now we do it but for the ticket. + var/obj/item/paper/notepad/receipt/T = new(owner.loc) + var/tickettname = "Order ticket: [ticket_number]" + ticket_number++ + T.set_content_unsafe(tickettname, ticket, sum) + stamp_receipt(T) + usr.put_in_any_hand_if_possible(T) + ticket = "" + receipt = "" + +/datum/component/quikpay_shop/proc/stamp_receipt(obj/item/paper/R) // Stamps the papers, made into a proc to avoid copy pasting too much + var/image/stampoverlay = image('icons/obj/bureaucracy.dmi') + stampoverlay.icon_state = "paper_stamp-hop" + if(!R.stamped) + R.stamped = new + R.stamped += /obj/item/stamp + R.AddOverlays(stampoverlay) + R.stamps += "
    This paper has been stamped by \the [owner]." + R.ripped = TRUE diff --git a/code/modules/cooking/machinery/commissary.dm b/code/modules/cooking/machinery/commissary.dm index dba823d2beb..bb89d7ca255 100644 --- a/code/modules/cooking/machinery/commissary.dm +++ b/code/modules/cooking/machinery/commissary.dm @@ -41,6 +41,7 @@ display_tiers = 5 display_tier_amt = 3 has_emissive = FALSE + visible_takeout = TRUE /obj/machinery/smartfridge/tradeshelf/clothing name = "clothing shelf" @@ -87,6 +88,17 @@ display_tier_amt = 5 has_emissive = TRUE +/obj/machinery/smartfridge/tradeshelf/food/attackby(obj/item/attacking_item, mob/user) + if(attacking_item.tool_behaviour == TOOL_PEN) + name_fridge(user) + return + . = ..() + +/obj/machinery/smartfridge/tradeshelf/food/proc/name_fridge(mob/user) + var/newname = tgui_input_text(user, "What would you like to rename the fridge? Note that fridge will be appended to the end of it", "Fridge name") + if(newname) + name = newname + " fridge" + /obj/machinery/smartfridge/tradeshelf/toy name = "toy shelf" desc = "A commercialized shelf for toys and associated items." @@ -139,308 +151,119 @@ // ------------------------------------------------- /obj/structure/cash_register/commissary - var/machine_id = "" - var/list/items = list() - var/list/items_to_price = list() - var/list/buying = list() - var/new_item = "" - var/new_price = 0 - var/sum = 0 - var/editmode = FALSE - var/receipt = "" - var/destinationact = "Operations" - var/credit = 100 - var/shop_name = "Commissary" storage_type = null + req_one_access = list(ACCESS_BAR, ACCESS_GALLEY, ACCESS_CARGO) + var/destination = "Operations" /obj/structure/cash_register/commissary/mechanics_hints(mob/user, distance, is_adjacent) . = list() - . += "Alt click with a command id in hand, to gain command access." - . += "Alt click with credits in hand, to deposit them." - . += "Alt click while having operations access, to withdraw credits from it." + . += "Alt-click with credits in hand, to deposit them." + . += "Alt-click while having the proper access, to withdraw credits from it." . += "Items can be paid for with id cards, charge cards or physical credits, and a receipt will be printed." . += "The register can print a paper which can be used to quickly fill it out in the future by using it on the register." /obj/structure/cash_register/commissary/Initialize() . = ..() - machine_id = "[station_name()] Idris Quik-Pay Register #[SSeconomy.num_financial_terminals++]" + src.LoadComponent(/datum/component/quikpay_shop, req_one_access, destination) /obj/structure/cash_register/commissary/AltClick(var/mob/user) - var/item = user.get_active_hand() - var/obj/item/card/id/I = item - if(istype(I) && (ACCESS_HEADS in I.access)) - if(ACCESS_HEADS in I.access) - editmode = TRUE - to_chat(user, SPAN_NOTICE("Command access granted.")) - SStgui.update_uis(src) + . = ..() + var/datum/component/quikpay_shop/qp_shop = src.GetComponent(/datum/component/quikpay_shop) + if(!qp_shop) return - if(istype(item, /obj/item/spacecash) && !istype(item, /obj/item/spacecash/ewallet)) - var/obj/item/spacecash/cashmoney = item - credit += cashmoney.worth - user.drop_from_inventory(cashmoney,get_turf(src)) - visible_message("\The [user] inserts some credits into \the [src]." ) - qdel(cashmoney) - return - I = user.GetIdCard() - if(istype(I) && (ACCESS_CARGO in I.access)) - var/price_guess = text2num(sanitizeSafe( tgui_input_text(user, "How much do you wish to withdraw? Remaining credits: [credit]电", "QuikPay", 0, 10), 10)) - if(isnull(price_guess) || price_guess == 0) - return - price_guess = max(0, round(price_guess, 0.01)) - if(credit >= price_guess) - spawn_money(price_guess, loc, user) - credit -= price_guess - visible_message("\The [user] remove some credits from \the [src]." ) - return - -/obj/structure/cash_register/commissary/proc/print_receipt() - var/obj/item/paper/notepad/receipt/R = new(loc) - var/receiptname = "Receipt: [machine_id]" - R.set_content_unsafe(receiptname, receipt, sum) - - //stamp the paper - var/image/stampoverlay = image('icons/obj/bureaucracy.dmi') - stampoverlay.icon_state = "paper_stamp-hop" - if(!R.stamped) - R.stamped = new - R.stamped += /obj/item/stamp - R.AddOverlays(stampoverlay) - R.stamps += "
    This paper has been stamped by the Idris Quik-Pay Register." - usr.put_in_any_hand_if_possible(R) - R.ripped = TRUE + qp_shop.take_give_credits(user, loc) /obj/structure/cash_register/commissary/attackby(obj/item/attacking_item, mob/user) - if(istype(attacking_item, /obj/item/paper)) - read_paper_list(attacking_item, user) + . = ..() + var/datum/component/quikpay_shop/qp_shop = src.GetComponent(/datum/component/quikpay_shop) + if(!qp_shop) return - if(sum == 0) - return - if (istype(attacking_item, /obj/item/spacecash/ewallet)) - card_pay(attacking_item, user) - return - else if (istype(attacking_item, /obj/item/card/id)) - ID_pay(attacking_item, user) - return - else if(istype(attacking_item, /obj/item/spacecash)) - cash_pay(attacking_item, user) - return - -/obj/structure/cash_register/commissary/proc/cash_pay(obj/item/spacecash/cashmoney, mob/user) - var/transaction_amount = sum - if(transaction_amount > cashmoney.worth) - to_chat(user, SPAN_WARNING("[icon2html(cashmoney, user)] That is not enough money.")) - return 0 - if(istype(cashmoney, /obj/item/spacecash/bundle)) - visible_message(SPAN_INFO("\The [user] inserts some cash into \the [src].")) - var/obj/item/spacecash/bundle/cashmoney_bundle = cashmoney - cashmoney_bundle.worth -= transaction_amount - - if(cashmoney_bundle.worth <= 0) - usr.drop_from_inventory(cashmoney_bundle,get_turf(src)) - qdel(cashmoney_bundle) - else - cashmoney_bundle.update_icon() - else - visible_message(SPAN_INFO("\The [user] inserts a bill into \the [src].")) - var/left = cashmoney.worth - transaction_amount - user.drop_from_inventory(cashmoney,get_turf(src)) - qdel(cashmoney) - - if(left) - spawn_money(left, get_turf(user), user) - credit += transaction_amount - print_receipt() - clear_order() - return 1 - -/obj/structure/cash_register/commissary/proc/ID_pay(obj/item/attacking_item, mob/user) - var/obj/item/card/id/I = attacking_item.GetID() - var/transaction_amount = sum - var/transaction_purpose = "[destinationact] Payment" - var/transaction_terminal = machine_id - - var/transaction = SSeconomy.transfer_money(I.associated_account_number, SSeconomy.get_department_account(destinationact)?.account_number,transaction_purpose,transaction_terminal,transaction_amount,null,usr) - - if(transaction) - to_chat(user, SPAN_NOTICE("[icon2html(src, user)][transaction].")) - else - visible_message("\The [user] swipes a card on \the [src]." ) - audible_message(SPAN_NOTICE("[icon2html(src, viewers(get_turf(src)))] \The [src] chimes.")) - playsound(src, 'sound/machines/chime.ogg', 50, 1) - print_receipt() - sum = 0 - receipt = "" - to_chat(user, SPAN_NOTICE("Transaction completed, please return to the home screen.")) - clear_order() - -/obj/structure/cash_register/commissary/proc/card_pay(obj/item/attacking_item, mob/user) - var/obj/item/spacecash/ewallet/E = attacking_item - var/transaction_amount = sum - var/transaction_purpose = "[destinationact] Payment" - var/transaction_terminal = machine_id - - if(transaction_amount <= E.worth) - SSeconomy.charge_to_account(SSeconomy.get_department_account(destinationact)?.account_number, E.owner_name, transaction_purpose, transaction_terminal, transaction_amount) - E.worth -= transaction_amount - - visible_message("\The [user] swipes a card on \the [src]." ) - audible_message(SPAN_NOTICE("[icon2html(src, viewers(get_turf(src)))] \The [src] chimes.")) - playsound(src, 'sound/machines/chime.ogg', 50, 1) - print_receipt() - sum = 0 - receipt = "" - to_chat(user, SPAN_NOTICE("Transaction completed, please return to the home screen.")) - clear_order() - else if (transaction_amount > E.worth) - to_chat(user, SPAN_WARNING("[icon2html(src, user)]\The [E] doesn't have that much money!")) - return - -/obj/structure/cash_register/commissary/proc/read_paper_list(obj/item/paper/R, mob/user) - if(!editmode) - balloon_alert(user, "device locked!") - return FALSE - var/result = read_paper_price_list(R) - for(var/item in result) - items += list(list("name" = item["name"], "price" = item["price"])) - items_to_price[item["name"]] += item["price"] - -/obj/structure/cash_register/commissary/proc/print_price(mob/user) - return print_price_to_paper(shop_name, items, loc, user) + qp_shop.interact_object(attacking_item, user) /obj/structure/cash_register/commissary/attack_hand(mob/living/user) . = ..() - ui_interact(user) - -/obj/structure/cash_register/commissary/ui_interact(mob/user, datum/tgui/ui) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "QuikPay", "Idris Quik-Pay Register", 550, 550) - ui.open() - -/obj/structure/cash_register/commissary/ui_data(var/mob/user) - var/list/data = list() - - data["items"] = items - data["buying"] = buying - data["sum"] = sum - data["new_item"] = new_item - data["new_price"] = new_price - data["editmode"] = editmode - data["destinationact"] = destinationact - - return data - -/obj/structure/cash_register/commissary/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) - . = ..() - if(.) + var/datum/component/quikpay_shop/qp_shop = src.GetComponent(/datum/component/quikpay_shop) + if(!qp_shop) return - switch(action) - if("add") - if(!editmode) - balloon_alert(usr, "device locked!") - return FALSE + qp_shop.ui_interact(user) - items += list(list("name" = new_item, "price" = new_price)) - items_to_price[new_item] = new_price - . = TRUE +/obj/machinery/commissary_wall_shop + name = "self-serve shop teller" + desc = "An ordering terminal designed by Idris for quicker expedition." + icon = 'icons/obj/machinery/wall/terminals.dmi' + icon_state = "orderterminal" + idle_power_usage = 10 + anchored = TRUE + var/turned_on = FALSE + req_one_access = list(ACCESS_BAR, ACCESS_GALLEY, ACCESS_CARGO) + var/destination = "Operations" - if("remove") - if(!editmode) - balloon_alert(usr, "device locked!") - return FALSE - var/index = 0 - for(var/list/L in items) - index++ - if(L["name"] == params["removing"]) - items.Cut(index, index+1) - . = TRUE +/obj/machinery/commissary_wall_shop/mechanics_hints(mob/user, distance, is_adjacent) + . += ..() + . += "Items can be paid for with id cards or charge cards, and a receipt will be printed." + . += "The terminal can print a paper which can be used to quickly fill it out in the future by using it on the register." + . += "With the proper access, ctrl-click to turn the machine on and off." - if("set_new_price") - new_price = params["set_new_price"] - . = TRUE +/obj/machinery/commissary_wall_shop/Initialize() + . = ..() + src.LoadComponent(/datum/component/quikpay_shop/orderterminal, req_one_access, destination) + update_icon() - if("set_new_item") - new_item = params["set_new_item"] - . = TRUE +/obj/machinery/commissary_wall_shop/attackby(obj/item/attacking_item, mob/user) + if(!turned_on) + balloon_alert(user, "turned off") + return + if(stat & NOPOWER) + balloon_alert(user, "no power") + return + var/datum/component/quikpay_shop/orderterminal/qp_shop = src.GetComponent(/datum/component/quikpay_shop/orderterminal) + if(!qp_shop) + return + qp_shop.interact_object(attacking_item, user) - if("clear") - clear_order() - . = TRUE +/obj/machinery/commissary_wall_shop/attack_hand(mob/living/user) + if(!turned_on) + balloon_alert(user, "turned off") + return + if(stat & NOPOWER) + balloon_alert(user, "no power") + return + var/datum/component/quikpay_shop/orderterminal/qp_shop = src.GetComponent(/datum/component/quikpay_shop/orderterminal) + if(!qp_shop) + return + qp_shop.ui_interact(user) - if("buy") - for(var/list/L in buying) - if(L["name"] == params["buying"]) - L["amount"]++ - return TRUE - buying += list(list("name" = params["buying"], "amount" = params["amount"], "price" = items_to_price[params["buying"]])) +/obj/machinery/commissary_wall_shop/CtrlClick(mob/user) + var/obj/item/card/id/I = user.GetIdCard() + if(!istype(I)) + balloon_alert(user, "no id!") + return + if(!has_access(req_one_access = src.req_one_access, accesses = I.access)) + balloon_alert(user, "no access!") + return + turned_on = !turned_on + balloon_alert(user, "turned [turned_on ? "on" : "off"]") + update_icon() - if("removal") - var/index = 0 - for(var/list/L in buying) - index++ - if(L["name"] == params["removal"]) - if(L["amount"] > 1) - L["amount"]-- - else - buying.Cut(index, index+1) - . = TRUE +/obj/machinery/commissary_wall_shop/power_change() + ..() + update_icon() - if("confirm") - // Ensuring it is clear, in case the button is clicked multiple times - receipt = "" - sum = 0 - var/obj/item/card/id/id_card = usr.GetIdCard() - var/cashier = id_card? id_card.registered_name : "Unknown" - receipt = "

    [shop_name] receipt

    Today's date: [worlddate2text()]
    Cashier: [cashier]

    Purchased items:
    Total: [sum]电
    " - playsound(src, 'sound/machines/ping.ogg', 25, 1) - audible_message(SPAN_NOTICE("[icon2html(src, viewers(get_turf(src)))] \The [src] pings.")) - . = TRUE - - if("locking") - if(editmode) - editmode = FALSE - balloon_alert(usr, "device locked!") - else - if(!editmode) - var/obj/item/card/id/I = usr.GetIdCard() - if(!istype(I)) - return - if(check_access(I)) - editmode = !editmode - balloon_alert(usr, "device [editmode ? "un" : ""]locked") - . = TRUE - - if("accountselect") - if(!editmode) - balloon_alert(usr, "device locked!") - return FALSE - - var/dest = tgui_input_list(usr, "What account would you like to select?", "Destination Account", assoc_to_keys(SSeconomy.department_accounts)) - if(!dest) - return FALSE - destinationact = dest - . = TRUE - - if("print_dsv") - if(!editmode) - balloon_alert(usr, "device locked!") - return FALSE - print_price(usr) - . = TRUE - -/obj/structure/cash_register/commissary/proc/clear_order() - buying.Cut() - sum = 0 - receipt = "" +/obj/machinery/commissary_wall_shop/process() + if(stat & NOPOWER || !turned_on) + ClearOverlays() + set_light(FALSE) + return /obj/item/commissary_restrock name = "commissary cigarette restock pack" @@ -701,6 +524,17 @@ desc = "A crate packed with boxes of various goods. Handle with care!" /obj/structure/closet/crate/commissary/fill() + for(var/i = 1 to 8) + new /obj/item/storage/box/unique/papersack(src) + new /obj/item/storage/bag/plasticbag(src) + new /obj/item/storage/box/plasticbag(src) + new /obj/item/tape_roll(src) + new /obj/item/hand_labeler(src) + new /obj/item/storage/toolbox/mechanical(src) + +/obj/structure/closet/crate/commissary/resupply + +/obj/structure/closet/crate/commissary/resupply/fill() new /obj/item/commissary_restrock(src) new /obj/item/commissary_restrock/rollable(src) new /obj/item/commissary_restrock/chewable(src) diff --git a/code/modules/cooking/machinery/smartfridge.dm b/code/modules/cooking/machinery/smartfridge.dm index 31957f5890e..19447520bc9 100644 --- a/code/modules/cooking/machinery/smartfridge.dm +++ b/code/modules/cooking/machinery/smartfridge.dm @@ -20,6 +20,7 @@ var/scan_id = 1 var/is_secure = 0 var/machineselect = 0 + var/visible_takeout = FALSE var/list/accepted_items = list(/obj/item/reagent_containers/food/snacks/grown, /obj/item/seeds, /obj/item/mollusc) /// List of items that the machine starts with upon spawn @@ -536,15 +537,20 @@ var/i = amount for(var/obj/O in contents) - if(O.name == K) - if(Adjacent(user)) - user.put_in_hands(O) - else - O.forceMove(loc) - i-- - update_overlays() - if(i <= 0) - break + if(O.name != K) + continue + if(Adjacent(user)) + user.put_in_hands(O) + if(visible_takeout) + user.visible_message( + "[SPAN_BOLD("[user]")] takes \a [O] from \the [src].", + SPAN_NOTICE("You take \a [O] from \the [src].")) + else + O.forceMove(loc) + i-- + update_overlays() + if(i <= 0) + break if(item_quants[K] <= 0) update_static_data_for_all_viewers() diff --git a/code/modules/economy/OrderTerminal.dm b/code/modules/economy/OrderTerminal.dm index 9df4983d1a6..d5b1dd8779d 100644 --- a/code/modules/economy/OrderTerminal.dm +++ b/code/modules/economy/OrderTerminal.dm @@ -21,16 +21,16 @@ var/ticket = "" var/destinationact = "Service" var/ticket_number = 1 - req_one_access = list(ACCESS_BAR, ACCESS_GALLEY) // Access to change the menu + req_one_access = list(ACCESS_BAR, ACCESS_GALLEY, ACCESS_CARGO) // Access to change the menu /obj/machinery/orderterminal/mechanics_hints(mob/user, distance, is_adjacent) . += ..() - . += "To edit the menu, select 'Toggle Lock' while wearing an ID with galley access." - . += "All credits from the machine will automatically go to the civilian account." + . += "Items can be paid for with id cards or charge cards, and a receipt will be printed." + . += "The terminal can print a paper which can be used to quickly fill it out in the future by using it on the register." /obj/machinery/orderterminal/Initialize() . = ..() - machine_id = "Idris Ordering Terminal #[SSeconomy.num_financial_terminals++]" + src.LoadComponent(/datum/component/quikpay_shop/orderterminal/food, req_one_access, destinationact) update_icon() /obj/machinery/orderterminal/power_change() @@ -54,152 +54,19 @@ return /obj/machinery/orderterminal/attack_hand(var/mob/user) - ui_interact(user) - -/obj/machinery/orderterminal/ui_interact(mob/user, var/datum/tgui/ui) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "OrderTerminal", "Idris Ordering Terminal", 450, 450) - ui.open() - -/obj/machinery/orderterminal/proc/print_receipt() // Print the receipt followed by the order ticket - var/obj/item/paper/notepad/receipt/R = new(usr.loc) - var/receiptname = "Receipt: [machine_id]" - R.set_content_unsafe(receiptname, receipt, sum) - stamp_receipt(R) - // And now we do it but for the ticket. - var/obj/item/paper/notepad/receipt/T = new(usr.loc) - var/tickettname = "Order ticket: [ticket_number]" - ticket_number++ - T.set_content_unsafe(tickettname, ticket, sum) - stamp_receipt(T) - -/obj/machinery/orderterminal/proc/stamp_receipt(obj/item/paper/R) // Stamps the papers, made into a proc to avoid copy pasting too much - var/image/stampoverlay = image('icons/obj/bureaucracy.dmi') - stampoverlay.icon_state = "paper_stamp-hop" - if(!R.stamped) - R.stamped = new - R.stamped += /obj/item/stamp - R.AddOverlays(stampoverlay) - R.stamps += "
    This paper has been stamped by the Idris Ordering Terminal." - R.ripped = TRUE + if(stat & NOPOWER) + balloon_alert(user, "no power") + return + var/datum/component/quikpay_shop/orderterminal/food/qp_shop = src.GetComponent(/datum/component/quikpay_shop/orderterminal/food) + if(!qp_shop) + return + qp_shop.ui_interact(user) /obj/machinery/orderterminal/attackby(obj/item/attacking_item, mob/user) - var/obj/item/card/id/I = attacking_item.GetID() - if (!I) + if(stat & NOPOWER) + balloon_alert(user, "no power") return - if (!istype(attacking_item)) + var/datum/component/quikpay_shop/orderterminal/food/qp_shop = src.GetComponent(/datum/component/quikpay_shop/orderterminal/food) + if(!qp_shop) return - - else if (confirmorder) - var/transaction_amount = sum - var/transaction_purpose = "Idris Ordering Terminal order." - var/transaction_terminal = machine_id - if(sum > 0) // it will just get denied if the order is 0 credits. We still need the id regardless for the name - var/transaction = SSeconomy.transfer_money(I.associated_account_number, SSeconomy.get_department_account(destinationact)?.account_number,transaction_purpose,transaction_terminal,transaction_amount,null,usr) - if(transaction) - to_chat(user,"[icon2html(src, user)][transaction].") - else - playsound(src, 'sound/machines/chime.ogg', 50, 1) - src.visible_message("[icon2html(src, viewers(get_turf(src)))] \The [src] chimes.") - ticket += "
    Customer: [I.registered_name]" - receipt += "
    Customer: [I.registered_name]" - print_receipt() - clear_order() - -/obj/machinery/orderterminal/ui_data(mob/user) - var/list/data = list() - - data["items"] = items - data["buying"] = buying - data["sum"] = sum - data["new_item"] = new_item - data["new_price"] = new_price - data["editmode"] = editmode - data["destinationact"] = destinationact - - return data - -/obj/machinery/orderterminal/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) - . = ..() - if(.) - return - - switch(action) - if("add") - if(!editmode) - to_chat(usr, SPAN_NOTICE("You don't have access to use this option.")) - return FALSE - items += list(list("name" = new_item, "price" = new_price)) - items_to_price[new_item] = new_price - . = TRUE - - if("remove") - if(!editmode) - to_chat(usr, SPAN_NOTICE("You don't have access to use this option.")) - return FALSE - items -= params["remove"] - items_to_price -= params["remove"] - . = TRUE - - if("buy") - for(var/list/L in buying) - if(L["name"] == params["buying"]) - L["amount"]++ - return TRUE - buying += list(list("name" = params["buying"], "amount" = params["amount"])) - . = TRUE - - if("removal") - for(var/list/L in buying) - if(L["name"] == params["removal"]) - if(L["amount"] > 1) - L["amount"]-- - else - buying -= L - . = TRUE - - if("clear") - clear_order() - . = TRUE - - if("set_new_price") - new_price = params["set_new_price"] - . = TRUE - - if("set_new_item") - new_item = params["set_new_item"] - . = TRUE - - if("confirm") - confirmorder = TRUE - receipt += "
    Idris Food Terminal Receipt

    " - ticket += "
    Idris Food Terminal Ticket

    " - for(var/list/bought_item in buying) - var/item_name = bought_item["name"] - var/item_amount = bought_item["amount"] - var/item_price = items_to_price[item_name] - sum += item_price - - receipt += "[name]: [item_name] x[item_amount] at [item_price]电 each
    " - ticket += "[name]: [item_name] x[item_amount] at [item_price]电 each
    " - receipt += "
    Total: [sum]电" - ticket += "
    Total: [sum]电" - sum = sum - . = TRUE - - if("locking") - var/obj/item/card/id/I = usr.GetIdCard() - if(!istype(I)) - return - if(check_access(I)) - editmode = !editmode - to_chat(usr, SPAN_NOTICE("Device [editmode ? "un" : ""]locked.")) - . = TRUE - -/obj/machinery/orderterminal/proc/clear_order() - buying.Cut() - sum = 0 - receipt = "" - ticket = "" - confirmorder = FALSE + qp_shop.interact_object(attacking_item, user) diff --git a/code/modules/economy/quikpay.dm b/code/modules/economy/quikpay.dm index a3c3c01c667..3e29362b030 100644 --- a/code/modules/economy/quikpay.dm +++ b/code/modules/economy/quikpay.dm @@ -8,36 +8,31 @@ item_state = "electronic" w_class = WEIGHT_CLASS_SMALL slot_flags = SLOT_BELT - var/machine_id = "" - var/list/items = list() - var/list/items_to_price = list() - var/list/buying = list() - var/new_item = "" - var/new_price = 0 - var/sum = 0 - var/editmode = FALSE - var/receipt = "" var/destinationact = "Service" - var/shop_name = "Quikpay" + var/shop_name + req_one_access = list(ACCESS_BAR, ACCESS_GALLEY, ACCESS_CARGO) + +/obj/item/quikpay/mechanics_hints(mob/user, distance, is_adjacent) + . += ..() + . += "Items can be paid for with id cards or charge cards, and a receipt will be printed." + . += "The quikpay can print a paper which can be used to quickly fill it out in the future by using it on the register." /obj/item/quikpay/Initialize() . = ..() - machine_id = "[station_name()] Idris Quik-Pay #[SSeconomy.num_financial_terminals++]" + src.LoadComponent(/datum/component/quikpay_shop/quikpay, req_one_access, destinationact) //create a short manual as well var/obj/item/paper/R = new(src.loc) R.name = "Quik And Easy: How to make a transaction" R.info += "Quik-Pay setup:
    " - R.info += "
    1. Remember your access code included on the paper that is included with your device
    2. " R.info += "
    3. Unlock it to be able to add items to the menu
    4. " - R.info += "
    5. Add items to the menu by typing the item name and its price
    " + R.info += "
  • Add items to the menu by typing the item name and its price, optionally include a category
  • " R.info += "When starting a new transaction:
    " R.info += "
    1. Have the customer enter the amount of the item they want and then confirm the purchase.
    2. " R.info += "
    3. Allow them to review the sum.
    4. " R.info += "
    5. Have them swipe their card to pay for the items.
    " - //stamp the paper var/image/stampoverlay = image('icons/obj/bureaucracy.dmi') stampoverlay.icon_state = "paper_stamp-cent" @@ -50,238 +45,24 @@ R.AddOverlays(stampoverlay) R.stamps += "
    This paper has been stamped by the Executive Officer's desk." -/obj/item/quikpay/AltClick(var/mob/user) - var/obj/item/card/id/I = user.GetIdCard() - if(istype(I) && (ACCESS_HEADS in I.access)) - editmode = TRUE - to_chat(user, SPAN_NOTICE("Command access granted.")) - SStgui.update_uis(src) - -/obj/item/quikpay/proc/print_receipt() - var/obj/item/paper/notepad/receipt/R = new(usr.loc) - var/receiptname = "Receipt: [machine_id]" - R.set_content_unsafe(receiptname, receipt, sum) - - //stamp the paper - var/image/stampoverlay = image('icons/obj/bureaucracy.dmi') - stampoverlay.icon_state = "paper_stamp-hop" - if(!R.stamped) - R.stamped = new - R.stamped += /obj/item/stamp - R.AddOverlays(stampoverlay) - R.stamps += "
    This paper has been stamped by the Quik-Pay device." - R.ripped = TRUE - usr.put_in_any_hand_if_possible(R) - /obj/item/quikpay/attackby(obj/item/attacking_item, mob/user) - if(istype(attacking_item, /obj/item/paper)) - read_paper_list(attacking_item, user) + . = ..() + var/datum/component/quikpay_shop/quikpay/qp_shop = src.GetComponent(/datum/component/quikpay_shop/quikpay) + if(!qp_shop) return - if (istype(attacking_item, /obj/item/spacecash/ewallet)) - var/obj/item/spacecash/ewallet/E = attacking_item - var/transaction_amount = sum - var/transaction_purpose = "[destinationact] Payment" - var/transaction_terminal = machine_id - - if(transaction_amount <= E.worth) - audible_message(SPAN_NOTICE("[icon2html(src, viewers(get_turf(src)))] \The [src] chimes.")) - playsound(src, 'sound/machines/chime.ogg', 50, 1) - - SSeconomy.charge_to_account(SSeconomy.get_department_account(destinationact)?.account_number, E.owner_name, transaction_purpose, transaction_terminal, transaction_amount) - E.worth -= transaction_amount - print_receipt() - sum = 0 - receipt = "" - to_chat(user, SPAN_NOTICE("Transaction completed, please return to the home screen.")) - else if (transaction_amount > E.worth) - to_chat(user, SPAN_WARNING("[icon2html(src, user)]\The [E] doesn't have that much money!")) - return - - var/obj/item/card/id/I = attacking_item.GetID() - if (!istype(attacking_item)) - return - - var/transaction_amount = sum - var/transaction_purpose = "[destinationact] Payment" - var/transaction_terminal = machine_id - - var/transaction = SSeconomy.transfer_money(I.associated_account_number, SSeconomy.get_department_account(destinationact)?.account_number,transaction_purpose,transaction_terminal,transaction_amount,null,usr) - - if(transaction) - to_chat(user, SPAN_NOTICE("[icon2html(src, user)][transaction].")) - else - audible_message(SPAN_NOTICE("[icon2html(src, viewers(get_turf(src)))] \The [src] chimes.")) - playsound(src, 'sound/machines/chime.ogg', 50, 1) - print_receipt() - sum = 0 - receipt = "" - to_chat(user, SPAN_NOTICE("Transaction completed, please return to the home screen.")) - -/obj/item/quikpay/proc/read_paper_list(obj/item/paper/R, mob/user) - if(!editmode) - balloon_alert(user, "device locked!") - return FALSE - var/result = read_paper_price_list(R) - for(var/item in result) - items += list(list("name" = item["name"], "price" = item["price"])) - items_to_price[item["name"]] += item["price"] - -/obj/item/quikpay/proc/print_price(mob/user) - return print_price_to_paper(shop_name, items, loc, user) + qp_shop.interact_object(attacking_item, user) /obj/item/quikpay/attack_self(var/mob/user) - ui_interact(user) - -/obj/item/quikpay/ui_interact(mob/user, datum/tgui/ui) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "QuikPay", "Idris Quik-Pay", 550, 550) - ui.open() - -/obj/item/quikpay/ui_data(var/mob/user) - var/list/data = list() - - data["items"] = items - data["buying"] = buying - data["sum"] = sum - data["new_item"] = new_item - data["new_price"] = new_price - data["editmode"] = editmode - data["destinationact"] = destinationact - - return data - -/obj/item/quikpay/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) . = ..() - if(.) + var/datum/component/quikpay_shop/quikpay/qp_shop = src.GetComponent(/datum/component/quikpay_shop/quikpay) + if(!qp_shop) return - - switch(action) - if("add") - if(!editmode) - balloon_alert(usr, "device locked!") - return FALSE - - items += list(list("name" = new_item, "price" = new_price)) - items_to_price[new_item] = new_price - . = TRUE - - if("remove") - if(!editmode) - balloon_alert(usr, "device locked!") - return FALSE - var/index = 0 - for(var/list/L in items) - index++ - if(L["name"] == params["removing"]) - items.Cut(index, index+1) - . = TRUE - - if("set_new_price") - new_price = params["set_new_price"] - . = TRUE - - if("set_new_item") - new_item = params["set_new_item"] - . = TRUE - - if("clear") - clear_order() - . = TRUE - - if("buy") - for(var/list/L in buying) - if(L["name"] == params["buying"]) - L["amount"]++ - return TRUE - buying += list(list("name" = params["buying"], "amount" = params["amount"], "price" = items_to_price[params["buying"]])) - - if("removal") - var/index = 0 - for(var/list/L in buying) - index++ - if(L["name"] == params["removal"]) - if(L["amount"] > 1) - L["amount"]-- - else - buying.Cut(index, index+1) - . = TRUE - - if("confirm") - // Ensuring it is clear, in case the button is clicked multiple times - receipt = "" - sum = 0 - var/obj/item/card/id/id_card = usr.GetIdCard() - var/cashier = id_card? id_card.registered_name : "Unknown" - receipt = "

    [shop_name] receipt

    Today's date: [worlddate2text()]
    Cashier: [cashier]

    Purchased items:
    Total: [sum]电
    " - playsound(src, 'sound/machines/ping.ogg', 25, 1) - audible_message(SPAN_NOTICE("[icon2html(src, viewers(get_turf(src)))] \The [src] pings.")) - . = TRUE - - if("locking") - if(editmode) - editmode = FALSE - balloon_alert(usr, "device locked!") - else - if(!editmode) - var/obj/item/card/id/I = usr.GetIdCard() - if(!istype(I)) - return - if(check_access(I)) - editmode = !editmode - to_chat(usr, SPAN_NOTICE("Device [editmode ? "un" : ""]locked.")) - . = TRUE - - if("accountselect") - if(!editmode) - balloon_alert(usr, "device locked!") - return FALSE - - var/dest = tgui_input_list(usr, "What account would you like to select?", "Destination Account", assoc_to_keys(SSeconomy.department_accounts)) - if(!dest) - return FALSE - destinationact = dest - . = TRUE - - if("print_dsv") - if(!editmode) - balloon_alert(usr, "device locked!") - return FALSE - print_price(usr) - . = TRUE - -/obj/item/quikpay/proc/clear_order() - buying.Cut() - sum = 0 - receipt = "" + qp_shop.ui_interact(user) /obj/item/quikpay/afterattack(atom/target, mob/user, proximity) if (!proximity) return - if (!istype(target, /obj)) + + var/datum/component/quikpay_shop/quikpay/qp_shop = src.GetComponent(/datum/component/quikpay_shop/quikpay) + if(!qp_shop) return - if (!editmode) - to_chat(user, SPAN_NOTICE("Unlock \the [src] to add items.")) - return - - var/obj/O = target - var/name_guess = O.name - var/price_guess = 0 - - price_guess = text2num(sanitizeSafe( tgui_input_text(user, "Set price for [name_guess]:", "QuikPay", 0, 10), 10)) - if(isnull(price_guess) || price_guess == 0) - return - price_guess = max(0, round(price_guess, 0.01)) - - items += list(list("name" = "[name_guess]", "price" = price_guess)) - items_to_price[name_guess] = price_guess - - to_chat(user, SPAN_NOTICE("[src]: added '[name_guess]' for [price_guess].")) + qp_shop.add_item(target, user) diff --git a/html/changelogs/CommissaryChanges.yml b/html/changelogs/CommissaryChanges.yml new file mode 100644 index 00000000000..743518a6308 --- /dev/null +++ b/html/changelogs/CommissaryChanges.yml @@ -0,0 +1,13 @@ +author: TheGreyWolf + +delete-after: True + +changes: + - bugfix: "Fixed that the quikpay and cash register prices could be wrong." + - rscadd: "The commissary register now has categories." + - refactor: "Changed the commissary and quikpay to rely on a component, making them easier to maintan and ensuring they function almost identical." + - rscadd: "The commissary now has a wall terminal, that can be enabled by hangar technicians." + - bugfix: "The noticeboard in operations is now properly on one side of the wall, instead of on the wall turf itself." + - rscadd: "The food and drink fridges in the commissary can now be renamed." + - rscadd: "The shelves in the commissary now has a message when an item are taken from them." + - rscadd: "The quick-e-meals vendor was readded behind the café." diff --git a/icons/obj/machinery/wall/terminals.dmi b/icons/obj/machinery/wall/terminals.dmi index 41a5b5fe63b..08286b10cae 100644 Binary files a/icons/obj/machinery/wall/terminals.dmi and b/icons/obj/machinery/wall/terminals.dmi differ diff --git a/maps/sccv_horizon/sccv_horizon.dmm b/maps/sccv_horizon/sccv_horizon.dmm index fce8db4516b..f5dec896418 100644 --- a/maps/sccv_horizon/sccv_horizon.dmm +++ b/maps/sccv_horizon/sccv_horizon.dmm @@ -1304,8 +1304,10 @@ /obj/effect/floor_decal/corner/dark_green{ dir = 10 }, -/obj/structure/extinguisher_cabinet/south, -/obj/machinery/light/floor, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/green{ + icon_state = "1-2" + }, /turf/simulated/floor/tiled, /area/horizon/hallway/primary/deck_2/central) "agD" = ( @@ -1322,8 +1324,10 @@ /turf/simulated/floor/tiled/dark, /area/horizon/storage/eva) "agL" = ( -/obj/structure/closet/crate/commissary, -/turf/simulated/floor/tiled/dark/full, +/obj/effect/floor_decal/spline/plain/lime{ + dir = 9 + }, +/turf/simulated/floor/tiled/dark, /area/horizon/operations/commissary) "agP" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ @@ -1343,6 +1347,7 @@ /area/horizon/hangar/intrepid) "agU" = ( /obj/machinery/smartfridge/tradeshelf/clothing, +/obj/machinery/firealarm/west, /turf/simulated/floor/tiled/full, /area/horizon/operations/commissary) "agV" = ( @@ -3465,10 +3470,21 @@ /turf/unsimulated/floor/plating, /area/antag/mercenary) "auR" = ( -/obj/structure/table/rack/retail_shelf, -/obj/machinery/light, -/turf/simulated/floor/tiled/full, -/area/horizon/operations/commissary) +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + icon_state = "pipe-c" + }, +/obj/structure/cable/green{ + icon_state = "2-8" + }, +/obj/structure/lattice/catwalk/indoor/grate, +/turf/simulated/floor/plating, +/area/horizon/hallway/primary/deck_2/central) "auT" = ( /obj/structure/platform/ledge{ dir = 1 @@ -4906,6 +4922,20 @@ }, /turf/simulated/open, /area/horizon/maintenance/deck_2/main/starboard) +"aEx" = ( +/obj/structure/table/reinforced/steel, +/obj/machinery/door/window/desk/northright{ + req_one_access = list(26,29,31,48,67,35,25,28,37) + }, +/obj/machinery/door/firedoor{ + req_one_access = list(24,11,67,73) + }, +/obj/machinery/door/blast/shutters{ + dir = 2; + id = "horizon_commissary_desk" + }, +/turf/simulated/floor/tiled/dark/full, +/area/horizon/operations/commissary) "aEz" = ( /obj/effect/floor_decal/corner/dark_green{ dir = 1 @@ -6913,15 +6943,13 @@ /turf/simulated/floor/tiled, /area/horizon/operations/mining_main/refinery) "aRD" = ( -/obj/structure/bed/stool/chair{ - dir = 4 +/obj/structure/lattice/catwalk/indoor/grate/dark, +/obj/structure/cable/green{ + icon_state = "1-2" }, -/obj/machinery/alarm/west, -/obj/effect/floor_decal/corner/dark_blue{ - dir = 9 - }, -/turf/simulated/floor/tiled, -/area/horizon/security/lobby) +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/plating, +/area/horizon/maintenance/deck_2/service/port) "aRE" = ( /obj/structure/heavy_vehicle_frame, /obj/machinery/mech_recharger, @@ -7531,10 +7559,11 @@ /obj/machinery/light{ dir = 1 }, -/obj/effect/floor_decal/corner/dark_blue{ - dir = 5 - }, /obj/structure/reagent_dispensers/water_cooler, +/obj/effect/floor_decal/corner/dark_blue/full{ + dir = 8 + }, +/obj/machinery/newscaster/west, /turf/simulated/floor/tiled, /area/horizon/security/lobby) "aVW" = ( @@ -12763,10 +12792,11 @@ /turf/unsimulated/floor, /area/centcom/legion/hangar5) "bFt" = ( -/obj/machinery/power/apc/east, -/obj/structure/disposalpipe/segment, -/obj/structure/cable/green, /obj/structure/lattice/catwalk/indoor/grate/dark, +/obj/structure/disposalpipe/segment, +/obj/machinery/light/small/emergency{ + dir = 4 + }, /turf/simulated/floor/plating, /area/horizon/maintenance/deck_2/service/port) "bFC" = ( @@ -20990,6 +21020,16 @@ /turf/simulated/floor, /area/tdome/tdome1) "cMN" = ( +/obj/structure/bed/stool/chair{ + dir = 4 + }, +/obj/effect/floor_decal/corner/dark_blue{ + dir = 9 + }, +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 4 + }, +/obj/machinery/alarm/west, /turf/simulated/floor/tiled, /area/horizon/security/lobby) "cMP" = ( @@ -26924,18 +26964,20 @@ /turf/simulated/floor/airless, /area/horizon/hangar/operations) "dyf" = ( -/obj/structure/bed/stool/chair{ +/obj/machinery/power/apc/east, +/obj/structure/cable/green{ + icon_state = "0-8" + }, +/obj/effect/floor_decal/spline/plain/lime{ dir = 4 }, -/obj/structure/cable/green{ - icon_state = "0-4" +/obj/structure/table/reinforced/steel, +/obj/item/toy/comic/azmarian/issue_1, +/obj/item/toy/comic/inspector{ + pixel_x = -4 }, -/obj/effect/floor_decal/corner/dark_blue{ - dir = 9 - }, -/obj/machinery/power/apc/low/west, -/turf/simulated/floor/tiled, -/area/horizon/security/lobby) +/turf/simulated/floor/tiled/dark, +/area/horizon/operations/commissary) "dyi" = ( /obj/structure/tank_wall{ icon_state = "m-10" @@ -30431,10 +30473,19 @@ /turf/simulated/floor/tiled, /area/horizon/rnd/hallway/secondary) "dWE" = ( -/obj/random/junk, +/obj/machinery/door/airlock/maintenance{ + dir = 1; + req_one_access = list(12,26,29,31,48,67,35,25,28,37) + }, /obj/structure/disposalpipe/segment, -/obj/structure/lattice/catwalk/indoor/grate/dark, -/turf/simulated/floor/plating, +/obj/structure/cable/green{ + icon_state = "1-2" + }, +/obj/effect/floor_decal/industrial/hatch_door/yellow{ + dir = 8 + }, +/obj/machinery/door/firedoor, +/turf/simulated/floor/tiled/dark/full, /area/horizon/maintenance/deck_2/service/port) "dWF" = ( /obj/machinery/space_heater, @@ -30830,17 +30881,16 @@ /turf/simulated/floor, /area/horizon/maintenance/deck_3/cafe) "dZA" = ( -/obj/machinery/door/firedoor{ - req_one_access = list(24,11,67,73); - dir = 4 +/obj/effect/floor_decal/spline/plain/lime{ + dir = 6 }, -/obj/effect/floor_decal/industrial/hatch_door/yellow, -/obj/machinery/door/airlock/maintenance{ - dir = 4; - name = "Commissary Maintenance"; - req_one_access = list(25,26,28,29,31,35,37,48,67) +/obj/structure/noticeboard{ + desc = "A board for uncovering hidden conspiracies."; + name = "corkboard"; + pixel_x = 32 }, -/turf/simulated/floor/tiled/dark/full, +/obj/item/modular_computer/console/preset/supply, +/turf/simulated/floor/tiled/dark, /area/horizon/operations/commissary) "dZB" = ( /obj/random/tech_supply, @@ -31501,10 +31551,7 @@ /obj/effect/floor_decal/corner/dark_green{ dir = 10 }, -/obj/structure/disposalpipe/segment, -/obj/structure/cable/green{ - icon_state = "1-2" - }, +/obj/machinery/light/floor, /turf/simulated/floor/tiled, /area/horizon/hallway/primary/deck_2/central) "edo" = ( @@ -49334,9 +49381,11 @@ /area/horizon/operations/warehouse) "gAF" = ( /obj/machinery/light, -/obj/effect/floor_decal/corner/dark_blue{ - dir = 10 +/obj/structure/bed/stool/chair{ + dir = 4 }, +/obj/effect/floor_decal/corner/dark_blue/full, +/obj/machinery/firealarm/west, /turf/simulated/floor/tiled, /area/horizon/security/lobby) "gAJ" = ( @@ -52972,12 +53021,16 @@ /turf/simulated/floor/tiled, /area/horizon/engineering/hallway/aft) "hab" = ( -/obj/structure/cable/green{ - icon_state = "4-8" +/obj/effect/floor_decal/corner/dark_blue{ + dir = 9 }, -/obj/machinery/atmospherics/unary/vent_scrubber/on{ +/obj/structure/bed/stool/chair{ dir = 4 }, +/obj/structure/cable/green{ + icon_state = "0-4" + }, +/obj/machinery/power/apc/low/west, /turf/simulated/floor/tiled, /area/horizon/security/lobby) "hap" = ( @@ -53907,6 +53960,9 @@ /obj/effect/floor_decal/corner/dark_green{ dir = 9 }, +/obj/machinery/light/floor{ + dir = 8 + }, /turf/simulated/floor/tiled, /area/horizon/operations/commissary) "hgn" = ( @@ -59280,10 +59336,7 @@ /turf/simulated/floor/tiled/dark/full, /area/horizon/security/armoury) "hPw" = ( -/obj/machinery/alarm/east, -/obj/structure/disposalpipe/segment, -/obj/structure/lattice/catwalk/indoor/grate/dark, -/turf/simulated/floor/plating, +/turf/simulated/wall, /area/horizon/maintenance/deck_2/service/port) "hPx" = ( /obj/machinery/light{ @@ -67028,10 +67081,6 @@ /turf/simulated/floor/tiled, /area/horizon/hangar/operations) "iSm" = ( -/obj/structure/disposalpipe/segment{ - icon_state = "pipe-c" - }, -/obj/structure/lattice/catwalk/indoor/grate/dark, /turf/simulated/floor/plating, /area/horizon/maintenance/deck_2/service/port) "iSo" = ( @@ -72391,20 +72440,8 @@ /turf/simulated/floor/tiled, /area/horizon/hangar/intrepid) "jEi" = ( -/obj/machinery/door/firedoor, -/obj/structure/disposalpipe/segment, -/obj/machinery/door/airlock/maintenance{ - dir = 1; - req_one_access = list(12,26,29,31,48,67,35,25,28,37) - }, -/obj/structure/cable/green{ - icon_state = "1-2" - }, -/obj/effect/floor_decal/industrial/hatch_door/yellow{ - dir = 8 - }, -/turf/simulated/floor/tiled/dark/full, -/area/horizon/hallway/primary/deck_2/central) +/turf/simulated/wall/r_wall, +/area/horizon/operations/commissary) "jEl" = ( /obj/structure/lattice, /obj/machinery/atmospherics/pipe/manifold/visible/red, @@ -75021,13 +75058,6 @@ }, /turf/simulated/floor/wood, /area/merchant_station/warehouse) -"jWp" = ( -/obj/machinery/light{ - dir = 8 - }, -/obj/machinery/smartfridge/tradeshelf/food, -/turf/simulated/floor/tiled/full, -/area/horizon/operations/commissary) "jWv" = ( /obj/structure/cable/green{ icon_state = "4-8" @@ -75199,35 +75229,10 @@ /turf/simulated/floor/plating, /area/horizon/operations/machinist) "jXw" = ( -/obj/effect/floor_decal/spline/plain/lime{ - dir = 5 - }, -/obj/machinery/disposal/small/west, -/obj/structure/closet/crate, -/obj/item/storage/box/plasticbag, -/obj/item/storage/box/unique/papersack, -/obj/item/storage/box/unique/papersack, -/obj/item/storage/box/unique/papersack, -/obj/item/storage/box/unique/papersack, -/obj/item/storage/box/unique/papersack, -/obj/item/storage/box/unique/papersack, -/obj/item/storage/box/unique/papersack, -/obj/item/storage/box/unique/papersack, -/obj/item/storage/box/plasticbag, -/obj/item/storage/bag/plasticbag, -/obj/item/storage/bag/plasticbag, -/obj/item/storage/bag/plasticbag, -/obj/item/storage/bag/plasticbag, -/obj/item/storage/bag/plasticbag, -/obj/item/storage/bag/plasticbag, -/obj/item/storage/bag/plasticbag, -/obj/item/storage/bag/plasticbag, -/obj/machinery/power/apc/east, -/obj/structure/disposalpipe/trunk, /obj/structure/cable/green{ - icon_state = "0-2" + icon_state = "2-4" }, -/obj/item/tape_roll, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled/dark, /area/horizon/operations/commissary) "jXA" = ( @@ -76253,12 +76258,13 @@ }, /area/centcom/control) "kep" = ( -/obj/structure/table/rack/retail_shelf, -/obj/item/hand_labeler, -/obj/item/storage/toolbox/mechanical{ - pixel_y = 13 +/obj/effect/floor_decal/industrial/outline/operations, +/obj/machinery/door/window/desk/southleft{ + req_one_access = list(26,29,31,48,67,35,25,28,37) }, -/obj/structure/window/reinforced, +/obj/structure/crate_shelf, +/obj/structure/closet/crate/commissary/resupply, +/obj/structure/closet/crate/commissary, /obj/machinery/door/blast/shutters{ dir = 2; id = "horizon_commissary_desk" @@ -77007,6 +77013,20 @@ }, /turf/simulated/floor/tiled/dark, /area/horizon/rnd/xenoarch/storage) +"kiP" = ( +/obj/structure/table/reinforced/steel, +/obj/machinery/door/window/desk/northleft{ + req_one_access = list(26,29,31,48,67,35,25,28,37) + }, +/obj/machinery/door/firedoor{ + req_one_access = list(24,11,67,73) + }, +/obj/machinery/door/blast/shutters{ + dir = 2; + id = "horizon_commissary_desk" + }, +/turf/simulated/floor/tiled/dark/full, +/area/horizon/operations/commissary) "kiT" = ( /obj/structure/shuttle_part/scc_space_ship{ icon_state = "d3-4-f" @@ -86408,35 +86428,7 @@ /turf/simulated/floor/wood, /area/horizon/repoffice/consular_one) "lrG" = ( -/obj/effect/floor_decal/spline/plain/lime{ - dir = 4 - }, -/obj/machinery/button/remote/airlock{ - dir = 4; - id = "horizon_commissary_door"; - name = "Commissary Door Bolts"; - pixel_x = 22; - specialfunctions = 4; - pixel_y = -2 - }, -/obj/machinery/button/remote/blast_door{ - dir = 4; - id = "horizon_commissary_desk"; - name = "Desk Shutters"; - pixel_x = 22; - pixel_y = 10 - }, -/obj/machinery/button/switch/holosign{ - id = "commissary"; - dir = 4; - pixel_y = 1; - pixel_x = 29 - }, /obj/machinery/hologram/holopad, -/obj/machinery/light_switch/east{ - pixel_x = 29; - pixel_y = 12 - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 10 }, @@ -95438,17 +95430,37 @@ /turf/simulated/floor, /area/horizon/maintenance/deck_3/security/port) "mEq" = ( -/obj/structure/sign/nosmoking_2{ - pixel_x = -32; - pixel_y = -32 +/obj/machinery/light_switch/east{ + pixel_x = 29; + pixel_y = 12 }, -/obj/structure/bed/stool/chair{ +/obj/machinery/button/switch/holosign{ + id = "commissary"; + dir = 4; + pixel_y = 1; + pixel_x = 29 + }, +/obj/machinery/button/remote/airlock{ + dir = 4; + id = "horizon_commissary_door"; + name = "Commissary Door Bolts"; + pixel_x = 22; + specialfunctions = 4; + pixel_y = -2 + }, +/obj/machinery/button/remote/blast_door{ + dir = 4; + id = "horizon_commissary_desk"; + name = "Desk Shutters"; + pixel_x = 22; + pixel_y = 10 + }, +/obj/effect/floor_decal/spline/plain/lime{ dir = 4 }, -/obj/machinery/firealarm/west, -/obj/effect/floor_decal/corner/dark_blue/full, -/turf/simulated/floor/tiled, -/area/horizon/security/lobby) +/obj/structure/table/reinforced/steel, +/turf/simulated/floor/tiled/dark, +/area/horizon/operations/commissary) "mEu" = ( /obj/structure/table/rack, /obj/item/gun/energy/rifle/ionrifle{ @@ -113323,6 +113335,13 @@ /obj/structure/flora/ausbushes/brflowers, /turf/simulated/floor/exoplanet/grass/grove, /area/centcom/shared_dream) +"oXJ" = ( +/obj/effect/floor_decal/corner/dark_green{ + dir = 10 + }, +/obj/structure/extinguisher_cabinet/south, +/turf/simulated/floor/tiled, +/area/horizon/hallway/primary/deck_2/central) "oXL" = ( /obj/structure/railing/mapped{ dir = 4 @@ -115604,6 +115623,12 @@ req_one_access = list(24,11,67,73); dir = 4 }, +/obj/item/paper_bin{ + pixel_y = 2 + }, +/obj/item/pen{ + pixel_y = 1 + }, /turf/simulated/floor/tiled/dark/full, /area/horizon/security/office) "pob" = ( @@ -124403,12 +124428,13 @@ /turf/simulated/floor/airless, /area/horizon/engineering/atmos) "qAt" = ( -/obj/machinery/light{ - dir = 8 - }, /obj/effect/floor_decal/corner/dark_green{ dir = 9 }, +/obj/machinery/commissary_wall_shop{ + dir = 8; + pixel_x = -16 + }, /turf/simulated/floor/tiled, /area/horizon/operations/commissary) "qAB" = ( @@ -124985,10 +125011,10 @@ /turf/simulated/floor/tiled/dark/full, /area/horizon/rnd/xenoarch/hallway/hangar) "qEv" = ( -/obj/effect/floor_decal/spline/plain/lime{ - dir = 9 - }, /obj/machinery/atmospherics/unary/vent_pump/on, +/obj/effect/floor_decal/spline/plain/lime{ + dir = 8 + }, /turf/simulated/floor/tiled/dark, /area/horizon/operations/commissary) "qEE" = ( @@ -125602,19 +125628,12 @@ /turf/simulated/floor/tiled/white, /area/horizon/medical/gen_treatment) "qIo" = ( -/obj/machinery/newscaster/west, -/obj/structure/table/standard, -/obj/item/paper_bin{ - pixel_y = 2 - }, -/obj/item/pen{ - pixel_y = 1 - }, -/obj/effect/floor_decal/corner/dark_blue/full{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/horizon/security/lobby) +/obj/structure/lattice/catwalk/indoor/grate/dark, +/obj/machinery/power/apc/east, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/green, +/turf/simulated/floor/plating, +/area/horizon/maintenance/deck_2/service/port) "qIB" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -127419,6 +127438,9 @@ dir = 8; icon_state = "pipe-c" }, +/obj/machinery/light/floor{ + dir = 4 + }, /turf/simulated/floor/tiled, /area/horizon/operations/commissary) "qUZ" = ( @@ -136305,7 +136327,7 @@ dir = 4 }, /turf/simulated/floor/tiled/dark/full, -/area/horizon/operations/commissary) +/area/horizon/maintenance/deck_2/service/port) "scz" = ( /obj/machinery/atmospherics/pipe/simple/visible/cyan{ dir = 10 @@ -141144,13 +141166,13 @@ /obj/structure/window/reinforced{ dir = 8 }, -/obj/structure/table/reinforced/steel, /obj/item/quikpay{ destinationact = "Operations"; pixel_y = 3; shop_name = "Commissary Quikpay" }, /obj/machinery/power/outlet, +/obj/structure/table/reinforced/steel, /obj/machinery/door/blast/shutters{ dir = 4; id = "horizon_commissary_desk" @@ -147081,13 +147103,18 @@ /turf/simulated/floor/plating, /area/horizon/engineering/drone_fabrication) "twp" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/light/small/emergency{ - dir = 4 +/obj/machinery/alarm/east, +/obj/machinery/disposal/small/west, +/obj/structure/disposalpipe/trunk{ + dir = 8 }, -/obj/structure/lattice/catwalk/indoor/grate/dark, -/turf/simulated/floor/plating, -/area/horizon/maintenance/deck_2/service/port) +/obj/effect/floor_decal/spline/plain/lime{ + dir = 5 + }, +/obj/structure/table/reinforced/steel, +/obj/machinery/firealarm/north, +/turf/simulated/floor/tiled/dark, +/area/horizon/operations/commissary) "twr" = ( /obj/effect/floor_decal/spline/fancy/wood{ dir = 1 @@ -150309,10 +150336,17 @@ /turf/simulated/floor/plating, /area/horizon/maintenance/deck_3/aft/port) "tTn" = ( -/obj/effect/floor_decal/industrial/outline/operations, -/obj/machinery/alarm/east, -/obj/structure/crate_shelf, -/turf/simulated/floor/tiled/dark/full, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, +/obj/effect/floor_decal/spline/plain/lime{ + dir = 1 + }, +/obj/machinery/light/floor{ + dir = 1 + }, +/turf/simulated/floor/tiled/dark, /area/horizon/operations/commissary) "tTp" = ( /obj/machinery/atmospherics/unary/vent_pump/on, @@ -156399,9 +156433,6 @@ /obj/structure/cable/green{ icon_state = "2-8" }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 10 - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 6 }, @@ -158325,11 +158356,9 @@ /turf/simulated/floor/plating, /area/horizon/engineering/atmos/air) "uWA" = ( -/obj/structure/disposalpipe/segment, -/obj/structure/cable/green{ - icon_state = "1-2" - }, /obj/structure/lattice/catwalk/indoor/grate/dark, +/obj/structure/disposalpipe/segment, +/obj/random/junk, /turf/simulated/floor/plating, /area/horizon/maintenance/deck_2/service/port) "uWB" = ( @@ -158864,15 +158893,13 @@ }, /area/centcom/holding) "vaJ" = ( -/obj/effect/floor_decal/spline/plain/lime{ - dir = 6 - }, /obj/machinery/atmospherics/unary/vent_scrubber/on, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/structure/cable/green{ icon_state = "1-2" }, /obj/structure/disposalpipe/segment, +/obj/effect/floor_decal/spline/plain/lime, /turf/simulated/floor/tiled/dark, /area/horizon/operations/commissary) "vaL" = ( @@ -159984,17 +160011,17 @@ /turf/simulated/floor/plating, /area/horizon/maintenance/deck_2/wing/starboard) "vje" = ( -/obj/structure/disposalpipe/segment{ - icon_state = "pipe-c" - }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /obj/structure/cable/green{ - icon_state = "2-8" + icon_state = "4-8" }, /obj/structure/lattice/catwalk/indoor/grate, /turf/simulated/floor/plating, @@ -160830,8 +160857,10 @@ /obj/structure/cable/green{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10 + }, /turf/simulated/floor/tiled, /area/horizon/security/lobby) "voC" = ( @@ -164646,9 +164675,11 @@ }, /area/centcom/specops) "vSV" = ( -/obj/structure/noticeboard, -/turf/simulated/wall, -/area/horizon/operations/office) +/obj/machinery/alarm/east, +/obj/structure/lattice/catwalk/indoor/grate/dark, +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/plating, +/area/horizon/maintenance/deck_2/service/port) "vSZ" = ( /obj/structure/table/rack, /obj/machinery/light, @@ -170950,6 +170981,17 @@ /obj/machinery/light/small/emergency{ dir = 4 }, +/obj/structure/table/rack/folding_table, +/obj/item/deck/cards{ + pixel_x = 6 + }, +/obj/item/material/stool/chair/folding{ + pixel_y = 19 + }, +/obj/item/material/stool/chair/folding{ + pixel_y = 22 + }, +/obj/effect/floor_decal/industrial/outline/grey, /obj/effect/floor_decal/industrial/warning, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor, @@ -178942,16 +178984,7 @@ /area/horizon/maintenance/deck_1/main/interstitial) "xIF" = ( /obj/effect/floor_decal/industrial/outline/grey, -/obj/structure/table/rack/folding_table, -/obj/item/material/stool/chair/folding{ - pixel_y = 22 - }, -/obj/item/material/stool/chair/folding{ - pixel_y = 19 - }, -/obj/item/deck/cards{ - pixel_x = 6 - }, +/obj/machinery/vending/quick_e_meals, /turf/simulated/floor, /area/horizon/maintenance/deck_3/cafe) "xIH" = ( @@ -180727,6 +180760,9 @@ pixel_x = 7 }, /obj/effect/floor_decal/industrial/outline/yellow, +/obj/structure/noticeboard{ + pixel_y = 30 + }, /turf/simulated/floor/tiled, /area/horizon/operations/office) "xUQ" = ( @@ -272211,7 +272247,7 @@ gbk sgk aFJ mKO -vSV +tWP xUO bji twh @@ -282232,7 +282268,7 @@ iKu ccb pdg mSK -jWp +mrm kgE kuV hgh @@ -283266,7 +283302,7 @@ oge pbt qZz aeC -auR +pfa xZE wNA nOR @@ -283516,7 +283552,7 @@ hTg fNg hkQ gst -vGI +kiP agL qEv qne @@ -283773,7 +283809,7 @@ hTg fNg hkQ gst -vGI +aEx tTn jXw lrG @@ -284031,13 +284067,13 @@ dvo sOs qKQ qZz -qZz -qZz -qZz +twp +dyf +mEq dZA qZz scw -qZz +hPw xZE ocO seV @@ -284288,12 +284324,12 @@ fNg vje edn jEi -uWA -bFt -hPw -dWE -twp -gOI +qZz +qZz +qZz +qZz +qZz +iSm ftp xZE xZE @@ -284542,15 +284578,15 @@ kBK nir hTg fNg -kaK +auR agC -icP -icP -icP -icP -icP -icP -iSm +dWE +aRD +qIo +vSV +uWA +bFt +rJN rJN feo rJN @@ -284800,12 +284836,12 @@ rRV mlB fNg kaK -gst -glY -qIo -dyf -aRD -mEq +oXJ +icP +icP +icP +icP +icP icP qKg efg @@ -352896,8 +352932,8 @@ czZ eiJ mfX qfv -tKb xIF +tKb wGM rfH xMK diff --git a/tgui/packages/tgui/interfaces/QuikPay.tsx b/tgui/packages/tgui/interfaces/QuikPay.tsx index b9ec897ecd8..9030db042e2 100644 --- a/tgui/packages/tgui/interfaces/QuikPay.tsx +++ b/tgui/packages/tgui/interfaces/QuikPay.tsx @@ -17,6 +17,7 @@ export type PayData = { buying: ItemBuy[]; new_item: string; new_price: number; + new_category: string; sum: number; editmode: BooleanLike; destinationact: number; @@ -25,6 +26,7 @@ export type PayData = { type Item = { name: string; price: number; + category: string; }; type ItemBuy = { @@ -79,52 +81,72 @@ export const QuikPay = (props, context) => { export const ItemWindow = (props, context) => { const { act, data } = useBackend(context); + const groupedItems = data.items.reduce((groups, item) => { + const category = item.category || 'Uncategorized'; + if (!groups[category]) { + groups[category] = []; + } + groups[category].push(item); + return groups; + }, {}); + + const sortedCategories = Object.keys(groupedItems).sort(); + return (
    -
    - - {data.items.map((item) => ( - - {item.name} - - {item.price.toFixed(2)}电   - - - {!data.editmode ? ( -
    + {groupedItems[category].map((item) => ( + + {item.name} + + {item.price.toFixed(2)}电   + + + {!data.editmode ? (
    -
    + ) : ( + <> +   +
    + ))} + +
    - {' '}