diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 817891e5925..07d153a7e0b 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -370,50 +370,64 @@ BREATH ANALYZER matter = list(DEFAULT_WALL_MATERIAL = 30, MATERIAL_GLASS = 20) origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 2) - var/details = 0 - var/recent_fail = 0 + var/details = FALSE -/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/Initialize() + . = ..() + create_reagents(5) /obj/item/device/mass_spectrometer/on_reagent_change() + clear_blood_overlay() if(reagents.total_volume) icon_state = initial(icon_state) + "_s" + var/image/I = image(icon, null, "[initial(icon_state)]-reagent") + I.color = reagents.get_color() + add_blood_overlay(I) else icon_state = initial(icon_state) -/obj/item/device/mass_spectrometer/attack_self(mob/user as mob) - if (user.stat) - return - if (!user.IsAdvancedToolUser()) - to_chat(user, "You don't have the dexterity to do this!") +/obj/item/device/mass_spectrometer/proc/clear_blood_overlay() + underlays = null + +/obj/item/device/mass_spectrometer/proc/add_blood_overlay(var/image/I) + underlays += I + +/obj/item/device/mass_spectrometer/attack_self(mob/user) + if(use_check_and_message(user)) return if(reagents.total_volume) - if(LAZYLEN(reagents.reagent_volumes) > 1 || !REAGENT_DATA(reagents, /decl/reagent/blood)) - reagents.clear_reagents() - to_chat(user, "The sample was contaminated! Please insert another sample") + if(LAZYLEN(reagents.reagent_volumes) > 1) + to_chat(user, SPAN_WARNING("There isn't enough blood in the sample!")) return - var/list/blood_traces = params2list(reagents.reagent_data[/decl/reagent/blood]["trace_chem"]) - var/dat = "Trace Chemicals Found: " + if(!REAGENT_DATA(reagents, /decl/reagent/blood)) + to_chat(user, SPAN_WARNING("The sample was contaminated with non-blood reagents!")) + return + var/list/blood_traces = reagents.reagent_data[/decl/reagent/blood]["trace_chem"] + var/list/output_text = list("Trace Chemicals Found:") for(var/_C in blood_traces) var/decl/reagent/C = decls_repository.get_decl(_C) + if(C.spectro_hidden && !details) + continue if(details) - dat += "[C] ([blood_traces[_C]] units) " + output_text += "- [C] ([max(round(blood_traces[_C], 0.1), 0.1)] units)" else - dat += "[C] " - to_chat(user, "[dat]") - reagents.clear_reagents() - return + output_text += "- [C]" + if(length(output_text) == 1) + output_text[1] = SPAN_NOTICE("No trace chemicals found.") + to_chat(user, jointext(output_text, "\n")) /obj/item/device/mass_spectrometer/adv name = "advanced mass spectrometer" icon_state = "adv_spectrometer" - details = 1 + details = TRUE origin_tech = list(TECH_MAGNET = 4, TECH_BIO = 2) +/obj/item/device/mass_spectrometer/adv/clear_blood_overlay() + cut_overlays() + +/obj/item/device/mass_spectrometer/adv/add_blood_overlay(var/image/I) + add_overlay(I) + /obj/item/device/reagent_scanner name = "reagent scanner" desc = "A hand-held reagent scanner which identifies chemical agents." diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 559d2bd4084..032bcac5abf 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -696,6 +696,10 @@ // TODO: stomach and bloodstream organ. if(!isSynthetic()) handle_trace_chems() + if(!(species.flags & NO_BLOOD)) + // update the trace chems in our blood vessels + var/decl/reagent/blood/B = decls_repository.get_decl(/decl/reagent/blood) + B.handle_trace_chems(vessel) for(var/_R in chem_doses) if ((_R in bloodstr.reagent_volumes) || (_R in ingested.reagent_volumes) || (_R in breathing.reagent_volumes) || (_R in touching.reagent_volumes)) diff --git a/code/modules/organs/blood.dm b/code/modules/organs/blood.dm index d1d0b96eee2..aa23667fa9c 100644 --- a/code/modules/organs/blood.dm +++ b/code/modules/organs/blood.dm @@ -15,6 +15,7 @@ return vessel.add_reagent(/decl/reagent/blood, species.blood_volume, temperature = species?.body_temperature) + fixblood() //Resets blood data /mob/living/carbon/human/proc/fixblood() @@ -217,6 +218,13 @@ proc/blood_incompatible(donor,receiver,donor_species,receiver_species) data["dose_chem"] = chem_doses.Copy() return data +/mob/living/carbon/human/get_blood_data() + . = ..() + var/list/trace_chems = list() + if(LAZYLEN(vessel.reagent_data)) + trace_chems = LAZYACCESS(vessel.reagent_data[/decl/reagent/blood], "trace_chem") || list() + .["trace_chem"] = trace_chems.Copy() + proc/blood_splatter(var/target, var/source, var/large, var/spray_dir, var/sourceless_color) var/obj/effect/decal/cleanable/blood/splatter diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index e17379a8306..af33750316f 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -14,6 +14,7 @@ var/overdose = 0 // Volume of a chemical required in the blood to meet overdose criteria. var/od_minimum_dose = 5 // Metabolised dose of a chemical required to meet overdose criteria. var/scannable = 0 // Shows up on health analyzers. + var/spectro_hidden = FALSE // doesn't show up on basic mass spectrometers, only shows on the advanced variant var/affects_dead = 0 var/glass_icon_state = null var/glass_name = null @@ -43,6 +44,12 @@ /decl/reagent/proc/remove_self(var/amount, var/datum/reagents/holder) // Shortcut holder.remove_reagent(type, amount) // Don't typecheck this, fix anywhere this is called with a null holder. + if(ishuman(holder.my_atom)) + var/mob/living/carbon/human/H = holder.my_atom + if(H.vessel.reagent_data[/decl/reagent/blood]["trace_chem"][type]) + H.vessel.reagent_data[/decl/reagent/blood]["trace_chem"][type] += amount + else + H.vessel.reagent_data[/decl/reagent/blood]["trace_chem"][type] = amount // This doesn't apply to skin contact - this is for, e.g. extinguishers and sprays. The difference is that reagent is not directly on the mob's skin - it might just be on their clothing. /decl/reagent/proc/touch_mob(var/mob/living/M, var/amount, var/datum/reagents/holder) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm index e9e74f13c22..0fe40bdf2bd 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm @@ -12,13 +12,27 @@ fallback_specific_heat = 3.617 +/decl/reagent/blood/initialize_data(newdata, datum/reagents/holder) + . = ..() + if(.) + LAZYINITLIST(.["trace_chem"]) + +/decl/reagent/blood/proc/handle_trace_chems(var/datum/reagents/holder) + var/list/trace_chems = holder.reagent_data[type]["trace_chem"] + for(var/chem in trace_chems) + var/decl/reagent/R = decls_repository.get_decl(chem) + trace_chems[chem] = trace_chems[chem] - (R.metabolism / 10) // work your way out of the body but at 10th the speed + if(trace_chems[chem] < 0) + trace_chems -= chem + holder.reagent_data[type]["trace_chem"] = trace_chems + /decl/reagent/blood/mix_data(var/list/newdata, var/newamount, var/datum/reagents/holder) var/list/data = ..() if(LAZYACCESS(newdata, "trace_chem")) var/list/other_chems = LAZYACCESS(newdata, "trace_chem") if(!data) data = newdata.Copy() - else if(!data["trace_chem"]) + else if(!length(data["trace_chem"])) data["trace_chem"] = other_chems.Copy() else var/list/my_chems = data["trace_chem"] diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm index 73fbee7345b..a1b33ad60cc 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm @@ -254,6 +254,7 @@ description = "A strong neurotoxin that puts the subject into a death-like state." reagent_state = SOLID color = "#669900" + spectro_hidden = TRUE metabolism = REM strength = 3 taste_description = "death" @@ -769,6 +770,7 @@ description = "A complicated to make and highly illegal drug that cause paralysis mostly focused on the limbs." reagent_state = LIQUID color = "#002067" + spectro_hidden = TRUE metabolism = REM * 0.2 strength = 0 taste_description = "danger" diff --git a/html/changelogs/geeves-mass_spectrometer.yml b/html/changelogs/geeves-mass_spectrometer.yml new file mode 100644 index 00000000000..8fb05c123b3 --- /dev/null +++ b/html/changelogs/geeves-mass_spectrometer.yml @@ -0,0 +1,11 @@ +author: Geeves + +delete-after: True + +changes: + - rscadd: "All reagents processed in the body now get added to the bloodstream's trace chemicals. Trace chemicals decay at a rate ten times slower than normal blood metabolism." + - bugfix: "Mass spectrometers now properly access the blood's trace chemicals." + - tweak: "Mass spectrometers no longer delete the sample after being analyzed." + - rscadd: "Mass spectrometers will now show the correct color for the blood inside it." + - tweak: "Mass spectrometers now tell you when no trace chemicals are found." + - rscadd: "Zombie Powder and Dextrotoxin no longer show up on normal mass spectrometers, only the advanced version will detect them." \ No newline at end of file diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index a4625bb2b13..79320e921aa 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