@@ -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, "<span class='notice'>It's locked with a privacy lock, and can only be unlocked by the buyer's ID.</span>")
|
||||
. += "<span class='notice'>It's locked with a privacy lock, and can only be unlocked by the buyer's ID.</span>"
|
||||
|
||||
/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
|
||||
|
||||
@@ -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 += "<h2>[station_name()] Supply Requisition</h2>"
|
||||
P.info += "<hr/>"
|
||||
P.info += "Order #[id]<br/>"
|
||||
P.info += "Time of Order: [STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]<br/>"
|
||||
P.info += "Item: [pack.name]<br/>"
|
||||
P.info += "Access Restrictions: [get_access_desc(pack.access)]<br/>"
|
||||
P.info += "Requested by: [orderer]<br/>"
|
||||
@@ -68,10 +69,10 @@
|
||||
P.name = "shipping manifest - [packname?"#[id] ([pack.name])":"(Grouped Item Crate)"]"
|
||||
P.info += "<h2>[command_name()] Shipping Manifest</h2>"
|
||||
P.info += "<hr/>"
|
||||
if(id && !(id == "Cargo"))
|
||||
if(owner && !(owner == "Cargo"))
|
||||
P.info += "Direct purchase from [owner]<br/>"
|
||||
P.name += " - Purchased by [owner]"
|
||||
P.info += "Order #[id]<br/>"
|
||||
P.info += "Order[packname?"":"s"]: [id]<br/>"
|
||||
P.info += "Destination: [station_name]<br/>"
|
||||
if(packname)
|
||||
P.info += "Item: [packname]<br/>"
|
||||
@@ -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 += "<li>[AM.name]</li>"
|
||||
else
|
||||
continue
|
||||
P.info += "<li>[AM.name]</li>"
|
||||
P.info += "</ul>"
|
||||
P.info += "<h4>Stamp below to confirm receipt of goods:</h4>"
|
||||
@@ -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, "")
|
||||
|
||||
@@ -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
|
||||
@@ -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."
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user