Robotic organ and disease improvements (#76766)

## About The Pull Request

In the code description for the `ORGAN_ROBOTIC` flag, it says that
robotic organs are not supposed to decay or regenerate health. I went
and fixed this and added some more "robotic" behavior.

New changes for robotic organs:
- No longer heal damage passively
- No longer gain health from revival
- No longer heal in the smart organ fridge
- No longer heal from pluoxium
- Robotic ears no longer heal from ear healing items (earmuffs, etc.)
- Robotic eyes are immune to changeling blind stings
- Robotic eyes no longer heal from occuline

New changes for diseases:
- Some diseases now require an organ to work. A robotic organ will give
immunity to the disease symptom unless the disease has "Inorganic
Biology".
- The transmission methods for diseases require organs to work but
robotic organs are immune. (except inorganic biology) Airborne disease
transmission require lungs. Ingested (drunk or eaten) disease
transmission requires a stomach. Blood (inject or patch) disease
transmission requires a heart.
- Organs removed from a mob that is afflicted with a disease will be
infectious while handling or transplanting it. (again, robotic organs
are immune unless inorganic biology is present) Certain admin spawned or
special diseases are exempt from this transmission method.
- A stomach is required for nebula nausea, gastritium, carpellosis,
metabolic boost, vomit, weight loss, death sandwich poisoning,
- Lungs are required for choking, asphyxiation, cough, cold9, oxygen
restoration, sneezing, flu, cold, spanish flu, tuberculosis
- A liver is required for tissue hydration, plasma fixation, parasitic
infection
- Ears are required for deafness, sensory restoration
- A heart is required for toxolysis, heart failure
- Eyes are required for sensory restoration, hyphema
- A tongue is required for voice change, parrot possession, pierrot
throat
- Wizarditis no longer requires a head (wtf?) to function

## Why It's Good For The Game

Robotic organs should behave as intended. Not naturally healing (like
organic organs) was supposed to be their downside to counteract their
their ability to not decay upon death.

## Changelog

🆑
fix: Fix robotic organs to not gain health passively, from revival,
smart organ fridge, pluxium, occuline, and earmuffs.
add: Some diseases now require the appropriate internal organ to work. A
robotic organ will give immunity to the disease symptom unless the
disease has "Inorganic Biology".
add: Disease transmission methods now require an internal organ to be
successful. Robotic organs give immunity. (except inorganic biology)
Airborne disease transmission require lungs. Ingested (drunk or eaten)
disease transmission requires a stomach. Blood (inject or patch) disease
transmission requires a heart.
add: Organs removed from a mob that is afflicted with a disease will be
infectious while handling or transplanting it. (again, robotic organs
are immune unless inorganic biology is present) Certain admin spawned or
special diseases are exempt from this transmission method.
add: A stomach is required for nebula nausea, gastritium, carpellosis,
metabolic boost, vomit, weight loss, death sandwich poisoning
add: Lungs are required for choking, asphyxiation, cough, cold9, oxygen
restoration, sneezing, flu, cold, spanish flu, tuberculosis
add: A liver is required for tissue hydration, plasma fixation,
parasitic infection
add: Ears are required for deafness, sensory restoration
add: A heart is required for toxolysis, heart failure
add: Eyes are required for sensory restoration, hyphema
add: A tongue is required for voice change, pierrot throat
bal: Remove head requirement for wizarditis disease
/🆑

---------

Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
This commit is contained in:
Tim
2023-07-21 11:55:29 +01:00
committed by GitHub
co-authored by MrMelbert
parent ec3e558204
commit e3d68c0236
41 changed files with 269 additions and 160 deletions
+22 -4
View File
@@ -43,9 +43,19 @@
RegisterSignal(parent, COMSIG_PILL_CONSUMED, PROC_REF(try_infect_eat))
if(istype(parent, /obj/item/reagent_containers/cup))
RegisterSignal(parent, COMSIG_GLASS_DRANK, PROC_REF(try_infect_drink))
if(isorgan(parent))
RegisterSignal(parent, COMSIG_ORGAN_IMPLANTED, PROC_REF(on_organ_insertion))
else if(istype(parent, /obj/effect/decal/cleanable/blood/gibs))
RegisterSignal(parent, COMSIG_GIBS_STREAK, PROC_REF(try_infect_streak))
/datum/component/infective/proc/on_organ_insertion(obj/item/organ/target, mob/living/carbon/receiver)
SIGNAL_HANDLER
for(var/datum/disease/disease in diseases)
receiver.ForceContractDisease(disease)
qdel(src) // once organ is implanted delete the infective component
/datum/component/infective/proc/try_infect_eat(datum/source, mob/living/eater, mob/living/feeder)
SIGNAL_HANDLER
@@ -55,19 +65,27 @@
if(is_weak && !prob(weak_infection_chance))
return
for(var/V in diseases)
eater.ForceContractDisease(V)
for(var/datum/disease/disease in diseases)
if(!disease.has_required_infectious_organ(eater, ORGAN_SLOT_STOMACH))
continue
eater.ForceContractDisease(disease)
try_infect(feeder, BODY_ZONE_L_ARM)
/datum/component/infective/proc/try_infect_drink(datum/source, mob/living/drinker, mob/living/feeder)
SIGNAL_HANDLER
for(var/disease in diseases)
drinker.ForceContractDisease(disease)
var/appendage_zone = feeder.held_items.Find(source)
appendage_zone = appendage_zone == 0 ? BODY_ZONE_CHEST : appendage_zone % 2 ? BODY_ZONE_R_ARM : BODY_ZONE_L_ARM
try_infect(feeder, appendage_zone)
for(var/datum/disease/disease in diseases)
if(!disease.has_required_infectious_organ(drinker, ORGAN_SLOT_STOMACH))
continue
drinker.ForceContractDisease(disease)
/datum/component/infective/proc/clean(datum/source, clean_types)
SIGNAL_HANDLER
+10 -6
View File
@@ -101,11 +101,15 @@
if(((disease.spread_flags & DISEASE_SPREAD_AIRBORNE) || force_spread) && prob((50*disease.spreading_modifier) - 1))
ForceContractDisease(disease)
/mob/living/carbon/AirborneContractDisease(datum/disease/D, force_spread)
/mob/living/carbon/AirborneContractDisease(datum/disease/disease, force_spread)
if(internal)
return
if(HAS_TRAIT(src, TRAIT_NOBREATH))
return
if(!disease.has_required_infectious_organ(src, ORGAN_SLOT_LUNGS))
return
..()
@@ -122,14 +126,14 @@
return TRUE
/mob/living/carbon/human/CanContractDisease(datum/disease/D)
/mob/living/carbon/human/CanContractDisease(datum/disease/disease)
if(dna)
if(HAS_TRAIT(src, TRAIT_VIRUSIMMUNE) && !D.bypasses_immunity)
if(HAS_TRAIT(src, TRAIT_VIRUSIMMUNE) && !disease.bypasses_immunity)
return FALSE
if(disease.required_organ)
if(!disease.has_required_infectious_organ(src, disease.required_organ))
return FALSE
for(var/thing in D.required_organs)
if(!((locate(thing) in bodyparts) || (locate(thing) in organs)))
return FALSE
return ..()
/mob/living/proc/CanSpreadAirborneDisease()
+22 -3
View File
@@ -30,7 +30,8 @@
var/bypasses_immunity = FALSE //Does it skip species virus immunity check? Some things may diseases and not viruses
var/spreading_modifier = 1
var/severity = DISEASE_SEVERITY_NONTHREAT
var/list/required_organs = list()
/// If the disease requires an organ for the effects to function, robotic organs are immune to disease unless inorganic biology symptom is present
var/required_organ
var/needs_all_cures = TRUE
var/list/strain_data = list() //dna_spread special bullshit
var/infectable_biotypes = MOB_ORGANIC //if the disease can spread on organics, synthetics, or undead
@@ -61,11 +62,14 @@
var/turf/source_turf = get_turf(infectee)
log_virus("[key_name(infectee)] was infected by virus: [src.admin_details()] at [loc_name(source_turf)]")
///Proc to process the disease and decide on whether to advance, cure or make the sympthoms appear. Returns a boolean on whether to continue acting on the symptoms or not.
/datum/disease/proc/stage_act(seconds_per_tick, times_fired)
var/slowdown = HAS_TRAIT(affected_mob, TRAIT_VIRUS_RESISTANCE) ? 0.5 : 1 // spaceacillin slows stage speed by 50%
if(required_organ)
if(!has_required_infectious_organ(affected_mob, required_organ))
return FALSE
if(has_cure())
if(disease_flags & CHRONIC && SPT_PROB(cure_chance, seconds_per_tick))
update_stage(1)
@@ -149,7 +153,7 @@
//note that stage is not copied over - the copy starts over at stage 1
var/static/list/copy_vars = list("name", "visibility_flags", "disease_flags", "spread_flags", "form", "desc", "agent", "spread_text",
"cure_text", "max_stages", "stage_prob", "viable_mobtypes", "cures", "infectivity", "cure_chance",
"bypasses_immunity", "spreading_modifier", "severity", "required_organs", "needs_all_cures", "strain_data",
"required_organ", "bypasses_immunity", "spreading_modifier", "severity", "needs_all_cures", "strain_data",
"infectable_biotypes", "process_dead")
var/datum/disease/D = copy_type ? new copy_type() : new type()
@@ -193,6 +197,21 @@
return FALSE
/// Checks if the mob has the required organ and it's not robotic or affected by inorganic biology
/datum/disease/proc/has_required_infectious_organ(mob/living/carbon/target, required_organ_slot)
if(!iscarbon(target))
return FALSE
var/obj/item/organ/target_organ = target.get_organ_slot(required_organ_slot)
if(!istype(target_organ))
return FALSE
// robotic organs are immune to disease unless 'inorganic biology' symptom is present
if(IS_ROBOTIC_ORGAN(target_organ) && !(infectable_biotypes & MOB_ROBOTIC))
return FALSE
return TRUE
//Use this to compare severities
/proc/get_disease_severity_value(severity)
switch(severity)
@@ -8,9 +8,9 @@
agent = "Carp Ella"
cures = list(/datum/reagent/carpet)
viable_mobtypes = list(/mob/living/carbon/human)
required_organs = list(/obj/item/organ/internal/stomach)
spread_flags = DISEASE_SPREAD_NON_CONTAGIOUS
severity = DISEASE_SEVERITY_MEDIUM
required_organ = ORGAN_SLOT_STOMACH
max_stages = 5
/// The chance of Carp Ella to spawn on cure
var/ella_spawn_chance = 10
@@ -6,10 +6,10 @@
agent = "Atmobacter Polyri"
cures = list(/datum/reagent/firefighting_foam)
viable_mobtypes = list(/mob/living/carbon/human)
required_organs = list(/obj/item/organ/internal/stomach)
spread_flags = DISEASE_SPREAD_NON_CONTAGIOUS
severity = DISEASE_SEVERITY_HARMFUL
max_stages = 5
required_organ = ORGAN_SLOT_STOMACH
/// The chance of burped out tritium to be hot during max stage
var/tritium_burp_hot_chance = 10
@@ -6,9 +6,9 @@
agent = "Stars"
cures = list(/datum/reagent/bluespace)
viable_mobtypes = list(/mob/living/carbon/human)
required_organs = list(/obj/item/organ/internal/stomach)
spread_flags = DISEASE_SPREAD_NON_CONTAGIOUS
severity = DISEASE_SEVERITY_MEDIUM
required_organ = ORGAN_SLOT_STOMACH
max_stages = 5
/datum/disease/advance/nebula_nausea/New()
@@ -20,6 +20,7 @@
base_message_chance = 15
symptom_delay_min = 10
symptom_delay_max = 30
required_organ = ORGAN_SLOT_LUNGS
threshold_descs = list(
"Stage Speed 8" = "Causes choking more frequently.",
"Stealth 4" = "The symptom remains hidden until active."
@@ -35,26 +36,28 @@
if(A.totalStealth() >= 4)
suppress_warning = TRUE
/datum/symptom/choking/Activate(datum/disease/advance/A)
/datum/symptom/choking/Activate(datum/disease/advance/advanced_disease)
. = ..()
if(!.)
return
var/mob/living/M = A.affected_mob
switch(A.stage)
var/mob/living/carbon/infected_mob = advanced_disease.affected_mob
switch(advanced_disease.stage)
if(1, 2)
if(prob(base_message_chance) && !suppress_warning)
to_chat(M, span_warning("[pick("You're having difficulty breathing.", "Your breathing becomes heavy.")]"))
to_chat(infected_mob, span_warning("[pick("You're having difficulty breathing.", "Your breathing becomes heavy.")]"))
if(3, 4)
if(!suppress_warning)
to_chat(M, span_warning("[pick("Your windpipe feels like a straw.", "Your breathing becomes tremendously difficult.")]"))
to_chat(infected_mob, span_warning("[pick("Your windpipe feels like a straw.", "Your breathing becomes tremendously difficult.")]"))
else
to_chat(M, span_warning("You feel very [pick("dizzy","woozy","faint")].")) //fake bloodloss messages
Choke_stage_3_4(M, A)
M.emote("gasp")
to_chat(infected_mob, span_warning("You feel very [pick("dizzy","woozy","faint")].")) //fake bloodloss messages
Choke_stage_3_4(infected_mob, advanced_disease)
infected_mob.emote("gasp")
else
to_chat(M, span_userdanger("[pick("You're choking!", "You can't breathe!")]"))
Choke(M, A)
M.emote("gasp")
to_chat(infected_mob, span_userdanger("[pick("You're choking!", "You can't breathe!")]"))
Choke(infected_mob, advanced_disease)
infected_mob.emote("gasp")
/datum/symptom/choking/proc/Choke_stage_3_4(mob/living/M, datum/disease/advance/A)
M.adjustOxyLoss(rand(6,13))
@@ -82,7 +85,6 @@ Bonus
*/
/datum/symptom/asphyxiation
name = "Acute respiratory distress syndrome"
desc = "The virus causes shrinking of the host's lungs, causing severe asphyxiation. May also lead to heart attacks."
illness = "Iron Lungs"
@@ -95,11 +97,12 @@ Bonus
base_message_chance = 15
symptom_delay_min = 14
symptom_delay_max = 30
var/paralysis = FALSE
required_organ = ORGAN_SLOT_LUNGS
threshold_descs = list(
"Stage Speed 8" = "Additionally synthesizes pancuronium and sodium thiopental inside the host.",
"Transmission 8" = "Doubles the damage caused by the symptom."
)
var/paralysis = FALSE
/datum/symptom/asphyxiation/Start(datum/disease/advance/A)
@@ -19,7 +19,7 @@
base_message_chance = 15
symptom_delay_min = 2
symptom_delay_max = 15
var/spread_range = 1
required_organ = ORGAN_SLOT_LUNGS
threshold_descs = list(
"Resistance 11" = "The host will drop small items when coughing.",
"Resistance 15" = "Occasionally causes coughing fits that stun the host. The extra coughs do not spread the virus.",
@@ -31,6 +31,7 @@
COOLDOWN_DECLARE(cough_cooldown)
///if FALSE, there is a percentage chance that the mob will emote coughing while cough_cooldown is on cooldown. If TRUE, won't emote again until after the off cooldown cough occurs.
var/off_cooldown_coughed = FALSE
var/spread_range = 1
/datum/symptom/cough/Start(datum/disease/advance/active_disease)
. = ..()
@@ -19,6 +19,7 @@
base_message_chance = 100
symptom_delay_min = 25
symptom_delay_max = 80
required_organ = ORGAN_SLOT_EARS
threshold_descs = list(
"Resistance 9" = "Causes permanent deafness, instead of intermittent.",
"Stealth 4" = "The symptom remains hidden until active.",
@@ -38,15 +39,15 @@
REMOVE_TRAIT(advanced_disease.affected_mob, TRAIT_DEAF, DISEASE_TRAIT)
return ..()
/datum/symptom/deafness/Activate(datum/disease/advance/A)
/datum/symptom/deafness/Activate(datum/disease/advance/advanced_disease)
. = ..()
if(!.)
return
var/mob/living/carbon/infected_mob = A.affected_mob
var/mob/living/carbon/infected_mob = advanced_disease.affected_mob
var/obj/item/organ/internal/ears/ears = infected_mob.get_organ_slot(ORGAN_SLOT_EARS)
if(!ears)
return //cutting off your ears to cure the deafness: the ultimate own
switch(A.stage)
switch(advanced_disease.stage)
if(3, 4)
if(prob(base_message_chance) && !suppress_warning)
to_chat(infected_mob, span_warning("[pick("You hear a ringing in your ear.", "Your ears pop.")]"))
@@ -8,7 +8,6 @@
*/
/datum/symptom/dizzy // Not the egg
name = "Dizziness"
desc = "The virus causes inflammation of the vestibular system, leading to bouts of dizziness."
illness = "Motion Sickness"
+49 -45
View File
@@ -11,7 +11,6 @@
symptom_delay_max = 1
var/passive_message = "" //random message to infected but not actively healing people
/datum/symptom/heal/Activate(datum/disease/advance/A)
. = ..()
if(!.)
@@ -181,17 +180,18 @@
*/
/datum/symptom/heal/chem
name = "Toxolysis"
desc = "The virus rapidly breaks down any foreign chemicals in the bloodstream."
stealth = 0
resistance = -2
stage_speed = 2
transmittable = -2
level = 7
var/food_conversion = FALSE
desc = "The virus rapidly breaks down any foreign chemicals in the bloodstream."
required_organ = ORGAN_SLOT_HEART
threshold_descs = list(
"Resistance 7" = "Increases chem removal speed.",
"Stage Speed 6" = "Consumed chemicals nourish the host.",
)
var/food_conversion = FALSE
/datum/symptom/heal/chem/Start(datum/disease/advance/A)
. = ..()
@@ -222,19 +222,20 @@
*/
/datum/symptom/heal/metabolism
name = "Metabolic Boost"
desc = "The virus causes the host's metabolism to accelerate rapidly, making them process chemicals twice as fast,\
but also causing increased hunger."
stealth = -1
resistance = -2
stage_speed = 2
transmittable = 1
level = 7
var/triple_metabolism = FALSE
var/reduced_hunger = FALSE
desc = "The virus causes the host's metabolism to accelerate rapidly, making them process chemicals twice as fast,\
but also causing increased hunger."
required_organ = ORGAN_SLOT_STOMACH
threshold_descs = list(
"Stealth 3" = "Reduces hunger rate.",
"Stage Speed 10" = "Chemical metabolization is tripled instead of doubled.",
)
var/triple_metabolism = FALSE
var/reduced_hunger = FALSE
/datum/symptom/heal/metabolism/Start(datum/disease/advance/A)
. = ..()
@@ -245,17 +246,16 @@
if(A.totalStealth() >= 3)
reduced_hunger = TRUE
/datum/symptom/heal/metabolism/Heal(mob/living/carbon/C, datum/disease/advance/A, actual_power)
if(!istype(C))
return
/datum/symptom/heal/metabolism/Heal(mob/living/carbon/infected_mob, datum/disease/advance/A, actual_power)
var/metabolic_boost = triple_metabolism ? 2 : 1
C.reagents.metabolize(C, metabolic_boost * SSMOBS_DT, 0, can_overdose=TRUE) //this works even without a liver; it's intentional since the virus is metabolizing by itself
C.overeatduration = max(C.overeatduration - 4 SECONDS, 0)
infected_mob.reagents.metabolize(infected_mob, metabolic_boost * SSMOBS_DT, 0, can_overdose=TRUE) //this works even without a liver; it's intentional since the virus is metabolizing by itself
infected_mob.overeatduration = max(infected_mob.overeatduration - 4 SECONDS, 0)
var/lost_nutrition = 9 - (reduced_hunger * 5)
C.adjust_nutrition(-lost_nutrition * HUNGER_FACTOR) //Hunger depletes at 10x the normal speed
infected_mob.adjust_nutrition(-lost_nutrition * HUNGER_FACTOR) //Hunger depletes at 10x the normal speed
if(prob(2))
to_chat(C, span_notice("You feel an odd gurgle in your stomach, as if it was working much faster than normal."))
return 1
to_chat(infected_mob, span_notice("You feel an odd gurgle in your stomach, as if it was working much faster than normal."))
return TRUE
/*Nocturnal Regeneration
* Increases stealth
* Slightly reduces resistance
@@ -312,6 +312,7 @@
if(M.getBruteLoss() || M.getFireLoss())
return TRUE
return FALSE
/*Regen Coma
* No effect on stealth
* Increases resistance
@@ -427,11 +428,12 @@
transmittable = 1
level = 6
passive_message = span_notice("Your skin feels oddly dry...")
var/absorption_coeff = 1
required_organ = ORGAN_SLOT_LIVER
threshold_descs = list(
"Resistance 5" = "Water is consumed at a much slower rate.",
"Stage Speed 7" = "Increases healing speed.",
)
var/absorption_coeff = 1
/datum/symptom/heal/water/Start(datum/disease/advance/A)
. = ..()
@@ -442,17 +444,18 @@
if(A.totalResistance() >= 5)
absorption_coeff = 0.25
/datum/symptom/heal/water/CanHeal(datum/disease/advance/A)
/datum/symptom/heal/water/CanHeal(datum/disease/advance/advanced_disease)
. = 0
var/mob/living/M = A.affected_mob
if(M.fire_stacks < 0)
M.adjust_fire_stacks(min(absorption_coeff, -M.fire_stacks))
var/mob/living/carbon/infected_mob = advanced_disease.affected_mob
if(infected_mob.fire_stacks < 0)
infected_mob.adjust_fire_stacks(min(absorption_coeff, -infected_mob.fire_stacks))
. += power
if(M.reagents.has_reagent(/datum/reagent/water/holywater, needs_metabolizing = FALSE))
M.reagents.remove_reagent(/datum/reagent/water/holywater, 0.5 * absorption_coeff)
if(infected_mob.reagents.has_reagent(/datum/reagent/water/holywater, needs_metabolizing = FALSE))
infected_mob.reagents.remove_reagent(/datum/reagent/water/holywater, 0.5 * absorption_coeff)
. += power * 0.75
else if(M.reagents.has_reagent(/datum/reagent/water, needs_metabolizing = FALSE))
M.reagents.remove_reagent(/datum/reagent/water, 0.5 * absorption_coeff)
else if(infected_mob.reagents.has_reagent(/datum/reagent/water, needs_metabolizing = FALSE))
infected_mob.reagents.remove_reagent(/datum/reagent/water, 0.5 * absorption_coeff)
. += power * 0.5
/datum/symptom/heal/water/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
@@ -472,9 +475,10 @@
return 1
/datum/symptom/heal/water/passive_message_condition(mob/living/M)
if(M.getBruteLoss() || M.getFireLoss())
/datum/symptom/heal/water/passive_message_condition(mob/living/carbon/infected_mob)
if(infected_mob.getBruteLoss() || infected_mob.getFireLoss())
return TRUE
return FALSE
/// Determines the rate at which Plasma Fixation heals based on the amount of plasma in the air
@@ -499,11 +503,12 @@
transmittable = -2
level = 8
passive_message = span_notice("You feel an odd attraction to plasma.")
var/temp_rate = 1
required_organ = ORGAN_SLOT_LIVER
threshold_descs = list(
"Transmission 6" = "Increases temperature adjustment rate.",
"Stage Speed 7" = "Increases healing speed.",
)
var/temp_rate = 1
/datum/symptom/heal/plasma/Start(datum/disease/advance/A)
. = ..()
@@ -535,7 +540,7 @@
// Check internals breath, environmental plasma, and plasma in bloodstream to determine the heal power
/datum/symptom/heal/plasma/CanHeal(datum/disease/advance/advanced_disease)
var/mob/living/diseased_mob = advanced_disease.affected_mob
var/mob/living/carbon/infected_mob = advanced_disease.affected_mob
var/datum/gas_mixture/environment
var/list/gases
@@ -545,24 +550,23 @@
/// the amount of mols in a breath is significantly lower than in the environment so we are just going to use the tank's
/// distribution pressure as an abstraction rather than calculate it using the ideal gas equation.
/// balanced around a tank set to 4kpa = about 0.2 healing power. maxes out at 0.75 healing power, or 15kpa.
if(iscarbon(diseased_mob))
var/mob/living/carbon/breather = diseased_mob
var/obj/item/tank/internals/internals_tank = breather.internal
if(internals_tank)
var/datum/gas_mixture/tank_contents = internals_tank.return_air()
if(tank_contents && round(tank_contents.return_pressure())) // make sure the tank is not empty or 0 pressure
if(tank_contents.gases[/datum/gas/plasma])
// higher tank distribution pressure leads to more healing, but once you get to about 15kpa you reach the max
. += power * min(MAX_HEAL_COEFFICIENT_INTERNALS, internals_tank.distribute_pressure * HEALING_PER_BREATH_PRESSURE)
// Check environment
if(diseased_mob.loc)
environment = diseased_mob.loc.return_air()
if(environment)
gases = environment.gases
if(gases[/datum/gas/plasma])
. += power * min(MAX_HEAL_COEFFICIENT_INTERNALS, gases[/datum/gas/plasma][MOLES] * HEALING_PER_MOL)
var/obj/item/tank/internals/internals_tank = infected_mob.internal
if(internals_tank)
var/datum/gas_mixture/tank_contents = internals_tank.return_air()
if(tank_contents && round(tank_contents.return_pressure())) // make sure the tank is not empty or 0 pressure
if(tank_contents.gases[/datum/gas/plasma])
// higher tank distribution pressure leads to more healing, but once you get to about 15kpa you reach the max
. += power * min(MAX_HEAL_COEFFICIENT_INTERNALS, internals_tank.distribute_pressure * HEALING_PER_BREATH_PRESSURE)
else // Check environment
if(infected_mob.loc)
environment = infected_mob.loc.return_air()
if(environment)
gases = environment.gases
if(gases[/datum/gas/plasma])
. += power * min(MAX_HEAL_COEFFICIENT_INTERNALS, gases[/datum/gas/plasma][MOLES] * HEALING_PER_MOL)
// Check for reagents in bloodstream
if(diseased_mob.reagents.has_reagent(/datum/reagent/toxin/plasma, needs_metabolizing = TRUE))
if(infected_mob.reagents.has_reagent(/datum/reagent/toxin/plasma, needs_metabolizing = TRUE))
. += power * MAX_HEAL_COEFFICIENT_BLOODSTREAM //Determines how much the symptom heals if injected or ingested
/datum/symptom/heal/plasma/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
@@ -17,10 +17,11 @@
base_message_chance = 5
symptom_delay_min = 1
symptom_delay_max = 1
var/regenerate_blood = FALSE
required_organ = ORGAN_SLOT_LUNGS
threshold_descs = list(
"Resistance 8" = "Additionally regenerates lost blood."
)
var/regenerate_blood = FALSE
/datum/symptom/oxygen/Start(datum/disease/advance/A)
. = ..()
@@ -29,20 +30,21 @@
if(A.totalResistance() >= 8) //blood regeneration
regenerate_blood = TRUE
/datum/symptom/oxygen/Activate(datum/disease/advance/A)
/datum/symptom/oxygen/Activate(datum/disease/advance/advanced_disease)
. = ..()
if(!.)
return
var/mob/living/carbon/M = A.affected_mob
switch(A.stage)
var/mob/living/carbon/infected_mob = advanced_disease.affected_mob
switch(advanced_disease.stage)
if(4, 5)
M.adjustOxyLoss(-7, 0)
M.losebreath = max(0, M.losebreath - 4)
if(regenerate_blood && M.blood_volume < BLOOD_VOLUME_NORMAL)
M.blood_volume += 1
infected_mob.adjustOxyLoss(-7, 0)
infected_mob.losebreath = max(0, infected_mob.losebreath - 4)
if(regenerate_blood && infected_mob.blood_volume < BLOOD_VOLUME_NORMAL)
infected_mob.blood_volume += 1
else
if(prob(base_message_chance))
to_chat(M, span_notice("[pick("Your lungs feel great.", "You realize you haven't been breathing.", "You don't feel the need to breathe.")]"))
to_chat(infected_mob, span_notice("[pick("Your lungs feel great.", "You realize you haven't been breathing.", "You don't feel the need to breathe.")]"))
return
/datum/symptom/oxygen/on_stage_change(datum/disease/advance/A)
@@ -87,34 +87,34 @@
symptom_delay_min = 1
symptom_delay_max = 1
/datum/symptom/sensory_restoration/Activate(datum/disease/advance/source_disease)
/datum/symptom/sensory_restoration/Activate(datum/disease/advance/advanced_disease)
. = ..()
if(!.)
return
var/mob/living/carbon/ill_mob = source_disease.affected_mob
switch(source_disease.stage)
var/mob/living/carbon/infected_mob = advanced_disease.affected_mob
switch(advanced_disease.stage)
if(4, 5)
var/obj/item/organ/internal/ears/ears = ill_mob.get_organ_slot(ORGAN_SLOT_EARS)
if(ears)
if(advanced_disease.has_required_infectious_organ(infected_mob, ORGAN_SLOT_EARS))
var/obj/item/organ/internal/ears/ears = infected_mob.get_organ_slot(ORGAN_SLOT_EARS)
ears.adjustEarDamage(-4, -4)
ill_mob.adjust_temp_blindness(-4 SECONDS)
ill_mob.adjust_eye_blur(-4 SECONDS)
var/obj/item/organ/internal/eyes/eyes = ill_mob.get_organ_slot(ORGAN_SLOT_EYES)
if(!eyes) // only dealing with eye stuff from here on out
if(!advanced_disease.has_required_infectious_organ(infected_mob, ORGAN_SLOT_EYES))
return
var/obj/item/organ/internal/eyes/eyes = infected_mob.get_organ_slot(ORGAN_SLOT_EYES)
infected_mob.adjust_temp_blindness(-4 SECONDS)
infected_mob.adjust_eye_blur(-4 SECONDS)
eyes.apply_organ_damage(-2)
if(prob(20))
if(ill_mob.is_blind_from(EYE_DAMAGE))
to_chat(ill_mob, span_warning("Your vision slowly returns..."))
ill_mob.adjust_eye_blur(20 SECONDS)
if(infected_mob.is_blind_from(EYE_DAMAGE))
to_chat(infected_mob, span_warning("Your vision slowly returns..."))
infected_mob.adjust_eye_blur(20 SECONDS)
else if(ill_mob.is_nearsighted_from(EYE_DAMAGE))
to_chat(ill_mob, span_warning("The blackness in your peripheral vision begins to fade."))
ill_mob.adjust_eye_blur(5 SECONDS)
else if(infected_mob.is_nearsighted_from(EYE_DAMAGE))
to_chat(infected_mob, span_warning("The blackness in your peripheral vision begins to fade."))
infected_mob.adjust_eye_blur(5 SECONDS)
else
if(prob(base_message_chance))
to_chat(ill_mob, span_notice("[pick("Your eyes feel great.","You feel like your eyes can focus more clearly.", "You don't feel the need to blink.","Your ears feel great.","Your hearing feels more acute.")]"))
to_chat(infected_mob, span_notice("[pick("Your eyes feel great.","You feel like your eyes can focus more clearly.", "You don't feel the need to blink.","Your ears feel great.","Your hearing feels more acute.")]"))
@@ -18,8 +18,7 @@
severity = 1
symptom_delay_min = 5
symptom_delay_max = 35
var/spread_range = 4
var/cartoon_sneezing = FALSE //ah, ah, AH, AH-CHOO!!
required_organ = ORGAN_SLOT_LUNGS
threshold_descs = list(
"Transmission 9" = "Increases sneezing range, spreading the virus over 6 meter cone instead of over a 4 meter cone.",
"Stealth 4" = "The symptom remains hidden until active.",
@@ -27,6 +26,8 @@
)
///Emote cooldowns
COOLDOWN_DECLARE(sneeze_cooldown)
var/spread_range = 4
var/cartoon_sneezing = FALSE //ah, ah, AH, AH-CHOO!!
///if FALSE, there is a percentage chance that the mob will emote sneezing while sneeze_cooldown is on cooldown. If TRUE, won't emote again until after the off cooldown sneeze occurs.
var/off_cooldown_sneezed = FALSE
@@ -37,6 +37,8 @@
var/list/thresholds
///If this symptom can appear from /datum/disease/advance/GenerateSymptoms()
var/naturally_occuring = TRUE
///If the symptom requires an organ for the effects to function, robotic organs are immune to disease unless inorganic biology symptom is present
var/required_organ
/datum/symptom/New()
var/list/S = SSdisease.list_symptoms
@@ -58,9 +60,13 @@
return FALSE
return TRUE
/datum/symptom/proc/Activate(datum/disease/advance/A)
/datum/symptom/proc/Activate(datum/disease/advance/advanced_disease)
if(neutered)
return FALSE
if(required_organ)
if(!advanced_disease.has_required_infectious_organ(advanced_disease.affected_mob, required_organ))
return FALSE
if(world.time < next_activation)
return FALSE
else
+16 -17
View File
@@ -19,11 +19,11 @@
base_message_chance = 50
symptom_delay_min = 25
symptom_delay_max = 80
required_organ = ORGAN_SLOT_EYES
threshold_descs = list(
"Resistance 12" = "Weakens extraocular muscles, eventually leading to complete detachment of the eyes.",
"Stealth 4" = "The symptom remains hidden until active.",
)
/// At max stage: If FALSE, cause blindness. If TRUE, cause their eyes to fall out.
var/remove_eyes = FALSE
@@ -40,41 +40,40 @@
. = ..()
if(!.)
return
var/mob/living/carbon/ill_mob = source_disease.affected_mob
var/obj/item/organ/internal/eyes/eyes = ill_mob.get_organ_slot(ORGAN_SLOT_EYES)
if(!eyes)
return // can't do much
var/mob/living/carbon/infected_mob = source_disease.affected_mob
var/obj/item/organ/internal/eyes/eyes = infected_mob.get_organ_slot(ORGAN_SLOT_EYES)
switch(source_disease.stage)
if(1, 2)
if(prob(base_message_chance) && !suppress_warning)
to_chat(ill_mob, span_warning("Your eyes itch."))
to_chat(infected_mob, span_warning("Your eyes itch."))
if(3, 4)
to_chat(ill_mob, span_boldwarning("Your eyes burn!"))
ill_mob.set_eye_blur_if_lower(20 SECONDS)
to_chat(infected_mob, span_boldwarning("Your eyes burn!"))
infected_mob.set_eye_blur_if_lower(20 SECONDS)
eyes.apply_organ_damage(1)
else
ill_mob.set_eye_blur_if_lower(40 SECONDS)
infected_mob.set_eye_blur_if_lower(40 SECONDS)
eyes.apply_organ_damage(5)
// Applies nearsighted at minimum
if(!ill_mob.is_nearsighted_from(EYE_DAMAGE) && eyes.damage <= eyes.low_threshold)
if(!infected_mob.is_nearsighted_from(EYE_DAMAGE) && eyes.damage <= eyes.low_threshold)
eyes.set_organ_damage(eyes.low_threshold)
if(prob(eyes.damage - eyes.low_threshold + 1))
if(remove_eyes)
ill_mob.visible_message(
span_warning("[ill_mob]'s eyes fall out of their sockets!"),
infected_mob.visible_message(
span_warning("[infected_mob]'s eyes fall out of their sockets!"),
span_userdanger("Your eyes fall out of their sockets!"),
)
eyes.Remove(ill_mob)
eyes.forceMove(get_turf(ill_mob))
eyes.Remove(infected_mob)
eyes.forceMove(get_turf(infected_mob))
else if(!ill_mob.is_blind_from(EYE_DAMAGE))
to_chat(ill_mob, span_userdanger("You go blind!"))
else if(!infected_mob.is_blind_from(EYE_DAMAGE))
to_chat(infected_mob, span_userdanger("You go blind!"))
eyes.apply_organ_damage(eyes.maxHealth)
else
to_chat(ill_mob, span_userdanger("Your eyes burn horrifically!"))
to_chat(infected_mob, span_userdanger("Your eyes burn horrifically!"))
@@ -20,13 +20,14 @@
base_message_chance = 100
symptom_delay_min = 60
symptom_delay_max = 120
var/scramble_language = FALSE
var/datum/language/current_language
required_organ = ORGAN_SLOT_TONGUE
threshold_descs = list(
"Transmission 14" = "The host's language center of the brain is damaged, leading to complete inability to speak or understand any language.",
"Stage Speed 7" = "Changes voice more often.",
"Stealth 3" = "The symptom remains hidden until active."
)
var/scramble_language = FALSE
var/datum/language/current_language
/datum/symptom/voice_change/Start(datum/disease/advance/A)
. = ..()
@@ -20,14 +20,15 @@ and your disease can spread via people walking on vomit.
base_message_chance = 100
symptom_delay_min = 25
symptom_delay_max = 80
var/vomit_nebula = FALSE
var/vomit_blood = FALSE
var/proj_vomit = 0
required_organ = ORGAN_SLOT_STOMACH
threshold_descs = list(
"Resistance 7" = "Host will vomit blood, causing internal damage.",
"Transmission 7" = "Host will projectile vomit, increasing vomiting range.",
"Stealth 4" = "The symptom remains hidden until active."
)
var/vomit_nebula = FALSE
var/vomit_blood = FALSE
var/proj_vomit = 0
/datum/symptom/vomit/Start(datum/disease/advance/A)
. = ..()
@@ -18,6 +18,7 @@
base_message_chance = 100
symptom_delay_min = 15
symptom_delay_max = 45
required_organ = ORGAN_SLOT_STOMACH
threshold_descs = list(
"Stealth 4" = "The symptom is less noticeable."
)
+1 -2
View File
@@ -9,10 +9,9 @@
viable_mobtypes = list(/mob/living/carbon/human)
cure_chance = 7.5 //higher chance to cure, since two reagents are required
desc = "This disease destroys the braincells, causing brain fever, brain necrosis and general intoxication."
required_organs = list(/obj/item/organ/internal/brain)
required_organ = ORGAN_SLOT_BRAIN
severity = DISEASE_SEVERITY_HARMFUL
/datum/disease/brainrot/stage_act(seconds_per_tick, times_fired) //Removed toxloss because damaging diseases are pretty horrible. Last round it killed the entire station because the cure didn't work -- Urist -ACTUALLY Removed rather than commented out, I don't see it returning - RR
. = ..()
if(!.)
+1
View File
@@ -9,6 +9,7 @@
spreading_modifier = 0.5
spread_text = "Airborne"
severity = DISEASE_SEVERITY_NONTHREAT
required_organ = ORGAN_SLOT_LUNGS
/datum/disease/cold/stage_act(seconds_per_tick, times_fired)
+1 -1
View File
@@ -9,7 +9,7 @@
viable_mobtypes = list(/mob/living/carbon/human)
desc = "If left untreated the subject will slow, as if partly frozen."
severity = DISEASE_SEVERITY_HARMFUL
required_organ = ORGAN_SLOT_LUNGS
/datum/disease/cold9/stage_act(seconds_per_tick, times_fired)
. = ..()
@@ -14,7 +14,7 @@
spread_flags = DISEASE_SPREAD_SPECIAL
visibility_flags = HIDDEN_SCANNER
bypasses_immunity = TRUE
required_organ = ORGAN_SLOT_STOMACH
/datum/disease/death_sandwich_poisoning/stage_act(seconds_per_tick, times_fired)
. = ..()
+1 -1
View File
@@ -10,7 +10,7 @@
spreading_modifier = 0.75
desc = "If left untreated the subject will feel quite unwell."
severity = DISEASE_SEVERITY_MINOR
required_organ = ORGAN_SLOT_LUNGS
/datum/disease/flu/stage_act(seconds_per_tick, times_fired)
. = ..()
+1 -1
View File
@@ -10,7 +10,7 @@
spreading_modifier = 0.75
desc = "If left untreated the subject will burn to death for being a heretic."
severity = DISEASE_SEVERITY_DANGEROUS
required_organ = ORGAN_SLOT_LUNGS
/datum/disease/fluspanish/stage_act(seconds_per_tick, times_fired)
. = ..()
+1 -1
View File
@@ -13,7 +13,7 @@
spread_flags = DISEASE_SPREAD_NON_CONTAGIOUS
spread_text = "Organ failure"
visibility_flags = HIDDEN_PANDEMIC
required_organs = list(/obj/item/organ/internal/heart)
required_organ = ORGAN_SLOT_HEART
bypasses_immunity = TRUE // Immunity is based on not having an appendix; this isn't a virus
var/sound = FALSE
+1 -2
View File
@@ -11,10 +11,9 @@
severity = DISEASE_SEVERITY_HARMFUL
disease_flags = CAN_CARRY|CAN_RESIST
spread_flags = DISEASE_SPREAD_NON_CONTAGIOUS
required_organs = list(/obj/item/organ/internal/liver)
required_organ = ORGAN_SLOT_LIVER
bypasses_immunity = TRUE
/datum/disease/parasite/stage_act(seconds_per_tick, times_fired)
. = ..()
if(!.)
+1 -1
View File
@@ -10,7 +10,7 @@
spreading_modifier = 0.75
desc = "If left untreated the subject will probably drive others to insanity."
severity = DISEASE_SEVERITY_MEDIUM
required_organ = ORGAN_SLOT_TONGUE
/datum/disease/pierrot_throat/stage_act(seconds_per_tick, times_fired)
. = ..()
+1 -1
View File
@@ -9,7 +9,7 @@
viable_mobtypes = list(/mob/living/carbon/human)
cure_chance = 2.5 //like hell are you getting out of hell
desc = "A rare highly transmissible virulent virus. Few samples exist, rumoured to be carefully grown and cultured by clandestine bio-weapon specialists. Causes fever, blood vomiting, lung damage, weight loss, and fatigue."
required_organs = list(/obj/item/organ/internal/lungs)
required_organ = ORGAN_SLOT_LUNGS
severity = DISEASE_SEVERITY_BIOHAZARD
bypasses_immunity = TRUE // TB primarily impacts the lungs; it's also bacterial or fungal in nature; viral immunity should do nothing.
-1
View File
@@ -16,7 +16,6 @@
A gulp of strong, manly spirits usually reverts them to normal, humanlike, condition. \
A form of magical grounding can help, too, but will not cure it on its own."
severity = DISEASE_SEVERITY_HARMFUL
required_organs = list(/obj/item/bodypart/head)
/// List of random non-targeted spells to pick from to cast
var/list/datum/action/cooldown/spell/random_spells = list()
+1 -1
View File
@@ -27,7 +27,7 @@
for(var/i in user_by_item)
var/mob/living/carbon/user = user_by_item[i]
var/obj/item/organ/internal/ears/ears = user.get_organ_slot(ORGAN_SLOT_EARS)
if(!ears || !ears.damage || ears.organ_flags & ORGAN_FAILING)
if(!ears || !ears.damage || (ears.organ_flags & ORGAN_FAILING) || IS_ROBOTIC_ORGAN(ears))
continue
ears.deaf = max(ears.deaf - 0.25 * seconds_per_tick, (ears.damage < ears.maxHealth ? 0 : 1)) // Do not clear deafness if our ears are too damaged
ears.apply_organ_damage(-0.025 * seconds_per_tick)
@@ -195,7 +195,7 @@
/datum/action/changeling/sting/blind
name = "Blind Sting"
desc = "We temporarily blind our victim. Costs 25 chemicals."
helptext = "This sting completely blinds a target for a short time, and leaves them with blurred vision for a long time."
helptext = "This sting completely blinds a target for a short time, and leaves them with blurred vision for a long time. Does not work if target has robotic or missing eyes."
button_icon_state = "sting_blind"
chemical_cost = 25
dna_cost = 1
@@ -206,6 +206,10 @@
user.balloon_alert(user, "no eyes!")
return FALSE
if(IS_ROBOTIC_ORGAN(eyes))
user.balloon_alert(user, "robotic eyes!")
return FALSE
log_combat(user, target, "stung", "blind sting")
to_chat(target, span_danger("Your eyes burn horrifically!"))
eyes.apply_organ_damage(eyes.maxHealth * 0.8)
@@ -597,8 +597,11 @@
repair_rate = max(0, STANDARD_ORGAN_HEALING * (matter_bin.tier - 1) * 0.5)
/obj/machinery/smartfridge/organ/process(seconds_per_tick)
for(var/obj/item/organ/organ in contents)
organ.apply_organ_damage(-repair_rate * organ.maxHealth * seconds_per_tick)
for(var/obj/item/organ/target_organ in contents)
if(!target_organ.damage)
continue
target_organ.apply_organ_damage(-repair_rate * target_organ.maxHealth * seconds_per_tick, required_organ_flag = ORGAN_ORGANIC)
/obj/machinery/smartfridge/organ/Exited(atom/movable/gone, direction)
. = ..()
+5 -2
View File
@@ -851,8 +851,11 @@
if(dna && !HAS_TRAIT(src, TRAIT_NOBLOOD))
blood_volume += (excess_healing * 2) //1 excess = 10 blood
for(var/obj/item/organ/organ as anything in organs)
organ.apply_organ_damage(excess_healing * -1) //1 excess = 5 organ damage healed
for(var/obj/item/organ/target_organ as anything in organs)
if(!target_organ.damage)
continue
target_organ.apply_organ_damage(excess_healing * -1, required_organ_flag = ORGAN_ORGANIC) //1 excess = 5 organ damage healed
return ..()
@@ -127,7 +127,10 @@
return ..()
for(var/obj/item/organ/organ_being_healed as anything in breather.organs)
organ_being_healed.apply_organ_damage(-0.5 * REM * seconds_per_tick)
if(!organ_being_healed.damage)
continue
organ_being_healed.apply_organ_damage(-0.5 * REM * seconds_per_tick, required_organ_flag = ORGAN_ORGANIC)
return ..()
@@ -227,17 +227,17 @@
if(SPT_PROB(2.5, seconds_per_tick) && iscarbon(drinker))
var/obj/item/organ/internal/eyes/eyes = drinker.get_organ_slot(ORGAN_SLOT_EYES)
if(drinker.is_blind())
if(istype(eyes))
if(eyes && IS_ORGANIC_ORGAN(eyes)) // doesn't affect robotic eyes
if(drinker.is_blind())
eyes.Remove(drinker)
eyes.forceMove(get_turf(drinker))
to_chat(drinker, span_userdanger("You double over in pain as you feel your eyeballs liquify in your head!"))
drinker.emote("scream")
drinker.adjustBruteLoss(15, required_bodytype = affected_bodytype)
else
to_chat(drinker, span_userdanger("You scream in terror as you go blind!"))
eyes.apply_organ_damage(eyes.maxHealth)
drinker.emote("scream")
else
to_chat(drinker, span_userdanger("You scream in terror as you go blind!"))
eyes.apply_organ_damage(eyes.maxHealth)
drinker.emote("scream")
if(SPT_PROB(1.5, seconds_per_tick) && iscarbon(drinker))
drinker.visible_message(span_danger("[drinker] starts having a seizure!"), span_userdanger("You have a seizure!"))
@@ -730,7 +730,7 @@
// Healing eye damage will cure nearsightedness and blindness from ... eye damage
eyes.apply_organ_damage(-2 * REM * seconds_per_tick * normalise_creation_purity(), required_organ_flag = affected_organ_flags)
// If our eyes are seriously damaged, we have a probability of causing eye blur while healing depending on purity
if(eyes.damaged && SPT_PROB(16 - min(normalized_purity * 6, 12), seconds_per_tick))
if(eyes.damaged && IS_ORGANIC_ORGAN(eyes) && SPT_PROB(16 - min(normalized_purity * 6, 12), seconds_per_tick))
// While healing, gives some eye blur
if(affected_mob.is_blind_from(EYE_DAMAGE))
to_chat(affected_mob, span_warning("Your vision slowly returns..."))
@@ -32,9 +32,22 @@
if((strain.spread_flags & DISEASE_SPREAD_SPECIAL) || (strain.spread_flags & DISEASE_SPREAD_NON_CONTAGIOUS))
continue
if(methods & (INJECT|INGEST|PATCH))
if(methods & INGEST)
if(!strain.has_required_infectious_organ(exposed_mob, ORGAN_SLOT_STOMACH))
continue
exposed_mob.ForceContractDisease(strain)
else if((methods & (TOUCH|VAPOR)) && (strain.spread_flags & DISEASE_SPREAD_CONTACT_FLUIDS))
else if(methods & (INJECT|PATCH))
if(!strain.has_required_infectious_organ(exposed_mob, ORGAN_SLOT_HEART))
continue
exposed_mob.ForceContractDisease(strain)
else if((methods & VAPOR) && (strain.spread_flags & DISEASE_SPREAD_CONTACT_FLUIDS))
if(!strain.has_required_infectious_organ(exposed_mob, ORGAN_SLOT_LUNGS))
continue
exposed_mob.ContactContractDisease(strain)
else if((methods & TOUCH) && (strain.spread_flags & DISEASE_SPREAD_CONTACT_FLUIDS))
exposed_mob.ContactContractDisease(strain)
if(iscarbon(exposed_mob))
+21
View File
@@ -150,6 +150,9 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
/obj/item/organ/proc/on_remove(mob/living/carbon/organ_owner, special)
SHOULD_CALL_PARENT(TRUE)
if(!iscarbon(organ_owner))
stack_trace("Organ removal should not be happening on non carbon mobs: [organ_owner]")
for(var/trait in organ_traits)
REMOVE_TRAIT(organ_owner, trait, REF(src))
@@ -163,6 +166,24 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
SEND_SIGNAL(src, COMSIG_ORGAN_REMOVED, organ_owner)
SEND_SIGNAL(organ_owner, COMSIG_CARBON_LOSE_ORGAN, src, special)
var/list/diseases = organ_owner.get_static_viruses()
if(!LAZYLEN(diseases))
return
var/list/datum/disease/diseases_to_add = list()
for(var/datum/disease/disease as anything in diseases)
// robotic organs are immune to disease unless 'inorganic biology' symptom is present
if(IS_ROBOTIC_ORGAN(src) && !(disease.infectable_biotypes & MOB_ROBOTIC))
continue
// admin or special viruses that should not be reproduced
if(disease.spread_flags & (DISEASE_SPREAD_SPECIAL | DISEASE_SPREAD_NON_CONTAGIOUS))
continue
diseases_to_add += disease
if(LAZYLEN(diseases_to_add))
AddComponent(/datum/component/infective, diseases_to_add)
/// Add a Trait to an organ that it will give its owner.
/obj/item/organ/proc/add_organ_trait(trait)
LAZYADD(organ_traits, trait)
@@ -64,6 +64,9 @@
if(!damage) // No sense healing if you're not even hurt bro
return
if(IS_ROBOTIC_ORGAN(src)) // Robotic organs don't naturally heal
return
///Damage decrements by a percent of its maxhealth
var/healing_amount = healing_factor
///Damage decrements again by a percent of its maxhealth, up to a total of 4 extra times depending on the owner's health
+1
View File
@@ -196,6 +196,7 @@ As the Quartermaster, be sure to check the manifests on crates you receive to ma
As the Quartermaster, you can construct an express supply console that instantly delivers crates by drop pod. The impact will cause a small explosion as well.
As the Research Director, you can lock down cyborgs instead of blowing them up. Then you can have their laws reset or if that doesn't work, safely dismantled.
As the Research Director, you can take AIs out of their cores by loading them into an intelliCard, which lets you see their laws, even ion/syndicate ones. It can then be placed into an AI system integrity restorer computer to revive and/or repair them.
As the Virologist, robotic organs can give immunity to disease effects and transmissibility. Make use of the inorganic biology symptom to bypass the protection.
As the Virologist, you only require small amounts of vaccine to heal a sick patient. Work with the Chemist to distribute your cures more efficiently.
As the Virologist, your viruses can range from healing powers so great that you can heal out of critical status, or diseases so dangerous they can kill the entire crew with airborne spontaneous combustion. Experiment!
As the Warden, if a prisoner's crimes are heinous enough you can put them in permabrig or the gulag. Make sure to check on them once in a while!