mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-01-02 13:42:32 +00:00
Conflicts: code/game/jobs/job/civilian.dm code/game/objects/items/weapons/defib.dm code/game/objects/items/weapons/stunbaton.dm code/modules/mob/living/silicon/robot/component.dm code/modules/reagents/reagent_containers/syringes.dm
397 lines
14 KiB
Plaintext
397 lines
14 KiB
Plaintext
/*
|
|
CONTAINS:
|
|
T-RAY
|
|
DETECTIVE SCANNER
|
|
HEALTH ANALYZER
|
|
GAS ANALYZER
|
|
PLANT ANALYZER
|
|
MASS SPECTROMETER
|
|
REAGENT SCANNER
|
|
*/
|
|
/obj/item/device/t_scanner
|
|
name = "T-ray scanner"
|
|
desc = "A terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
|
|
icon_state = "t-ray0"
|
|
var/on = 0
|
|
flags = FPRINT | TABLEPASS
|
|
slot_flags = SLOT_BELT
|
|
w_class = 2
|
|
item_state = "electronic"
|
|
m_amt = 150
|
|
origin_tech = "magnets=1;engineering=1"
|
|
|
|
/obj/item/device/t_scanner/attack_self(mob/user)
|
|
|
|
on = !on
|
|
icon_state = "t-ray[on]"
|
|
|
|
if(on)
|
|
processing_objects.Add(src)
|
|
|
|
|
|
/obj/item/device/t_scanner/process()
|
|
if(!on)
|
|
processing_objects.Remove(src)
|
|
return null
|
|
|
|
for(var/turf/T in range(1, src.loc) )
|
|
|
|
if(!T.intact)
|
|
continue
|
|
|
|
for(var/obj/O in T.contents)
|
|
|
|
if(O.level != 1)
|
|
continue
|
|
|
|
if(O.invisibility == 101)
|
|
O.invisibility = 0
|
|
spawn(10)
|
|
if(O)
|
|
var/turf/U = O.loc
|
|
if(U.intact)
|
|
O.invisibility = 101
|
|
|
|
var/mob/living/M = locate() in T
|
|
if(M && M.invisibility == 2)
|
|
M.invisibility = 0
|
|
spawn(2)
|
|
if(M)
|
|
M.invisibility = INVISIBILITY_LEVEL_TWO
|
|
|
|
|
|
/obj/item/device/healthanalyzer
|
|
name = "Health Analyzer"
|
|
icon_state = "health"
|
|
item_state = "analyzer"
|
|
desc = "A hand-held body scanner able to distinguish vital signs of the subject."
|
|
flags = FPRINT | TABLEPASS | CONDUCT
|
|
slot_flags = SLOT_BELT
|
|
throwforce = 3
|
|
w_class = 1.0
|
|
throw_speed = 5
|
|
throw_range = 10
|
|
m_amt = 200
|
|
origin_tech = "magnets=1;biotech=1"
|
|
var/mode = 1;
|
|
|
|
|
|
/obj/item/device/healthanalyzer/attack(mob/living/M as mob, mob/living/user as mob)
|
|
if (( (M_CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50))
|
|
user << text("\red You try to analyze the floor's vitals!")
|
|
for(var/mob/O in viewers(M, null))
|
|
O.show_message(text("\red [user] has analyzed the floor's vitals!"), 1)
|
|
user.show_message(text("\blue Analyzing Results for The floor:\n\t Overall Status: Healthy"), 1)
|
|
user.show_message(text("\blue \t Damage Specifics: [0]-[0]-[0]-[0]"), 1)
|
|
user.show_message("\blue Key: Suffocation/Toxin/Burns/Brute", 1)
|
|
user.show_message("\blue Body Temperature: ???", 1)
|
|
return
|
|
if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
|
|
usr << "\red You don't have the dexterity to do this!"
|
|
return
|
|
user.visible_message("<span class='notice'> [user] has analyzed [M]'s vitals.","<span class='notice'> You have analyzed [M]'s vitals.")
|
|
var/fake_oxy = max(rand(1,40), M.getOxyLoss(), (300 - (M.getToxLoss() + M.getFireLoss() + M.getBruteLoss())))
|
|
var/OX = M.getOxyLoss() > 50 ? "<b>[M.getOxyLoss()]</b>" : M.getOxyLoss()
|
|
var/TX = M.getToxLoss() > 50 ? "<b>[M.getToxLoss()]</b>" : M.getToxLoss()
|
|
var/BU = M.getFireLoss() > 50 ? "<b>[M.getFireLoss()]</b>" : M.getFireLoss()
|
|
var/BR = M.getBruteLoss() > 50 ? "<b>[M.getBruteLoss()]</b>" : M.getBruteLoss()
|
|
if(M.status_flags & FAKEDEATH)
|
|
OX = fake_oxy > 50 ? "<b>[fake_oxy]</b>" : fake_oxy
|
|
user.show_message("\blue Analyzing Results for [M]:\n\t Overall Status: dead")
|
|
else
|
|
user.show_message("\blue Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "dead" : "[M.health - M.halloss]% healthy"]")
|
|
user.show_message("\t Key: <font color='blue'>Suffocation</font>/<font color='green'>Toxin</font>/<font color='#FFA500'>Burns</font>/<font color='red'>Brute</font>", 1)
|
|
user.show_message("\t Damage Specifics: <font color='blue'>[OX]</font> - <font color='green'>[TX]</font> - <font color='#FFA500'>[BU]</font> - <font color='red'>[BR]</font>")
|
|
user.show_message("\blue Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1)
|
|
if(M.tod && (M.stat == DEAD || (M.status_flags & FAKEDEATH)))
|
|
user.show_message("\blue Time of Death: [M.tod]")
|
|
if(istype(M, /mob/living/carbon/human) && mode == 1)
|
|
var/mob/living/carbon/human/H = M
|
|
var/list/damaged = H.get_damaged_organs(1,1)
|
|
user.show_message("\blue Localized Damage, Brute/Burn:",1)
|
|
if(length(damaged)>0)
|
|
for(var/datum/organ/external/org in damaged)
|
|
user.show_message(text("\blue \t []: [][]\blue - []", \
|
|
capitalize(org.display_name), \
|
|
(org.brute_dam > 0) ? "\red [org.brute_dam]" :0, \
|
|
(org.status & ORGAN_BLEEDING)?"\red <b>\[Bleeding\]</b>":"\t", \
|
|
(org.burn_dam > 0) ? "<font color='#FFA500'>[org.burn_dam]</font>" :0),1)
|
|
else
|
|
user.show_message("\blue \t Limbs are OK.",1)
|
|
|
|
OX = M.getOxyLoss() > 50 ? "<font color='blue'><b>Severe oxygen deprivation detected</b></font>" : "Subject bloodstream oxygen level normal"
|
|
TX = M.getToxLoss() > 50 ? "<font color='green'><b>Dangerous amount of toxins detected</b></font>" : "Subject bloodstream toxin level minimal"
|
|
BU = M.getFireLoss() > 50 ? "<font color='#FFA500'><b>Severe burn damage detected</b></font>" : "Subject burn injury status O.K"
|
|
BR = M.getBruteLoss() > 50 ? "<font color='red'><b>Severe anatomical damage detected</b></font>" : "Subject brute-force injury status O.K"
|
|
if(M.status_flags & FAKEDEATH)
|
|
OX = fake_oxy > 50 ? "\red Severe oxygen deprivation detected\blue" : "Subject bloodstream oxygen level normal"
|
|
user.show_message("[OX] | [TX] | [BU] | [BR]")
|
|
if (istype(M, /mob/living/carbon))
|
|
if(M:reagents.total_volume > 0)
|
|
user.show_message(text("\red Warning: Unknown substance detected in subject's blood."))
|
|
if(M:virus2.len)
|
|
var/mob/living/carbon/C = M
|
|
for (var/ID in C.virus2)
|
|
if (ID in virusDB)
|
|
var/datum/data/record/V = virusDB[ID]
|
|
user.show_message(text("\red Warning: Pathogen [V.fields["name"]] detected in subject's blood. Known antigen : [V.fields["antigen"]]"))
|
|
// user.show_message(text("\red Warning: Unknown pathogen detected in subject's blood."))
|
|
if (M.getCloneLoss())
|
|
user.show_message("\red Subject appears to have been imperfectly cloned.")
|
|
for(var/datum/disease/D in M.viruses)
|
|
if(!D.hidden[SCANNER])
|
|
user.show_message(text("\red <b>Warning: [D.form] Detected</b>\nName: [D.name].\nType: [D.spread].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure]"))
|
|
if (M.reagents && M.reagents.get_reagent_amount("inaprovaline"))
|
|
user.show_message("\blue Bloodstream Analysis located [M.reagents:get_reagent_amount("inaprovaline")] units of rejuvenation chemicals.")
|
|
if (M.getBrainLoss() >= 100 || istype(M, /mob/living/carbon/human) && M:brain_op_stage == 4.0)
|
|
user.show_message("\red Subject is brain dead.")
|
|
else if (M.getBrainLoss() >= 60)
|
|
user.show_message("\red Severe brain damage detected. Subject likely to have mental retardation.")
|
|
else if (M.getBrainLoss() >= 10)
|
|
user.show_message("\red Significant brain damage detected. Subject may have had a concussion.")
|
|
if(ishuman(M))
|
|
var/mob/living/carbon/human/H = M
|
|
for(var/name in H.organs_by_name)
|
|
var/datum/organ/external/e = H.organs_by_name[name]
|
|
var/limb = e.display_name
|
|
if(e.status & ORGAN_BROKEN)
|
|
if(((e.name == "l_arm") || (e.name == "r_arm") || (e.name == "l_leg") || (e.name == "r_leg")) && (!(e.status & ORGAN_SPLINTED)))
|
|
user << "\red Unsecured fracture in subject [limb]. Splinting recommended for transport."
|
|
if(e.is_infected())
|
|
user << "\red Infected wound detected in subject [limb]. Disinfection recommended."
|
|
|
|
for(var/name in H.organs_by_name)
|
|
var/datum/organ/external/e = H.organs_by_name[name]
|
|
if(e.status & ORGAN_BROKEN)
|
|
user.show_message(text("\red Bone fractures detected. Advanced scanner required for location."), 1)
|
|
break
|
|
for(var/datum/organ/external/e in H.organs)
|
|
for(var/datum/wound/W in e.wounds) if(W.internal)
|
|
user.show_message(text("\red Internal bleeding detected. Advanced scanner required for location."), 1)
|
|
break
|
|
if(M:vessel)
|
|
var/blood_volume = round(M:vessel.get_reagent_amount("blood"))
|
|
var/blood_percent = blood_volume / 560
|
|
blood_percent *= 100
|
|
if(blood_volume <= 500)
|
|
user.show_message("\red <b>Warning: Blood Level LOW: [blood_percent]% [blood_volume]cl")
|
|
else if(blood_volume <= 336)
|
|
user.show_message("\red <b>Warning: Blood Level CRITICAL: [blood_percent]% [blood_volume]cl")
|
|
else
|
|
user.show_message("\blue Blood Level Normal: [blood_percent]% [blood_volume]cl")
|
|
user.show_message("\blue Subject's pulse: <font color='[H.pulse == PULSE_THREADY || H.pulse == PULSE_NONE ? "red" : "blue"]'>[H.get_pulse(GETPULSE_TOOL)] bpm.</font>")
|
|
src.add_fingerprint(user)
|
|
return
|
|
|
|
/obj/item/device/healthanalyzer/verb/toggle_mode()
|
|
set name = "Switch Verbosity"
|
|
set category = "Object"
|
|
|
|
mode = !mode
|
|
switch (mode)
|
|
if(1)
|
|
usr << "The scanner now shows specific limb damage."
|
|
if(0)
|
|
usr << "The scanner no longer shows limb damage."
|
|
|
|
|
|
/obj/item/device/analyzer
|
|
desc = "A hand-held environmental scanner which reports current gas levels."
|
|
name = "analyzer"
|
|
icon_state = "atmos"
|
|
item_state = "analyzer"
|
|
w_class = 2.0
|
|
flags = FPRINT | TABLEPASS| CONDUCT
|
|
slot_flags = SLOT_BELT
|
|
throwforce = 5
|
|
throw_speed = 4
|
|
throw_range = 20
|
|
m_amt = 30
|
|
g_amt = 20
|
|
origin_tech = "magnets=1;engineering=1"
|
|
|
|
/obj/item/device/analyzer/attack_self(mob/user as mob)
|
|
|
|
if (user.stat)
|
|
return
|
|
if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
|
|
usr << "\red You don't have the dexterity to do this!"
|
|
return
|
|
|
|
var/turf/location = user.loc
|
|
if (!( istype(location, /turf) ))
|
|
return
|
|
|
|
var/datum/gas_mixture/environment = location.return_air()
|
|
|
|
var/pressure = environment.return_pressure()
|
|
var/total_moles = environment.total_moles()
|
|
|
|
user.show_message("\blue <B>Results:</B>", 1)
|
|
if(abs(pressure - ONE_ATMOSPHERE) < 10)
|
|
user.show_message("\blue Pressure: [round(pressure,0.1)] kPa", 1)
|
|
else
|
|
user.show_message("\red Pressure: [round(pressure,0.1)] kPa", 1)
|
|
if(total_moles)
|
|
var/o2_concentration = environment.oxygen/total_moles
|
|
var/n2_concentration = environment.nitrogen/total_moles
|
|
var/co2_concentration = environment.carbon_dioxide/total_moles
|
|
var/plasma_concentration = environment.toxins/total_moles
|
|
|
|
var/unknown_concentration = 1-(o2_concentration+n2_concentration+co2_concentration+plasma_concentration)
|
|
if(abs(n2_concentration - N2STANDARD) < 20)
|
|
user.show_message("\blue Nitrogen: [round(n2_concentration*100)]%", 1)
|
|
else
|
|
user.show_message("\red Nitrogen: [round(n2_concentration*100)]%", 1)
|
|
|
|
if(abs(o2_concentration - O2STANDARD) < 2)
|
|
user.show_message("\blue Oxygen: [round(o2_concentration*100)]%", 1)
|
|
else
|
|
user.show_message("\red Oxygen: [round(o2_concentration*100)]%", 1)
|
|
|
|
if(co2_concentration > 0.01)
|
|
user.show_message("\red CO2: [round(co2_concentration*100)]%", 1)
|
|
else
|
|
user.show_message("\blue CO2: [round(co2_concentration*100)]%", 1)
|
|
|
|
if(plasma_concentration > 0.01)
|
|
user.show_message("\red Plasma: [round(plasma_concentration*100)]%", 1)
|
|
|
|
if(unknown_concentration > 0.01)
|
|
user.show_message("\red Unknown: [round(unknown_concentration*100)]%", 1)
|
|
|
|
user.show_message("\blue Temperature: [round(environment.temperature-T0C)]°C", 1)
|
|
|
|
src.add_fingerprint(user)
|
|
return
|
|
|
|
/obj/item/device/mass_spectrometer
|
|
desc = "A hand-held mass spectrometer which identifies trace chemicals in a blood sample."
|
|
name = "mass-spectrometer"
|
|
icon_state = "spectrometer"
|
|
item_state = "analyzer"
|
|
w_class = 2.0
|
|
flags = FPRINT | TABLEPASS| CONDUCT | OPENCONTAINER
|
|
slot_flags = SLOT_BELT
|
|
throwforce = 5
|
|
throw_speed = 4
|
|
throw_range = 20
|
|
m_amt = 30
|
|
g_amt = 20
|
|
origin_tech = "magnets=2;biotech=2"
|
|
var/details = 0
|
|
var/recent_fail = 0
|
|
|
|
/obj/item/device/mass_spectrometer/New()
|
|
..()
|
|
var/datum/reagents/R = new/datum/reagents(5)
|
|
reagents = R
|
|
R.my_atom = src
|
|
|
|
/obj/item/device/mass_spectrometer/on_reagent_change()
|
|
if(reagents.total_volume)
|
|
icon_state = initial(icon_state) + "_s"
|
|
else
|
|
icon_state = initial(icon_state)
|
|
|
|
/obj/item/device/mass_spectrometer/attack_self(mob/user as mob)
|
|
if (user.stat)
|
|
return
|
|
if (crit_fail)
|
|
user << "\red This device has critically failed and is no longer functional!"
|
|
return
|
|
if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
|
|
user << "\red You don't have the dexterity to do this!"
|
|
return
|
|
if(reagents.total_volume)
|
|
var/list/blood_traces = list()
|
|
for(var/datum/reagent/R in reagents.reagent_list)
|
|
if(R.id != "blood")
|
|
reagents.clear_reagents()
|
|
user << "\red The sample was contaminated! Please insert another sample"
|
|
return
|
|
else
|
|
blood_traces = params2list(R.data["trace_chem"])
|
|
break
|
|
var/dat = "Trace Chemicals Found: "
|
|
for(var/R in blood_traces)
|
|
if(prob(reliability))
|
|
if(details)
|
|
dat += "[R] ([blood_traces[R]] units) "
|
|
else
|
|
dat += "[R] "
|
|
recent_fail = 0
|
|
else
|
|
if(recent_fail)
|
|
crit_fail = 1
|
|
reagents.clear_reagents()
|
|
return
|
|
else
|
|
recent_fail = 1
|
|
user << "[dat]"
|
|
reagents.clear_reagents()
|
|
return
|
|
|
|
/obj/item/device/mass_spectrometer/adv
|
|
name = "advanced mass-spectrometer"
|
|
icon_state = "adv_spectrometer"
|
|
details = 1
|
|
origin_tech = "magnets=4;biotech=2"
|
|
|
|
/obj/item/device/reagent_scanner
|
|
name = "reagent scanner"
|
|
desc = "A hand-held reagent scanner which identifies chemical agents."
|
|
icon_state = "spectrometer"
|
|
item_state = "analyzer"
|
|
w_class = 2.0
|
|
flags = FPRINT | TABLEPASS | CONDUCT
|
|
slot_flags = SLOT_BELT
|
|
throwforce = 5
|
|
throw_speed = 4
|
|
throw_range = 20
|
|
m_amt = 30
|
|
g_amt = 20
|
|
origin_tech = "magnets=2;biotech=2"
|
|
var/details = 0
|
|
var/recent_fail = 0
|
|
|
|
/obj/item/device/reagent_scanner/afterattack(obj/O, mob/user as mob)
|
|
if (user.stat)
|
|
return
|
|
if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
|
|
user << "\red You don't have the dexterity to do this!"
|
|
return
|
|
if(!istype(O))
|
|
return
|
|
if (crit_fail)
|
|
user << "\red This device has critically failed and is no longer functional!"
|
|
return
|
|
|
|
if(!isnull(O.reagents))
|
|
var/dat = ""
|
|
if(O.reagents.reagent_list.len > 0)
|
|
var/one_percent = O.reagents.total_volume / 100
|
|
for (var/datum/reagent/R in O.reagents.reagent_list)
|
|
if(prob(reliability))
|
|
dat += "\n \t \blue [R][details ? ": [R.volume / one_percent]%" : ""]"
|
|
recent_fail = 0
|
|
else if(recent_fail)
|
|
crit_fail = 1
|
|
dat = null
|
|
break
|
|
else
|
|
recent_fail = 1
|
|
if(dat)
|
|
user << "\blue Chemicals found: [dat]"
|
|
else
|
|
user << "\blue No active chemical agents found in [O]."
|
|
else
|
|
user << "\blue No significant chemical agents found in [O]."
|
|
|
|
return
|
|
|
|
/obj/item/device/reagent_scanner/adv
|
|
name = "advanced reagent scanner"
|
|
icon_state = "adv_spectrometer"
|
|
details = 1
|
|
origin_tech = "magnets=4;biotech=2" |