diff --git a/aurorastation.dme b/aurorastation.dme
index 7afbd72766a..65f04fe86fa 100644
--- a/aurorastation.dme
+++ b/aurorastation.dme
@@ -2132,6 +2132,7 @@
#include "code\modules\cooking\plasticbag.dm"
#include "code\modules\cooking\plates.dm"
#include "code\modules\cooking\trays.dm"
+#include "code\modules\cooking\machinery\commissary.dm"
#include "code\modules\cooking\machinery\foodcart.dm"
#include "code\modules\cooking\machinery\gibber.dm"
#include "code\modules\cooking\machinery\icecream.dm"
diff --git a/code/game/objects/structures/urban.dm b/code/game/objects/structures/urban.dm
index a411ecaada2..0e6441534e5 100644
--- a/code/game/objects/structures/urban.dm
+++ b/code/game/objects/structures/urban.dm
@@ -825,7 +825,7 @@ ABSTRACT_TYPE(/obj/structure/stairs/urban/road_ramp)
name = "cash compartment"
/obj/structure/cash_register/mouse_drop_dragged(atom/over, mob/user, src_location, over_location, params)
- if(user == over && ishuman(over))
+ if(user == over && ishuman(over) && storage_compartment)
var/mob/living/carbon/human/H = over
storage_compartment.open(H)
diff --git a/code/modules/cooking/machinery/commissary.dm b/code/modules/cooking/machinery/commissary.dm
new file mode 100644
index 00000000000..3eb5003466a
--- /dev/null
+++ b/code/modules/cooking/machinery/commissary.dm
@@ -0,0 +1,339 @@
+/obj/machinery/smartfridge/tradeshelf
+ name = "cigarette shelf"
+ desc = "A commercialized shelf for cigarettes and associated items."
+ icon_state = "trade_smokes"
+ use_power = POWER_USE_OFF
+ idle_power_usage = 0
+ active_power_usage = 0
+ contents_path = "-cigarettebox"
+ accepted_items = list(/obj/item/storage/box/fancy/cigarettes,
+ /obj/item/storage/chewables,
+ /obj/item/storage/box/fancy/chewables,
+ /obj/item/storage/cigfilters,
+ /obj/item/storage/box/fancy/cigpaper,
+ /obj/item/storage/box/fancy/matches,
+ /obj/item/flame/lighter,
+ /obj/item/clothing/mask/smokable/ecig,
+ /obj/item/reagent_containers/ecig_cartridge
+ )
+ display_tiers = 5
+ display_tier_amt = 3
+
+/obj/machinery/smartfridge/tradeshelf/clothing
+ name = "clothing shelf"
+ desc = "A commercialized shelf for clothing and associated items."
+ icon_state = "trade_clothes"
+ contents_path = "-clothing"
+ accepted_items = list(/obj/item/storage/backpack,
+ /obj/item/storage/belt,
+ /obj/item/clothing
+ )
+ display_tiers = 3
+ display_tier_amt = 5
+
+/obj/machinery/smartfridge/tradeshelf/food
+ name = "food and drinks shelf"
+ desc = "A commercialized shelf for food and drinks."
+ icon_state = "trade_food"
+ contents_path = "-edible"
+ use_power = POWER_USE_IDLE
+ idle_power_usage = 5
+ active_power_usage = 100
+ cooling = TRUE
+ accepted_items = list(/obj/item/reagent_containers/food,
+ /obj/item/storage/box/fancy/cookiesnack
+ )
+ display_tiers = 4
+ display_tier_amt = 5
+
+/obj/machinery/smartfridge/tradeshelf/toy
+ name = "toy shelf"
+ desc = "A commercialized shelf for toys and associated items."
+ icon_state = "trade_toys"
+ contents_path = "-toy"
+ accepted_items = list(/obj/item/toy,
+ /obj/item/lipstick,
+ /obj/item/device/paicard,
+ /obj/item/device/camera,
+ /obj/item/device/synthesized_instrument,
+ /obj/item/storage/box/unique/snappops,
+ /obj/item/haircomb,
+ /obj/item/storage/box/fancy/crayons,
+ /obj/item/melee/dinograbber,
+ /obj/item/device/laser_pointer,
+ /obj/item/deck,
+ /obj/item/storage/pill_bottle/dice
+ )
+ display_tiers = 4
+ display_tier_amt = 5
+
+// -------------------------------------------------
+/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
+ storage_type = null
+
+/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."
+ . += "Items can be paid for with id cards, charge cards or physical credits, and a receipt will be printed."
+
+/obj/structure/cash_register/commissary/Initialize()
+ . = ..()
+ machine_id = "[station_name()] Idris Quik-Pay Register #[SSeconomy.num_financial_terminals++]"
+
+/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)
+ 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 cash: [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/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-cent"
+ 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)
+
+/obj/structure/cash_register/commissary/attackby(obj/item/attacking_item, mob/user)
+ 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
+ playsound(src, 'sound/machines/chime.ogg', 50, 1)
+ visible_message(SPAN_NOTICE("[icon2html(src, viewers(get_turf(src)))] \The [src] chimes."))
+ visible_message("\The [user] swipes a card on \the [src]." )
+ 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)
+ playsound(src, 'sound/machines/chime.ogg', 50, 1)
+ src.visible_message(SPAN_NOTICE("[icon2html(src, viewers(get_turf(src)))] \The [src] chimes."))
+
+ 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]." )
+ 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/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", 400, 400)
+ 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(.)
+ return
+ switch(action)
+ if("add")
+ if(!editmode)
+ to_chat(usr, SPAN_WARNING("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)
+ to_chat(usr, SPAN_NOTICE("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"]))
+
+ if("removal")
+ var/index = 0
+ for(var/list/L in buying)
+ index++
+ if(L["name"] == params["removal"])
+ if(L["amount"] > 1)
+ L["amount"]--
+ else
+ items.Cut(index, index+1)
+ . = TRUE
+
+ if("confirm")
+ 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]
+
+ receipt += "[item_name]: x[item_amount] at [item_price]cr each
"
+ sum += item_price * item_amount
+ receipt += "Total: [sum]cr
"
+ . = TRUE
+
+ if("locking")
+ if(editmode)
+ editmode = FALSE
+ to_chat(usr, SPAN_NOTICE("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)
+ to_chat(usr, SPAN_WARNING("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
+ return TRUE
+
+/obj/structure/cash_register/commissary/proc/clear_order()
+ buying.Cut()
+ sum = 0
+ receipt = ""
diff --git a/code/modules/cooking/machinery/smartfridge.dm b/code/modules/cooking/machinery/smartfridge.dm
index 62b1e05237e..1c7c3334c3d 100644
--- a/code/modules/cooking/machinery/smartfridge.dm
+++ b/code/modules/cooking/machinery/smartfridge.dm
@@ -30,6 +30,8 @@
// what icon overlay to use to show its contents - set to NULL if no contents.
var/contents_path = "-plant"
+ var/display_tiers = 3
+ var/display_tier_amt = 25
component_types = list(
/obj/item/circuitboard/smartfridge,
@@ -284,17 +286,14 @@
AddOverlays("[initial(icon_state)]-panel")
var/list/shown_contents = contents - component_parts
if(contents_path && shown_contents.len > 0)
- var/contents_icon_state
- switch(shown_contents.len)
- if(1 to 25)
- contents_icon_state = "-1"
- if(26 to 50)
- contents_icon_state = "-2"
- if(50 to INFINITY)
- contents_icon_state = "-3"
+ var/contents_icon_state = change_display(shown_contents.len - 1)
AddOverlays("[initial(icon_state)][contents_path][contents_icon_state]")
AddOverlays("[initial(icon_state)]-glass[(stat & BROKEN) ? "-broken" : ""]")
+/obj/machinery/smartfridge/proc/change_display(var/length)
+ var/tier = clamp((floor(length / display_tier_amt) + 1), 1, display_tiers)
+ return "-[num2text(tier)]"
+
/*******************
* Item Adding
********************/
diff --git a/code/modules/economy/quikpay.dm b/code/modules/economy/quikpay.dm
index 148fe5f3bac..bef6aba4acc 100644
--- a/code/modules/economy/quikpay.dm
+++ b/code/modules/economy/quikpay.dm
@@ -152,9 +152,11 @@
if(!editmode)
to_chat(usr, SPAN_NOTICE("Device locked."))
return FALSE
-
- items -= params["remove"]
- items_to_price -= params["remove"]
+ 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")
@@ -214,24 +216,34 @@
to_chat(usr, SPAN_WARNING("Device locked."))
return FALSE
- switch(input("What account would you like to select?", "Destination Account") as null|anything in list("Service", "Operations", "Command", "Medical", "Security", "Engineering", "Science"))
- if("Service")
- destinationact = "Service"
- if("Operations")
- destinationact = "Operations"
- if("Command")
- destinationact = "Command"
- if("Medical")
- destinationact = "Medical"
- if("Security")
- destinationact = "Security"
- if("Engineering")
- destinationact = "Engineering"
- if("Science")
- destinationact = "Science"
- . = TRUE
+ 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
+ return TRUE
/obj/item/device/quikpay/proc/clear_order()
buying.Cut()
sum = 0
receipt = ""
+
+/obj/item/device/quikpay/afterattack(atom/target, mob/user, proximity)
+ if (!proximity) return
+ if (!istype(target, /obj))
+ 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))
+
+ to_chat(user, SPAN_NOTICE("[src]: added '[name_guess]' for [price_guess]."))
diff --git a/html/changelogs/CommissaryUpgrades.yml b/html/changelogs/CommissaryUpgrades.yml
new file mode 100644
index 00000000000..4e60fa8a2a7
--- /dev/null
+++ b/html/changelogs/CommissaryUpgrades.yml
@@ -0,0 +1,9 @@
+author: TheGreyWolf, Tomixcomics
+
+delete-after: True
+
+changes:
+ - rscadd: "The commissary now has specific storage shelves for smokes, clothes, toys and food and drinks."
+ - rscadd: "The commissary has acquired a cash register to handle transactions with."
+ - rscadd: "The quik-pay can now add items by clicking on them while unlocked."
+ - bugfix: "The quik-pay can now remove items that has been input on it."
diff --git a/icons/obj/machinery/smartfridge.dmi b/icons/obj/machinery/smartfridge.dmi
index 67723acff5d..57f69f2d154 100644
Binary files a/icons/obj/machinery/smartfridge.dmi and b/icons/obj/machinery/smartfridge.dmi differ
diff --git a/maps/sccv_horizon/sccv_horizon.dmm b/maps/sccv_horizon/sccv_horizon.dmm
index a33ffb6443f..7779545441c 100644
--- a/maps/sccv_horizon/sccv_horizon.dmm
+++ b/maps/sccv_horizon/sccv_horizon.dmm
@@ -15850,7 +15850,6 @@
/turf/simulated/floor/tiled/full,
/area/horizon/rnd/eva)
"clw" = (
-/obj/machinery/vending/cigarette,
/obj/structure/disposalpipe/segment{
dir = 4
},
@@ -15861,6 +15860,7 @@
dir = 4
},
/obj/effect/floor_decal/industrial/hatch/operations,
+/obj/machinery/vending/cola,
/turf/simulated/floor/tiled/full,
/area/horizon/operations/commissary)
"clz" = (
@@ -60926,6 +60926,10 @@
},
/turf/simulated/floor/plating,
/area/merchant_station/warehouse)
+"iAu" = (
+/obj/machinery/smartfridge/tradeshelf,
+/turf/simulated/floor/tiled/full,
+/area/horizon/operations/commissary)
"iAy" = (
/obj/effect/decal/fake_object{
color = "#545c68";
@@ -83186,6 +83190,11 @@
dir = 4;
id = "horizon_commissary_desk"
},
+/obj/structure/cash_register/commissary{
+ dir = 4;
+ pixel_y = 10;
+ pixel_x = 4
+ },
/turf/simulated/floor/tiled/dark/full,
/area/horizon/operations/commissary)
"lFQ" = (
@@ -87735,6 +87744,10 @@
},
/turf/simulated/floor/tiled/dark,
/area/horizon/security/checkpoint)
+"mrm" = (
+/obj/machinery/smartfridge/tradeshelf/food,
+/turf/simulated/floor/tiled/full,
+/area/horizon/operations/commissary)
"mrr" = (
/obj/effect/floor_decal/corner/dark_green{
dir = 5
@@ -107804,8 +107817,7 @@
/obj/machinery/light{
dir = 8
},
-/obj/effect/floor_decal/industrial/hatch/operations,
-/obj/machinery/vending/cola,
+/obj/machinery/smartfridge/tradeshelf/toy,
/turf/simulated/floor/tiled/full,
/area/horizon/operations/commissary)
"plL" = (
@@ -162913,8 +162925,7 @@
/obj/machinery/light{
dir = 8
},
-/obj/effect/floor_decal/industrial/hatch/operations,
-/obj/machinery/vending/snack,
+/obj/machinery/smartfridge/tradeshelf/clothing,
/turf/simulated/floor/tiled/full,
/area/horizon/operations/commissary)
"wYh" = (
@@ -271218,7 +271229,7 @@ ebX
hOg
mQb
vGI
-pfa
+mrm
djK
uIf
exs
@@ -271475,7 +271486,7 @@ gHE
vJd
gst
vGI
-pfa
+iAu
djK
clw
exs
diff --git a/tgui/packages/tgui/interfaces/QuikPay.tsx b/tgui/packages/tgui/interfaces/QuikPay.tsx
index 76f1c92697c..b756fa9e5f2 100644
--- a/tgui/packages/tgui/interfaces/QuikPay.tsx
+++ b/tgui/packages/tgui/interfaces/QuikPay.tsx
@@ -32,12 +32,22 @@ export const QuikPay = (props, context) => {
act('locking')}
- />
+ <>
+