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 16:05:29 -03:00
committed by GitHub
parent 7be4ab14d4
commit 6da96bef84
48 changed files with 270 additions and 229 deletions

View File

@@ -9,6 +9,10 @@
#define COMSIG_MOB_LOGOUT "mob_logout" #define COMSIG_MOB_LOGOUT "mob_logout"
///from base of mob/set_stat(): (new_stat, old_stat) ///from base of mob/set_stat(): (new_stat, old_stat)
#define COMSIG_MOB_STATCHANGE "mob_statchange" #define COMSIG_MOB_STATCHANGE "mob_statchange"
///from base of mob/reagent_check(): (datum/reagent/chem, seconds_per_tick, times_fired)
#define COMSIG_MOB_REAGENT_CHECK "mob_reagent_check"
///stops the reagent check call
#define COMSIG_MOB_STOP_REAGENT_CHECK (1<<0)
///from base of mob/clickon(): (atom/A, params) ///from base of mob/clickon(): (atom/A, params)
#define COMSIG_MOB_CLICKON "mob_clickon" #define COMSIG_MOB_CLICKON "mob_clickon"
///from base of mob/MiddleClickOn(): (atom/A) ///from base of mob/MiddleClickOn(): (atom/A)

View File

@@ -3,3 +3,6 @@
#define COMSIG_SPECIES_GAIN "species_gain" #define COMSIG_SPECIES_GAIN "species_gain"
///from datum/species/on_species_loss(): (datum/species/lost_species) ///from datum/species/on_species_loss(): (datum/species/lost_species)
#define COMSIG_SPECIES_LOSS "species_loss" #define COMSIG_SPECIES_LOSS "species_loss"
///from datum/species/handle_chemical(): (datum/reagent/chem, mob/living/carbon/human/affected, seconds_per_tick, times_fired)
#define COMSIG_SPECIES_HANDLE_CHEMICAL "species_handle_chemicals"
// same return values as COMSIG_MOB_STOP_REAGENT_CHECK

View File

