From 8a6dbb1a459504cd5c1b5b2c8af00f2a0ab3c984 Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Sun, 15 Sep 2024 20:48:09 +0200 Subject: [PATCH] Gives detectives an ID that looks like an assistant ID when flipped. Also makes their camera silent. (#85912) ## About The Pull Request This PR adds an ID subtype which the detective outfit uses. It that can be flipped to go plainclothes as an assistant. Access retained. Spare clothes not included. I've also made the detective camera silent (a sound cue is still played to the user, others won't hear it) and with the flash disabled. ## Why It's Good For The Game I want to make it a little easier for detectives to go plainclothes. Between clothings and inventory management, it's already quite tricky as a gimmick and without doubt a double-edged sword that can lead to goofy-ass situations where officers actually confuse you for an assistant. As for the camera, it's just a stealth buff. ## Changelog :cl: add: Gave the detective an ID that can flipped to look like an assistant ID. balance: The detective camera is now silent and doesn't flash. /:cl: --- code/game/objects/items/cards_ids.dm | 48 +++++++++++++++++-- code/modules/jobs/job_types/detective.dm | 7 ++- code/modules/photography/camera/camera.dm | 6 ++- .../camera/camera_image_capturing.dm | 6 --- code/modules/photography/camera/other.dm | 10 +++- 5 files changed, 60 insertions(+), 17 deletions(-) diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index 65daf8141c4..9ba78e7ad80 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -987,6 +987,11 @@ return ..() +/obj/item/card/id/advanced/proc/after_input_check(mob/user) + if(QDELETED(user) || QDELETED(src) || !user.client || !user.can_perform_action(src, NEED_DEXTERITY|FORBID_TELEKINESIS_REACH)) + return FALSE + return TRUE + /obj/item/card/id/advanced/item_interaction(mob/living/user, obj/item/tool, list/modifiers) . = ..() if(.) @@ -1442,6 +1447,44 @@ trim = /datum/id_trim/highlander wildcard_slots = WILDCARD_LIMIT_ADMIN +/// An ID that you can flip with attack_self_secondary, overriding the appearance of the ID (useful for plainclothes detectives for example). +/obj/item/card/id/advanced/plainclothes + name = "Plainclothes ID" + ///The trim that we use as plainclothes identity + var/alt_trim = /datum/id_trim/job/assistant + +/obj/item/card/id/advanced/plainclothes/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + context[SCREENTIP_CONTEXT_LMB] = "Show/Flip ID" + +/obj/item/card/id/advanced/plainclothes/examine(mob/user) + . = ..() + if(trim_assignment_override) + . += span_smallnotice("it's currently under plainclothes identity.") + else + . += span_smallnotice("flip it to switch to the plainclothes identity.") + +/obj/item/card/id/advanced/plainclothes/attack_self(mob/user) + var/popup_input = tgui_input_list(user, "Choose Action", "Two-Sided ID", list("Show", "Flip")) + if(!popup_input || !after_input_check(user)) + return TRUE + if(popup_input == "Show") + return ..() + balloon_alert(user, "flipped") + if(trim_assignment_override) + SSid_access.remove_trim_from_chameleon_card(src) + else + SSid_access.apply_trim_to_chameleon_card(src, alt_trim) + update_label() + update_appearance() + +/obj/item/card/id/advanced/plainclothes/update_label() + if(!trim_assignment_override) + return ..() + var/name_string = registered_name ? "[registered_name]'s ID Card" : initial(name) + var/datum/id_trim/fake = SSid_access.trim_singletons_by_path[alt_trim] + name = "[name_string] ([fake.assignment])" + /obj/item/card/id/advanced/chameleon name = "agent card" desc = "A highly advanced chameleon ID card. Touch this card on another ID card or player to choose which accesses to copy. \ @@ -1724,11 +1767,6 @@ registered_account = account to_chat(user, span_notice("Your account number has been automatically assigned.")) -/obj/item/card/id/advanced/chameleon/proc/after_input_check(mob/user) - if(QDELETED(user) || QDELETED(src) || !user.client || !user.can_perform_action(src, NEED_DEXTERITY|FORBID_TELEKINESIS_REACH)) - return FALSE - return TRUE - /obj/item/card/id/advanced/chameleon/add_item_context(obj/item/source, list/context, atom/target, mob/living/user,) . = ..() diff --git a/code/modules/jobs/job_types/detective.dm b/code/modules/jobs/job_types/detective.dm index 00bd8790d9b..258b2b322f1 100644 --- a/code/modules/jobs/job_types/detective.dm +++ b/code/modules/jobs/job_types/detective.dm @@ -29,13 +29,14 @@ mail_goodies = list( /obj/item/storage/fancy/cigarettes = 25, - /obj/item/ammo_box/c38 = 25, + /obj/item/ammo_box/c38 = 20, /obj/item/ammo_box/c38/dumdum = 5, /obj/item/ammo_box/c38/hotshot = 5, /obj/item/ammo_box/c38/iceblox = 5, /obj/item/ammo_box/c38/match = 5, /obj/item/ammo_box/c38/trac = 5, - /obj/item/storage/belt/holster/detective/full = 1 + /obj/item/card/id/advanced/plainclothes = 5, + /obj/item/storage/belt/holster/detective/full = 1, ) family_heirlooms = list(/obj/item/reagent_containers/cup/glass/bottle/whiskey) @@ -49,6 +50,8 @@ name = "Detective" jobtype = /datum/job/detective + id = /obj/item/card/id/advanced/plainclothes + id_trim = /datum/id_trim/job/detective uniform = /obj/item/clothing/under/rank/security/detective suit = /obj/item/clothing/suit/jacket/det_suit diff --git a/code/modules/photography/camera/camera.dm b/code/modules/photography/camera/camera.dm index eb29ca4b8b5..425ff9d38a4 100644 --- a/code/modules/photography/camera/camera.dm +++ b/code/modules/photography/camera/camera.dm @@ -30,7 +30,6 @@ var/blending = FALSE //lets not take pictures while the previous is still processing! var/see_ghosts = CAMERA_NO_GHOSTS //for the spoop of it var/obj/item/disk/holodisk/disk - var/sound/custom_sound var/silent = FALSE var/picture_size_x = 2 var/picture_size_y = 2 @@ -118,7 +117,7 @@ return FALSE else if(user.client && !(get_turf(target) in get_hear(user.client.view, user))) return FALSE - else if(!(get_turf(target) in get_hear(world.view, user))) + else if(!(get_turf(target) in get_hear(CONFIG_GET(string/default_view), user))) return FALSE else if(isliving(loc)) if(!(get_turf(target) in view(world.view, loc))) @@ -252,6 +251,9 @@ if(print_picture_on_snap) printpicture(user, picture) + if(!silent) + playsound(loc, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 75, TRUE, -3) + /obj/item/camera/proc/printpicture(mob/user, datum/picture/picture) //Normal camera proc for creating photos pictures_left-- var/obj/item/photo/new_photo = new(get_turf(src), picture) diff --git a/code/modules/photography/camera/camera_image_capturing.dm b/code/modules/photography/camera/camera_image_capturing.dm index 64eeb192a22..c9f8d8dbe8e 100644 --- a/code/modules/photography/camera/camera_image_capturing.dm +++ b/code/modules/photography/camera/camera_image_capturing.dm @@ -142,12 +142,6 @@ res.Blend(img, blendMode2iconMode(clone.blend_mode), xo, yo) CHECK_TICK - if(!silent) - if(istype(custom_sound)) //This is where the camera actually finishes its exposure. - playsound(loc, custom_sound, 75, TRUE, -3) - else - playsound(loc, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 75, TRUE, -3) - if(wipe_atoms) QDEL_LIST(atoms) else diff --git a/code/modules/photography/camera/other.dm b/code/modules/photography/camera/other.dm index 166517d055f..83e9a5fd28c 100644 --- a/code/modules/photography/camera/other.dm +++ b/code/modules/photography/camera/other.dm @@ -25,7 +25,13 @@ see_ghosts = CAMERA_SEE_GHOSTS_ORBIT /obj/item/camera/detective - name = "Detective's camera" - desc = "A polaroid camera with extra capacity for crime investigations." + name = "detective's camera" + desc = "A silent polaroid camera with extra capacity for crime investigations." + flash_enabled = FALSE + silent = TRUE pictures_max = 30 pictures_left = 30 + +/obj/item/camera/detective/after_picture(mob/user, datum/picture/picture) + . = ..() + user.playsound_local(get_turf(src), pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 35, TRUE)