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.
This commit is contained in:
mwerezak
2014-06-20 18:18:02 -04:00
parent 032061522b
commit cf5ff7e992
8 changed files with 63 additions and 35 deletions

View File

@@ -293,6 +293,7 @@
var/splint = "" var/splint = ""
var/internal_bleeding = "" var/internal_bleeding = ""
var/lung_ruptured = "" var/lung_ruptured = ""
var/infection = ""
for(var/datum/wound/W in e.wounds) if(W.internal) for(var/datum/wound/W in e.wounds) if(W.internal)
internal_bleeding = "<br>Internal bleeding" internal_bleeding = "<br>Internal bleeding"
break break
@@ -308,6 +309,13 @@
robot = "Prosthetic:" robot = "Prosthetic:"
if(e.open) if(e.open)
open = "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 var/unknown_body = 0
for(var/I in e.implants) for(var/I in e.implants)

View File

@@ -161,7 +161,7 @@ REAGENT SCANNER
if(e.status & ORGAN_BROKEN) 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))) 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." 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." user << "\red Infected wound detected in subject [limb]. Disinfection recommended."
for(var/name in H.organs_by_name) for(var/name in H.organs_by_name)

View File

@@ -674,20 +674,27 @@
else else
loc_temp = environment.temperature 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.phoron < MOLES_PHORON_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.phoron < MOLES_PHORON_VISIBLE)
return // Temperatures are within normal ranges, fuck all this processing. ~Ccomp return // Temperatures are within normal ranges, fuck all this processing. ~Ccomp
//Body temperature adjusts depending on surrounding atmosphere based on your thermal protection //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. 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) if(thermal_protection < 1)
var/amt = min((1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_COLD_DIVISOR), BODYTEMP_COOLING_MAX) temp_adj = (1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_COLD_DIVISOR) //this will be negative
bodytemperature += amt else if (loc_temp > bodytemperature) //Place is hotter than we are
else if (loc_temp > species.heat_level_1) //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. 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) if(thermal_protection < 1)
var/amt = min((1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR), BODYTEMP_HEATING_MAX) temp_adj = (1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR)
bodytemperature += amt
//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. // +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt.
if(bodytemperature > species.heat_level_1) if(bodytemperature > species.heat_level_1)
@@ -738,12 +745,8 @@
bodytemperature += 0.5 * TEMPERATURE_DAMAGE_COEFFICIENT //Synthetics suffer overheating in a vaccuum. ~Z bodytemperature += 0.5 * TEMPERATURE_DAMAGE_COEFFICIENT //Synthetics suffer overheating in a vaccuum. ~Z
else else
if(species && species.flags & IS_SYNTHETIC)
bodytemperature += 1 * TEMPERATURE_DAMAGE_COEFFICIENT
if( !(COLD_RESISTANCE in mutations)) if( !(COLD_RESISTANCE in mutations))
adjustBruteLoss( LOW_PRESSURE_DAMAGE ) apply_damage(LOW_PRESSURE_DAMAGE, BRUTE, used_weapon = "Low Pressure")
pressure_alert = -2 pressure_alert = -2
else else
pressure_alert = -1 pressure_alert = -1
@@ -771,22 +774,26 @@
return temp_change return temp_change
*/ */
proc/stabilize_temperature_from_calories() proc/stabilize_body_temperature()
var/body_temperature_difference = 310.15 - bodytemperature 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) if (abs(body_temperature_difference) < 0.5)
return //fuck this precision return //fuck this precision
switch(bodytemperature) 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. if(nutrition >= 2) //If we are very, very cold we'll use up quite a bit of nutriment to heat us up.
nutrition -= 2 nutrition -= 2
var/recovery_amt = max((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM) var/recovery_amt = max((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM)
// log_debug("Cold. Difference = [body_temperature_difference]. Recovering [recovery_amt]") // log_debug("Cold. Difference = [body_temperature_difference]. Recovering [recovery_amt]")
bodytemperature += 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 var/recovery_amt = body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR
// log_debug("Norm. Difference = [body_temperature_difference]. Recovering [recovery_amt]") // log_debug("Norm. Difference = [body_temperature_difference]. Recovering [recovery_amt]")
bodytemperature += 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...~ //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 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]") // log_debug("Hot. Difference = [body_temperature_difference]. Recovering [recovery_amt]")
@@ -1087,7 +1094,7 @@
else //ALIVE. LIGHTS ARE ON else //ALIVE. LIGHTS ARE ON
updatehealth() //TODO updatehealth() //TODO
if(!in_stasis) if(!in_stasis)
stabilize_temperature_from_calories() //Body temperature adjusts itself stabilize_body_temperature() //Body temperature adjusts itself
handle_organs() //Optimized. handle_organs() //Optimized.
handle_blood() handle_blood()

View File

@@ -29,6 +29,9 @@
var/heat_level_2 = 400 // Heat damage level 2 above this point. var/heat_level_2 = 400 // Heat damage level 2 above this point.
var/heat_level_3 = 1000 // Heat damage level 2 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/darksight = 2
var/hazard_high_pressure = HAZARD_HIGH_PRESSURE // Dangerously high pressure. var/hazard_high_pressure = HAZARD_HIGH_PRESSURE // Dangerously high pressure.
var/warning_high_pressure = WARNING_HIGH_PRESSURE // High pressure warning. var/warning_high_pressure = WARNING_HIGH_PRESSURE // High pressure warning.
@@ -279,6 +282,8 @@
heat_level_2 = 3000 heat_level_2 = 3000
heat_level_3 = 4000 heat_level_3 = 4000
body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not
flags = IS_WHITELISTED | NO_BREATHE | REQUIRE_LIGHT | NO_SCAN | IS_PLANT | RAD_ABSORB | NO_BLOOD | IS_SLOW | NO_PAIN flags = IS_WHITELISTED | NO_BREATHE | REQUIRE_LIGHT | NO_SCAN | IS_PLANT | RAD_ABSORB | NO_BLOOD | IS_SLOW | NO_PAIN
blood_color = "#004400" blood_color = "#004400"
@@ -327,6 +332,8 @@
heat_level_2 = 3000 heat_level_2 = 3000
heat_level_3 = 4000 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 flags = IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | IS_SYNTHETIC
blood_color = "#1F181F" blood_color = "#1F181F"

View File

@@ -5,6 +5,9 @@
var/list/datum/autopsy_data/autopsy_data = list() var/list/datum/autopsy_data/autopsy_data = list()
var/list/trace_chemicals = list() // traces of chemicals in the organ, 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 // 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() proc/process()
return 0 return 0
@@ -82,7 +85,7 @@
//Moving makes open wounds get infected much faster //Moving makes open wounds get infected much faster
if (E.wounds.len) if (E.wounds.len)
for(var/datum/wound/W in E.wounds) for(var/datum/wound/W in E.wounds)
if (W.can_infect()) if (W.infection_check())
W.germ_level += 1 W.germ_level += 1
//Special effects for limbs. //Special effects for limbs.

View File

@@ -40,8 +40,6 @@
var/obj/item/hidden = null var/obj/item/hidden = null
var/list/implants = list() 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 // how often wounds should be updated, a higher number means less often
var/wound_update_accuracy = 1 var/wound_update_accuracy = 1
@@ -345,7 +343,7 @@ This function completely restores a damaged organ to perfect condition.
//Syncing germ levels with external wounds //Syncing germ levels with external wounds
for(var/datum/wound/W in wounds) for(var/datum/wound/W in wounds)
//Open wounds can become infected //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++ W.germ_level++
//Infected wounds raise the organ's germ level //Infected wounds raise the organ's germ level
@@ -357,11 +355,16 @@ This function completely restores a damaged organ to perfect condition.
if (antibiotics > 5) if (antibiotics > 5)
if (prob(4*antibiotics)) germ_level-- if (prob(4*antibiotics)) germ_level--
if(germ_level > GANGREN_LEVEL_ONE && prob(round(germ_level/10))) //aiming for a light infection to become serious after 40 minutes, standing still 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(prob(round(germ_level/10))) //aiming for a light infection to become serious after 40 minutes, standing still
germ_level += 1 germ_level += 1
owner.adjustToxLoss(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++ germ_level++
owner.adjustToxLoss(1) owner.adjustToxLoss(1)
@@ -691,9 +694,9 @@ This function completely restores a damaged organ to perfect condition.
/datum/organ/external/proc/get_damage() //returns total damage /datum/organ/external/proc/get_damage() //returns total damage
return max(brute_dam + burn_dam - perma_injury, perma_injury) //could use health? 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) for(var/datum/wound/W in wounds)
if(W.germ_level > 100) if(W.germ_level > 150)
return 1 return 1
return 0 return 0

View File

@@ -119,7 +119,7 @@
// checks if wound is considered open for external infections // 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 // 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) if (is_treated() && damage < 10)
return 0 return 0
if (disinfected) if (disinfected)

View File

@@ -38,7 +38,7 @@
#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_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_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_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_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_HEAT_DAMAGE_LIMIT 360.15 // The limit the human body can take before it starts taking damage from heat.
@@ -771,6 +771,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. //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_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 GERM_LEVEL_MOVE_CAP 200 //maximum germ level you can reach by running around
#define GANGREN_LEVEL_ONE 100 #define INFECTION_LEVEL_ONE 100
#define GANGREN_LEVEL_TWO 1000 #define INFECTION_LEVEL_TWO 1000
#define GANGREN_LEVEL_TERMINAL 2500 #define INFECTION_LEVEL_TERMINAL 2500