diff --git a/code/datums/outfits/outfit_debug.dm b/code/datums/outfits/outfit_debug.dm
index 6da911d2337..40ad60665c7 100644
--- a/code/datums/outfits/outfit_debug.dm
+++ b/code/datums/outfits/outfit_debug.dm
@@ -95,10 +95,11 @@
/obj/item/clothing/glasses/hud/debug
name = "AVD-CNED glasses"
- desc = "Medical, security and diagnostic hud. Alt click to toggle xray."
+ desc = "Diagnostic, Hydroponic, Medical, Security, and Skills HUD. Built-in advanced reagent scanner. Alt-click to toggle X-ray vision."
icon_state = "nvgmeson"
flags_cover = GLASSESCOVERSEYES
flash_protect = FLASH_PROTECTION_WELDER
+ scan_reagents_advanced = TRUE
prescription_upgradable = FALSE
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 9e643b7f756..7c8d91b18b7 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -394,24 +394,53 @@
/atom/proc/build_reagent_description(mob/user)
. = list()
- if(reagents)
+ if(!reagents)
+ return
+ var/one_percent = reagents.total_volume / 100
+ var/blood_type = ""
+ if(user.advanced_reagent_vision()) // You can see absolute unit concentrations in transparent containers and % concentrations in opaque containers. You can also see blood types.
+ . += "It contains:"
+ if(!length(reagents.reagent_list))
+ . += "Nothing."
+ return
if(container_type & TRANSPARENT)
- . += "It contains:"
- if(length(reagents.reagent_list))
- if(user.can_see_reagents()) //Show each individual reagent
- for(var/I in reagents.reagent_list)
- var/datum/reagent/R = I
- . += "[R.volume] units of [R.name]"
- else //Otherwise, just show the total volume
- if(reagents && length(reagents.reagent_list))
- . += "[reagents.total_volume] units of various reagents."
+ for(var/I in reagents.reagent_list)
+ var/datum/reagent/R = I
+ if(R.id != "blood")
+ . += "[R.volume] units of [R] ([round(R.volume / one_percent)]%)"
+ else
+ blood_type = R.data["blood_type"]
+ . += "[R.volume] units of [R] ([blood_type ? "[blood_type]" : ""]) ([round(R.volume / one_percent)]%)"
+ return
+ // Opaque containers
+ for(var/datum/reagent/R in reagents.reagent_list)
+ if(R.id != "blood")
+ . += "[R] ([round(R.volume / one_percent)]%)"
else
- . += "Nothing."
- else if(container_type & AMOUNT_VISIBLE)
- if(reagents.total_volume)
- . += "It has [reagents.total_volume] unit\s left."
- else
- . += "It's empty."
+ blood_type = R.data["blood_type"]
+ . += "[R] ([blood_type ? "[blood_type]" : ""]) ([round(R.volume / one_percent)]%)"
+ return
+
+ if(container_type & TRANSPARENT)
+ . += "It contains:"
+ if(user.reagent_vision()) // You can see absolute unit quantities of reagents in transparent containers.
+ for(var/I in reagents.reagent_list)
+ var/datum/reagent/R = I
+ . += "[R.volume] units of [R] ([round(R.volume / one_percent)]%)"
+ return
+
+ //Otherwise, just show the total volume
+ if(length(reagents?.reagent_list))
+ . += "[reagents.total_volume] units of various reagents."
+ else
+ . += "Nothing."
+ return
+
+ if(container_type & AMOUNT_VISIBLE)
+ if(reagents.total_volume)
+ . += "It has [reagents.total_volume] unit\s left."
+ else
+ . += "It's empty."
/atom/proc/examine(mob/user, infix = "", suffix = "")
. = build_base_description(infix, suffix)
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 02350ef8814..054dfa99020 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -691,10 +691,10 @@ SLIME SCANNER
var/one_percent = O.reagents.total_volume / 100
for(var/datum/reagent/R in O.reagents.reagent_list)
if(R.id != "blood")
- dat += "
[TAB][R][details ? ": [R.volume / one_percent]%" : ""]"
+ dat += "
[TAB][R] [details ? ":([R.volume / one_percent]%)" : ""]"
else
blood_type = R.data["blood_type"]
- dat += "
[TAB][R][blood_type ? " [blood_type]" : ""][details ? ": [R.volume / one_percent]%" : ""]"
+ dat += "
[TAB][blood_type ? "[blood_type]" : ""] [R.name] [details ? ":([R.volume / one_percent]%)" : ""]"
if(dat)
to_chat(user, "Chemicals found: [dat]")
datatoprint = dat
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index a339ad902a0..afbbd575e83 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -3,8 +3,12 @@
max_integrity = 200
integrity_failure = 80
resistance_flags = FLAMMABLE
- var/list/species_restricted = null //Only these species can wear this kit.
- var/scan_reagents = 0 //Can the wearer see reagents while it's equipped?
+ /// Only these species can wear this kit.
+ var/list/species_restricted
+ /// Can the wearer see reagents inside transparent containers while it's equipped?
+ var/scan_reagents = FALSE
+ /// Can the wearer see reagents inside any container and identify blood types while it's equipped?
+ var/scan_reagents_advanced = FALSE
/*
Sprites used when the clothing item is refit. This is done by setting icon_override.
@@ -256,8 +260,8 @@
attack_verb = list("challenged")
var/transfer_prints = FALSE
///Master pickpocket?
- var/pickpocket = 0
- var/clipped = 0
+ var/pickpocket = FALSE
+ var/clipped = FALSE
///Do they protect the wearer from poison ink?
var/safe_from_poison = FALSE
strip_delay = 20
diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm
index 23a088d9f9d..38667b158bb 100644
--- a/code/modules/clothing/glasses/glasses.dm
+++ b/code/modules/clothing/glasses/glasses.dm
@@ -157,7 +157,7 @@
item_state = "glasses"
origin_tech = "magnets=2;engineering=1"
prescription_upgradable = TRUE
- scan_reagents = 1 //You can see reagents while wearing science goggles
+ scan_reagents = TRUE // You can see reagents while wearing science goggles
resistance_flags = ACID_PROOF
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 200, ACID = INFINITY)
sprite_sheets = list(
@@ -170,7 +170,7 @@
/obj/item/clothing/glasses/science/item_action_slot_check(slot)
if(slot == SLOT_HUD_GLASSES)
- return 1
+ return TRUE
/obj/item/clothing/glasses/science/night
name = "night vision science goggles"
@@ -371,7 +371,7 @@
/obj/item/clothing/glasses/sunglasses/noir/item_action_slot_check(slot)
if(slot == SLOT_HUD_GLASSES)
- return 1
+ return TRUE
/obj/item/clothing/glasses/sunglasses/noir/proc/toggle_noir(mob/user)
color_view = color_view ? null : MATRIX_GREYSCALE //Toggles between null and grayscale, with null being the default option.
@@ -399,8 +399,8 @@
/obj/item/clothing/glasses/sunglasses/reagent
name = "sunscanners"
- desc = "Strangely ancient technology used to help provide rudimentary eye cover. Outfitted with an apparatus to scan individual reagents, tech potentials, and machines internal components."
- scan_reagents = 1
+ desc = "Strangely ancient technology used to help provide rudimentary eye cover. Outfitted with an apparatus to scan individual reagents, tech potentials, and the internal components of machines."
+ scan_reagents = TRUE
actions_types = list(/datum/action/item_action/toggle_research_scanner)
/obj/item/clothing/glasses/sunglasses/reagent/item_action_slot_check(slot)
diff --git a/code/modules/mob/dead/observer/observer_base.dm b/code/modules/mob/dead/observer/observer_base.dm
index 7125defde13..1cecdbfa03e 100644
--- a/code/modules/mob/dead/observer/observer_base.dm
+++ b/code/modules/mob/dead/observer/observer_base.dm
@@ -705,7 +705,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
updateghostimages()
-/mob/dead/observer/can_see_reagents()
+/mob/dead/observer/advanced_reagent_vision() // Ghosts can see all the reagents inside things.
return TRUE
/proc/updateallghostimages()
diff --git a/code/modules/mob/living/carbon/human/human_mob.dm b/code/modules/mob/living/carbon/human/human_mob.dm
index d9c0e6b9032..2c3d81904c3 100644
--- a/code/modules/mob/living/carbon/human/human_mob.dm
+++ b/code/modules/mob/living/carbon/human/human_mob.dm
@@ -789,12 +789,12 @@
/mob/living/carbon/human/abiotic(full_body = 0)
if(full_body && ((src.l_hand && !(src.l_hand.flags & ABSTRACT)) || (src.r_hand && !(src.r_hand.flags & ABSTRACT)) || (src.back || src.wear_mask || src.head || src.shoes || src.w_uniform || src.wear_suit || src.glasses || src.l_ear || src.r_ear || src.gloves)))
- return 1
+ return TRUE
if((src.l_hand && !(src.l_hand.flags & ABSTRACT)) || (src.r_hand && !(src.r_hand.flags & ABSTRACT)))
- return 1
+ return TRUE
- return 0
+ return FALSE
/mob/living/carbon/human/proc/check_dna()
@@ -873,8 +873,8 @@
// Todo, check stomach organ when implemented.
var/obj/item/organ/external/head/H = get_organ("head")
if(!H || !H.can_intake_reagents)
- return 0
- return 1
+ return FALSE
+ return TRUE
/mob/living/carbon/human/proc/get_visible_gender()
var/list/obscured = check_obscured_slots()
@@ -1275,7 +1275,7 @@
set desc = "Use blood on your hands to write a short message on the floor or a wall, murder mystery style."
if(usr != src)
- return 0 //something is terribly wrong
+ return FALSE //something is terribly wrong
if(incapacitated())
to_chat(src, "You can't write on the floor in your current state!")
return
@@ -1652,15 +1652,25 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
return
return md5(dna.uni_identity)
-/mob/living/carbon/human/can_see_reagents() //If they have some glasses or helmet equipped that lets them see reagents, they can see reagents
+/mob/living/carbon/human/reagent_vision() // If they have some glasses or helmet equipped that lets them see reagents inside transparent containers, they can see them.
if(istype(head, /obj/item/clothing/head))
var/obj/item/clothing/head/hat = head
if(hat.scan_reagents)
- return 1
+ return TRUE
if(istype(glasses, /obj/item/clothing/glasses))
var/obj/item/clothing/rscan = glasses
if(rscan.scan_reagents)
- return 1
+ return TRUE
+
+/mob/living/carbon/human/advanced_reagent_vision() // If they have some glasses or helmet equipped that lets them see reagents inside everything, they can see reagents inside everything.
+ if(istype(head, /obj/item/clothing/head))
+ var/obj/item/clothing/head/hat = head
+ if(hat.scan_reagents_advanced)
+ return TRUE
+ if(istype(glasses, /obj/item/clothing/glasses))
+ var/obj/item/clothing/rscan = glasses
+ if(rscan.scan_reagents_advanced)
+ return TRUE
/mob/living/carbon/human/can_eat(flags = 255)
return dna.species && (dna.species.dietflags & flags)
@@ -1668,26 +1678,26 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
/mob/living/carbon/human/selfFeed(obj/item/food/toEat, fullness)
if(!check_has_mouth())
to_chat(src, "Where do you intend to put \the [toEat]? You don't have a mouth!")
- return 0
+ return FALSE
return ..()
/mob/living/carbon/human/forceFed(obj/item/food/toEat, mob/user, fullness)
if(!check_has_mouth())
if(!((istype(toEat, /obj/item/reagent_containers/drinks) && (ismachineperson(src)))))
to_chat(user, "Where do you intend to put \the [toEat]? \The [src] doesn't have a mouth!")
- return 0
+ return FALSE
return ..()
/mob/living/carbon/human/selfDrink(obj/item/reagent_containers/drinks/toDrink)
if(!check_has_mouth())
if(!ismachineperson(src))
to_chat(src, "Where do you intend to put \the [src]? You don't have a mouth!")
- return 0
+ return FALSE
else
to_chat(src, "You pour a bit of liquid from [toDrink] into your connection port.")
else
to_chat(src, "You swallow a gulp of [toDrink].")
- return 1
+ return TRUE
/mob/living/carbon/human/can_track(mob/living/user)
if(wear_id)
diff --git a/code/modules/mob/living/silicon/robot/robot_mob.dm b/code/modules/mob/living/silicon/robot/robot_mob.dm
index 959c3e8a6ab..057ed9a1f18 100644
--- a/code/modules/mob/living/silicon/robot/robot_mob.dm
+++ b/code/modules/mob/living/silicon/robot/robot_mob.dm
@@ -114,9 +114,9 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
var/datum/action/item_action/toggle_research_scanner/scanner = null
var/list/module_actions = list()
- var/see_reagents = FALSE // Determines if the cyborg can see reagents
+ var/has_advanced_reagent_vision = FALSE // Determines if the cyborg has advanced reagent vision.
- /// Integer used to determine self-mailing location, used only by drones and saboteur borgs
+ /// Integer used to determine self-mailing location, used only by drones and saboteur borgs.
var/mail_destination = 1
var/datum/ui_module/robot_self_diagnosis/self_diagnosis
var/datum/ui_module/destination_tagger/mail_setter
@@ -574,7 +574,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
if(camera && ("Robots" in camera.network))
camera.network += "Medical"
status_flags &= ~CANPUSH
- see_reagents = TRUE
+ has_advanced_reagent_vision = TRUE
if("Mining")
module = new /obj/item/robot_module/miner(src)
module.channels = list("Supply" = 1)
@@ -583,7 +583,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
if("Service")
module = new /obj/item/robot_module/butler(src)
module.channels = list("Service" = 1)
- see_reagents = TRUE
+ has_advanced_reagent_vision = TRUE
if(selected_sprite == "Bro")
module.module_type = "Brobot"
if("Combat")
@@ -1484,7 +1484,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
is_emaggable = FALSE
can_lock_cover = TRUE
default_cell_type = /obj/item/stock_parts/cell/bluespace
- see_reagents = TRUE
+ has_advanced_reagent_vision = TRUE
/mob/living/silicon/robot/deathsquad/init(alien = FALSE, connect_to_AI = TRUE, mob/living/silicon/ai/ai_to_sync_to = null)
laws = new /datum/ai_laws/deathsquad
@@ -1517,7 +1517,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
can_lock_cover = TRUE
default_cell_type = /obj/item/stock_parts/cell/super
var/eprefix = "Amber"
- see_reagents = TRUE
+ has_advanced_reagent_vision = TRUE
/mob/living/silicon/robot/ert/init(alien = FALSE, connect_to_AI = TRUE, mob/living/silicon/ai/ai_to_sync_to = null)
@@ -1573,7 +1573,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
damage_protection = 20 // Reduce all incoming damage by this number. Very high in the case of /destroyer borgs, since it is an admin-only borg.
can_lock_cover = TRUE
default_cell_type = /obj/item/stock_parts/cell/bluespace
- see_reagents = TRUE
+ has_advanced_reagent_vision = TRUE
/mob/living/silicon/robot/destroyer/init(alien = FALSE, connect_to_AI = TRUE, mob/living/silicon/ai/ai_to_sync_to = null)
aiCamera = new/obj/item/camera/siliconcam/robot_camera(src)
@@ -1692,8 +1692,8 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
playsound(loc, 'sound/machines/warning-buzzer.ogg', 75, TRUE)
to_chat(src, "CRITICAL ERROR: All modules OFFLINE.")
-/mob/living/silicon/robot/can_see_reagents()
- return see_reagents
+/mob/living/silicon/robot/advanced_reagent_vision()
+ return has_advanced_reagent_vision
/mob/living/silicon/robot/verb/powerwarn()
set category = "Robot Commands"
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index 8a2af85852e..5e8d534d65a 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -333,7 +333,6 @@
/obj/item/crowbar/cyborg/red,
/obj/item/healthanalyzer/advanced,
/obj/item/robotanalyzer,
- /obj/item/reagent_scanner/adv,
/obj/item/borg_defib,
/obj/item/handheld_defibrillator,
/obj/item/roller_holder,
@@ -600,7 +599,6 @@
/obj/item/razor,
/obj/item/instrument/piano_synth,
/obj/item/healthanalyzer/advanced,
- /obj/item/reagent_scanner/adv,
/obj/item/rsf,
/obj/item/reagent_containers/dropper/cyborg,
/obj/item/lighter/zippo,
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 9b68f235181..e5543649cfc 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -1077,8 +1077,12 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
return TRUE
-//Can the mob see reagents inside of containers?
-/mob/proc/can_see_reagents()
+// Can the mob see reagents inside of transparent containers?
+/mob/proc/reagent_vision()
+ return FALSE
+
+// Can the mob see reagents inside any container and also identify blood types?
+/mob/proc/advanced_reagent_vision()
return FALSE
//Can this mob leave its location without breaking things terrifically?