diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 2f5e49b0709..525f6c636df 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -151,6 +151,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
SSpoints_of_interest.make_point_of_interest(src)
ADD_TRAIT(src, TRAIT_HEAR_THROUGH_DARKNESS, ref(src))
+ ADD_TRAIT(src, TRAIT_SECURITY_HUD, ref(src))
/mob/dead/observer/get_photo_description(obj/item/camera/camera)
if(!invisibility || camera.see_ghosts)
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 0a9c7c49bd9..1a1827e198f 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -383,7 +383,7 @@
. += "\[See quirks\]"
if(HAS_TRAIT(user, TRAIT_SECURITY_HUD))
- if(!user.stat && user != src)
+ if((user.stat == CONSCIOUS || isobserver(user)) && user != src)
//|| !user.canmove || user.restrained()) Fluff: Sechuds have eye-tracking technology and sets 'arrest' to people that the wearer looks and blinks at.
var/wanted_status = WANTED_NONE
var/security_note = "None."
@@ -393,13 +393,16 @@
wanted_status = target_record.wanted_status
if(target_record.security_note)
security_note = target_record.security_note
-
- . += "Criminal status: \[[wanted_status]\]"
+ if(ishuman(user))
+ . += "Criminal status: \[[wanted_status]\]"
+ else
+ . += "Criminal status: [wanted_status]"
. += "Important Notes: [security_note]"
- . += jointext(list("Security record: \[View\]",
- "\[Add citation\]",
- "\[Add crime\]",
- "\[Add note\]"), "")
+ . += "Security record: \[View\]"
+ if(ishuman(user))
+ . += jointext(list("\[Add citation\]",
+ "\[Add crime\]",
+ "\[Add note\]"), "")
else if(isobserver(user))
. += span_info("Quirks: [get_quirk_string(FALSE, CAT_QUIRK_ALL)]")
. += ""
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index ce4f93d99c1..4d71c556736 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -94,22 +94,24 @@
///////HUDs///////
if(href_list["hud"])
- if(!ishuman(usr))
+ if(!ishuman(usr) && !isobserver(usr))
return
- var/mob/living/carbon/human/human_user = usr
+ var/mob/human_or_ghost_user = usr
var/perpname = get_face_name(get_id_name(""))
- if(!HAS_TRAIT(human_user, TRAIT_SECURITY_HUD) && !HAS_TRAIT(human_user, TRAIT_MEDICAL_HUD))
+ if(!HAS_TRAIT(human_or_ghost_user, TRAIT_SECURITY_HUD) && !HAS_TRAIT(human_or_ghost_user, TRAIT_MEDICAL_HUD))
return
if((text2num(href_list["examine_time"]) + 1 MINUTES) < world.time)
- to_chat(human_user, "[span_notice("It's too late to use this now!")]")
+ to_chat(human_or_ghost_user, "[span_notice("It's too late to use this now!")]")
return
var/datum/record/crew/target_record = find_record(perpname)
if(href_list["photo_front"] || href_list["photo_side"])
if(!target_record)
return
- if(!human_user.canUseHUD())
- return
- if(!HAS_TRAIT(human_user, TRAIT_SECURITY_HUD) && !HAS_TRAIT(human_user, TRAIT_MEDICAL_HUD))
+ if(ishuman(human_or_ghost_user))
+ var/mob/living/carbon/human/human_user = human_or_ghost_user
+ if(!human_user.canUseHUD())
+ return
+ if(!HAS_TRAIT(human_or_ghost_user, TRAIT_SECURITY_HUD) && !HAS_TRAIT(human_or_ghost_user, TRAIT_MEDICAL_HUD))
return
var/obj/item/photo/photo_from_record = null
if(href_list["photo_front"])
@@ -117,10 +119,11 @@
else if(href_list["photo_side"])
photo_from_record = target_record.get_side_photo()
if(photo_from_record)
- photo_from_record.show(human_user)
+ photo_from_record.show(human_or_ghost_user)
return
- if(href_list["hud"] == "m")
+ if(ishuman(human_or_ghost_user) && href_list["hud"] == "m")
+ var/mob/living/carbon/human/human_user = human_or_ghost_user
if(!HAS_TRAIT(human_user, TRAIT_MEDICAL_HUD))
return
if(href_list["evaluation"])
@@ -198,33 +201,36 @@
return //Medical HUD ends here.
if(href_list["hud"] == "s")
- if(!HAS_TRAIT(human_user, TRAIT_SECURITY_HUD))
- return
- if(human_user.stat || human_user == src) //|| !human_user.canmove || human_user.restrained()) Fluff: Sechuds have eye-tracking technology and sets 'arrest' to people that the wearer looks and blinks at.
- return //Non-fluff: This allows sec to set people to arrest as they get disarmed or beaten
- // Checks the user has security clearence before allowing them to change arrest status via hud, comment out to enable all access
var/allowed_access = null
- var/obj/item/clothing/glasses/hud/security/user_glasses = human_user.glasses
- if(istype(user_glasses) && (user_glasses.obj_flags & EMAGGED))
- allowed_access = "@%&ERROR_%$*"
- else //Implant and standard glasses check access
- if(human_user.wear_id)
- var/list/access = human_user.wear_id.GetAccess()
- if(ACCESS_SECURITY in access)
- allowed_access = human_user.get_authentification_name()
-
- if(!allowed_access)
- to_chat(human_user, span_warning("ERROR: Invalid access."))
+ if(!HAS_TRAIT(human_or_ghost_user, TRAIT_SECURITY_HUD))
return
+ if(ishuman(human_or_ghost_user))
+ var/mob/living/carbon/human/human_user = human_or_ghost_user
+ if(human_user.stat || human_user == src) //|| !human_user.canmove || human_user.restrained()) Fluff: Sechuds have eye-tracking technology and sets 'arrest' to people that the wearer looks and blinks at.
+ return //Non-fluff: This allows sec to set people to arrest as they get disarmed or beaten
+ // Checks the user has security clearence before allowing them to change arrest status via hud, comment out to enable all access
+ var/obj/item/clothing/glasses/hud/security/user_glasses = human_user.glasses
+ if(istype(user_glasses) && (user_glasses.obj_flags & EMAGGED))
+ allowed_access = "@%&ERROR_%$*"
+ else //Implant and standard glasses check access
+ if(human_user.wear_id)
+ var/list/access = human_user.wear_id.GetAccess()
+ if(ACCESS_SECURITY in access)
+ allowed_access = human_user.get_authentification_name()
+
+ if(!allowed_access)
+ to_chat(human_user, span_warning("ERROR: Invalid access."))
+ return
if(!perpname)
- to_chat(human_user, span_warning("ERROR: Can not identify target."))
+ to_chat(human_or_ghost_user, span_warning("ERROR: Can not identify target."))
return
target_record = find_record(perpname)
if(!target_record)
- to_chat(human_user, span_warning("ERROR: Unable to locate data core entry for target."))
+ to_chat(human_or_ghost_user, span_warning("ERROR: Unable to locate data core entry for target."))
return
- if(href_list["status"])
+ if(ishuman(human_or_ghost_user) && href_list["status"])
+ var/mob/living/carbon/human/human_user = human_or_ghost_user
var/new_status = tgui_input_list(human_user, "Specify a new criminal status for this person.", "Security HUD", WANTED_STATUSES(), target_record.wanted_status)
if(!new_status || !target_record || !human_user.canUseHUD() || !HAS_TRAIT(human_user, TRAIT_SECURITY_HUD))
return
@@ -240,66 +246,69 @@
return
if(href_list["view"])
- if(!human_user.canUseHUD())
+ if(ishuman(human_or_ghost_user))
+ var/mob/living/carbon/human/human_user = human_or_ghost_user
+ if(!human_user.canUseHUD())
+ return
+ if(!HAS_TRAIT(human_or_ghost_user, TRAIT_SECURITY_HUD))
return
- if(!HAS_TRAIT(human_user, TRAIT_SECURITY_HUD))
- return
- to_chat(human_user, "Name: [target_record.name]")
- to_chat(human_user, "Criminal Status: [target_record.wanted_status]")
- to_chat(human_user, "Citations: [length(target_record.citations)]")
- to_chat(human_user, "Note: [target_record.security_note || "None"]")
- to_chat(human_user, "Rapsheet: [length(target_record.crimes)] incidents")
+ var/sec_record_message = ""
+ sec_record_message += "Name: [target_record.name]"
+ sec_record_message += "\nCriminal Status: [target_record.wanted_status]"
+ sec_record_message += "\nCitations: [length(target_record.citations)]"
+ sec_record_message += "\nNote: [target_record.security_note || "None"]"
+ sec_record_message += "\nRapsheet: [length(target_record.crimes)] incidents"
if(length(target_record.crimes))
for(var/datum/crime/crime in target_record.crimes)
if(!crime.valid)
- to_chat(human_user, span_notice("-- REDACTED --"))
+ sec_record_message += span_notice("\n-- REDACTED --")
continue
- to_chat(human_user, "Crime: [crime.name]")
- to_chat(human_user, "Details: [crime.details]")
- to_chat(human_user, "Added by [crime.author] at [crime.time]")
- to_chat(human_user, "----------")
-
+ sec_record_message += "\nCrime: [crime.name]"
+ sec_record_message += "\nDetails: [crime.details]"
+ sec_record_message += "\nAdded by [crime.author] at [crime.time]"
+ to_chat(human_or_ghost_user, examine_block(sec_record_message))
return
+ if(ishuman(human_or_ghost_user))
+ var/mob/living/carbon/human/human_user = human_or_ghost_user
+ if(href_list["add_citation"])
+ var/max_fine = CONFIG_GET(number/maxfine)
+ var/citation_name = tgui_input_text(human_user, "Citation crime", "Security HUD")
+ var/fine = tgui_input_number(human_user, "Citation fine", "Security HUD", 50, max_fine, 5)
+ if(!fine || !target_record || !citation_name || !allowed_access || !isnum(fine) || fine > max_fine || fine <= 0 || !human_user.canUseHUD() || !HAS_TRAIT(human_user, TRAIT_SECURITY_HUD))
+ return
+
+ var/datum/crime/citation/new_citation = new(name = citation_name, author = allowed_access, fine = fine)
+
+ target_record.citations += new_citation
+ new_citation.alert_owner(usr, src, target_record.name, "You have been fined [fine] credits for '[citation_name]'. Fines may be paid at security.")
+ investigate_log("New Citation: [citation_name] Fine: [fine] | Added to [target_record.name] by [key_name(human_user)]", INVESTIGATE_RECORDS)
+ SSblackbox.ReportCitation(REF(new_citation), human_user.ckey, human_user.real_name, target_record.name, citation_name, fine)
- if(href_list["add_citation"])
- var/max_fine = CONFIG_GET(number/maxfine)
- var/citation_name = tgui_input_text(human_user, "Citation crime", "Security HUD")
- var/fine = tgui_input_number(human_user, "Citation fine", "Security HUD", 50, max_fine, 5)
- if(!fine || !target_record || !citation_name || !allowed_access || !isnum(fine) || fine > max_fine || fine <= 0 || !human_user.canUseHUD() || !HAS_TRAIT(human_user, TRAIT_SECURITY_HUD))
return
- var/datum/crime/citation/new_citation = new(name = citation_name, author = allowed_access, fine = fine)
+ if(href_list["add_crime"])
+ var/crime_name = tgui_input_text(human_user, "Crime name", "Security HUD")
+ if(!target_record || !crime_name || !allowed_access || !human_user.canUseHUD() || !HAS_TRAIT(human_user, TRAIT_SECURITY_HUD))
+ return
- target_record.citations += new_citation
- new_citation.alert_owner(usr, src, target_record.name, "You have been fined [fine] credits for '[citation_name]'. Fines may be paid at security.")
- investigate_log("New Citation: [citation_name] Fine: [fine] | Added to [target_record.name] by [key_name(human_user)]", INVESTIGATE_RECORDS)
- SSblackbox.ReportCitation(REF(new_citation), human_user.ckey, human_user.real_name, target_record.name, citation_name, fine)
+ var/datum/crime/new_crime = new(name = crime_name, author = allowed_access)
- return
+ target_record.crimes += new_crime
+ investigate_log("New Crime: [crime_name] | Added to [target_record.name] by [key_name(human_user)]", INVESTIGATE_RECORDS)
+ to_chat(human_user, span_notice("Successfully added a crime."))
- if(href_list["add_crime"])
- var/crime_name = tgui_input_text(human_user, "Crime name", "Security HUD")
- if(!target_record || !crime_name || !allowed_access || !human_user.canUseHUD() || !HAS_TRAIT(human_user, TRAIT_SECURITY_HUD))
return
- var/datum/crime/new_crime = new(name = crime_name, author = allowed_access)
+ if(href_list["add_note"])
+ var/new_note = tgui_input_text(human_user, "Security note", "Security Records", multiline = TRUE)
+ if(!target_record || !new_note || !allowed_access || !human_user.canUseHUD() || !HAS_TRAIT(human_user, TRAIT_SECURITY_HUD))
+ return
- target_record.crimes += new_crime
- investigate_log("New Crime: [crime_name] | Added to [target_record.name] by [key_name(human_user)]", INVESTIGATE_RECORDS)
- to_chat(human_user, span_notice("Successfully added a crime."))
+ target_record.security_note = new_note
- return
-
- if(href_list["add_note"])
- var/new_note = tgui_input_text(human_user, "Security note", "Security Records", multiline = TRUE)
- if(!target_record || !new_note || !allowed_access || !human_user.canUseHUD() || !HAS_TRAIT(human_user, TRAIT_SECURITY_HUD))
return
- target_record.security_note = new_note
-
- return
-
..() //end of this massive fucking chain. TODO: make the hud chain not spooky. - Yeah, great job doing that.
//called when something steps onto a human