mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-16 02:24:11 +01:00
Streamlines Life() a little (#96215)
## About The Pull Request Main changes - `handle_mutations` is gone, DNA Injectors are now managed via a status effect - `handle_diseases` is gone, disease stages are just handled via life signal - `handle_bodyparts` is gone, it was unused and in the future any implementations should use a life signal - `spec_life` is gone, the main content of it is now in `human/Life`, most children implementations now use life signal, zombie tongues now handle zombie groans - Life signal was split in two (pre and active) Other changes - DNA injector code was cleaned up considerably - HARS now alerts admins when you inject someone else with it like Monkey - `COPY_DNA_SE` is no longer mistakenly unused (meaning stuff like transformation sting no longer copies "active mutations") ## Why It's Good For The Game Across the course of a full round we spend the same amount of time doing literally nothing in life as we spend on handling human breathing. Now in the context of a full round this is 8 seconds. Which in the grand scheme of things, not a whole lot, but if we can get a tiny performance gain from... not doing literally nothing (especially when we can do these things cleaner with signals) that's a win in my book ## Changelog 🆑 Melbert refactor: Refactored dna injectors (both the ones that change appearance and activate mutations), report any oddities with them like failing to revert your appearance or mutations not applying correctly code: Ever so slightly changed how diseases tick, report any oddities code: Ever so slightly changed how some species mechanics tick, like golems and slimes, report any oddities code: The code behind printing appearance modifying dna injectors from genetics has changed, report any oddities code: Some backend transformation sting code changed slightly, report any oddities code: Zombie "idle" groaning is now tied to the tongue rather than the species itself admin: Force-injecting someone with HARS give an admin alert, the same as force-injecting someone with Monkey fix: Several methods of copying DNA (including transformation sting) mistakenly copied "active mutations", this has been fixed /🆑 --------- Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
This commit is contained in:
@@ -91,7 +91,6 @@
|
||||
|
||||
/// Updates effects that rely on blood volume or status, like blood HUDs.
|
||||
/mob/living/proc/update_blood_effects()
|
||||
living_flags &= ~BLOOD_UPDATE_QUEUED
|
||||
blood_hud_set_status()
|
||||
|
||||
/// Updates effects that rely on whether the mob can have blood.
|
||||
|
||||
@@ -542,11 +542,6 @@ GLOBAL_LIST_EMPTY(features_by_species)
|
||||
|
||||
return new_features
|
||||
|
||||
/datum/species/proc/spec_life(mob/living/carbon/human/H, seconds_per_tick)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
if(HAS_TRAIT(H, TRAIT_NOBREATH) && (H.health < H.crit_threshold) && !HAS_TRAIT(H, TRAIT_NOCRITDAMAGE))
|
||||
H.adjust_brute_loss(0.5 * seconds_per_tick)
|
||||
|
||||
/datum/species/proc/can_equip(obj/item/I, slot, disable_warning, mob/living/carbon/human/H, bypass_equip_delay_self = FALSE, ignore_equipped = FALSE, indirect_action = FALSE)
|
||||
if(no_equip_flags & slot)
|
||||
if(!I.species_exception || !is_type_in_list(src, I.species_exception))
|
||||
|
||||
@@ -696,7 +696,7 @@
|
||||
if(heal_flags & HEAL_NEGATIVE_MUTATIONS)
|
||||
for(var/datum/mutation/existing_mutation in dna.mutations)
|
||||
if(existing_mutation.quality != POSITIVE && existing_mutation.remove_on_aheal)
|
||||
dna.remove_mutation(existing_mutation, list(MUTATION_SOURCE_ACTIVATED, MUTATION_SOURCE_MUTATOR, MUTATION_SOURCE_TIMED_INJECTOR))
|
||||
dna.remove_mutation(existing_mutation, GLOB.standard_mutation_sources)
|
||||
|
||||
if(heal_flags & HEAL_TEMP)
|
||||
set_coretemperature(get_body_temp_normal(apply_change = FALSE))
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
return
|
||||
|
||||
. = ..()
|
||||
|
||||
if(QDELETED(src))
|
||||
return FALSE
|
||||
|
||||
@@ -45,8 +44,9 @@
|
||||
handle_heart(seconds_per_tick)
|
||||
// Handles liver failure effects, if we lack a liver
|
||||
handle_liver(seconds_per_tick)
|
||||
// For special species interactions
|
||||
dna.species.spec_life(src, seconds_per_tick)
|
||||
// Crit damage but specifically for people who don't get suffocate while in crit so they can actually die eventually
|
||||
if(HAS_TRAIT(src, TRAIT_NOBREATH) && (health < crit_threshold) && !HAS_TRAIT(src, TRAIT_NOCRITDAMAGE))
|
||||
adjust_brute_loss(0.5 * seconds_per_tick)
|
||||
return stat != DEAD
|
||||
|
||||
/mob/living/carbon/human/calculate_affecting_pressure(pressure)
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
RegisterSignal(human_who_gained_species, COMSIG_CARBON_DEFIB_HEART_CHECK, PROC_REF(defib_check))
|
||||
RegisterSignal(human_who_gained_species, COMSIG_ATOM_ITEM_INTERACTION, PROC_REF(rebuild_check))
|
||||
RegisterSignal(human_who_gained_species, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine))
|
||||
RegisterSignal(human_who_gained_species, COMSIG_LIVING_LIFE, PROC_REF(on_life))
|
||||
// nutrition = health, so give people a head start
|
||||
human_who_gained_species.set_nutrition(NUTRITION_LEVEL_WELL_FED)
|
||||
|
||||
@@ -81,14 +82,16 @@
|
||||
COMSIG_CARBON_DEFIB_HEART_CHECK,
|
||||
COMSIG_ATOM_ITEM_INTERACTION,
|
||||
COMSIG_ATOM_EXAMINE,
|
||||
COMSIG_LIVING_LIFE,
|
||||
))
|
||||
|
||||
human_who_lost_species.physiology.stamina_mod /= 0.6
|
||||
human_who_lost_species.physiology.stun_mod /= 0.6
|
||||
human_who_lost_species.physiology.knockdown_mod /= 1.2
|
||||
|
||||
/datum/species/golem/spec_life(mob/living/carbon/human/source, seconds_per_tick)
|
||||
. = ..()
|
||||
/datum/species/golem/proc/on_life(mob/living/carbon/human/source, seconds_per_tick)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(source.nutrition <= 20)
|
||||
// this is "hard crit" for golems
|
||||
source.Unconscious(1.5 SECONDS * seconds_per_tick)
|
||||
|
||||
@@ -215,7 +215,10 @@
|
||||
// so if someone mindswapped into them, they'd still be shared.
|
||||
bodies = null
|
||||
C.set_blood_volume(C.get_blood_volume(), maximum = BLOOD_VOLUME_NORMAL)
|
||||
UnregisterSignal(C, COMSIG_LIVING_DEATH)
|
||||
UnregisterSignal(C, list(
|
||||
COMSIG_LIVING_DEATH,
|
||||
COMSIG_LIVING_LIFE,
|
||||
))
|
||||
..()
|
||||
|
||||
/datum/species/jelly/slime/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load, regenerate_icons)
|
||||
@@ -232,6 +235,7 @@
|
||||
bodies |= C
|
||||
|
||||
RegisterSignal(C, COMSIG_LIVING_DEATH, PROC_REF(on_death_move_body))
|
||||
RegisterSignal(C, COMSIG_LIVING_LIFE, PROC_REF(on_life))
|
||||
|
||||
/datum/species/jelly/slime/proc/on_death_move_body(mob/living/carbon/human/source, gibbed)
|
||||
SIGNAL_HANDLER
|
||||
@@ -255,16 +259,16 @@
|
||||
/datum/species/jelly/slime/copy_properties_from(datum/species/jelly/slime/old_species)
|
||||
bodies = old_species.bodies
|
||||
|
||||
/datum/species/jelly/slime/spec_life(mob/living/carbon/human/H, seconds_per_tick)
|
||||
. = ..()
|
||||
if(H.get_blood_volume() >= BLOOD_VOLUME_SLIME_SPLIT)
|
||||
/datum/species/jelly/slime/proc/on_life(mob/living/carbon/human/source, seconds_per_tick)
|
||||
SIGNAL_HANDLER
|
||||
if(source.get_blood_volume() >= BLOOD_VOLUME_SLIME_SPLIT)
|
||||
if(SPT_PROB(2.5, seconds_per_tick))
|
||||
to_chat(H, span_notice("You feel very bloated!"))
|
||||
to_chat(source, span_notice("You feel very bloated!"))
|
||||
|
||||
else if(H.nutrition >= NUTRITION_LEVEL_WELL_FED)
|
||||
H.adjust_blood_volume(1.5 * seconds_per_tick)
|
||||
if(H.get_blood_volume() <= BLOOD_VOLUME_LOSE_NUTRITION)
|
||||
H.adjust_nutrition(-1.25 * seconds_per_tick)
|
||||
else if(source.nutrition >= NUTRITION_LEVEL_WELL_FED)
|
||||
source.adjust_blood_volume(1.5 * seconds_per_tick)
|
||||
if(source.get_blood_volume() <= BLOOD_VOLUME_LOSE_NUTRITION)
|
||||
source.adjust_nutrition(-1.25 * seconds_per_tick)
|
||||
|
||||
/datum/action/innate/split_body
|
||||
name = "Split Body"
|
||||
|
||||
@@ -33,16 +33,21 @@
|
||||
new_vampire.skin_tone = "albino"
|
||||
RegisterSignal(new_vampire, COMSIG_ATOM_ATTACKBY, PROC_REF(on_attackby))
|
||||
RegisterSignal(new_vampire, COMSIG_MOB_HUD_CREATED, PROC_REF(on_hud_created))
|
||||
RegisterSignal(new_vampire, COMSIG_LIVING_LIFE, PROC_REF(on_life))
|
||||
if(new_vampire.hud_used)
|
||||
on_hud_created(new_vampire)
|
||||
|
||||
/datum/species/human/vampire/on_species_loss(mob/living/carbon/human/old_vampire, datum/species/new_species, pref_load)
|
||||
. = ..()
|
||||
UnregisterSignal(old_vampire, COMSIG_ATOM_ATTACKBY)
|
||||
UnregisterSignal(old_vampire, list(
|
||||
COMSIG_ATOM_ATTACKBY,
|
||||
COMSIG_MOB_HUD_CREATED,
|
||||
COMSIG_LIVING_LIFE,
|
||||
))
|
||||
old_vampire.hud_used?.remove_screen_object(HUD_MOB_BLOOD_LEVEL)
|
||||
|
||||
/datum/species/human/vampire/spec_life(mob/living/carbon/human/vampire, seconds_per_tick)
|
||||
. = ..()
|
||||
/datum/species/human/vampire/proc/on_life(mob/living/carbon/human/vampire, seconds_per_tick)
|
||||
SIGNAL_HANDLER
|
||||
if(istype(vampire.loc, /obj/structure/closet/crate/coffin))
|
||||
var/need_mob_update = FALSE
|
||||
need_mob_update += vampire.heal_overall_damage(brute = 2 * seconds_per_tick, burn = 2 * seconds_per_tick, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC)
|
||||
|
||||
@@ -47,15 +47,6 @@
|
||||
BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/zombie
|
||||
)
|
||||
|
||||
/// Spooky growls we sometimes play while alive
|
||||
var/static/list/spooks = list(
|
||||
'sound/effects/hallucinations/growl1.ogg',
|
||||
'sound/effects/hallucinations/growl2.ogg',
|
||||
'sound/effects/hallucinations/growl3.ogg',
|
||||
'sound/effects/hallucinations/veryfar_noise.ogg',
|
||||
'sound/effects/hallucinations/wail.ogg',
|
||||
)
|
||||
|
||||
/// Zombies do not stabilize body temperature they are the walking dead and are cold blooded
|
||||
/datum/species/zombie/body_temperature_core(mob/living/carbon/human/humi, seconds_per_tick)
|
||||
return
|
||||
@@ -178,11 +169,6 @@
|
||||
/datum/species/zombie/infectious/spec_stun(mob/living/carbon/human/H,amount)
|
||||
return min(2 SECONDS, amount)
|
||||
|
||||
/datum/species/zombie/infectious/spec_life(mob/living/carbon/carbon_mob, seconds_per_tick)
|
||||
. = ..()
|
||||
if(!HAS_TRAIT(carbon_mob, TRAIT_CRITICAL_CONDITION) && SPT_PROB(2, seconds_per_tick))
|
||||
playsound(carbon_mob, pick(spooks), 50, TRUE, 10)
|
||||
|
||||
// Weaker subtype - less healing, weaker attacks, etc
|
||||
/datum/species/zombie/infectious/mindless
|
||||
name = "Mindless Infectious Zombie"
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
if(HAS_TRAIT(src, TRAIT_STASIS))
|
||||
. = ..()
|
||||
if(QDELETED(src))
|
||||
return
|
||||
|
||||
reagents?.handle_stasis_chems(src, seconds_per_tick)
|
||||
else
|
||||
//Reagent processing needs to come before breathing, to prevent edge cases.
|
||||
@@ -31,9 +34,6 @@
|
||||
GLOB.addictions[key].process_addiction(src, seconds_per_tick)
|
||||
handle_brain_damage(seconds_per_tick)
|
||||
|
||||
if(stat != DEAD)
|
||||
handle_bodyparts(seconds_per_tick)
|
||||
|
||||
if(stat != DEAD)
|
||||
return TRUE
|
||||
|
||||
@@ -501,10 +501,6 @@
|
||||
|
||||
return COMPONENT_NO_EXPOSE_REAGENTS
|
||||
|
||||
/mob/living/carbon/proc/handle_bodyparts(seconds_per_tick)
|
||||
for(var/obj/item/bodypart/limb as anything in get_bodyparts(include_stumps = TRUE))
|
||||
. |= limb.on_life(seconds_per_tick)
|
||||
|
||||
/mob/living/carbon/proc/handle_organs(seconds_per_tick)
|
||||
if(stat == DEAD)
|
||||
if(reagents && (reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 1) || reagents.has_reagent(/datum/reagent/cryostylane))) // No organ decay if the body contains formaldehyde.
|
||||
@@ -526,49 +522,6 @@
|
||||
if(organ?.owner) // This exist mostly because reagent metabolization can cause organ reshuffling
|
||||
organ.on_life(seconds_per_tick)
|
||||
|
||||
/mob/living/carbon/handle_diseases(seconds_per_tick)
|
||||
for(var/datum/disease/disease as anything in diseases)
|
||||
if(QDELETED(disease)) //Got cured/deleted while the loop was still going.
|
||||
continue
|
||||
if(stat != DEAD || disease.process_dead)
|
||||
disease.stage_act(seconds_per_tick)
|
||||
|
||||
/mob/living/carbon/handle_mutations(time_since_irradiated, seconds_per_tick)
|
||||
if(!LAZYLEN(dna?.temporary_mutations))
|
||||
return
|
||||
|
||||
for(var/mut, mut_data in dna.temporary_mutations)
|
||||
if(mut_data < world.time)
|
||||
if(!LAZYLEN(dna.previous))
|
||||
continue
|
||||
if(mut == UI_CHANGED)
|
||||
if(dna.previous["UI"])
|
||||
dna.unique_identity = merge_text(dna.unique_identity,dna.previous["UI"])
|
||||
updateappearance(mutations_overlay_update=1)
|
||||
dna.previous.Remove("UI")
|
||||
LAZYREMOVE(dna.temporary_mutations, mut)
|
||||
continue
|
||||
if(mut == UF_CHANGED)
|
||||
if(dna.previous["UF"])
|
||||
dna.unique_features = merge_text(dna.unique_features,dna.previous["UF"])
|
||||
updateappearance(mutcolor_update=1, mutations_overlay_update=1)
|
||||
dna.previous.Remove("UF")
|
||||
LAZYREMOVE(dna.temporary_mutations, mut)
|
||||
continue
|
||||
if(mut == UE_CHANGED)
|
||||
if(dna.previous["name"])
|
||||
real_name = dna.previous["name"]
|
||||
name = real_name
|
||||
dna.previous.Remove("name")
|
||||
if(dna.previous["UE"])
|
||||
dna.unique_enzymes = dna.previous["UE"]
|
||||
dna.previous.Remove("UE")
|
||||
if(dna.previous["blood_type"])
|
||||
set_blood_type(dna.previous["blood_type"])
|
||||
dna.previous.Remove("blood_type")
|
||||
LAZYREMOVE(dna.temporary_mutations, mut)
|
||||
continue
|
||||
|
||||
/**
|
||||
* Returns a multiplier representing how effectively this mob can regenerate blood
|
||||
*
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
set waitfor = FALSE
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
|
||||
var/signal_result = SEND_SIGNAL(src, COMSIG_LIVING_LIFE, seconds_per_tick)
|
||||
var/signal_result = SEND_SIGNAL(src, COMSIG_LIVING_PRE_LIFE, seconds_per_tick)
|
||||
|
||||
if(signal_result & COMPONENT_LIVING_CANCEL_LIFE_PROCESSING) // mmm less work
|
||||
return
|
||||
@@ -41,18 +41,15 @@
|
||||
if(isnull(loc) || HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
|
||||
return
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_LIVING_LIFE, seconds_per_tick)
|
||||
if(QDELETED(src)) // signal handlers such as diseases could delete the mob
|
||||
return
|
||||
|
||||
if(!HAS_TRAIT(src, TRAIT_STASIS))
|
||||
if(stat != DEAD)
|
||||
//Mutations and radiation
|
||||
handle_mutations(seconds_per_tick)
|
||||
//Breathing, if applicable
|
||||
handle_breathing(seconds_per_tick)
|
||||
|
||||
handle_diseases(seconds_per_tick) // 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)
|
||||
@@ -64,21 +61,15 @@
|
||||
update_nutrition()
|
||||
living_flags &= ~QUEUE_NUTRITION_UPDATE
|
||||
|
||||
if (living_flags & BLOOD_UPDATE_QUEUED)
|
||||
if(living_flags & BLOOD_UPDATE_QUEUED)
|
||||
update_blood_effects()
|
||||
living_flags &= ~BLOOD_UPDATE_QUEUED
|
||||
|
||||
if(stat != DEAD)
|
||||
return TRUE
|
||||
|
||||
/mob/living/proc/handle_breathing(seconds_per_tick)
|
||||
SEND_SIGNAL(src, COMSIG_LIVING_HANDLE_BREATHING, seconds_per_tick)
|
||||
return
|
||||
|
||||
/mob/living/proc/handle_mutations(seconds_per_tick)
|
||||
return
|
||||
|
||||
/mob/living/proc/handle_diseases(seconds_per_tick)
|
||||
return
|
||||
|
||||
// Base mob environment handler for body temperature
|
||||
/mob/living/proc/handle_environment(datum/gas_mixture/environment, seconds_per_tick)
|
||||
|
||||
@@ -1309,7 +1309,7 @@
|
||||
if (ismonkey(human_mob))
|
||||
if (!HAS_TRAIT(human_mob, TRAIT_BORN_MONKEY))
|
||||
//This is the only time mutadone should remove monkeyism
|
||||
human_mob.dna.remove_mutation(/datum/mutation/race, list(MUTATION_SOURCE_ACTIVATED, MUTATION_SOURCE_MUTATOR))
|
||||
human_mob.dna.remove_mutation(/datum/mutation/race, GLOB.standard_mutation_sources)
|
||||
else if (HAS_TRAIT(human_mob, TRAIT_BORN_MONKEY))
|
||||
human_mob.monkeyize()
|
||||
|
||||
|
||||
@@ -661,10 +661,6 @@
|
||||
|
||||
update_icon_dropped()
|
||||
|
||||
//Return TRUE to get whatever mob this is in to update health.
|
||||
/obj/item/bodypart/proc/on_life(seconds_per_tick)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
|
||||
/**
|
||||
* #receive_damage
|
||||
*
|
||||
|
||||
@@ -420,6 +420,14 @@
|
||||
disliked_foodtypes = NONE
|
||||
// List of english words that translate to zombie phrases
|
||||
var/static/list/english_to_zombie = list()
|
||||
/// Spooky growls we sometimes play while alive
|
||||
var/static/list/spooks = list(
|
||||
'sound/effects/hallucinations/growl1.ogg',
|
||||
'sound/effects/hallucinations/growl2.ogg',
|
||||
'sound/effects/hallucinations/growl3.ogg',
|
||||
'sound/effects/hallucinations/veryfar_noise.ogg',
|
||||
'sound/effects/hallucinations/wail.ogg',
|
||||
)
|
||||
|
||||
/obj/item/organ/tongue/zombie/proc/add_word_to_translations(english_word, zombie_word)
|
||||
english_to_zombie[english_word] = zombie_word
|
||||
@@ -475,6 +483,11 @@
|
||||
message = capitalize(message)
|
||||
speech_args[SPEECH_MESSAGE] = message
|
||||
|
||||
/obj/item/organ/tongue/zombie/on_life(seconds_per_tick)
|
||||
. = ..()
|
||||
if(owner.stat == CONSCIOUS && SPT_PROB(2, seconds_per_tick))
|
||||
playsound(owner, pick(spooks), 50, TRUE, 10)
|
||||
|
||||
/obj/item/organ/tongue/alien
|
||||
name = "alien tongue"
|
||||
desc = "According to leading xenobiologists the evolutionary benefit of having a second mouth in your mouth is \"that it looks badass\"."
|
||||
|
||||
Reference in New Issue
Block a user