diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm index 4922c80f9d1..401255a160d 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm @@ -381,3 +381,6 @@ /// Sent to a mob when one of their bodypart's surgery state changes, OR sent from the basic_surgery_state holder when its surgery state changes (old_state, new_state, changed_states) #define COMSIG_LIVING_UPDATING_SURGERY_STATE "carbon_updating_surgery_state" + +/// Sent to a mob when its player DNRs +#define COMSIG_LIVING_DNR "living_dnr" diff --git a/code/__DEFINES/quirks.dm b/code/__DEFINES/quirks.dm index 8cc1dee678b..41b2882e37e 100644 --- a/code/__DEFINES/quirks.dm +++ b/code/__DEFINES/quirks.dm @@ -17,3 +17,5 @@ /// Quirk is similar to brain trauma and should be shown in medical guides as one. /// You don't need to set this on quirks that apply a trauma, that's redundant. #define QUIRK_TRAUMALIKE (1<<5) +/// Do not transfer this quirk via transfer_quirk_datums +#define QUIRK_NO_TRANSFER (1<<6) diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 8365b5a58ed..dea44f55315 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -1597,9 +1597,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// Trait that signals to objects on this turf that its open (has UNDERFLOOR_INTERACTIBLE) but still covers them #define TRAIT_UNCOVERED_TURF "uncovered_turf" -/// A trait that blocks the metabolism of formaldehyde -#define TRAIT_BLOCK_FORMALDEHYDE_METABOLISM "block_formaldehyde_metabolism" - ///Attached to objects currently on tables and such, allowing them to walk on other objects without the climbing delay #define TRAIT_ON_CLIMBABLE "on_climbable" diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 8f46c495437..58afc53aff7 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -195,7 +195,6 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_BIRTHDAY_BOY" = TRAIT_BIRTHDAY_BOY, "TRAIT_BLOB_ALLY" = TRAIT_BLOB_ALLY, "TRAIT_BLOCKING_PROJECTILES" = TRAIT_BLOCKING_PROJECTILES, - "TRAIT_BLOCK_FORMALDEHYDE_METABOLISM" = TRAIT_BLOCK_FORMALDEHYDE_METABOLISM, "TRAIT_BLOCK_SECHUD" = TRAIT_BLOCK_SECHUD, "TRAIT_BLOCK_SHUTTLE_MOVEMENT" = TRAIT_BLOCK_SHUTTLE_MOVEMENT, "TRAIT_BLOODSHOT_EYES" = TRAIT_BLOODSHOT_EYES, diff --git a/code/datums/components/ghostrole_on_revive.dm b/code/datums/components/ghostrole_on_revive.dm index a8930831c88..52ea1d0bd07 100644 --- a/code/datums/components/ghostrole_on_revive.dm +++ b/code/datums/components/ghostrole_on_revive.dm @@ -6,14 +6,31 @@ var/datum/callback/on_successful_revive /// The chance to twitch when orbiting the spawn var/twitch_chance = 30 + /// The title shown to ghosts when polled to enter the body + var/revive_title -/datum/component/ghostrole_on_revive/Initialize(refuse_revival_if_failed, on_successful_revive) - . = ..() + // Text displayed in the spawners menu + var/spawn_text + var/you_are_text + var/flavor_text + var/important_text +/datum/component/ghostrole_on_revive/Initialize( + refuse_revival_if_failed = FALSE, + datum/callback/on_successful_revive, + revive_title = "a recovered crewmember", + spawn_text = "Recovered Crew", + you_are_text = "You are a long dead crewmember, but are soon to be revived to rejoin the crew!", + flavor_text = "Get a job and get back to work!", + important_text = "Do your best to help the station. You still roll for midround antagonists." +) src.refuse_revival_if_failed = refuse_revival_if_failed src.on_successful_revive = on_successful_revive - - ADD_TRAIT(parent, TRAIT_GHOSTROLE_ON_REVIVE, REF(src)) //for adding an alternate examination + src.revive_title = revive_title + src.spawn_text = spawn_text + src.you_are_text = you_are_text + src.flavor_text = flavor_text + src.important_text = important_text if(ismob(parent)) prepare_mob(parent) @@ -22,138 +39,152 @@ if(!istype(parent, /obj/item/organ/brain)) return COMPONENT_INCOMPATIBLE - var/obj/item/organ/brain/brein = parent - if(brein.owner) - prepare_mob(brein.owner) + var/obj/item/organ/brain/brain_parent = parent + if(brain_parent.owner) + prepare_mob(brain_parent.owner) else - prepare_brain(brein) + prepare_brain(brain_parent) /// Give the appropriate signals, and watch for organ removal -/datum/component/ghostrole_on_revive/proc/prepare_mob(mob/living/liver) - RegisterSignal(liver, COMSIG_LIVING_REVIVE, PROC_REF(on_revive)) - ADD_TRAIT(liver, TRAIT_GHOSTROLE_ON_REVIVE, REF(src)) +/datum/component/ghostrole_on_revive/proc/prepare_mob(mob/living/to_prepare) + RegisterSignal(to_prepare, COMSIG_LIVING_REVIVE, PROC_REF(on_revive)) + RegisterSignal(to_prepare, COMSIG_MOB_REAGENT_TICK, PROC_REF(block_formaldehyde_metabolism)) + if(istype(parent, /obj/item/organ/brain)) + RegisterSignal(to_prepare, COMSIG_CARBON_LOSE_ORGAN, PROC_REF(on_remove)) + ADD_TRAIT(to_prepare, TRAIT_GHOSTROLE_ON_REVIVE, REF(src)) - add_orbit_twitching(liver) + add_orbit_twitching(to_prepare) + to_prepare.med_hud_set_status() - liver.med_hud_set_status() +/datum/component/ghostrole_on_revive/proc/unprepare_mob(mob/living/to_unprepare) + REMOVE_TRAIT(to_unprepare, TRAIT_GHOSTROLE_ON_REVIVE, REF(src)) + UnregisterSignal(to_unprepare, list( + COMSIG_LIVING_REVIVE, + COMSIG_MOB_REAGENT_TICK, + COMSIG_CARBON_LOSE_ORGAN, + )) - if(iscarbon(liver)) - var/mob/living/carbon/carbon = liver - var/obj/item/organ/brain = carbon.get_organ_by_type(/obj/item/organ/brain) - if(brain) - RegisterSignal(brain, COMSIG_ORGAN_REMOVED, PROC_REF(on_remove)) + to_unprepare.med_hud_set_status() + remove_orbit_twitching(to_unprepare) -/datum/component/ghostrole_on_revive/proc/on_remove(obj/item/organ/brain, mob/living/old_owner) +/datum/component/ghostrole_on_revive/proc/on_remove(mob/living/carbon/source, obj/item/organ/removed_brain) SIGNAL_HANDLER - REMOVE_TRAIT(old_owner, TRAIT_GHOSTROLE_ON_REVIVE, REF(src)) - remove_orbit_twitching(old_owner) + if(!istype(removed_brain, /obj/item/organ/brain)) + return + + unprepare_mob(source) // we might have some lingering blinking eyes - var/obj/item/bodypart/head/head = old_owner?.get_bodypart(BODY_ZONE_HEAD) + var/obj/item/bodypart/head/head = source.get_bodypart(BODY_ZONE_HEAD) if(head) var/soul_eyes = locate(/datum/bodypart_overlay/simple/soul_pending_eyes) in head.bodypart_overlays if(soul_eyes) head.remove_bodypart_overlay(soul_eyes) - prepare_brain(brain) + prepare_brain(removed_brain) -/datum/component/ghostrole_on_revive/proc/prepare_brain(obj/item/organ/brein) +/datum/component/ghostrole_on_revive/proc/prepare_brain(obj/item/organ/source) + ADD_TRAIT(source, TRAIT_GHOSTROLE_ON_REVIVE, REF(src)) + RegisterSignal(source, COMSIG_ORGAN_IMPLANTED, PROC_REF(prepare_mob_from_brain)) + UnregisterSignal(source, COMSIG_ORGAN_REMOVED) + +/datum/component/ghostrole_on_revive/proc/unprepare_brain(obj/item/organ/source) + REMOVE_TRAIT(source, TRAIT_GHOSTROLE_ON_REVIVE, REF(src)) + UnregisterSignal(source, COMSIG_ORGAN_IMPLANTED) + RegisterSignal(source, COMSIG_ORGAN_REMOVED, PROC_REF(prepare_brain)) + source.owner?.med_hud_set_status() + +/datum/component/ghostrole_on_revive/proc/prepare_mob_from_brain(obj/item/organ/brain/source, mob/living/owner) SIGNAL_HANDLER - RegisterSignal(brein, COMSIG_ORGAN_IMPLANTED, PROC_REF(prepare_mob_from_brain)) - UnregisterSignal(brein, COMSIG_ORGAN_REMOVED) - -/datum/component/ghostrole_on_revive/proc/prepare_mob_from_brain(obj/item/organ/brain/brein, mob/living/owner) - SIGNAL_HANDLER - - UnregisterSignal(brein, COMSIG_ORGAN_IMPLANTED) + REMOVE_TRAIT(source, TRAIT_GHOSTROLE_ON_REVIVE, REF(src)) + UnregisterSignal(source, COMSIG_ORGAN_IMPLANTED) prepare_mob(owner) -/datum/component/ghostrole_on_revive/proc/on_revive(mob/living/aliver) +/datum/component/ghostrole_on_revive/proc/on_revive(mob/living/source) SIGNAL_HANDLER - INVOKE_ASYNC(src, PROC_REF(poll_ghosts), aliver) + INVOKE_ASYNC(src, PROC_REF(poll_ghosts), source) -/datum/component/ghostrole_on_revive/proc/poll_ghosts(mob/living/aliver) - var/soul_eyes - var/obj/item/bodypart/head +/datum/component/ghostrole_on_revive/proc/poll_ghosts(mob/living/reviving) + var/datum/bodypart_overlay/simple/soul_pending_eyes/soul_eyes // adds soulful SOUL PENDING eyes to indicate what's happening to observers + var/obj/item/bodypart/head/head = reviving.get_bodypart(BODY_ZONE_HEAD) + if(head) + soul_eyes = new() + head.add_bodypart_overlay(soul_eyes) - var/mob/living/carbon/human/hewmon - if(ishuman(aliver)) - hewmon = aliver - head = hewmon.get_bodypart(BODY_ZONE_HEAD) - if(head) - soul_eyes = new /datum/bodypart_overlay/simple/soul_pending_eyes() - head.add_bodypart_overlay(soul_eyes) - - // So during the potentially short period of time we're revived, we don't metabolize formaldehyde - // Really just a QOL for coroners, so we dont suddenly start decaying - ADD_TRAIT(aliver, TRAIT_BLOCK_FORMALDEHYDE_METABOLISM, type) + var/list/jobbans = list(ROLE_RECOVERED_CREW) + if(reviving.mind) + jobbans |= reviving.mind.assigned_role.title + for(var/datum/antagonist/antag as anything in reviving.mind.antag_datums) + if(antag.jobban_flag) + jobbans |= antag.jobban_flag + if(antag.pref_flag) + jobbans |= antag.pref_flag + if(!(antag.antag_flags & ANTAG_FAKE)) + jobbans |= ROLE_SYNDICATE var/mob/dead/observer/chosen_one = SSpolling.poll_ghosts_for_target( - question = "Would you like to play as a recovered crewmember?", - role = null, - check_jobban = ROLE_RECOVERED_CREW, + question = "Would you like to play as [revive_title]?", + check_jobban = jobbans, poll_time = 15 SECONDS, - checked_target = aliver, + checked_target = reviving, ignore_category = POLL_IGNORE_RECOVERED_CREW, - alert_pic = aliver, - role_name_text = "recovered crew", + alert_pic = reviving, + role_name_text = revive_title, ) - REMOVE_TRAIT(aliver, TRAIT_BLOCK_FORMALDEHYDE_METABOLISM, type) - if(head) head.remove_bodypart_overlay(soul_eyes) + if(soul_eyes) + qdel(soul_eyes) - if(!isobserver(chosen_one)) - if(refuse_revival_if_failed) - aliver.death() - aliver.visible_message(span_deadsay("[aliver.name]'s soul is struggling to return!")) - else - aliver.PossessByPlayer(chosen_one.ckey) - on_successful_revive?.Invoke(aliver) + if(isobserver(chosen_one)) + reviving.PossessByPlayer(chosen_one.ckey) + on_successful_revive?.Invoke(reviving) qdel(src) -/datum/component/ghostrole_on_revive/proc/add_orbit_twitching(mob/living/liver) - liver.AddElement(/datum/element/orbit_twitcher, twitch_chance) + else if(refuse_revival_if_failed) + reviving.death() + reviving.visible_message(span_deadsay("[reviving]'s soul is struggling to return!")) + +/datum/component/ghostrole_on_revive/proc/add_orbit_twitching(mob/living/parent_mob) + parent_mob.AddElement(/datum/element/orbit_twitcher, twitch_chance) // Add it to the ghostrole spawner menu. Note that we can't directly spawn from it, but we can make it twitch to alert bystanders to defib it - LAZYADD(GLOB.joinable_mobs[format_text("Recovered Crew")], liver) - RegisterSignal(liver, COMSIG_LIVING_GHOSTROLE_INFO, PROC_REF(set_spawner_info)) + LAZYADDASSOCLIST(GLOB.joinable_mobs, spawn_text, parent_mob) + RegisterSignal(parent_mob, COMSIG_LIVING_GHOSTROLE_INFO, PROC_REF(set_spawner_info)) -/datum/component/ghostrole_on_revive/proc/set_spawner_info(datum/spawners_menu/menu, string_info) +/datum/component/ghostrole_on_revive/proc/set_spawner_info(datum/spawners_menu/menu, list/string_info) SIGNAL_HANDLER - string_info["you_are_text"] = "You are a long dead crewmember, but are soon to be revived to rejoin the crew!" - string_info["flavor_text"] = "Get a job and get back to work!" - string_info["important_text"] = "Do your best to help the station. You still roll for midround antagonists." + string_info["you_are_text"] = src.you_are_text + string_info["flavor_text"] = src.flavor_text + string_info["important_text"] = src.important_text -/datum/component/ghostrole_on_revive/proc/remove_orbit_twitching(mob/living/living) - living.RemoveElement(/datum/element/orbit_twitcher, twitch_chance) +/datum/component/ghostrole_on_revive/proc/remove_orbit_twitching(mob/living/parent_mob) + parent_mob.RemoveElement(/datum/element/orbit_twitcher, twitch_chance) + LAZYREMOVEASSOC(GLOB.joinable_mobs, spawn_text, parent_mob) + UnregisterSignal(parent_mob, COMSIG_LIVING_GHOSTROLE_INFO) - // Remove from the ghostrole spawning menu - var/list/spawners = GLOB.joinable_mobs[format_text("Recovered Crew")] - LAZYREMOVE(spawners, living) +// Block formaldehyde from being metabolized, Coroner QoL +/datum/component/ghostrole_on_revive/proc/block_formaldehyde_metabolism(mob/living/source, datum/reagent/chem) + SIGNAL_HANDLER - if(!LAZYLEN(spawners)) - GLOB.joinable_mobs -= format_text("Recovered Crew") - - UnregisterSignal(living, COMSIG_LIVING_GHOSTROLE_INFO) + if(istype(chem, /datum/reagent/toxin/formaldehyde)) + return COMSIG_MOB_STOP_REAGENT_TICK /datum/component/ghostrole_on_revive/Destroy(force) - REMOVE_TRAIT(parent, TRAIT_GHOSTROLE_ON_REVIVE, REF(src)) - - var/mob/living/living if(isliving(parent)) - living = parent + unprepare_mob(parent) + else if(istype(parent, /obj/item/organ/brain)) var/obj/item/organ/brain/brain = parent - living = brain.owner - living?.med_hud_set_status() - if(living) - remove_orbit_twitching(living) + if(brain.owner) + unprepare_mob(brain.owner) + else + unprepare_brain(brain) return ..() diff --git a/code/datums/quirks/_quirk.dm b/code/datums/quirks/_quirk.dm index e8d6748faa3..46be5ac25a5 100644 --- a/code/datums/quirks/_quirk.dm +++ b/code/datums/quirks/_quirk.dm @@ -286,5 +286,7 @@ var/datum/preferences/to_pass = client || to_mob.client for(var/datum/quirk/quirk as anything in quirks) + if(quirk.quirk_flags & QUIRK_NO_TRANSFER) + continue quirk.remove_from_current_holder(quirk_transfer = TRUE) quirk.add_to_holder(to_mob, quirk_transfer = TRUE, client_source = to_pass) diff --git a/code/datums/quirks/neutral_quirks/thanatorenasia.dm b/code/datums/quirks/neutral_quirks/thanatorenasia.dm new file mode 100644 index 00000000000..6b2d1303fb8 --- /dev/null +++ b/code/datums/quirks/neutral_quirks/thanatorenasia.dm @@ -0,0 +1,55 @@ +/datum/quirk/death_dnr_poll + name = "Thanatorenasia" + desc = "Whenever you die and elect to \"Do Not Resuscitate\", your body may be taken over by another ghost upon revival - \ + giving it an entirely new personality and fresh set of memories." + icon = FA_ICON_ZAP + value = 0 + medical_record_text = "Patient has Thanatorenasia - in the event of their death and resuscitation, \ + they may experience memory loss or a change in personality." + medical_symptom_text = "In the event of the patient's death and resuscitation, \ + they may experience memory loss or a change in personality." + quirk_flags = QUIRK_NO_TRANSFER + + // Used the the spawners menu to describe the quirk + var/you_are_text = "You are a deceased crewmember, afflicted with Thanatorenasia - \ + a condition which alters personality and causes memory loss upon death and revival." + var/flavor_text = "Something feels... different. \ + You're not entirely sure who you are or what happened - All you remember is your name and that you work here. \ + Oh well, better get back to work - the last thing you want is to be both unemployed AND an amnesiac." + var/important_text = "Resume your assigned duty. \ + If you choose to \"Do Not Resuscitate\" upon death, another ghost will be allowed to take over the body. \ + You still roll for midround antagonists." + +/datum/quirk/death_dnr_poll/add_unique(client/client_source) + . = ..() + RegisterSignal(quirk_holder, COMSIG_LIVING_DNR, PROC_REF(mob_died)) + +/datum/quirk/death_dnr_poll/remove() + . = ..() + UnregisterSignal(quirk_holder, COMSIG_LIVING_DNR) + +/datum/quirk/death_dnr_poll/proc/mob_died(mob/living/source, mob/dead/observer/dnring) + SIGNAL_HANDLER + + var/whomst = source.real_name + if(source.mind && !is_unassigned_job(source.mind.assigned_role)) + whomst += "Job: [span_notice(source.mind.assigned_role.title)]." + if(length(source.mind?.get_special_roles())) + whomst += "Status: [span_boldnotice(english_list(source.mind?.get_special_roles()))]." + + source.AddComponent(/datum/component/ghostrole_on_revive, \ + refuse_revival_if_failed = TRUE, \ + on_successful_revive = CALLBACK(src, PROC_REF(on_successful_revive)), \ + revive_title = whomst, \ + spawn_text = "Deceased Crew", \ + you_are_text = src.you_are_text, \ + flavor_text = src.flavor_text, \ + important_text = src.important_text, \ + ) + source.log_message("was made ghostrole pollable by [name] quirk.", LOG_GAME, color = COLOR_PURPLE) + +/datum/quirk/death_dnr_poll/proc/on_successful_revive() + quirk_holder.log_message("has had their body taken over by a ghost due to the [name] quirk.", LOG_GAME, color = COLOR_PURPLE) + var/welcome_msg = boxed_message(span_notice("[quirk_holder.real_name] has [name] - you are [quirk_holder.p_their()] new owner.
\ + If you choose to \"Do Not Resuscitate\" upon death, another ghost will take over the body once again.")) + addtimer(CALLBACK(src, GLOBAL_PROC_REF(to_chat), quirk_holder, welcome_msg), 2 SECONDS) diff --git a/code/datums/spawners_menu.dm b/code/datums/spawners_menu.dm index b6adf6782e6..1c91fbd48da 100644 --- a/code/datums/spawners_menu.dm +++ b/code/datums/spawners_menu.dm @@ -50,9 +50,10 @@ this["name"] = mob_type this["amount_left"] = 0 for(var/mob/joinable_mob as anything in GLOB.joinable_mobs[mob_type]) + SEND_SIGNAL(joinable_mob, COMSIG_LIVING_GHOSTROLE_INFO, this) this["amount_left"] += 1 - if(!SEND_SIGNAL(joinable_mob, COMSIG_LIVING_GHOSTROLE_INFO, this)) - this["desc"] = initial(joinable_mob.desc) + this["desc"] ||= initial(joinable_mob.desc) + if(this["amount_left"] > 0) data["spawners"] += list(this) return data diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index e8e26e5de0a..80d383faba9 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -410,6 +410,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp // Update med huds current_mob.med_hud_set_status() current_mob.log_message("had their player ([key_name(src)]) do-not-resuscitate / DNR", LOG_GAME, color = COLOR_GREEN, log_globally = FALSE) + SEND_SIGNAL(current_mob, COMSIG_LIVING_DNR, src) + log_message("has opted to do-not-resuscitate / DNR from their body ([current_mob])", LOG_GAME, color = COLOR_GREEN) // Disassociates observer mind from the body mind diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index 279e65b8355..6dc3007864c 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -237,7 +237,7 @@ var/obj/item/organ/brain/brain = get_organ_by_type(/obj/item/organ/brain) if(brain && isnull(ai_controller)) var/npc_message = "" - if(HAS_TRAIT(brain, TRAIT_GHOSTROLE_ON_REVIVE)) + if(HAS_TRAIT(brain, TRAIT_GHOSTROLE_ON_REVIVE) || HAS_TRAIT(src, TRAIT_GHOSTROLE_ON_REVIVE)) npc_message = "Soul is pending..." else if(!key) npc_message = "[t_He] [t_is] totally catatonic. The stresses of life in deep-space must have been too much for [t_him]. Any recovery is unlikely." @@ -324,7 +324,7 @@ var/t_is = p_are() //This checks to see if the body is revivable var/obj/item/organ/brain = get_organ_by_type(/obj/item/organ/brain) - if(brain && HAS_TRAIT(brain, TRAIT_GHOSTROLE_ON_REVIVE)) + if((brain && HAS_TRAIT(brain, TRAIT_GHOSTROLE_ON_REVIVE)) || HAS_TRAIT(src, TRAIT_GHOSTROLE_ON_REVIVE)) return span_deadsay("[t_He] [t_is] limp and unresponsive; but [t_his] soul might yet come back...") var/client_like = client || HAS_TRAIT(src, TRAIT_MIND_TEMPORARILY_GONE) var/valid_ghost = ghost?.can_reenter_corpse && ghost?.client diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 4c95b21afe7..41cba75b8bc 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -785,17 +785,11 @@ if(affected_mob.adjust_tox_loss(-1 * metabolization_ratio * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) //it counteracts its own toxin damage. return UPDATE_MOB_HEALTH return - else if(SPT_PROB(2.5, seconds_per_tick) && !HAS_TRAIT(affected_mob, TRAIT_BLOCK_FORMALDEHYDE_METABOLISM)) + else if(SPT_PROB(2.5, seconds_per_tick)) holder.add_reagent(/datum/reagent/toxin/histamine, pick(5,15)) holder.remove_reagent(/datum/reagent/toxin/formaldehyde, 2.4 * metabolization_ratio * seconds_per_tick) return ..() -/datum/reagent/toxin/formaldehyde/metabolize_reagent(mob/living/carbon/affected_mob, seconds_per_tick, metabolized_volume) - if(HAS_TRAIT(affected_mob, TRAIT_BLOCK_FORMALDEHYDE_METABOLISM)) - return - - return ..() - /datum/reagent/toxin/venom name = "Venom" description = "An exotic poison extracted from highly toxic fauna. Causes scaling amounts of toxin damage and bruising depending and dosage. Often decays into Histamine." diff --git a/tgstation.dme b/tgstation.dme index b28377361c5..a815bb3c542 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1953,6 +1953,7 @@ #include "code\datums\quirks\neutral_quirks\pineapple_hater.dm" #include "code\datums\quirks\neutral_quirks\pineapple_liker.dm" #include "code\datums\quirks\neutral_quirks\shifty_eyes.dm" +#include "code\datums\quirks\neutral_quirks\thanatorenasia.dm" #include "code\datums\quirks\neutral_quirks\transhumanist.dm" #include "code\datums\quirks\neutral_quirks\vegetarian.dm" #include "code\datums\quirks\positive_quirks\alcohol_tolerance.dm"