From 5f1c555177295c70dc1b783500ee6f72c0677abc Mon Sep 17 00:00:00 2001 From: DeltaFire <46569814+DeltaFire15@users.noreply.github.com> Date: Fri, 13 Sep 2024 16:46:38 +0200 Subject: [PATCH] [Semi-Experimental] The coldbloodening (#2684) --- code/__DEFINES/traits.dm | 2 + code/_globalvars/traits.dm | 3 +- code/modules/mob/living/carbon/human/life.dm | 4 +- .../mob/living/carbon/human/species.dm | 27 ++++---- code/modules/mob/living/carbon/life.dm | 4 ++ code/modules/mob/living/life.dm | 3 + nsv13.dme | 3 + nsv13/code/__DEFINES/atmospherics.dm | 17 +++++ nsv13/code/datums/mood_events/nsv_events.dm | 18 +++-- .../modules/mob/living/carbon/human/human.dm | 4 ++ .../mob/living/carbon/human/nsv_species.dm | 39 +++++++++++ .../human/species_types/nsv_lizardpeople.dm | 67 +++++++++++++++++++ nsv13/code/modules/mob/living/nsv_life.dm | 46 +++++++++++++ 13 files changed, 215 insertions(+), 22 deletions(-) create mode 100644 nsv13/code/modules/mob/living/carbon/human/nsv_species.dm create mode 100644 nsv13/code/modules/mob/living/carbon/human/species_types/nsv_lizardpeople.dm create mode 100644 nsv13/code/modules/mob/living/nsv_life.dm diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 7b3ccedb781..801955563f1 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -241,6 +241,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_SOMMELIER "sommelier" // shows different booze power flavor texts #define TRAIT_BARMASTER "bar_master" // always can identify reagents #define TRAIT_HIVE_BURNT "hive-burnt" +///Prevents natural body temperature stabilization. +#define TRAIT_COLDBLOODED "cold_blooded" //NSV13 species trait. // You can stare into the abyss, but it does not stare back. // You're immune to the hallucination effect of the supermatter, either diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm index 952feff6854..5299a5d4bd6 100644 --- a/code/_globalvars/traits.dm +++ b/code/_globalvars/traits.dm @@ -110,7 +110,8 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_NICE_SHOT" = TRAIT_NICE_SHOT, "TRAIT_ALWAYS_STUBS" = TRAIT_ALWAYS_STUBS, "TRAIT_NAIVE" = TRAIT_NAIVE, - "TRAIT_DROPS_ITEMS_ON_DEATH" = TRAIT_DROPS_ITEMS_ON_DEATH + "TRAIT_DROPS_ITEMS_ON_DEATH" = TRAIT_DROPS_ITEMS_ON_DEATH, + "TRAIT_COLDBLOODED" = TRAIT_COLDBLOODED//NSV13 ), /obj/item/bodypart = list( "TRAIT_PARALYSIS" = TRAIT_PARALYSIS diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 32758526664..1aad4689f04 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -245,7 +245,7 @@ thermal_protection += THERMAL_PROTECTION_HAND_RIGHT - return min(1,thermal_protection) + return min(1,round(thermal_protection, 0.001)) //NSV13 - rounding because sure, lets split this into 11 values, decimal precision will NOT mess us up :) //See proc/get_heat_protection_flags(temperature) for the description of this proc. /mob/living/carbon/human/proc/get_cold_protection_flags(temperature) @@ -302,7 +302,7 @@ if(thermal_protection_flags & HAND_RIGHT) thermal_protection += THERMAL_PROTECTION_HAND_RIGHT - return min(1,thermal_protection) + return min(1,round(thermal_protection, 0.001)) //NSV13 - rounding because sure, lets split this into 11 values, decimal precision will NOT mess us up :) /mob/living/carbon/human/handle_random_events() //Puke if toxloss is too high diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index aecc0b67dd0..7318e3ec06a 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1883,27 +1883,26 @@ GLOBAL_LIST_EMPTY(roundstart_races) //Body temperature is adjusted in two parts: first there your body tries to naturally preserve homeostasis (shivering/sweating), then it reacts to the surrounding environment //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 - if(H.stat != DEAD) - natural = H.natural_bodytemperature_stabilization() + + //NSV13 - segment adjusted due to jank. + var/natural = 0 + if(H.stat != DEAD) + natural = H.natural_bodytemperature_stabilization() + if(!H.on_fire && loc_temp < H.bodytemperature) //Place is colder than we are. But don't cool if we are on fire. var/thermal_protection = 1 - if(loc_temp < H.bodytemperature) //Place is colder than we are - thermal_protection -= H.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(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)) - 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 - if (loc_temp > H.bodytemperature) //Place is hotter than we are - var/natural = 0 - if(H.stat != DEAD) - natural = H.natural_bodytemperature_stabilization() + thermal_protection -= H.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(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)) + 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 + else if(loc_temp > H.bodytemperature) //Place is hotter than we are var/thermal_protection = 1 thermal_protection -= H.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(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 H.adjust_bodytemperature((thermal_protection+1)*natural + min(thermal_protection * (loc_temp - H.bodytemperature) / BODYTEMP_HEAT_DIVISOR, BODYTEMP_HEATING_MAX)) else //we're sweating, insulation hinders out ability to reduce heat - but will reduce the amount of heat we get from the environment H.adjust_bodytemperature(natural*(1/(thermal_protection+1)) + min(thermal_protection * (loc_temp - H.bodytemperature) / BODYTEMP_HEAT_DIVISOR, BODYTEMP_HEATING_MAX)) + //NSV13 end. // +/- 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)) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 09401524726..aea243a733b 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -547,6 +547,10 @@ 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() + //NSV13 - coldblooded beings do not naturally stabilize. + if(HAS_TRAIT(src, TRAIT_COLDBLOODED)) + return 0 + //NSV13 end. var/body_temperature_difference = BODYTEMP_NORMAL - bodytemperature switch(bodytemperature) if(-INFINITY to BODYTEMP_COLD_DAMAGE_LIMIT) //Cold damage limit is 50 below the default, the temperature where you start to feel effects. diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index e12943185f7..ce543b9fe6a 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -33,6 +33,9 @@ var/datum/gas_mixture/environment = loc.return_air() if(environment) handle_environment(environment) + ///NSV13 - aggressive grab temp exchange hook. + handle_temperature_exchange() + ///NSV13 end. //Handle gravity var/gravity = has_gravity() diff --git a/nsv13.dme b/nsv13.dme index 8806afaff65..97b9c981cf1 100644 --- a/nsv13.dme +++ b/nsv13.dme @@ -3933,13 +3933,16 @@ #include "nsv13\code\modules\mob\mob_helpers.dm" #include "nsv13\code\modules\mob\dead\new_player\sprite_accessories.dm" #include "nsv13\code\modules\mob\dead\observer\oberserver.dm" +#include "nsv13\code\modules\mob\living\nsv_life.dm" #include "nsv13\code\modules\mob\living\carbon\carbon.dm" #include "nsv13\code\modules\mob\living\carbon\examine_tgui.dm" #include "nsv13\code\modules\mob\living\carbon\human\human.dm" #include "nsv13\code\modules\mob\living\carbon\human\nsv_emotes.dm" #include "nsv13\code\modules\mob\living\carbon\human\nsv_human_helpers.dm" +#include "nsv13\code\modules\mob\living\carbon\human\nsv_species.dm" #include "nsv13\code\modules\mob\living\carbon\human\species_types\catgirl.dm" #include "nsv13\code\modules\mob\living\carbon\human\species_types\nanotrasen_knpc.dm" +#include "nsv13\code\modules\mob\living\carbon\human\species_types\nsv_lizardpeople.dm" #include "nsv13\code\modules\mob\living\carbon\human\species_types\other_knpc.dm" #include "nsv13\code\modules\mob\living\carbon\human\species_types\spacepirate_knpc.dm" #include "nsv13\code\modules\mob\living\carbon\human\species_types\syndicate_knpc.dm" diff --git a/nsv13/code/__DEFINES/atmospherics.dm b/nsv13/code/__DEFINES/atmospherics.dm index e12f9c12bc1..2cdd8dadd87 100644 --- a/nsv13/code/__DEFINES/atmospherics.dm +++ b/nsv13/code/__DEFINES/atmospherics.dm @@ -2,3 +2,20 @@ #define ATMOS_GAS_MONITOR_OUTPUT_NUCLEIUM "nucleium_out" #define ATMOS_GAS_MONITOR_SENSOR_NUCLEIUM "nucleium_sensor" #define ATMOS_TANK_NUCLEIUM "nucleium=750;TEMP=293.15" + +//Nerd stuff (coldblooded limited thermoregulation via e.g. muscle fibrillations) + +#define LIZARD_ECTOTHERMISM_COLD_MAX_STACKS 10 //! Essentially the maximum life ticks thermogenesis will remain ready / active after the condition has passed. +#define LIZARD_THERMOGENESIS_COLD_TRIGGER_STACKS 5 //! At this many stacks we start using thermogenesis. + +#define ECTOTHERM_THERMOGENESIS_MIN_COLDNESS 22 //! An ectotherm humanoid must be at least this many kelvin below the normal bodytemperature target define to actively thermoregulate. +#define ECTOTHERM_THERMOGENESIS_CRIT_COLDNESS 50 //! If this much temperature difference exists (relative to the basic standard temp), we are VERY cold and use a significant portion of energy just to vibrate. +#define ECTOTHERM_RECOVERY_DIVISOR 11 //! The base divisor for total heat difference that is tried to adjust for. For now just the base autorecovery divisor since it usually hits the min or max cap. +#define ECTOTHERM_MIN_RECOVERY 0.2 //! The minimum amount of heat (kelvins) generated by ectotherms if trying to recover. Should be very small +#define ECTOTHERM_MAX_RECOVERY 3 //! The maximum amount of heat (kelvins) generated per tick by ectotherms if trying to recover. Should be fairly small. +#define ECTOTHERM_CRIT_COLD_MAX_RECOVERY_MOD 2 //! Maximum temperature recovery is multiplied by this value if we are below the critical coldness threshold. + +#define ECTOTHERM_THERMOGENESIS_NUTRITION_USE 0.2 //! Standard use for temp adjustment for ectotherms. +#define ECTOTHERM_MAJOR_THERMOGENESIS_NUTRITION_USE 1 //! This method of temperature regulation is inefficient, thus its nutrition drain increases disproportionately to the cap gained if very cold. + +#define ECTOTHERM_NO_THERMOGENESIS_NEEDED -1 //! Return value if no thermoregulation was needed nor done. diff --git a/nsv13/code/datums/mood_events/nsv_events.dm b/nsv13/code/datums/mood_events/nsv_events.dm index d684925ae08..8ca78dc5b70 100644 --- a/nsv13/code/datums/mood_events/nsv_events.dm +++ b/nsv13/code/datums/mood_events/nsv_events.dm @@ -1,7 +1,7 @@ /datum/mood_event/moth_drink_blood description = "That hit the spot!\n" - mood_change = 10 - timeout = 10 MINUTES + mood_change = 3 + timeout = 7 MINUTES /datum/mood_event/tailpull description = "OUCH! Stop pulling my tail! It hurts!\n" @@ -40,11 +40,11 @@ /datum/mood_event/drink_navy_coffee description = "THAT SHIT TASTED FUCKING DELICIOUS LET'S GO FUCK SOME SYNDICATE SHIPS UP, NAVY FOR LIFE WOOOOOO!!\n" - mood_change = 10 - timeout = 10 MINUTES + mood_change = 3 + timeout = 7 MINUTES /datum/mood_event/drink_navy_coffee/add_effects(list/faction) - if("Syndicate" in faction) + if(FACTION_SYNDICATE in faction) description = "THAT SHIT TASTED FUCKING DELICIOUS LET'S GO FUCK SOME NANOTRASEN SHIPS UP, NAVY FOR LIFE WOOOOOO!!\n" @@ -52,3 +52,11 @@ description = "Cheers! ¡Salud! Kanpai! Prost! Skål! Santé! Sláinte! Saúde!\n" mood_change = 3 timeout = 30 SECONDS + +/datum/mood_event/lizard_shivers + description = "I'm shivering.. I need to find a spot where I can bask in the sun!\n" //Evolved mental response, even if not entirely true here. + mood_change = -2 + +/datum/mood_event/comfy_lizard_temperature + description = "I'm nice and warm! I missed this feeling..\n" //These ships run at 20°C by default, which is.. not very nice for something coldblooded. + mood_change = 2 //This is really hard to hit and maintain so I felt like at least a +2 would be appropriate. diff --git a/nsv13/code/modules/mob/living/carbon/human/human.dm b/nsv13/code/modules/mob/living/carbon/human/human.dm index 9a1b61d44fa..bf9d1e28764 100644 --- a/nsv13/code/modules/mob/living/carbon/human/human.dm +++ b/nsv13/code/modules/mob/living/carbon/human/human.dm @@ -9,3 +9,7 @@ if(gravity <= 1) //This is fine. return return ..() + +//OVERRIDE - Humans handle thermoregulation on species level. +/mob/living/carbon/human/natural_bodytemperature_stabilization() + return dna.species.natural_bodytemperature_stabilization(src) diff --git a/nsv13/code/modules/mob/living/carbon/human/nsv_species.dm b/nsv13/code/modules/mob/living/carbon/human/nsv_species.dm new file mode 100644 index 00000000000..3214ec2cde5 --- /dev/null +++ b/nsv13/code/modules/mob/living/carbon/human/nsv_species.dm @@ -0,0 +1,39 @@ +//Modular File for NSV species stuff + +///The species-level version of bodytemperature stabilization. +/datum/species/proc/natural_bodytemperature_stabilization(mob/living/carbon/human/human_holder) + if(HAS_TRAIT(human_holder, TRAIT_COLDBLOODED)) + ectotherm_thermogenesis(human_holder) //Man I love the word "thermogenesis". Such a magic term for what is essentially just "makes heat". + return 0 + var/body_temperature_difference = BODYTEMP_NORMAL - human_holder.bodytemperature + switch(human_holder.bodytemperature) + if(-INFINITY to BODYTEMP_COLD_DAMAGE_LIMIT) //Cold damage limit is 50 below the default, the temperature where you start to feel effects. + return max((body_temperature_difference * human_holder.metabolism_efficiency / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM) + if(BODYTEMP_COLD_DAMAGE_LIMIT to BODYTEMP_NORMAL) + return max(body_temperature_difference * human_holder.metabolism_efficiency / BODYTEMP_AUTORECOVERY_DIVISOR, min(body_temperature_difference, BODYTEMP_AUTORECOVERY_MINIMUM/4)) + if(BODYTEMP_NORMAL to BODYTEMP_HEAT_DAMAGE_LIMIT) // Heat damage limit is 50 above the default, the temperature where you start to feel effects. + return min(body_temperature_difference * human_holder.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 + +/** + * A proc for coldblooded species' means of limited thermal control. Also known as "vibrating your muscles". + * * Returns: Amount of kelvin adjustment performed, or ECTOTHERM_NO_THERMOGENESIS_NEEDED (-1) if we are fine. +**/ +/datum/species/proc/ectotherm_thermogenesis(mob/living/carbon/human/human_holder, use_temp_diff_range_check = TRUE) + var/temperature_differential = BODYTEMP_NORMAL - human_holder.bodytemperature + if(temperature_differential <= 0 || (use_temp_diff_range_check && temperature_differential < ECTOTHERM_THERMOGENESIS_MIN_COLDNESS)) + return ECTOTHERM_NO_THERMOGENESIS_NEEDED + var/adjustment = 0 + if(temperature_differential < ECTOTHERM_THERMOGENESIS_CRIT_COLDNESS) + if(human_holder.nutrition < ECTOTHERM_THERMOGENESIS_NUTRITION_USE * human_holder.metabolism_efficiency) + return 0 + adjustment = round(CLAMP(temperature_differential / ECTOTHERM_RECOVERY_DIVISOR * human_holder.metabolism_efficiency, ECTOTHERM_MIN_RECOVERY * human_holder.metabolism_efficiency, ECTOTHERM_MAX_RECOVERY * human_holder.metabolism_efficiency), 0.1) + human_holder.adjust_nutrition(-ECTOTHERM_THERMOGENESIS_NUTRITION_USE * human_holder.metabolism_efficiency) + else + if(human_holder.nutrition < ECTOTHERM_MAJOR_THERMOGENESIS_NUTRITION_USE * human_holder.metabolism_efficiency) + return 0 + adjustment = round(CLAMP(temperature_differential / ECTOTHERM_RECOVERY_DIVISOR * human_holder.metabolism_efficiency, ECTOTHERM_MIN_RECOVERY * human_holder.metabolism_efficiency, ECTOTHERM_MAX_RECOVERY * human_holder.metabolism_efficiency * ECTOTHERM_CRIT_COLD_MAX_RECOVERY_MOD), 0.1) + human_holder.adjust_nutrition(-ECTOTHERM_MAJOR_THERMOGENESIS_NUTRITION_USE * human_holder.metabolism_efficiency) + human_holder.adjust_bodytemperature(adjustment) + return adjustment diff --git a/nsv13/code/modules/mob/living/carbon/human/species_types/nsv_lizardpeople.dm b/nsv13/code/modules/mob/living/carbon/human/species_types/nsv_lizardpeople.dm new file mode 100644 index 00000000000..360c469fd23 --- /dev/null +++ b/nsv13/code/modules/mob/living/carbon/human/species_types/nsv_lizardpeople.dm @@ -0,0 +1,67 @@ +//Modular NSV file for special stuff lizards have here. + +//Modular type attachment. +/datum/species/lizard + coldmod = 1 // Lizards here have exchanged their inherent damage modifier for them being cold-blooded. + inherent_traits = list(TRAIT_COLDBLOODED) // The aforementioned coldbloodedness + ///Controls whether lizards use their muscles to generate additional heat if very cold. + var/cold_stacks = 0 + ///Stores if we already sent them a message & adjusted stuff. + var/fibrillating = FALSE + ///Used to store whether the signal to adjust mood due to good temperatures has been updated. + var/is_comfy = FALSE + +//Another modular type attachment. +/datum/species/lizard/ashwalker + inherent_traits = list(TRAIT_NOGUNS,TRAIT_NOBREATH, TRAIT_COLDBLOODED) //Ashwalkers are also coldblooded [we have no lavaland so I don't have to worry about if lavaland always gens with survivable temps :) ] + +/datum/species/lizard/ectotherm_thermogenesis(mob/living/carbon/human/human_holder, use_temp_diff_range_check = TRUE) + var/temp_diff = BODYTEMP_NORMAL - human_holder.bodytemperature + switch(temp_diff) + if(ECTOTHERM_THERMOGENESIS_CRIT_COLDNESS to INFINITY) //Being extremely cold quickly triggers thermogenesis. + cold_stacks = min(cold_stacks + 3, LIZARD_ECTOTHERMISM_COLD_MAX_STACKS) + if(ECTOTHERM_THERMOGENESIS_MIN_COLDNESS to ECTOTHERM_THERMOGENESIS_CRIT_COLDNESS) + cold_stacks = min(cold_stacks + 1, LIZARD_ECTOTHERMISM_COLD_MAX_STACKS) //Basic cold takes some time to respond to. + else + cold_stacks = max(cold_stacks - 1, 0) //Takes a while to calm down muscles. + + if(cold_stacks < LIZARD_THERMOGENESIS_COLD_TRIGGER_STACKS && !fibrillating) + return ECTOTHERM_NO_THERMOGENESIS_NEEDED + if(!fibrillating) // !fibrillating reaching this point means enough stacks exist. + to_chat(human_holder, "You start shivering and feel the urge to find a sunny spot!") + SEND_SIGNAL(human_holder, COMSIG_ADD_MOOD_EVENT, "lizard_shivers", /datum/mood_event/lizard_shivers) + fibrillating = TRUE + else if(cold_stacks == 0) //We also check if we have to stop vibrating here. + to_chat(human_holder, "You stop shivering.") + SEND_SIGNAL(human_holder, COMSIG_CLEAR_MOOD_EVENT, "lizard_shivers") + fibrillating = FALSE + return ECTOTHERM_NO_THERMOGENESIS_NEEDED + + return ..(human_holder, FALSE) //We already use some fancy logic for our thermoregulation triggering so we don't use the normal temp difference check save for if we would get hot. + +//Modular proc attachment +/datum/species/lizard/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load) //Human variable, named C. What did they mean by this? + SEND_SIGNAL(C, COMSIG_CLEAR_MOOD_EVENT, "lizard_shivers") //Safely remove if our species is changed. + SEND_SIGNAL(C, COMSIG_CLEAR_MOOD_EVENT, "comfy_liz_temp") + return ..() + +//Lizards are most comfortable between 30 and 60°C. Good luck managing to stabilize at that temp, but hey if you manage to, you get a mood buff! +#define LIZARD_COMFY_TEMP_MIN 303.15 +#define LIZARD_COMFY_TEMP_MAX 333.15 //From what I read some terran lizards have ~40-45°C as their upper targeted bounds, buut firstly these are space lizards, and secondly this is already hard enough to hit, so I extended it to 60°C. + +/datum/species/lizard/spec_life(mob/living/carbon/human/H) + . = ..() + var/owner_bodytemperature = H.bodytemperature + if(owner_bodytemperature < LIZARD_COMFY_TEMP_MIN || owner_bodytemperature > LIZARD_COMFY_TEMP_MAX) //Should be low on processing since the first condition will catch almost all the time. + if(!is_comfy) + return + SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "comfy_liz_temp") + is_comfy = FALSE + return + if(is_comfy) + return + SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "comfy_liz_temp", /datum/mood_event/comfy_lizard_temperature) + is_comfy = TRUE + +#undef LIZARD_COMFY_TEMP_MIN +#undef LIZARD_COMFY_TEMP_MAX diff --git a/nsv13/code/modules/mob/living/nsv_life.dm b/nsv13/code/modules/mob/living/nsv_life.dm new file mode 100644 index 00000000000..871bd14dc1d --- /dev/null +++ b/nsv13/code/modules/mob/living/nsv_life.dm @@ -0,0 +1,46 @@ +///NSV13 living life() stuff file. Modularization. + +#define GRAB_TEMP_EXCHANGE_MIN_DIFF 1 //If we have less than 1K difference in temp, why are we even bothering? (Might also do some weird stuff at very low differences due to decimal precision) + +///If grabbing aggressively (or above), exchanges temperature with the target (taking into account insulation and all that stuff we hate dealing with). +/mob/living/proc/handle_temperature_exchange() + +//I'm not bothering adjusting for all the weird edge cases carbons that are not-quite-human code have, so only /human to /human does this. +/mob/living/carbon/human/handle_temperature_exchange() + if(!pulling || !ishuman(pulling)) + return + var/mob/living/carbon/human/pulled_human = pulling + if(grab_state < GRAB_AGGRESSIVE) //Handholding is not enough to share body heat. + return + var/tempdiff = pulled_human.bodytemperature - bodytemperature + if(abs(tempdiff) < GRAB_TEMP_EXCHANGE_MIN_DIFF) + return //Why are we still here.. + var/thermoconductivity = 1 + //We ALWAYS handle the bodytemp adjustment as a cooling action, not as a heating one. If this is too effective, it could be handled as heating instead. (cold temp adjustments allow more oomph by default) + if(tempdiff > 0) //Pulled is hotter than us. Cool pulled, heat us by diff. + //Averaging insulation of both targets, UNLESS either of the two has full thermal protection to the vector. + var/self_thermoprotect = get_heat_protection(pulled_human.bodytemperature) + var/pulled_thermoprotect = pulled_human.get_cold_protection(bodytemperature) + if(self_thermoprotect >= 1 || pulled_thermoprotect >= 1) + return //Full insulation. + thermoconductivity -= ((self_thermoprotect + pulled_thermoprotect) / 2) //Non-full protection, average for simplicity and to preserve effectiveness. + var/true_adjustment = min(thermoconductivity * tempdiff / BODYTEMP_COLD_DIVISOR, -BODYTEMP_COOLING_MAX) + //Aaand equalize. + adjust_bodytemperature(true_adjustment) + pulled_human.adjust_bodytemperature(-true_adjustment) + . = true_adjustment //This return value isn't used but someone might use it. Plus, traceability. + else if(tempdiff < 0) //We are hotter than pulled. Cool us, transfer lost heat to them. + tempdiff = -tempdiff //This was negative. I don't want that. + //Averaging insulation of both targets again, this time the other way around because we are hotter. + var/self_thermoprotect = get_cold_protection(pulled_human.bodytemperature) + var/pulled_thermoprotect = pulled_human.get_heat_protection(bodytemperature) + if(self_thermoprotect >= 1 || pulled_thermoprotect >= 1) + return //Full insulation + thermoconductivity -= ((self_thermoprotect + pulled_thermoprotect) / 2) //Bit copypasty I know but I really don't feel like making an omni-case instead. + var/true_adjustment = min(thermoconductivity * tempdiff / BODYTEMP_COLD_DIVISOR, -BODYTEMP_COOLING_MAX) + //And equalize, the other way around this time. + adjust_bodytemperature(-true_adjustment) + pulled_human.adjust_bodytemperature(true_adjustment) + . = true_adjustment + +#undef GRAB_TEMP_EXCHANGE_MIN_DIFF