From c6007727cd2979375bda9571e186540f6fe8f2bf Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Mon, 7 Sep 2020 04:10:16 +0200 Subject: [PATCH] Many issue fixes for stomachs and chem interactions (#53440) (#671) This changes the has_reagent check to work with stomachs. Several supporting procs have been added to fully support this behavior. end_metabolization will work as expected again expose is working with INGEST items again on_mob_add working as intended on_mob_life has been reviewed and worked over. Health Analyzers now show stomach contents, same with the medical kiosk. Included the unit test to validate reagent checks. Unit tests for the new procs on mob Co-authored-by: NightRed --- code/datums/components/rot.dm | 2 +- code/datums/diseases/_disease.dm | 4 +- code/datums/diseases/advance/symptoms/heal.dm | 10 ++-- .../diseases/advance/symptoms/sensory.dm | 8 +-- code/datums/status_effects/debuffs.dm | 6 ++- code/datums/traits/negative.dm | 6 +-- code/datums/wounds/bones.dm | 4 +- code/datums/wounds/burns.dm | 6 +-- code/datums/wounds/pierce.dm | 2 +- code/datums/wounds/slash.dm | 2 +- code/game/machinery/medical_kiosk.dm | 8 ++- code/game/objects/items/devices/scanners.dm | 13 ++++- code/modules/antagonists/cult/ritual.dm | 6 +-- code/modules/antagonists/devil/devil.dm | 4 +- code/modules/mob/living/bloodcrawl.dm | 4 +- code/modules/mob/living/carbon/death.dm | 2 +- .../mob/living/carbon/human/examine.dm | 4 +- .../mob/living/carbon/human/species.dm | 2 +- .../carbon/human/species_types/vampire.dm | 2 +- code/modules/mob/living/carbon/life.dm | 52 +++++++++++++++++-- .../mob/living/carbon/monkey/monkey.dm | 4 +- code/modules/mob/living/life.dm | 36 +++++++++++++ .../mob/living/simple_animal/slime/slime.dm | 4 +- code/modules/reagents/chemistry/holder.dm | 14 ++++- .../chemistry/reagents/alcohol_reagents.dm | 4 +- .../reagents/cat2_medicine_reagents.dm | 4 +- .../chemistry/reagents/drink_reagents.dm | 8 +-- .../chemistry/reagents/food_reagents.dm | 12 ++--- .../chemistry/reagents/medicine_reagents.dm | 28 +++++----- .../chemistry/reagents/other_reagents.dm | 8 +-- .../reagents/pyrotechnic_reagents.dm | 8 +-- .../chemistry/reagents/toxin_reagents.dm | 14 ++--- .../crossbreeding/_status_effects.dm | 2 +- code/modules/surgery/organs/heart.dm | 2 +- code/modules/surgery/organs/lungs.dm | 2 +- code/modules/surgery/organs/stomach.dm | 4 +- code/modules/surgery/surgery_step.dm | 4 +- code/modules/unit_tests/_unit_tests.dm | 3 ++ code/modules/unit_tests/pills.dm | 10 ++++ code/modules/unit_tests/reagent_mod_procs.dm | 41 +++++++++++++++ code/modules/unit_tests/stomach.dm | 19 +++++++ 41 files changed, 281 insertions(+), 97 deletions(-) create mode 100644 code/modules/unit_tests/pills.dm create mode 100644 code/modules/unit_tests/reagent_mod_procs.dm create mode 100644 code/modules/unit_tests/stomach.dm diff --git a/code/datums/components/rot.dm b/code/datums/components/rot.dm index 18629a725fe..9b1d45f9acf 100644 --- a/code/datums/components/rot.dm +++ b/code/datums/components/rot.dm @@ -47,7 +47,7 @@ return // No decay if formaldehyde in corpse or when the corpse is charred - if(C.reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 15) || HAS_TRAIT(C, TRAIT_HUSK)) + if(C.has_reagent(/datum/reagent/toxin/formaldehyde, 15) || HAS_TRAIT(C, TRAIT_HUSK)) return // Also no decay if corpse chilled or not organic/undead diff --git a/code/datums/diseases/_disease.dm b/code/datums/diseases/_disease.dm index 2402f6bb46b..11981d15448 100644 --- a/code/datums/diseases/_disease.dm +++ b/code/datums/diseases/_disease.dm @@ -88,7 +88,7 @@ . = cures.len for(var/C_id in cures) - if(!affected_mob.reagents.has_reagent(C_id)) + if(!affected_mob.has_reagent(C_id)) .-- if(!. || (needs_all_cures && . < cures.len)) return FALSE @@ -101,7 +101,7 @@ if(!(spread_flags & DISEASE_SPREAD_AIRBORNE) && !force_spread) return - if(affected_mob.reagents.has_reagent(/datum/reagent/medicine/spaceacillin) || (affected_mob.satiety > 0 && prob(affected_mob.satiety/10))) + if(affected_mob.has_reagent(/datum/reagent/medicine/spaceacillin) || (affected_mob.satiety > 0 && prob(affected_mob.satiety/10))) return var/spread_range = 2 diff --git a/code/datums/diseases/advance/symptoms/heal.dm b/code/datums/diseases/advance/symptoms/heal.dm index 1f57d58d541..24328abdcf1 100644 --- a/code/datums/diseases/advance/symptoms/heal.dm +++ b/code/datums/diseases/advance/symptoms/heal.dm @@ -342,11 +342,11 @@ if(M.fire_stacks < 0) M.set_fire_stacks(min(M.fire_stacks + 1 * absorption_coeff, 0)) . += power - if(M.reagents.has_reagent(/datum/reagent/water/holywater, needs_metabolizing = FALSE)) - M.reagents.remove_reagent(/datum/reagent/water/holywater, 0.5 * absorption_coeff) + if(M.has_reagent(/datum/reagent/water/holywater, needs_metabolizing = FALSE)) + M.remove_reagent(/datum/reagent/water/holywater, 0.5 * absorption_coeff) . += power * 0.75 - else if(M.reagents.has_reagent(/datum/reagent/water, needs_metabolizing = FALSE)) - M.reagents.remove_reagent(/datum/reagent/water, 0.5 * absorption_coeff) + else if(M.has_reagent(/datum/reagent/water, needs_metabolizing = FALSE)) + M.remove_reagent(/datum/reagent/water, 0.5 * absorption_coeff) . += power * 0.5 /datum/symptom/heal/water/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power) @@ -407,7 +407,7 @@ gases = environment.gases if(gases[/datum/gas/plasma] && gases[/datum/gas/plasma][MOLES] > gases[/datum/gas/plasma][GAS_META][META_GAS_MOLES_VISIBLE]) //if there's enough plasma in the air to see . += power * 0.5 - if(M.reagents.has_reagent(/datum/reagent/toxin/plasma, needs_metabolizing = TRUE)) + if(M.has_reagent(/datum/reagent/toxin/plasma, needs_metabolizing = TRUE)) . += power * 0.75 /datum/symptom/heal/plasma/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power) diff --git a/code/datums/diseases/advance/symptoms/sensory.dm b/code/datums/diseases/advance/symptoms/sensory.dm index 05cb7aa93d8..be5d1b479fc 100644 --- a/code/datums/diseases/advance/symptoms/sensory.dm +++ b/code/datums/diseases/advance/symptoms/sensory.dm @@ -46,10 +46,10 @@ if(A.stage >= 4) M.drowsyness = max(0, M.drowsyness - 2) - if(M.reagents.has_reagent(/datum/reagent/toxin/mindbreaker)) - M.reagents.remove_reagent(/datum/reagent/toxin/mindbreaker, 5) - if(M.reagents.has_reagent(/datum/reagent/toxin/histamine)) - M.reagents.remove_reagent(/datum/reagent/toxin/histamine, 5) + if(M.has_reagent(/datum/reagent/toxin/mindbreaker)) + M.remove_reagent(/datum/reagent/toxin/mindbreaker, 5) + if(M.has_reagent(/datum/reagent/toxin/histamine)) + M.remove_reagent(/datum/reagent/toxin/histamine, 5) M.hallucination = max(0, M.hallucination - 10) if(A.stage >= 5) diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index e88b3a94eab..3b510dc0a5d 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -195,7 +195,11 @@ . = ..() if(.) update_time_of_death() - owner.reagents?.end_metabolization(owner, FALSE) + if(istype(owner, /mob/living/carbon)) + var/mob/living/carbon/body = owner + body.end_metabolization(FALSE) + else + owner.reagents?.end_metabolization(owner, FALSE) /datum/status_effect/grouped/stasis/on_apply() . = ..() diff --git a/code/datums/traits/negative.dm b/code/datums/traits/negative.dm index 8b32b3ea4e0..c00e91cab33 100644 --- a/code/datums/traits/negative.dm +++ b/code/datums/traits/negative.dm @@ -463,7 +463,7 @@ hardcore_value = 6 /datum/quirk/insanity/on_process() - if(quirk_holder.reagents.has_reagent(/datum/reagent/toxin/mindbreaker, needs_metabolizing = TRUE)) + if(quirk_holder.has_reagent(/datum/reagent/toxin/mindbreaker, needs_metabolizing = TRUE)) quirk_holder.hallucination = 0 return if(prob(2)) //we'll all be mad soon enough @@ -710,11 +710,11 @@ return var/mob/living/carbon/carbon_quirk_holder = quirk_holder for(var/M in allergies) - var/datum/reagent/instantiated_med = carbon_quirk_holder.reagents.has_reagent(M) + var/datum/reagent/instantiated_med = carbon_quirk_holder.has_reagent(M) if(!instantiated_med) continue //Just halts the progression, I'd suggest you run to medbay asap to get it fixed - if(carbon_quirk_holder.reagents.has_reagent(/datum/reagent/medicine/epinephrine)) + if(carbon_quirk_holder.has_reagent(/datum/reagent/medicine/epinephrine)) instantiated_med.reagent_removal_skip_list |= ALLERGIC_REMOVAL_SKIP return //intentionally stops the entire proc so we avoid the organ damage after the loop instantiated_med.reagent_removal_skip_list -= ALLERGIC_REMOVAL_SKIP diff --git a/code/datums/wounds/bones.dm b/code/datums/wounds/bones.dm index 1fd448ad13f..98354ff1ef2 100644 --- a/code/datums/wounds/bones.dm +++ b/code/datums/wounds/bones.dm @@ -363,9 +363,9 @@ var/painkiller_bonus = 0 if(victim.drunkenness) painkiller_bonus += 5 - if(victim.reagents?.has_reagent(/datum/reagent/medicine/morphine)) + if(victim.has_reagent(/datum/reagent/medicine/morphine)) painkiller_bonus += 10 - if(victim.reagents?.has_reagent(/datum/reagent/determination)) + if(victim.has_reagent(/datum/reagent/determination)) painkiller_bonus += 5 if(prob(25 + (20 * severity - 2) - painkiller_bonus)) // 25%/45% chance to fail self-applying with severe and critical wounds, modded by painkillers diff --git a/code/datums/wounds/burns.dm b/code/datums/wounds/burns.dm index 850593e72e9..a998f3645f5 100644 --- a/code/datums/wounds/burns.dm +++ b/code/datums/wounds/burns.dm @@ -41,11 +41,11 @@ return if(victim.reagents) - if(victim.reagents.has_reagent(/datum/reagent/medicine/spaceacillin)) + if(victim.has_reagent(/datum/reagent/medicine/spaceacillin)) sanitization += 0.9 - if(victim.reagents.has_reagent(/datum/reagent/space_cleaner/sterilizine/)) + if(victim.has_reagent(/datum/reagent/space_cleaner/sterilizine/)) sanitization += 0.9 - if(victim.reagents.has_reagent(/datum/reagent/medicine/mine_salve)) + if(victim.has_reagent(/datum/reagent/medicine/mine_salve)) sanitization += 0.3 flesh_healing += 0.5 diff --git a/code/datums/wounds/pierce.dm b/code/datums/wounds/pierce.dm index 8fd2382ff0e..6ef74bee556 100644 --- a/code/datums/wounds/pierce.dm +++ b/code/datums/wounds/pierce.dm @@ -57,7 +57,7 @@ if(prob(5)) to_chat(victim, "You feel the [lowertext(name)] in your [limb.name] firming up from the cold!") - if(victim.reagents?.has_reagent(/datum/reagent/toxin/heparin)) + if(victim.has_reagent(/datum/reagent/toxin/heparin)) blood_flow += 0.5 // old herapin used to just add +2 bleed stacks per tick, this adds 0.5 bleed flow to all open cuts which is probably even stronger as long as you can cut them first if(limb.current_gauze) diff --git a/code/datums/wounds/slash.dm b/code/datums/wounds/slash.dm index 337ebd32b84..039d4e393b9 100644 --- a/code/datums/wounds/slash.dm +++ b/code/datums/wounds/slash.dm @@ -96,7 +96,7 @@ blood_flow = min(blood_flow, WOUND_SLASH_MAX_BLOODFLOW) - if(victim.reagents?.has_reagent(/datum/reagent/toxin/heparin)) + if(victim.has_reagent(/datum/reagent/toxin/heparin)) blood_flow += 0.5 // old herapin used to just add +2 bleed stacks per tick, this adds 0.5 bleed flow to all open cuts which is probably even stronger as long as you can cut them first if(limb.current_gauze) diff --git a/code/game/machinery/medical_kiosk.dm b/code/game/machinery/medical_kiosk.dm index 4f72b94eab0..dc2e1e4964d 100644 --- a/code/game/machinery/medical_kiosk.dm +++ b/code/game/machinery/medical_kiosk.dm @@ -236,7 +236,13 @@ chemical_list += list(list("name" = R.name, "volume" = round(R.volume, 0.01))) if(R.overdosed) overdose_list += list(list("name" = R.name)) - + var/obj/item/organ/stomach/belly = altPatient.getorganslot(ORGAN_SLOT_STOMACH) + if(belly?.reagents.reagent_list.len) //include the stomach contents if it exists + for(var/bile in belly.reagents.reagent_list) + var/datum/reagent/bit = bile + chemical_list += list(list("name" = bit.name, "volume" = round(bit.volume, 0.01))) + if(bit.overdosed) + overdose_list += list(list("name" = bit.name)) if(altPatient.reagents.addiction_list.len) for(var/datum/reagent/R in altPatient.reagents.addiction_list) addict_list += list(list("name" = R.name)) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index b7656dd7dff..2f3b6b5c367 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -407,11 +407,20 @@ GENE SCANNER if(istype(M) && M.reagents) var/render_list = list() if(M.reagents.reagent_list.len) - render_list += "Subject contains the following reagents:\n" + render_list += "Subject contains the following reagents in their blood:\n" for(var/datum/reagent/R in M.reagents.reagent_list) render_list += "[round(R.volume, 0.001)] units of [R.name][R.overdosed ? " - OVERDOSING" : "."]\n" else - render_list += "Subject contains no reagents.\n" + render_list += "Subject contains no reagents in their blood.\n" + var/obj/item/organ/stomach/belly = M.getorganslot(ORGAN_SLOT_STOMACH) + if(belly) + if(belly.reagents.reagent_list.len) + render_list += "Subject contains the following reagents in their stomach:\n" + for(var/bile in belly.reagents.reagent_list) + var/datum/reagent/bit = bile + render_list += "[round(bit.volume, 0.001)] units of [bit.name][bit.overdosed ? " - OVERDOSING" : "."]\n" + else + render_list += "Subject contains no reagents in their stomach.\n" if(M.reagents.addiction_list.len) render_list += "Subject is addicted to the following reagents:\n" for(var/datum/reagent/R in M.reagents.addiction_list) diff --git a/code/modules/antagonists/cult/ritual.dm b/code/modules/antagonists/cult/ritual.dm index 65c7613a9c1..40185894c09 100644 --- a/code/modules/antagonists/cult/ritual.dm +++ b/code/modules/antagonists/cult/ritual.dm @@ -24,10 +24,10 @@ This file contains the cult dagger and rune list code /obj/item/melee/cultblade/dagger/attack(mob/living/M, mob/living/user) if(iscultist(M)) - if(M.reagents && M.reagents.has_reagent(/datum/reagent/water/holywater)) //allows cultists to be rescued from the clutches of ordained religion + if(M.has_reagent(/datum/reagent/water/holywater)) //allows cultists to be rescued from the clutches of ordained religion to_chat(user, "You remove the taint from [M]." ) - var/holy2unholy = M.reagents.get_reagent_amount(/datum/reagent/water/holywater) - M.reagents.del_reagent(/datum/reagent/water/holywater) + var/holy2unholy = M.get_reagent_amount(/datum/reagent/water/holywater) + M.remove_reagent(/datum/reagent/water/holywater, holy2unholy) M.reagents.add_reagent(/datum/reagent/fuel/unholywater,holy2unholy) log_combat(user, M, "smacked", src, " removing the holy water from them") return FALSE diff --git a/code/modules/antagonists/devil/devil.dm b/code/modules/antagonists/devil/devil.dm index 0add4f4a825..be678284dd1 100644 --- a/code/modules/antagonists/devil/devil.dm +++ b/code/modules/antagonists/devil/devil.dm @@ -385,14 +385,14 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master", if(BANISH_WATER) if(iscarbon(body)) var/mob/living/carbon/H = body - return H.reagents.has_reagent(/datum/reagent/water/holywater) + return H.has_reagent(/datum/reagent/water/holywater) return FALSE if(BANISH_COFFIN) return (body && istype(body.loc, /obj/structure/closet/crate/coffin)) if(BANISH_FORMALDYHIDE) if(iscarbon(body)) var/mob/living/carbon/H = body - return H.reagents.has_reagent(/datum/reagent/toxin/formaldehyde) + return H.has_reagent(/datum/reagent/toxin/formaldehyde) return FALSE if(BANISH_RUNES) if(body) diff --git a/code/modules/mob/living/bloodcrawl.dm b/code/modules/mob/living/bloodcrawl.dm index f7451edba28..e9505ddb714 100644 --- a/code/modules/mob/living/bloodcrawl.dm +++ b/code/modules/mob/living/bloodcrawl.dm @@ -79,7 +79,7 @@ if(victim.stat == CONSCIOUS) visible_message("[victim] kicks free of the blood pool just before entering it!", null, "You hear splashing and struggling.") - else if(victim.reagents?.has_reagent(/datum/reagent/consumable/ethanol/demonsblood, needs_metabolizing = TRUE)) + else if(victim.has_reagent(/datum/reagent/consumable/ethanol/demonsblood, needs_metabolizing = TRUE)) visible_message("Something prevents [victim] from entering the pool!", "A strange force is blocking [victim] from entering!", "You hear a splash and a thud.") else victim.forceMove(src) @@ -112,7 +112,7 @@ if(!victim) return FALSE - if(victim.reagents?.has_reagent(/datum/reagent/consumable/ethanol/devilskiss, needs_metabolizing = TRUE)) + if(victim.has_reagent(/datum/reagent/consumable/ethanol/devilskiss, needs_metabolizing = TRUE)) to_chat(src, "AAH! THEIR FLESH! IT BURNS!") adjustBruteLoss(25) //I can't use adjustHealth() here because bloodcrawl affects /mob/living and adjustHealth() only affects simple mobs var/found_bloodpool = FALSE diff --git a/code/modules/mob/living/carbon/death.dm b/code/modules/mob/living/carbon/death.dm index 5b2a08a8dcb..0e69053951e 100644 --- a/code/modules/mob/living/carbon/death.dm +++ b/code/modules/mob/living/carbon/death.dm @@ -7,7 +7,7 @@ if(!gibbed) emote("deathgasp") - reagents.end_metabolization(src) + end_metabolization() . = ..() diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 5c35060e89a..355c1bb1c2e 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -281,7 +281,7 @@ if(appears_dead) bleed_text += ", but it has pooled and is not flowing.\n" else - if(reagents.has_reagent(/datum/reagent/toxin/heparin, needs_metabolizing = TRUE)) + if(has_reagent(/datum/reagent/toxin/heparin, needs_metabolizing = TRUE)) bleed_text += " incredibly quickly" bleed_text += "!\n" @@ -292,7 +292,7 @@ msg += bleed_text.Join() - if(reagents.has_reagent(/datum/reagent/teslium, needs_metabolizing = TRUE)) + if(has_reagent(/datum/reagent/teslium, needs_metabolizing = TRUE)) msg += "[t_He] [t_is] emitting a gentle blue glow!\n" if(islist(stun_absorption)) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 7c15e50ed74..7f866150083 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -371,7 +371,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) C.setToxLoss(0, TRUE, TRUE) if(TRAIT_NOMETABOLISM in inherent_traits) - C.reagents.end_metabolization(C, keep_liverless = TRUE) + C.end_metabolization(keep_liverless = TRUE) if(TRAIT_GENELESS in inherent_traits) C.dna.remove_all_mutations() // Radiation immune mobs can't get mutations normally diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm index 9e6ac3a9e12..b6a25d5ac7e 100644 --- a/code/modules/mob/living/carbon/human/species_types/vampire.dm +++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm @@ -102,7 +102,7 @@ to_chat(victim, "[H] tries to bite you, but stops before touching you!") to_chat(H, "[victim] is blessed! You stop just in time to avoid catching fire.") return - if(victim?.reagents?.has_reagent(/datum/reagent/consumable/garlic)) + if(victim.has_reagent(/datum/reagent/consumable/garlic)) to_chat(victim, "[H] tries to bite you, but recoils in disgust!") to_chat(H, "[victim] reeks of garlic! you can't bring yourself to drain such tainted blood.") return diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 66b17f7fe6d..c844b3e6cae 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -74,7 +74,7 @@ //Second link in a breath chain, calls check_breath() /mob/living/carbon/proc/breathe() var/obj/item/organ/lungs = getorganslot(ORGAN_SLOT_LUNGS) - if(reagents.has_reagent(/datum/reagent/toxin/lexorin, needs_metabolizing = TRUE)) + if(has_reagent(/datum/reagent/toxin/lexorin, needs_metabolizing = TRUE)) return if(istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell)) return @@ -146,7 +146,7 @@ //CRIT if(!breath || (breath.total_moles() == 0) || !lungs) - if(reagents.has_reagent(/datum/reagent/medicine/epinephrine, needs_metabolizing = TRUE) && lungs) + if(has_reagent(/datum/reagent/medicine/epinephrine, needs_metabolizing = TRUE) && lungs) return FALSE adjustOxyLoss(1) @@ -346,7 +346,7 @@ if(O.owner) // This exist mostly because reagent metabolization can cause organ reshuffling O.on_life() else - if(reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 1)) // No organ decay if the body contains formaldehyde. + if(has_reagent(/datum/reagent/toxin/formaldehyde, 1)) // No organ decay if the body contains formaldehyde. return for(var/V in internal_organs) var/obj/item/organ/O = V @@ -723,6 +723,37 @@ All effects don't start immediately, but rather get worse over time; the rate is return fullness +/mob/living/carbon/has_reagent(reagent, amount = -1, needs_metabolizing = FALSE) + . = ..() + if(.) + return + var/obj/item/organ/stomach/belly = getorganslot(ORGAN_SLOT_STOMACH) + if(!belly) + return FALSE + return belly.reagents.has_reagent(reagent, amount, needs_metabolizing) + +/mob/living/carbon/remove_reagent(reagent, custom_amount, safety) + if(!custom_amount) + custom_amount = get_reagent_amount(reagent) + var/amount_body = reagents.get_reagent_amount(reagent) + if(custom_amount <= amount_body) + reagents.remove_reagent(reagent, custom_amount, safety) + return TRUE + reagents.remove_reagent(reagent, amount_body, safety) + custom_amount -= amount_body + var/obj/item/organ/stomach/belly = getorganslot(ORGAN_SLOT_STOMACH) + if(!belly) + return FALSE + belly.reagents.remove_reagent(reagent, custom_amount, safety) + return TRUE + +/mob/living/carbon/get_reagent_amount(reagent) + . = ..() + var/obj/item/organ/stomach/belly = getorganslot(ORGAN_SLOT_STOMACH) + if(!belly) + return + . += belly.reagents.get_reagent_amount(reagent) + ///////// //LIVER// ///////// @@ -741,7 +772,7 @@ All effects don't start immediately, but rather get worse over time; the rate is return TRUE /mob/living/carbon/proc/liver_failure() - reagents.end_metabolization(src, keep_liverless = TRUE) //Stops trait-based effects on reagents, to prevent permanent buffs + end_metabolization(keep_liverless = TRUE) //Stops trait-based effects on reagents, to prevent permanent buffs reagents.metabolize(src, can_overdose=FALSE, liverless = TRUE) if(HAS_TRAIT(src, TRAIT_STABLELIVER) || HAS_TRAIT(src, TRAIT_NOMETABOLISM)) return @@ -749,6 +780,19 @@ All effects don't start immediately, but rather get worse over time; the rate is if(prob(30)) to_chat(src, "You feel a stabbing pain in your abdomen!") +/** + * Ends metabolization on the mob + * + * This stop all reagents in the body and organs from metabolizing + * Vars: + * * keep_liverless (bool)(optional)(default:TRUE) Will keep working without a liver + */ +/mob/living/carbon/proc/end_metabolization(keep_liverless = TRUE) + reagents.end_metabolization(src, keep_liverless = keep_liverless) + var/obj/item/organ/stomach/belly = getorganslot(ORGAN_SLOT_STOMACH) + if(belly) + belly.reagents.end_metabolization(src, keep_liverless = keep_liverless) + ///////////// //CREMATION// ///////////// diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index 8f0fb6d5c53..efefd945d1d 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -70,9 +70,9 @@ /mob/living/carbon/monkey/on_reagent_change() . = ..() var/amount - if(reagents.has_reagent(/datum/reagent/medicine/morphine)) + if(has_reagent(/datum/reagent/medicine/morphine)) amount = -1 - if(reagents.has_reagent(/datum/reagent/consumable/nuka_cola)) + if(has_reagent(/datum/reagent/consumable/nuka_cola)) amount = -1 if(amount) add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/monkey_reagent_speedmod, TRUE, amount) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index e01ed2440ee..22a11a8c7e8 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -132,6 +132,42 @@ fullness += bits.nutriment_factor * bits.volume / bits.metabolization_rate return fullness +/** + * Check if the mob contains this reagent. + * + * This will validate the the reagent holder for the mob and any sub holders contain the requested reagent. + * Vars: + * * reagent (typepath) takes a PATH to a reagent. + * * amount (int) checks for having a specific amount of that chemical. + * * needs_metabolizing (bool) takes into consideration if the chemical is matabolizing when it's checked. + */ +/mob/living/proc/has_reagent(reagent, amount = -1, needs_metabolizing = FALSE) + return reagents.has_reagent(reagent, amount, needs_metabolizing) + +/** + * Removes reagents from the mob + * + * This will locate the reagent in the mob and remove it from reagent holders + * Vars: + * * reagent (typepath) takes a PATH to a reagent. + * * custom_amount (int)(optional) checks for having a specific amount of that chemical. + * * safety (bool) check for the trans_id_to + */ +/mob/living/proc/remove_reagent(reagent, custom_amount, safety) + if(!custom_amount) + custom_amount = get_reagent_amount(reagent) + return reagents.remove_reagent(reagent, custom_amount, safety) + +/** + * Returns the amount of a reagent from the mob + * + * This will locate the reagent in the mob and return the total amount from all reagent holders + * Vars: + * * reagent (typepath) takes a PATH to a reagent. + */ +/mob/living/proc/get_reagent_amount(reagent) + return reagents.get_reagent_amount(reagent) + //this updates all special effects: knockdown, druggy, stuttering, etc.. /mob/living/proc/handle_status_effects() diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index bb0546606ad..59c33681a81 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -146,9 +146,9 @@ . = ..() remove_movespeed_modifier(/datum/movespeed_modifier/slime_reagentmod) var/amount = 0 - if(reagents.has_reagent(/datum/reagent/medicine/morphine)) // morphine slows slimes down + if(has_reagent(/datum/reagent/medicine/morphine)) // morphine slows slimes down amount = 2 - if(reagents.has_reagent(/datum/reagent/consumable/frostoil)) // Frostoil also makes them move VEEERRYYYYY slow + if(has_reagent(/datum/reagent/consumable/frostoil)) // Frostoil also makes them move VEEERRYYYYY slow amount = 5 if(amount) add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/slime_reagentmod, multiplicative_slowdown = amount) diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 2c25e1e9dc2..9cab0471a31 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -252,7 +252,10 @@ trans_data = copy_data(T) R.add_reagent(T.type, transfer_amount * multiplier, trans_data, chem_temp, no_react = 1) //we only handle reaction after every reagent has been transfered. if(methods) - R.expose_single(T, target_atom, methods, part, show_message) + if(istype(target_atom, /obj/item/organ/stomach)) + R.expose_single(T, target, methods, part, show_message) + else + R.expose_single(T, target_atom, methods, part, show_message) T.on_transfer(target_atom, methods, transfer_amount * multiplier) remove_reagent(T.type, transfer_amount) transfer_log[T.type] = transfer_amount @@ -272,7 +275,10 @@ R.add_reagent(T.type, transfer_amount * multiplier, trans_data, chem_temp, no_react = 1) to_transfer = max(to_transfer - transfer_amount , 0) if(methods) - R.expose_single(T, target_atom, methods, transfer_amount, show_message) + if(istype(target_atom, /obj/item/organ/stomach)) + R.expose_single(T, target, methods, transfer_amount, show_message) + else + R.expose_single(T, target_atom, methods, transfer_amount, show_message) T.on_transfer(target_atom, methods, transfer_amount * multiplier) remove_reagent(T.type, transfer_amount) transfer_log[T.type] = transfer_amount @@ -766,6 +772,10 @@ if(isliving(my_atom)) R.on_mob_add(my_atom) //Must occur befor it could posibly run on_mob_delete + else if(istype(my_atom, /obj/item/organ/stomach)) + var/obj/item/organ/stomach/belly = my_atom + var/mob/living/carbon/body = belly.owner + R.on_mob_add(body) update_total() if(my_atom) my_atom.on_reagent_change(ADD_REAGENT) diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index 855f7cc84d6..9113550bcd3 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm @@ -654,7 +654,7 @@ All effects don't start immediately, but rather get worse over time; the rate is /datum/reagent/consumable/ethanol/tequila_sunrise/on_mob_life(mob/living/carbon/M) if(QDELETED(light_holder)) - M.reagents.del_reagent(/datum/reagent/consumable/ethanol/tequila_sunrise) //If we lost our light object somehow, remove the reagent + holder.del_reagent(type) //If we lost our light object somehow, remove the reagent else if(light_holder.loc != M) light_holder.forceMove(M) return ..() @@ -1730,7 +1730,7 @@ All effects don't start immediately, but rather get worse over time; the rate is /datum/reagent/consumable/ethanol/alexander/on_mob_life(mob/living/L) ..() if(mighty_shield && !(mighty_shield in L.contents)) //If you had a shield and lose it, you lose the reagent as well. Otherwise this is just a normal drink. - L.reagents.del_reagent(/datum/reagent/consumable/ethanol/alexander) + holder.remove_reagent(type) /datum/reagent/consumable/ethanol/alexander/on_mob_end_metabolize(mob/living/L) if(mighty_shield) diff --git a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm index 85a8754e771..d574e489eb2 100644 --- a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm @@ -60,7 +60,7 @@ to_chat(M, "You win, and the malevolent spirits fade away as well as your wounds.") M.client.give_award(/datum/award/achievement/misc/helbitaljanken, M) M.revive(full_heal = TRUE, admin_revive = FALSE) - M.reagents.del_reagent(type) + holder.del_reagent(type) return ..() @@ -268,7 +268,7 @@ radbonustemp = rand(radbonustemp - 50, radbonustemp + 50) // Basically this means 50K and below will always give the percent heal, and upto 150K could. Calculated once. /datum/reagent/medicine/c2/seiver/on_mob_life(mob/living/carbon/human/M) - var/chemtemp = min(M.reagents?.chem_temp, 1000) + var/chemtemp = min(holder.chem_temp, 1000) chemtemp = chemtemp ? chemtemp : 273 //why do you have null sweaty var/healypoints = 0 //5 healypoints = 1 heart damage; 5 rads = 1 tox damage healed for the purpose of healypoints diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm index d5fd7418e85..d0df0ce2222 100644 --- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm @@ -211,8 +211,8 @@ if(M.getBruteLoss() && prob(20)) M.heal_bodypart_damage(1,0, 0) . = 1 - if(holder.has_reagent(/datum/reagent/consumable/capsaicin)) - holder.remove_reagent(/datum/reagent/consumable/capsaicin, 2) + if(M.has_reagent(/datum/reagent/consumable/capsaicin)) + M.remove_reagent(/datum/reagent/consumable/capsaicin, 2) ..() /datum/reagent/consumable/soymilk @@ -266,8 +266,8 @@ M.AdjustSleeping(-40, FALSE) //310.15 is the normal bodytemp. M.adjust_bodytemperature(25 * TEMPERATURE_DAMAGE_COEFFICIENT, 0, M.get_body_temp_normal()) - if(holder.has_reagent(/datum/reagent/consumable/frostoil)) - holder.remove_reagent(/datum/reagent/consumable/frostoil, 5) + if(M.has_reagent(/datum/reagent/consumable/frostoil)) + M.remove_reagent(/datum/reagent/consumable/frostoil, 5) ..() . = 1 diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index 07aa33cf5d8..cc580905886 100755 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -237,8 +237,8 @@ switch(current_cycle) if(1 to 15) heating = 5 * TEMPERATURE_DAMAGE_COEFFICIENT - if(holder.has_reagent(/datum/reagent/cryostylane)) - holder.remove_reagent(/datum/reagent/cryostylane, 5) + if(M.has_reagent(/datum/reagent/cryostylane)) + M.remove_reagent(/datum/reagent/cryostylane, 5) if(isslime(M)) heating = rand(5,20) if(15 to 25) @@ -267,8 +267,8 @@ switch(current_cycle) if(1 to 15) cooling = -10 * TEMPERATURE_DAMAGE_COEFFICIENT - if(holder.has_reagent(/datum/reagent/consumable/capsaicin)) - holder.remove_reagent(/datum/reagent/consumable/capsaicin, 5) + if(M.has_reagent(/datum/reagent/consumable/capsaicin)) + M.remove_reagent(/datum/reagent/consumable/capsaicin, 5) if(isslime(M)) cooling = -rand(5,20) if(15 to 25) @@ -343,7 +343,7 @@ victim.vomit() /datum/reagent/consumable/condensedcapsaicin/on_mob_life(mob/living/carbon/M) - if(!holder.has_reagent(/datum/reagent/consumable/milk)) + if(!M.has_reagent(/datum/reagent/consumable/milk)) if(prob(10)) M.visible_message("[M] [pick("dry heaves!","coughs!","splutters!")]") ..() @@ -596,7 +596,7 @@ mytray.adjustPests(rand(1,2)) /datum/reagent/consumable/honey/on_mob_life(mob/living/carbon/M) - M.reagents.add_reagent(/datum/reagent/consumable/sugar,3) + holder.add_reagent(/datum/reagent/consumable/sugar,3) if(prob(55)) M.adjustBruteLoss(-1*REM, 0) M.adjustFireLoss(-1*REM, 0) diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index b7b28965f72..2bef3c55ced 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -111,8 +111,8 @@ M.AdjustUnconscious(-20, FALSE) M.AdjustImmobilized(-20, FALSE) M.AdjustParalyzed(-20, FALSE) - if(holder.has_reagent(/datum/reagent/toxin/mindbreaker)) - holder.remove_reagent(/datum/reagent/toxin/mindbreaker, 5) + if(M.has_reagent(/datum/reagent/toxin/mindbreaker)) + M.remove_reagent(/datum/reagent/toxin/mindbreaker, 5) M.hallucination = max(0, M.hallucination - 10) if(prob(30)) M.adjustToxLoss(1, 0) @@ -126,10 +126,10 @@ /datum/reagent/medicine/synaphydramine/on_mob_life(mob/living/carbon/M) M.drowsyness = max(M.drowsyness-5, 0) - if(holder.has_reagent(/datum/reagent/toxin/mindbreaker)) - holder.remove_reagent(/datum/reagent/toxin/mindbreaker, 5) - if(holder.has_reagent(/datum/reagent/toxin/histamine)) - holder.remove_reagent(/datum/reagent/toxin/histamine, 5) + if(M.has_reagent(/datum/reagent/toxin/mindbreaker)) + M.remove_reagent(/datum/reagent/toxin/mindbreaker, 5) + if(M.has_reagent(/datum/reagent/toxin/histamine)) + M.remove_reagent(/datum/reagent/toxin/histamine, 5) M.hallucination = max(0, M.hallucination - 10) if(prob(30)) M.adjustToxLoss(1, 0) @@ -570,7 +570,7 @@ if(prob(10)) M.drowsyness += 1 M.jitteriness -= 1 - M.reagents.remove_reagent(/datum/reagent/toxin/histamine,3) + M.remove_reagent(/datum/reagent/toxin/histamine,3) ..() /datum/reagent/medicine/morphine @@ -726,11 +726,11 @@ /datum/reagent/medicine/epinephrine/on_mob_life(mob/living/carbon/M) . = TRUE - if(holder.has_reagent(/datum/reagent/toxin/lexorin)) - holder.remove_reagent(/datum/reagent/toxin/lexorin, 2) - holder.remove_reagent(/datum/reagent/medicine/epinephrine, 1) + if(M.has_reagent(/datum/reagent/toxin/lexorin)) + M.remove_reagent(/datum/reagent/toxin/lexorin, 2) + M.remove_reagent(/datum/reagent/medicine/epinephrine, 1) if(prob(20)) - holder.add_reagent(/datum/reagent/toxin/histamine, 4) + M.reagents.add_reagent(/datum/reagent/toxin/histamine, 4) ..() return if(M.health <= M.crit_threshold) @@ -824,8 +824,8 @@ color = "#C0C0C0" //ditto /datum/reagent/medicine/neurine/on_mob_life(mob/living/carbon/C) - if(holder.has_reagent(/datum/reagent/consumable/ethanol/neurotoxin)) - holder.remove_reagent(/datum/reagent/consumable/ethanol/neurotoxin, 5) + if(C.has_reagent(/datum/reagent/consumable/ethanol/neurotoxin)) + C.remove_reagent(/datum/reagent/consumable/ethanol/neurotoxin, 5) if(prob(15)) C.cure_trauma_type(resilience = TRAUMA_RESILIENCE_BASIC) ..() @@ -908,7 +908,7 @@ /datum/reagent/medicine/insulin/on_mob_life(mob/living/carbon/M) if(M.AdjustSleeping(-20, FALSE)) . = 1 - M.reagents.remove_reagent(/datum/reagent/consumable/sugar, 3) + M.remove_reagent(/datum/reagent/consumable/sugar, 3) ..() //Trek Chems, used primarily by medibots. Only heals a specific damage type, but is very efficient. diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index b5ac596877f..3e3ca95c10f 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -535,7 +535,7 @@ if(current_cycle >= cycles_to_turn) var/datum/species/species_type = race H.set_species(species_type) - H.reagents.del_reagent(type) + holder.del_reagent(type) to_chat(H, "You've become \a [lowertext(initial(species_type.name))]!") return ..() @@ -592,12 +592,12 @@ to_chat(H, "Your jelly shifts and morphs, turning you into another subspecies!") var/species_type = pick(subtypesof(/datum/species/jelly)) H.set_species(species_type) - H.reagents.del_reagent(type) + holder.del_reagent(type) return TRUE if(current_cycle >= cycles_to_turn) //overwrite since we want subtypes of jelly var/datum/species/species_type = pick(subtypesof(race)) H.set_species(species_type) - H.reagents.del_reagent(type) + holder.del_reagent(type) to_chat(H, "You've become \a [initial(species_type.name)]!") return TRUE return ..() @@ -2195,7 +2195,7 @@ var/yuck_cycle = 0 //! The `current_cycle` when puking starts. /datum/reagent/yuck/on_mob_add(mob/living/L) - if(HAS_TRAIT(src, TRAIT_NOHUNGER)) //they can't puke + if(HAS_TRAIT(L, TRAIT_NOHUNGER)) //they can't puke holder.del_reagent(type) #define YUCK_PUKE_CYCLES 3 // every X cycle is a puke diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm index bb48951d06f..8d3a5385cfd 100644 --- a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm @@ -211,8 +211,8 @@ /datum/reagent/cryostylane/on_mob_life(mob/living/carbon/M) //TODO: code freezing into an ice cube - if(M.reagents.has_reagent(/datum/reagent/oxygen)) - M.reagents.remove_reagent(/datum/reagent/oxygen, 0.5) + if(M.has_reagent(/datum/reagent/oxygen)) + M.remove_reagent(/datum/reagent/oxygen, 0.5) M.adjust_bodytemperature(-15) ..() @@ -232,8 +232,8 @@ self_consuming = TRUE /datum/reagent/pyrosium/on_mob_life(mob/living/carbon/M) - if(M.reagents.has_reagent(/datum/reagent/oxygen)) - M.reagents.remove_reagent(/datum/reagent/oxygen, 0.5) + if(M.has_reagent(/datum/reagent/oxygen)) + M.remove_reagent(/datum/reagent/oxygen, 0.5) M.adjust_bodytemperature(15) ..() diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 32db835f22d..a9eb707b338 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -74,8 +74,8 @@ penetrates_skin = NONE /datum/reagent/toxin/plasma/on_mob_life(mob/living/carbon/C) - if(holder.has_reagent(/datum/reagent/medicine/epinephrine)) - holder.remove_reagent(/datum/reagent/medicine/epinephrine, 2*REM) + if(C.has_reagent(/datum/reagent/medicine/epinephrine)) + C.remove_reagent(/datum/reagent/medicine/epinephrine, 2*REM) C.adjustPlasma(20) return ..() @@ -120,8 +120,8 @@ material = /datum/material/hot_ice /datum/reagent/toxin/hot_ice/on_mob_life(mob/living/carbon/M) - if(holder.has_reagent(/datum/reagent/medicine/epinephrine)) - holder.remove_reagent(/datum/reagent/medicine/epinephrine, 2*REM) + if(M.has_reagent(/datum/reagent/medicine/epinephrine)) + M.remove_reagent(/datum/reagent/medicine/epinephrine, 2*REM) M.adjustPlasma(20) M.adjust_bodytemperature(-7 * TEMPERATURE_DAMAGE_COEFFICIENT, M.get_body_temp_normal()) return ..() @@ -214,7 +214,7 @@ . = ..() exposed_mob.adjustOxyLoss(0.5*REM, 0) if(methods & INGEST) - var/datum/reagent/toxin/zombiepowder/zombiepowder = exposed_mob.reagents.has_reagent(/datum/reagent/toxin/zombiepowder) + var/datum/reagent/toxin/zombiepowder/zombiepowder = exposed_mob.has_reagent(/datum/reagent/toxin/zombiepowder) if(istype(zombiepowder)) zombiepowder.fakedeath_active = TRUE @@ -530,7 +530,7 @@ . = 1 if(prob(15)) M.reagents.add_reagent(/datum/reagent/toxin/histamine, pick(5,10)) - M.reagents.remove_reagent(/datum/reagent/toxin/venom, 1.1) + holder.remove_reagent(/datum/reagent/toxin/venom, 1.1) else ..() @@ -604,7 +604,7 @@ . = 1 if(prob(3)) M.reagents.add_reagent(/datum/reagent/toxin/histamine,rand(1,3)) - M.reagents.remove_reagent(/datum/reagent/toxin/itching_powder,1.2) + holder.remove_reagent(/datum/reagent/toxin/itching_powder,1.2) return ..() diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm index 711f68c6a23..0de053e6405 100644 --- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm +++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm @@ -903,7 +903,7 @@ /datum/status_effect/stabilized/lightpink/tick() for(var/mob/living/carbon/human/H in range(1, get_turf(owner))) - if(H != owner && H.stat != DEAD && H.health <= 0 && !H.reagents.has_reagent(/datum/reagent/medicine/epinephrine)) + if(H != owner && H.stat != DEAD && H.health <= 0 && !H.has_reagent(/datum/reagent/medicine/epinephrine)) to_chat(owner, "[linked_extract] pulses in sync with [H]'s heartbeat, trying to keep [H.p_them()] alive.") H.reagents.add_reagent(/datum/reagent/medicine/epinephrine,5) return ..() diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm index bd9eb339cca..19e81068651 100644 --- a/code/modules/surgery/organs/heart.dm +++ b/code/modules/surgery/organs/heart.dm @@ -220,7 +220,7 @@ /obj/item/organ/heart/cybernetic/on_life() . = ..() - if(dose_available && owner.health <= owner.crit_threshold && !owner.reagents.has_reagent(rid)) + if(dose_available && owner.health <= owner.crit_threshold && !owner.has_reagent(rid)) used_dose() /obj/item/organ/heart/cybernetic/proc/used_dose() diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index 3cbafc8a5f1..e8768306886 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -77,7 +77,7 @@ return if(!breath || (breath.total_moles() == 0)) - if(H.reagents.has_reagent(crit_stabilizing_reagent, needs_metabolizing = TRUE)) + if(H.has_reagent(crit_stabilizing_reagent, needs_metabolizing = TRUE)) return if(H.health >= H.crit_threshold) H.adjustOxyLoss(HUMAN_MAX_OXYLOSS) diff --git a/code/modules/surgery/organs/stomach.dm b/code/modules/surgery/organs/stomach.dm index d517e435111..134030c1baa 100755 --- a/code/modules/surgery/organs/stomach.dm +++ b/code/modules/surgery/organs/stomach.dm @@ -33,7 +33,9 @@ //digest food var/mob/living/carbon/body = owner - reagents.metabolize(body, can_overdose=TRUE) + var/obj/item/organ/liver/liver = body.getorganslot(ORGAN_SLOT_LIVER) + var/liverless = (!liver || (liver.organ_flags & ORGAN_FAILING)) + reagents.metabolize(body, can_overdose=TRUE, liverless=liverless) if(body) handle_disgust(body) diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm index 124f996937e..3efc06caed0 100644 --- a/code/modules/surgery/surgery_step.dm +++ b/code/modules/surgery/surgery_step.dm @@ -152,12 +152,12 @@ if(require_all_chems) . = TRUE for(var/R in chems_needed) - if(!target.reagents.has_reagent(R)) + if(!target.has_reagent(R)) return FALSE else . = FALSE for(var/R in chems_needed) - if(target.reagents.has_reagent(R)) + if(target.has_reagent(R)) return TRUE /datum/surgery_step/proc/get_chem_list() diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index ff22ba4fb31..223ea1b4bae 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -23,15 +23,18 @@ #include "medical_wounds.dm" #include "metabolizing.dm" #include "outfit_sanity.dm" +#include "pills.dm" #include "plantgrowth_tests.dm" #include "quick_swap_sanity.dm" #include "reagent_id_typos.dm" +#include "reagent_mod_procs.dm" #include "reagent_recipe_collisions.dm" #include "resist.dm" #include "say.dm" #include "siunit.dm" #include "spawn_humans.dm" #include "species_whitelists.dm" +#include "stomach.dm" #include "subsystem_init.dm" #include "surgeries.dm" #include "timer_sanity.dm" diff --git a/code/modules/unit_tests/pills.dm b/code/modules/unit_tests/pills.dm new file mode 100644 index 00000000000..ed8f64ce958 --- /dev/null +++ b/code/modules/unit_tests/pills.dm @@ -0,0 +1,10 @@ +/datum/unit_test/pills/Run() + var/mob/living/carbon/human/human = allocate(/mob/living/carbon/human) + var/obj/item/reagent_containers/pill/iron/pill = allocate(/obj/item/reagent_containers/pill/iron) + + TEST_ASSERT_EQUAL(human.has_reagent(/datum/reagent/iron), FALSE, "Human somehow has iron before taking pill") + + pill.attack(human, human) + human.Life() + + TEST_ASSERT(human.has_reagent(/datum/reagent/iron), "Human doesn't have iron after taking pill") diff --git a/code/modules/unit_tests/reagent_mod_procs.dm b/code/modules/unit_tests/reagent_mod_procs.dm new file mode 100644 index 00000000000..c95b48f41c3 --- /dev/null +++ b/code/modules/unit_tests/reagent_mod_procs.dm @@ -0,0 +1,41 @@ +/datum/unit_test/reagent_mob_procs/Run() + var/mob/living/carbon/human/human = allocate(/mob/living/carbon/human) + var/obj/item/organ/stomach/belly = human.getorganslot(ORGAN_SLOT_STOMACH) + var/obj/item/reagent_containers/food/snacks/hotdog/food = allocate(/obj/item/reagent_containers/food/snacks/hotdog) + + TEST_ASSERT_EQUAL(human.has_reagent(/datum/reagent/consumable/ketchup), FALSE, "Human somehow has ketchup before eating") + TEST_ASSERT_EQUAL(human.has_reagent(/datum/reagent/medicine/epinephrine), FALSE, "Human somehow has epinephrine before injecting") + + food.attack(human, human) + human.reagents.add_reagent(/datum/reagent/medicine/epinephrine, 5) + + TEST_ASSERT(human.has_reagent(/datum/reagent/consumable/ketchup), "Human doesn't have ketchup after eating") + TEST_ASSERT(human.has_reagent(/datum/reagent/medicine/epinephrine), "Human doesn't have epinephrine after injecting") + + TEST_ASSERT_EQUAL(human.get_reagent_amount(/datum/reagent/medicine/epinephrine), 5, "Human does not have the proper amount of epinephrine") + + var/ketchup_amount = human.get_reagent_amount(/datum/reagent/consumable/ketchup) + human.remove_reagent(/datum/reagent/consumable/ketchup, ketchup_amount) + // Test that the removal of a stomach only reagent works + TEST_ASSERT_EQUAL(human.has_reagent(/datum/reagent/consumable/ketchup), FALSE, "Human still has ketchup after removal") + TEST_ASSERT(human.has_reagent(/datum/reagent/medicine/epinephrine), "Human doesn't have epinephrine after removal of ketchup") + + belly.reagents.add_reagent(/datum/reagent/medicine/epinephrine, 5) + + TEST_ASSERT_EQUAL(human.get_reagent_amount(/datum/reagent/medicine/epinephrine), 10, "Human does not have the proper amount of epinephrine after added to belly") + + human.remove_reagent(/datum/reagent/medicine/epinephrine, 7) + // Test that the removal goes past the body and in to the stomach + TEST_ASSERT_EQUAL(human.get_reagent_amount(/datum/reagent/medicine/epinephrine), 3, "Human does not have the proper amount of epinephrine after removal of 7u") + + human.reagents.add_reagent(/datum/reagent/medicine/epinephrine, 6) + + TEST_ASSERT_EQUAL(human.get_reagent_amount(/datum/reagent/medicine/epinephrine), 9, "Human does not have the proper amount of epinephrine after added to body") + + human.remove_reagent(/datum/reagent/medicine/epinephrine, 3) + // Test that removing a value less then what is in the body does not bleed to stomach + TEST_ASSERT_EQUAL(human.get_reagent_amount(/datum/reagent/medicine/epinephrine), 6, "Human does not have the proper amount of epinephrine after removal of 3u") + + human.remove_reagent(/datum/reagent/medicine/epinephrine) + // Test removing all named reagent without a value + TEST_ASSERT_EQUAL(human.get_reagent_amount(/datum/reagent/medicine/epinephrine), FALSE, "Human does not have the proper amount of epinephrine after removal of 3u") diff --git a/code/modules/unit_tests/stomach.dm b/code/modules/unit_tests/stomach.dm new file mode 100644 index 00000000000..e7f5458da7f --- /dev/null +++ b/code/modules/unit_tests/stomach.dm @@ -0,0 +1,19 @@ +/datum/unit_test/stomach/Run() + var/mob/living/carbon/human/human = allocate(/mob/living/carbon/human) + var/obj/item/reagent_containers/food/snacks/hotdog/fooditem = allocate(/obj/item/reagent_containers/food/snacks/hotdog) + var/obj/item/organ/stomach/belly = human.getorganslot(ORGAN_SLOT_STOMACH) + + TEST_ASSERT_EQUAL(human.has_reagent(/datum/reagent/consumable/ketchup), FALSE, "Human somehow has ketchup before eating") + + fooditem.attack(human, human) + + TEST_ASSERT(human.has_reagent(/datum/reagent/consumable/ketchup), "Human doesn't have ketchup after eating") + TEST_ASSERT(belly.reagents.has_reagent(/datum/reagent/consumable/ketchup), "Stomach doesn't have ketchup after eating") + + qdel(belly) + + TEST_ASSERT_EQUAL(human.has_reagent(/datum/reagent/consumable/ketchup), FALSE, "Human still has ketchup after removal of stomach") + + fooditem.attack(human, human) + + TEST_ASSERT_EQUAL(human.has_reagent(/datum/reagent/consumable/ketchup), FALSE, "Human has ketchup without a stomach")