[MIRROR] Gibs/Dead bodies no longer produce miasma (#4444)

* Gibs/Dead bodies no longer produce miasma (#57957)

* Gibs/Dead bodies no longer produce miasma

Miasma production as it is now is too little over too long a time span, and it just ends up spreading across the
station and having little effect. My goal here is to remove a source of uninteresting gas from the station's
air, and make corpses and gib piles more infectious.
I've placed the cap on disease payout at a strength of 7, so there's a slight chance of a positive disease, but
I think it's counteracted by the danger presented by just infecting yourself till you get what you want.

I've rewriten the rot component to just run a percent chance to infect someone with a disease based on the type
of rot, and moved almost all of its behavior to signals. There's one portion I can't rewrite without making
significant changes to how I handle atmos sensitivity, so that'll come later.

Co-authored-by: Mothblocks <35135081+Mothblocks@ users.noreply.github.com>

* Gibs/Dead bodies no longer produce miasma

Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
Co-authored-by: Mothblocks <35135081+Mothblocks@ users.noreply.github.com>
This commit is contained in:
SkyratBot
2021-03-27 14:20:55 +00:00
committed by GitHub
co-authored by Mothblocks LemonInTheDark
parent 2ddbb74439
commit cdfbf86d07
9 changed files with 136 additions and 75 deletions
+7 -5
View File
@@ -117,7 +117,7 @@
#define COMSIG_ATOM_UPDATE_OVERLAYS "atom_update_overlays"
///from base of [/atom/update_icon]: (signalOut, did_anything)
#define COMSIG_ATOM_UPDATED_ICON "atom_updated_icon"
///from base of atom/Entered(): (atom/movable/entering, /atom)
///from base of atom/Entered(): (atom/movable/entering, /atom/oldLoc)
#define COMSIG_ATOM_ENTERED "atom_entered"
/// Sent from the atom that just Entered src. From base of atom/Entered(): (/atom/entered_atom, /atom/oldLoc)
#define COMSIG_ATOM_ENTERING "atom_entering"
@@ -230,11 +230,11 @@
#define COMSIG_REAGENTS_ADD_REAGENT "reagents_add_reagent"
///from base of [/datum/reagents/proc/del_reagent]: (/datum/reagent)
#define COMSIG_REAGENTS_DEL_REAGENT "reagents_del_reagent"
///from base of [/datum/reagents/proc/clear_reagents]: ()
#define COMSIG_REAGENTS_REM_REAGENT "reagents_rem_reagent"
///from base of [/datum/reagents/proc/set_temperature]: (new_temp, old_temp)
#define COMSIG_REAGENTS_CLEAR_REAGENTS "reagents_clear_reagents"
///from base of [/datum/reagents/proc/remove_reagent]: (/datum/reagent, amount)
#define COMSIG_REAGENTS_REM_REAGENT "reagents_rem_reagent"
///from base of [/datum/reagents/proc/clear_reagents]: ()
#define COMSIG_REAGENTS_CLEAR_REAGENTS "reagents_clear_reagents"
///from base of [/datum/reagents/proc/set_temperature]: (new_temp, old_temp)
#define COMSIG_REAGENTS_TEMP_CHANGE "reagents_temp_change"
///from base of [/datum/reagents/proc/handle_reactions]: (num_reactions)
#define COMSIG_REAGENTS_REACTED "reagents_reacted"
@@ -855,6 +855,8 @@
#define COMSIG_HUMAN_DISARM_HIT "human_disarm_hit"
///Whenever EquipRanked is called, called after job is set
#define COMSIG_JOB_RECEIVED "job_received"
///from /mob/living/carbon/human/proc/set_coretemperature(): (oldvalue, newvalue)
#define COMSIG_HUMAN_CORETEMP_CHANGE "human_coretemp_change"
// /datum/species signals
+112 -58
View File
@@ -1,78 +1,132 @@
/datum/component/rot
/// Amount of miasma we're spawning per tick
var/amount = 1
/// Time remaining before we remove the component
var/time_remaining = 5 MINUTES
#define REAGENT_BLOCKER (1<<0)
#define TEMPERATURE_BLOCKER (1<<1)
#define HUSK_BLOCKER (1<<2)
/datum/component/rot/Initialize(new_amount)
///Makes a thing rotting, carries with it a start delay and some things that can halt the rot, along with infection logic
/datum/component/rot
///The time we were created, allows for cheese smell
var/start_time = 0
///The delay in ticks between the start of rot and effects kicking in
var/start_delay = 0
///How strong is the rot? used for scaling different aspects of the component. Between 0 and 1
var/strength = 0
///Is the component active right now?
var/active = FALSE
///Bitfield of sources preventing the component from rotting
var/blockers = NONE
/datum/component/rot/Initialize(delay, severity)
if(!isatom(parent))
return COMPONENT_INCOMPATIBLE
if(isliving(parent))
var/mob/living/living_parent = parent
//I think this can break in cases where someone becomes a robot post death, but I uh, I don't know how to account for that
if(!(living_parent.mob_biotypes & (MOB_ORGANIC|MOB_UNDEAD)))
return COMPONENT_INCOMPATIBLE
if(new_amount)
amount = new_amount
start_delay = delay
strength = severity
START_PROCESSING(SSprocessing, src)
RegisterSignal(parent, list(COMSIG_ATOM_HULK_ATTACK, COMSIG_ATOM_ATTACK_ANIMAL, COMSIG_ATOM_ATTACK_HAND), .proc/rot_react_touch)
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/rot_hit_react)
if(ismovable(parent))
RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED, COMSIG_MOVABLE_BUMP), .proc/rot_react)
if(isliving(parent))
RegisterSignal(parent, COMSIG_LIVING_REVIVE, .proc/react_to_revive) //mobs stop this when they come to life
RegisterSignal(parent, COMSIG_LIVING_GET_PULLED, .proc/rot_react_touch)
if(iscarbon(parent))
var/mob/living/carbon/carbon_parent = parent
RegisterSignal(carbon_parent.reagents, list(COMSIG_REAGENTS_ADD_REAGENT,
COMSIG_REAGENTS_REM_REAGENT,
COMSIG_REAGENTS_DEL_REAGENT), .proc/check_reagent)
RegisterSignal(parent, list(SIGNAL_ADDTRAIT(TRAIT_HUSK), SIGNAL_REMOVETRAIT(TRAIT_HUSK)), .proc/check_husk_trait)
check_reagent(carbon_parent.reagents, null)
check_husk_trait(null)
if(ishuman(parent))
var/mob/living/carbon/human/human_parent = parent
RegisterSignal(parent, COMSIG_HUMAN_CORETEMP_CHANGE, .proc/check_for_temperature)
check_for_temperature(null, 0, human_parent.coretemperature)
/datum/component/rot/Destroy(force, silent)
STOP_PROCESSING(SSprocessing, src)
. = ..()
start_up(NONE) //If nothing's blocking it, start
/datum/component/rot/process(delta_time)
var/atom/A = parent
///One of two procs that modifies blockers, this one handles removing a blocker and potentially restarting the rot
/datum/component/rot/proc/start_up(blocker_type)
blockers &= ~blocker_type //Yeet the type
if(blockers || active) //If it's not empty
return
start_time = world.time
active = TRUE
//SSprocessing goes off per 1 second
time_remaining -= delta_time * 1 SECONDS
if(time_remaining <= 0)
qdel(src)
///One of two procs that modifies blockers, this one handles adding a blocker and potentially ending the rot
/datum/component/rot/proc/rest(blocker_type)
var/old_blockers = blockers
blockers |= blocker_type
if(old_blockers || !active) //If it had anything before this
return
start_delay = max((start_time + start_delay) - world.time, 0) //Account for the time spent rotting
active = FALSE
/datum/component/rot/proc/react_to_revive()
SIGNAL_HANDLER
qdel(src)
/datum/component/rot/proc/check_reagent(datum/reagents/source, datum/reagent/modified)
SIGNAL_HANDLER
if(modified && !istype(modified, /datum/reagent/toxin/formaldehyde) && !istype(modified, /datum/reagent/cryostylane))
return
if(source.has_reagent(/datum/reagent/toxin/formaldehyde, 15) || source.has_reagent(/datum/reagent/cryostylane))
rest(REAGENT_BLOCKER)
return
start_up(REAGENT_BLOCKER)
/datum/component/rot/proc/check_for_temperature(datum/source, old_temp, new_temp)
if(new_temp <= T0C-10)
rest(TEMPERATURE_BLOCKER)
return
start_up(TEMPERATURE_BLOCKER)
/datum/component/rot/proc/check_husk_trait()
SIGNAL_HANDLER
if(HAS_TRAIT(parent, TRAIT_HUSK))
rest(HUSK_BLOCKER)
return
start_up(HUSK_BLOCKER)
/datum/component/rot/proc/rot_hit_react(datum/source, obj/item/hit_with, mob/living/attacker, params)
SIGNAL_HANDLER
rot_react_touch(source, attacker)
/datum/component/rot/proc/rot_react_touch(datum/source, mob/living/react_to)
SIGNAL_HANDLER
rot_react(source, react_to, react_to.zone_selected)
///The main bit of logic for the rot component, does a temperature check and has a chance to infect react_to
/datum/component/rot/proc/rot_react(source, mob/living/react_to, target_zone = null)
SIGNAL_HANDLER
if(!isliving(react_to))
return
var/turf/open/T = get_turf(A)
if(!istype(T) || T.planetary_atmos || T.return_air().return_pressure() > (WARNING_HIGH_PRESSURE - 10))
// Don't infect if you're chilled (I'd like to link this with the signals, but I can't come up with a good way to pull it off)
var/atom/atom_parent = parent
var/datum/gas_mixture/our_mix = atom_parent.return_air()
if(our_mix?.temperature <= T0C-10)
return
var/datum/gas_mixture/stank = new
ADD_GAS(/datum/gas/miasma, stank.gases)
stank.gases[/datum/gas/miasma][MOLES] = amount * delta_time
stank.temperature = BODYTEMP_NORMAL // otherwise we have gas below 2.7K which will break our lag generator
T.assume_air(stank)
T.air_update_turf(FALSE, FALSE)
/datum/component/rot/corpse
amount = MIASMA_CORPSE_MOLES
time_remaining = 7 MINUTES //2 minutes more to compensate for the delay
/datum/component/rot/corpse/Initialize()
if(!iscarbon(parent))
return COMPONENT_INCOMPATIBLE
. = ..()
/datum/component/rot/corpse/process()
var/mob/living/carbon/carbon_mob = parent
if(carbon_mob.stat != DEAD)
qdel(src)
if(!active)
return
// Wait a bit before decaying
if(world.time - carbon_mob.timeofdeath < 2 MINUTES)
if(world.time - start_time < start_delay)
return
// Properly stored corpses shouldn't create miasma
if(istype(carbon_mob.loc, /obj/structure/closet/crate/coffin)|| istype(carbon_mob.loc, /obj/structure/closet/body_bag) || istype(carbon_mob.loc, /obj/structure/bodycontainer))
if(!prob(strength * 8))
return
// No decay if formaldehyde in corpse or when the corpse is charred
if(carbon_mob.reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 15) || HAS_TRAIT(carbon_mob, TRAIT_HUSK))
return
//We're running just under the "worst disease", since we don't want these to be too strong
var/datum/disease/advance/random/rand_disease = new(rand(5 * strength), rand(strength * 7))
rand_disease.name = "Unknown"
react_to.ContactContractDisease(rand_disease, target_zone)
// Similar to formaldehyde except it slows down surgery too
if(carbon_mob.reagents.has_reagent(/datum/reagent/cryostylane))
return
// Also no decay if corpse chilled or not organic/undead
if(carbon_mob.bodytemperature <= T0C-10 || !(carbon_mob.mob_biotypes & (MOB_ORGANIC|MOB_UNDEAD)))
return
..()
/datum/component/rot/gibs
amount = MIASMA_GIBS_MOLES
#undef REAGENT_BLOCKER
#undef TEMPERATURE_BLOCKER
#undef HUSK_BLOCKER
+1 -1
View File
@@ -19,7 +19,7 @@
/datum/disease/advance
name = "Unknown" // We will always let our Virologist name our disease.
desc = "An engineered disease which can contain a multitude of symptoms."
form = "Advance Disease" // Will let med-scanners know that this disease was engineered.
form = "Advanced Disease" // Will let med-scanners know that this disease was engineered.
agent = "advance microbes"
max_stages = 5
spread_text = "Unknown"
+1 -1
View File
@@ -346,7 +346,7 @@
owner.bodytemperature = owner.get_body_temp_normal()
if(istype(owner, /mob/living/carbon/human))
var/mob/living/carbon/human/humi = owner
humi.coretemperature = humi.get_body_temp_normal()
humi.set_coretemperature(humi.get_body_temp_normal())
return TRUE
/datum/status_effect/regenerative_core/on_remove()
@@ -8,12 +8,15 @@
bloodiness = BLOOD_AMOUNT_PER_DECAL
beauty = -100
clean_type = CLEAN_TYPE_BLOOD
var/should_dry = TRUE
var/dryname = "dried blood" //when the blood lasts long enough, it becomes dry and gets a new name
var/drydesc = "Looks like it's been here a while. Eew." //as above
var/drytime = 0
/obj/effect/decal/cleanable/blood/Initialize()
/obj/effect/decal/cleanable/blood/Initialize(mapload)
. = ..()
if(!should_dry)
return
if(bloodiness)
start_drying()
else
@@ -98,15 +101,13 @@
. = ..()
reagents.add_reagent(/datum/reagent/liquidgibs, 5)
RegisterSignal(src, COMSIG_MOVABLE_PIPE_EJECTING, .proc/on_pipe_eject)
if(mapload) //Don't rot at roundstart for the love of god
return
/obj/effect/decal/cleanable/blood/gibs/replace_decal(obj/effect/decal/cleanable/C)
return FALSE //Never fail to place us
/obj/effect/decal/cleanable/blood/gibs/dry()
. = ..()
AddComponent(/datum/component/rot/gibs)
AddComponent(/datum/component/rot, 0, 0.7)
/obj/effect/decal/cleanable/blood/gibs/ex_act(severity, target)
return FALSE
@@ -169,6 +170,7 @@
desc = "Space Jesus, why didn't anyone clean this up? They smell terrible."
icon_state = "gib1-old"
bloodiness = 0
should_dry = FALSE
dryname = "old rotting gibs"
drydesc = "Space Jesus, why didn't anyone clean this up? They smell terrible."
@@ -177,6 +179,7 @@
setDir(pick(1,2,4,8))
add_blood_DNA(list("Non-human DNA" = random_blood_type()))
AddElement(/datum/element/swabable, CELL_LINE_TABLE_SLUDGE, CELL_VIRUS_TABLE_GENERIC, rand(2,4), 10)
dry()
/obj/effect/decal/cleanable/blood/drip
name = "drips of blood"
+2 -3
View File
@@ -8,8 +8,7 @@
ADD_TRAIT(src, TRAIT_AGEUSIA, NO_TONGUE_TRAIT)
GLOB.carbon_list += src
if(!mapload) //I don't want no gas leaks on my space ruin you hear?
RegisterSignal(src, COMSIG_LIVING_DEATH, .proc/attach_rot)
RegisterSignal(src, COMSIG_LIVING_DEATH, .proc/attach_rot)
/mob/living/carbon/Destroy()
//This must be done first, so the mob ghosts correctly before DNA etc is nulled
@@ -1321,4 +1320,4 @@
/mob/living/carbon/proc/attach_rot(mapload)
AddComponent(/datum/component/rot/corpse)
AddComponent(/datum/component/rot, 6 MINUTES, 1)
@@ -51,7 +51,6 @@
var/failed_last_breath = FALSE
var/co2overloadtime = null
var/temperature_resistance = T0C+75
var/obj/item/food/meat/slab/type_of_meat = /obj/item/food/meat/slab
var/gib_type = /obj/effect/decal/cleanable/blood/gibs
@@ -760,7 +760,7 @@
for(var/datum/mutation/human/HM in dna.mutations)
if(HM.quality != POSITIVE)
dna.remove_mutation(HM.name)
coretemperature = get_body_temp_normal(apply_change=FALSE)
set_coretemperature(get_body_temp_normal(apply_change=FALSE))
heat_exposure_stacks = 0
return ..()
+5 -1
View File
@@ -128,7 +128,11 @@
* * max_temp (optional) The maximum body temperature after adjustment
*/
/mob/living/carbon/human/proc/adjust_coretemperature(amount, min_temp=0, max_temp=INFINITY)
coretemperature = clamp(coretemperature + amount, min_temp, max_temp)
set_coretemperature(clamp(coretemperature + amount, min_temp, max_temp))
/mob/living/carbon/human/proc/set_coretemperature(value)
SEND_SIGNAL(src, COMSIG_HUMAN_CORETEMP_CHANGE, coretemperature, value)
coretemperature = value
/**
* get_body_temperature Returns the body temperature with any modifications applied