mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-11 08:06:33 +01:00
d0a7f955f8
## About The Pull Request Commit messages should be descriptive of all changes. The "incorrect `\The` macro capitalization" was intentional when it was added, but as far as I know TG says "the supermatter" rather than "The Supermatter," so it's incorrect now. This is completely untested. I don't even know how you'd go about testing this, it's just a fuckton of strings. Someday I want to extract them and run NLP on it to catch grammar problems... ## Why It's Good For The Game Basic grammar pass for name strings. Should make `\the` work better and avoid cases like `the John Smith`.
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 [src] 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
|