mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-16 03:56:20 +00:00
* Corrects a define regarding the amount of mail arriving on station + QOL changes. (#58723) There was a math error in mail's implementation in the economy SS when I switched it over to delta_time, so that basically the time-based define MAX_MAIL_PER_MINUTE was being multiplied by delta_time. Just one problem, delta_time was being considered in deciseconds as usual, but my chimp brain failed to recognize that, meaning that the maximum amount of mail arriving on station was around 100x more than expected. This corrects the delta_time variable to think in terms of MINUTE time defines, not just a static decimal multipliers. Junk mail is funny and good, but you'll never read any of these if you get 200+ letters every shift just like it. Additionally, adds some fluff text to the examine_more of letters, to let players know that you can use destination taggers to sne and distribute letters once they arrive. QOL tweak is just to make cargo players and in-game purists lives easier. * Corrects a define regarding the amount of mail arriving on station + QOL changes. Co-authored-by: ArcaneMusic <41715314+ArcaneMusic@users.noreply.github.com>
288 lines
10 KiB
Plaintext
288 lines
10 KiB
Plaintext
/// Mail is tamper-evident and unresealable, postmarked by CentCom for an individual recepient.
|
|
/obj/item/mail
|
|
name = "mail"
|
|
gender = NEUTER
|
|
desc = "An officially postmarked, tamper-evident parcel regulated by CentCom and made of high-quality materials."
|
|
icon = 'icons/obj/bureaucracy.dmi'
|
|
icon_state = "mail_small"
|
|
inhand_icon_state = "paper"
|
|
worn_icon_state = "paper"
|
|
item_flags = NOBLUDGEON
|
|
w_class = WEIGHT_CLASS_SMALL
|
|
drop_sound = 'sound/items/handling/paper_drop.ogg'
|
|
pickup_sound = 'sound/items/handling/paper_pickup.ogg'
|
|
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
|
|
/// 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.
|
|
var/list/generic_goodies = list(
|
|
/obj/item/stack/spacecash/c50 = 10,
|
|
/obj/item/stack/spacecash/c100 = 25,
|
|
/obj/item/stack/spacecash/c200 = 15,
|
|
/obj/item/stack/spacecash/c500 = 5,
|
|
/obj/item/stack/spacecash/c1000 = 1,
|
|
)
|
|
// Overlays (pure fluff)
|
|
/// Does the letter have the postmark overlay?
|
|
var/postmarked = TRUE
|
|
/// Does the letter have a stamp overlay?
|
|
var/stamped = TRUE
|
|
/// List of all stamp overlays on the letter.
|
|
var/list/stamps = list()
|
|
/// Maximum number of stamps on the letter.
|
|
var/stamp_max = 1
|
|
/// Physical offset of stamps on the object. X direction.
|
|
var/stamp_offset_x = 0
|
|
/// Physical offset of stamps on the object. Y direction.
|
|
var/stamp_offset_y = 2
|
|
|
|
///mail will have the color of the department the recipient is in.
|
|
var/static/list/department_colors
|
|
|
|
/obj/item/mail/envelope
|
|
name = "envelope"
|
|
icon_state = "mail_large"
|
|
goodie_count = 2
|
|
stamp_max = 2
|
|
stamp_offset_y = 5
|
|
|
|
/obj/item/mail/Initialize()
|
|
. = ..()
|
|
RegisterSignal(src, COMSIG_MOVABLE_DISPOSING, .proc/disposal_handling)
|
|
AddElement(/datum/element/item_scaling, 0.75, 1)
|
|
if(isnull(department_colors))
|
|
department_colors = list(
|
|
ACCOUNT_CIV = COLOR_WHITE,
|
|
ACCOUNT_ENG = COLOR_PALE_ORANGE,
|
|
ACCOUNT_SCI = COLOR_PALE_PURPLE_GRAY,
|
|
ACCOUNT_MED = COLOR_PALE_BLUE_GRAY,
|
|
ACCOUNT_SRV = COLOR_PALE_GREEN_GRAY,
|
|
ACCOUNT_CAR = COLOR_BEIGE,
|
|
ACCOUNT_SEC = COLOR_PALE_RED_GRAY,
|
|
)
|
|
|
|
// Icons
|
|
// Add some random stamps.
|
|
if(stamped == TRUE)
|
|
var/stamp_count = rand(1, stamp_max)
|
|
for(var/i = 1, i <= stamp_count, i++)
|
|
stamps += list("stamp_[rand(2, 6)]")
|
|
update_icon()
|
|
|
|
/obj/item/mail/update_overlays()
|
|
. = ..()
|
|
var/bonus_stamp_offset = 0
|
|
for(var/stamp in stamps)
|
|
var/image/stamp_image = image(
|
|
icon = icon,
|
|
icon_state = stamp,
|
|
pixel_x = stamp_offset_x,
|
|
pixel_y = stamp_offset_y + bonus_stamp_offset
|
|
)
|
|
stamp_image.appearance_flags |= RESET_COLOR
|
|
add_overlay(stamp_image)
|
|
bonus_stamp_offset -= 5
|
|
|
|
if(postmarked == TRUE)
|
|
var/image/postmark_image = image(
|
|
icon = icon,
|
|
icon_state = "postmark",
|
|
pixel_x = stamp_offset_x + rand(-3, 1),
|
|
pixel_y = stamp_offset_y + rand(bonus_stamp_offset + 3, 1)
|
|
)
|
|
postmark_image.appearance_flags |= RESET_COLOR
|
|
add_overlay(postmark_image)
|
|
|
|
/obj/item/mail/attackby(obj/item/W, mob/user, params)
|
|
// Destination tagging
|
|
if(istype(W, /obj/item/dest_tagger))
|
|
var/obj/item/dest_tagger/destination_tag = W
|
|
|
|
if(sort_tag != destination_tag.currTag)
|
|
var/tag = uppertext(GLOB.TAGGERLOCATIONS[destination_tag.currTag])
|
|
to_chat(user, "<span class='notice'>*[tag]*</span>")
|
|
sort_tag = destination_tag.currTag
|
|
playsound(loc, 'sound/machines/twobeep_high.ogg', 100, TRUE)
|
|
|
|
/obj/item/mail/attack_self(mob/user)
|
|
if(recipient && user != recipient)
|
|
to_chat(user, "<span class='notice'>You can't open somebody else's mail! That's <em>illegal</em>!</span>")
|
|
return
|
|
|
|
to_chat(user, "<span class='notice'>You start to unwrap the package...</span>")
|
|
if(!do_after(user, 1.5 SECONDS, target = user))
|
|
return
|
|
user.temporarilyRemoveItemFromInventory(src, TRUE)
|
|
if(contents.len)
|
|
user.put_in_hands(contents[1])
|
|
playsound(loc, 'sound/items/poster_ripped.ogg', 50, TRUE)
|
|
qdel(src)
|
|
|
|
/obj/item/mail/examine_more(mob/user)
|
|
. = ..()
|
|
var/list/msg = list("<span class='notice'><i>You notice the postmarking on the front of the mail...</i></span>")
|
|
if(recipient)
|
|
msg += "\t<span class='info'>Certified NT mail for [recipient].</span>"
|
|
else
|
|
msg += "\t<span class='info'>Certified mail for [GLOB.station_name].</span>"
|
|
msg += "\t<span class='info'>Distribute by hand or via destination tagger using the certified NT disposal system.</span>"
|
|
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])"
|
|
var/list/goodies = generic_goodies
|
|
|
|
var/datum/job/this_job = SSjob.name_occupations[new_recipient.job]
|
|
if(this_job)
|
|
if(this_job.paycheck_department && department_colors[this_job.paycheck_department])
|
|
color = department_colors[this_job.paycheck_department]
|
|
var/list/job_goodies = this_job.get_mail_goodies()
|
|
if(LAZYLEN(job_goodies))
|
|
// certain roles and jobs (prisoner) do not receive generic gifts.
|
|
if(this_job.exclusive_mail_goodies)
|
|
goodies = job_goodies
|
|
else
|
|
goodies += job_goodies
|
|
|
|
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)
|
|
|
|
return TRUE
|
|
|
|
/// Alternate setup, just complete garbage inside and anyone can open
|
|
/obj/item/mail/proc/junk_mail()
|
|
|
|
var/obj/junk = /obj/item/paper/fluff/junkmail_generic
|
|
var/special_name = FALSE
|
|
|
|
if(prob(25))
|
|
special_name = TRUE
|
|
junk = pick(list(/obj/item/paper/pamphlet/gateway, /obj/item/paper/pamphlet/violent_video_games, /obj/item/paper/fluff/junkmail_redpill, /obj/effect/decal/cleanable/ash))
|
|
|
|
var/list/junk_names = list(
|
|
/obj/item/paper/pamphlet/gateway = "[initial(name)] for [pick(GLOB.adjectives)] adventurers",
|
|
/obj/item/paper/pamphlet/violent_video_games = "[initial(name)] for the truth about the arcade centcom doesn't want to hear",
|
|
/obj/item/paper/fluff/junkmail_redpill = "[initial(name)] for those feeling [pick(GLOB.adjectives)] working at Nanotrasen",
|
|
/obj/effect/decal/cleanable/ash = "[initial(name)] with INCREDIBLY IMPORTANT ARTIFACT- DELIVER TO SCIENCE DIVISION. HANDLE WITH CARE.",
|
|
)
|
|
|
|
color = pick(department_colors) //eh, who gives a shit.
|
|
name = special_name ? junk_names[junk] : "important [initial(name)]"
|
|
|
|
junk = new junk(src)
|
|
return TRUE
|
|
|
|
/obj/item/mail/proc/disposal_handling(disposal_source, obj/structure/disposalholder/disposal_holder, obj/machinery/disposal/disposal_machine, hasmob)
|
|
SIGNAL_HANDLER
|
|
if(!hasmob)
|
|
disposal_holder.destinationTag = sort_tag
|
|
|
|
/// Subtype that's always junkmail
|
|
/obj/item/mail/junkmail/Initialize()
|
|
..()
|
|
junk_mail()
|
|
|
|
/// Crate for mail from CentCom.
|
|
/obj/structure/closet/crate/mail
|
|
name = "mail crate"
|
|
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)
|
|
icon_state = "[initial(icon_state)]open"
|
|
if(locate(/obj/item/mail) in src)
|
|
icon_state = initial(icon_state)
|
|
else
|
|
icon_state = "[initial(icon_state)]sealed"
|
|
|
|
/obj/structure/closet/crate/mail/full/Initialize()
|
|
. = ..()
|
|
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)
|
|
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.
|
|
else
|
|
new_mail.junk_mail()
|
|
|
|
|
|
/// Mailbag.
|
|
/obj/item/storage/bag/mail
|
|
name = "mail bag"
|
|
desc = "A bag for letters, envelopes, and other postage."
|
|
icon = 'icons/obj/library.dmi'
|
|
icon_state = "bookbag"
|
|
worn_icon_state = "bookbag"
|
|
resistance_flags = FLAMMABLE
|
|
|
|
/obj/item/storage/bag/mail/ComponentInitialize()
|
|
. = ..()
|
|
var/datum/component/storage/storage = GetComponent(/datum/component/storage)
|
|
storage.max_w_class = WEIGHT_CLASS_NORMAL
|
|
storage.max_combined_w_class = 42
|
|
storage.max_items = 21
|
|
storage.display_numerical_stacking = FALSE
|
|
storage.set_holdable(list(
|
|
/obj/item/mail,
|
|
/obj/item/small_delivery,
|
|
/obj/item/paper
|
|
))
|
|
|
|
/obj/item/paper/fluff/junkmail_redpill
|
|
name = "smudged paper"
|
|
icon_state = "scrap"
|
|
var/nuclear_option_odds = 0.1
|
|
|
|
/obj/item/paper/fluff/junkmail_redpill/Initialize()
|
|
. = ..()
|
|
if(!prob(nuclear_option_odds)) // 1 in 1000 chance of getting 2 random nuke code characters.
|
|
info = "<i>You need to escape the simulation. Don't forget the numbers, they help you remember:</i> '[rand(0,9)][rand(0,9)][rand(0,9)]...'"
|
|
return
|
|
var/code = random_nukecode()
|
|
for(var/obj/machinery/nuclearbomb/selfdestruct/self_destruct in GLOB.nuke_list)
|
|
self_destruct.r_code = code
|
|
message_admins("Through junkmail, the self-destruct code was set to \"[code]\".")
|
|
info = "<i>You need to escape the simulation. Don't forget the numbers, they help you remember:</i> '[code[rand(1,5)]][code[rand(1,5)]]...'"
|
|
|
|
/obj/item/paper/fluff/junkmail_redpill/true //admin letter enabling players to brute force their way through the nuke code if they're so inclined.
|
|
nuclear_option_odds = 100
|
|
|
|
/obj/item/paper/fluff/junkmail_generic
|
|
name = "important document"
|
|
icon_state = "paper_words"
|
|
|
|
/obj/item/paper/fluff/junkmail_generic/Initialize()
|
|
. = ..()
|
|
info = pick(GLOB.junkmail_messages)
|