mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 05:00:55 +01:00
## About The Pull Request Last Christmas we had and resolved this bug #88595 where via the mechanic of buying random trash, Cargo could roll on the roulette to try and get random Christmas presents and open them for random items. This was removed because it's not supposed to work that way and was a way of exploiting Christmas cheer for personal gain, which is grinchsome behaviour. That said, being able to order Christmas presents is also kind of soulful, so this PR brings that mechanic back but on purpose this time. During the Christmas season _only_, Cargo can spend 3000 credits of their budget to order a "Surplus Christmas Gifts" crate which contains 4-6 presents _with pre-assigned recipients_. In a similar system to addressed mail, only the person written on the gift tag can open the present, so unless you're sufficiently scroogeous to collect a huge pile of presents on the cargo room floor in hopes of getting a couple with your name on (in my testing these contained raw unbaked croissant dough, and a piece of paper from a space ruin) you should mostly be using this to deliver generalised holiday cheer to the crew rather than just yourself. This PR also contains (maybe as more lines than the actual feature) a refactor changing a bunch of boolean vars on `/datum/supply_pack` into bitflags, because I needed to add one more and it seemed silly to have so many booleans. ## Why It's Good For The Game It allows those with the yuletide spirit to deliver some christmas cheer to their fellow man, isn't that the season's reason? ## Changelog 🆑 add: When the game considers it to be Christmas, Cargo can order additional Christmas gifts pre-addressed to random crew members. /🆑
178 lines
7.0 KiB
Plaintext
178 lines
7.0 KiB
Plaintext
/datum/supply_pack
|
|
/// The name of the supply pack, as listed on th cargo purchasing UI.
|
|
var/name = "Crate"
|
|
/// The group that the supply pack is sorted into within the cargo purchasing UI.
|
|
var/group = ""
|
|
/// Cost of the crate. DO NOT GO ANY LOWER THAN X1.4 the "CARGO_CRATE_VALUE" value if using regular crates, or infinite profit will be possible!
|
|
var/cost = CARGO_CRATE_VALUE * 1.4
|
|
/// What access is required to open the crate when spawned?
|
|
var/access = FALSE
|
|
/// Who can view this supply_pack and with what access.
|
|
var/access_view = FALSE
|
|
/// If someone with any of the following accesses in a list can open this cargo pack crate.
|
|
var/access_any = FALSE
|
|
/// A list of items that are spawned in the crate of the supply pack.
|
|
var/list/contains = null
|
|
/// What is the name of the crate that is spawned with the crate's contents??
|
|
var/crate_name = "crate"
|
|
/// When spawning a gas canistor, what kind of gas type are we spawning?
|
|
var/id
|
|
/// The description shown on the cargo purchasing UI. No desc by default.
|
|
var/desc = ""
|
|
/// What typepath of crate do you spawn?
|
|
var/crate_type = /obj/structure/closet/crate
|
|
/// If this pack comes shipped in a specific pod when launched from the express console
|
|
var/special_pod
|
|
/// Can coupons target this pack? If so, how rarely?
|
|
var/discountable = SUPPLY_PACK_NOT_DISCOUNTABLE
|
|
/// Is this supply pack considered unpredictable for the purposes of testing unit testing? Examples include the stock market, or miner supply crates. If true, exempts from unit testing
|
|
var/test_ignored = FALSE
|
|
/// Various properties for cargo order mostly used to determine which consoles can see it
|
|
var/order_flags = NONE
|
|
|
|
/datum/supply_pack/New()
|
|
id = type
|
|
|
|
/// Returns data used for cargo purchasing UI
|
|
/datum/supply_pack/proc/get_contents_ui_data()
|
|
var/list/data = list()
|
|
for(var/obj/item/item as anything in contains)
|
|
var/list/item_data = list(
|
|
"name" = item.name,
|
|
"icon" = item.greyscale_config ? null : item.icon,
|
|
"icon_state" = item.greyscale_config ? null : item.icon_state,
|
|
"amount" = contains[item]
|
|
)
|
|
UNTYPED_LIST_ADD(data, item_data)
|
|
|
|
return data
|
|
|
|
/**
|
|
* Proc that takes a given supply_pack, and attempts to create a crate containing the pack's contents as determined by fill()
|
|
*
|
|
* @ atom/A: The location or turf that the pack is being generated onto. Cargo shuttle provides an empty turf, other generate()s call this either null or otherwise.
|
|
* @ datum/bank_account/paying_account: The account to associate the supply pack with when going and generating the crate. Only the paying account can open said secure crate/case.
|
|
*/
|
|
/datum/supply_pack/proc/generate(atom/A, datum/bank_account/paying_account)
|
|
var/obj/structure/closet/crate/C
|
|
if(paying_account)
|
|
C = new /obj/structure/closet/crate/secure/owned(A, paying_account)
|
|
C.name = "[crate_name] - Purchased by [paying_account.account_holder]"
|
|
else if(!crate_type)
|
|
CRASH("tried to generate a supply pack without a valid crate type")
|
|
else
|
|
C = new crate_type(A)
|
|
C.name = crate_name
|
|
if(access)
|
|
C.req_access = list(access)
|
|
if(access_any)
|
|
C.req_one_access = access_any
|
|
|
|
fill(C)
|
|
return C
|
|
|
|
/datum/supply_pack/proc/get_cost()
|
|
. = cost
|
|
. *= SSeconomy.pack_price_modifier
|
|
|
|
/datum/supply_pack/proc/fill(obj/structure/closet/crate/C)
|
|
for(var/item in contains)
|
|
if(!contains[item])
|
|
contains[item] = 1
|
|
for(var/iteration = 1 to contains[item])
|
|
var/atom/A = new item(C)
|
|
if(!(order_flags & ORDER_ADMIN_SPAWNED))
|
|
continue
|
|
A.flags_1 |= ADMIN_SPAWNED_1
|
|
|
|
|
|
/// For generating supply packs at runtime. Returns a list of supply packs to use instead of this one.
|
|
/datum/supply_pack/proc/generate_supply_packs()
|
|
return
|
|
|
|
///Easily send a supplypod to an area
|
|
/proc/send_supply_pod_to_area(contents, area_type, pod_type = /obj/structure/closet/supplypod)
|
|
var/list/areas = get_areas(area_type)
|
|
if(!LAZYLEN(areas))
|
|
return FALSE
|
|
var/list/open_turfs = list()
|
|
for(var/turf/open/floor/found_turf in get_area_turfs(pick(areas), subtypes = TRUE))
|
|
open_turfs += found_turf
|
|
|
|
if(!length(open_turfs))
|
|
return FALSE
|
|
|
|
new /obj/effect/pod_landingzone (pick(open_turfs), new pod_type (), contents)
|
|
return TRUE
|
|
|
|
/**
|
|
* Custom supply pack
|
|
* The contents are given on New rather than being static
|
|
* This is for adding custom orders to the Cargo console (like order consoles)
|
|
*/
|
|
/datum/supply_pack/custom
|
|
name = "mining order"
|
|
order_flags = ORDER_INVISIBLE
|
|
crate_name = "shaft mining delivery crate"
|
|
access = ACCESS_MINING
|
|
test_ignored = TRUE
|
|
|
|
/datum/supply_pack/custom/New(purchaser, cost, list/contains)
|
|
. = ..()
|
|
name = "[purchaser]'s Mining Order"
|
|
src.cost = cost
|
|
src.contains = contains
|
|
|
|
/datum/supply_pack/custom/minerals
|
|
name = "materials order"
|
|
crate_name = "galactic materials market delivery crate"
|
|
access = FALSE
|
|
crate_type = /obj/structure/closet/crate/cardboard
|
|
|
|
/datum/supply_pack/custom/minerals/New(purchaser, cost, list/contains)
|
|
. = ..()
|
|
name = "[purchaser]'s Materials Order"
|
|
src.cost = cost
|
|
src.contains = contains
|
|
|
|
///Alters material amrkey & adjust order quantities if they exceed whats on the market
|
|
/datum/supply_pack/custom/minerals/proc/adjust_market()
|
|
. = list()
|
|
for(var/obj/item/stack/sheet/possible_stack as anything in contains)
|
|
var/material_type = possible_stack.material_type
|
|
//in case we ordered more than what's in the market at the time due to market fluctuations
|
|
//we find the min of what was ordered & what's actually available in the market at this point of time
|
|
var/market_quantity = SSstock_market.materials_quantity[material_type]
|
|
var/available_quantity = contains[possible_stack]
|
|
if(available_quantity > market_quantity)
|
|
var/message = "[possible_stack::singular_name]: requested=[available_quantity] sheets, available=[market_quantity] sheets, adjusted=[market_quantity - available_quantity] sheets."
|
|
available_quantity = market_quantity
|
|
if(!available_quantity)
|
|
. += "[possible_stack::singular_name]: order cancelled due to insufficient sheets in the market."
|
|
contains -= possible_stack
|
|
continue
|
|
. += message
|
|
|
|
//adjust the order based ont the available quantity
|
|
contains[possible_stack] = available_quantity
|
|
|
|
//Prices go up as material quantity becomes scarce
|
|
var/fraction = available_quantity
|
|
if(market_quantity != available_quantity) //to avoid division by zero error
|
|
fraction /= (market_quantity - available_quantity)
|
|
SSstock_market.adjust_material_price(material_type, SSstock_market.materials_prices[material_type] * fraction)
|
|
|
|
//We decrease the quantity only after adjusting our prices for accurate values
|
|
SSstock_market.adjust_material_quantity(material_type, -available_quantity)
|
|
|
|
/datum/supply_pack/custom/minerals/fill(obj/structure/closet/crate/C)
|
|
for(var/obj/item/stack/sheet/possible_stack as anything in contains)
|
|
//spawn the ordered stack inside the crate
|
|
var/sheets_to_spawn = contains[possible_stack]
|
|
while(sheets_to_spawn)
|
|
var/spawn_quantity = min(sheets_to_spawn, MAX_STACK_SIZE)
|
|
var/obj/item/stack/sheet/ordered_stack = new possible_stack(C, spawn_quantity)
|
|
if(order_flags & ORDER_ADMIN_SPAWNED)
|
|
ordered_stack.flags_1 |= ADMIN_SPAWNED_1
|
|
sheets_to_spawn -= spawn_quantity
|