mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-20 11:40:07 +01:00
## About The Pull Request
Changes human name to update whenever anything that could result in
their visible name changing occurs, such as changing IDs, equipping
gasmasks, picking potted plants, etc. Currently name updates occur every
``Life()`` tick and in a few "special" cases, which causes a lot of name
changes from sources such as equipment to not apply until the mob ticks,
and makes us waste a tiiiny bit of CPU time on name updates.
I've also slighly cleaned up human /Life() and made species'
``spec_life()`` not run when the mob is dead, as it was causing certain
unintended interactions, such as slimepeople regenerating blood while
dead.
## Why It's Good For The Game
Microoptimization, ensures that correct names are always used (in case
something could update their name but the mob hasn't ticked yet), plus
its just a cleaner implementation
(cherry picked from commit 87e1ef6f64)
# Conflicts:
# code/game/data_huds.dm
156 lines
6.1 KiB
Plaintext
156 lines
6.1 KiB
Plaintext
/// This divisor controls how fast body temperature changes to match the environment
|
|
#define BODYTEMP_DIVISOR 16
|
|
|
|
/**
|
|
* Handles the biological and general over-time processes of the mob.
|
|
*
|
|
*
|
|
* Arguments:
|
|
* - seconds_per_tick: The amount of time that has elapsed since this last fired.
|
|
* - times_fired: The number of times SSmobs has fired
|
|
*/
|
|
/mob/living/proc/Life(seconds_per_tick = SSMOBS_DT, times_fired)
|
|
set waitfor = FALSE
|
|
SHOULD_NOT_SLEEP(TRUE)
|
|
|
|
var/signal_result = SEND_SIGNAL(src, COMSIG_LIVING_LIFE, seconds_per_tick, times_fired)
|
|
|
|
if(signal_result & COMPONENT_LIVING_CANCEL_LIFE_PROCESSING) // mmm less work
|
|
return
|
|
|
|
if (client)
|
|
var/turf/T = get_turf(src)
|
|
if(!T)
|
|
move_to_error_room()
|
|
var/msg = " was found to have no .loc with an attached client, if the cause is unknown it would be wise to ask how this was accomplished."
|
|
message_admins(ADMIN_LOOKUPFLW(src) + msg)
|
|
send2tgs_adminless_only("Mob", key_name_and_tag(src) + msg, R_ADMIN)
|
|
src.log_message("was found to have no .loc with an attached client.", LOG_GAME)
|
|
|
|
// This is a temporary error tracker to make sure we've caught everything
|
|
else if (registered_z != T.z)
|
|
#ifdef TESTING
|
|
message_admins("[ADMIN_LOOKUPFLW(src)] has somehow ended up in Z-level [T.z] despite being registered in Z-level [registered_z]. If you could ask them how that happened and notify coderbus, it would be appreciated.")
|
|
#endif
|
|
log_game("Z-TRACKING: [src] has somehow ended up in Z-level [T.z] despite being registered in Z-level [registered_z].")
|
|
update_z(T.z)
|
|
else if (registered_z)
|
|
log_game("Z-TRACKING: [src] of type [src.type] has a Z-registration despite not having a client.")
|
|
update_z(null)
|
|
|
|
if(isnull(loc) || HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
|
|
return
|
|
|
|
if(!HAS_TRAIT(src, TRAIT_STASIS))
|
|
if(stat != DEAD)
|
|
//Mutations and radiation
|
|
handle_mutations(seconds_per_tick, times_fired)
|
|
//Breathing, if applicable
|
|
handle_breathing(seconds_per_tick, times_fired)
|
|
|
|
handle_diseases(seconds_per_tick, times_fired) // DEAD check is in the proc itself; we want it to spread even if the mob is dead, but to handle its disease-y properties only if you're not.
|
|
|
|
if (QDELETED(src)) // Diseases can qdel the mob via transformations
|
|
return
|
|
|
|
// Handle temperature/pressure differences between body and environment
|
|
var/datum/gas_mixture/environment = loc.return_air()
|
|
if(environment)
|
|
handle_environment(environment, seconds_per_tick, times_fired)
|
|
|
|
handle_gravity(seconds_per_tick, times_fired)
|
|
|
|
if(living_flags & QUEUE_NUTRITION_UPDATE)
|
|
mob_mood?.update_nutrition_moodlets()
|
|
hud_used?.hunger?.update_hunger_bar()
|
|
living_flags &= ~QUEUE_NUTRITION_UPDATE
|
|
|
|
if(stat != DEAD)
|
|
return TRUE
|
|
|
|
/mob/living/proc/handle_breathing(seconds_per_tick, times_fired)
|
|
SEND_SIGNAL(src, COMSIG_LIVING_HANDLE_BREATHING, seconds_per_tick, times_fired)
|
|
return
|
|
|
|
/mob/living/proc/handle_mutations(seconds_per_tick, times_fired)
|
|
return
|
|
|
|
/mob/living/proc/handle_diseases(seconds_per_tick, times_fired)
|
|
return
|
|
|
|
// Base mob environment handler for body temperature
|
|
/mob/living/proc/handle_environment(datum/gas_mixture/environment, seconds_per_tick, times_fired)
|
|
var/loc_temp = get_temperature(environment)
|
|
var/temp_delta = loc_temp - bodytemperature
|
|
|
|
if(ismovable(loc))
|
|
var/atom/movable/occupied_space = loc
|
|
temp_delta *= (1 - occupied_space.contents_thermal_insulation)
|
|
|
|
if(temp_delta < 0) // it is cold here
|
|
if(!on_fire) // do not reduce body temp when on fire
|
|
adjust_bodytemperature(max(max(temp_delta / BODYTEMP_DIVISOR, BODYTEMP_COOLING_MAX) * seconds_per_tick, temp_delta))
|
|
else // this is a hot place
|
|
adjust_bodytemperature(min(min(temp_delta / BODYTEMP_DIVISOR, BODYTEMP_HEATING_MAX) * seconds_per_tick, temp_delta))
|
|
|
|
/**
|
|
* Get the fullness of the mob
|
|
*
|
|
* Fullness is a representation of how much nutrition the mob has,
|
|
* including the nutrition of stuff yet to be digested (reagents in blood / stomach)
|
|
*
|
|
* * only_consumable - if TRUE, only consumable reagents are counted.
|
|
* Otherwise, all reagents contribute to fullness, despite not adding nutrition as they process.
|
|
*
|
|
* Returns a number representing fullness, scaled similarly to nutrition.
|
|
*/
|
|
/mob/living/proc/get_fullness(only_consumable)
|
|
var/fullness = nutrition
|
|
// we add the nutrition value of what we're currently digesting
|
|
for(var/datum/reagent/consumable/bits in reagents.reagent_list)
|
|
fullness += bits.get_nutriment_factor(src) * bits.volume / bits.metabolization_rate
|
|
return fullness
|
|
|
|
/**
|
|
* Check if the mob contains this reagent.
|
|
*
|
|
* This will validate the the reagent holder for the mob and any sub holders contain the requested reagent.
|
|
* Vars:
|
|
* * reagent (typepath) takes a PATH to a reagent.
|
|
* * amount (int) checks for having a specific amount of that chemical.
|
|
* * needs_metabolizing (bool) takes into consideration if the chemical is matabolizing when it's checked.
|
|
*/
|
|
/mob/living/proc/has_reagent(reagent, amount = -1, needs_metabolizing = FALSE)
|
|
return reagents?.has_reagent(reagent, amount, needs_metabolizing)
|
|
|
|
/mob/living/proc/update_damage_hud()
|
|
return
|
|
|
|
/mob/living/proc/handle_gravity(seconds_per_tick, times_fired)
|
|
if(gravity_state > STANDARD_GRAVITY)
|
|
handle_high_gravity(gravity_state, seconds_per_tick, times_fired)
|
|
|
|
/mob/living/proc/gravity_animate()
|
|
if(!get_filter("gravity"))
|
|
add_filter("gravity",1,list("type"="motion_blur", "x"=0, "y"=0))
|
|
animate(get_filter("gravity"), y = 1, time = 10, loop = -1)
|
|
animate(y = 0, time = 10)
|
|
|
|
/mob/living/proc/handle_high_gravity(gravity, seconds_per_tick, times_fired)
|
|
if(gravity < GRAVITY_DAMAGE_THRESHOLD) //Aka gravity values of 3 or more
|
|
return
|
|
|
|
var/grav_strength = gravity - GRAVITY_DAMAGE_THRESHOLD
|
|
adjustBruteLoss(min(GRAVITY_DAMAGE_SCALING * grav_strength, GRAVITY_DAMAGE_MAXIMUM) * seconds_per_tick)
|
|
|
|
/// Proc used for custom metabolization of reagents, if any
|
|
/mob/living/proc/reagent_tick(datum/reagent/chem, seconds_per_tick, times_fired)
|
|
SHOULD_CALL_PARENT(TRUE)
|
|
return SEND_SIGNAL(src, COMSIG_MOB_REAGENT_TICK, chem, seconds_per_tick, times_fired)
|
|
|
|
/// Proc used for custom reagent exposure effects, if any
|
|
/mob/living/proc/reagent_expose(datum/reagent/chem, methods = TOUCH, reac_volume, show_message = TRUE, touch_protection = 0)
|
|
return
|
|
|
|
#undef BODYTEMP_DIVISOR
|