diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index cf741294f8e..d69691cc5fe 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -733,6 +733,13 @@ BREATH ANALYZER
var/obj/item/paper/medscan/R = new /obj/item/paper/medscan(src, connected.format_occupant_data(get_occupant_data(M)), "Scan ([M.name]) ([worldtime2text()])", M)
connected.print(R, message = "\The [src] beeps, printing \the [R] after a moment.", user = user)
+/// Variant of print_scan(), main difference is different method to print the paper
+/obj/item/device/advanced_healthanalyzer/cyborg/print_scan(var/mob/M, var/mob/living/user)
+ var/obj/item/paper/medscan/R = new /obj/item/paper/medscan(src, connected.format_occupant_data(get_occupant_data(M)), "Scan ([M.name]) ([worldtime2text()])", M)
+ user.visible_message(SPAN_NOTICE("\The [src] beeps, printing \the [R] after a moment."))
+ playsound(user.loc, /singleton/sound_category/print_sound, 50, 1)
+ R.forceMove(user.loc)
+
/obj/item/device/advanced_healthanalyzer/proc/get_occupant_data(var/mob/living/carbon/human/H)
if (!ishuman(H))
return
diff --git a/code/modules/heavy_vehicle/equipment/medical.dm b/code/modules/heavy_vehicle/equipment/medical.dm
index a0894a4fe06..9f906dcc6a9 100644
--- a/code/modules/heavy_vehicle/equipment/medical.dm
+++ b/code/modules/heavy_vehicle/equipment/medical.dm
@@ -280,17 +280,27 @@
restricted_hardpoints = list(HARDPOINT_LEFT_HAND, HARDPOINT_RIGHT_HAND)
restricted_software = list(MECH_SOFTWARE_MEDICAL)
-/obj/item/device/healthanalyzer/mech //Used to set up the full body scan feature
- var/obj/machinery/body_scanconsole/internal_bodyscanner = null
- var/fullScan = FALSE //Toggle whether to do full or basic scan
+/// Special health analyzer used by the exosuit health analyzer.
+/obj/item/device/healthanalyzer/mech
+ name = "mounted health analyzer"
+ var/obj/machinery/body_scanconsole/connected = null
+ /// Toggle whether to do full or basic scan
+ var/fullScan = FALSE
+
+/obj/item/device/healthanalyzer/mech/get_hardpoint_maptext()
+ return "[(fullScan ? "Full" : "Basic")]"
/obj/item/device/healthanalyzer/mech/Initialize()
. = ..()
- internal_bodyscanner = new /obj/machinery/body_scanconsole(src)
- internal_bodyscanner.use_power = FALSE
+ if(!connected)
+ var/obj/machinery/body_scanconsole/S = new (src)
+ S.forceMove(src)
+ S.update_use_power(POWER_USE_OFF)
+ connected = S
/obj/item/device/healthanalyzer/mech/Destroy()
- QDEL_NULL(internal_bodyscanner)
+ if(connected)
+ QDEL_NULL(connected)
. = ..()
/obj/item/mecha_equipment/mounted_system/medanalyzer/CtrlClick(mob/user)
@@ -298,38 +308,92 @@
if(istype(HA))
HA.fullScan = !HA.fullScan
to_chat(user, SPAN_NOTICE("You switch to \the [src]'s [HA.fullScan ? "full body" : "basic"] scan mode."))
+ if(HA.fullScan)
+ icon_state = "mecha_healthyanalyzer_alt"
+ else
+ icon_state = "mecha_healthyanalyzer"
+ update_icon()
+ owner.update_icon()
/obj/item/device/healthanalyzer/mech/attack(mob/living/target_mob, mob/living/user, target_zone)
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)
user.do_attack_animation(src)
+ var/mob/living/heavy_vehicle/user_vehicle = user
+ if(!istype(user_vehicle))
+ to_chat(user, SPAN_NOTICE("Only Exosuits can handle this equipment!"))
+ return FALSE
if(!fullScan)
- var/mob/living/heavy_vehicle/user_vehicle = user
- if(istype(user_vehicle))
- for(var/mob/pilot in user_vehicle.pilots)
- health_scan_mob(target_mob, pilot, TRUE, TRUE, sound_scan = TRUE)
+ for(var/mob/pilot in user_vehicle.pilots)
+ health_scan_mob(target_mob, pilot, TRUE, TRUE, sound_scan = TRUE)
else
- user.visible_message("[user] starts scanning \the [target_mob] with \the [src].",
+ user_vehicle.visible_message("[user_vehicle] starts scanning \the [target_mob] with \the [src].",
SPAN_NOTICE("You start scanning \the [target_mob] with \the [src]."))
- if(do_after(user, 7 SECONDS))
- print_scan(target_mob, user)
- add_fingerprint(user)
+ for(var/mob/pilot in user_vehicle.pilots)
+ if(!do_after(pilot, 7 SECONDS, target_mob, (DO_DEFAULT & ~DO_USER_CAN_TURN) | DO_USER_UNIQUE_ACT | DO_FAIL_FEEDBACK)) // Pilots must not move while scanning
+ return FALSE
+ print_scan(target_mob, user_vehicle)
-/obj/item/device/healthanalyzer/mech/proc/print_scan(var/mob/M, var/mob/living/user)
- var/obj/item/paper/medscan/R = new /obj/item/paper/medscan(user.loc, internal_bodyscanner.format_occupant_data(get_medical_data(M)), "Scan ([M.name])", M)
- if(ishuman(user) && !(user.l_hand && user.r_hand))
- user.put_in_hands(R)
- user.visible_message(SPAN_NOTICE("\The [src] spits out a piece of paper."))
+/obj/item/device/healthanalyzer/mech/proc/print_scan(var/mob/M, var/mob/living/heavy_vehicle/user_vehicle)
+ var/obj/item/paper/medscan/R = new /obj/item/paper/medscan(user_vehicle.loc, connected.format_occupant_data(get_medical_data(M)), "Scan ([M.name])", M)
+ for(var/mob/pilot in user_vehicle.pilots)
+ R.show_content(pilot)
+ user_vehicle.visible_message(SPAN_NOTICE("\The [src] spits out a piece of paper."))
+ playsound(user_vehicle.loc, /singleton/sound_category/print_sound, 50, 1)
+ R.forceMove(user_vehicle.loc)
/obj/item/device/healthanalyzer/mech/proc/get_medical_data(var/mob/living/carbon/human/H)
if (!ishuman(H))
return
- var/list/medical_data = list(
+ var/displayed_stat = H.stat
+ var/blood_oxygenation = H.get_blood_oxygenation()
+ if(H.status_flags & FAKEDEATH)
+ displayed_stat = DEAD
+ blood_oxygenation = min(blood_oxygenation, BLOOD_VOLUME_SURVIVE)
+ switch(displayed_stat)
+ if(CONSCIOUS)
+ displayed_stat = "Conscious"
+ if(UNCONSCIOUS)
+ displayed_stat = "Unconscious"
+ if(DEAD)
+ displayed_stat = "DEAD"
+
+ var/pulse_result
+ if(H.should_have_organ(BP_HEART))
+ var/obj/item/organ/internal/heart/heart = H.internal_organs_by_name[BP_HEART]
+ if(!heart)
+ pulse_result = 0
+ else if(BP_IS_ROBOTIC(heart))
+ pulse_result = -2
+ else if(H.status_flags & FAKEDEATH)
+ pulse_result = 0
+ else
+ pulse_result = H.get_pulse(GETPULSE_TOOL)
+ else
+ pulse_result = -1
+
+ if(pulse_result == ">250")
+ pulse_result = -3
+
+ var/datum/reagents/R = H.bloodstr
+
+ connected.has_internal_injuries = FALSE
+ connected.has_external_injuries = FALSE
+ var/list/bodyparts = connected.get_external_wound_data(H)
+ var/list/organs = connected.get_internal_wound_data(H)
+
+ var/list/occupant_data = list(
"stationtime" = worldtime2text(),
+ "stat" = displayed_stat,
+ "name" = H.name,
+ "species" = H.get_species(),
+
"brain_activity" = H.get_brain_status(),
+ "pulse" = text2num(pulse_result),
"blood_volume" = H.get_blood_volume(),
"blood_oxygenation" = H.get_blood_oxygenation(),
"blood_pressure" = H.get_blood_pressure(),
+ "blood_type" = H.dna.b_type,
"bruteloss" = get_severity(H.getBruteLoss(), TRUE),
"fireloss" = get_severity(H.getFireLoss(), TRUE),
@@ -341,18 +405,18 @@
"paralysis" = H.paralysis,
"bodytemp" = H.bodytemperature,
"borer_present" = H.has_brain_worms(),
- "inaprovaline_amount" = REAGENT_VOLUME(H.reagents, /singleton/reagent/inaprovaline),
- "dexalin_amount" = REAGENT_VOLUME(H.reagents, /singleton/reagent/dexalin),
- "stoxin_amount" = REAGENT_VOLUME(H.reagents, /singleton/reagent/soporific),
- "bicaridine_amount" = REAGENT_VOLUME(H.reagents, /singleton/reagent/bicaridine),
- "dermaline_amount" = REAGENT_VOLUME(H.reagents, /singleton/reagent/dermaline),
- "thetamycin_amount" = REAGENT_VOLUME(H.reagents, /singleton/reagent/thetamycin),
- "blood_amount" = REAGENT_VOLUME(H.vessel, /singleton/reagent/blood),
- "disabilities" = H.sdisabilities,
- "lung_ruptured" = H.is_lung_ruptured(),
- "lung_rescued" = H.is_lung_rescued(),
- "external_organs" = H.organs.Copy(),
- "internal_organs" = H.internal_organs.Copy(),
- "species_organs" = H.species.has_organ
+ "inaprovaline_amount" = REAGENT_VOLUME(R, /singleton/reagent/inaprovaline),
+ "dexalin_amount" = REAGENT_VOLUME(R, /singleton/reagent/dexalin),
+ "soporific_amount" = REAGENT_VOLUME(R, /singleton/reagent/soporific),
+ "bicaridine_amount" = REAGENT_VOLUME(R, /singleton/reagent/bicaridine),
+ "dermaline_amount" = REAGENT_VOLUME(R, /singleton/reagent/dermaline),
+ "thetamycin_amount" = REAGENT_VOLUME(R, /singleton/reagent/thetamycin),
+ "other_amount" = R.total_volume - (REAGENT_VOLUME(R, /singleton/reagent/inaprovaline) + REAGENT_VOLUME(R, /singleton/reagent/soporific) + REAGENT_VOLUME(R, /singleton/reagent/bicaridine) + REAGENT_VOLUME(R, /singleton/reagent/dexalin) + REAGENT_VOLUME(R, /singleton/reagent/dermaline) + REAGENT_VOLUME(R, /singleton/reagent/thetamycin)),
+ "bodyparts" = bodyparts,
+ "organs" = organs,
+ "has_internal_injuries" = connected.has_internal_injuries,
+ "has_external_injuries" = connected.has_external_injuries,
+ "missing_limbs" = connected.get_missing_limbs(H),
+ "missing_organs" = connected.get_missing_organs(H)
)
- return medical_data
+ return occupant_data
diff --git a/code/modules/mob/living/silicon/ai/ai_remote_control.dm b/code/modules/mob/living/silicon/ai/ai_remote_control.dm
index 42e7f04aea6..dfd9eac4b1b 100644
--- a/code/modules/mob/living/silicon/ai/ai_remote_control.dm
+++ b/code/modules/mob/living/silicon/ai/ai_remote_control.dm
@@ -29,7 +29,7 @@
modules += new /obj/item/wrench/robotic(src)
modules += new /obj/item/device/healthanalyzer(src)
modules += new /obj/item/extinguisher/mini(src)
- modules += new /obj/item/device/advanced_healthanalyzer(src)
+ modules += new /obj/item/device/advanced_healthanalyzer/cyborg(src)
modules += new /obj/item/tank/jetpack/carbondioxide/synthetic(src)
modules += new /obj/item/inflatable_dispenser(src)
modules += new /obj/item/device/gps(src)
diff --git a/html/changelogs/Ben10083 - Adv Health.yml b/html/changelogs/Ben10083 - Adv Health.yml
new file mode 100644
index 00000000000..741b23eb6f4
--- /dev/null
+++ b/html/changelogs/Ben10083 - Adv Health.yml
@@ -0,0 +1,59 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# - (fixes bugs)
+# wip
+# - (work in progress)
+# qol
+# - (quality of life)
+# soundadd
+# - (adds a sound)
+# sounddel
+# - (removes a sound)
+# rscadd
+# - (adds a feature)
+# rscdel
+# - (removes a feature)
+# imageadd
+# - (adds an image or sprite)
+# imagedel
+# - (removes an image or sprite)
+# spellcheck
+# - (fixes spelling or grammar)
+# experiment
+# - (experimental change)
+# balance
+# - (balance changes)
+# code_imp
+# - (misc internal code change)
+# refactor
+# - (refactors code)
+# config
+# - (makes a change to the config files)
+# admin
+# - (makes changes to administrator tools)
+# server
+# - (miscellaneous changes to server)
+#################################
+
+# Your name.
+author: Ben10083
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit.
+# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - bugfix: "AI shell and Exosuit adv health analyser now works properly."
+ - qol: "Increased feedback for which mode the exosuit health analyser is on."
diff --git a/icons/mecha/mech_equipment.dmi b/icons/mecha/mech_equipment.dmi
index a7339435fec..20589dbb784 100644
Binary files a/icons/mecha/mech_equipment.dmi and b/icons/mecha/mech_equipment.dmi differ
diff --git a/icons/mecha/mecha_weapon_overlays.dmi b/icons/mecha/mecha_weapon_overlays.dmi
index c88e950f72a..bcbbe8a1f15 100644
Binary files a/icons/mecha/mecha_weapon_overlays.dmi and b/icons/mecha/mecha_weapon_overlays.dmi differ