Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor rework to how toxic chemicals work #22504

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
coldmod = 0.75
heatmod = 1.5
pressuremod = 0.75 //Xenos are completely pressure immune, they're bargain bin xenos
toxmod = 0.8 //their blood is acid, their liver is pretty used to fucked up things
acidmod = 0.2 //Their blood is literally acid
action_speed_coefficient = 1.1 //claws aren't dextrous like hands
speedmod = -0.1 //apex predator humanoid hybrid
Expand Down
9 changes: 2 additions & 7 deletions code/modules/reagents/chemistry/reagents/toxin_reagents.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,10 @@
taste_description = "bitterness"
taste_mult = 1.2
evaporation_rate = 3 //6x faster than normal chems
/// Handled by the liver, does full damage for the highest toxpwr, and reduced for every following one
var/toxpwr = 1.5
var/silent_toxin = FALSE //won't produce a pain message when processed by liver/Life(seconds_per_tick = SSMOBS_DT, times_fired) if there isn't another non-silent toxin present.

/datum/reagent/toxin/on_mob_life(mob/living/carbon/M)
if(toxpwr)
M.adjustToxLoss(toxpwr*REM, 0)
. = TRUE
..()

/datum/reagent/toxin/amatoxin
name = "Amatoxin"
description = "A powerful poison derived from certain species of mushroom."
Expand Down Expand Up @@ -916,7 +911,7 @@
/datum/reagent/toxin/delayed/on_mob_life(mob/living/carbon/M)
if(current_cycle > delay)
holder.remove_reagent(type, actual_metaboliztion_rate * M.metabolism_efficiency)
M.adjustToxLoss(actual_toxpwr*REM, 0)
toxpwr = actual_toxpwr
if(prob(10))
M.Paralyze(20, 0)
. = 1
Expand Down
61 changes: 27 additions & 34 deletions code/modules/surgery/organs/liver.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#define LIVER_DEFAULT_TOX_TOLERANCE 3 //amount of toxins the liver can filter out
#define LIVER_DEFAULT_TOX_LETHALITY 0.01 //lower values lower how harmful toxins are to the liver
#define LIVER_DEFAULT_TOX_LETHALITY 1 //lower values lower how harmful toxins are to the liver

/obj/item/organ/liver
name = "liver"
Expand All @@ -12,38 +11,40 @@
maxHealth = STANDARD_ORGAN_THRESHOLD
healing_factor = STANDARD_ORGAN_HEALING
decay_factor = STANDARD_ORGAN_DECAY // smack in the middle of decay times
var/operated = FALSE //whether we can still have our damages fixed through surgery
var/alcohol_tolerance = ALCOHOL_RATE//affects how much damage the liver takes from alcohol
var/toxTolerance = LIVER_DEFAULT_TOX_TOLERANCE//maximum amount of toxins the liver can just shrug off
var/toxLethality = LIVER_DEFAULT_TOX_LETHALITY//affects how much damage toxins do to the liver
var/filterToxins = TRUE //whether to filter toxins

#define HAS_SILENT_TOXIN 0 //don't provide a feedback message if this is the only toxin present
#define HAS_NO_TOXIN 1
#define HAS_PAINFUL_TOXIN 2
/// whether we can still have our damages fixed through surgery
var/operated = FALSE
/// affects how much damage the liver takes from alcohol
var/alcohol_tolerance = ALCOHOL_RATE
/// modifier to toxpwr for liver and toxin damage taken
var/toxLethality = LIVER_DEFAULT_TOX_LETHALITY

/obj/item/organ/liver/on_life()
var/mob/living/carbon/C = owner
..() //perform general on_life()
if(istype(C))
if(!(organ_flags & ORGAN_FAILING))//can't process reagents with a failing liver

var/provide_pain_message = HAS_NO_TOXIN
if(filterToxins && !HAS_TRAIT(owner, TRAIT_TOXINLOVER))
//handle liver toxin filtration
for(var/datum/reagent/toxin/T in C.reagents.reagent_list)
var/thisamount = C.reagents.get_reagent_amount(T.type)
if (thisamount && thisamount <= toxTolerance)
C.reagents.remove_reagent(T.type, 1)
else
damage += (thisamount*toxLethality)
if(provide_pain_message != HAS_PAINFUL_TOXIN)
provide_pain_message = T.silent_toxin ? HAS_SILENT_TOXIN : HAS_PAINFUL_TOXIN
var/provide_pain_message = FALSE
var/damage_multiplier = 1 //reduced for every toxin
var/list/toxpwr = list()

