mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 04:30:44 +01:00
[MIRROR] Refactors mail, delivery and goodies code (#6432)
* Refactors mail and delivery code (#59730) - Mail now uses weakreferences to minds, which means the presence of mail will not cause harddels, and persist between mindswaps or cloning or whatever horrible mob transfer things you've got going on. - The code for creating a crate of mail has been refactored into a single proc, rather than having the same code twice. - Instead of special casing reagents being delivered, instead reagent mail goodies are just regular bottle items like any other. * Refactors mail, delivery and goodies code Co-authored-by: coiax <yellowbounder@gmail.com>
This commit is contained in:
@@ -14,8 +14,8 @@
|
||||
mouse_drag_pointer = MOUSE_ACTIVE_POINTER
|
||||
/// Destination tagging for the mail sorter.
|
||||
var/sort_tag = 0
|
||||
/// Who this mail is for and who can open it.
|
||||
var/datum/weakref/recipient
|
||||
/// Weak reference to who this mail is for and who can open it.
|
||||
var/datum/weakref/recipient_ref
|
||||
/// How many goodies this mail contains.
|
||||
var/goodie_count = 1
|
||||
/// Goodies which can be given to anyone. The base weight for cash is 56. For there to be a 50/50 chance of getting a department item, they need 56 weight as well.
|
||||
@@ -109,9 +109,13 @@
|
||||
playsound(loc, 'sound/machines/twobeep_high.ogg', 100, TRUE)
|
||||
|
||||
/obj/item/mail/attack_self(mob/user)
|
||||
if(recipient && user != recipient)
|
||||
to_chat(user, span_notice("You can't open somebody else's mail! That's <em>illegal</em>!"))
|
||||
return
|
||||
if(recipient_ref)
|
||||
var/datum/mind/recipient = recipient_ref.resolve()
|
||||
// If the recipient's mind has gone, then anyone can open their mail
|
||||
// whether a mind can actually be qdel'd is an exercise for the reader
|
||||
if(recipient && recipient != user?.mind)
|
||||
to_chat(user, span_notice("You can't open somebody else's mail! That's <em>illegal</em>!"))
|
||||
return
|
||||
|
||||
to_chat(user, span_notice("You start to unwrap the package..."))
|
||||
if(!do_after(user, 1.5 SECONDS, target = user))
|
||||
@@ -125,6 +129,7 @@
|
||||
/obj/item/mail/examine_more(mob/user)
|
||||
. = ..()
|
||||
var/list/msg = list(span_notice("<i>You notice the postmarking on the front of the mail...</i>"))
|
||||
var/datum/mind/recipient = recipient_ref.resolve()
|
||||
if(recipient)
|
||||
msg += "\t[span_info("Certified NT mail for [recipient].")]"
|
||||
else
|
||||
@@ -132,13 +137,15 @@
|
||||
msg += "\t[span_info("Distribute by hand or via destination tagger using the certified NT disposal system.")]"
|
||||
return msg
|
||||
|
||||
/// Accepts a mob to initialize goodies for a piece of mail.
|
||||
/obj/item/mail/proc/initialize_for_recipient(mob/new_recipient)
|
||||
recipient = new_recipient
|
||||
name = "[initial(name)] for [new_recipient.real_name] ([new_recipient.job])"
|
||||
/// Accepts a mind to initialize goodies for a piece of mail.
|
||||
/obj/item/mail/proc/initialize_for_recipient(datum/mind/recipient)
|
||||
name = "[initial(name)] for [recipient.name] ([recipient.assigned_role])"
|
||||
recipient_ref = WEAKREF(recipient)
|
||||
|
||||
var/mob/living/body = recipient.current
|
||||
var/list/goodies = generic_goodies
|
||||
|
||||
var/datum/job/this_job = SSjob.name_occupations[new_recipient.job]
|
||||
var/datum/job/this_job = SSjob.name_occupations[recipient.assigned_role]
|
||||
if(this_job)
|
||||
if(this_job.paycheck_department && department_colors[this_job.paycheck_department])
|
||||
color = department_colors[this_job.paycheck_department]
|
||||
@@ -152,14 +159,8 @@
|
||||
|
||||
for(var/iterator = 0, iterator < goodie_count, iterator++)
|
||||
var/target_good = pickweight(goodies)
|
||||
if(ispath(target_good, /datum/reagent))
|
||||
var/obj/item/reagent_containers/target_container = new /obj/item/reagent_containers/glass/bottle(src)
|
||||
target_container.reagents.add_reagent(target_good, target_container.volume)
|
||||
target_container.name = "[target_container.reagents.reagent_list[1].name] bottle"
|
||||
new_recipient.log_message("[key_name(new_recipient)] received reagent container [target_container.name] in the mail ([target_good])", LOG_GAME)
|
||||
else
|
||||
var/atom/movable/target_atom = new target_good(src)
|
||||
new_recipient.log_message("[key_name(new_recipient)] received [target_atom.name] in the mail ([target_good])", LOG_GAME)
|
||||
var/atom/movable/target_atom = new target_good(src)
|
||||
body.log_message("[key_name(body)] received [target_atom.name] in the mail ([target_good])", LOG_GAME)
|
||||
|
||||
return TRUE
|
||||
|
||||
@@ -202,11 +203,6 @@
|
||||
desc = "A certified post crate from CentCom."
|
||||
icon_state = "mail"
|
||||
|
||||
/// Crate for mail that automatically generates a lot of mail. Usually only normal mail, but on lowpop it may end up just being junk.
|
||||
/obj/structure/closet/crate/mail/full
|
||||
name = "brimming mail crate"
|
||||
desc = "A certified post crate from CentCom. Looks stuffed to the gills."
|
||||
|
||||
/obj/structure/closet/crate/mail/update_icon_state()
|
||||
. = ..()
|
||||
if(opened)
|
||||
@@ -216,26 +212,51 @@
|
||||
else
|
||||
icon_state = "[initial(icon_state)]sealed"
|
||||
|
||||
/obj/structure/closet/crate/mail/full/Initialize()
|
||||
. = ..()
|
||||
/// Fills this mail crate with N pieces of mail, where N is the lower of the amount var passed, and the maximum capacity of this crate. If N is larger than the number of alive human players, the excess will be junkmail.
|
||||
/obj/structure/closet/crate/mail/proc/populate(amount)
|
||||
var/mail_count = min(amount, storage_capacity)
|
||||
// Fills the
|
||||
var/list/mail_recipients = list()
|
||||
for(var/mob/living/carbon/human/alive in GLOB.player_list)
|
||||
if(alive.stat != DEAD)
|
||||
mail_recipients += alive
|
||||
for(var/iterator in 1 to storage_capacity)
|
||||
|
||||
for(var/mob/living/carbon/human/human in GLOB.player_list)
|
||||
if(human.stat == DEAD || !human.mind)
|
||||
continue
|
||||
// Skip wizards, nuke ops, cyborgs; Centcom does not send them mail
|
||||
if(!SSjob.GetJob(human.mind.assigned_role) || (human.mind.assigned_role in GLOB.nonhuman_positions))
|
||||
continue
|
||||
|
||||
mail_recipients += human.mind
|
||||
|
||||
for(var/i in 1 to mail_count)
|
||||
var/obj/item/mail/new_mail
|
||||
if(prob(FULL_CRATE_LETTER_ODDS))
|
||||
new_mail = new /obj/item/mail(src)
|
||||
else
|
||||
new_mail = new /obj/item/mail/envelope(src)
|
||||
var/mob/living/carbon/human/mail_to
|
||||
mail_to = pick(mail_recipients)
|
||||
if(mail_to)
|
||||
new_mail.initialize_for_recipient(mail_to)
|
||||
mail_recipients -= mail_to //Once picked, the mail crate will need a new recipient.
|
||||
|
||||
var/datum/mind/recipient = pick_n_take(mail_recipients)
|
||||
if(recipient)
|
||||
new_mail.initialize_for_recipient(recipient)
|
||||
else
|
||||
new_mail.junk_mail()
|
||||
|
||||
update_icon()
|
||||
|
||||
/// Crate for mail that automatically depletes the economy subsystem's pending mail counter.
|
||||
/obj/structure/closet/crate/mail/economy/Initialize()
|
||||
. = ..()
|
||||
populate(SSeconomy.mail_waiting)
|
||||
SSeconomy.mail_waiting = 0
|
||||
|
||||
/// Crate for mail that automatically generates a lot of mail. Usually only normal mail, but on lowpop it may end up just being junk.
|
||||
/obj/structure/closet/crate/mail/full
|
||||
name = "brimming mail crate"
|
||||
desc = "A certified post crate from CentCom. Looks stuffed to the gills."
|
||||
|
||||
/obj/structure/closet/crate/mail/full/Initialize()
|
||||
. = ..()
|
||||
populate(INFINITY)
|
||||
|
||||
|
||||
/// Mailbag.
|
||||
/obj/item/storage/bag/mail
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
mail_goodies = list(
|
||||
/obj/item/storage/box/rubbershot = 30,
|
||||
/datum/reagent/consumable/clownstears = 10,
|
||||
/obj/item/reagent_containers/glass/bottle/clownstears = 10,
|
||||
/obj/item/stack/sheet/mineral/plasma = 10,
|
||||
/obj/item/stack/sheet/mineral/uranium = 10,
|
||||
)
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
family_heirlooms = list(/obj/item/cultivator, /obj/item/reagent_containers/glass/bucket, /obj/item/toy/plush/beeplushie)
|
||||
|
||||
mail_goodies = list(
|
||||
/datum/reagent/toxin/mutagen = 20,
|
||||
/datum/reagent/saltpetre = 20,
|
||||
/datum/reagent/diethylamine = 20,
|
||||
/obj/item/reagent_containers/glass/bottle/mutagen = 20,
|
||||
/obj/item/reagent_containers/glass/bottle/saltpetre = 20,
|
||||
/obj/item/reagent_containers/glass/bottle/diethylamine = 20,
|
||||
/obj/item/gun/energy/floragun = 10,
|
||||
/obj/effect/spawner/lootdrop/space/rareseed = 5,// These are strong, rare seeds, so use sparingly.
|
||||
/obj/item/food/monkeycube/bee = 2
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
family_heirlooms = list(/obj/item/book/manual/wiki/chemistry, /obj/item/ph_booklet)
|
||||
|
||||
mail_goodies = list(
|
||||
/datum/reagent/flash_powder = 15,
|
||||
/datum/reagent/exotic_stabilizer = 5,
|
||||
/datum/reagent/toxin/leadacetate = 5,
|
||||
/obj/item/reagent_containers/glass/bottle/flash_powder = 15,
|
||||
/obj/item/reagent_containers/glass/bottle/exotic_stabilizer = 5,
|
||||
/obj/item/reagent_containers/glass/bottle/leadacetate = 5,
|
||||
/obj/item/paper/secretrecipe = 1
|
||||
)
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
mail_goodies = list(
|
||||
/obj/item/storage/box/ingredients/random = 80,
|
||||
/datum/reagent/consumable/caramel = 20,
|
||||
/obj/item/reagent_containers/glass/bottle/caramel = 20,
|
||||
/obj/item/reagent_containers/food/condiment/flour = 20,
|
||||
/obj/item/reagent_containers/food/condiment/rice = 20,
|
||||
/obj/item/reagent_containers/food/condiment/enzyme = 15,
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
/obj/item/scalpel/advanced = 6,
|
||||
/obj/item/retractor/advanced = 6,
|
||||
/obj/item/cautery/advanced = 6,
|
||||
/datum/reagent/toxin/formaldehyde = 6,
|
||||
/obj/item/reagent_containers/glass/bottle/formaldehyde = 6,
|
||||
/obj/effect/spawner/lootdrop/organ_spawner = 5,
|
||||
/obj/effect/spawner/lootdrop/memeorgans = 1
|
||||
)
|
||||
|
||||
@@ -420,3 +420,35 @@
|
||||
/obj/item/reagent_containers/glass/bottle/thermite
|
||||
name = "thermite bottle"
|
||||
list_reagents = list(/datum/reagent/thermite = 30)
|
||||
|
||||
// Bottles for mail goodies.
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/clownstears
|
||||
name = "bottle of distilled clown misery"
|
||||
desc = "A small bottle. Contains a mythical liquid used by sublime bartenders; made from the unhappiness of clowns."
|
||||
list_reagents = list(/datum/reagent/consumable/clownstears = 30)
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/saltpetre
|
||||
name = "saltpetre bottle"
|
||||
desc = "A small bottle. Contains saltpetre."
|
||||
list_reagents = list(/datum/reagent/saltpetre = 30)
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/flash_powder
|
||||
name = "flash powder bottle"
|
||||
desc = "A small bottle. Contains flash powder."
|
||||
list_reagents = list(/datum/reagent/flash_powder = 30)
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/exotic_stabilizer
|
||||
name = "exotic stabilizer bottle"
|
||||
desc = "A small bottle. Contains exotic stabilizer."
|
||||
list_reagents = list(/datum/reagent/exotic_stabilizer = 30)
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/leadacetate
|
||||
name = "lead acetate bottle"
|
||||
desc = "A small bottle. Contains lead acetate."
|
||||
list_reagents = list(/datum/reagent/toxin/leadacetate = 30)
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/caramel
|
||||
name = "bottle of caramel"
|
||||
desc = "A bottle containing caramalized sugar, also known as caramel. Do not lick."
|
||||
list_reagents = list(/datum/reagent/consumable/caramel = 30)
|
||||
|
||||
@@ -246,6 +246,7 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
|
||||
//Early return if there's no mail waiting to prevent taking up a slot. We also don't send mails on sundays or holidays.
|
||||
if(!SSeconomy.mail_waiting || SSeconomy.mail_blocked)
|
||||
return
|
||||
|
||||
//spawn crate
|
||||
var/list/empty_turfs = list()
|
||||
for(var/place as anything in shuttle_areas)
|
||||
@@ -254,35 +255,8 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
|
||||
if(shuttle_floor.is_blocked_turf())
|
||||
continue
|
||||
empty_turfs += shuttle_floor
|
||||
var/obj/structure/closet/crate/mail/mailcrate = new(pick(empty_turfs))
|
||||
|
||||
//collect recipients
|
||||
var/list/mail_recipients = list()
|
||||
for(var/mob/living/carbon/human/player_human in shuffle(GLOB.player_list))
|
||||
if(player_human.stat == DEAD)
|
||||
continue
|
||||
if(!SSjob.GetJob(player_human.mind.assigned_role) || (player_human.mind.assigned_role in GLOB.nonhuman_positions))
|
||||
continue //this check stops wizards and nuke ops from getting mail, which is hilarious but should definitely not happen
|
||||
mail_recipients += player_human
|
||||
|
||||
//Creates mail for all the mail waiting to arrive, if there's nobody to recieve it it's just junkmail.
|
||||
for(var/mail_iterator in 1 to SSeconomy.mail_waiting)
|
||||
var/obj/item/mail/new_mail
|
||||
if(prob(FULL_CRATE_LETTER_ODDS))
|
||||
new_mail = new /obj/item/mail(mailcrate)
|
||||
else
|
||||
new_mail = new /obj/item/mail/envelope(mailcrate)
|
||||
var/mob/living/carbon/human/mail_to
|
||||
if(mail_recipients.len)
|
||||
mail_to = pick(mail_recipients)
|
||||
new_mail.initialize_for_recipient(mail_to)
|
||||
mail_recipients -= mail_to
|
||||
else
|
||||
new_mail.junk_mail()
|
||||
if(new_mail)
|
||||
SSeconomy.mail_waiting -= 1
|
||||
mailcrate.update_icon()
|
||||
return mailcrate
|
||||
new /obj/structure/closet/crate/mail/economy(pick(empty_turfs))
|
||||
|
||||
#undef GOODY_FREE_SHIPPING_MAX
|
||||
#undef CRATE_TAX
|
||||
|
||||
Reference in New Issue
Block a user