@@ -43,7 +43,7 @@
source.balloon_alert(user, "not edible!") source.balloon_alert(user, "not edible!")
return COMPONENT_CANCEL_ATTACK_CHAIN return COMPONENT_CANCEL_ATTACK_CHAIN
if (!snack_type.can_consume(target)) if (!snack_type.can_consume(target))
source.balloon_alert(user, "incompatible mineral!") source.balloon_alert(user, "can't consume!")
return COMPONENT_CANCEL_ATTACK_CHAIN return COMPONENT_CANCEL_ATTACK_CHAIN
if (!golem_snack) if (!golem_snack)
golem_snack = new( golem_snack = new(

View File

@@ -1,5 +1,4 @@
/datum/mutation /datum/mutation
var/name var/name
/datum/mutation/human /datum/mutation/human

View File

@@ -66,9 +66,6 @@
else else
clear_alert(ALERT_XENO_FIRE) clear_alert(ALERT_XENO_FIRE)
/mob/living/carbon/alien/reagent_check(datum/reagent/R, seconds_per_tick, times_fired) //can metabolize all reagents
return FALSE
/mob/living/carbon/alien/getTrail() /mob/living/carbon/alien/getTrail()
if(getBruteLoss() < 200) if(getBruteLoss() < 200)
return pick (list("xltrails_1", "xltrails2")) return pick (list("xltrails_1", "xltrails2"))

View File

@@ -830,7 +830,10 @@ GLOBAL_LIST_EMPTY(features_by_species)
return return
/datum/species/proc/spec_life(mob/living/carbon/human/H, seconds_per_tick, times_fired) /datum/species/proc/spec_life(mob/living/carbon/human/H, seconds_per_tick, times_fired)
if(HAS_TRAIT(H, TRAIT_NOBREATH) && H.stat != DEAD && (H.health < H.crit_threshold) && !HAS_TRAIT(H, TRAIT_NOCRITDAMAGE)) SHOULD_CALL_PARENT(TRUE)
if(H.stat == DEAD)
return
if(HAS_TRAIT(H, TRAIT_NOBREATH) && (H.health < H.crit_threshold) && !HAS_TRAIT(H, TRAIT_NOCRITDAMAGE))
H.adjustBruteLoss(0.5 * seconds_per_tick) H.adjustBruteLoss(0.5 * seconds_per_tick)
/datum/species/proc/spec_death(gibbed, mob/living/carbon/human/H) /datum/species/proc/spec_death(gibbed, mob/living/carbon/human/H)
@@ -998,22 +1001,24 @@ GLOBAL_LIST_EMPTY(features_by_species)
return return
/** /**
* Handling special reagent types. * Handling special reagent interactions.
* *
* Return False to run the normal on_mob_life() for that reagent. * Return null continue running the normal on_mob_life() for that reagent.
* Return True to not run the normal metabolism effects. * Return COMSIG_MOB_STOP_REAGENT_CHECK to not run the normal metabolism effects.
* NOTE: If you return TRUE, that reagent will not be removed liike normal! You must handle it manually. *
*/ * NOTE: If you return COMSIG_MOB_STOP_REAGENT_CHECK, that reagent will not be removed liike normal! You must handle it manually.
/datum/species/proc/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H, seconds_per_tick, times_fired) **/
/datum/species/proc/handle_chemical(datum/reagent/chem, mob/living/carbon/human/affected, seconds_per_tick, times_fired)
SHOULD_CALL_PARENT(TRUE) SHOULD_CALL_PARENT(TRUE)
if(chem.type == exotic_blood) if(chem.type == exotic_blood)
H.blood_volume = min(H.blood_volume + round(chem.volume, 0.1), BLOOD_VOLUME_MAXIMUM) affected.blood_volume = min(affected.blood_volume + round(chem.volume, 0.1), BLOOD_VOLUME_MAXIMUM)
H.reagents.del_reagent(chem.type) affected.reagents.del_reagent(chem.type)
return TRUE return COMSIG_MOB_STOP_REAGENT_CHECK
if(!chem.overdosed && chem.overdose_threshold && chem.volume >= chem.overdose_threshold) if(!chem.overdosed && chem.overdose_threshold && chem.volume >= chem.overdose_threshold)
chem.overdosed = TRUE chem.overdosed = TRUE
chem.overdose_start(H) chem.overdose_start(affected)
H.log_message("has started overdosing on [chem.name] at [chem.volume] units.", LOG_GAME) affected.log_message("has started overdosing on [chem.name] at [chem.volume] units.", LOG_GAME)
return SEND_SIGNAL(affected, COMSIG_SPECIES_HANDLE_CHEMICAL, chem, affected, seconds_per_tick, times_fired)
/datum/species/proc/check_species_weakness(obj/item, mob/living/attacker) /datum/species/proc/check_species_weakness(obj/item, mob/living/attacker)
return 1 //This is not a boolean, it's the multiplier for the damage that the user takes from the item. The force of the item is multiplied by this value return 1 //This is not a boolean, it's the multiplier for the damage that the user takes from the item. The force of the item is multiplied by this value

View File

@@ -921,6 +921,12 @@
return ..() return ..()
/mob/living/carbon/human/reagent_check(datum/reagent/chem, seconds_per_tick, times_fired)
. = ..()
if(. & COMSIG_MOB_STOP_REAGENT_CHECK)
return
return dna.species.handle_chemical(chem, src, seconds_per_tick, times_fired)
/mob/living/carbon/human/updatehealth() /mob/living/carbon/human/updatehealth()
. = ..() . = ..()
dna?.species.spec_updatehealth(src) dna?.species.spec_updatehealth(src)

View File

@@ -110,10 +110,6 @@
//Check inventory slots //Check inventory slots
return (wear_id?.GetID() || belt?.GetID()) return (wear_id?.GetID() || belt?.GetID())
/mob/living/carbon/human/reagent_check(datum/reagent/R, seconds_per_tick, times_fired)
return dna.species.handle_chemicals(R, src, seconds_per_tick, times_fired)
// if it returns 0, it will run the usual on_mob_life for that reagent. otherwise, it will stop after running handle_chemicals for the species.
/mob/living/carbon/human/can_use_guns(obj/item/G) /mob/living/carbon/human/can_use_guns(obj/item/G)
. = ..() . = ..()
if(G.trigger_guard == TRIGGER_GUARD_NORMAL) if(G.trigger_guard == TRIGGER_GUARD_NORMAL)

View File

@@ -28,22 +28,20 @@
//Body temperature stability and damage //Body temperature stability and damage
dna.species.handle_body_temperature(src, seconds_per_tick, times_fired) dna.species.handle_body_temperature(src, seconds_per_tick, times_fired)
if(!IS_IN_STASIS(src)) if(!IS_IN_STASIS(src))
if(.) //not dead
for(var/datum/mutation/human/HM in dna.mutations) // Handle active genes
HM.on_life(seconds_per_tick, times_fired)
if(stat != DEAD) if(stat != DEAD)
//handle active mutations
for(var/datum/mutation/human/human_mutation as anything in dna.mutations)
human_mutation.on_life(seconds_per_tick, times_fired)
//heart attack stuff //heart attack stuff
handle_heart(seconds_per_tick, times_fired) handle_heart(seconds_per_tick, times_fired)
//handles liver failure effects, if we lack a liver
handle_liver(seconds_per_tick, times_fired) handle_liver(seconds_per_tick, times_fired)
dna.species.spec_life(src, seconds_per_tick, times_fired) // for mutantraces // for special species interactions
dna.species.spec_life(src, seconds_per_tick, times_fired)
else else
for(var/i in all_wounds) for(var/datum/wound/iter_wound as anything in all_wounds)
var/datum/wound/iter_wound = i
iter_wound.on_stasis(seconds_per_tick, times_fired) iter_wound.on_stasis(seconds_per_tick, times_fired)
//Update our name based on whether our face is obscured/disfigured //Update our name based on whether our face is obscured/disfigured

View File

@@ -71,6 +71,7 @@
human.reset_perspective(human) human.reset_perspective(human)
/datum/species/dullahan/spec_life(mob/living/carbon/human/human, seconds_per_tick, times_fired) /datum/species/dullahan/spec_life(mob/living/carbon/human/human, seconds_per_tick, times_fired)
. = ..()
if(QDELETED(my_head)) if(QDELETED(my_head))
my_head = null my_head = null
human.investigate_log("has been gibbed by the loss of [human.p_their()] head.", INVESTIGATE_DEATHS) human.investigate_log("has been gibbed by the loss of [human.p_their()] head.", INVESTIGATE_DEATHS)

View File

@@ -22,13 +22,14 @@
examine_limb_id = SPECIES_HUMAN examine_limb_id = SPECIES_HUMAN
// Prevents felinids from taking toxin damage from carpotoxin // Prevents felinids from taking toxin damage from carpotoxin
/datum/species/human/felinid/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H, seconds_per_tick, times_fired) /datum/species/human/felinid/handle_chemical(datum/reagent/chem, mob/living/carbon/human/affected, seconds_per_tick, times_fired)
. = ..() . = ..()
if(. & COMSIG_MOB_STOP_REAGENT_CHECK)
return
if(istype(chem, /datum/reagent/toxin/carpotoxin)) if(istype(chem, /datum/reagent/toxin/carpotoxin))
var/datum/reagent/toxin/carpotoxin/fish = chem var/datum/reagent/toxin/carpotoxin/fish = chem
fish.toxpwr = 0 fish.toxpwr = 0
/datum/species/human/felinid/on_species_gain(mob/living/carbon/carbon_being, datum/species/old_species, pref_load) /datum/species/human/felinid/on_species_gain(mob/living/carbon/carbon_being, datum/species/old_species, pref_load)
if(ishuman(carbon_being)) if(ishuman(carbon_being))
var/mob/living/carbon/human/target_human = carbon_being var/mob/living/carbon/human/target_human = carbon_being

View File

