From 0faac6dce6c44b08239424be8b4b21ff18a6ab64 Mon Sep 17 00:00:00 2001 From: DeltaFire Date: Tue, 14 Dec 2021 23:06:42 +0100 Subject: [PATCH] hoo boy --- code/__DEFINES/atmospherics.dm | 6 ++ code/__DEFINES/traits.dm | 1 + code/_globalvars/traits.dm | 1 + code/game/objects/items/devices/scanners.dm | 9 +-- .../abductor/equipment/glands/heal.dm | 2 +- code/modules/mob/living/blood.dm | 47 +++++++------- code/modules/mob/living/carbon/human/life.dm | 2 + .../mob/living/carbon/human/species.dm | 18 ++++-- .../human/species_types/anthropomorph.dm | 6 +- .../living/carbon/human/species_types/ipc.dm | 5 +- .../carbon/human/species_types/synthliz.dm | 6 +- code/modules/mob/living/carbon/life.dm | 32 +++++++++- .../chemistry/reagents/medicine_reagents.dm | 1 - code/modules/surgery/organs/ears.dm | 14 ++--- code/modules/surgery/organs/lungs.dm | 61 ++++++++++++++++++- code/modules/surgery/organs/organ_internal.dm | 2 +- code/modules/surgery/organs/stomach.dm | 8 +-- 17 files changed, 168 insertions(+), 53 deletions(-) diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index 1c6b7c21d4..5457f52208 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -68,6 +68,12 @@ #define TEMPERATURE_DAMAGE_COEFFICIENT 1.5 //This is used in handle_temperature_damage() for humans, and in reagents that affect body temperature. Temperature damage is multiplied by this amount. +#define SYNTH_PASSIVE_HEAT_GAIN 10 //Degrees C per handle_environment() Synths passively heat up. Mitigated by cooling efficiency. Can lead to overheating if not managed. +#define SYNTH_HEAT_EFFICIENCY_COEFF 0.005 //How quick the difference between the Synth and the environment starts to matter. The smaller the higher the difference has to be for the same change. +#define SYNTH_SINGLE_INFLUENCE_COOLING_EFFECT_CAP 3 //How big can the multiplier for heat / pressure cooling be in an optimal environment +#define SYNTH_TOTAL_ENVIRONMENT_EFFECT_CAP 2 //How big of an multiplier can the environment give in an optimal scenario (maximum efficiency in the end is 1, this just counters low coolant levels) +#define SYNTH_ACTIVE_COOLING_TEMP_BOUNDARY 10 //The minimum distance from room temperature a Synth needs to have for active cooling to actively cool. + #define BODYTEMP_NORMAL 310.15 //The natural temperature for a body #define BODYTEMP_AUTORECOVERY_DIVISOR 11 //This is the divisor which handles how much of the temperature difference between the current body temperature and 310.15K (optimal temperature) humans auto-regenerate each tick. The higher the number, the slower the recovery. This is applied each tick, so long as the mob is alive. #define BODYTEMP_AUTORECOVERY_MINIMUM 12 //Minimum amount of kelvin moved toward 310K per tick. So long as abs(310.15 - bodytemp) is more than 50. diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index ca326ece5f..edc6f58eaf 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -121,6 +121,7 @@ #define TRAIT_ROBOTIC_ORGANISM "robotic_organism" #define TRAIT_ROBOT_RADSHIELDING "robot_radshielding" #define TRAIT_NOBREATH "no_breath" +#define TRAIT_AUXILIARY_LUNGS "auxiliary_lungs" //Lungs not neccessary required due to nobreath, but provides some other helpful function. #define TRAIT_ANTIMAGIC "anti_magic" #define TRAIT_HOLY "holy" #define TRAIT_DEPRESSION "depression" diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm index bbe801cfc2..a3a1a35888 100644 --- a/code/_globalvars/traits.dm +++ b/code/_globalvars/traits.dm @@ -55,6 +55,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_ROBOTIC_ORGANISM" = TRAIT_ROBOTIC_ORGANISM, "TRAIT_ROBOT_RADSHIELDING" = TRAIT_ROBOT_RADSHIELDING, "TRAIT_NOBREATH" = TRAIT_NOBREATH, + "TRAIT_AUXILIARY_LUNGS" = TRAIT_AUXILIARY_LUNGS, "TRAIT_ANTIMAGIC" = TRAIT_ANTIMAGIC, "TRAIT_HOLY" = TRAIT_HOLY, "TRAIT_DEPRESSION" = TRAIT_DEPRESSION, diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 3ded0310dd..a8e76d04ca 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -325,7 +325,7 @@ GENETICS SCANNER var/breathes = TRUE var/blooded = TRUE if(C.dna && C.dna.species) - if(HAS_TRAIT_FROM(C, TRAIT_NOBREATH, SPECIES_TRAIT)) + if(!HAS_TRAIT_FROM(C, TRAIT_AUXILIARY_LUNGS, SPECIES_TRAIT) && HAS_TRAIT_FROM(C, TRAIT_NOBREATH, SPECIES_TRAIT)) breathes = FALSE if(NOBLOOD in C.dna.species.species_traits) blooded = FALSE @@ -434,12 +434,13 @@ GENETICS SCANNER if(R) blood_type = R.name + if((C.scan_blood_volume() + C.integrating_blood) <= (BLOOD_VOLUME_SAFE * C.blood_ratio) && (C.scan_blood_volume() + C.integrating_blood) > (BLOOD_VOLUME_OKAY*C.blood_ratio)) - msg += "LOW blood level [blood_percent] %, [C.scan_blood_volume()] cl[C.integrating_blood? ", with [integrated_blood_percent] % of it integrating, [C.integrating_blood] cl " : ""]. type: [blood_type]\n" + msg += "LOW [HAS_TRAIT(C, TRAIT_ROBOTIC_ORGANISM) ? "coolant" : "blood"] level [blood_percent] %, [C.scan_blood_volume()] cl[C.integrating_blood? ", with [integrated_blood_percent] % of it integrating, [C.integrating_blood] cl " : ""]. type: [blood_type]\n" else if((C.scan_blood_volume() + C.integrating_blood) <= (BLOOD_VOLUME_OKAY * C.blood_ratio)) - msg += "CRITICAL blood level [blood_percent] %, [C.scan_blood_volume()] cl[C.integrating_blood? ", with [integrated_blood_percent] % of it integrating, [C.integrating_blood] cl " : ""]. type: [blood_type]\n" + msg += "CRITICAL [HAS_TRAIT(C, TRAIT_ROBOTIC_ORGANISM) ? "coolant" : "blood"] level [blood_percent] %, [C.scan_blood_volume()] cl[C.integrating_blood? ", with [integrated_blood_percent] % of it integrating, [C.integrating_blood] cl " : ""]. type: [blood_type]\n" else - msg += "Blood level [blood_percent] %, [C.scan_blood_volume()] cl[C.integrating_blood? ", with [integrated_blood_percent] % of it integrating, [C.integrating_blood] cl " : ""]. type: [blood_type]\n" + msg += "[HAS_TRAIT(C, TRAIT_ROBOTIC_ORGANISM) ? "Coolant" : "Blood"] level [blood_percent] %, [C.scan_blood_volume()] cl[C.integrating_blood? ", with [integrated_blood_percent] % of it integrating, [C.integrating_blood] cl " : ""]. type: [blood_type]\n" var/cyberimp_detect diff --git a/code/modules/antagonists/abductor/equipment/glands/heal.dm b/code/modules/antagonists/abductor/equipment/glands/heal.dm index 8917e1661e..e995826af6 100644 --- a/code/modules/antagonists/abductor/equipment/glands/heal.dm +++ b/code/modules/antagonists/abductor/equipment/glands/heal.dm @@ -23,7 +23,7 @@ return var/obj/item/organ/lungs/lungs = owner.getorganslot(ORGAN_SLOT_LUNGS) - if((!lungs && !HAS_TRAIT(owner, TRAIT_NOBREATH)) || (lungs && (istype(lungs, /obj/item/organ/lungs/cybernetic)))) + if((!lungs && (HAS_TRAIT_FROM(owner, TRAIT_AUXILIARY_LUNGS, SPECIES_TRAIT) || !HAS_TRAIT(owner, TRAIT_NOBREATH))) || (lungs && (istype(lungs, /obj/item/organ/lungs/cybernetic)))) replace_lungs(lungs) return diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm index 7615792028..813aafbb8e 100644 --- a/code/modules/mob/living/blood.dm +++ b/code/modules/mob/living/blood.dm @@ -65,29 +65,30 @@ blood_volume = min(BLOOD_VOLUME_NORMAL, blood_volume + 0.5 * nutrition_ratio) //Effects of bloodloss - var/word = pick("dizzy","woozy","faint") - var/blood_effect_volume = blood_volume + integrating_blood - switch(blood_effect_volume) - if(BLOOD_VOLUME_MAXIMUM to BLOOD_VOLUME_EXCESS) - if(prob(10)) - to_chat(src, "You feel terribly bloated.") - if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE) - if(prob(5)) - to_chat(src, "You feel [word].") - adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1)) - if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY) - adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1)) - if(prob(5)) - blur_eyes(6) - to_chat(src, "You feel very [word].") - if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD) - adjustOxyLoss(5) - if(prob(15)) - Unconscious(rand(20,60)) - to_chat(src, "You feel extremely [word].") - if(-INFINITY to BLOOD_VOLUME_SURVIVE) - if(!HAS_TRAIT(src, TRAIT_NODEATH)) - death() + if(!HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM)) //Synths are immune to direct consequences of bloodloss, instead suffering penalties to heat exchange. + var/word = pick("dizzy","woozy","faint") + var/blood_effect_volume = blood_volume + integrating_blood + switch(blood_effect_volume) + if(BLOOD_VOLUME_MAXIMUM to BLOOD_VOLUME_EXCESS) + if(prob(10)) + to_chat(src, "You feel terribly bloated.") + if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE) + if(prob(5)) + to_chat(src, "You feel [word].") + adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1)) + if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY) + adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1)) + if(prob(5)) + blur_eyes(6) + to_chat(src, "You feel very [word].") + if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD) + adjustOxyLoss(5) + if(prob(15)) + Unconscious(rand(20,60)) + to_chat(src, "You feel extremely [word].") + if(-INFINITY to BLOOD_VOLUME_SURVIVE) + if(!HAS_TRAIT(src, TRAIT_NODEATH)) + death() var/temp_bleed = 0 //Bleeding out diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 85f01e63b3..b69d327807 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -79,6 +79,8 @@ var/L = getorganslot(ORGAN_SLOT_LUNGS) if(!L) + if(HAS_TRAIT(src, TRAIT_NOBREATH)) + return if(health >= crit_threshold) adjustOxyLoss(HUMAN_MAX_OXYLOSS + 1) else if(!HAS_TRAIT(src, TRAIT_NOCRITDAMAGE)) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index d81297d41f..785a515438 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -331,7 +331,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/should_have_brain = TRUE var/should_have_heart = !(NOBLOOD in species_traits) - var/should_have_lungs = !(TRAIT_NOBREATH in inherent_traits) + var/should_have_lungs = ((TRAIT_AUXILIARY_LUNGS in inherent_traits) || !(TRAIT_NOBREATH in inherent_traits)) var/should_have_appendix = !(TRAIT_NOHUNGER in inherent_traits) var/should_have_eyes = TRUE var/should_have_ears = TRUE @@ -1165,7 +1165,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/takes_crit_damage = !HAS_TRAIT(H, TRAIT_NOCRITDAMAGE) if((H.health < H.crit_threshold) && takes_crit_damage) - H.adjustBruteLoss(1) + if(!HAS_TRAIT(H, TRAIT_ROBOTIC_ORGANISM)) + H.adjustBruteLoss(1) + else + H.adjustFireLoss(1) //Robots melt instead of taking brute. /datum/species/proc/spec_death(gibbed, mob/living/carbon/human/H) if(H) @@ -1874,7 +1877,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(BODY_ZONE_HEAD) if(!I.get_sharpness() && armor_block < 50) if(prob(I.force)) - if(HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM)) + if(HAS_TRAIT(H, TRAIT_ROBOTIC_ORGANISM)) H.adjustToxLoss(5, toxins_type = TOX_SYSCORRUPT) //Bonk! - Effectively 5 bonus damage else H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 20) @@ -2171,15 +2174,20 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) //Thermal protection (insulation) has mixed benefits in two situations (hot in hot places, cold in hot places) if(!H.on_fire) //If you're on fire, you do not heat up or cool down based on surrounding gases var/natural = 0 + var/cooling_efficiency = 1 if(H.stat != DEAD) natural = H.natural_bodytemperature_stabilization() + cooling_efficiency = H.get_cooling_efficiency() + + if(HAS_TRAIT(H, TRAIT_ROBOTIC_ORGANISM)) //Synths by default slowly heat up and need to lose said heat to the environment or active cooling. + H.adjust_bodytemperature(SYNTH_PASSIVE_HEAT_GAIN * (1 - cooling_efficiency), max_temp = T0C + 200) var/thermal_protection = 1 if(loc_temp < H.bodytemperature) //Place is colder than we are thermal_protection -= H.get_thermal_protection(loc_temp, TRUE) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to. if(H.bodytemperature < BODYTEMP_NORMAL) //we're cold, insulation helps us retain body heat and will reduce the heat we lose to the environment - H.adjust_bodytemperature((thermal_protection+1)*natural + max(thermal_protection * (loc_temp - H.bodytemperature) / BODYTEMP_COLD_DIVISOR, BODYTEMP_COOLING_MAX)) + H.adjust_bodytemperature((thermal_protection+1)*natural + max((thermal_protection * (loc_temp - H.bodytemperature) * cooling_efficiency) / BODYTEMP_COLD_DIVISOR, BODYTEMP_COOLING_MAX)) else //we're sweating, insulation hinders our ability to reduce heat - and it will reduce the amount of cooling you get from the environment - H.adjust_bodytemperature(natural*(1/(thermal_protection+1)) + max((thermal_protection * (loc_temp - H.bodytemperature) + BODYTEMP_NORMAL - H.bodytemperature) / BODYTEMP_COLD_DIVISOR , BODYTEMP_COOLING_MAX)) //Extra calculation for hardsuits to bleed off heat + H.adjust_bodytemperature(natural*(1/(thermal_protection+1)) + max(((thermal_protection * (loc_temp - H.bodytemperature) + BODYTEMP_NORMAL - H.bodytemperature) * cooling_efficiency) / BODYTEMP_COLD_DIVISOR , BODYTEMP_COOLING_MAX)) //Extra calculation for hardsuits to bleed off heat else //Place is hotter than we are thermal_protection -= H.get_thermal_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to. if(H.bodytemperature < BODYTEMP_NORMAL) //and we're cold, insulation enhances our ability to retain body heat but reduces the heat we get from the environment diff --git a/code/modules/mob/living/carbon/human/species_types/anthropomorph.dm b/code/modules/mob/living/carbon/human/species_types/anthropomorph.dm index df129c6ff4..9ddd3e68bf 100644 --- a/code/modules/mob/living/carbon/human/species_types/anthropomorph.dm +++ b/code/modules/mob/living/carbon/human/species_types/anthropomorph.dm @@ -24,11 +24,15 @@ id = SPECIES_MAMMAL_SYNTHETIC species_traits = list(MUTCOLORS,NOTRANSSTING,EYECOLOR,LIPS,HAIR,ROBOTIC_LIMBS,HAS_FLESH,HAS_BONE,WINGCOLOR,HORNCOLOR) - inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM) + inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM, TRAIT_RESISTLOWPRESSURE, TRAIT_NOBREATH, TRAIT_AUXILIARY_LUNGS) inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID|MOB_BEAST meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc gib_types = list(/obj/effect/gibspawner/ipc, /obj/effect/gibspawner/ipc/bodypartless) + + coldmod = 0.5 + heatmod = 1.2 + //Just robo looking parts. mutant_heart = /obj/item/organ/heart/ipc mutantlungs = /obj/item/organ/lungs/ipc diff --git a/code/modules/mob/living/carbon/human/species_types/ipc.dm b/code/modules/mob/living/carbon/human/species_types/ipc.dm index eb870f9624..943381b3d6 100644 --- a/code/modules/mob/living/carbon/human/species_types/ipc.dm +++ b/code/modules/mob/living/carbon/human/species_types/ipc.dm @@ -5,7 +5,7 @@ default_color = "00FF00" blacklisted = 0 sexes = 0 - inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM) + inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM, TRAIT_RESISTLOWPRESSURE, TRAIT_NOBREATH, TRAIT_AUXILIARY_LUNGS) species_traits = list(MUTCOLORS,NOEYES,NOTRANSSTING,HAS_FLESH,HAS_BONE,HAIR,ROBOTIC_LIMBS) hair_alpha = 210 inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID @@ -13,6 +13,9 @@ meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc gib_types = list(/obj/effect/gibspawner/ipc, /obj/effect/gibspawner/ipc/bodypartless) + coldmod = 0.5 + heatmod = 1.2 + //Just robo looking parts. mutant_heart = /obj/item/organ/heart/ipc mutantlungs = /obj/item/organ/lungs/ipc diff --git a/code/modules/mob/living/carbon/human/species_types/synthliz.dm b/code/modules/mob/living/carbon/human/species_types/synthliz.dm index b6a7e93c72..a8abf3015e 100644 --- a/code/modules/mob/living/carbon/human/species_types/synthliz.dm +++ b/code/modules/mob/living/carbon/human/species_types/synthliz.dm @@ -4,11 +4,15 @@ say_mod = "beeps" default_color = "00FF00" species_traits = list(MUTCOLORS,NOTRANSSTING,EYECOLOR,LIPS,HAIR,ROBOTIC_LIMBS,HAS_FLESH,HAS_BONE) - inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM) + inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM, TRAIT_RESISTLOWPRESSURE, TRAIT_NOBREATH, TRAIT_AUXILIARY_LUNGS) inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID mutant_bodyparts = list("ipc_antenna" = "Synthetic Lizard - Antennae","mam_tail" = "Synthetic Lizard", "mam_snouts" = "Synthetic Lizard - Snout", "legs" = "Digitigrade", "mam_body_markings" = "Synthetic Lizard - Plates", "taur" = "None") meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc gib_types = list(/obj/effect/gibspawner/ipc, /obj/effect/gibspawner/ipc/bodypartless) + + coldmod = 0.5 + heatmod = 1.2 + //Just robo looking parts. mutant_heart = /obj/item/organ/heart/ipc mutantlungs = /obj/item/organ/lungs/ipc diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 196c5ff654..a2d1a12d17 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -661,7 +661,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put //used in human and monkey handle_environment() /mob/living/carbon/proc/natural_bodytemperature_stabilization() - if (HAS_TRAIT(src, TRAIT_COLDBLOODED)) + if(HAS_TRAIT(src, TRAIT_COLDBLOODED) || HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM)) return 0 //Return 0 as your natural temperature. Species proc handle_environment() will adjust your temperature based on this. var/body_temperature_difference = BODYTEMP_NORMAL - bodytemperature @@ -674,6 +674,36 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put return min(body_temperature_difference * metabolism_efficiency / BODYTEMP_AUTORECOVERY_DIVISOR, max(body_temperature_difference, -BODYTEMP_AUTORECOVERY_MINIMUM/4)) if(BODYTEMP_HEAT_DAMAGE_LIMIT to INFINITY) return min((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), -BODYTEMP_AUTORECOVERY_MINIMUM) //We're dealing with negative numbers + +/mob/living/carbon/proc/get_cooling_efficiency() + if(!HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM)) + return 1 + + var/blood_effective_volume = blood_volume + integrating_blood + var/coolant_efficiency = min(blood_effective_volume / BLOOD_VOLUME_SAFE, 1) //Low coolant is only a negative, adding more than needed will not help you. + var/environment_efficiency = get_environment_cooling_efficiency() + + return min(coolant_efficiency * environment_efficiency, 1) + + +/mob/living/carbon/proc/get_environment_cooling_efficiency() + if(istype(get_item_by_slot(SLOT_HEAD), /obj/item/clothing/head/helmet/space) && istype(get_item_by_slot(SLOT_WEAR_SUIT), /obj/item/clothing/suit/space)) + return 1 //If you are wearing full EVA gear, assume it has been made to accomodate your cooling needs. + var/datum/gas_mixture/environment = loc.return_air() + if(!environment) + return 0 + + var/pressure = environment.return_pressure() + var/heat = environment.return_temperature() + + var/heat_efficiency = clamp(1 + ((bodytemperature - heat) * SYNTH_HEAT_EFFICIENCY_COEFF), 0, SYNTH_SINGLE_INFLUENCE_COOLING_EFFECT_CAP) + var/pressure_efficiency = clamp(pressure / ONE_ATMOSPHERE, 0, SYNTH_SINGLE_INFLUENCE_COOLING_EFFECT_CAP) + + var/total_environment_efficiency = min(heat_efficiency * pressure_efficiency, SYNTH_TOTAL_ENVIRONMENT_EFFECT_CAP) //At best, you can get 200% total + return total_environment_efficiency + + + ///////// //LIVER// ///////// diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 650409b5cc..6732103e78 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -17,7 +17,6 @@ /datum/reagent/medicine/leporazine name = "Leporazine" description = "Leporazine will effectively regulate a patient's body temperature, ensuring it never leaves safe levels." - chemical_flags = REAGENT_ALL_PROCESS pH = 8.4 color = "#82b8aa" value = REAGENT_VALUE_COMMON diff --git a/code/modules/surgery/organs/ears.dm b/code/modules/surgery/organs/ears.dm index 3787d4e781..80b7599ec3 100644 --- a/code/modules/surgery/organs/ears.dm +++ b/code/modules/surgery/organs/ears.dm @@ -148,14 +148,14 @@ return to_chat(owner, "Alert: Auditory systems corrupted!.") switch(severity) - if(1) - owner.Jitter(30) - owner.Dizzy(30) - owner.DefaultCombatKnockdown(80) - deaf = 30 - - if(2) + if(1 to 50) owner.Jitter(15) owner.Dizzy(15) owner.DefaultCombatKnockdown(40) + + if(50 to INFINITY) + owner.Jitter(30) + owner.Dizzy(30) + owner.DefaultCombatKnockdown(80) + deaf = max(deaf, 30) damage += 0.15 * severity diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index 2b212bd224..6d61ccf085 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -425,6 +425,10 @@ /obj/item/organ/lungs/ipc name = "ipc cooling system" icon_state = "lungs-c" + var/is_cooling = 0 + var/cooling_coolant_drain = 5 //Coolant (blood) use per tick of active cooling. + var/next_warn = BLOOD_VOLUME_NORMAL + actions_types = list(/datum/action/item_action/organ_action/toggle) /obj/item/organ/lungs/ipc/emp_act(severity) //Should probably put it somewhere else later . = ..() @@ -432,11 +436,62 @@ return to_chat(owner, "Alert: Critical cooling system failure!") switch(severity) - if(1) - owner.adjust_bodytemperature(100*TEMPERATURE_DAMAGE_COEFFICIENT) - if(2) + if(1 to 50) owner.adjust_bodytemperature(30*TEMPERATURE_DAMAGE_COEFFICIENT) + if(50 to INFINITY) + owner.adjust_bodytemperature(100*TEMPERATURE_DAMAGE_COEFFICIENT) + +/obj/item/organ/lungs/ipc/ui_action_click(mob/user, actiontype) + if(!owner) + return + if(!HAS_TRAIT(user, TRAIT_ROBOTIC_ORGANISM)) + to_chat(user, "Biotype incompatible with cooling system. Activation signal suppressed.") + return + if(!is_cooling && owner.blood_volume < cooling_coolant_drain) + to_chat(user, "Coolant levels insufficient to enable active cooling - Replenish immediately.") + return + is_cooling = !is_cooling + to_chat(user, "Active cooling [is_cooling ? "enabled" : "disabled"] - current coolant level: [round(owner.blood_volume / BLOOD_VOLUME_NORMAL * 100, 0.1)] percent.") + var/possible_next_warn = owner.blood_volume - (BLOOD_VOLUME_NORMAL * 0.1) + if(possible_next_warn > next_warn) + next_warn = possible_next_warn //If we recovered blood inbetween activations, update warning + +/obj/item/organ/lungs/ipc/on_life(seconds, times_fired) + . = ..() + if(!.) + if(is_cooling) + to_chat(owner, "Cooling system safeguards triggered - active cooling aborted.") + is_cooling = 0 + return + if(!is_cooling) + return + if(!HAS_TRAIT(owner, TRAIT_ROBOTIC_ORGANISM)) + to_chat(owner, "Biotype incompatible with cooling system. Commencing emergency shutdown.") + is_cooling = 0 + return + if(owner.stat >= SOFT_CRIT) + to_chat(owner, "Operating system ping returned null response - Shutting down active cooling to avoid component damage.") + is_cooling = 0 + return + if(owner.blood_volume < cooling_coolant_drain) + to_chat(owner, "Coolant levels insufficient to maintain active cooling - Replenish immediately.") + is_cooling = 0 + return + if(abs(owner.bodytemperature - T20C) < SYNTH_ACTIVE_COOLING_TEMP_BOUNDARY) + return //Does not drain coolant (blood) nor do anything if we are close enough to room temp. + var/cooling_efficiency = owner.get_cooling_efficiency() + var/actual_drain = cooling_coolant_drain * max(1 - cooling_efficiency, 0.2) //Being in a suitable environment reduces drain by up to 80% + var/temp_diff = owner.bodytemperature - T20C + if(temp_diff > 0) + owner.adjust_bodytemperature(min(((T20C - owner.bodytemperature) * max(cooling_efficiency, 0.2) / BODYTEMP_COLD_DIVISOR), BODYTEMP_COOLING_MAX)) + else + owner.adjust_bodytemperature(min(((T20C - owner.bodytemperature) * max(cooling_efficiency, 0.2) / BODYTEMP_HEAT_DIVISOR), BODYTEMP_HEATING_MAX)) + owner.blood_volume = max(owner.blood_volume - actual_drain, 0) + if(owner.blood_volume <= next_warn) + to_chat(owner, "[owner.blood_volume > BLOOD_VOLUME_BAD ? "" : ""]Coolant level passed threshold - now [round(owner.blood_volume / BLOOD_VOLUME_NORMAL * 100, 0.1)] percent.") + next_warn -= (BLOOD_VOLUME_NORMAL * 0.1) + /obj/item/organ/lungs/plasmaman name = "plasma filter" desc = "A spongy rib-shaped mass for filtering plasma from the air." diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index de8e3d623d..a3c6ea06c8 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -249,7 +249,7 @@ var/breathes = TRUE var/blooded = TRUE if(dna && dna.species) - if(HAS_TRAIT_FROM(src, TRAIT_NOBREATH, SPECIES_TRAIT)) + if(!HAS_TRAIT_FROM(src, TRAIT_AUXILIARY_LUNGS, SPECIES_TRAIT) && HAS_TRAIT_FROM(src, TRAIT_NOBREATH, SPECIES_TRAIT)) breathes = FALSE if(NOBLOOD in dna.species.species_traits) blooded = FALSE diff --git a/code/modules/surgery/organs/stomach.dm b/code/modules/surgery/organs/stomach.dm index f436b31513..f7b84eab20 100644 --- a/code/modules/surgery/organs/stomach.dm +++ b/code/modules/surgery/organs/stomach.dm @@ -136,11 +136,11 @@ if(!owner || . & EMP_PROTECT_SELF) return switch(severity) - if(1) - owner.nutrition = min(owner.nutrition - 50, 0) + if(1 to 50) + owner.nutrition = max(owner.nutrition - 50, 0) to_chat(owner, "Alert: Detected severe battery discharge!") - if(2) - owner.nutrition = min(owner.nutrition - 100, 0) + if(50 to INFINITY) + owner.nutrition = max(owner.nutrition - 100, 0) to_chat(owner, "Alert: Minor battery discharge!") /obj/item/organ/stomach/ethereal