From 6e256506e3db16fc870cc7385fd04e8c1a8ca3db Mon Sep 17 00:00:00 2001 From: mwerezak Date: Fri, 20 Jun 2014 18:18:02 -0400 Subject: [PATCH] Body temperature fixes and updates Body temperature regulation is now based on species, and environmental temperature now respects the air density when affecting living/humans. This also fixes some bugs with heat/cold protection handling and improves the way synthetic species body temperatures are handled to be much more logical. IPCs always gain temperature but cool down because of their environment. When the heat transfer to the environment is reduced because of the lack of air, this will cause IPCs to heat up. As well, having an infection will increase your body temperature, and body scanners now detect infections. Conflicts: code/modules/mob/living/carbon/human/life.dm code/modules/mob/living/carbon/species.dm --- code/game/machinery/adv_med.dm | 8 ++++ code/game/objects/items/devices/scanners.dm | 2 +- code/modules/mob/living/carbon/human/life.dm | 48 +++++++++++--------- code/modules/mob/living/carbon/species.dm | 12 ++++- code/modules/organs/organ.dm | 5 +- code/modules/organs/organ_external.dm | 21 +++++---- code/modules/organs/wound.dm | 2 +- code/setup.dm | 12 ++--- 8 files changed, 70 insertions(+), 40 deletions(-) diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 467c42b33d8..cd273fdeb20 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -293,6 +293,7 @@ var/splint = "" var/internal_bleeding = "" var/lung_ruptured = "" + var/infection = "" for(var/datum/wound/W in e.wounds) if(W.internal) internal_bleeding = "
Internal bleeding" break @@ -308,6 +309,13 @@ robot = "Prosthetic:" if(e.open) open = "Open:" + switch (e.germ_level) + if (150 to 500) + infection = "Infection - Minor:" + if (500 to INFECTION_LEVEL_TWO) + infection = "Infection - Severe:" + if (INFECTION_LEVEL_TWO to INFINITY) + infection = "Infection - Septic:" var/unknown_body = 0 for(var/I in e.implants) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 8e0c4b03e8f..95fb8cdec87 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -169,7 +169,7 @@ REAGENT SCANNER if(e.status & ORGAN_BROKEN) if(((e.name == "l_arm") || (e.name == "r_arm") || (e.name == "l_leg") || (e.name == "r_leg")) && (!(e.status & ORGAN_SPLINTED))) user << "\red Unsecured fracture in subject [limb]. Splinting recommended for transport." - if(e.is_infected()) + if(e.has_infected_wound()) user << "\red Infected wound detected in subject [limb]. Disinfection recommended." for(var/name in H.organs_by_name) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 161ad5a2c82..acff3269842 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -739,23 +739,29 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc else loc_temp = environment.temperature - if(adjusted_pressure < species.warning_low_pressure && adjusted_pressure > species.warning_low_pressure && abs(loc_temp - 293.15) < 20 && abs(bodytemperature - 310.14) < 0.5 && environment.toxins < MOLES_PLASMA_VISIBLE) + if(adjusted_pressure < species.warning_high_pressure && adjusted_pressure > species.warning_low_pressure && abs(loc_temp - bodytemperature) < 20 && bodytemperature < species.heat_level_1 && bodytemperature > species.cold_level_1 && environment.toxins < MOLES_PLASMA_VISIBLE) return // Temperatures are within normal ranges, fuck all this processing. ~Ccomp - //After then, it reacts to the surrounding atmosphere based on your thermal protection if(!on_fire) //If you're on fire, you do not heat up or cool down based on surrounding gases - //Body temperature adjusts depending on surrounding atmosphere based on your thermal protection - if(loc_temp < species.cold_level_1) //Place is colder than we are + var/temp_adj = 0 + if(loc_temp < bodytemperature) //Place is colder than we are var/thermal_protection = get_cold_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(thermal_protection < 1) - var/amt = min((1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_COLD_DIVISOR), BODYTEMP_COOLING_MAX) - bodytemperature += amt - else if (loc_temp > species.heat_level_1) //Place is hotter than we are + temp_adj = (1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_COLD_DIVISOR) //this will be negative + else if (loc_temp > bodytemperature) //Place is hotter than we are var/thermal_protection = get_heat_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(thermal_protection < 1) - var/amt = min((1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR), BODYTEMP_HEATING_MAX) - bodytemperature += amt + temp_adj = (1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR) + + //Use heat transfer as proportional to the gas density. However, we only care about the relative density vs standard 101 kPa/20 C air. Therefore we can use mole ratios + var/relative_density = environment.total_moles() / MOLES_CELLSTANDARD + temp_adj *= relative_density + + if (temp_adj > BODYTEMP_HEATING_MAX) temp_adj = BODYTEMP_HEATING_MAX + if (temp_adj < BODYTEMP_COOLING_MAX) temp_adj = BODYTEMP_COOLING_MAX + bodytemperature += temp_adj + // +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt. if(bodytemperature > species.heat_level_1) @@ -807,12 +813,8 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc bodytemperature += 0.5 * TEMPERATURE_DAMAGE_COEFFICIENT //Synthetics suffer overheating in a vaccuum. ~Z else - - if(species && species.flags & IS_SYNTHETIC) - bodytemperature += 1 * TEMPERATURE_DAMAGE_COEFFICIENT - if( !(M_RESIST_COLD in mutations)) - adjustBruteLoss( LOW_PRESSURE_DAMAGE ) + apply_damage(LOW_PRESSURE_DAMAGE, BRUTE, used_weapon = "Low Pressure") pressure_alert = -2 else pressure_alert = -1 @@ -825,7 +827,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc handle_fire() if(..()) return - var/thermal_protection = get_heat_protection(30000) //If you don't have fire suit level protection, you get a temperature increase + var/thermal_protection = get_heat_protection(10000) //If you don't have fire suit level protection, you get a temperature increase if((1 - thermal_protection) > 0.0001) bodytemperature += BODYTEMP_HEATING_MAX return @@ -850,22 +852,26 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc return temp_change */ - proc/stabilize_temperature_from_calories() - var/body_temperature_difference = 310.15 - bodytemperature + proc/stabilize_body_temperature() + if (species && species.flags & IS_SYNTHETIC) + bodytemperature += species.synth_temp_gain //that CPU/posibrain just keeps putting out heat. + return + + var/body_temperature_difference = species.body_temperature - bodytemperature if (abs(body_temperature_difference) < 0.5) return //fuck this precision switch(bodytemperature) - if(-INFINITY to 260.15) //260.15 is 310.15 - 50, the temperature where you start to feel effects. + if(-INFINITY to species.cold_level_1) //260.15 is 310.15 - 50, the temperature where you start to feel effects. if(nutrition >= 2) //If we are very, very cold we'll use up quite a bit of nutriment to heat us up. nutrition -= 2 var/recovery_amt = max((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM) // log_debug("Cold. Difference = [body_temperature_difference]. Recovering [recovery_amt]") bodytemperature += recovery_amt - if(260.15 to 360.15) + if(species.cold_level_1 to species.heat_level_1) var/recovery_amt = body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR // log_debug("Norm. Difference = [body_temperature_difference]. Recovering [recovery_amt]") bodytemperature += recovery_amt - if(360.15 to INFINITY) //360.15 is 310.15 + 50, the temperature where you start to feel effects. + if(species.heat_level_1 to INFINITY) //360.15 is 310.15 + 50, the temperature where you start to feel effects. //We totally need a sweat system cause it totally makes sense...~ var/recovery_amt = min((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), -BODYTEMP_AUTORECOVERY_MINIMUM) //We're dealing with negative numbers // log_debug("Hot. Difference = [body_temperature_difference]. Recovering [recovery_amt]") @@ -1188,7 +1194,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc updatehealth() //TODO if(!in_stasis) - stabilize_temperature_from_calories() //Body temperature adjusts itself + stabilize_body_temperature() //Body temperature adjusts itself handle_organs() //Optimized. handle_blood() diff --git a/code/modules/mob/living/carbon/species.dm b/code/modules/mob/living/carbon/species.dm index 500413635dd..47bf2a4fbe5 100644 --- a/code/modules/mob/living/carbon/species.dm +++ b/code/modules/mob/living/carbon/species.dm @@ -26,7 +26,10 @@ var/heat_level_1 = 360 // Heat damage level 1 above this point. var/heat_level_2 = 400 // Heat damage level 2 above this point. - var/heat_level_3 = 1000 // Heat damage level 3 above this point. + var/heat_level_3 = 1000 // Heat damage level 2 above this point. + + var/body_temperature = 310.15 //non-IS_SYNTHETIC species will try to stabilize at this temperature. (also affects temperature processing) + var/synth_temp_gain = 0 //IS_SYNTHETIC species will gain this much temperature every second var/darksight = 2 var/hazard_high_pressure = HAZARD_HIGH_PRESSURE // Dangerously high pressure. @@ -370,6 +373,11 @@ flags = NO_BREATHE | REQUIRE_LIGHT | NO_SCAN | IS_PLANT | RAD_ABSORB | NO_BLOOD | IS_SLOW | NO_PAIN + body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not + + blood_color = "#004400" + flesh_color = "#907E4A" + /datum/species/diona/handle_post_spawn(var/mob/living/carbon/human/H) H.gender = NEUTER @@ -415,6 +423,8 @@ heat_level_2 = 3000 heat_level_3 = 4000 + synth_temp_gain = 6.7 //round(40 / BODYTEMP_COLD_DIVISOR, 0.1) //this should cause IPCs to stabilize at ~60 C in a 20 C environment. Based on some CPU operating temperatures + flags = IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | IS_SYNTHETIC | NO_INTORGANS flesh_color = "#AAAAAA" diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 146ec7be165..a61c18e808e 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -5,6 +5,9 @@ var/list/datum/autopsy_data/autopsy_data = list() var/list/trace_chemicals = list() // traces of chemicals in the organ, // links chemical IDs to number of ticks for which they'll stay in the blood + + var/germ_level = 0 // INTERNAL germs inside the organ, this is BAD if it's greater than INFECTION_LEVEL_ONE + proc/process() return 0 @@ -82,7 +85,7 @@ //Moving makes open wounds get infected much faster if (E.wounds.len) for(var/datum/wound/W in E.wounds) - if (W.can_infect()) + if (W.infection_check()) W.germ_level += 1 //Special effects for limbs. diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 85b3d88ce21..47b7313496c 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -40,8 +40,6 @@ var/obj/item/hidden = null var/list/implants = list() - // INTERNAL germs inside the organ, this is BAD if it's greater 0 - var/germ_level = 0 // how often wounds should be updated, a higher number means less often var/wound_update_accuracy = 1 @@ -350,7 +348,7 @@ This function completely restores a damaged organ to perfect condition. //Syncing germ levels with external wounds for(var/datum/wound/W in wounds) //Open wounds can become infected - if (owner.germ_level > W.germ_level && W.can_infect()) + if (owner.germ_level > W.germ_level && W.infection_check()) W.germ_level++ //Infected wounds raise the organ's germ level @@ -361,12 +359,17 @@ This function completely restores a damaged organ to perfect condition. var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") if (antibiotics > 5) if (prob(4*antibiotics)) germ_level-- + + if(germ_level > INFECTION_LEVEL_ONE) + //having an infection raises your body temperature + var/temperature_increase = (owner.species.heat_level_1 - owner.species.body_temperature - 1)* min(germ_level/INFECTION_LEVEL_TWO, 1) + owner.bodytemperature += temperature_increase - if(germ_level > GANGREN_LEVEL_ONE && prob(round(germ_level/10))) //aiming for a light infection to become serious after 40 minutes, standing still - germ_level += 1 - owner.adjustToxLoss(1) + if(prob(round(germ_level/10))) //aiming for a light infection to become serious after 40 minutes, standing still + germ_level += 1 + owner.adjustToxLoss(1) - if(germ_level > GANGREN_LEVEL_TWO && antibiotics < 30) //overdosing is necessary to stop severe infections + if(germ_level > INFECTION_LEVEL_TWO && antibiotics < 30) //overdosing is necessary to stop severe infections germ_level++ owner.adjustToxLoss(1) @@ -731,9 +734,9 @@ This function completely restores a damaged organ to perfect condition. /datum/organ/external/proc/get_damage() //returns total damage return max(brute_dam + burn_dam - perma_injury, perma_injury) //could use health? -/datum/organ/external/proc/is_infected() +/datum/organ/external/proc/has_infected_wound() for(var/datum/wound/W in wounds) - if(W.germ_level > 100) + if(W.germ_level > 150) return 1 return 0 diff --git a/code/modules/organs/wound.dm b/code/modules/organs/wound.dm index a789248627f..e2763d4697a 100644 --- a/code/modules/organs/wound.dm +++ b/code/modules/organs/wound.dm @@ -119,7 +119,7 @@ // checks if wound is considered open for external infections // untreated cuts (and bleeding bruises) and burns are possibly infectable, chance higher if wound is bigger - proc/can_infect() + proc/infection_check() if (is_treated() && damage < 10) return 0 if (disinfected) diff --git a/code/setup.dm b/code/setup.dm index 045b852d610..43a908eef23 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -38,16 +38,16 @@ #define BODYTEMP_AUTORECOVERY_MINIMUM 10 //Minimum amount of kelvin moved toward 310.15K per tick. So long as abs(310.15 - bodytemp) is more than 50. #define BODYTEMP_COLD_DIVISOR 6 //Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is lower than their body temperature. Make it lower to lose bodytemp faster. #define BODYTEMP_HEAT_DIVISOR 6 //Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is higher than their body temperature. Make it lower to gain bodytemp faster. -#define BODYTEMP_COOLING_MAX 30 //The maximum number of degrees that your body can cool in 1 tick, when in a cold area. +#define BODYTEMP_COOLING_MAX -30 //The maximum number of degrees that your body can cool in 1 tick, when in a cold area. #define BODYTEMP_HEATING_MAX 30 //The maximum number of degrees that your body can heat up in 1 tick, when in a hot area. #define BODYTEMP_HEAT_DAMAGE_LIMIT 360.15 // The limit the human body can take before it starts taking damage from heat. #define BODYTEMP_COLD_DAMAGE_LIMIT 260.15 // The limit the human body can take before it starts taking damage from coldness. #define SPACE_HELMET_MIN_COLD_PROTECITON_TEMPERATURE 2.0 //what min_cold_protection_temperature is set to for space-helmet quality headwear. MUST NOT BE 0. -#define SPACE_HELMET_MAX_HEAT_PROTECITON_TEMPERATURE 5000 +#define SPACE_HELMET_MAX_HEAT_PROTECITON_TEMPERATURE 10000 #define SPACE_SUIT_MIN_COLD_PROTECITON_TEMPERATURE 2.0 //what min_cold_protection_temperature is set to for space-suit quality jumpsuits or suits. MUST NOT BE 0. -#define SPACE_SUIT_MAX_HEAT_PROTECITON_TEMPERATURE 5000 //These need better heat protect +#define SPACE_SUIT_MAX_HEAT_PROTECITON_TEMPERATURE 10000 //These need better heat protect #define FIRESUIT_MAX_HEAT_PROTECITON_TEMPERATURE 30000 //what max_heat_protection_temperature is set to for firesuit quality headwear. MUST NOT BE 0. #define FIRE_HELMET_MAX_HEAT_PROTECITON_TEMPERATURE 30000 //for fire helmet quality items (red and white hardhats) #define HELMET_MIN_COLD_PROTECITON_TEMPERATURE 160 //For normal helmets @@ -866,6 +866,6 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse //These numbers have been calculated so that an untreated cut will become a serious infection after 50 minutes. #define GERM_LEVEL_AMBIENT 110 //maximum germ level you can reach by standing still #define GERM_LEVEL_MOVE_CAP 200 //maximum germ level you can reach by running around -#define GANGREN_LEVEL_ONE 100 -#define GANGREN_LEVEL_TWO 1000 -#define GANGREN_LEVEL_TERMINAL 2500 +#define INFECTION_LEVEL_ONE 100 +#define INFECTION_LEVEL_TWO 1000 +#define INFECTION_LEVEL_TERMINAL 2500