Better Bodyscanners and Surgery Stuff (#17520)

* Better Bodyscanners and Surgery Stuff

* ope

* i can't believe that worked

* adv

* bodyscanner fixes
This commit is contained in:
Wowzewow (Wezzy)
2023-10-08 05:36:13 +08:00
committed by GitHub
parent a44d7a3b7f
commit ea1101ec5c
45 changed files with 1015 additions and 877 deletions
+127 -82
View File
@@ -20,8 +20,8 @@ BREATH ANALYZER
throw_range = 10
matter = list(DEFAULT_WALL_MATERIAL = 200)
origin_tech = list(TECH_MAGNET = 1, TECH_BIO = 1)
var/mode = 1
var/last_scan = 0
var/mode = 1
var/sound_scan = FALSE
/obj/item/device/healthanalyzer/attack(mob/living/M, mob/living/user)
@@ -29,6 +29,8 @@ BREATH ANALYZER
if(last_scan <= world.time - 20) //Spam limiter.
last_scan = world.time
sound_scan = TRUE
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)
user.do_attack_animation(src)
flick("[icon_state]-scan", src) //makes it so that it plays the scan animation on a successful scan
health_scan_mob(M, user, mode, sound_scan = sound_scan)
add_fingerprint(user)
@@ -38,6 +40,8 @@ BREATH ANALYZER
if(last_scan <= world.time - 20) //Spam limiter.
last_scan = world.time
sound_scan = TRUE
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)
user.do_attack_animation(src)
flick("[icon_state]-scan", src) //makes it so that it plays the scan animation on a successful scan
health_scan_mob(user, user, mode, sound_scan = sound_scan)
add_fingerprint(user)
@@ -93,8 +97,8 @@ BREATH ANALYZER
playsound(user.loc, 'sound/items/healthscanner/healthscanner_used.ogg', 25)
return
if(!usr.IsAdvancedToolUser())
to_chat(usr, "<span class='warning'>You don't have the dexterity to do this!</span>")
if(!user.IsAdvancedToolUser())
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
return
user.visible_message("<b>[user]</b> runs a scanner over [M].","<span class='notice'>You run the scanner over [M].</span>")
@@ -131,6 +135,9 @@ BREATH ANALYZER
. += "[b]Scan results for \the [H]:[endb]"
if(H.stat == DEAD || H.status_flags & FAKEDEATH)
dat += "<span class='scan_warning'>[b]Time of Death:[endb] [worldtime2text(H.timeofdeath)]</span>"
// Brain activity.
var/brain_status = H.get_brain_status()
dat += "Brain activity: [brain_status]"
@@ -152,9 +159,6 @@ BREATH ANALYZER
else
playsound(user.loc, 'sound/items/healthscanner/healthscanner_stable.ogg', 25)
if(H.stat == DEAD || H.status_flags & FAKEDEATH)
dat += "<span class='scan_warning'>[b]Time of Death:[endb] [worldtime2text(H.timeofdeath)]</span>"
// Pulse rate.
var/pulse_result = "normal"
if(H.should_have_organ(BP_HEART))
@@ -162,33 +166,27 @@ BREATH ANALYZER
pulse_result = "<span class='danger'>0</span>"
else
pulse_result = H.get_pulse(GETPULSE_TOOL)
pulse_result = "<span class='scan_green'>[pulse_result]</span>"
pulse_result = "<span class='scan_green'>[pulse_result] BPM</span>"
if(H.pulse() == PULSE_NONE)
pulse_result = "<span class='scan_danger'>[pulse_result]</span>"
pulse_result = "<span class='scan_danger'>[pulse_result] BPM</span>"
else if(H.pulse() < PULSE_NORM)
pulse_result = "<span class='scan_notice'>[pulse_result]</span>"
pulse_result = "<span class='scan_notice'>[pulse_result] BPM</span>"
else if(H.pulse() > PULSE_NORM)
pulse_result = "<span class='scan_warning'>[pulse_result]</span>"
pulse_result = "<span class='scan_warning'>[pulse_result] BPM</span>"
else
pulse_result = "<span class='scan_danger'>0</span>"
dat += "Pulse rate: [pulse_result] bpm"
pulse_result = "<span class='scan_danger'>0 BPM</span>"
dat += "Pulse rate: [pulse_result]"
// Body temperature. Rounds to one digit after decimal.
var/temperature_string
if(H.bodytemperature < H.species.cold_level_1 || H.bodytemperature > H.species.heat_level_1)
temperature_string = "Body temperature: <span class='scan_warning'>[round(H.bodytemperature-T0C, 0.1)]&deg;C ([round(H.bodytemperature*1.8-459.67, 0.1)]&deg;F)</span>"
else
temperature_string = "Body temperature: <span class='scan_green'>[round(H.bodytemperature-T0C, 0.1)]&deg;C ([round(H.bodytemperature*1.8-459.67, 0.1)]&deg;F)</span>"
dat += temperature_string
// Blood pressure and blood type. Based on the idea of a normal blood pressure being 120 over 80.
if(H.should_have_organ(BP_HEART))
if(H.get_blood_volume() <= 70)
dat += "<span class='scan_danger'>Severe blood loss detected.</span>"
var/oxygenation_string = "<span class='scan_green'>[H.get_blood_oxygenation()]% blood oxygenation</span>"
dat += "Blood type: <span class ='scan_green'>[H.dna.b_type]</span>"
switch(H.get_blood_oxygenation())
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
oxygenation_string = "<span class='scan_notice'>[oxygenation_string]</span>"
if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_OKAY)
oxygenation_string = "<span class='scan_warning'>[oxygenation_string]</span>"
if(-(INFINITY) to BLOOD_VOLUME_SURVIVE)
oxygenation_string = "<span class='scan_danger'>[oxygenation_string]</span>"
if(H.status_flags & FAKEDEATH)
oxygenation_string = "<span class='scan_danger'>0% blood oxygenation</span>"
var/blood_pressure_string
switch(H.get_blood_pressure_alert())
if(1)
@@ -199,23 +197,38 @@ BREATH ANALYZER
blood_pressure_string = "<span class='scan_warning'>[H.get_blood_pressure()]</span>"
if(4)
blood_pressure_string = "<span class='scan_danger'>[H.get_blood_pressure()]</span>"
dat += "Blood pressure: [blood_pressure_string] ([oxygenation_string])"
var/blood_volume_string = "<span class='scan_green'>\>[BLOOD_VOLUME_SAFE]%</span>"
switch(H.get_blood_oxygenation())
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
blood_volume_string = "<span class='scan_notice'>\<[BLOOD_VOLUME_SAFE]%</span>"
if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_OKAY)
blood_volume_string = "<span class='scan_warning'>\<[BLOOD_VOLUME_OKAY]%</span>"
if(-(INFINITY) to BLOOD_VOLUME_SURVIVE)
blood_volume_string = "<span class='scan_danger'>\<[BLOOD_VOLUME_SURVIVE]%</span>"
var/oxygenation_string = "<span class='scan_green'>[H.get_blood_oxygenation()]%</span>"
switch(H.get_blood_oxygenation())
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
oxygenation_string = "<span class='scan_notice'>[oxygenation_string]%</span>"
if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_OKAY)
oxygenation_string = "<span class='scan_warning'>[oxygenation_string]%</span>"
if(-(INFINITY) to BLOOD_VOLUME_SURVIVE)
oxygenation_string = "<span class='scan_danger'>[oxygenation_string]%</span>"
if(H.status_flags & FAKEDEATH)
oxygenation_string = "<span class='scan_danger'>[rand(0,10)]%</span>"
dat += "Blood pressure: [blood_pressure_string]"
dat += "Blood oxygenation: [oxygenation_string]"
dat += "Blood volume: [blood_volume_string]"
dat += "Blood type: <span class ='scan_green'>[H.dna.b_type]</span>"
else
dat += "Blood pressure: N/A"
// Body temperature. Rounds to one digit after decimal.
var/temperature_string
if(H.bodytemperature < H.species.cold_level_1 || H.bodytemperature > H.species.heat_level_1)
temperature_string = "Body temperature: <span class='scan_warning'>[round(H.bodytemperature-T0C, 0.1)]&deg;C ([round(H.bodytemperature*1.8-459.67, 0.1)]&deg;F)</span>"
else
temperature_string = "Body temperature: <span class='scan_green'>[round(H.bodytemperature-T0C, 0.1)]&deg;C ([round(H.bodytemperature*1.8-459.67, 0.1)]&deg;F)</span>"
dat += temperature_string
// Traumatic shock.
if(H.is_asystole() || (H.status_flags & FAKEDEATH))
dat += "<span class='scan_danger'>Patient is suffering from cardiovascular shock. Administer CPR immediately.</span>"
dat += "<span class='scan_danger'>Cardiovascular shock detected. Administer CPR immediately.</span>"
else if(H.shock_stage > 80)
dat += "<span class='scan_warning'>Patient is at serious risk of going into shock. Pain relief recommended.</span>"
dat += "<span class='scan_warning'>Imminent cardiovascular shock. Pain relief recommended.</span>"
if(H.getOxyLoss() > 50)
dat += "<span class='scan_blue'>[b]Severe oxygen deprivation detected.[endb]</span>"
@@ -226,18 +239,6 @@ BREATH ANALYZER
if(H.getBruteLoss() > 50)
dat += "<span class='scan_red'>[b]Severe anatomical damage detected.[endb]</span>"
var/rad_result = "Radiation: "
switch(H.total_radiation)
if(RADS_NONE)
rad_result += span("scan_green", "No radiation detected.")
if(RADS_LOW to RADS_MED)
rad_result += span("scan_orange", "Low levels of radiation poisoning detected.")
if(RADS_MED to RADS_HIGH)
rad_result += span("scan_orange", "Severe levels of radiation poisoning detected!")
if(RADS_HIGH to INFINITY)
rad_result += span("scan_red", "[b]Extreme levels of radiation poisoning detected![endb]")
dat += rad_result
if(show_limb_damage)
var/list/damaged = H.get_damaged_organs(1,1)
if(damaged.len)
@@ -347,9 +348,10 @@ BREATH ANALYZER
. = jointext(.,"<br>")
. = jointext(list(header,.),null)
to_chat(user, "<hr>")
to_chat(user, .)
to_chat(user, "<hr>")
if(user)
to_chat(user, "<hr>")
to_chat(user, .)
to_chat(user, "<hr>")
/obj/item/device/healthanalyzer/verb/toggle_mode()
set name = "Switch Verbosity"
@@ -683,31 +685,33 @@ BREATH ANALYZER
/obj/item/device/advanced_healthanalyzer
name = "zeng-hu body analyzer"
desc = "An expensive and varied-use health analyzer that prints full-body scans after a short scanning delay."
icon_state = "zh-analyzer"
item_state = "zh-analyzer"
name = "advanced health analyzer"
desc = "An expensive and varied-use health analyzer of Zeng-Hu design that prints full-body scans after a short scanning delay."
icon_state = "adv-analyzer"
item_state = "adv-analyzer"
slot_flags = SLOT_BELT
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 3)
var/obj/machinery/body_scanconsole/internal_bodyscanner = null //this is used to print the date and to deal with extra
var/obj/machinery/body_scanconsole/connected = null //this is used to print the date and to deal with extra
/obj/item/device/advanced_healthanalyzer/Initialize()
. = ..()
if(!internal_bodyscanner)
if(!connected)
var/obj/machinery/body_scanconsole/S = new (src)
S.forceMove(src)
S.update_use_power(POWER_USE_OFF)
internal_bodyscanner = S
connected = S
/obj/item/device/advanced_healthanalyzer/Destroy()
if(internal_bodyscanner)
QDEL_NULL(internal_bodyscanner)
if(connected)
QDEL_NULL(connected)
return ..()
/obj/item/device/advanced_healthanalyzer/attack(mob/living/M, mob/living/user)
if(!internal_bodyscanner)
if(!connected)
return
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)
user.do_attack_animation(src)
user.visible_message("<b>[user]</b> starts scanning \the [M] with \the [src].", SPAN_NOTICE("You start scanning \the [M] with \the [src]."))
if(do_after(user, 7 SECONDS, M, DO_UNIQUE))
print_scan(M, user)
@@ -716,22 +720,63 @@ BREATH ANALYZER
/obj/item/device/advanced_healthanalyzer/proc/print_scan(var/mob/M, var/mob/living/user)
var/obj/item/paper/medscan/R = new(user.loc)
R.color = "#eeffe8"
R.set_content_unsafe("Scan ([M.name])", internal_bodyscanner.format_occupant_data(get_medical_data(M)))
R.set_content_unsafe("Scan ([M.name])", connected.format_occupant_data(get_occupant_data(M)))
if(ishuman(user) && !(user.l_hand && user.r_hand))
user.put_in_hands(R)
user.visible_message("\The [src] spits out a piece of paper.")
connected.print(R, message = "\The [src] beeps, printing \the [R] after a moment.", user = user)
/obj/item/device/advanced_healthanalyzer/proc/get_medical_data(var/mob/living/carbon/human/H)
/obj/item/device/advanced_healthanalyzer/proc/get_occupant_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),
@@ -743,18 +788,18 @@ BREATH ANALYZER
"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