for(var/datum/reagent/toxin/T in C.reagents.reagent_list)
toxpwr += T.toxpwr
provide_pain_message = provide_pain_message || !T.silent_toxin

sort_list(toxpwr, cmp = /proc/cmp_numeric_dsc) //sort all toxpowers scaling from highest to lowest

Copy link
Contributor

@SapphicOverload SapphicOverload Sep 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this should probably be cached on the liver and updated whenever a toxin is added or removed from the body so you don't have to sort the list every single tick.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

guh, i considered that but it sounds like a lot of work

for(var/dmg in toxpwr)
var/real_damage = dmg * toxLethality * damage_multiplier
damage_multiplier *= 0.5 //reduce the damage dealt for every subsequent toxin
C.adjustToxLoss(real_damage)
if(!HAS_TRAIT(owner, TRAIT_TOXINLOVER)) //don't hurt the liver if they like toxins
damage += (real_damage / 2)

//metabolize reagents
C.reagents.metabolize(C, can_overdose=TRUE)

if(provide_pain_message && damage > 10 && prob(damage/3))//the higher the damage the higher the probability
if(provide_pain_message && damage > 10 && !HAS_TRAIT(owner, TRAIT_TOXINLOVER) && prob(damage/3))//the higher the damage the higher the probability
to_chat(C, span_warning("You feel a dull pain in your abdomen."))
else //for when our liver's failing
C.reagents.end_metabolization(C, keep_liverless = TRUE) //Stops trait-based effects on reagents, to prevent permanent buffs
Expand All @@ -57,10 +58,6 @@
if(damage > maxHealth)//cap liver damage
damage = maxHealth

#undef HAS_SILENT_TOXIN
#undef HAS_NO_TOXIN
#undef HAS_PAINFUL_TOXIN

/obj/item/organ/liver/prepare_eat()
var/obj/S = ..()
S.reagents.add_reagent(/datum/reagent/iron, 5)
Expand All @@ -84,8 +81,7 @@
name = "alien liver" // doesnt matter for actual aliens because they dont take toxin damage
icon_state = "liver-x" // Same sprite as fly-person liver.
desc = "A liver that used to belong to a killer alien, who knows what it used to eat."
toxLethality = LIVER_DEFAULT_TOX_LETHALITY * 2.5 // rejects its owner early after too much punishment
toxTolerance = 15 // complete toxin immunity like xenos have would be too powerful
toxLethality = LIVER_DEFAULT_TOX_LETHALITY * 0.5

/obj/item/organ/liver/cybernetic
name = "cybernetic liver"
Expand All @@ -94,8 +90,7 @@
organ_flags = ORGAN_SYNTHETIC
alcohol_tolerance = 0.001
maxHealth = 2 * STANDARD_ORGAN_THRESHOLD
toxTolerance = 3.3
toxLethality = 0.009
toxLethality = LIVER_DEFAULT_TOX_LETHALITY * 0.9

/obj/item/organ/liver/cybernetic/upgraded
name = "upgraded cybernetic liver"
Expand All @@ -104,8 +99,7 @@
alcohol_tolerance = 0.0005
maxHealth = 3 * STANDARD_ORGAN_THRESHOLD //300% health of a normal liver
healing_factor = 2 * STANDARD_ORGAN_HEALING //Can regenerate from damage quicker
toxTolerance = 20
toxLethality = 0.007
toxLethality = LIVER_DEFAULT_TOX_LETHALITY * 0.7

/obj/item/organ/liver/cybernetic/upgraded/on_life()
. = ..()
Expand All @@ -125,7 +119,6 @@
attack_verb = list("processed")
desc = "A machine component, installed in the chest. This grants the machine the ability to process chemicals that enter its systems."
alcohol_tolerance = 0
toxTolerance = -1
toxLethality = 0
status = ORGAN_ROBOTIC
compatible_biotypes = ALL_BIOTYPES
Expand Down
Loading