diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm index 0839f8f5909..c5eaade7051 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm @@ -9,6 +9,10 @@ #define COMSIG_MOB_LOGOUT "mob_logout" ///from base of mob/set_stat(): (new_stat, old_stat) #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) #define COMSIG_MOB_CLICKON "mob_clickon" ///from base of mob/MiddleClickOn(): (atom/A) diff --git a/code/__DEFINES/dcs/signals/signals_specie.dm b/code/__DEFINES/dcs/signals/signals_species.dm similarity index 52% rename from code/__DEFINES/dcs/signals/signals_specie.dm rename to code/__DEFINES/dcs/signals/signals_species.dm index ab28febbb2c..ee5cc33ba35 100644 --- a/code/__DEFINES/dcs/signals/signals_specie.dm +++ b/code/__DEFINES/dcs/signals/signals_species.dm @@ -3,3 +3,6 @@ #define COMSIG_SPECIES_GAIN "species_gain" ///from datum/species/on_species_loss(): (datum/species/lost_species) #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 diff --git a/code/datums/components/food/golem_food.dm b/code/datums/components/food/golem_food.dm index 818bb555a38..e6b6fbbf4c3 100644 --- a/code/datums/components/food/golem_food.dm +++ b/code/datums/components/food/golem_food.dm @@ -43,7 +43,7 @@ source.balloon_alert(user, "not edible!") return COMPONENT_CANCEL_ATTACK_CHAIN if (!snack_type.can_consume(target)) - source.balloon_alert(user, "incompatible mineral!") + source.balloon_alert(user, "can't consume!") return COMPONENT_CANCEL_ATTACK_CHAIN if (!golem_snack) golem_snack = new( diff --git a/code/datums/mutations/_mutations.dm b/code/datums/mutations/_mutations.dm index 0226326165c..9ea3c8dfb17 100644 --- a/code/datums/mutations/_mutations.dm +++ b/code/datums/mutations/_mutations.dm @@ -1,5 +1,4 @@ /datum/mutation - var/name /datum/mutation/human diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index 48d72c665c6..639586b2974 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -66,9 +66,6 @@ else 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() if(getBruteLoss() < 200) return pick (list("xltrails_1", "xltrails2")) diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index 83ca1cac0e8..b4bf93d252d 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -830,7 +830,10 @@ GLOBAL_LIST_EMPTY(features_by_species) return /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) /datum/species/proc/spec_death(gibbed, mob/living/carbon/human/H) @@ -998,22 +1001,24 @@ GLOBAL_LIST_EMPTY(features_by_species) return /** - * Handling special reagent types. + * Handling special reagent interactions. * - * Return False to run the normal on_mob_life() for that reagent. - * Return True 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. - */ -/datum/species/proc/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H, seconds_per_tick, times_fired) + * Return null 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 liike normal! You must handle it manually. + **/ +/datum/species/proc/handle_chemical(datum/reagent/chem, mob/living/carbon/human/affected, seconds_per_tick, times_fired) SHOULD_CALL_PARENT(TRUE) if(chem.type == exotic_blood) - H.blood_volume = min(H.blood_volume + round(chem.volume, 0.1), BLOOD_VOLUME_MAXIMUM) - H.reagents.del_reagent(chem.type) - return TRUE + affected.blood_volume = min(affected.blood_volume + round(chem.volume, 0.1), BLOOD_VOLUME_MAXIMUM) + affected.reagents.del_reagent(chem.type) + return COMSIG_MOB_STOP_REAGENT_CHECK if(!chem.overdosed && chem.overdose_threshold && chem.volume >= chem.overdose_threshold) chem.overdosed = TRUE - chem.overdose_start(H) - H.log_message("has started overdosing on [chem.name] at [chem.volume] units.", LOG_GAME) + chem.overdose_start(affected) + 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) 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 diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index b5a7ff45b75..b4cf3010e4f 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -921,6 +921,12 @@ 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() . = ..() dna?.species.spec_updatehealth(src) diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index 7a0ade3707a..5aa79eee0b4 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -110,10 +110,6 @@ //Check inventory slots 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) . = ..() if(G.trigger_guard == TRIGGER_GUARD_NORMAL) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 18033f79479..8c7c8fd61f7 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -28,22 +28,20 @@ //Body temperature stability and damage dna.species.handle_body_temperature(src, seconds_per_tick, times_fired) - 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) + //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 handle_heart(seconds_per_tick, times_fired) + //handles liver failure effects, if we lack a liver 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 - for(var/i in all_wounds) - var/datum/wound/iter_wound = i + for(var/datum/wound/iter_wound as anything in all_wounds) iter_wound.on_stasis(seconds_per_tick, times_fired) //Update our name based on whether our face is obscured/disfigured diff --git a/code/modules/mob/living/carbon/human/species_types/dullahan.dm b/code/modules/mob/living/carbon/human/species_types/dullahan.dm index fff80507fe0..9550c8c4e05 100644 --- a/code/modules/mob/living/carbon/human/species_types/dullahan.dm +++ b/code/modules/mob/living/carbon/human/species_types/dullahan.dm @@ -71,6 +71,7 @@ human.reset_perspective(human) /datum/species/dullahan/spec_life(mob/living/carbon/human/human, seconds_per_tick, times_fired) + . = ..() if(QDELETED(my_head)) my_head = null human.investigate_log("has been gibbed by the loss of [human.p_their()] head.", INVESTIGATE_DEATHS) diff --git a/code/modules/mob/living/carbon/human/species_types/felinid.dm b/code/modules/mob/living/carbon/human/species_types/felinid.dm index 6989eabe3a4..6afacb454f1 100644 --- a/code/modules/mob/living/carbon/human/species_types/felinid.dm +++ b/code/modules/mob/living/carbon/human/species_types/felinid.dm @@ -22,13 +22,14 @@ examine_limb_id = SPECIES_HUMAN // 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)) var/datum/reagent/toxin/carpotoxin/fish = chem fish.toxpwr = 0 - /datum/species/human/felinid/on_species_gain(mob/living/carbon/carbon_being, datum/species/old_species, pref_load) if(ishuman(carbon_being)) var/mob/living/carbon/human/target_human = carbon_being diff --git a/code/modules/mob/living/carbon/human/species_types/flypeople.dm b/code/modules/mob/living/carbon/human/species_types/flypeople.dm index 5d76627aeb5..de5716ed6e1 100644 --- a/code/modules/mob/living/carbon/human/species_types/flypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/flypeople.dm @@ -35,12 +35,12 @@ 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) - H.adjustToxLoss(3 * REM * seconds_per_tick) - H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM * seconds_per_tick) - return TRUE - return ..() + affected.adjustToxLoss(3 * REM * seconds_per_tick) /datum/species/fly/check_species_weakness(obj/item/weapon, mob/living/attacker) if(istype(weapon, /obj/item/melee/flyswatter)) diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index 1d7ea3d0c21..381dd51d714 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -39,6 +39,7 @@ mutantbrain = /obj/item/organ/internal/brain/golem mutanttongue = /obj/item/organ/internal/tongue/golem mutantstomach = /obj/item/organ/internal/stomach/golem + mutantliver = /obj/item/organ/internal/liver/golem mutantappendix = /obj/item/organ/internal/appendix/golem bodypart_overrides = list( BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left/golem, @@ -94,10 +95,3 @@ )) 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 ..() diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm index c96a8e3e4e1..e4aae3fb56c 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -67,6 +67,7 @@ return ..() /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 return @@ -240,6 +241,7 @@ bodies = old_species.bodies /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(SPT_PROB(2.5, seconds_per_tick)) to_chat(H, span_notice("You feel very bloated!")) @@ -249,8 +251,6 @@ if(H.blood_volume <= BLOOD_VOLUME_LOSE_NUTRITION) H.adjust_nutrition(-1.25 * seconds_per_tick) - ..() - /datum/action/innate/split_body name = "Split Body" check_flags = AB_CHECK_CONSCIOUS diff --git a/code/modules/mob/living/carbon/human/species_types/mothmen.dm b/code/modules/mob/living/carbon/human/species_types/mothmen.dm index be33d8dd553..f3d36e27be7 100644 --- a/code/modules/mob/living/carbon/human/species_types/mothmen.dm +++ b/code/modules/mob/living/carbon/human/species_types/mothmen.dm @@ -51,11 +51,12 @@ 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) - H.adjustToxLoss(3 * REM * seconds_per_tick) - H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM * seconds_per_tick) + affected.adjustToxLoss(3 * REM * seconds_per_tick) /datum/species/moth/check_species_weakness(obj/item/weapon, mob/living/attacker) if(istype(weapon, /obj/item/melee/flyswatter)) diff --git a/code/modules/mob/living/carbon/human/species_types/mushpeople.dm b/code/modules/mob/living/carbon/human/species_types/mushpeople.dm index 93d7eee8a1e..40437bcff3c 100644 --- a/code/modules/mob/living/carbon/human/species_types/mushpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/mushpeople.dm @@ -57,13 +57,13 @@ mush.remove(C) 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) - H.adjustToxLoss(3 * REM * seconds_per_tick) - H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM * seconds_per_tick) - return TRUE - return ..() + affected.adjustToxLoss(3 * REM * seconds_per_tick) /datum/species/mush/handle_mutant_bodyparts(mob/living/carbon/human/H, forced_colour) forced_colour = FALSE - ..() + return ..() diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index 6a82ef96a40..25d7e252965 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -20,7 +20,7 @@ inherent_respiration_type = RESPIRATION_PLASMA mutantlungs = /obj/item/organ/internal/lungs/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 mutantappendix = null mutantheart = null @@ -62,6 +62,7 @@ C.set_safe_hunger_level() /datum/species/plasmaman/spec_life(mob/living/carbon/human/H, seconds_per_tick, times_fired) + . = ..() var/atmos_sealed = TRUE if(HAS_TRAIT(H, TRAIT_NOFIRE)) atmos_sealed = FALSE @@ -133,57 +134,6 @@ 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) return pick( 'sound/voice/plasmaman/plasmeme_scream_1.ogg', diff --git a/code/modules/mob/living/carbon/human/species_types/podpeople.dm b/code/modules/mob/living/carbon/human/species_types/podpeople.dm index 89e03756e19..617fab8c25e 100644 --- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm @@ -48,6 +48,7 @@ return ..() /datum/species/pod/spec_life(mob/living/carbon/human/H, seconds_per_tick, times_fired) + . = ..() if(H.stat == DEAD) return @@ -66,14 +67,13 @@ if(H.nutrition < NUTRITION_LEVEL_STARVING + 50) 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) - H.adjustToxLoss(3 * REM * seconds_per_tick) - H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM * seconds_per_tick) - return TRUE - return ..() + affected.adjustToxLoss(3 * REM * seconds_per_tick) /datum/species/pod/create_pref_unique_perks() var/list/to_add = list() diff --git a/code/modules/mob/living/carbon/human/species_types/skeletons.dm b/code/modules/mob/living/carbon/human/species_types/skeletons.dm index 7e63318de3b..fb86b8952d2 100644 --- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm +++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm @@ -17,7 +17,6 @@ TRAIT_LIMBATTACHMENT, TRAIT_NOBREATH, TRAIT_NOCLONELOSS, - TRAIT_NOMETABOLISM, TRAIT_RADIMMUNE, TRAIT_PIERCEIMMUNE, TRAIT_RESISTCOLD, @@ -33,7 +32,7 @@ mutantstomach = /obj/item/organ/internal/stomach/bone mutantappendix = null mutantheart = null - mutantliver = null + mutantliver = /obj/item/organ/internal/liver/bone mutantlungs = null disliked_food = NONE liked_food = GROSS | MEAT | RAW | GORE @@ -61,45 +60,6 @@ return TRUE 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() 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!\"" diff --git a/code/modules/mob/living/carbon/human/species_types/snail.dm b/code/modules/mob/living/carbon/human/species_types/snail.dm index b9b9c1533a9..8b4ed885459 100644 --- a/code/modules/mob/living/carbon/human/species_types/snail.dm +++ b/code/modules/mob/living/carbon/human/species_types/snail.dm @@ -28,13 +28,15 @@ 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)) - H.adjustFireLoss(2 * REM * seconds_per_tick) - playsound(H, 'sound/weapons/sear.ogg', 30, TRUE) - H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM * seconds_per_tick) - return TRUE + playsound(affected, SFX_SEAR, 30, TRUE) + affected.adjustFireLoss(2 * REM * seconds_per_tick) + affected.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM * seconds_per_tick) + return COMSIG_MOB_STOP_REAGENT_CHECK /datum/species/snail/on_species_gain(mob/living/carbon/new_snailperson, datum/species/old_species, pref_load) . = ..() diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 9bf815d529f..b031f03b322 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -1,5 +1,4 @@ /mob/living/carbon/Life(seconds_per_tick = SSMOBS_DT, times_fired) - if(notransform) return @@ -40,7 +39,7 @@ var/datum/addiction/addiction = SSaddiction.all_addictions[key] addiction.process_addiction(src, seconds_per_tick, times_fired) if(stat != DEAD) - return 1 + return TRUE /////////////// // BREATHING // @@ -482,10 +481,10 @@ D.stage_act(seconds_per_tick, times_fired) /mob/living/carbon/handle_wounds(seconds_per_tick, times_fired) - for(var/thing in all_wounds) - var/datum/wound/W = thing - if(W.processes) // meh - W.handle_process(seconds_per_tick, times_fired) + for(var/datum/wound/wound as anything in all_wounds) + if(!wound.processes) // meh + continue + wound.handle_process(seconds_per_tick, times_fired) /mob/living/carbon/handle_mutations(time_since_irradiated, seconds_per_tick, times_fired) if(!dna?.temporary_mutations.len) @@ -714,7 +713,7 @@ return 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)) return diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 8508b1c2ca8..95b7da5b9da 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -44,8 +44,6 @@ if(stat != DEAD) //Mutations and radiation handle_mutations(seconds_per_tick, times_fired) - - if(stat != DEAD) //Breathing, if applicable handle_breathing(seconds_per_tick, times_fired) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 66542714c70..06c384aa211 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1422,6 +1422,11 @@ stat = 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) switch(var_name) if(NAMEOF(src, control_object)) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 1be76be1f35..44eb4385955 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -222,11 +222,6 @@ return TRUE 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 * diff --git a/code/modules/research/designs/limbgrower_designs.dm b/code/modules/research/designs/limbgrower_designs.dm index 3c911a6567d..ef8c762acd7 100644 --- a/code/modules/research/designs/limbgrower_designs.dm +++ b/code/modules/research/designs/limbgrower_designs.dm @@ -162,7 +162,7 @@ id = "plasmamanliver" build_type = LIMBGROWER 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) /datum/design/plasmaman_stomach diff --git a/code/modules/surgery/organs/external/_external_organs.dm b/code/modules/surgery/organs/external/_external_organ.dm similarity index 100% rename from code/modules/surgery/organs/external/_external_organs.dm rename to code/modules/surgery/organs/external/_external_organ.dm diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/internal/_internal_organ.dm similarity index 100% rename from code/modules/surgery/organs/organ_internal.dm rename to code/modules/surgery/organs/internal/_internal_organ.dm diff --git a/code/modules/surgery/organs/appendix.dm b/code/modules/surgery/organs/internal/appendix/_appendix.dm similarity index 100% rename from code/modules/surgery/organs/appendix.dm rename to code/modules/surgery/organs/internal/appendix/_appendix.dm diff --git a/code/modules/surgery/organs/appendix_golem.dm b/code/modules/surgery/organs/internal/appendix/appendix_golem.dm similarity index 100% rename from code/modules/surgery/organs/appendix_golem.dm rename to code/modules/surgery/organs/internal/appendix/appendix_golem.dm diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/internal/cyberimp/augments_arms.dm similarity index 100% rename from code/modules/surgery/organs/augments_arms.dm rename to code/modules/surgery/organs/internal/cyberimp/augments_arms.dm diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/internal/cyberimp/augments_chest.dm similarity index 100% rename from code/modules/surgery/organs/augments_chest.dm rename to code/modules/surgery/organs/internal/cyberimp/augments_chest.dm diff --git a/code/modules/surgery/organs/augments_eyes.dm b/code/modules/surgery/organs/internal/cyberimp/augments_eyes.dm similarity index 100% rename from code/modules/surgery/organs/augments_eyes.dm rename to code/modules/surgery/organs/internal/cyberimp/augments_eyes.dm diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm similarity index 100% rename from code/modules/surgery/organs/augments_internal.dm rename to code/modules/surgery/organs/internal/cyberimp/augments_internal.dm diff --git a/code/modules/surgery/organs/ears.dm b/code/modules/surgery/organs/internal/ears/_ears.dm similarity index 100% rename from code/modules/surgery/organs/ears.dm rename to code/modules/surgery/organs/internal/ears/_ears.dm diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/internal/eyes/_eyes.dm similarity index 100% rename from code/modules/surgery/organs/eyes.dm rename to code/modules/surgery/organs/internal/eyes/_eyes.dm diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/internal/heart/_heart.dm similarity index 100% rename from code/modules/surgery/organs/heart.dm rename to code/modules/surgery/organs/internal/heart/_heart.dm diff --git a/code/modules/surgery/organs/liver.dm b/code/modules/surgery/organs/internal/liver/_liver.dm similarity index 78% rename from code/modules/surgery/organs/liver.dm rename to code/modules/surgery/organs/internal/liver/_liver.dm index 7c0de6f043a..cf160fc4588 100644 --- a/code/modules/surgery/organs/liver.dm +++ b/code/modules/surgery/organs/internal/liver/_liver.dm @@ -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 security." + . += span_info("Fatty deposits and sprinkle residue, imply that this is the liver of someone in security.") if(HAS_TRAIT(src, TRAIT_CULINARY_METABOLISM)) - . += "The high iron content and slight smell of garlic, implies that this is the liver of a cook." + . += span_info("The high iron content and slight smell of garlic, implies that this is the liver of a cook.") 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 clown." + . += span_info("A smell of bananas, a slippery sheen and [span_clown("honking")] when depressed, implies that this is the liver of a clown.") 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 medical worker." + . += span_info("Marks of stress and a faint whiff of medicinal alcohol, imply that this is the liver of a medical worker.") if(HAS_TRAIT(src, TRAIT_ENGINEER_METABOLISM)) - . += "Signs of radiation exposure and space adaption, implies that this is the liver of an engineer." + . += span_info("Signs of radiation exposure and space adaption, implies that this is the liver of an engineer.") 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 scientist." + . += span_info("Strange glowing residues, sprinklings of congealed solid plasma, and what seem to be tumors indicate this is the radiated liver of a scientist.") 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 assistant'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 assistant'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 head of staff." + . += span_info("A rich diet of luxury food, suppleness from soft beds, implies that this is the liver of a head of staff.") 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 someone who wants to be a head of staff." + . += span_info("A diet of imitation caviar, and signs of insomnia, implies that this is the liver of someone who wants to be a head of staff.") /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 diff --git a/code/modules/surgery/organs/internal/liver/liver_golem.dm b/code/modules/surgery/organs/internal/liver/liver_golem.dm new file mode 100644 index 00000000000..69d1a0b9baf --- /dev/null +++ b/code/modules/surgery/organs/internal/liver/liver_golem.dm @@ -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 diff --git a/code/modules/surgery/organs/internal/liver/liver_plasmaman.dm b/code/modules/surgery/organs/internal/liver/liver_plasmaman.dm new file mode 100644 index 00000000000..34dbec6ab61 --- /dev/null +++ b/code/modules/surgery/organs/internal/liver/liver_plasmaman.dm @@ -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 diff --git a/code/modules/surgery/organs/internal/liver/liver_skeleton.dm b/code/modules/surgery/organs/internal/liver/liver_skeleton.dm new file mode 100644 index 00000000000..3ddd3214353 --- /dev/null +++ b/code/modules/surgery/organs/internal/liver/liver_skeleton.dm @@ -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 diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/internal/lungs/_lungs.dm similarity index 100% rename from code/modules/surgery/organs/lungs.dm rename to code/modules/surgery/organs/internal/lungs/_lungs.dm diff --git a/code/modules/surgery/organs/stomach/_stomach.dm b/code/modules/surgery/organs/internal/stomach/_stomach.dm similarity index 99% rename from code/modules/surgery/organs/stomach/_stomach.dm rename to code/modules/surgery/organs/internal/stomach/_stomach.dm index 345027ef5d7..8769076418a 100644 --- a/code/modules/surgery/organs/stomach/_stomach.dm +++ b/code/modules/surgery/organs/internal/stomach/_stomach.dm @@ -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 diff --git a/code/modules/surgery/organs/stomach/stomach_ethereal.dm b/code/modules/surgery/organs/internal/stomach/stomach_ethereal.dm similarity index 100% rename from code/modules/surgery/organs/stomach/stomach_ethereal.dm rename to code/modules/surgery/organs/internal/stomach/stomach_ethereal.dm diff --git a/code/modules/surgery/organs/stomach/stomach_golem.dm b/code/modules/surgery/organs/internal/stomach/stomach_golem.dm similarity index 93% rename from code/modules/surgery/organs/stomach/stomach_golem.dm rename to code/modules/surgery/organs/internal/stomach/stomach_golem.dm index 6b556c8d1f6..17adbe7ad0c 100644 --- a/code/modules/surgery/organs/stomach/stomach_golem.dm +++ b/code/modules/surgery/organs/internal/stomach/stomach_golem.dm @@ -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) diff --git a/code/modules/surgery/organs/tongue.dm b/code/modules/surgery/organs/internal/tongue/_tongue.dm similarity index 100% rename from code/modules/surgery/organs/tongue.dm rename to code/modules/surgery/organs/internal/tongue/_tongue.dm diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/internal/vocal_cords/_vocal_cords.dm similarity index 100% rename from code/modules/surgery/organs/vocal_cords.dm rename to code/modules/surgery/organs/internal/vocal_cords/_vocal_cords.dm diff --git a/icons/obj/medical/organs/organs.dmi b/icons/obj/medical/organs/organs.dmi index acab1e24840..b47584b321c 100644 Binary files a/icons/obj/medical/organs/organs.dmi and b/icons/obj/medical/organs/organs.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 01e80d08ec7..0caa8826527 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -302,7 +302,7 @@ #include "code\__DEFINES\dcs\signals\signals_scangate.dm" #include "code\__DEFINES\dcs\signals\signals_screentips.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_storage.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\plasmaman_bodyparts.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\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\liver.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\_external_organ.dm" #include "code\modules\surgery\organs\external\restyling.dm" #include "code\modules\surgery\organs\external\spines.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\moth_wings.dm" #include "code\modules\surgery\organs\external\wings\wings.dm" -#include "code\modules\surgery\organs\stomach\_stomach.dm" -#include "code\modules\surgery\organs\stomach\stomach_ethereal.dm" -#include "code\modules\surgery\organs\stomach\stomach_golem.dm" +#include "code\modules\surgery\organs\internal\_internal_organ.dm" +#include "code\modules\surgery\organs\internal\appendix\_appendix.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\to_chat.dm" #include "code\modules\tgs\includes.dm"