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 0000000000..6c3e6b3e79
Binary files /dev/null and b/icons/mob/screen_synth.dmi differ