@@ -35,12 +35,12 @@
BODY_ZONE_CHEST = /obj/item/bodypart/chest/fly, BODY_ZONE_CHEST = /obj/item/bodypart/chest/fly,
) )
/datum/species/fly/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H, seconds_per_tick, times_fired) /datum/species/fly/handle_chemical(datum/reagent/chem, mob/living/carbon/human/affected, seconds_per_tick, times_fired)
. = ..()
if(. & COMSIG_MOB_STOP_REAGENT_CHECK)
return
if(chem.type == /datum/reagent/toxin/pestkiller) if(chem.type == /datum/reagent/toxin/pestkiller)
H.adjustToxLoss(3 * REM * seconds_per_tick) affected.adjustToxLoss(3 * REM * seconds_per_tick)
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM * seconds_per_tick)
return TRUE
return ..()
/datum/species/fly/check_species_weakness(obj/item/weapon, mob/living/attacker) /datum/species/fly/check_species_weakness(obj/item/weapon, mob/living/attacker)
if(istype(weapon, /obj/item/melee/flyswatter)) if(istype(weapon, /obj/item/melee/flyswatter))

View File

@@ -39,6 +39,7 @@
mutantbrain = /obj/item/organ/internal/brain/golem mutantbrain = /obj/item/organ/internal/brain/golem
mutanttongue = /obj/item/organ/internal/tongue/golem mutanttongue = /obj/item/organ/internal/tongue/golem
mutantstomach = /obj/item/organ/internal/stomach/golem mutantstomach = /obj/item/organ/internal/stomach/golem
mutantliver = /obj/item/organ/internal/liver/golem
mutantappendix = /obj/item/organ/internal/appendix/golem mutantappendix = /obj/item/organ/internal/appendix/golem
bodypart_overrides = list( bodypart_overrides = list(
BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left/golem, BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left/golem,
@@ -94,10 +95,3 @@
)) ))
return to_add return to_add
/// Remove nutrient value from non-mineral food, wish this was on an organ and not species but such is life
/datum/species/golem/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H, delta_time, times_fired)
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 ..()

View File

@@ -67,6 +67,7 @@
return ..() return ..()
/datum/species/jelly/spec_life(mob/living/carbon/human/H, seconds_per_tick, times_fired) /datum/species/jelly/spec_life(mob/living/carbon/human/H, seconds_per_tick, times_fired)
. = ..()
if(H.stat == DEAD) //can't farm slime jelly from a dead slime/jelly person indefinitely if(H.stat == DEAD) //can't farm slime jelly from a dead slime/jelly person indefinitely
return return
@@ -240,6 +241,7 @@
bodies = old_species.bodies bodies = old_species.bodies
/datum/species/jelly/slime/spec_life(mob/living/carbon/human/H, seconds_per_tick, times_fired) /datum/species/jelly/slime/spec_life(mob/living/carbon/human/H, seconds_per_tick, times_fired)
. = ..()
if(H.blood_volume >= BLOOD_VOLUME_SLIME_SPLIT) if(H.blood_volume >= BLOOD_VOLUME_SLIME_SPLIT)
if(SPT_PROB(2.5, seconds_per_tick)) if(SPT_PROB(2.5, seconds_per_tick))
to_chat(H, span_notice("You feel very bloated!")) to_chat(H, span_notice("You feel very bloated!"))
@@ -249,8 +251,6 @@
if(H.blood_volume <= BLOOD_VOLUME_LOSE_NUTRITION) if(H.blood_volume <= BLOOD_VOLUME_LOSE_NUTRITION)
H.adjust_nutrition(-1.25 * seconds_per_tick) H.adjust_nutrition(-1.25 * seconds_per_tick)
..()
/datum/action/innate/split_body /datum/action/innate/split_body
name = "Split Body" name = "Split Body"
check_flags = AB_CHECK_CONSCIOUS check_flags = AB_CHECK_CONSCIOUS

View File

@@ -51,11 +51,12 @@
return randname return randname
/datum/species/moth/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H, seconds_per_tick, times_fired) /datum/species/moth/handle_chemical(datum/reagent/chem, mob/living/carbon/human/affected, seconds_per_tick, times_fired)
. = ..() . = ..()
if(. & COMSIG_MOB_STOP_REAGENT_CHECK)
return
if(chem.type == /datum/reagent/toxin/pestkiller) if(chem.type == /datum/reagent/toxin/pestkiller)
H.adjustToxLoss(3 * REM * seconds_per_tick) affected.adjustToxLoss(3 * REM * seconds_per_tick)
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM * seconds_per_tick)
/datum/species/moth/check_species_weakness(obj/item/weapon, mob/living/attacker) /datum/species/moth/check_species_weakness(obj/item/weapon, mob/living/attacker)
if(istype(weapon, /obj/item/melee/flyswatter)) if(istype(weapon, /obj/item/melee/flyswatter))

View File

@@ -57,13 +57,13 @@
mush.remove(C) mush.remove(C)
QDEL_NULL(mush) QDEL_NULL(mush)
/datum/species/mush/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H, seconds_per_tick, times_fired) /datum/species/mush/handle_chemical(datum/reagent/chem, mob/living/carbon/human/affected, seconds_per_tick, times_fired)
. = ..()
if(. & COMSIG_MOB_STOP_REAGENT_CHECK)
return
if(chem.type == /datum/reagent/toxin/plantbgone/weedkiller) if(chem.type == /datum/reagent/toxin/plantbgone/weedkiller)
H.adjustToxLoss(3 * REM * seconds_per_tick) affected.adjustToxLoss(3 * REM * seconds_per_tick)
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM * seconds_per_tick)
return TRUE
return ..()
/datum/species/mush/handle_mutant_bodyparts(mob/living/carbon/human/H, forced_colour) /datum/species/mush/handle_mutant_bodyparts(mob/living/carbon/human/H, forced_colour)
forced_colour = FALSE forced_colour = FALSE
..() return ..()

View File

