Files
Bubberstation/code/game/objects/items/mail.dm
SkyratBot a94325afe4 [MIRROR] Replacing more C-style for loops with the faster, traditional ones. [MDB IGNORE] (#9560)
* Replacing more C-style for loops with the faster, traditional ones. (#62908)

* Replacing more C-style for loops with the faster, traditional ones.

Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
2021-11-19 20:37:13 +00:00

312 lines
11 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
/// 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.
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(mapload)
. = ..()
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,
ACCOUNT_CMD = COLOR_BLUE_GRAY, // SKYRAT EDIT ADDITION
ACCOUNT_CCM = COLOR_DARK_MODERATE_LIME_GREEN, // SKYRAT EDIT ADDITION
)
// Icons
// Add some random stamps.
if(stamped == TRUE)
var/stamp_count = rand(1, stamp_max)
for(var/i in 1 to stamp_count)
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_notice("*[tag]*"))
sort_tag = destination_tag.currTag
playsound(loc, 'sound/machines/twobeep_high.ogg', 100, TRUE)
/obj/item/mail/attack_self(mob/user)
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))
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_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
msg += "\t[span_info("Certified mail for [GLOB.station_name].")]"
msg += "\t[span_info("Distribute by hand or via destination tagger using the certified NT disposal system.")]"
return msg
/// 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.title])"
recipient_ref = WEAKREF(recipient)
var/mob/living/body = recipient.current
var/list/goodies = generic_goodies
var/datum/job/this_job = recipient.assigned_role
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 in 1 to goodie_count)
var/target_good = pick_weight(goodies)
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
/// 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(mapload)
. = ..()
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"
can_install_electronics = FALSE
/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"
/// 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/human in GLOB.player_list)
if(human.stat == DEAD || !human.mind)
continue
// Skip wizards, nuke ops, cyborgs; Centcom does not send them mail
if(!(human.mind.assigned_role.job_flags & JOB_CREW_MEMBER))
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/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(mapload)
. = ..()
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(mapload)
. = ..()
populate(INFINITY)
/// 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(mapload)
. = ..()
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(mapload)
. = ..()
info = pick(GLOB.junkmail_messages)