SPECIES NUKING 2023: Mein leber! Allows livers to handle reagents in special ways, instead of the species datum doing it (#76184)

## About The Pull Request

Refactors livers so special chemical handling can be done by them,
instead of the species datum.
Plasmamen, skeletons and golems all use the liver for all their species
specific chem handling now.

## Why It's Good For The Game

SPECIES DATUM I HATE YOU!
Also, being able to handle reagents like any species if you have their
liver is REALLY FREAKING COOL and allows for emergent gameplay by mixing
various organs from various sources.

## Changelog

🆑
refactor: Mutant livers can now handle chemicals in special ways.
Currently, only plasmaman, skeleton and golem livers do it. Every other
species is the same.
/🆑

---------

Co-authored-by: Time-Green <7501474+Time-Green@users.noreply.github.com>
This commit is contained in:
ChungusGamer666
2023-06-24 21:05:29 +02:00
committed by GitHub
co-authored by Time-Green
parent 7be4ab14d4
commit 6da96bef84
48 changed files with 270 additions and 229 deletions
@@ -5,12 +5,12 @@
/obj/item/organ/internal/liver
name = "liver"
desc = "Pairing suggestion: chianti and fava beans."
icon_state = "liver"
visual = FALSE
w_class = WEIGHT_CLASS_SMALL
zone = BODY_ZONE_CHEST
slot = ORGAN_SLOT_LIVER
desc = "Pairing suggestion: chianti and fava beans."
maxHealth = STANDARD_ORGAN_THRESHOLD
healing_factor = STANDARD_ORGAN_HEALING
@@ -33,6 +33,7 @@
// If the liver handles foods like a clown, it honks like a bike horn
// Don't think about it too much.
RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_COMEDY_METABOLISM), PROC_REF(on_add_comedy_metabolism))
RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_COMEDY_METABOLISM), PROC_REF(on_remove_comedy_metabolism))
/* Signal handler for the liver gaining the TRAIT_COMEDY_METABOLISM trait
*
@@ -50,30 +51,59 @@
// Would that make the clown more or less likely to honk it
AddComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 50, falloff_exponent = 20)
/* Signal handler for the liver losing the TRAIT_COMEDY_METABOLISM trait
*
* Basically just removes squeak component
*/
/obj/item/organ/internal/liver/proc/on_remove_comedy_metabolism()
SIGNAL_HANDLER
qdel(GetComponent(/datum/component/squeak))
/// Registers COMSIG_MOB_REAGENT_CHECK from owner
/obj/item/organ/internal/liver/on_insert(mob/living/carbon/organ_owner, special)
. = ..()
RegisterSignal(organ_owner, COMSIG_SPECIES_HANDLE_CHEMICAL, PROC_REF(handle_chemical))
/// Unregisters COMSIG_MOB_REAGENT_CHECK from owner
/obj/item/organ/internal/liver/on_remove(mob/living/carbon/organ_owner, special)
. = ..()
UnregisterSignal(organ_owner, COMSIG_SPECIES_HANDLE_CHEMICAL)
/**
* This proc can be overriden by liver subtypes so they can handle certain chemicals in special ways.
* Return null to continue running the normal on_mob_life() for that reagent.
* Return COMSIG_MOB_STOP_REAGENT_CHECK to not run the normal metabolism effects.
*
* NOTE: If you return COMSIG_MOB_STOP_REAGENT_CHECK, that reagent will not be removed like normal! You must handle it manually.
**/
/obj/item/organ/internal/liver/proc/handle_chemical(mob/living/carbon/organ_owner, datum/reagent/chem, seconds_per_tick, times_fired)
SIGNAL_HANDLER
/obj/item/organ/internal/liver/examine(mob/user)
. = ..()
if(HAS_TRAIT(user, TRAIT_ENTRAILS_READER) || (user.mind && HAS_TRAIT(user.mind, TRAIT_ENTRAILS_READER)) || isobserver(user))
if(HAS_TRAIT(src, TRAIT_LAW_ENFORCEMENT_METABOLISM))
. += "Fatty deposits and sprinkle residue, imply that this is the liver of someone in <em>security</em>."
. += span_info("Fatty deposits and sprinkle residue, imply that this is the liver of someone in <em>security</em>.")
if(HAS_TRAIT(src, TRAIT_CULINARY_METABOLISM))
. += "The high iron content and slight smell of garlic, implies that this is the liver of a <em>cook</em>."
. += span_info("The high iron content and slight smell of garlic, implies that this is the liver of a <em>cook</em>.")
if(HAS_TRAIT(src, TRAIT_COMEDY_METABOLISM))
. += "A smell of bananas, a slippery sheen and [span_clown("honking")] when depressed, implies that this is the liver of a <em>clown</em>."
. += span_info("A smell of bananas, a slippery sheen and [span_clown("honking")] when depressed, implies that this is the liver of a <em>clown</em>.")
if(HAS_TRAIT(src, TRAIT_MEDICAL_METABOLISM))
. += "Marks of stress and a faint whiff of medicinal alcohol, imply that this is the liver of a <em>medical worker</em>."
. += span_info("Marks of stress and a faint whiff of medicinal alcohol, imply that this is the liver of a <em>medical worker</em>.")
if(HAS_TRAIT(src, TRAIT_ENGINEER_METABOLISM))
. += "Signs of radiation exposure and space adaption, implies that this is the liver of an <em>engineer</em>."
. += span_info("Signs of radiation exposure and space adaption, implies that this is the liver of an <em>engineer</em>.")
if(HAS_TRAIT(src, TRAIT_BALLMER_SCIENTIST))
. += "Strange glowing residues, sprinklings of congealed solid plasma, and what seem to be tumors indicate this is the radiated liver of a <em>scientist</em>."
. += span_info("Strange glowing residues, sprinklings of congealed solid plasma, and what seem to be tumors indicate this is the radiated liver of a <em>scientist</em>.")
if(HAS_TRAIT(src, TRAIT_MAINTENANCE_METABOLISM))
. += "A half-digested rat's tail (somehow), disgusting sludge, and the faint smell of Grey Bull imply this is what remains of an <em>assistant</em>'s liver."
. += span_info("A half-digested rat's tail (somehow), disgusting sludge, and the faint smell of Grey Bull imply this is what remains of an <em>assistant</em>'s liver.")
// royal trumps pretender royal
if(HAS_TRAIT(src, TRAIT_ROYAL_METABOLISM))
. += "A rich diet of luxury food, suppleness from soft beds, implies that this is the liver of a <em>head of staff</em>."
. += span_info("A rich diet of luxury food, suppleness from soft beds, implies that this is the liver of a <em>head of staff</em>.")
else if(HAS_TRAIT(src, TRAIT_PRETENDER_ROYAL_METABOLISM))
. += "A diet of imitation caviar, and signs of insomnia, implies that this is the liver of <em>someone who wants to be a head of staff</em>."
. += span_info("A diet of imitation caviar, and signs of insomnia, implies that this is the liver of <em>someone who wants to be a head of staff</em>.")
/obj/item/organ/internal/liver/before_organ_replacement(obj/item/organ/replacement)
. = ..()
@@ -95,13 +125,15 @@
#define HAS_PAINFUL_TOXIN 2
/obj/item/organ/internal/liver/on_life(seconds_per_tick, times_fired)
var/mob/living/carbon/liver_owner = owner
. = ..() //perform general on_life()
var/mob/living/carbon/liver_owner = owner
if(!istype(liver_owner))
return
if(organ_flags & ORGAN_FAILING || HAS_TRAIT(liver_owner, TRAIT_NOMETABOLISM)) //If your liver is failing or you lack a metabolism then we use the liverless version of metabolize
liver_owner.reagents.metabolize(liver_owner, seconds_per_tick, times_fired, can_overdose=TRUE, liverless=TRUE)
//If your liver is failing, then we use the liverless version of metabolize
//We don't check for TRAIT_NOMETABOLISM here because we do want a functional liver if somehow we have one inserted
if(organ_flags & ORGAN_FAILING)
liver_owner.reagents.metabolize(liver_owner, seconds_per_tick, times_fired, can_overdose = TRUE, liverless = TRUE)
return
var/obj/belly = liver_owner.get_organ_slot(ORGAN_SLOT_STOMACH)
@@ -123,7 +155,7 @@
if(provide_pain_message != HAS_PAINFUL_TOXIN)
provide_pain_message = toxin.silent_toxin ? HAS_SILENT_TOXIN : HAS_PAINFUL_TOXIN
liver_owner.reagents.metabolize(liver_owner, seconds_per_tick, times_fired, can_overdose=TRUE)
liver_owner.reagents.metabolize(liver_owner, seconds_per_tick, times_fired, can_overdose = TRUE)
if(liver_damage)
apply_organ_damage(min(liver_damage * seconds_per_tick , MAX_TOXIN_LIVER_DAMAGE * seconds_per_tick))
@@ -205,24 +237,18 @@
/obj/item/organ/internal/liver/get_availability(datum/species/owner_species, mob/living/owner_mob)
return owner_species.mutantliver
/obj/item/organ/internal/liver/plasmaman
name = "reagent processing crystal"
icon_state = "liver-p"
desc = "A large crystal that is somehow capable of metabolizing chemicals, these are found in plasmamen."
status = ORGAN_MINERAL
// alien livers can ignore up to 15u of toxins, but they take x3 liver damage
/obj/item/organ/internal/liver/alien
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."
icon_state = "liver-x" // Same sprite as fly-person liver.
liver_resistance = 0.333 * LIVER_DEFAULT_TOX_RESISTANCE // -66%
toxTolerance = 15 // complete toxin immunity like xenos have would be too powerful
/obj/item/organ/internal/liver/cybernetic
name = "basic cybernetic liver"
icon_state = "liver-c"
desc = "A very basic device designed to mimic the functions of a human liver. Handles toxins slightly worse than an organic liver."
icon_state = "liver-c"
organ_flags = ORGAN_SYNTHETIC
toxTolerance = 2
liver_resistance = 0.9 * LIVER_DEFAULT_TOX_RESISTANCE // -10%
@@ -231,8 +257,8 @@
/obj/item/organ/internal/liver/cybernetic/tier2
name = "cybernetic liver"
icon_state = "liver-c-u"
desc = "An electronic device designed to mimic the functions of a human liver. Handles toxins slightly better than an organic liver."
icon_state = "liver-c-u"
maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD
toxTolerance = 5 //can shrug off up to 5u of toxins
liver_resistance = 1.2 * LIVER_DEFAULT_TOX_RESISTANCE // +20%
@@ -240,8 +266,8 @@
/obj/item/organ/internal/liver/cybernetic/tier3
name = "upgraded cybernetic liver"
icon_state = "liver-c-u2"
desc = "An upgraded version of the cybernetic liver, designed to improve further upon organic livers. It is resistant to alcohol poisoning and is very robust at filtering toxins."
icon_state = "liver-c-u2"
alcohol_tolerance = 0.001
maxHealth = 2 * STANDARD_ORGAN_THRESHOLD
toxTolerance = 10 //can shrug off up to 10u of toxins
@@ -0,0 +1,24 @@
/**
* Golem liver
* Basically only exists to remove the nutriment factor from consumables,
* so golems can only consume minerals even when injecting reagents.
*
* Actually consuming golem food is handled by /obj/item/organ/internal/stomach/golem!
**/
/obj/item/organ/internal/liver/golem
name = "porous rock"
desc = "A spongy rock capable of absorbing chemicals."
icon_state = "liver-p"
status = ORGAN_MINERAL
color = COLOR_GOLEM_GRAY
/obj/item/organ/internal/liver/golem/handle_chemical(mob/living/carbon/organ_owner, datum/reagent/chem, seconds_per_tick, times_fired)
. = ..()
// parent returned COMSIG_MOB_STOP_REAGENT_CHECK or we are failing
if(. || (organ_flags & ORGAN_FAILING))
return
// golems can only eat minerals
if(istype(chem, /datum/reagent/consumable) && !istype(chem, /datum/reagent/consumable/nutriment/mineral))
var/datum/reagent/consumable/yummy_chem = chem
yummy_chem.nutriment_factor = 0
return // Do normal metabolism
@@ -0,0 +1,25 @@
/**
* Plasmaman liver
* Makes plasma and hot ice heal wounds, also makes gunpowder a hallucinogen.
**/
/obj/item/organ/internal/liver/bone/plasmaman
name = "reagent processing crystal"
desc = "A large crystal that is somehow capable of metabolizing chemicals, these are found in plasmamen."
icon_state = "liver-p"
status = ORGAN_MINERAL
/obj/item/organ/internal/liver/bone/plasmaman/handle_chemical(mob/living/carbon/organ_owner, datum/reagent/chem, seconds_per_tick, times_fired)
. = ..()
//parent returned COMSIG_MOB_STOP_REAGENT_CHECK or we are failing
if(. || (organ_flags & ORGAN_FAILING))
return
// plasmamen use plasma to reform their bones or whatever
if(istype(chem, /datum/reagent/toxin/plasma) || istype(chem, /datum/reagent/toxin/hot_ice))
for(var/datum/wound/iter_wound as anything in organ_owner.all_wounds)
iter_wound.on_xadone(4 * REM * seconds_per_tick)
return // Do normal metabolism
if(istype(chem, /datum/reagent/gunpowder))
organ_owner.set_timed_status_effect(15 SECONDS * seconds_per_tick, /datum/status_effect/drugginess)
if(organ_owner.get_timed_status_effect_duration(/datum/status_effect/hallucination) / 10 < chem.volume)
organ_owner.adjust_hallucinations(2.5 SECONDS * seconds_per_tick)
return // Do normal metabolism
@@ -0,0 +1,49 @@
/**
* Bone liver
* Gives the owner liverless metabolism, makes them vulnerable to bone hurting juice and
* makes milk heal them through meme magic.
**/
/obj/item/organ/internal/liver/bone
name = "mass of bones"
desc = "You have no idea what this strange ball of bones does."
icon_state = "liver-bone"
organ_traits = list(TRAIT_NOMETABOLISM)
/obj/item/organ/internal/liver/bone/handle_chemical(mob/living/carbon/organ_owner, datum/reagent/chem, seconds_per_tick, times_fired)
. = ..()
//parent returned COMSIG_MOB_STOP_REAGENT_CHECK or we are failing
if(. || (organ_flags & ORGAN_FAILING))
return
if(istype(chem, /datum/reagent/toxin/bonehurtingjuice))
organ_owner.adjustStaminaLoss(7.5 * REM * seconds_per_tick, 0)
organ_owner.adjustBruteLoss(0.5 * REM * seconds_per_tick, 0)
if(SPT_PROB(10, seconds_per_tick))
switch(rand(1, 3))
if(1)
INVOKE_ASYNC(organ_owner, TYPE_PROC_REF(/atom/movable, say), pick("oof.", "ouch.", "my bones.", "oof ouch.", "oof ouch my bones."), forced = chem.type)
if(2)
organ_owner.manual_emote(pick("oofs silently.", "looks like [organ_owner.p_their()] bones hurt.", "grimaces, as though [organ_owner.p_their()] bones hurt."))
if(3)
to_chat(organ_owner, span_warning("Your bones hurt!"))
if(chem.overdosed)
if(SPT_PROB(2, seconds_per_tick)) //big oof
var/selected_part = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) //God help you if the same limb gets picked twice quickly...
var/obj/item/bodypart/bodypart = organ_owner.get_bodypart(selected_part) //We're so sorry skeletons, you're so misunderstood
if(bodypart)
playsound(organ_owner, SFX_DESECRATION, 50, vary = TRUE) //You just want to socialize
organ_owner.visible_message(span_warning("[organ_owner] rattles loudly and flails around!!"), span_danger("Your bones hurt so much that your missing muscles spasm!!"))
INVOKE_ASYNC(organ_owner, TYPE_PROC_REF(/atom/movable, say), "OOF!!", forced = chem.type)
bodypart.receive_damage(brute = 200) //But I don't think we should
else
to_chat(organ_owner, span_warning("Your missing [parse_zone(selected_part)] aches from wherever you left it."))
INVOKE_ASYNC(organ_owner, TYPE_PROC_REF(/mob, emote), "sigh")
organ_owner.reagents.remove_reagent(chem.type, chem.metabolization_rate * seconds_per_tick)
return COMSIG_MOB_STOP_REAGENT_CHECK // Stop metabolism
if(chem.type == /datum/reagent/consumable/milk)
if(chem.volume > 50)
organ_owner.reagents.remove_reagent(chem.type, (chem.volume - 50))
to_chat(organ_owner, span_warning("The excess milk is dripping off your bones!"))
organ_owner.heal_bodypart_damage(2.5 * REM * seconds_per_tick)
for(var/datum/wound/iter_wound as anything in organ_owner.all_wounds)
iter_wound.on_xadone(1 * REM * seconds_per_tick)
return // Do normal metabolism
@@ -3,6 +3,7 @@
/obj/item/organ/internal/stomach
name = "stomach"
desc = "Onaka ga suite imasu."
icon_state = "stomach"
visual = FALSE
w_class = WEIGHT_CLASS_SMALL
@@ -10,7 +11,6 @@
slot = ORGAN_SLOT_STOMACH
attack_verb_continuous = list("gores", "squishes", "slaps", "digests")
attack_verb_simple = list("gore", "squish", "slap", "digest")
desc = "Onaka ga suite imasu."
healing_factor = STANDARD_ORGAN_HEALING
decay_factor = STANDARD_ORGAN_DECAY * 1.15 // ~13 minutes, the stomach is one of the first organs to die
@@ -268,21 +268,23 @@
return ..()
/obj/item/organ/internal/stomach/bone
name = "mass of bones"
desc = "You have no idea what this strange ball of bones does."
icon_state = "stomach-bone"
metabolism_efficiency = 0.025 //very bad
organ_traits = list(TRAIT_NOHUNGER)
/obj/item/organ/internal/stomach/bone/plasmaman
name = "digestive crystal"
icon_state = "stomach-p"
organ_traits = list()
desc = "A strange crystal that is responsible for metabolizing the unseen energy force that feeds plasmamen."
icon_state = "stomach-p"
metabolism_efficiency = 0.06
organ_traits = null
/obj/item/organ/internal/stomach/cybernetic
name = "basic cybernetic stomach"
icon_state = "stomach-c"
desc = "A basic device designed to mimic the functions of a human stomach"
icon_state = "stomach-c"
organ_flags = ORGAN_SYNTHETIC
maxHealth = STANDARD_ORGAN_THRESHOLD * 0.5
var/emp_vulnerability = 80 //Chance of permanent effects if emp-ed.
@@ -290,8 +292,8 @@
/obj/item/organ/internal/stomach/cybernetic/tier2
name = "cybernetic stomach"
icon_state = "stomach-c-u"
desc = "An electronic device designed to mimic the functions of a human stomach. Handles disgusting food a bit better."
icon_state = "stomach-c-u"
maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD
disgust_metabolism = 2
emp_vulnerability = 40
@@ -299,8 +301,8 @@
/obj/item/organ/internal/stomach/cybernetic/tier3
name = "upgraded cybernetic stomach"
icon_state = "stomach-c-u2"
desc = "An upgraded version of the cybernetic stomach, designed to improve further upon organic stomachs. Handles disgusting food very well."
icon_state = "stomach-c-u2"
maxHealth = 2 * STANDARD_ORGAN_THRESHOLD
disgust_metabolism = 3
emp_vulnerability = 20
@@ -17,10 +17,7 @@
RegisterSignal(owner, COMSIG_CARBON_ATTEMPT_EAT, PROC_REF(try_eating))
if(!ishuman(organ_owner))
return
setup_physiology(organ_owner)
/// Physiology doesn't exist yet if this is added on initialisation of a golem, so we need to wait until it does
/obj/item/organ/internal/stomach/golem/proc/setup_physiology(mob/living/carbon/human/human_owner)
var/mob/living/carbon/human/human_owner = organ_owner
human_owner.physiology?.hunger_mod *= hunger_mod
/obj/item/organ/internal/stomach/golem/on_remove(mob/living/carbon/organ_owner, special)
@@ -51,9 +48,10 @@
/// Slow down based on how full you are
/obj/item/organ/internal/stomach/golem/handle_hunger(mob/living/carbon/human/human, delta_time, times_fired)
// the effects are all negative, so just don't run them if you have the trait
. = ..()
if(HAS_TRAIT(human, TRAIT_NOHUNGER))
return
. = ..()
var/hunger = (NUTRITION_LEVEL_HUNGRY - human.nutrition) / NUTRITION_LEVEL_HUNGRY // starving = 1, satisfied = 0
if(hunger > 0)
var/slowdown = LERP(min_hunger_slowdown, max_hunger_slowdown, hunger)