@@ -20,7 +20,7 @@
inherent_respiration_type = RESPIRATION_PLASMA inherent_respiration_type = RESPIRATION_PLASMA
mutantlungs = /obj/item/organ/internal/lungs/plasmaman mutantlungs = /obj/item/organ/internal/lungs/plasmaman
mutanttongue = /obj/item/organ/internal/tongue/bone/plasmaman mutanttongue = /obj/item/organ/internal/tongue/bone/plasmaman
mutantliver = /obj/item/organ/internal/liver/plasmaman mutantliver = /obj/item/organ/internal/liver/bone/plasmaman
mutantstomach = /obj/item/organ/internal/stomach/bone/plasmaman mutantstomach = /obj/item/organ/internal/stomach/bone/plasmaman
mutantappendix = null mutantappendix = null
mutantheart = null mutantheart = null
@@ -62,6 +62,7 @@
C.set_safe_hunger_level() C.set_safe_hunger_level()
/datum/species/plasmaman/spec_life(mob/living/carbon/human/H, seconds_per_tick, times_fired) /datum/species/plasmaman/spec_life(mob/living/carbon/human/H, seconds_per_tick, times_fired)
. = ..()
var/atmos_sealed = TRUE var/atmos_sealed = TRUE
if(HAS_TRAIT(H, TRAIT_NOFIRE)) if(HAS_TRAIT(H, TRAIT_NOFIRE))
atmos_sealed = FALSE atmos_sealed = FALSE
@@ -133,57 +134,6 @@
return randname return randname
/datum/species/plasmaman/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H, seconds_per_tick, times_fired)
. = ..()
if(istype(chem, /datum/reagent/toxin/plasma) || istype(chem, /datum/reagent/toxin/hot_ice))
for(var/i in H.all_wounds)
var/datum/wound/iter_wound = i
iter_wound.on_xadone(4 * REM * seconds_per_tick) // plasmamen use plasma to reform their bones or whatever
return FALSE // do normal metabolism
if(istype(chem, /datum/reagent/toxin/bonehurtingjuice))
H.adjustStaminaLoss(7.5 * REM * seconds_per_tick, 0)
H.adjustBruteLoss(0.5 * REM * seconds_per_tick, 0)
if(SPT_PROB(10, seconds_per_tick))
switch(rand(1, 3))
if(1)
H.say(pick("oof.", "ouch.", "my bones.", "oof ouch.", "oof ouch my bones."), forced = /datum/reagent/toxin/bonehurtingjuice)
if(2)
H.manual_emote(pick("oofs silently.", "looks like [H.p_their()] bones hurt.", "grimaces, as though [H.p_their()] bones hurt."))
if(3)
to_chat(H, span_warning("Your bones hurt!"))
if(chem.overdosed)
if(SPT_PROB(2, seconds_per_tick) && iscarbon(H)) //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/bp = H.get_bodypart(selected_part) //We're so sorry skeletons, you're so misunderstood
if(bp)
playsound(H, get_sfx(SFX_DESECRATION), 50, TRUE, -1) //You just want to socialize
H.visible_message(span_warning("[H] rattles loudly and flails around!!"), span_danger("Your bones hurt so much that your missing muscles spasm!!"))
H.say("OOF!!", forced=/datum/reagent/toxin/bonehurtingjuice)
bp.receive_damage(200, 0, 0) //But I don't think we should
else
to_chat(H, span_warning("Your missing arm aches from wherever you left it."))
H.emote("sigh")
H.reagents.remove_reagent(chem.type, chem.metabolization_rate * seconds_per_tick)
return TRUE
if(istype(chem, /datum/reagent/gunpowder))
H.set_timed_status_effect(15 SECONDS * seconds_per_tick, /datum/status_effect/drugginess)
if(H.get_timed_status_effect_duration(/datum/status_effect/hallucination) / 10 < chem.volume)
H.adjust_hallucinations(2.5 SECONDS * seconds_per_tick)
// Do normal metabolism
return FALSE
if(chem.type == /datum/reagent/consumable/milk)
if(chem.volume > 50)
H.reagents.remove_reagent(chem.type, chem.volume - 5)
to_chat(H, span_warning("The excess milk is dripping off your bones!"))
H.heal_bodypart_damage(2.5 * REM * seconds_per_tick)
for(var/datum/wound/iter_wound as anything in H.all_wounds)
iter_wound.on_xadone(1 * REM * seconds_per_tick)
H.reagents.remove_reagent(chem.type, chem.metabolization_rate * seconds_per_tick)
return FALSE
/datum/species/plasmaman/get_scream_sound(mob/living/carbon/human) /datum/species/plasmaman/get_scream_sound(mob/living/carbon/human)
return pick( return pick(
'sound/voice/plasmaman/plasmeme_scream_1.ogg', 'sound/voice/plasmaman/plasmeme_scream_1.ogg',

View File

@@ -48,6 +48,7 @@
return ..() return ..()
/datum/species/pod/spec_life(mob/living/carbon/human/H, seconds_per_tick, times_fired) /datum/species/pod/spec_life(mob/living/carbon/human/H, seconds_per_tick, times_fired)
. = ..()
if(H.stat == DEAD) if(H.stat == DEAD)
return return
@@ -66,14 +67,13 @@
if(H.nutrition < NUTRITION_LEVEL_STARVING + 50) if(H.nutrition < NUTRITION_LEVEL_STARVING + 50)
H.take_overall_damage(brute = 1 * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC) H.take_overall_damage(brute = 1 * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC)
..()
/datum/species/pod/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H, seconds_per_tick, times_fired) /datum/species/pod/handle_chemical(datum/reagent/chem, mob/living/carbon/human/affected, seconds_per_tick, times_fired)
. = ..()
if(. & COMSIG_MOB_STOP_REAGENT_CHECK)
return
if(chem.type == /datum/reagent/toxin/plantbgone) if(chem.type == /datum/reagent/toxin/plantbgone)
H.adjustToxLoss(3 * REM * seconds_per_tick) affected.adjustToxLoss(3 * REM * seconds_per_tick)
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM * seconds_per_tick)
return TRUE
return ..()
/datum/species/pod/create_pref_unique_perks() /datum/species/pod/create_pref_unique_perks()
var/list/to_add = list() var/list/to_add = list()

View File

