From ce3c4e99ea42d9c6158a09c64659309620a5fffb Mon Sep 17 00:00:00 2001 From: LetterN <24603524+LetterN@users.noreply.github.com> Date: Sun, 21 Mar 2021 13:46:18 +0800 Subject: [PATCH 1/3] fix-but-its-in-the-wrong-branch --- code/modules/cargo/order.dm | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/code/modules/cargo/order.dm b/code/modules/cargo/order.dm index 4fa6a4eade..ad9fa2018e 100644 --- a/code/modules/cargo/order.dm +++ b/code/modules/cargo/order.dm @@ -16,7 +16,7 @@ errors |= MANIFEST_ERROR_ITEM /obj/item/paper/fluff/jobs/cargo/manifest/proc/is_approved() - return stamped && stamped.len && !is_denied() + return stamped?.len && !is_denied() /obj/item/paper/fluff/jobs/cargo/manifest/proc/is_denied() return stamped && ("stamp-deny" in stamped) @@ -49,6 +49,7 @@ P.info += "

[station_name()] Supply Requisition

" P.info += "
" P.info += "Order #[id]
" + P.info += "Time of Order: [STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]
" P.info += "Item: [pack.name]
" P.info += "Access Restrictions: [get_access_desc(pack.access)]
" P.info += "Requested by: [orderer]
" @@ -68,10 +69,10 @@ P.name = "shipping manifest - [packname?"#[id] ([pack.name])":"(Grouped Item Crate)"]" P.info += "

[command_name()] Shipping Manifest

