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 <nightred@gmail.com>
This commit is contained in:
SkyratBot
2020-09-07 04:10:16 +02:00
committed by GitHub
co-authored by NightRed
parent afe04f1b94
commit c6007727cd
41 changed files with 281 additions and 97 deletions
+2 -2
View File
@@ -79,7 +79,7 @@
if(victim.stat == CONSCIOUS)
visible_message("<span class='warning'>[victim] kicks free of the blood pool just before entering it!</span>", null, "<span class='notice'>You hear splashing and struggling.</span>")
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("<span class='warning'>Something prevents [victim] from entering the pool!</span>", "<span class='warning'>A strange force is blocking [victim] from entering!</span>", "<span class='notice'>You hear a splash and a thud.</span>")
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, "<span class='warning'><b>AAH! THEIR FLESH! IT BURNS!</b></span>")
adjustBruteLoss(25) //I can't use adjustHealth() here because bloodcrawl affects /mob/living and adjustHealth() only affects simple mobs
var/found_bloodpool = FALSE
+1 -1
View File
@@ -7,7 +7,7 @@
if(!gibbed)
emote("deathgasp")
reagents.end_metabolization(src)
end_metabolization()
. = ..()
@@ -281,7 +281,7 @@
if(appears_dead)
bleed_text += ", but it has pooled and is not flowing.</span></B>\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 += "!</B>\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))
@@ -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
@@ -102,7 +102,7 @@
to_chat(victim, "<span class='warning'>[H] tries to bite you, but stops before touching you!</span>")
to_chat(H, "<span class='warning'>[victim] is blessed! You stop just in time to avoid catching fire.</span>")
return
if(victim?.reagents?.has_reagent(/datum/reagent/consumable/garlic))
if(victim.has_reagent(/datum/reagent/consumable/garlic))
to_chat(victim, "<span class='warning'>[H] tries to bite you, but recoils in disgust!</span>")
to_chat(H, "<span class='warning'>[victim] reeks of garlic! you can't bring yourself to drain such tainted blood.</span>")
return
+48 -4
View File
@@ -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, "<span class='warning'>You feel a stabbing pain in your abdomen!</span>")
/**
* 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//
/////////////
@@ -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)
+36
View File
@@ -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()
@@ -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)