@@ -17,7 +17,6 @@
TRAIT_LIMBATTACHMENT, TRAIT_LIMBATTACHMENT,
TRAIT_NOBREATH, TRAIT_NOBREATH,
TRAIT_NOCLONELOSS, TRAIT_NOCLONELOSS,
TRAIT_NOMETABOLISM,
TRAIT_RADIMMUNE, TRAIT_RADIMMUNE,
TRAIT_PIERCEIMMUNE, TRAIT_PIERCEIMMUNE,
TRAIT_RESISTCOLD, TRAIT_RESISTCOLD,
@@ -33,7 +32,7 @@
mutantstomach = /obj/item/organ/internal/stomach/bone mutantstomach = /obj/item/organ/internal/stomach/bone
mutantappendix = null mutantappendix = null
mutantheart = null mutantheart = null
mutantliver = null mutantliver = /obj/item/organ/internal/liver/bone
mutantlungs = null mutantlungs = null
disliked_food = NONE disliked_food = NONE
liked_food = GROSS | MEAT | RAW | GORE liked_food = GROSS | MEAT | RAW | GORE
@@ -61,45 +60,6 @@
return TRUE return TRUE
return ..() return ..()
//Can still metabolize milk through meme magic
/datum/species/skeleton/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H, seconds_per_tick, times_fired)
. = ..()
if(chem.type == /datum/reagent/toxin/bonehurtingjuice)
H.adjustStaminaLoss(7.5 * REM * seconds_per_tick, 0)
H.adjustBruteLoss(0.5 * REM * seconds_per_tick, 0)
if(SPT_PROB(10, seconds_per_tick))
switch(rand(1, 3))
if(1)
H.say(pick("oof.", "ouch.", "my bones.", "oof ouch.", "oof ouch my bones."), forced = /datum/reagent/toxin/bonehurtingjuice)
if(2)
H.manual_emote(pick("oofs silently.", "looks like [H.p_their()] bones hurt.", "grimaces, as though [H.p_their()] bones hurt."))
if(3)
to_chat(H, span_warning("Your bones hurt!"))
if(chem.overdosed)
if(SPT_PROB(2, seconds_per_tick) && iscarbon(H)) //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/bp = H.get_bodypart(selected_part) //We're so sorry skeletons, you're so misunderstood
if(bp)
playsound(H, get_sfx(SFX_DESECRATION), 50, TRUE, -1) //You just want to socialize
H.visible_message(span_warning("[H] rattles loudly and flails around!!"), span_danger("Your bones hurt so much that your missing muscles spasm!!"))
H.say("OOF!!", forced=/datum/reagent/toxin/bonehurtingjuice)
bp.receive_damage(200, 0, 0) //But I don't think we should
else
to_chat(H, span_warning("Your missing arm aches from wherever you left it."))
H.emote("sigh")
H.reagents.remove_reagent(chem.type, chem.metabolization_rate * seconds_per_tick)
return TRUE
if(chem.type == /datum/reagent/consumable/milk)
if(chem.volume > 50)
H.reagents.remove_reagent(chem.type, chem.volume - 5)
to_chat(H, span_warning("The excess milk is dripping off your bones!"))
H.heal_bodypart_damage(2.5 * REM * seconds_per_tick, 2.5 * REM * seconds_per_tick)
for(var/datum/wound/iter_wound as anything in H.all_wounds)
iter_wound.on_xadone(1 * REM * seconds_per_tick)
H.reagents.remove_reagent(chem.type, chem.metabolization_rate * seconds_per_tick)
return FALSE
/datum/species/skeleton/get_species_description() /datum/species/skeleton/get_species_description()
return "A rattling skeleton! They descend upon Space Station 13 \ return "A rattling skeleton! They descend upon Space Station 13 \
Every year to spook the crew! \"I've got a BONE to pick with you!\"" Every year to spook the crew! \"I've got a BONE to pick with you!\""

View File

@@ -28,13 +28,15 @@
BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/snail BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/snail
) )
/datum/species/snail/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H, seconds_per_tick, times_fired) /datum/species/snail/handle_chemical(datum/reagent/chem, mob/living/carbon/human/affected, seconds_per_tick, times_fired)
. = ..() . = ..()
if(. & COMSIG_MOB_STOP_REAGENT_CHECK)
return
if(istype(chem,/datum/reagent/consumable/salt)) if(istype(chem,/datum/reagent/consumable/salt))
H.adjustFireLoss(2 * REM * seconds_per_tick) playsound(affected, SFX_SEAR, 30, TRUE)
playsound(H, 'sound/weapons/sear.ogg', 30, TRUE) affected.adjustFireLoss(2 * REM * seconds_per_tick)
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM * seconds_per_tick) affected.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM * seconds_per_tick)
return TRUE return COMSIG_MOB_STOP_REAGENT_CHECK
/datum/species/snail/on_species_gain(mob/living/carbon/new_snailperson, datum/species/old_species, pref_load) /datum/species/snail/on_species_gain(mob/living/carbon/new_snailperson, datum/species/old_species, pref_load)
. = ..() . = ..()

View File

@@ -1,5 +1,4 @@
/mob/living/carbon/Life(seconds_per_tick = SSMOBS_DT, times_fired) /mob/living/carbon/Life(seconds_per_tick = SSMOBS_DT, times_fired)
if(notransform) if(notransform)
return return
@@ -40,7 +39,7 @@
var/datum/addiction/addiction = SSaddiction.all_addictions[key] var/datum/addiction/addiction = SSaddiction.all_addictions[key]
addiction.process_addiction(src, seconds_per_tick, times_fired) addiction.process_addiction(src, seconds_per_tick, times_fired)
if(stat != DEAD) if(stat != DEAD)
return 1 return TRUE
/////////////// ///////////////
// BREATHING // // BREATHING //
@@ -482,10 +481,10 @@
D.stage_act(seconds_per_tick, times_fired) D.stage_act(seconds_per_tick, times_fired)
/mob/living/carbon/handle_wounds(seconds_per_tick, times_fired) /mob/living/carbon/handle_wounds(seconds_per_tick, times_fired)
for(var/thing in all_wounds) for(var/datum/wound/wound as anything in all_wounds)
var/datum/wound/W = thing if(!wound.processes) // meh
if(W.processes) // meh continue
W.handle_process(seconds_per_tick, times_fired) wound.handle_process(seconds_per_tick, times_fired)
/mob/living/carbon/handle_mutations(time_since_irradiated, seconds_per_tick, times_fired) /mob/living/carbon/handle_mutations(time_since_irradiated, seconds_per_tick, times_fired)
if(!dna?.temporary_mutations.len) if(!dna?.temporary_mutations.len)
@@ -714,7 +713,7 @@
return return
reagents.end_metabolization(src, keep_liverless = TRUE) //Stops trait-based effects on reagents, to prevent permanent buffs reagents.end_metabolization(src, keep_liverless = TRUE) //Stops trait-based effects on reagents, to prevent permanent buffs
reagents.metabolize(src, seconds_per_tick, times_fired, can_overdose=TRUE, liverless = TRUE) reagents.metabolize(src, seconds_per_tick, times_fired, can_overdose = TRUE, liverless = TRUE)
if(HAS_TRAIT(src, TRAIT_STABLELIVER) || HAS_TRAIT(src, TRAIT_NOMETABOLISM)) if(HAS_TRAIT(src, TRAIT_STABLELIVER) || HAS_TRAIT(src, TRAIT_NOMETABOLISM))
return return

