From 0faac6dce6c44b08239424be8b4b21ff18a6ab64 Mon Sep 17 00:00:00 2001 From: DeltaFire Date: Tue, 14 Dec 2021 23:06:42 +0100 Subject: [PATCH 01/17] 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 From c7667a2f50b8a51e768b220f7a3bcf22d6c87cbf Mon Sep 17 00:00:00 2001 From: DeltaFire Date: Sat, 1 Jan 2022 18:52:02 +0100 Subject: [PATCH 02/17] coldblooded blacklist & blood types standartizes blood types of ipc, synths and synth mammals (which used organic blood??) to S type blood, plis implements coldblooded blacklist (with trait point balancing after. --- code/__DEFINES/is_helpers.dm | 2 +- code/modules/mob/living/carbon/human/species.dm | 14 +++++++++----- .../carbon/human/species_types/anthropomorph.dm | 6 +++++- .../mob/living/carbon/human/species_types/ipc.dm | 4 +++- .../living/carbon/human/species_types/synthliz.dm | 2 ++ 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 9538cf91fa..0609b9dabe 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -79,7 +79,7 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list( #define isangel(A) (is_species(A, /datum/species/angel)) #define ismush(A) (is_species(A, /datum/species/mush)) #define isshadow(A) (is_species(A, /datum/species/shadow)) -#define isrobotic(A) (is_species(A, /datum/species/ipc) || is_species(A, /datum/species/synthliz)) +#define isrobotic(A) (is_species(A, /datum/species/ipc) || is_species(A, /datum/species/synthliz) || is_species(A, /datum/species/mammal/synthetic)) #define isdwarf(A) (is_species(A, /datum/species/dwarf)) // Citadel specific species diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 785a515438..5a2a632af2 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -147,6 +147,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/list/blacklisted_quirks = list() // Quirks that will be removed upon gaining this species, to be defined by species var/list/removed_quirks = list() // Quirks that got removed due to being blacklisted, and will be restored when on_species_loss() is called + var/balance_point_values = FALSE //If true, will balance point values on species gain after removing blacklisted quirks. Use this for roundstart species with blacklisted quirks that people may attempt to use to powergame trait points. ///Punch-specific attack verb. var/attack_verb = "punch" @@ -575,11 +576,14 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) /datum/species/proc/remove_blacklisted_quirks(mob/living/carbon/C) var/mob/living/L = C.mind?.current if(istype(L)) - for(var/q in L.roundstart_quirks) - var/datum/quirk/Q = q - if(Q.type in blacklisted_quirks) - qdel(Q) - removed_quirks += Q.type + if(!balance_point_values) + for(var/q in L.roundstart_quirks) + var/datum/quirk/Q = q + if(Q.type in blacklisted_quirks) + qdel(Q) + removed_quirks += Q.type + else + removed_quirks += SSquirks.filter_quirks(L.roundstart_quirks, blacklisted_quirks) // restore any quirks that we removed /datum/species/proc/restore_quirks(mob/living/carbon/C) 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 9ddd3e68bf..6303a474c9 100644 --- a/code/modules/mob/living/carbon/human/species_types/anthropomorph.dm +++ b/code/modules/mob/living/carbon/human/species_types/anthropomorph.dm @@ -32,6 +32,8 @@ coldmod = 0.5 heatmod = 1.2 + blacklisted_quirks = list(/datum/quirk/coldblooded) + balance_point_values = TRUE //Just robo looking parts. mutant_heart = /obj/item/organ/heart/ipc @@ -51,5 +53,7 @@ attack_sound = 'sound/weapons/slash.ogg' miss_sound = 'sound/weapons/slashmiss.ogg' + exotic_bloodtype = "S" + exotic_blood_color = BLOOD_COLOR_OIL allowed_limb_ids = list("mammal","aquatic","avian", "human") - species_category = "robot" + species_category = SPECIES_CATEGORY_ROBOT 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 943381b3d6..f3e245bb5d 100644 --- a/code/modules/mob/living/carbon/human/species_types/ipc.dm +++ b/code/modules/mob/living/carbon/human/species_types/ipc.dm @@ -15,6 +15,8 @@ coldmod = 0.5 heatmod = 1.2 + blacklisted_quirks = list(/datum/quirk/coldblooded) + balance_point_values = TRUE //Just robo looking parts. mutant_heart = /obj/item/organ/heart/ipc @@ -29,7 +31,7 @@ //special cybernetic organ for getting power from apcs mutant_organs = list(/obj/item/organ/cyberimp/arm/power_cord) - exotic_bloodtype = "HF" + exotic_bloodtype = "S" exotic_blood_color = BLOOD_COLOR_OIL species_category = SPECIES_CATEGORY_ROBOT 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 a8abf3015e..d3752dee15 100644 --- a/code/modules/mob/living/carbon/human/species_types/synthliz.dm +++ b/code/modules/mob/living/carbon/human/species_types/synthliz.dm @@ -12,6 +12,8 @@ coldmod = 0.5 heatmod = 1.2 + blacklisted_quirks = list(/datum/quirk/coldblooded) + balance_point_values = TRUE //Just robo looking parts. mutant_heart = /obj/item/organ/heart/ipc From 50e79579099cb773dd193f50dac6dbf240afc222 Mon Sep 17 00:00:00 2001 From: DeltaFire Date: Sat, 1 Jan 2022 18:59:50 +0100 Subject: [PATCH 03/17] no oxychem & tempchem processing well, one exception, pyrosium and cryostane still work as they have conditional effects that are more of a chemical reaction than impact on metabolism. --- .../reagents/chemistry/reagents/medicine_reagents.dm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 6732103e78..a47ac494bf 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -692,7 +692,6 @@ reagent_state = LIQUID color = "#00FFFF" metabolization_rate = 0.25 * REAGENTS_METABOLISM - chemical_flags = REAGENT_ALL_PROCESS pH = 2 /datum/reagent/medicine/salbutamol/on_mob_life(mob/living/carbon/M) @@ -709,7 +708,6 @@ reagent_state = LIQUID color = "#FF6464" metabolization_rate = 0.25 * REAGENTS_METABOLISM - chemical_flags = REAGENT_ALL_PROCESS pH = 11 /datum/reagent/medicine/perfluorodecalin/on_mob_life(mob/living/carbon/human/M) @@ -919,7 +917,6 @@ reagent_state = LIQUID color = "#000000" metabolization_rate = 0.25 * REAGENTS_METABOLISM - chemical_flags = REAGENT_ALL_PROCESS overdose_threshold = 35 pH = 12 value = REAGENT_VALUE_UNCOMMON @@ -950,7 +947,6 @@ reagent_state = LIQUID color = "#D2FFFA" metabolization_rate = 0.25 * REAGENTS_METABOLISM - chemical_flags = REAGENT_ALL_PROCESS overdose_threshold = 30 pH = 10.2 @@ -1202,7 +1198,6 @@ description = "Restores oxygen loss. Overdose causes it instead." reagent_state = LIQUID color = "#13d2f0" - chemical_flags = REAGENT_ALL_PROCESS overdose_threshold = 30 pH = 9.7 @@ -1266,7 +1261,6 @@ reagent_state = LIQUID pH = 8.5 color = "#5dc1f0" - chemical_flags = REAGENT_ALL_PROCESS /datum/reagent/medicine/inaprovaline/on_mob_life(mob/living/carbon/M) if(M.losebreath >= 5) From 875391325518665132ab486ab21c71fe19728967 Mon Sep 17 00:00:00 2001 From: DeltaFire Date: Sat, 1 Jan 2022 19:16:58 +0100 Subject: [PATCH 04/17] robots still get bz metabolites when in bz I very nearly buffed synth lings to ignore bz. Oops, I guess something something bz properties make it still interact with them (doesn't make the most sense, but better than synthlings ignoring bz) --- code/modules/mob/living/carbon/human/life.dm | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index b69d327807..4cfc230075 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -76,8 +76,20 @@ /mob/living/carbon/human/check_breath(datum/gas_mixture/breath) - var/L = getorganslot(ORGAN_SLOT_LUNGS) + if(breath && HAS_TRAIT(src, TRAIT_NOBREATH) && HAS_TRAIT(src, TRAIT_AUXILIARY_LUNGS)) //Something something bz and synth cooling systems interacting (in reality, this only exists to not make robot lings too strong) + var/total_moles = breath.total_moles() + var/pressure = breath.return_pressure() + #define PP_MOLES(X) ((X / total_moles) * pressure) + #define PP(air, gas) PP_MOLES(air.get_moles(gas)) + var/bz_pp = PP(breath, GAS_BZ) + if(bz_pp > 1) + reagents.add_reagent(/datum/reagent/bz_metabolites,5) + else if(bz_pp > 0.1) + reagents.add_reagent(/datum/reagent/bz_metabolites,1) + #undef PP_MOLES + #undef PP + var/L = getorganslot(ORGAN_SLOT_LUNGS) if(!L) if(HAS_TRAIT(src, TRAIT_NOBREATH)) return From 1c3891582e92494978b180121abac2bc0d2bdcda Mon Sep 17 00:00:00 2001 From: DeltaFire Date: Sat, 1 Jan 2022 19:35:16 +0100 Subject: [PATCH 05/17] =?UTF-8?q?robots=20have=20-125=C2=B0=20cold=20temp?= =?UTF-8?q?=20tolerance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit title. They will only take cold damage (and slowdown) once they are *really* cold (e.g. icethrowers or supercooled environments), as their internal components struggle to compensate and their coolant starts to freeze. --- code/modules/mob/living/carbon/human/species.dm | 10 +++++++--- .../living/carbon/human/species_types/anthropomorph.dm | 1 + .../mob/living/carbon/human/species_types/ipc.dm | 1 + .../mob/living/carbon/human/species_types/synthliz.dm | 1 + 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 5a2a632af2..0bd0bb24a2 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -108,6 +108,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/burnmod = 1 ///multiplier for damage from cold temperature var/coldmod = 1 + ///moves their safe minimum temp by this value. + var/cold_offset = 0 + ///moves their safe maximum temp by this value. + var/hot_offset = 0 ///multiplier for damage from hot temperature var/heatmod = 1 ///multiplier for stun durations @@ -2215,7 +2219,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) H.throw_alert("tempfeel", /atom/movable/screen/alert/hot, 3) // +/- 50 degrees from 310K is the 'safe' zone, where no damage is dealt. - if(H.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTHEAT)) + if(H.bodytemperature > (BODYTEMP_HEAT_DAMAGE_LIMIT + hot_offset) && !HAS_TRAIT(H, TRAIT_RESISTHEAT)) //Body temperature is too hot. SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "cold") @@ -2243,11 +2247,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) H.emote("scream") H.apply_damage(burn_damage, BURN) - else if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTCOLD)) + else if(H.bodytemperature < (BODYTEMP_COLD_DAMAGE_LIMIT + cold_offset) && !HAS_TRAIT(H, TRAIT_RESISTCOLD)) SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "hot") SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "cold", /datum/mood_event/cold) //Apply cold slowdown - H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/cold, multiplicative_slowdown = ((BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR)) + H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/cold, multiplicative_slowdown = (((BODYTEMP_COLD_DAMAGE_LIMIT + cold_offset) - H.bodytemperature) / COLD_SLOWDOWN_FACTOR)) switch(H.bodytemperature) if(200 to BODYTEMP_COLD_DAMAGE_LIMIT) H.throw_alert("temp", /atom/movable/screen/alert/shiver, 1) 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 6303a474c9..744375db9c 100644 --- a/code/modules/mob/living/carbon/human/species_types/anthropomorph.dm +++ b/code/modules/mob/living/carbon/human/species_types/anthropomorph.dm @@ -32,6 +32,7 @@ coldmod = 0.5 heatmod = 1.2 + cold_offset = -125 //Can handle pretty cold environments, but it's still a slightly bad idea if you enter a room thats full of near-absolute-zero gas blacklisted_quirks = list(/datum/quirk/coldblooded) balance_point_values = TRUE 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 f3e245bb5d..4f6b940692 100644 --- a/code/modules/mob/living/carbon/human/species_types/ipc.dm +++ b/code/modules/mob/living/carbon/human/species_types/ipc.dm @@ -15,6 +15,7 @@ coldmod = 0.5 heatmod = 1.2 + cold_offset = -125 //Can handle pretty cold environments, but it's still a slightly bad idea if you enter a room thats full of near-absolute-zero gas blacklisted_quirks = list(/datum/quirk/coldblooded) balance_point_values = TRUE 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 d3752dee15..7fc2da1132 100644 --- a/code/modules/mob/living/carbon/human/species_types/synthliz.dm +++ b/code/modules/mob/living/carbon/human/species_types/synthliz.dm @@ -12,6 +12,7 @@ coldmod = 0.5 heatmod = 1.2 + cold_offset = -125 //Can handle pretty cold environments, but it's still a slightly bad idea if you enter a room thats full of near-absolute-zero gas blacklisted_quirks = list(/datum/quirk/coldblooded) balance_point_values = TRUE From f1c40b8001f4f7c76bfffd4e27f86cd9ce38731f Mon Sep 17 00:00:00 2001 From: DeltaFire Date: Sat, 1 Jan 2022 19:39:10 +0100 Subject: [PATCH 06/17] =?UTF-8?q?increases=20max=20passive=20heat=20temp?= =?UTF-8?q?=20cap=20by=2050=C2=B0C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit title. Only applies if cooling is insufficient and a Synthetic allows themselves to heat up that far. --- code/__DEFINES/atmospherics.dm | 1 + code/modules/mob/living/carbon/human/species.dm | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index 5457f52208..eb3c71dec0 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -69,6 +69,7 @@ #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_MAX_PASSIVE_GAIN_TEMP 250 //Degrees C above 0 that a synth can be heated up to by their internal heat gain, provided their cooling is insufficient to mitigate it. #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) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 0bd0bb24a2..27c8b289e5 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -2188,7 +2188,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) 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) + H.adjust_bodytemperature(SYNTH_PASSIVE_HEAT_GAIN * (1 - cooling_efficiency), max_temp = (T0C + SYNTH_MAX_PASSIVE_GAIN_TEMP)) 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. From fa358a807f55bcd4b6f5c3d3abf5844509406546 Mon Sep 17 00:00:00 2001 From: DeltaFire Date: Sun, 2 Jan 2022 01:27:50 +0100 Subject: [PATCH 07/17] HUD info, more readouts HUD & a examine readout for the HUD for coolant & cooling efficiency info. Penalty active-cooling-cost-wise when in very low pressure area. Higher minimum efficiency for active cooling. Synths don't look pale. --- code/__DEFINES/atmospherics.dm | 2 + code/_onclick/hud/hud.dm | 2 + code/_onclick/hud/human.dm | 57 ++++++++++++++++++ .../mob/living/carbon/human/examine.dm | 21 ++++--- code/modules/mob/living/carbon/human/life.dm | 2 + .../mob/living/carbon/human/species.dm | 3 + code/modules/surgery/organs/lungs.dm | 7 ++- icons/mob/screen_synth.dmi | Bin 0 -> 672 bytes 8 files changed, 82 insertions(+), 12 deletions(-) create mode 100644 icons/mob/screen_synth.dmi diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index eb3c71dec0..ab12e53bcf 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -74,6 +74,8 @@ #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 SYNTH_ACTIVE_COOLING_LOW_PRESSURE_THRESHOLD 0.05 //At how much percentage of default pressure (or lower) active cooling gets a massive cost penalty. +#define SYNTH_ACTIVE_COOLING_LOW_PRESSURE_PENALTY 2.5 //By how much is active cooling cost multiplied if in a very-low-pressure environment? #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. diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 36a3cd1f1a..144a38e728 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -35,6 +35,8 @@ GLOBAL_LIST_INIT(available_ui_styles, list( var/atom/movable/screen/devil/soul_counter/devilsouldisplay + var/atom/movable/screen/synth/coolant_counter/coolant_display + var/atom/movable/screen/action_intent var/atom/movable/screen/zone_select var/atom/movable/screen/pull_icon diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index e4a9dc24e8..d8d44690f2 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -80,6 +80,59 @@ icon_state = "power_display" screen_loc = ui_lingchemdisplay +#define ui_coolant_display "EAST,SOUTH+3:15" + +/atom/movable/screen/synth + invisibility = INVISIBILITY_ABSTRACT + + +/atom/movable/screen/synth/proc/clear() + invisibility = INVISIBILITY_ABSTRACT + +/atom/movable/screen/synth/proc/update_counter(value, mob/living/carbon/human/owner) + invisibility = 0 + +/atom/movable/screen/synth/coolant_counter + icon = 'icons/mob/screen_synth.dmi' + name = "Coolant System Readout" + icon_state = "coolant-3" + screen_loc = ui_coolant_display + +/atom/movable/screen/synth/coolant_counter/update_counter(value, mob/living/carbon/owner) + ..() + var/valuecolor = "#FF6666" + if(owner.stat == DEAD) + maptext = "
ERR-0F
" + icon_state = "coolant-3" + return + if(owner.blood_volume > BLOOD_VOLUME_SAFE * owner.blood_ratio) + valuecolor = "#FFDDDD" + else if(owner.blood_volume > BLOOD_VOLUME_BAD * owner.blood_ratio) + valuecolor = "#FFAAAA" + maptext = "
[round(value,1)]
" + + var/coolant_efficiency = owner.get_cooling_efficiency() + switch(coolant_efficiency) + if(-INFINITY to 0.4) + icon_state = "coolant-1" + if(0.4 to 0.75) + icon_state = "coolant-2" + if(0.75 to 0.95) + icon_state = "coolant-3" + if(0.95 to 1.3) + icon_state = "coolant-4" + else + icon_state = "coolant-5" + +/atom/movable/screen/synth/coolant_counter/examine(mob/user) + . = ..() + var/mob/living/carbon/human/owner = hud.mymob + if(owner.stat == DEAD) + return + . += "Performing internal cooling system diagnostics:" + . += "Coolant level: [owner.blood_volume] units, [round((owner.blood_volume / (BLOOD_VOLUME_NORMAL * owner.blood_ratio)) * 100, 0.1)] percent" + . += "Current Cooling Efficiency: [round(owner.get_cooling_efficiency() * 100, 0.1)] percent, environment viability: [round(owner.get_environment_cooling_efficiency() * 100, 0.1)] percent." + /datum/hud/human/New(mob/living/carbon/human/owner) ..() owner.overlay_fullscreen("see_through_darkness", /atom/movable/screen/fullscreen/see_through_darkness) @@ -359,6 +412,10 @@ sunlight_display.hud = src infodisplay += sunlight_display + coolant_display = new /atom/movable/screen/synth/coolant_counter //Coolant & cooling efficiency readouts for Synths. + coolant_display.hud = src + infodisplay += coolant_display + zone_select = new /atom/movable/screen/zone_sel() zone_select.icon = ui_style zone_select.hud = src diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 0e75595c75..c3fb82de36 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -249,16 +249,17 @@ if(DISGUST_LEVEL_DISGUSTED to INFINITY) msg += "[t_He] look[p_s()] extremely disgusted.\n" - var/apparent_blood_volume = blood_volume - if(dna.species.use_skintones && skin_tone == "albino") - apparent_blood_volume -= 150 // enough to knock you down one tier - switch(apparent_blood_volume) - if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE) - msg += "[t_He] [t_has] pale skin.\n" - if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY) - msg += "[t_He] look[p_s()] like pale death.\n" - if(-INFINITY to BLOOD_VOLUME_BAD) - msg += "[t_He] resemble[p_s()] a crushed, empty juice pouch.\n" + if(!HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM)) + var/apparent_blood_volume = blood_volume + if(dna.species.use_skintones && skin_tone == "albino") + apparent_blood_volume -= 150 // enough to knock you down one tier + switch(apparent_blood_volume) + if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE) + msg += "[t_He] [t_has] pale skin.\n" + if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY) + msg += "[t_He] look[p_s()] like pale death.\n" + if(-INFINITY to BLOOD_VOLUME_BAD) + msg += "[t_He] resemble[p_s()] a crushed, empty juice pouch.\n" if(bleedsuppress) msg += "[t_He] [t_is] embued with a power that defies bleeding.\n" // only statues and highlander sword can cause this so whatever diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 4cfc230075..1c73a4bd37 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -30,6 +30,8 @@ /mob/living/carbon/human/PhysicalLife(seconds, times_fired) if(!(. = ..())) return + if(HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM) && hud_used) + hud_used.coolant_display.update_counter(blood_volume, src) //Update our name based on whether our face is obscured/disfigured name = get_visible_name() diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 27c8b289e5..4f26907eff 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -574,6 +574,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) for(var/obj/item/bodypart/B in C.bodyparts) B.change_bodypart_status(initial(B.status), FALSE, TRUE) + if((TRAIT_ROBOTIC_ORGANISM in inherent_traits) && C.hud_used) + C.hud_used.coolant_display.clear() + SEND_SIGNAL(C, COMSIG_SPECIES_LOSS, src) // shamelessly inspired by antag_datum.remove_blacklisted_quirks() diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index 6d61ccf085..8cedaf2f9e 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -484,9 +484,12 @@ 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)) + owner.adjust_bodytemperature(max(((T0C - owner.bodytemperature) * max(cooling_efficiency, 0.5) / 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.adjust_bodytemperature(min(((T20C - owner.bodytemperature) * max(cooling_efficiency, 0.5) / BODYTEMP_HEAT_DIVISOR), BODYTEMP_HEATING_MAX)) + var/datum/gas_mixture/air = owner.loc.return_air() + if(!air || air.return_pressure() < ONE_ATMOSPHERE * SYNTH_ACTIVE_COOLING_LOW_PRESSURE_THRESHOLD) + actual_drain *= SYNTH_ACTIVE_COOLING_LOW_PRESSURE_PENALTY //Our cooling system can handle hot places okayish, but starts to cry at low pressures (reads: Effectively vents hot coolant thats been warmed up via internal heat-exchange as emergency measure and with very low efficiency) 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.") diff --git a/icons/mob/screen_synth.dmi b/icons/mob/screen_synth.dmi new file mode 100644 index 0000000000000000000000000000000000000000..6c3e6b3e79d7199bc8f7e8552e91b1ed48cd5d4b GIT binary patch literal 672 zcmV;R0$=@!P)fFDZ*Bkpc$`yKaB_9`^iy#0_2eo`Eh^5;&r`5fFwryM;w;ZhDainGjE%TB zGg33tGfE(w;*!LYR3K9+IX^!qF|S0|P>G8(C9|j)C}zmTnO2mTn+joLs5By4r7_Ve zO^8-$ic6)kf~%hkI0yhRSW6T7#GqaP00F2;L_t(YiQSbuPQ)+}hMm2E!y-g!Qy^M6 z0a6sSZ-f~oRZo>y$o&)AhM$er8TjN zclPt)<#}A7S=eOx7=dQKFO0p~B|$TjTn*MQP`nexXxuJP%;c?7K7=5d`2eO&vykGG z%jg5BqZBEwv~}2n2t_VZtjn`;0416t1;sE!skIgq!wi+%K=7s>EYEtls9L00SLfM5 z7R{U4kl<3ggYyyI8+%a8tWNG~fFf&q6%w5Hmv0L2DeKwMAEk`hUiYcyN9*9ZzpVkA znk09Bg7dq^)j09+9s*`r-akR}0By~XCB|kT^xtxP&^@(?LqZR}B<29;e;eol+5?z7hi@A_J}mi43?Nq Date: Sun, 2 Jan 2022 01:42:56 +0100 Subject: [PATCH 08/17] no lung break choking message for nobreath --- code/modules/surgery/organs/lungs.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index 8cedaf2f9e..313a97a40d 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -415,7 +415,7 @@ if(!.) return if(!failed && organ_flags & ORGAN_FAILING) - if(owner && owner.stat == CONSCIOUS) + if(owner && owner.stat == CONSCIOUS && !HAS_TRAIT(owner, TRAIT_NOBREATH)) owner.visible_message("[owner] grabs [owner.p_their()] throat, struggling for breath!", \ "You suddenly feel like you can't breathe!") failed = TRUE From 074fe5b4175217ef542d37b6dde3cc69eae81fe8 Mon Sep 17 00:00:00 2001 From: DeltaFire Date: Sun, 2 Jan 2022 19:44:35 +0100 Subject: [PATCH 09/17] a bunch of stuff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 5° min temp adjustment for active cooling 150% max total cooling efficiency as opposed to 100% passive heating cools instead at >100% efficiency (to -30°C min) EMPs jam cooling system readouts. Nanogel is now printable, for a decent price though it needs a bit of diamond. --- code/__DEFINES/atmospherics.dm | 7 ++-- code/_onclick/hud/human.dm | 36 ++++++++++++++----- code/game/objects/items/stacks/medical.dm | 3 ++ .../mob/living/carbon/human/human_defense.dm | 1 + code/modules/mob/living/carbon/human/life.dm | 2 +- .../mob/living/carbon/human/species.dm | 4 +-- code/modules/mob/living/carbon/life.dm | 2 +- .../research/designs/medical_designs.dm | 11 +++++- .../research/techweb/nodes/robotics_nodes.dm | 2 +- code/modules/surgery/organs/lungs.dm | 4 +-- 10 files changed, 54 insertions(+), 18 deletions(-) diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index ab12e53bcf..8f23d89a0b 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -69,13 +69,16 @@ #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_MAX_PASSIVE_GAIN_TEMP 250 //Degrees C above 0 that a synth can be heated up to by their internal heat gain, provided their cooling is insufficient to mitigate it. +#define SYNTH_MAX_PASSIVE_GAIN_TEMP 250 //Degrees C that a synth can be heated up to by their internal heat gain, provided their cooling is insufficient to mitigate it. +#define SYNTH_MIN_PASSIVE_COOLING_TEMP -30 //Degrees C a synth can cool towards at very high cooling efficiency. #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_TOTAL_ENVIRONMENT_EFFECT_CAP 2 //How big of an multiplier can the environment give in an optimal scenario (maximum efficiency in the end is at a lower cap, this mostly counters low coolant levels) +#define SYNTH_MAX_COOLING_EFFICIENCY 1.5 //The maximum possible cooling efficiency one can achieve at optimal conditions. #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 SYNTH_ACTIVE_COOLING_LOW_PRESSURE_THRESHOLD 0.05 //At how much percentage of default pressure (or lower) active cooling gets a massive cost penalty. #define SYNTH_ACTIVE_COOLING_LOW_PRESSURE_PENALTY 2.5 //By how much is active cooling cost multiplied if in a very-low-pressure environment? +#define SYNTH_ACTIVE_COOLING_MIN_ADJUSTMENT 5 //What is the minimum amount of temp you move towards the target point, even if it would be less with default calculations? #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. diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index d8d44690f2..fe8a716234 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -89,7 +89,7 @@ /atom/movable/screen/synth/proc/clear() invisibility = INVISIBILITY_ABSTRACT -/atom/movable/screen/synth/proc/update_counter(value, mob/living/carbon/human/owner) +/atom/movable/screen/synth/proc/update_counter(mob/living/carbon/human/owner) invisibility = 0 /atom/movable/screen/synth/coolant_counter @@ -97,21 +97,30 @@ name = "Coolant System Readout" icon_state = "coolant-3" screen_loc = ui_coolant_display + var/jammed = 0 -/atom/movable/screen/synth/coolant_counter/update_counter(value, mob/living/carbon/owner) +/atom/movable/screen/synth/coolant_counter/update_counter(mob/living/carbon/owner) ..() var/valuecolor = "#FF6666" if(owner.stat == DEAD) maptext = "
ERR-0F
" icon_state = "coolant-3" return - if(owner.blood_volume > BLOOD_VOLUME_SAFE * owner.blood_ratio) + var/coolant_efficiency + var/coolant + if(!jammed) + coolant_efficiency = owner.get_cooling_efficiency() + coolant = owner.blood_volume + else + coolant_efficiency = rand(1, 15) / 10 + coolant = rand(1, 600) + jammed-- + if(coolant > BLOOD_VOLUME_SAFE * owner.blood_ratio) valuecolor = "#FFDDDD" - else if(owner.blood_volume > BLOOD_VOLUME_BAD * owner.blood_ratio) + else if(coolant > BLOOD_VOLUME_BAD * owner.blood_ratio) valuecolor = "#FFAAAA" - maptext = "
[round(value,1)]
" + maptext = "
[round(coolant,1)]
" - var/coolant_efficiency = owner.get_cooling_efficiency() switch(coolant_efficiency) if(-INFINITY to 0.4) icon_state = "coolant-1" @@ -129,9 +138,20 @@ var/mob/living/carbon/human/owner = hud.mymob if(owner.stat == DEAD) return + var/coolant + var/total_efficiency + var/environ_efficiency + if(!jammed) + coolant = owner.blood_volume + total_efficiency = owner.get_cooling_efficiency() + environ_efficiency = owner.get_environment_cooling_efficiency() + else + coolant = rand(1, 600) + total_efficiency = rand(1, 15) / 10 + environ_efficiency = rand(1, 20) / 10 . += "Performing internal cooling system diagnostics:" - . += "Coolant level: [owner.blood_volume] units, [round((owner.blood_volume / (BLOOD_VOLUME_NORMAL * owner.blood_ratio)) * 100, 0.1)] percent" - . += "Current Cooling Efficiency: [round(owner.get_cooling_efficiency() * 100, 0.1)] percent, environment viability: [round(owner.get_environment_cooling_efficiency() * 100, 0.1)] percent." + . += "Coolant level: [coolant] units, [round((coolant / (BLOOD_VOLUME_NORMAL * owner.blood_ratio)) * 100, 0.1)] percent" + . += "Current Cooling Efficiency: [round(total_efficiency * 100, 0.1)] percent, environment viability: [round(environ_efficiency * 100, 0.1)] percent." /datum/hud/human/New(mob/living/carbon/human/owner) ..() diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index f888927411..0bd3083a59 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -488,6 +488,9 @@ icon_state = "nanogel" var/being_applied = FALSE //No doafter stacking. +/obj/item/stack/medical/nanogel/one + amount = 1 + /obj/item/stack/medical/nanogel/try_heal(mob/living/M, mob/user, silent = FALSE) if(being_applied) to_chat(user, "You are already applying [src]!") diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 16ab351d64..e1f4055998 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -416,6 +416,7 @@ severity *= 0.5 var/do_not_stun = FALSE if(HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM)) + hud_used?.coolant_display.jammed = min(round(hud_used.coolant_display.jammed + (severity / 10),1), 20) //Messes up the cooling system readout. severity *= 0.5 //Robotpeople take less limb damage, but instead suffer system corruption (see carbon emp_act) do_not_stun = TRUE for(var/obj/item/bodypart/L in src.bodyparts) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 1c73a4bd37..1ea28211af 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -31,7 +31,7 @@ if(!(. = ..())) return if(HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM) && hud_used) - hud_used.coolant_display.update_counter(blood_volume, src) + hud_used.coolant_display.update_counter(src) //Update our name based on whether our face is obscured/disfigured name = get_visible_name() diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 4f26907eff..83486dc0f2 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -2190,8 +2190,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) 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 + SYNTH_MAX_PASSIVE_GAIN_TEMP)) + 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. If you have very high cooling efficiency, you instead passively cool. + H.adjust_bodytemperature(SYNTH_PASSIVE_HEAT_GAIN * (1 - cooling_efficiency), (T0C + SYNTH_MIN_PASSIVE_COOLING_TEMP), (T0C + SYNTH_MAX_PASSIVE_GAIN_TEMP)) 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. diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index a2d1a12d17..d5c4ab8e7d 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -683,7 +683,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put 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) + return min(coolant_efficiency * environment_efficiency, SYNTH_MAX_COOLING_EFFICIENCY) /mob/living/carbon/proc/get_environment_cooling_efficiency() diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 663cf1fdd7..cf17ec8545 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -213,7 +213,7 @@ category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE -/datum/design/hypospray/mkii +/datum/design/hypospray_mkii name = "Hypospray Mk. II" id = "hypospray_mkii" build_type = PROTOLATHE @@ -222,6 +222,15 @@ category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL +/datum/design/nanogel + name = "Nanogel paste" + id = "nanogel" + build_type = PROTOLATHE | MECHFAB + materials = list(/datum/material/iron = 800, /datum/material/titanium = 500, /datum/material/gold = 100, /datum/material/diamond = 20) + build_path = /obj/item/stack/medical/nanogel/one + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE + /datum/design/blood_bag name = "Empty Blood Bag" desc = "A small sterilized plastic bag for blood." diff --git a/code/modules/research/techweb/nodes/robotics_nodes.dm b/code/modules/research/techweb/nodes/robotics_nodes.dm index 6248cd99aa..ee4fbd261b 100644 --- a/code/modules/research/techweb/nodes/robotics_nodes.dm +++ b/code/modules/research/techweb/nodes/robotics_nodes.dm @@ -28,7 +28,7 @@ display_name = "Advanced Robotics Research" description = "It can even do the dishes!" prereq_ids = list("robotics") - design_ids = list("borg_upgrade_diamonddrill", "borg_upgrade_advancedmop", "borg_upgrade_advcutter") + design_ids = list("borg_upgrade_diamonddrill", "borg_upgrade_advancedmop", "borg_upgrade_advcutter", "nanogel") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3000) /datum/techweb_node/neural_programming diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index 313a97a40d..8df0696098 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -484,9 +484,9 @@ 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(max(((T0C - owner.bodytemperature) * max(cooling_efficiency, 0.5) / BODYTEMP_COLD_DIVISOR), BODYTEMP_COOLING_MAX)) + owner.adjust_bodytemperature(clamp(((T0C - owner.bodytemperature) * max(cooling_efficiency, 0.5) / BODYTEMP_COLD_DIVISOR), BODYTEMP_COOLING_MAX, -SYNTH_ACTIVE_COOLING_MIN_ADJUSTMENT)) else - owner.adjust_bodytemperature(min(((T20C - owner.bodytemperature) * max(cooling_efficiency, 0.5) / BODYTEMP_HEAT_DIVISOR), BODYTEMP_HEATING_MAX)) + owner.adjust_bodytemperature(clamp(((T20C - owner.bodytemperature) * max(cooling_efficiency, 0.5) / BODYTEMP_HEAT_DIVISOR), SYNTH_ACTIVE_COOLING_MIN_ADJUSTMENT, BODYTEMP_HEATING_MAX)) var/datum/gas_mixture/air = owner.loc.return_air() if(!air || air.return_pressure() < ONE_ATMOSPHERE * SYNTH_ACTIVE_COOLING_LOW_PRESSURE_THRESHOLD) actual_drain *= SYNTH_ACTIVE_COOLING_LOW_PRESSURE_PENALTY //Our cooling system can handle hot places okayish, but starts to cry at low pressures (reads: Effectively vents hot coolant thats been warmed up via internal heat-exchange as emergency measure and with very low efficiency) From 2e3d198c108d01e82a95bad4425df2fea209a05c Mon Sep 17 00:00:00 2001 From: DeltaFire Date: Sun, 2 Jan 2022 20:16:04 +0100 Subject: [PATCH 10/17] tm conflict avoidance --- .../mob/living/carbon/human/species_types/anthropomorph.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 744375db9c..334f76c487 100644 --- a/code/modules/mob/living/carbon/human/species_types/anthropomorph.dm +++ b/code/modules/mob/living/carbon/human/species_types/anthropomorph.dm @@ -57,4 +57,4 @@ exotic_bloodtype = "S" exotic_blood_color = BLOOD_COLOR_OIL allowed_limb_ids = list("mammal","aquatic","avian", "human") - species_category = SPECIES_CATEGORY_ROBOT + species_category = "robot" From 09afd40acc9481054b61bc9f55294fa42829e736 Mon Sep 17 00:00:00 2001 From: DeltaFire Date: Sun, 2 Jan 2022 20:23:40 +0100 Subject: [PATCH 11/17] tm conflict resolution 2 --- code/modules/mob/living/carbon/human/species.dm | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 83486dc0f2..fa46255ee6 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1176,10 +1176,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/takes_crit_damage = !HAS_TRAIT(H, TRAIT_NOCRITDAMAGE) if((H.health < H.crit_threshold) && takes_crit_damage) - if(!HAS_TRAIT(H, TRAIT_ROBOTIC_ORGANISM)) - H.adjustBruteLoss(1) - else - H.adjustFireLoss(1) //Robots melt instead of taking brute. + !HAS_TRAIT(H, TRAIT_ROBOTIC_ORGANISM) ? H.adjustBruteLoss(1) : H.adjustFireLoss(1) //Robots melt instead of taking brute. /datum/species/proc/spec_death(gibbed, mob/living/carbon/human/H) if(H) From fdeeacc279f6a14281eaa7322857c4687c6b71bf Mon Sep 17 00:00:00 2001 From: DeltaFire Date: Sun, 2 Jan 2022 21:27:13 +0100 Subject: [PATCH 12/17] and again --- code/modules/mob/living/carbon/human/species.dm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index fa46255ee6..93d2c47795 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1176,7 +1176,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) - !HAS_TRAIT(H, TRAIT_ROBOTIC_ORGANISM) ? H.adjustBruteLoss(1) : H.adjustFireLoss(1) //Robots melt instead of taking brute. + 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) From 1ba53e566e48086be70085c76f23857d25561c87 Mon Sep 17 00:00:00 2001 From: DeltaFire Date: Sun, 2 Jan 2022 23:25:55 +0100 Subject: [PATCH 13/17] miner stuff Miner suits can also suitlink. I can't just balance base cooling for lavaland because it's random now :) --- code/modules/mob/living/carbon/life.dm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index d5c4ab8e7d..bfd45f52f9 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -687,8 +687,10 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put /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/suit_item = get_item_by_slot(SLOT_WEAR_SUIT) + var/head_item = get_item_by_slot(SLOT_HEAD) + if((istype(head_item, /obj/item/clothing/head/helmet/space) && istype(suit_item, /obj/item/clothing/suit/space)) || (istype(head_item, /obj/item/clothing/head/hooded/explorer) && istype(suit_item, /obj/item/clothing/suit/hooded/explorer))) + return 1 //If you are wearing full EVA or lavaland hazard gear, assume it has been made to accomodate your cooling needs. var/datum/gas_mixture/environment = loc.return_air() if(!environment) return 0 From 46eb618f02816b8fe9623b2e5d23224c674a4760 Mon Sep 17 00:00:00 2001 From: DeltaFire Date: Mon, 3 Jan 2022 02:36:03 +0100 Subject: [PATCH 14/17] more hud stuff color coding percentage instead of blood volume indicator for if active cooling or not (small + and the bar changes to blue) --- code/_onclick/hud/human.dm | 34 +++++++++++++++++++++++----------- icons/mob/screen_synth.dmi | Bin 672 -> 806 bytes 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index fe8a716234..eb3016a06f 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -101,10 +101,10 @@ /atom/movable/screen/synth/coolant_counter/update_counter(mob/living/carbon/owner) ..() - var/valuecolor = "#FF6666" + var/valuecolor = "#ff2525" if(owner.stat == DEAD) maptext = "
ERR-0F
" - icon_state = "coolant-3" + icon_state = "coolant-31" return var/coolant_efficiency var/coolant @@ -115,23 +115,35 @@ coolant_efficiency = rand(1, 15) / 10 coolant = rand(1, 600) jammed-- - if(coolant > BLOOD_VOLUME_SAFE * owner.blood_ratio) - valuecolor = "#FFDDDD" + if(coolant > BLOOD_VOLUME_SAFE * owner.blood_ratio) //I unfortunately have to use this else-if stack because switch doesn't support variables. + valuecolor = "#4bbd34" + else if(coolant > BLOOD_VOLUME_OKAY * owner.blood_ratio) + valuecolor = "#dabb0d" else if(coolant > BLOOD_VOLUME_BAD * owner.blood_ratio) - valuecolor = "#FFAAAA" - maptext = "
[round(coolant,1)]
" + valuecolor = "#dd8109" + else if(coolant > BLOOD_VOLUME_SURVIVE * owner.blood_ratio) + valuecolor = "#e7520d" + maptext = "
[round((coolant / (BLOOD_VOLUME_NORMAL * owner.blood_ratio)) * 100, 1)]
" + var/efficiency_suffix + var/state_suffix switch(coolant_efficiency) if(-INFINITY to 0.4) - icon_state = "coolant-1" + efficiency_suffix = "1" if(0.4 to 0.75) - icon_state = "coolant-2" + efficiency_suffix = "2" if(0.75 to 0.95) - icon_state = "coolant-3" + efficiency_suffix = "3" if(0.95 to 1.3) - icon_state = "coolant-4" + efficiency_suffix = "4" else - icon_state = "coolant-5" + efficiency_suffix = "5" + var/obj/item/organ/lungs/ipc/L = owner.getorganslot(ORGAN_SLOT_LUNGS) + if(istype(L) && L.is_cooling) + state_suffix = "2" + else + state_suffix = "1" + icon_state = "coolant-[efficiency_suffix]-[state_suffix]" /atom/movable/screen/synth/coolant_counter/examine(mob/user) . = ..() diff --git a/icons/mob/screen_synth.dmi b/icons/mob/screen_synth.dmi index 6c3e6b3e79d7199bc8f7e8552e91b1ed48cd5d4b..95ecc5e2bbd6bde1dd25425c50d77c23fdd07ed7 100644 GIT binary patch delta 737 zcmV<70v`RK1*QgHiBL{Q4GJ0x0000DNk~Le0001h0001B1Oos704G#udH?_bAy7o!00DGTPE!Ct=GbNc z005AYTvC76P>G8(C9|j)C~C;XnO2mTn+joLQENoBS|bw7H6p=WV-n0YCc#`263jIr z!CX@k%r(VruCjuwp9?sm0dGZ$Y6Oms=>Px%7fD1xR9J=Wmc35HFc5&u&P?#4i}nJQ6Uh7E z>H?LSxGV~t63EPSLRpr)K;;B11`+n|Hm-ue@cJg z^*^OQ@cWK$znE&zTd*4@%|Es7OXy0Ggw*Om3L;HEY zzN=u!=mhjJ`zx&a|Dy>o_Yr2`_dj6Jpcdz9#BkF zMZmzow6wH~i;IGSf-WvDZEbC@e=EU3Ho(BZ0DlhP`1fW20004WQchCB1CCZAX+#9QWUi177n7^E!-1nm2(i$pA1jRx{6kr8TjNclPt)<#}A7S=eOx7=dQKFO0p~ zB|$TjTn*MQP`nexXxuJP%;c?7K7=5d`2eO&vykGG%jg5BqZBEwv~}2n2t_VZtjn`; z0416t1;sE!skIgq!wi+%K=7s>EYEtls9L00SLfM57R{U4kl<3ggYyyI8+%a8tWNHK zYJehZdleF#_m^)9@G0xr(I2IZ*8WE z^8jtlkR`@uAoSmIeB=}lBj?6X1&V(+$hMEle`8ykT=yHjQTi}5N)O`wOM1|v4$FFQ z-=Pl6deA+!h(kgTz9i-V=YJdM0ons~m^+7Vt_KIK2RQ$`k5+^nJAkqCU9=+P*a4J` z>Omp{t_O(>xE`c>K=t77Jp{TOa^%1QU5+@iaQ;Vn5Z43(VtNocka`f+MCn0jv>t>; o>p_%bl^&p88wT09E6vxiA7{UQcUpqhO8@`>07*qoM6N<$f^QBEVE_OC From 82177b9ecc67dd8eafb7d539c2af23e45b92d082 Mon Sep 17 00:00:00 2001 From: DeltaFire Date: Mon, 3 Jan 2022 03:33:35 +0100 Subject: [PATCH 15/17] oops --- code/_onclick/hud/human.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index eb3016a06f..8617d3e2ee 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -95,7 +95,7 @@ /atom/movable/screen/synth/coolant_counter icon = 'icons/mob/screen_synth.dmi' name = "Coolant System Readout" - icon_state = "coolant-3" + icon_state = "coolant-3-1" screen_loc = ui_coolant_display var/jammed = 0 @@ -104,7 +104,7 @@ var/valuecolor = "#ff2525" if(owner.stat == DEAD) maptext = "
ERR-0F
" - icon_state = "coolant-31" + icon_state = "coolant-3-1" return var/coolant_efficiency var/coolant From 6c5dabe8bc227883f9be29770ebefec20f1b7a9e Mon Sep 17 00:00:00 2001 From: DeltaFire Date: Mon, 3 Jan 2022 06:42:28 +0100 Subject: [PATCH 16/17] quirk removal fixes --- .../subsystem/processing/quirks.dm | 7 +++++ .../mob/living/carbon/human/species.dm | 26 +++++++++++++++---- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/code/controllers/subsystem/processing/quirks.dm b/code/controllers/subsystem/processing/quirks.dm index 74cd53b0ae..b3c8a6422f 100644 --- a/code/controllers/subsystem/processing/quirks.dm +++ b/code/controllers/subsystem/processing/quirks.dm @@ -48,6 +48,13 @@ PROCESSING_SUBSYSTEM_DEF(quirks) cli.prefs.save_character() if (!silent && LAZYLEN(cut)) to_chat(to_chat_target || user, "Some quirks have been cut from your character because of these quirks conflicting with your job assignment: [english_list(cut)].") + + var/mob/living/carbon/human/H = user + if(istype(H) && H.dna?.species) + var/datum/species/S = H.dna.species + if(S.remove_blacklisted_quirks(H)) + to_chat(to_chat_target || user, "Some quirks have been cut from your character due to them conflicting with your species: [english_list(S.removed_quirks)]") + /datum/controller/subsystem/processing/quirks/proc/quirk_path_by_name(name) return quirks[name] diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 93d2c47795..1c5bdb6114 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -581,16 +581,32 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) // shamelessly inspired by antag_datum.remove_blacklisted_quirks() /datum/species/proc/remove_blacklisted_quirks(mob/living/carbon/C) - var/mob/living/L = C.mind?.current - if(istype(L)) + . = 0 + if(istype(C)) if(!balance_point_values) - for(var/q in L.roundstart_quirks) + for(var/q in C.roundstart_quirks) var/datum/quirk/Q = q if(Q.type in blacklisted_quirks) - qdel(Q) removed_quirks += Q.type + . += 1 + qdel(Q) else - removed_quirks += SSquirks.filter_quirks(L.roundstart_quirks, blacklisted_quirks) + var/point_overhead = 0 + for(var/datum/quirk/Q as anything in C.roundstart_quirks) + if(Q.type in blacklisted_quirks) + point_overhead -= Q.value + removed_quirks += Q.type + . += 1 + qdel(Q) + if(point_overhead) + for(var/datum/quirk/Q as anything in C.roundstart_quirks) + if(Q.value > 0) + point_overhead -= Q.value + removed_quirks += Q.type + . += 1 + qdel(Q) + if(!point_overhead) + break // restore any quirks that we removed /datum/species/proc/restore_quirks(mob/living/carbon/C) From e7ed288cc25e1006c09996dfa7c0f971749349a2 Mon Sep 17 00:00:00 2001 From: DeltaFire Date: Sat, 22 Jan 2022 18:34:54 +0100 Subject: [PATCH 17/17] finishing touches suitlinking now tells you on examining the cooling system readout. miner gear suitlinking only works on the lavaland z. corruption has a medium-severity readout jamming event added to the pool. integrating coolant only counts as 40% of its volume for cooling efficiency purposes and is capped at adding at most 25% of current blood volume to cooling efficiency calculations. --- code/__DEFINES/atmospherics.dm | 18 +++++++++------- code/_onclick/hud/human.dm | 9 +++++++- .../mob/living/carbon/handle_corruption.dm | 8 ++++--- .../mob/living/carbon/human/human_defense.dm | 2 +- code/modules/mob/living/carbon/life.dm | 21 ++++++++++++++----- 5 files changed, 40 insertions(+), 18 deletions(-) diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index 8f23d89a0b..c9385e7e16 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -68,17 +68,19 @@ #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_MAX_PASSIVE_GAIN_TEMP 250 //Degrees C that a synth can be heated up to by their internal heat gain, provided their cooling is insufficient to mitigate it. -#define SYNTH_MIN_PASSIVE_COOLING_TEMP -30 //Degrees C a synth can cool towards at very high cooling efficiency. -#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 at a lower cap, this mostly counters low coolant levels) -#define SYNTH_MAX_COOLING_EFFICIENCY 1.5 //The maximum possible cooling efficiency one can achieve at optimal conditions. -#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 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_MAX_PASSIVE_GAIN_TEMP 250 //Degrees C that a synth can be heated up to by their internal heat gain, provided their cooling is insufficient to mitigate it. +#define SYNTH_MIN_PASSIVE_COOLING_TEMP -30 //Degrees C a synth can cool towards at very high cooling efficiency. +#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 at a lower cap, this mostly counters low coolant levels) +#define SYNTH_MAX_COOLING_EFFICIENCY 1.5 //The maximum possible cooling efficiency one can achieve at optimal conditions. +#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 SYNTH_ACTIVE_COOLING_LOW_PRESSURE_THRESHOLD 0.05 //At how much percentage of default pressure (or lower) active cooling gets a massive cost penalty. #define SYNTH_ACTIVE_COOLING_LOW_PRESSURE_PENALTY 2.5 //By how much is active cooling cost multiplied if in a very-low-pressure environment? #define SYNTH_ACTIVE_COOLING_MIN_ADJUSTMENT 5 //What is the minimum amount of temp you move towards the target point, even if it would be less with default calculations? +#define SYNTH_INTEGRATION_COOLANT_PENALTY 0.4 //Integrating coolant is multiplied with this for calculation of impact on passive cooling. +#define SYNTH_INTEGRATION_COOLANT_CAP 0.25 //Integrating coolant is capped at counting as current_blood * this number. This is so you can't just run on salglu or whatever. #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. diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 8617d3e2ee..83b8d7be48 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -153,17 +153,24 @@ var/coolant var/total_efficiency var/environ_efficiency + var/suitlink_efficiency if(!jammed) coolant = owner.blood_volume total_efficiency = owner.get_cooling_efficiency() environ_efficiency = owner.get_environment_cooling_efficiency() + suitlink_efficiency = owner.check_suitlinking() else coolant = rand(1, 600) total_efficiency = rand(1, 15) / 10 environ_efficiency = rand(1, 20) / 10 . += "Performing internal cooling system diagnostics:" . += "Coolant level: [coolant] units, [round((coolant / (BLOOD_VOLUME_NORMAL * owner.blood_ratio)) * 100, 0.1)] percent" - . += "Current Cooling Efficiency: [round(total_efficiency * 100, 0.1)] percent, environment viability: [round(environ_efficiency * 100, 0.1)] percent." + . += "Current Cooling Efficiency: [round(total_efficiency * 100, 0.1)] percent, [suitlink_efficiency ? "active suitlink detected, guaranteeing [suitlink_efficiency * 100]% environmental cooling efficiency." : "environment viability: [round(environ_efficiency * 100, 0.1)] percent."]" + +/atom/movable/screen/synth/coolant_counter/proc/jam(amount, cap = 20) + if(jammed > cap) //Preserve previous more impactful event. + return + jammed = min(jammed + amount, cap) /datum/hud/human/New(mob/living/carbon/human/owner) ..() diff --git a/code/modules/mob/living/carbon/handle_corruption.dm b/code/modules/mob/living/carbon/handle_corruption.dm index 5ac2a2f616..b56752453b 100644 --- a/code/modules/mob/living/carbon/handle_corruption.dm +++ b/code/modules/mob/living/carbon/handle_corruption.dm @@ -37,7 +37,7 @@ var/list/whatmighthappen = list() whatmighthappen += list("avoided" = 3, "dropthing" = 1, "movetile" = 1, "shortdeaf" = 1, "flopover" = 1, "nutriloss" = 1, "selfflash" = 1, "harmies" = 1) if(corruption >= CORRUPTION_THRESHHOLD_MAJOR) - whatmighthappen += list("longdeaf" = 1, "longknockdown" = 1, "shortlimbdisable" = 1, "shortblind" = 1, "shortstun" = 1, "shortmute" = 1, "vomit" = 1, "halluscinate" = 1) + whatmighthappen += list("longdeaf" = 1, "longknockdown" = 1, "shortlimbdisable" = 1, "shortblind" = 1, "shortstun" = 1, "shortmute" = 1, "vomit" = 1, "hallucinate" = 1, "jamcoolanthud" = 1) if(corruption >= CORRUPTION_THRESHHOLD_CRITICAL) whatmighthappen += list("receporgandamage" = 1, "longlimbdisable" = 1, "blindmutedeaf" = 1, "longstun" = 1, "sleep" = 1, "inducetrauma" = 1, "amplifycorrupt" = 1, "changetemp" = 1) var/event = pickweight(whatmighthappen) @@ -97,8 +97,10 @@ if("vomit") to_chat(src, "Ejecting contaminant.") vomit() - if("halluscinate") + if("hallucinate") hallucination += 20 //Doesn't give a cue + if("jamcoolanthud") + hud_used.coolant_display.jam(10) if("receporgandamage") adjustOrganLoss(ORGAN_SLOT_EARS, rand(10, 20)) adjustOrganLoss(ORGAN_SLOT_EYES, rand(10, 20)) @@ -159,7 +161,7 @@ /mob/living/carbon/proc/forcesleep(time = 100) to_chat(src, "Preparations complete, powering down.") - Sleeping(time, 0) + Sleeping(time) #undef CORRUPTION_CHECK_INTERVAL diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index e1f4055998..71573abc90 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -416,7 +416,7 @@ severity *= 0.5 var/do_not_stun = FALSE if(HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM)) - hud_used?.coolant_display.jammed = min(round(hud_used.coolant_display.jammed + (severity / 10),1), 20) //Messes up the cooling system readout. + hud_used?.coolant_display.jam(round(severity / 10, 1)) //Messes up the cooling system readout. severity *= 0.5 //Robotpeople take less limb damage, but instead suffer system corruption (see carbon emp_act) do_not_stun = TRUE for(var/obj/item/bodypart/L in src.bodyparts) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index bfd45f52f9..6950f75172 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -679,7 +679,8 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put if(!HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM)) return 1 - var/blood_effective_volume = blood_volume + integrating_blood + var/integration_bonus = min(blood_volume * SYNTH_INTEGRATION_COOLANT_CAP, integrating_blood * SYNTH_INTEGRATION_COOLANT_PENALTY) //Integration blood somewhat helps, though only at 40% impact and to a cap of 25% of current blood level. + var/blood_effective_volume = blood_volume + integration_bonus 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() @@ -687,10 +688,9 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put /mob/living/carbon/proc/get_environment_cooling_efficiency() - var/suit_item = get_item_by_slot(SLOT_WEAR_SUIT) - var/head_item = get_item_by_slot(SLOT_HEAD) - if((istype(head_item, /obj/item/clothing/head/helmet/space) && istype(suit_item, /obj/item/clothing/suit/space)) || (istype(head_item, /obj/item/clothing/head/hooded/explorer) && istype(suit_item, /obj/item/clothing/suit/hooded/explorer))) - return 1 //If you are wearing full EVA or lavaland hazard gear, assume it has been made to accomodate your cooling needs. + var/suitlink = check_suitlinking() + if(suitlink) + return suitlink //If you are wearing full EVA or lavaland hazard gear (on lavaland), assume it has been made to accomodate your cooling needs. var/datum/gas_mixture/environment = loc.return_air() if(!environment) return 0 @@ -704,7 +704,18 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put 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 +/mob/living/carbon/proc/check_suitlinking() + var/suit_item = get_item_by_slot(SLOT_WEAR_SUIT) + var/head_item = get_item_by_slot(SLOT_HEAD) + var/turf/T = get_turf(src) + + if(istype(head_item, /obj/item/clothing/head/helmet/space) && istype(suit_item, /obj/item/clothing/suit/space)) + return 1 + + if(T && is_mining_level(T.z) && istype(head_item, /obj/item/clothing/head/hooded/explorer) && istype(suit_item, /obj/item/clothing/suit/hooded/explorer)) + return 1 + return 0 ///////// //LIVER//