diff --git a/code/__DEFINES/cargo.dm b/code/__DEFINES/cargo.dm index 747e48559f7..56d3896f0dc 100644 --- a/code/__DEFINES/cargo.dm +++ b/code/__DEFINES/cargo.dm @@ -40,6 +40,12 @@ /// The baseline unit for cargo crates. Adjusting this will change the cost of all in-game shuttles, crate export values, bounty rewards, and all supply pack import values, as they use this as their unit of measurement. #define CARGO_CRATE_VALUE 200 +/// The highest amount of orders you can have of one thing at any one time +#define CARGO_MAX_ORDER 50 + +/// Returned by /obj/docking_port/mobile/supply/proc/get_order_count to signify us going over the order limit +#define OVER_ORDER_LIMIT "GO AWAY" + /// Universal Scanner mode for export scanning. #define SCAN_EXPORTS 1 /// Universal Scanner mode for using the sales tagger. diff --git a/code/game/machinery/computer/orders/order_computer/order_computer.dm b/code/game/machinery/computer/orders/order_computer/order_computer.dm index 92942add2ea..6fa124e8212 100644 --- a/code/game/machinery/computer/orders/order_computer/order_computer.dm +++ b/code/game/machinery/computer/orders/order_computer/order_computer.dm @@ -156,6 +156,7 @@ GLOBAL_LIST_EMPTY(order_console_products) //So miners cant spam buy crates for a very low price if(get_total_cost() < CARGO_CRATE_VALUE) return + var/obj/item/card/id/used_id_card = living_user.get_idcard(TRUE) if(!used_id_card || !used_id_card.registered_account) say("No bank account detected!") diff --git a/code/modules/cargo/department_order.dm b/code/modules/cargo/department_order.dm index 972588a6355..6658019f7f1 100644 --- a/code/modules/cargo/department_order.dm +++ b/code/modules/cargo/department_order.dm @@ -142,6 +142,12 @@ GLOBAL_LIST_INIT(department_order_cooldowns, list( if(GLOB.areas_by_type[delivery_area_type]) chosen_delivery_area = delivery_area_type break + + if(SSshuttle.supply.get_order_count(pack) == OVER_ORDER_LIMIT) + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + say("ERROR: No more then [CARGO_MAX_ORDER] of any pack may be ordered at once") + return + department_order = new(pack, name, rank, ckey, "", null, chosen_delivery_area, null) SSshuttle.shopping_list += department_order if(!already_signalled) diff --git a/code/modules/cargo/orderconsole.dm b/code/modules/cargo/orderconsole.dm index ed983ecab5d..0ca3418f8f1 100644 --- a/code/modules/cargo/orderconsole.dm +++ b/code/modules/cargo/orderconsole.dm @@ -111,9 +111,11 @@ message = blockade_warning data["message"] = message + var/list/amount_by_name = list() var/cart_list = list() for(var/datum/supply_order/order in SSshuttle.shopping_list) if(cart_list[order.pack.name]) + amount_by_name[order.pack.name] += 1 cart_list[order.pack.name][1]["amount"]++ cart_list[order.pack.name][1]["cost"] += order.get_final_cost() if(order.department_destination) @@ -122,6 +124,7 @@ cart_list[order.pack.name][1]["paid"]++ continue + amount_by_name[order.pack.name] += 1 cart_list[order.pack.name] = list(list( "cost_type" = order.cost_type, "object" = order.pack.name, @@ -139,19 +142,23 @@ data["requests"] = list() - for(var/datum/supply_order/SO in SSshuttle.request_list) + for(var/datum/supply_order/order in SSshuttle.request_list) + var/datum/supply_pack/pack = order.pack + amount_by_name[pack.name] += 1 data["requests"] += list(list( - "object" = SO.pack.name, - "cost" = SO.pack.get_cost(), - "orderer" = SO.orderer, - "reason" = SO.reason, - "id" = SO.id + "object" = pack.name, + "cost" = pack.get_cost(), + "orderer" = order.orderer, + "reason" = order.reason, + "id" = order.id )) + data["amount_by_name"] = amount_by_name return data /obj/machinery/computer/cargo/ui_static_data(mob/user) var/list/data = list() + data["max_order"] = CARGO_MAX_ORDER data["supplies"] = list() for(var/pack in SSshuttle.supply_packs) var/datum/supply_pack/P = SSshuttle.supply_packs[pack] @@ -185,7 +192,7 @@ var/datum/supply_pack/pack = SSshuttle.supply_packs[id] if(!istype(pack)) CRASH("Unknown supply pack id given by order console ui. ID: [id]") - if(amount > 50 || amount < 1) // Holy shit fuck off + if(amount > CARGO_MAX_ORDER || amount < 1) // Holy shit fuck off CRASH("Invalid amount passed into add_item") if((pack.hidden && !(obj_flags & EMAGGED)) || (pack.contraband && !contraband) || pack.drop_pod_only || (pack.special && !pack.special_enabled)) return @@ -220,8 +227,11 @@ say("[id_card] lacks the requisite access for this purchase.") return + // The list we are operating on right now + var/list/working_list = SSshuttle.shopping_list var/reason = "" if(requestonly && !self_paid) + working_list = SSshuttle.request_list reason = tgui_input_text(user, "Reason", name) if(isnull(reason)) return @@ -231,6 +241,13 @@ say("ERROR: Small crates may only be purchased by private accounts.") return + var/similar_count = SSshuttle.supply.get_order_count(pack) + if(similar_count == OVER_ORDER_LIMIT) + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + say("ERROR: No more then [CARGO_MAX_ORDER] of any pack may be ordered at once") + return + + amount = clamp(amount, 1, CARGO_MAX_ORDER - similar_count) for(var/count in 1 to amount) var/obj/item/coupon/applied_coupon for(var/obj/item/coupon/coupon_check in loaded_coupons) @@ -240,11 +257,8 @@ applied_coupon = coupon_check break - var/datum/supply_order/SO = new(pack = pack ,orderer = name, orderer_rank = rank, orderer_ckey = ckey, reason = reason, paying_account = account, coupon = applied_coupon) - if(requestonly && !self_paid) - SSshuttle.request_list += SO - else - SSshuttle.shopping_list += SO + var/datum/supply_order/order = new(pack = pack ,orderer = name, orderer_rank = rank, orderer_ckey = ckey, reason = reason, paying_account = account, coupon = applied_coupon) + working_list += order if(self_paid) say("Order processed. The price will be charged to [account.account_holder]'s bank account on delivery.") @@ -359,9 +373,7 @@ if("remove") var/order_name = params["order_name"] //try removing atleast one item with the specified name. An order may not be removed if it was from the department - //also we create an copy of the cart list else we would get runtimes when removing & iterating over the same SSshuttle.shopping_list - var/list/shopping_cart = SSshuttle.shopping_list.Copy() - for(var/datum/supply_order/order in shopping_cart) + for(var/datum/supply_order/order in SSshuttle.shopping_list) if(order.pack.name != order_name) continue if(remove_item(order.id)) @@ -372,8 +384,7 @@ var/order_name = params["order_name"] //clear out all orders with the above mentioned order_name name to make space for the new amount - var/list/shopping_cart = SSshuttle.shopping_list.Copy() //we operate on the list copy else we would get runtimes when removing & iterating over the same SSshuttle.shopping_list - for(var/datum/supply_order/order in shopping_cart) //find corresponding order id for the order name + for(var/datum/supply_order/order in SSshuttle.shopping_list) //find corresponding order id for the order name if(order.pack.name == order_name) remove_item(order.id) @@ -381,7 +392,7 @@ var/amount = text2num(params["amount"]) if(amount == 0) return TRUE - if(amount > 50) + if(amount > CARGO_MAX_ORDER) return var/supply_pack_id = name_to_id(order_name) //map order name to supply pack id for adding if(!supply_pack_id) diff --git a/code/modules/modular_computers/file_system/programs/budgetordering.dm b/code/modules/modular_computers/file_system/programs/budgetordering.dm index fb6e2505b62..a7171dc0494 100644 --- a/code/modules/modular_computers/file_system/programs/budgetordering.dm +++ b/code/modules/modular_computers/file_system/programs/budgetordering.dm @@ -118,9 +118,11 @@ if(SSshuttle.supply_blocked) message = blockade_warning data["message"] = message + var/list/amount_by_name = list() var/cart_list = list() for(var/datum/supply_order/order in SSshuttle.shopping_list) if(cart_list[order.pack.name]) + amount_by_name[order.pack.name] += 1 cart_list[order.pack.name][1]["amount"]++ cart_list[order.pack.name][1]["cost"] += order.get_final_cost() if(order.department_destination) @@ -145,17 +147,25 @@ data["cart"] += cart_list[item_id] data["requests"] = list() - for(var/datum/supply_order/SO in SSshuttle.request_list) + for(var/datum/supply_order/order in SSshuttle.request_list) + var/datum/supply_pack/pack = order.pack + amount_by_name[pack.name] += 1 data["requests"] += list(list( - "object" = SO.pack.name, - "cost" = SO.pack.get_cost(), - "orderer" = SO.orderer, - "reason" = SO.reason, - "id" = SO.id + "object" = pack.name, + "cost" = pack.get_cost(), + "orderer" = order.orderer, + "reason" = order.reason, + "id" = order.id )) + data["amount_by_name"] = amount_by_name return data +/datum/computer_file/program/budgetorders/ui_static_data(mob/user) + var/list/data = list() + data["max_order"] = CARGO_MAX_ORDER + return data + /datum/computer_file/program/budgetorders/ui_act(action, params, datum/tgui/ui) switch(action) if("send") @@ -233,15 +243,20 @@ return if(pack.goody && !self_paid) - playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + playsound(computer, 'sound/machines/buzz-sigh.ogg', 50, FALSE) computer.say("ERROR: Small crates may only be purchased by private accounts.") return + if(SSshuttle.supply.get_order_count(pack) == OVER_ORDER_LIMIT) + playsound(computer, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + computer.say("ERROR: No more then [CARGO_MAX_ORDER] of any pack may be ordered at once") + return + if(!requestonly && !self_paid && ishuman(usr) && !account) var/obj/item/card/id/id_card = computer.computer_id_slot?.GetID() account = SSeconomy.get_dep_account(id_card?.registered_account?.account_job.paycheck_department) - var/turf/T = get_turf(src) + var/turf/T = get_turf(computer) var/datum/supply_order/SO = new(pack, name, rank, ckey, reason, account) SO.generateRequisition(T) if((requestonly && !self_paid) || !(computer.computer_id_slot?.GetID())) diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index 03d36bfd1a7..ee28b39bcda 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -263,5 +263,17 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list( new /obj/structure/closet/crate/mail/economy(pick(empty_turfs)) +/// Takes a supply pack, returns the amount we currently have on order (or OVER_ORDER_LIMIT if we are over the hardcap on orders of this type) +/obj/docking_port/mobile/supply/proc/get_order_count(datum/supply_pack/ordering) + var/similar_count = 0 + for(var/datum/supply_order/order as anything in (SSshuttle.shopping_list | SSshuttle.request_list)) + if(order.pack == ordering) + similar_count += 1 + + if(similar_count >= CARGO_MAX_ORDER) + return OVER_ORDER_LIMIT + + return similar_count + #undef GOODY_FREE_SHIPPING_MAX #undef CRATE_TAX diff --git a/tgui/packages/tgui/interfaces/Cargo.js b/tgui/packages/tgui/interfaces/Cargo.js index 50b9300ed8f..2e25dc9aa74 100644 --- a/tgui/packages/tgui/interfaces/Cargo.js +++ b/tgui/packages/tgui/interfaces/Cargo.js @@ -156,6 +156,7 @@ export const CargoCatalog = (props, context) => { const { self_paid, app_cost } = data; const supplies = Object.values(data.supplies); + const { amount_by_name = [], max_order } = data; const [activeSupplyName, setActiveSupplyName] = useSharedState( context, @@ -264,6 +265,7 @@ export const CargoCatalog = (props, context) => { fluid tooltip={pack.desc} tooltipPosition="left" + disabled={(amount_by_name[pack.name] || 0) >= max_order} onClick={() => act('add', { id: pack.id, @@ -397,7 +399,15 @@ const CartHeader = (props, context) => { const CargoCart = (props, context) => { const { act, data } = useBackend(context); - const { requestonly, away, docked, location, can_send } = data; + const { + requestonly, + away, + docked, + location, + can_send, + amount_by_name, + max_order, + } = data; const cart = data.cart || []; return (
@@ -415,7 +425,7 @@ const CargoCart = (props, context) => { act('modify', { @@ -430,6 +440,7 @@ const CargoCart = (props, context) => { {!!can_send && !!entry.can_be_cancelled && (