View File

@@ -44,8 +44,6 @@
if(stat != DEAD) if(stat != DEAD)
//Mutations and radiation //Mutations and radiation
handle_mutations(seconds_per_tick, times_fired) handle_mutations(seconds_per_tick, times_fired)
if(stat != DEAD)
//Breathing, if applicable //Breathing, if applicable
handle_breathing(seconds_per_tick, times_fired) handle_breathing(seconds_per_tick, times_fired)

View File

@@ -1422,6 +1422,11 @@
stat = new_stat stat = new_stat
SEND_SIGNAL(src, COMSIG_MOB_STATCHANGE, new_stat, .) SEND_SIGNAL(src, COMSIG_MOB_STATCHANGE, new_stat, .)
/// Proc used for custom metabolization of reagents, if any
/mob/proc/reagent_check(datum/reagent/chem, seconds_per_tick, times_fired)
SHOULD_CALL_PARENT(TRUE)
return SEND_SIGNAL(src, COMSIG_MOB_REAGENT_CHECK, chem, seconds_per_tick, times_fired)
/mob/vv_edit_var(var_name, var_value) /mob/vv_edit_var(var_name, var_value)
switch(var_name) switch(var_name)
if(NAMEOF(src, control_object)) if(NAMEOF(src, control_object))

View File