" P.info += "
" - if(id && !(id == "Cargo")) + if(owner && !(owner == "Cargo")) P.info += "Direct purchase from [owner]
" P.name += " - Purchased by [owner]" - P.info += "Order #[id]
" + P.info += "Order[packname?"":"s"]: [id]
" P.info += "Destination: [station_name]
" if(packname) P.info += "Item: [packname]
" @@ -82,8 +83,11 @@ var/obj/structure/closet/C = container ignore_this += C.lockerelectronics for(var/atom/movable/AM in container.contents - ignore_this) - if((P.errors & MANIFEST_ERROR_CONTENTS) && prob(50)) - continue + if((P.errors & MANIFEST_ERROR_CONTENTS)) + if(prob(50)) + P.info += "
  • [AM.name]
  • " + else + continue P.info += "
  • [AM.name]
  • " P.info += "" P.info += "

    Stamp below to confirm receipt of goods:

    " @@ -94,7 +98,7 @@ /obj/structure/closet/crate/large, /obj/structure/closet/secure_closet/goodies )) - if(blacklisted_error[container.type]) + if(is_type_in_list(container, blacklisted_error)) P.errors &= ~MANIFEST_ERROR_ITEM else var/lost = max(round(container.contents.len / 10), 1) @@ -108,15 +112,23 @@ var/obj/structure/closet/crate/C = container C.manifest = P C.update_icon() + else + // manifest goes in if it's not a crate + container.contents += P return P /datum/supply_order/proc/generate(atom/A) + var/account_holder + if(paying_account) + account_holder = paying_account.account_holder + else + account_holder = "Cargo" var/obj/structure/closet/crate/C = pack.generate(A, paying_account) - generateManifest(C, paying_account, pack) + generateManifest(C, account_holder, pack) return C -/datum/supply_order/proc/generateCombo(var/miscbox, var/misc_own, var/misc_contents) +/datum/supply_order/proc/generateCombo(miscbox, misc_own, misc_contents) for (var/I in misc_contents) new I(miscbox) generateManifest(miscbox, misc_own, "") From 8d9c4f55d632f7726c09650baff5275fc4c9637a Mon Sep 17 00:00:00 2001 From: LetterN <24603524+LetterN@users.noreply.github.com> Date: Sun, 21 Mar 2021 13:51:08 +0800 Subject: [PATCH 2/3] no dumb names --- .../file_system/programs/budgetordering.dm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/modules/modular_computers/file_system/programs/budgetordering.dm b/code/modules/modular_computers/file_system/programs/budgetordering.dm index 65ff97dd1b..e55257dfbd 100644 --- a/code/modules/modular_computers/file_system/programs/budgetordering.dm +++ b/code/modules/modular_computers/file_system/programs/budgetordering.dm @@ -1,8 +1,9 @@ /datum/computer_file/program/budgetorders filename = "orderapp" - filedesc = "Nanotrasen Internal Requisition Network (NIRN)" + filedesc = "NT IRN" + category = PROGRAM_CATEGORY_SUPL program_icon_state = "request" - extended_desc = "A request network that utilizes the Nanotrasen Ordering network to purchase supplies using a department budget account." + extended_desc = "Nanotrasen Internal Requisition Network interface for supply purchasing using a department budget account." requires_ntnet = TRUE transfer_access = ACCESS_HEADS usage_flags = PROGRAM_LAPTOP | PROGRAM_TABLET @@ -35,7 +36,7 @@ return FALSE if(!paccess_to_check) // No required_access, allow it. return TRUE - if(IsAdminGhost(user)) + if(isAdminGhostAI(user)) return TRUE //Aquire access from the inserted ID card. @@ -79,7 +80,6 @@ data["supplies"] = list() for(var/pack in SSshuttle.supply_packs) var/datum/supply_pack/P = SSshuttle.supply_packs[pack] - // todo: replace to P.access_view if(!is_visible_pack(usr, P.access , null, P.contraband) || P.hidden) continue if(!data["supplies"][P.group]) @@ -105,7 +105,7 @@ data["docked"] = SSshuttle.supply.mode == SHUTTLE_IDLE data["loan"] = !!SSshuttle.shuttle_loan data["loan_dispatched"] = SSshuttle.shuttle_loan && SSshuttle.shuttle_loan.dispatched - data["can_send"] = FALSE //There is no situation where I want the app to be able to send the shuttle AWAY from the station, but conversely is fine. + data["can_send"] = FALSE //There is no situation where I want the app to be able to send the shuttle AWAY from the station, but conversely is fine. data["can_approve_requests"] = can_approve_requests data["app_cost"] = TRUE var/message = "Remember to stamp and send back the supply manifests." From 86b8bbf72752390a7ea258cad93828a86ca173af Mon Sep 17 00:00:00 2001 From: LetterN <24603524+LetterN@users.noreply.github.com> Date: Sun, 21 Mar 2021 21:44:04 +0800 Subject: [PATCH 3/3] no more free shipping --- .../crates_lockers/crates/secure.dm | 13 ++- .../file_system/programs/budgetordering.dm | 4 +- code/modules/shuttle/supply.dm | 96 ++++++++++++------- 3 files changed, 76 insertions(+), 37 deletions(-) diff --git a/code/game/objects/structures/crates_lockers/crates/secure.dm b/code/game/objects/structures/crates_lockers/crates/secure.dm index 2c923c1905..eb652c5180 100644 --- a/code/game/objects/structures/crates_lockers/crates/secure.dm +++ b/code/game/objects/structures/crates_lockers/crates/secure.dm @@ -80,16 +80,25 @@ name = "private crate" desc = "A crate cover designed to only open for who purchased its contents." icon_state = "privatecrate" + ///Account of the person buying the crate if private purchasing. var/datum/bank_account/buyer_account + ///Department of the person buying the crate if buying via the NIRN app. + var/datum/bank_account/department/department_account + ///Is the secure crate opened or closed? var/privacy_lock = TRUE + ///Is the crate being bought by a person, or a budget card? + var/department_purchase = FALSE /obj/structure/closet/crate/secure/owned/examine(mob/user) . = ..() - to_chat(user, "It's locked with a privacy lock, and can only be unlocked by the buyer's ID.") + . += "It's locked with a privacy lock, and can only be unlocked by the buyer's ID." /obj/structure/closet/crate/secure/owned/Initialize(mapload, datum/bank_account/_buyer_account) . = ..() buyer_account = _buyer_account + if(istype(buyer_account, /datum/bank_account/department)) + department_purchase = TRUE + department_account = buyer_account /obj/structure/closet/crate/secure/owned/togglelock(mob/living/user, silent) if(privacy_lock) @@ -97,7 +106,7 @@ var/obj/item/card/id/id_card = user.get_idcard(TRUE) if(id_card) if(id_card.registered_account) - if(id_card.registered_account == buyer_account) + if(id_card.registered_account == buyer_account || (department_purchase && (id_card.registered_account?.account_job?.paycheck_department) == (department_account.department_id))) if(iscarbon(user)) add_fingerprint(user) locked = !locked diff --git a/code/modules/modular_computers/file_system/programs/budgetordering.dm b/code/modules/modular_computers/file_system/programs/budgetordering.dm index e55257dfbd..162f480c02 100644 --- a/code/modules/modular_computers/file_system/programs/budgetordering.dm +++ b/code/modules/modular_computers/file_system/programs/budgetordering.dm @@ -1,7 +1,7 @@ /datum/computer_file/program/budgetorders filename = "orderapp" filedesc = "NT IRN" - category = PROGRAM_CATEGORY_SUPL + // category = PROGRAM_CATEGORY_SUPL program_icon_state = "request" extended_desc = "Nanotrasen Internal Requisition Network interface for supply purchasing using a department budget account." requires_ntnet = TRUE @@ -36,7 +36,7 @@ return FALSE if(!paccess_to_check) // No required_access, allow it. return TRUE - if(isAdminGhostAI(user)) + if(IsAdminGhost(user)) return TRUE //Aquire access from the inserted ID card. diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index 7af0315934..899e2b2f6f 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -25,7 +25,14 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list( /obj/item/shared_storage, /obj/structure/extraction_point, /obj/machinery/syndicatebomb, - /obj/item/hilbertshotel + /obj/item/hilbertshotel, + /obj/machinery/launchpad, + /obj/machinery/disposal, + /obj/structure/disposalpipe, + /obj/item/hilbertshotel, + /obj/machinery/camera, + /obj/item/gps, + /obj/structure/checkoutmachine ))) GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list( @@ -33,6 +40,11 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list( /mob/living/simple_animal/slaughter ))) +/// How many goody orders we can fit in a lockbox before we upgrade to a crate +#define GOODY_FREE_SHIPPING_MAX 5 +/// How much to charge oversized goody orders +#define CRATE_TAX 700 + /obj/docking_port/mobile/supply name = "supply shuttle" id = "supply" @@ -58,6 +70,7 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list( return check_blacklist(shuttle_areas, GLOB.blacklisted_cargo_types - GLOB.cargo_shuttle_leave_behind_typecache) return ..() +// fuc off /obj/docking_port/mobile/supply/enterTransit() var/list/leave_behind = list() for(var/i in check_blacklist(shuttle_areas, GLOB.cargo_shuttle_leave_behind_typecache)) @@ -98,12 +111,11 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list( sell() /obj/docking_port/mobile/supply/proc/buy() - if(!SSshuttle.shoppinglist.len) - return - var/list/obj/miscboxes = list() //miscboxes are combo boxes that contain all goody orders grouped var/list/misc_order_num = list() //list of strings of order numbers, so that the manifest can show all orders in a box var/list/misc_contents = list() //list of lists of items that each box will contain + if(!SSshuttle.shoppinglist.len) + return var/list/empty_turfs = list() for(var/place in shuttle_areas) @@ -113,30 +125,39 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list( continue empty_turfs += T - var/datum/bank_account/cargo_budget = SSeconomy.get_dep_account(ACCOUNT_CAR) var/value = 0 var/purchases = 0 + var/list/goodies_by_buyer = list() // if someone orders more than GOODY_FREE_SHIPPING_MAX goodies, we upcharge to a normal crate so they can't carry around 20 combat shotties + for(var/datum/supply_order/SO in SSshuttle.shoppinglist) if(!empty_turfs.len) break - var/price = SO.pack.cost if(SO.applied_coupon) price *= (1 - SO.applied_coupon.discount_pct_off) + var/datum/bank_account/D if(SO.paying_account) //Someone paid out of pocket D = SO.paying_account + var/list/current_buyer_orders = goodies_by_buyer[SO.paying_account] // so we can access the length a few lines down if(!SO.pack.goody) price *= 1.1 //TODO make this customizable by the quartermaster + + // note this is before we increment, so this is the GOODY_FREE_SHIPPING_MAX + 1th goody to ship. also note we only increment off this step if they successfully pay the fee, so there's no way around it + else if(LAZYLEN(current_buyer_orders) == GOODY_FREE_SHIPPING_MAX) + price += CRATE_TAX + D.bank_card_talk("Goody order size exceeds free shipping limit: Assessing [CRATE_TAX] credit S&H fee.") else - D = cargo_budget + D = SSeconomy.get_dep_account(ACCOUNT_CAR) if(D) - if(!D.adjust_money(-SO.pack.cost)) + if(!D.adjust_money(-price)) if(SO.paying_account) D.bank_card_talk("Cargo order #[SO.id] rejected due to lack of funds. Credits required: [price]") continue if(SO.paying_account) + if(SO.pack.goody) + LAZYADD(goodies_by_buyer[SO.paying_account], SO) D.bank_card_talk("Cargo order #[SO.id] has shipped. [price] credits have been charged to your bank account.") var/datum/bank_account/department/cargo = SSeconomy.get_dep_account(ACCOUNT_CAR) cargo.adjust_money(price - SO.pack.cost) //Cargo gets the handling fee @@ -145,30 +166,7 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list( SSshuttle.orderhistory += SO QDEL_NULL(SO.applied_coupon) - if(SO.pack.goody) //goody means it gets piled in the miscbox - if(SO.paying_account) - if(!miscboxes.len || !miscboxes[D.account_holder]) //if there's no miscbox for this person - miscboxes[D.account_holder] = new /obj/item/storage/lockbox/order(pick_n_take(empty_turfs)) - var/obj/item/storage/lockbox/order/our_box = miscboxes[D.account_holder] - our_box.buyer_account = SO.paying_account - miscboxes[D.account_holder].name = "small items case - purchased by [D.account_holder]" - misc_contents[D.account_holder] = list() - for (var/item in SO.pack.contains) - misc_contents[D.account_holder] += item - misc_order_num[D.account_holder] = "[misc_order_num[D.account_holder]]#[SO.id] " - else //No private payment, so we just stuff it all into a generic crate - if(!miscboxes.len || !miscboxes["Cargo"]) - miscboxes["Cargo"] = new /obj/structure/closet/secure_closet/goodies(pick_n_take(empty_turfs)) - miscboxes["Cargo"].name = "small items closet" - misc_contents["Cargo"] = list() - miscboxes["Cargo"].req_access = list() - for (var/item in SO.pack.contains) - misc_contents["Cargo"] += item - //new item(miscboxes["Cargo"]) - if(SO.pack.access) - miscboxes["Cargo"].req_access += SO.pack.access - misc_order_num["Cargo"] = "[misc_order_num["Cargo"]]#[SO.id] " - else + if(!SO.pack.goody) //we handle goody crates below SO.generate(pick_n_take(empty_turfs)) SSblackbox.record_feedback("nested tally", "cargo_imports", 1, list("[SO.pack.cost]", "[SO.pack.name]")) @@ -177,16 +175,43 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list( message_admins("\A [SO.pack.name] ordered by [ADMIN_LOOKUPFLW(SO.orderer_ckey)], paid by [D.account_holder] has shipped.") purchases++ + // we handle packing all the goodies last, since the type of crate we use depends on how many goodies they ordered. If it's more than GOODY_FREE_SHIPPING_MAX + // then we send it in a crate (including the CRATE_TAX cost), otherwise send it in a free shipping case + for(var/D in goodies_by_buyer) + var/list/buying_account_orders = goodies_by_buyer[D] + var/datum/bank_account/buying_account = D + var/buyer = buying_account.account_holder + + if(buying_account_orders.len > GOODY_FREE_SHIPPING_MAX) // no free shipping, send a crate + var/obj/structure/closet/crate/secure/owned/our_crate = new /obj/structure/closet/crate/secure/owned(pick_n_take(empty_turfs)) + our_crate.buyer_account = buying_account + our_crate.name = "goody crate - purchased by [buyer]" + miscboxes[buyer] = our_crate + else //free shipping in a case + miscboxes[buyer] = new /obj/item/storage/lockbox/order(pick_n_take(empty_turfs)) + var/obj/item/storage/lockbox/order/our_case = miscboxes[buyer] + our_case.buyer_account = buying_account + miscboxes[buyer].name = "goody case - purchased by [buyer]" + misc_contents[buyer] = list() + + for(var/O in buying_account_orders) + var/datum/supply_order/our_order = O + for (var/item in our_order.pack.contains) + misc_contents[buyer] += item + misc_order_num[buyer] = "[misc_order_num[buyer]]#[our_order.id] " + for(var/I in miscboxes) var/datum/supply_order/SO = new/datum/supply_order() SO.id = misc_order_num[I] SO.generateCombo(miscboxes[I], I, misc_contents[I]) qdel(SO) + var/datum/bank_account/cargo_budget = SSeconomy.get_dep_account(ACCOUNT_CAR) investigate_log("[purchases] orders in this shipment, worth [value] credits. [cargo_budget.account_balance] credits left.", INVESTIGATE_CARGO) /obj/docking_port/mobile/supply/proc/sell() var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) + var/presale_points = D.account_balance var/gain = 0 if(!GLOB.exports_list.len) // No exports list? Generate it! @@ -204,6 +229,8 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list( continue if(bounty_ship_item_and_contents(AM, dry_run = FALSE)) matched_bounty = TRUE + // ignore mech checks because the mech is ONLY for bounty + continue if(!AM.anchored || istype(AM, /obj/mecha)) export_item_and_contents(AM, export_categories , dry_run = FALSE, external_report = ex) @@ -230,4 +257,7 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list( msg = copytext_char(msg, 1, MAX_MESSAGE_LEN) SSshuttle.centcom_message = msg - investigate_log("Shuttle contents sold for [gain] credits. Contents: [ex.exported_atoms || "none."] Message: [SSshuttle.centcom_message || "none."]", INVESTIGATE_CARGO) + investigate_log("Shuttle contents sold for [D.account_balance - presale_points] credits. Contents: [ex.exported_atoms ? ex.exported_atoms.Join(",") + "." : "none."] Message: [SSshuttle.centcom_message || "none."]", INVESTIGATE_CARGO) + +#undef GOODY_FREE_SHIPPING_MAX +#undef CRATE_TAX