mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-29 18:40:42 +00:00
## About The Pull Request adds the forensics spoofing kit for 5tc to the uplink (is it really a kit if its only the item and instructions?)    silent mode: if off the scanner will make sounds and messages like a forensics scanner if used (Elliot Wardle points the forensic scanner at the reinforced wall and performs a forensic scan.) scan mode: scans stuff for NEWLY discovered fibers and fingerprint, stores them the scanner may only hold 5 each of fibers and prints the scanner reads sec records to display names next to fingerprints apply mode: it adds the fiber/fingerprint to whatever you use it on ## Why It's Good For The Game as it is right now forensics scanners are basically a guaranteed "this guy is an antag" if they scan anything syndicate related and find your prints on it (or fibers). that is not ideal because you will spend the next 30 minutes of your time getting trolled in the permabrig by security with this item you (traitor) get the benefit of the doubt which is good and makes detectives legit use their brain beyond CTRL+C CTRL+V on sec records ## Changelog 🆑 add: forensics spoofing kit for traitors/whoever with an uplink /🆑
199 lines
7.4 KiB
Plaintext
199 lines
7.4 KiB
Plaintext
/obj/item/forensics_spoofer
|
|
name = /obj/item/detective_scanner::name
|
|
desc = "Used to adjacently scan objects and biomass for fibers and fingerprints. Can replicate the findings."
|
|
icon = /obj/item/detective_scanner::icon
|
|
icon_state = /obj/item/detective_scanner::icon_state
|
|
w_class = WEIGHT_CLASS_SMALL
|
|
inhand_icon_state = /obj/item/detective_scanner::inhand_icon_state
|
|
worn_icon_state = /obj/item/detective_scanner::worn_icon_state
|
|
lefthand_file = /obj/item/detective_scanner::lefthand_file
|
|
righthand_file = /obj/item/detective_scanner::righthand_file
|
|
obj_flags = CONDUCTS_ELECTRICITY
|
|
item_flags = NOBLUDGEON
|
|
slot_flags = ITEM_SLOT_BELT
|
|
/// stored fibers in memory
|
|
var/list/fibers = list()
|
|
/// stored fingerprints in memory
|
|
var/list/fingerprints = list()
|
|
/// chosen fiber to add to target
|
|
var/chosen_fiber
|
|
/// chosen fingerprint to add to target
|
|
var/chosen_fingerprint
|
|
/// max storage for fibers/fingerprints seperate for each
|
|
var/max_storage = 5
|
|
/// do we scan for new material? if false will tamper
|
|
var/scan_mode = TRUE
|
|
/// do we make forensics scanner messages and sounds
|
|
var/silent_mode = FALSE
|
|
/// tamper cooldown time so people dont spam it on every single wall and thing ever
|
|
var/tamper_cooldown_time = 1 SECONDS
|
|
COOLDOWN_DECLARE(tamper_cooldown)
|
|
|
|
/obj/item/forensics_spoofer/Initialize(mapload)
|
|
. = ..()
|
|
// most things have add_fingerprint in their item interaction because lol lmao
|
|
// tl;dr cut off the chain before anything fires so we dont add user fingerprints to target
|
|
RegisterSignal(src, COMSIG_ITEM_INTERACTING_WITH_ATOM, PROC_REF(do_interact))
|
|
|
|
/obj/item/forensics_spoofer/attack_self_secondary(mob/user, modifiers)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
scan_mode = !scan_mode
|
|
balloon_alert(user, "now [scan_mode ? "scanning" : "applying"]")
|
|
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
|
|
|
// ok due to shenanigans basically every item interact adds your fingerprints to it which isnt ideal so we have this
|
|
/obj/item/forensics_spoofer/proc/do_interact(datum/source, mob/living/user, atom/interacting_with, list/modifiers)
|
|
SIGNAL_HANDLER
|
|
if(scan_mode)
|
|
INVOKE_ASYNC(src, PROC_REF(scan), interacting_with, user)
|
|
else
|
|
tamper(interacting_with, user, do_fibers = !isnull(chosen_fiber))
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/item/forensics_spoofer/proc/do_fake_scan(atom/target, mob/user)
|
|
if(silent_mode)
|
|
return
|
|
playsound(src, SFX_INDUSTRIAL_SCAN, 20, TRUE, -2, TRUE, FALSE)
|
|
user.visible_message(
|
|
span_notice("\The [user] points the [name] at \the [target] and performs a forensic scan.")
|
|
)
|
|
|
|
/obj/item/forensics_spoofer/proc/clear_values(list/the_list)
|
|
for(var/key in the_list)
|
|
the_list[key] = ""
|
|
|
|
/obj/item/forensics_spoofer/proc/scan(atom/target, mob/living/user)
|
|
do_fake_scan(target, user)
|
|
if(isnull(target.forensics))
|
|
target.balloon_alert(user, "nothing!")
|
|
return ITEM_INTERACT_FAILURE
|
|
var/list/new_fibers = LAZYCOPY(target.forensics.fibers) - fibers
|
|
var/list/new_prints = LAZYCOPY(target.forensics.fingerprints) - fingerprints
|
|
var/new_len = length(new_fibers) + length(new_prints)
|
|
balloon_alert(user, "[new_len ? new_len : "no"] new prints/fibers")
|
|
if(new_len)
|
|
var/list/message = list(span_bold("Scan results (Unstored Only):"))
|
|
for(var/text in new_fibers)
|
|
message += span_notice("Fiber: [text]")
|
|
if(length(fibers) > max_storage)
|
|
message += span_boldwarning("Fiber storage full.")
|
|
for(var/text in new_prints)
|
|
message += span_notice("Fingerprint: [text]")
|
|
if(length(fingerprints) > max_storage)
|
|
message += span_boldwarning("Fingerprint storage full.")
|
|
to_chat(user, boxed_message(jointext(message, "\n")), type = MESSAGE_TYPE_INFO)
|
|
if(length(fingerprints) < max_storage)
|
|
while(length(fingerprints) + length(new_prints) > max_storage)
|
|
var/to_remove = tgui_input_list(user, "Too many prints, cancel to discard all", "What to discard", new_fibers)
|
|
if(isnull(to_remove))
|
|
return ITEM_INTERACT_FAILURE
|
|
new_prints -= to_remove
|
|
clear_values(new_prints)
|
|
fingerprints += new_prints
|
|
for(var/fingerprint in fingerprints)
|
|
fingerprints[fingerprint] = get_name_from_fingerprint(fingerprint)
|
|
if(length(fibers) < max_storage)
|
|
while(length(fibers) + length(new_fibers) > max_storage)
|
|
var/to_remove = tgui_input_list(user, "Too many prints, cancel to discard all", "What to discard", new_fibers)
|
|
if(isnull(to_remove))
|
|
return ITEM_INTERACT_FAILURE
|
|
new_fibers -= to_remove
|
|
clear_values(new_fibers)
|
|
fibers += new_fibers
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/item/forensics_spoofer/proc/tamper(atom/target, mob/living/user, do_fibers = FALSE)
|
|
do_fake_scan(target, user)
|
|
if((!do_fibers && isnull(chosen_fingerprint)) || (do_fibers && isnull(chosen_fiber)))
|
|
balloon_alert(user, "no [do_fibers ? "fiber" : "fingerprint"] selected!") // we CAN automatically select it but if they dont have it selected then they likely didnt know of it in the first place so they learn it now
|
|
return ITEM_INTERACT_FAILURE
|
|
if(!COOLDOWN_FINISHED(src, tamper_cooldown))
|
|
balloon_alert(user, "please wait!")
|
|
return ITEM_INTERACT_FAILURE
|
|
if(!isnull(target.forensics) && LAZYFIND(do_fibers ? target.forensics.fibers : target.forensics.fingerprints, do_fibers ? chosen_fiber : chosen_fingerprint))
|
|
balloon_alert(user, "already present!")
|
|
return ITEM_INTERACT_FAILURE
|
|
|
|
if(do_fibers)
|
|
target.add_fiber_list(list(chosen_fiber))
|
|
user.log_message("has tampered with the fingerprints/fibers of [src]. Added [chosen_fiber]", LOG_ATTACK)
|
|
else
|
|
target.add_fingerprint_list(list(chosen_fingerprint))
|
|
user.log_message("has tampered with the fingerprints/fibers of [src]. Added [chosen_fingerprint]", LOG_ATTACK)
|
|
|
|
target.balloon_alert(user, "[do_fibers ? "fiber" : "fingerprint"] added")
|
|
target.add_hiddenprint(user)
|
|
COOLDOWN_START(src, tamper_cooldown, tamper_cooldown_time)
|
|
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/item/forensics_spoofer/proc/get_name_from_fingerprint(fingerprint)
|
|
. = "Unknown"
|
|
for(var/datum/record/crew/player_record as anything in GLOB.manifest.general)
|
|
if(player_record.fingerprint != fingerprint)
|
|
continue
|
|
return player_record.name
|
|
|
|
/obj/item/forensics_spoofer/ui_state(mob/user)
|
|
return GLOB.hands_state
|
|
|
|
/obj/item/forensics_spoofer/ui_interact(mob/user, datum/tgui/ui)
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if(!ui)
|
|
ui = new(user, src, "ForensicsSpoofer", name)
|
|
ui.open()
|
|
|
|
/obj/item/forensics_spoofer/ui_static_data(mob/user)
|
|
. = list(
|
|
"max_storage" = max_storage,
|
|
)
|
|
|
|
/obj/item/forensics_spoofer/ui_data(mob/user)
|
|
return list(
|
|
"scanmode" = scan_mode,
|
|
"silent" = silent_mode,
|
|
"fibers" = fibers,
|
|
"fingerprints" = fingerprints,
|
|
"chosen_fiber" = chosen_fiber,
|
|
"chosen_fingerprint" = chosen_fingerprint,
|
|
)
|
|
|
|
/obj/item/forensics_spoofer/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
if(!isnull(params["chosen"])) //fiber/print actions
|
|
var/chosen = params["chosen"]
|
|
switch(action)
|
|
if("delete")
|
|
if(chosen in fibers)
|
|
if(chosen_fiber == chosen)
|
|
chosen_fiber = null
|
|
fibers -= chosen
|
|
else
|
|
if(chosen_fingerprint == chosen)
|
|
chosen_fingerprint = null
|
|
fingerprints -= chosen
|
|
return TRUE
|
|
if("choose")
|
|
var/is_fiber = !!(chosen in fibers)
|
|
chosen_fiber = is_fiber ? chosen : null
|
|
chosen_fingerprint = is_fiber ? null : chosen
|
|
return TRUE
|
|
if("make_note")
|
|
if(chosen in fibers)
|
|
fibers[chosen] = params["note"]
|
|
else
|
|
fingerprints[chosen] = params["note"]
|
|
return TRUE
|
|
else
|
|
switch(action)
|
|
if("scanmode")
|
|
scan_mode = !scan_mode
|
|
return TRUE
|
|
if("stealth")
|
|
silent_mode = !silent_mode
|
|
return TRUE
|