@@ -222,11 +222,6 @@
return TRUE return TRUE
return FALSE return FALSE
/mob/proc/reagent_check(datum/reagent/R, seconds_per_tick, times_fired) // utilized in the species code
return TRUE
/** /**
* Fancy notifications for ghosts * Fancy notifications for ghosts
* *

View File

@@ -162,7 +162,7 @@
id = "plasmamanliver" id = "plasmamanliver"
build_type = LIMBGROWER build_type = LIMBGROWER
reagents_list = list(/datum/reagent/medicine/c2/synthflesh = 10, /datum/reagent/toxin/plasma = 20) reagents_list = list(/datum/reagent/medicine/c2/synthflesh = 10, /datum/reagent/toxin/plasma = 20)
build_path = /obj/item/organ/internal/liver/plasmaman build_path = /obj/item/organ/internal/liver/bone/plasmaman
category = list(SPECIES_PLASMAMAN) category = list(SPECIES_PLASMAMAN)
/datum/design/plasmaman_stomach /datum/design/plasmaman_stomach

View File

@@ -5,12 +5,12 @@
/obj/item/organ/internal/liver /obj/item/organ/internal/liver
name = "liver" name = "liver"
desc = "Pairing suggestion: chianti and fava beans."
icon_state = "liver" icon_state = "liver"
visual = FALSE visual = FALSE
w_class = WEIGHT_CLASS_SMALL w_class = WEIGHT_CLASS_SMALL
zone = BODY_ZONE_CHEST zone = BODY_ZONE_CHEST
slot = ORGAN_SLOT_LIVER slot = ORGAN_SLOT_LIVER
desc = "Pairing suggestion: chianti and fava beans."
maxHealth = STANDARD_ORGAN_THRESHOLD maxHealth = STANDARD_ORGAN_THRESHOLD
healing_factor = STANDARD_ORGAN_HEALING healing_factor = STANDARD_ORGAN_HEALING
@@ -33,6 +33,7 @@
// If the liver handles foods like a clown, it honks like a bike horn // If the liver handles foods like a clown, it honks like a bike horn
// Don't think about it too much. // Don't think about it too much.
RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_COMEDY_METABOLISM), PROC_REF(on_add_comedy_metabolism)) 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 /* 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 // 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) 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) /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(user, TRAIT_ENTRAILS_READER) || (user.mind && HAS_TRAIT(user.mind, TRAIT_ENTRAILS_READER)) || isobserver(user))
if(HAS_TRAIT(src, TRAIT_LAW_ENFORCEMENT_METABOLISM)) 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)) 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)) 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)) 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)) 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)) 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)) 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 // royal trumps pretender royal
if(HAS_TRAIT(src, TRAIT_ROYAL_METABOLISM)) 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)) 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) /obj/item/organ/internal/liver/before_organ_replacement(obj/item/organ/replacement)
. = ..() . = ..()
@@ -95,13 +125,15 @@
#define HAS_PAINFUL_TOXIN 2 #define HAS_PAINFUL_TOXIN 2
/obj/item/organ/internal/liver/on_life(seconds_per_tick, times_fired) /obj/item/organ/internal/liver/on_life(seconds_per_tick, times_fired)
var/mob/living/carbon/liver_owner = owner
. = ..() //perform general on_life() . = ..() //perform general on_life()
var/mob/living/carbon/liver_owner = owner
if(!istype(liver_owner)) if(!istype(liver_owner))
return 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 return
var/obj/belly = liver_owner.get_organ_slot(ORGAN_SLOT_STOMACH) var/obj/belly = liver_owner.get_organ_slot(ORGAN_SLOT_STOMACH)
@@ -123,7 +155,7 @@
if(provide_pain_message != HAS_PAINFUL_TOXIN) if(provide_pain_message != HAS_PAINFUL_TOXIN)
provide_pain_message = toxin.silent_toxin ? HAS_SILENT_TOXIN : 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) if(liver_damage)
apply_organ_damage(min(liver_damage * seconds_per_tick , MAX_TOXIN_LIVER_DAMAGE * seconds_per_tick)) 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) /obj/item/organ/internal/liver/get_availability(datum/species/owner_species, mob/living/owner_mob)
return owner_species.mutantliver 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 // alien livers can ignore up to 15u of toxins, but they take x3 liver damage
/obj/item/organ/internal/liver/alien /obj/item/organ/internal/liver/alien
name = "alien liver" // doesnt matter for actual aliens because they dont take toxin damage 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." 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% liver_resistance = 0.333 * LIVER_DEFAULT_TOX_RESISTANCE // -66%
toxTolerance = 15 // complete toxin immunity like xenos have would be too powerful toxTolerance = 15 // complete toxin immunity like xenos have would be too powerful
/obj/item/organ/internal/liver/cybernetic /obj/item/organ/internal/liver/cybernetic
name = "basic cybernetic liver" 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." 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 organ_flags = ORGAN_SYNTHETIC
toxTolerance = 2 toxTolerance = 2
liver_resistance = 0.9 * LIVER_DEFAULT_TOX_RESISTANCE // -10% liver_resistance = 0.9 * LIVER_DEFAULT_TOX_RESISTANCE // -10%
@@ -231,8 +257,8 @@
/obj/item/organ/internal/liver/cybernetic/tier2 /obj/item/organ/internal/liver/cybernetic/tier2
name = "cybernetic liver" 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." 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 maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD
toxTolerance = 5 //can shrug off up to 5u of toxins toxTolerance = 5 //can shrug off up to 5u of toxins
liver_resistance = 1.2 * LIVER_DEFAULT_TOX_RESISTANCE // +20% liver_resistance = 1.2 * LIVER_DEFAULT_TOX_RESISTANCE // +20%
@@ -240,8 +266,8 @@
/obj/item/organ/internal/liver/cybernetic/tier3 /obj/item/organ/internal/liver/cybernetic/tier3
name = "upgraded cybernetic liver" 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." 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 alcohol_tolerance = 0.001
maxHealth = 2 * STANDARD_ORGAN_THRESHOLD maxHealth = 2 * STANDARD_ORGAN_THRESHOLD
toxTolerance = 10 //can shrug off up to 10u of toxins toxTolerance = 10 //can shrug off up to 10u of toxins

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -3,6 +3,7 @@
/obj/item/organ/internal/stomach /obj/item/organ/internal/stomach
name = "stomach" name = "stomach"
desc = "Onaka ga suite imasu."
icon_state = "stomach" icon_state = "stomach"
visual = FALSE visual = FALSE
w_class = WEIGHT_CLASS_SMALL w_class = WEIGHT_CLASS_SMALL
@@ -10,7 +11,6 @@
slot = ORGAN_SLOT_STOMACH slot = ORGAN_SLOT_STOMACH
attack_verb_continuous = list("gores", "squishes", "slaps", "digests") attack_verb_continuous = list("gores", "squishes", "slaps", "digests")
attack_verb_simple = list("gore", "squish", "slap", "digest") attack_verb_simple = list("gore", "squish", "slap", "digest")
desc = "Onaka ga suite imasu."
healing_factor = STANDARD_ORGAN_HEALING healing_factor = STANDARD_ORGAN_HEALING
decay_factor = STANDARD_ORGAN_DECAY * 1.15 // ~13 minutes, the stomach is one of the first organs to die decay_factor = STANDARD_ORGAN_DECAY * 1.15 // ~13 minutes, the stomach is one of the first organs to die
@@ -268,21 +268,23 @@
return ..() return ..()
/obj/item/organ/internal/stomach/bone /obj/item/organ/internal/stomach/bone
name = "mass of bones"
desc = "You have no idea what this strange ball of bones does." desc = "You have no idea what this strange ball of bones does."
icon_state = "stomach-bone"
metabolism_efficiency = 0.025 //very bad metabolism_efficiency = 0.025 //very bad
organ_traits = list(TRAIT_NOHUNGER) organ_traits = list(TRAIT_NOHUNGER)
/obj/item/organ/internal/stomach/bone/plasmaman /obj/item/organ/internal/stomach/bone/plasmaman
name = "digestive crystal" 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." desc = "A strange crystal that is responsible for metabolizing the unseen energy force that feeds plasmamen."
icon_state = "stomach-p"
metabolism_efficiency = 0.06 metabolism_efficiency = 0.06
organ_traits = null
/obj/item/organ/internal/stomach/cybernetic /obj/item/organ/internal/stomach/cybernetic
name = "basic cybernetic stomach" name = "basic cybernetic stomach"
icon_state = "stomach-c"
desc = "A basic device designed to mimic the functions of a human stomach" desc = "A basic device designed to mimic the functions of a human stomach"
icon_state = "stomach-c"
organ_flags = ORGAN_SYNTHETIC organ_flags = ORGAN_SYNTHETIC
maxHealth = STANDARD_ORGAN_THRESHOLD * 0.5 maxHealth = STANDARD_ORGAN_THRESHOLD * 0.5
var/emp_vulnerability = 80 //Chance of permanent effects if emp-ed. var/emp_vulnerability = 80 //Chance of permanent effects if emp-ed.
@@ -290,8 +292,8 @@
/obj/item/organ/internal/stomach/cybernetic/tier2 /obj/item/organ/internal/stomach/cybernetic/tier2
name = "cybernetic stomach" 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." 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 maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD
disgust_metabolism = 2 disgust_metabolism = 2
emp_vulnerability = 40 emp_vulnerability = 40
@@ -299,8 +301,8 @@
/obj/item/organ/internal/stomach/cybernetic/tier3 /obj/item/organ/internal/stomach/cybernetic/tier3
name = "upgraded cybernetic stomach" 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." 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 maxHealth = 2 * STANDARD_ORGAN_THRESHOLD
disgust_metabolism = 3 disgust_metabolism = 3
emp_vulnerability = 20 emp_vulnerability = 20

View File

@@ -17,10 +17,7 @@
RegisterSignal(owner, COMSIG_CARBON_ATTEMPT_EAT, PROC_REF(try_eating)) RegisterSignal(owner, COMSIG_CARBON_ATTEMPT_EAT, PROC_REF(try_eating))
if(!ishuman(organ_owner)) if(!ishuman(organ_owner))
return return
setup_physiology(organ_owner) var/mob/living/carbon/human/human_owner = 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)
human_owner.physiology?.hunger_mod *= hunger_mod human_owner.physiology?.hunger_mod *= hunger_mod
/obj/item/organ/internal/stomach/golem/on_remove(mob/living/carbon/organ_owner, special) /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 /// 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) /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)) if(HAS_TRAIT(human, TRAIT_NOHUNGER))
return return
. = ..()
var/hunger = (NUTRITION_LEVEL_HUNGRY - human.nutrition) / NUTRITION_LEVEL_HUNGRY // starving = 1, satisfied = 0 var/hunger = (NUTRITION_LEVEL_HUNGRY - human.nutrition) / NUTRITION_LEVEL_HUNGRY // starving = 1, satisfied = 0
if(hunger > 0) if(hunger > 0)
var/slowdown = LERP(min_hunger_slowdown, max_hunger_slowdown, hunger) var/slowdown = LERP(min_hunger_slowdown, max_hunger_slowdown, hunger)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

@@ -302,7 +302,7 @@
#include "code\__DEFINES\dcs\signals\signals_scangate.dm" #include "code\__DEFINES\dcs\signals\signals_scangate.dm"
#include "code\__DEFINES\dcs\signals\signals_screentips.dm" #include "code\__DEFINES\dcs\signals\signals_screentips.dm"
#include "code\__DEFINES\dcs\signals\signals_spatial_grid.dm" #include "code\__DEFINES\dcs\signals\signals_spatial_grid.dm"
#include "code\__DEFINES\dcs\signals\signals_specie.dm" #include "code\__DEFINES\dcs\signals\signals_species.dm"
#include "code\__DEFINES\dcs\signals\signals_spell.dm" #include "code\__DEFINES\dcs\signals\signals_spell.dm"
#include "code\__DEFINES\dcs\signals\signals_storage.dm" #include "code\__DEFINES\dcs\signals\signals_storage.dm"
#include "code\__DEFINES\dcs\signals\signals_subsystem.dm" #include "code\__DEFINES\dcs\signals\signals_subsystem.dm"
@@ -5040,32 +5040,35 @@
#include "code\modules\surgery\bodyparts\species_parts\moth_bodyparts.dm" #include "code\modules\surgery\bodyparts\species_parts\moth_bodyparts.dm"
#include "code\modules\surgery\bodyparts\species_parts\plasmaman_bodyparts.dm" #include "code\modules\surgery\bodyparts\species_parts\plasmaman_bodyparts.dm"
#include "code\modules\surgery\organs\_organ.dm" #include "code\modules\surgery\organs\_organ.dm"
#include "code\modules\surgery\organs\appendix.dm"
#include "code\modules\surgery\organs\appendix_golem.dm"
#include "code\modules\surgery\organs\augments_arms.dm"
#include "code\modules\surgery\organs\augments_chest.dm"
#include "code\modules\surgery\organs\augments_eyes.dm"
#include "code\modules\surgery\organs\augments_internal.dm"
#include "code\modules\surgery\organs\autosurgeon.dm" #include "code\modules\surgery\organs\autosurgeon.dm"
#include "code\modules\surgery\organs\ears.dm"
#include "code\modules\surgery\organs\eyes.dm"
#include "code\modules\surgery\organs\heart.dm"
#include "code\modules\surgery\organs\helpers.dm" #include "code\modules\surgery\organs\helpers.dm"
#include "code\modules\surgery\organs\liver.dm" #include "code\modules\surgery\organs\external\_external_organ.dm"
#include "code\modules\surgery\organs\lungs.dm"
#include "code\modules\surgery\organs\organ_internal.dm"
#include "code\modules\surgery\organs\tongue.dm"
#include "code\modules\surgery\organs\vocal_cords.dm"
#include "code\modules\surgery\organs\external\_external_organs.dm"
#include "code\modules\surgery\organs\external\restyling.dm" #include "code\modules\surgery\organs\external\restyling.dm"
#include "code\modules\surgery\organs\external\spines.dm" #include "code\modules\surgery\organs\external\spines.dm"
#include "code\modules\surgery\organs\external\tails.dm" #include "code\modules\surgery\organs\external\tails.dm"
#include "code\modules\surgery\organs\external\wings\functional_wings.dm" #include "code\modules\surgery\organs\external\wings\functional_wings.dm"
#include "code\modules\surgery\organs\external\wings\moth_wings.dm" #include "code\modules\surgery\organs\external\wings\moth_wings.dm"
#include "code\modules\surgery\organs\external\wings\wings.dm" #include "code\modules\surgery\organs\external\wings\wings.dm"
#include "code\modules\surgery\organs\stomach\_stomach.dm" #include "code\modules\surgery\organs\internal\_internal_organ.dm"
#include "code\modules\surgery\organs\stomach\stomach_ethereal.dm" #include "code\modules\surgery\organs\internal\appendix\_appendix.dm"
#include "code\modules\surgery\organs\stomach\stomach_golem.dm" #include "code\modules\surgery\organs\internal\appendix\appendix_golem.dm"
#include "code\modules\surgery\organs\internal\cyberimp\augments_arms.dm"
#include "code\modules\surgery\organs\internal\cyberimp\augments_chest.dm"
#include "code\modules\surgery\organs\internal\cyberimp\augments_eyes.dm"
#include "code\modules\surgery\organs\internal\cyberimp\augments_internal.dm"
#include "code\modules\surgery\organs\internal\ears\_ears.dm"
#include "code\modules\surgery\organs\internal\eyes\_eyes.dm"
#include "code\modules\surgery\organs\internal\heart\_heart.dm"
#include "code\modules\surgery\organs\internal\liver\_liver.dm"
#include "code\modules\surgery\organs\internal\liver\liver_golem.dm"
#include "code\modules\surgery\organs\internal\liver\liver_plasmaman.dm"
#include "code\modules\surgery\organs\internal\liver\liver_skeleton.dm"
#include "code\modules\surgery\organs\internal\lungs\_lungs.dm"
#include "code\modules\surgery\organs\internal\stomach\_stomach.dm"
#include "code\modules\surgery\organs\internal\stomach\stomach_ethereal.dm"
#include "code\modules\surgery\organs\internal\stomach\stomach_golem.dm"
#include "code\modules\surgery\organs\internal\tongue\_tongue.dm"
#include "code\modules\surgery\organs\internal\vocal_cords\_vocal_cords.dm"
#include "code\modules\tgchat\message.dm" #include "code\modules\tgchat\message.dm"
#include "code\modules\tgchat\to_chat.dm" #include "code\modules\tgchat\to_chat.dm"
#include "code\modules\tgs\includes.dm" #include "code\modules\tgs\includes.dm"