Mob Destroy Refactoring (#22573)

Refactoring the entire destroy proc path from Mob Human all the way down
to Atom while trying to find the causes for the damn mob human hard
deletes. This PR comprehensively reorganizes every single stray
snowflake var used by /atom/ all the way to /mob/living/carbon/human,
and makes sure that every var that COULD store a reference, is now
cleared during the entirety of the Mob Destroy() parent hierarchy.

This may very well be the end of the lag war. 

In total, I've hunted down and cleared 39 hanging references between
/atom and /mob/living/carbon/human

---------

Signed-off-by: VMSolidus <evilexecutive@gmail.com>
This commit is contained in:
VMSolidus
2026-06-03 15:15:56 +00:00
committed by GitHub
parent 7799ea7355
commit 201592f6bd
58 changed files with 383 additions and 345 deletions
-6
View File
@@ -2,7 +2,6 @@
Contains helper procs for airflow, handled in /connection_group.
*/
/mob/var/tmp/last_airflow_stun = 0
/mob/proc/airflow_stun()
if(stat == 2)
return 0
@@ -60,11 +59,6 @@ Contains helper procs for airflow, handled in /connection_group.
if(4,5)
if(n < GLOB.vsc.airflow_medium_pressure) return 0
/atom/movable/var/tmp/turf/airflow_dest
/atom/movable/var/tmp/airflow_speed = 0
/atom/movable/var/tmp/airflow_time = 0
/atom/movable/var/tmp/last_airflow = 0
/atom/movable/proc/AirflowCanMove(n)
return 1
-2
View File
@@ -20,8 +20,6 @@ GLOBAL_DATUM_INIT(contamination_overlay, /image, image('icons/effects/contaminat
///Does being in sleeping gas cause you to hallucinate?
var/N2O_HALLUCINATION = TRUE
/obj/var/contaminated = 0
/obj/item/proc/can_contaminate()
if(item_flags & ITEM_FLAG_PHORON_GUARD)
return FALSE
-5
View File
@@ -623,11 +623,6 @@ Turf and target are seperate in case you want to teleport some distance from a t
if (progbar)
qdel(progbar)
/// Integer. Unique sequential ID from the `do_after` proc used to validate `DO_USER_UNIQUE_ACT` flag checks.
/mob/var/do_unique_user_handle = 0
/// The mob currently interacting with the atom during a `do_after` timer. Used to validate `DO_TARGET_UNIQUE_ACT` flag checks.
/atom/var/mob/do_unique_target_user
/**
* Timed actions involving one mob user and (optionally) one target.
*
-4
View File
@@ -3,10 +3,6 @@
~Sayu
*/
// 1 decisecond click delay (above and beyond mob/next_move)
/mob/var/next_click = 0
/**
* Before anything else, defer these calls to a per-mobtype handler. This allows us to
* remove istype() spaghetti code, but requires the addition of other handler procs to simplify it.
-9
View File
@@ -11,15 +11,6 @@ if(!click_handlers) { \
click_handlers += new/datum/click_handler/default(src) \
}
/**
* LAZYLIST (Instances of `/datum/click_handler`). Click handlers for this mob that should intercept and handle click
* calls.
*
* The 'topmost'/'active' click handler for the mob is the handler currently at index `1`. By default, this will be
* `/datum/click_handler/default`.
*/
/mob/var/list/click_handlers
// In the mob code, because otherwise it's a redefinition
// /mob/Destroy()
// QDEL_LIST(click_handlers)
+30 -26
View File
@@ -5,11 +5,6 @@
GLOBAL_DATUM_INIT(global_hud, /datum/global_hud, new)
GLOBAL_LIST(global_huds)
/datum/hud/var/atom/movable/screen/grab_intent
/datum/hud/var/atom/movable/screen/hurt_intent
/datum/hud/var/atom/movable/screen/disarm_intent
/datum/hud/var/atom/movable/screen/help_intent
/datum/global_hud
var/atom/movable/screen/vr_control
var/atom/movable/screen/druggy
@@ -111,12 +106,11 @@ GLOBAL_LIST(global_huds)
O.layer = IMPAIRED_LAYER
O.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
/*
The hud datum
Used to show and hide huds for all the different mob types,
including inventories and item quick actions.
*/
/**
* The hud datum
* Used to show and hide huds for all the different mob types,
* including inventories and item quick actions.
*/
/datum/hud
///The mob that possesses the HUD
var/mob/mymob
@@ -136,12 +130,21 @@ GLOBAL_LIST(global_huds)
///Boolean, if the action buttons are hidden
var/action_buttons_hidden = FALSE
/*
STOP ADDING SNOWFLAKE HUD ELEMENTS LIKE /datum/hud/var/atom/movable/screen/help_intent
IN DIFFERENT FILES ENTIRELY. IF YOU ARE ADDING A NEW HUD ELEMENT TO THIS, PUT IT IN THIS FILE UNDER THIS LIST,
AND INCLUDE A QDEL_NULL() FOR IT IN THE DESTROY PROC.
*/
var/atom/movable/screen/blobpwrdisplay
var/atom/movable/screen/blobhealthdisplay
var/atom/movable/screen/r_hand_hud_object
var/atom/movable/screen/l_hand_hud_object
var/atom/movable/screen/action_intent
var/atom/movable/screen/movement_intent/move_intent
var/atom/movable/screen/grab_intent
var/atom/movable/screen/hurt_intent
var/atom/movable/screen/disarm_intent
var/atom/movable/screen/help_intent
var/list/adding
var/list/other
@@ -177,26 +180,27 @@ GLOBAL_LIST(global_huds)
..()
/datum/hud/Destroy()
grab_intent = null
hurt_intent = null
disarm_intent = null
help_intent = null
blobpwrdisplay = null
blobhealthdisplay = null
r_hand_hud_object = null
l_hand_hud_object = null
action_intent = null
move_intent = null
adding = null
other = null
hotkeybuttons = null
// item_action_list = null // ?
mymob = null
QDEL_NULL(blobpwrdisplay)
QDEL_NULL(blobhealthdisplay)
QDEL_NULL(r_hand_hud_object)
QDEL_NULL(l_hand_hud_object)
QDEL_NULL(action_intent)
QDEL_NULL(move_intent)
QDEL_NULL(grab_intent)
QDEL_NULL(hurt_intent)
QDEL_NULL(disarm_intent)
QDEL_NULL(help_intent)
adding?.Cut()
other?.Cut()
QDEL_LIST(hotkeybuttons)
QDEL_LIST_ASSOC_VAL(plane_masters)
QDEL_LIST_ASSOC_VAL(plane_master_controllers)
QDEL_NULL(hide_actions_toggle)
. = ..()
return ..()
/datum/hud/proc/hidden_inventory_update()
if(!mymob)
+2 -2
View File
@@ -26,10 +26,10 @@
/atom/movable/screen/Destroy(force = FALSE)
master = null
screen_loc = null
if(hud?.mymob?.client)
if(length(hud?.mymob?.client?.screen))
hud.mymob.client.screen -= src
hud = null
. = ..()
return ..()
/// Screen elements are always on top of the players screen and don't move so yes they are adjacent
/atom/movable/screen/Adjacent(atom/neighbor, atom/target, atom/movable/mover)
-3
View File
@@ -410,9 +410,6 @@ SUBSYSTEM_DEF(jobs)
Debug("ER/([H]): Completed.")
return H
/mob/living/carbon/human
var/tmp/centcomm_despawn_timer
/mob/living/proc/centcomm_timeout()
if (!istype(get_area(src), /area/centcom/spawning))
return FALSE
-3
View File
@@ -66,9 +66,6 @@ SUBSYSTEM_DEF(mob_ai)
mutexes -= mob_weakref
/mob
var/thinking_enabled = FALSE
/**
* Perform AI logic for a mob, called by the AI subsystem
*
@@ -55,11 +55,6 @@ SUBSYSTEM_DEF(virtualreality)
if(bound && network)
bounded[network].Remove(bound)
/mob
var/mob/living/vr_mob = null // In which mob is our mind
var/mob/living/old_mob = null // Which mob is our old mob
/// Return to original body
/mob/proc/body_return()
set name = "Return to Body"
-11
View File
@@ -27,17 +27,6 @@
#define langchat_client_enabled(M) (M && M.client && M.client.prefs && (M.client.prefs.toggles_secondary & FLOATING_MESSAGES))
/*
* Duplicate vars and logic created for untranslated images for the sake of getting an untranslated langchat to display for listeners who do not understand
* the language being spoken. Someone could certainly think of cleaner ways to do this, but for want of a better solution right now, it has been implemented
* in this rote manner to make it easier to strip out in future if it needs replaced.
*/
/atom/var/image/langchat_image
/atom/var/image/langchat_image_untranslated
/atom/var/list/mob/langchat_listeners
/atom/var/list/mob/langchat_listeners_untranslated
/// Hides the images, if they exist. Do not null the langchat images; they are rotated when the mob is buckled or proned to maintain text orientation.
/atom/proc/langchat_drop_images()
if(langchat_listeners)
+22 -6
View File
@@ -138,19 +138,31 @@
/// This atom's cache of overlays that can only be removed explicitly, like C4. Do not manipulate directly- See SSoverlays.
var/list/atom_protected_overlay_cache
/// The mob currently interacting with the atom during a `do_after` timer. Used to validate `DO_TARGET_UNIQUE_ACT` flag checks.
var/mob/do_unique_target_user
/*
* Duplicate vars and logic created for untranslated images for the sake of getting an untranslated langchat to display for listeners who do not understand
* the language being spoken. Someone could certainly think of cleaner ways to do this, but for want of a better solution right now, it has been implemented
* in this rote manner to make it easier to strip out in future if it needs replaced.
*/
var/image/langchat_image
var/image/langchat_image_untranslated
var/list/mob/langchat_listeners
var/list/mob/langchat_listeners_untranslated
/atom/Destroy(force)
if(opacity)
updateVisibility(src)
if(reagents)
QDEL_NULL(reagents)
QDEL_NULL(reagents)
// Checking length(overlays) before cutting has significant speed benefits
if(length(overlays))
overlays.Cut()
if(light)
QDEL_NULL(light)
QDEL_NULL(light)
if(smoothing_flags & SMOOTH_QUEUED)
SSicon_smooth.remove_from_queues(src)
@@ -167,8 +179,12 @@
// The component is attached to us normaly and will be deleted elsewhere
orbiters = null
. = ..()
do_unique_target_user = null
QDEL_NULL(langchat_image)
QDEL_NULL(langchat_image_untranslated)
langchat_listeners?.Cut()
langchat_listeners_untranslated?.Cut()
return ..()
/atom/proc/handle_ricochet(obj/projectile/ricocheting_projectile)
var/turf/p_turf = get_turf(ricocheting_projectile)
+8 -3
View File
@@ -87,6 +87,11 @@
/// Whether this atom should have its dir automatically changed when it moves. Setting this to FALSE allows for things such as directional windows to retain dir on moving without snowflake code all of the place.
var/set_dir_on_move = TRUE
var/tmp/turf/airflow_dest
var/tmp/airflow_speed = 0
var/tmp/airflow_time = 0
var/tmp/last_airflow = 0
/atom/movable/Initialize(mapload, ...)
. = ..()
update_emissive_blocker()
@@ -114,14 +119,11 @@
QDEL_LAZYLIST(contained_mobs)
. = ..()
for(var/movable_content in contents)
qdel(movable_content)
//Pretend this is moveToNullspace()
moveToNullspace()
loc = null
//This absolutely must be after moveToNullspace()
//We rely on Entered and Exited to manage this list, and the copy of this list that is on any /atom/movable "Containers"
@@ -150,6 +152,9 @@
QDEL_NULL(light)
QDEL_NULL(static_light)
airflow_dest = null
loc = null
return ..()
/atom/movable/proc/moveToNullspace()
. = TRUE
-5
View File
@@ -1,8 +1,3 @@
/mob
//thou shall always be able to see the Geometer of Blood
var/image/narsimage = null
var/image/narglow = null
/mob/proc/cultify()
return
@@ -54,11 +54,6 @@
spawn (0)
AM.singularity_pull(src, src.current_size)
/mob
//thou shall always be able to see the rift
var/image/riftimage = null
/mob/proc/see_rift(var/obj/singularity/narsie/large/exit/R)
var/turf/T_mob = get_turf(src)
if((R.z == T_mob.z) && (get_dist(R,T_mob) <= (R.consume_range+10)) && !(R in view(T_mob)))
@@ -8,13 +8,6 @@
#define TECHNOMANCER_INSTABILITY_PRECISION 0.1 // Instability is rounded to this.
#define TECHNOMANCER_INSTABILITY_MIN_GLOW 10 // When above this number, the entity starts glowing, affecting others.
/mob/living
atom_flags = CRITICAL_ATOM
var/instability = 0
var/last_instability = 0 // Used to calculate instability delta.
var/last_instability_event = null // most recent world.time that something bad happened due to instability.
// Proc: adjust_instability()
// Parameters: 0
// Description: Does nothing, because inheritance.
@@ -14,10 +14,6 @@ would spawn and follow the beaker, even if it is carried or thrown.
pass_flags = PASSTABLE | PASSGRILLE
blocks_emissive = EMISSIVE_BLOCK_GENERIC
/obj/effect/Destroy()
QDEL_NULL(reagents)
return ..()
/datum/effect/effect/system
var/number = 3
var/cardinals = 0
+9
View File
@@ -108,6 +108,15 @@
var/persistant_objects_expiration_time_days = PERSISTENT_DEFAULT_EXPIRATION_DAYS
/* END PERSISTENCE VARS */
/// for easy reference of talking atoms
var/datum/talking_atom/talking_atom
/// Whether this object has been contaminated by atmos gasses like chlorine or phoron.
var/contaminated = FALSE
/// Allow overriding rad resistance.
var/rad_resistance_modifier = 1
/obj/Initialize(mapload, ...)
. = ..()
if(maxhealth)
-4
View File
@@ -1,7 +1,3 @@
/mob/var/mob/lastattacker = null
/mob/var/mob/lastattacked = null
/mob/var/attack_log = list()
/proc/log_and_message_admins(var/message as text, var/mob/user = usr, var/turf/location)
var/turf/T = location ? location : (user ? get_turf(user) : null)
if(T)
-5
View File
@@ -4,11 +4,6 @@
var/override = FALSE //If set to override we will stop multiplying the moment we get here. NOTE: Priority remains, if your override is on position 4, the other 3 will still have a say.
var/disability = FALSE
/mob
var/list/client_colors = list()
/*
Adds an instance of color_type to the mob's client_colors list
color_type - a typepath (subtyped from /datum/client_color)
@@ -1,7 +1,3 @@
/mob/living/carbon/human
var/singleton/origin_item/culture/culture
var/singleton/origin_item/origin/origin
/datum/category_item/player_setup_item/origin
name = "Origin"
sort_order = 1
@@ -25,9 +25,6 @@
module.holder.ui_interact(usr)
/mob
var/get_rig_stats = 0
/obj/item/rig_module/ai_container
name = "IIS module"
desc = "An integrated intelligence system module suitable for most hardsuits."
-8
View File
@@ -1,11 +1,3 @@
/mob
var/bloody_hands = null
var/datum/weakref/bloody_hands_mob
var/track_footprint = 0
var/list/feet_blood_DNA
var/track_footprint_type
var/footprint_color
/obj/item/clothing/gloves
var/transfer_blood = 0
var/datum/weakref/bloody_hands_mob
-4
View File
@@ -1,7 +1,3 @@
/mob
var/list/default_emotes = list()
var/list/usable_emotes = list()
/mob/proc/update_emotes(var/skip_sort)
usable_emotes.Cut()
for(var/emote in default_emotes)
@@ -200,7 +200,3 @@
M.ghost_spawner = WEAKREF(src)
return M
/// Used for cryo to free up a slot when a ghost cryos.
/mob/living/carbon/human
var/datum/weakref/ghost_spawner
-4
View File
@@ -1,7 +1,3 @@
/mob/living/carbon
var/next_hallucination = 0 //Hallucination spam limit var
var/list/hallucinations = list() //Hallucinations currently affecting the mob. Not to be confused with singular "hallucination" which is a NUM variable like confused/drowsy/eye_blind etc
//Hallucinated Hearing
/mob/living/carbon/hear_say(var/message, var/verb = "says", var/datum/language/language, var/alt_name = "",var/italics = 0, var/mob/speaker, var/sound/speech_sound, var/sound_vol)
if(hallucination >= 60 && prob(1))
@@ -122,9 +122,6 @@
return
return loc
/mob
var/mob/abstract/eye/eyeobj
/mob/proc/EyeMove(n, direct)
if(!eyeobj)
return
+2 -1
View File
@@ -6,7 +6,7 @@
/// This variable generally controls whether a ghost has restrictions on where it can go or not (ex. if the ghost can bypass holy places).
var/has_ghost_restrictions = TRUE
/// If the ghost has antagHUD.
var/antagHUD = 0
var/antagHUD = FALSE
/// Necessary for seeing wires.
var/obj/item/multitool/ghost_multitool
/// The POI we're orbiting.
@@ -22,6 +22,7 @@
/mob/abstract/ghost/Destroy()
QDEL_NULL(ghost_multitool)
orbiting_ref = null
return ..()
/mob/abstract/ghost/Topic(href, href_list)
@@ -22,17 +22,17 @@
/// This variable is set to 1 when you enter the game as an observer. Remains null if you died in the game and are a ghost. Not reliable for admins; they change mobs a lot.
var/started_as_observer
/// If the ghost has enabled antagHUD.
var/has_enabled_antagHUD = 0
var/has_enabled_antagHUD = FALSE
/// If the ghost has enabled medHUD.
var/medHUD = 0
var/medHUD = FALSE
/// If this is an adminghost.
var/admin_ghosted = 0
var/admin_ghosted = FALSE
/// If this ghost has enabled chat anonymization.
var/anonsay = 0
var/anonsay = FALSE
/// If the ghost can be seen through cult shenanigans.
var/is_manifest = 0
var/is_manifest = FALSE
/// Cooldown for ghost abilities, such as move_item().
var/ghost_cooldown = 0
var/ghost_cooldown = FALSE
/mob/abstract/ghost/observer/Initialize(mapload, mob/body)
. = ..()
@@ -87,12 +87,21 @@
src.LoadComponent(/datum/component/health_analyzer/observer)
/mob/abstract/ghost/observer/Destroy()
if(client)
// Handling client images
if(client && length(client.images))
for(var/image/I in client.images)
if(I.loc == src)
qdel(I)
// Something deleted the image, clear it and move on.
if (!istype(I) || QDELETED(I))
client.images -= I
continue
if(I.loc != src)
continue
qdel(I)
client.images -= I
QDEL_NULL(hud)
mind = null
return ..()
/mob/abstract/ghost/observer/proc/initialise_postkey(set_timers = TRUE)
-10
View File
@@ -7,10 +7,6 @@ currently only humans get dizzy
value of dizziness ranges from 0 to 1000
below 100 is not dizzy
*/
/mob/var/dizziness = 0//Carbon
/mob/var/is_dizzy = 0
/mob/proc/make_dizzy(var/amount)
if(!istype(src, /mob/living/carbon/human)) // for the moment, only humans get dizzy
return
@@ -43,8 +39,6 @@ note dizziness decrements automatically in the mob's Life() proc.
client.pixel_y = 0
// jitteriness - copy+paste of dizziness
/mob/var/is_jittery = 0
/mob/var/jitteriness = 0//Carbon
/mob/proc/make_jittery(var/amount)
return
@@ -69,10 +63,6 @@ note dizziness decrements automatically in the mob's Life() proc.
pixel_x = old_x
pixel_y = old_y
//handles up-down floaty effect in space and zero-gravity
/mob/var/is_floating = FALSE
/mob/proc/update_floating()
if(anchored || buckled_to)
set_floating(FALSE)
+8 -3
View File
@@ -39,14 +39,19 @@
. = 1
/mob/living/carbon/Destroy()
QDEL_NULL(touching)
species = null
QDEL_NULL(handcuffed)
QDEL_NULL(legcuffed)
QDEL_NULL(op_stage)
chem_doses?.Cut()
QDEL_NULL(bloodstr)
QDEL_NULL(dna)
QDEL_NULL(touching)
QDEL_NULL(breathing)
// Delete and null a direct list of references to our internal organs (such as brain, lungs, heart, etc).
QDEL_LIST(internal_organs)
// Null an Associative list of String = Reference to the same organs.
internal_organs_by_name = null
internal_organs_by_name?.Cut()
QDEL_LIST(hallucinations)
return ..()
/mob/living/carbon/rejuvenate()
@@ -50,7 +50,9 @@
/// Map organ names to organs.
var/list/organs_by_name = list()
/// So internal organs have less ickiness too.
/// List of references to all internal organs
var/list/internal_organs = list()
/// Associative List of "name" = ref
var/list/internal_organs_by_name = list()
var/list/stasis_sources = list()
@@ -58,3 +60,8 @@
/// For special cases where something permanently removes a mob's ability to feel pain.
var/pain_immune = FALSE
/// Hallucination spam limit var
var/next_hallucination = 0
/// Hallucinations currently affecting the mob. Not to be confused with singular "hallucination" which is a NUM variable like confused/drowsy/eye_blind etc
var/list/hallucinations = list()
var/shock_stage = 0
@@ -7,10 +7,6 @@
#define COLD_DAMAGE_LEVEL_2 1.5
#define COLD_DAMAGE_LEVEL_3 3
/mob/living/carbon/human
var/datum/dionastats/DS
/mob/living/carbon/human/proc/setup_gestalt()
composition_reagent = /singleton/reagent/nutriment //Dionae aren't animals, so eating them doesn't give animal protein
setup_dionastats()
+14 -22
View File
@@ -4,21 +4,12 @@
voice_name = "unknown"
icon = 'icons/mob/human.dmi'
icon_state = "body_m_s"
mob_size = 9 //Based on average weight of a human
var/pronouns = NEUTER
/// Used so species that need special items (autoinhalers for vaurca/RMT for offworlders) don't get them twice when they shouldn't.
var/species_items_equipped
var/list/hud_list[11]
/// To check if we've need to roll for damage on movement while an item is imbedded in us.
var/embedded_flag
/// This is very not good, but it's much much better than calling get_rig() every update_canmove() call.
var/obj/item/rig/wearing_rig
/// Pref holder for the speech bubble style.
var/speech_bubble_type
mob_bump_flag = HUMAN
mob_push_flags = ~HEAVY
mob_swap_flags = ~HEAVY
light_system = MOVABLE_LIGHT
blocks_emissive = EMISSIVE_BLOCK_NONE
/mob/living/carbon/human/Initialize(mapload, var/new_species = null)
if(!dna)
@@ -105,7 +96,7 @@
set_default_attack(species.unarmed_attacks[1])
/mob/living/carbon/human/Destroy(force)
ghost_spawner = null
QDEL_NULL(ghost_spawner)
//Srom (Shared Dreaming)
srom_pulled_by = null
@@ -118,9 +109,9 @@
// It's actually the set of all Limbs (left arm, head, leg leg, etc) we have. We Qdel and null the set of all limbs, which is unique to /human.
QDEL_LIST(organs)
// Then also null the associative list of those same limbs, which contains the same references.
organs_by_name = null
bad_internal_organs = null
bad_external_organs = null
QDEL_LIST_ASSOC_VAL(organs_by_name)
bad_internal_organs?.Cut()
bad_external_organs?.Cut()
QDEL_NULL(vessel)
@@ -150,13 +141,14 @@
//Yes this is shit, but since someone had the brillant mind to use images for this, we must suffer
if(length(hud_list))
for(var/image/hud_overlay/an_hud_overlay in hud_list)
if(an_hud_overlay.owner)
an_hud_overlay.owner.client?.images -= an_hud_overlay
if(length(an_hud_overlay.owner?.client?.images))
an_hud_overlay.owner.client.images -= an_hud_overlay
an_hud_overlay.owner = null
qdel(an_hud_overlay)
hud_list = null
hud_list.Cut()
. = ..()
wearing_rig = null
return ..()
/mob/living/carbon/human/can_devour(atom/movable/victim, var/silent = FALSE)
if(!should_have_organ(BP_STOMACH))
@@ -1,8 +1,4 @@
/mob/living/carbon/human
light_system = MOVABLE_LIGHT
blocks_emissive = EMISSIVE_BLOCK_NONE
// Tail Style
var/tail_style = null
@@ -103,10 +99,6 @@
var/list/gunshot_residue
var/pulling_punches // Are you trying not to hurt your opponent?
mob_bump_flag = HUMAN
mob_push_flags = ~HEAVY
mob_swap_flags = ~HEAVY
var/flash_protection = 0 // Total level of flash protection
var/equipment_tint_total = 0 // Total level of visualy impairing items
var/equipment_darkness_modifier // Darkvision modifier from equipped items
@@ -134,3 +126,48 @@
var/triage_tag = TRIAGE_NONE
var/lobotomized = FALSE //additional check for isAdvancedToolUser that can be set manually by things
var/list/organs = list()
///Container for blood and BLOOD ONLY. Do not transfer other chems here.
var/datum/reagents/vessel
/// Used for cryo to free up a slot when a ghost cryos.
var/datum/weakref/ghost_spawner
var/next_stance_collapse = 0
var/datum/dionastats/DS
var/oxygen_alert = 0
var/phoron_alert = 0
var/co2_alert = 0
var/fire_alert = 0
var/pressure_alert = 0
var/temperature_alert = 0
var/datum/weakref/srom_pulled_by
var/datum/weakref/srom_pulling
/// Our set of "raw" overlays that can be modified, but cannot be directly applied to the mob without preprocessing.
var/list/overlays_raw[TOTAL_LAYERS]
/// store what the body last looked like, so we only have to update it if something changed
var/previous_damage_appearance
var/singleton/origin_item/culture/culture
var/singleton/origin_item/origin/origin
var/tmp/centcomm_despawn_timer
var/pronouns = NEUTER
/// Used so species that need special items (autoinhalers for vaurca/RMT for offworlders) don't get them twice when they shouldn't.
var/species_items_equipped
var/list/hud_list[11]
/// To check if we've need to roll for damage on movement while an item is imbedded in us.
var/embedded_flag
/// This is very not good, but it's much much better than calling get_rig() every update_canmove() call.
var/obj/item/rig/wearing_rig
/// Pref holder for the speech bubble style.
var/speech_bubble_type
@@ -4,10 +4,6 @@
eyes.update_colour()
regenerate_icons()
/mob/living/carbon/var/list/internal_organs = list()
/mob/living/carbon/var/shock_stage = 0
/mob/living/carbon/human/var/list/organs = list()
/mob/living/carbon/human/proc/recheck_bad_external_organs()
var/damage_this_tick = getToxLoss()
var/arterial_check = 0
@@ -57,9 +53,6 @@
if (W.infection_check())
W.germ_level += 1
/mob/living/carbon/human
var/next_stance_collapse = 0
/mob/living/carbon/human/proc/handle_stance()
// Don't need to process any of this if they aren't standing anyways
// unless their stance is damaged, and we want to check if they should stay down
@@ -45,14 +45,6 @@
///The maximum dose that can be received, above this level all further radiation is taken as damage directly to the body, ignoring armor. Very rapidly fatal.
#define RADIATION_MAX_DOSE 1000
/mob/living/carbon/human
var/oxygen_alert = 0
var/phoron_alert = 0
var/co2_alert = 0
var/fire_alert = 0
var/pressure_alert = 0
var/temperature_alert = 0
/mob/living/carbon/human/Life(seconds_per_tick, times_fired)
if (transforming)
return
@@ -100,10 +100,6 @@ There are several things that need to be remembered:
ret.layer = layer
return ret
/mob/living/carbon/human
var/list/overlays_raw[TOTAL_LAYERS] // Our set of "raw" overlays that can be modified, but cannot be directly applied to the mob without preprocessing.
var/previous_damage_appearance // store what the body last looked like, so we only have to update it if something changed
// Updates overlays from overlays_raw.
/mob/living/carbon/human/update_icon()
if (QDELETED(src))
@@ -1,6 +1,3 @@
/mob/living
var/datum/language/default_language
/mob/living/verb/set_default_language_verb()
set name = "Set Default Language"
set category = "IC.Language"
-3
View File
@@ -196,9 +196,6 @@
/mob/living/proc/handle_hud_icons_health()
return
/mob/living
var/datum/weakref/last_weather
/mob/living/proc/is_outside()
var/turf/T = loc
return istype(T) && T.is_outside()
+13 -19
View File
@@ -53,9 +53,6 @@ default behaviour is:
return TRUE
return FALSE
/mob/living
var/tmp/last_push_notif
/mob/living/Collide(atom/movable/target_movable_atom)
if(now_pushing || !loc)
return
@@ -922,19 +919,17 @@ default behaviour is:
AddElement(/datum/element/connect_loc, loc_connections)
/mob/living/Destroy()
cameraFollow = null
if (length(actions))
for (var/datum/action/action in actions)
action.Remove(src)
actions -= action
//Aiming overlay
QDEL_NULL(stamina_bar)
QDEL_LIST(auras)
QDEL_NULL(psi)
QDEL_NULL(aiming)
QDEL_LIST(aimed_at_by)
//Psi complexus
QDEL_NULL(psi)
if(vr_mob)
vr_mob = null
if(old_mob)
old_mob = null
//Remove contained mobs
if(loc)
for(var/mob/M in contents)
@@ -943,12 +938,11 @@ default behaviour is:
for(var/mob/M in contents)
qdel(M)
QDEL_NULL(reagents)
if(auras)
for(var/a in auras)
remove_aura(a)
prepared_maneuver = null
available_maneuvers?.Cut()
default_language = null
QDEL_NULL(z_eye)
QDEL_NULL(last_weather)
return ..()
/mob/living/proc/nervous_system_failure()
+24
View File
@@ -102,3 +102,27 @@
/// Time since last weather effect
var/weather_cooldown_time = 0
var/datum/psi_complexus/psi
///The obj to overlay on the aim target
var/obj/aiming_overlay/aiming
///A list of mobs the target is being aimed at by
var/list/aimed_at_by
var/singleton/maneuver/prepared_maneuver
var/list/available_maneuvers = list()
var/datum/language/default_language
var/atom/movable/z_observer/z_eye
atom_flags = CRITICAL_ATOM
var/instability = 0
var/last_instability = 0 // Used to calculate instability delta.
var/last_instability_event = null // most recent world.time that something bad happened due to instability.
var/datum/weakref/last_weather
var/tmp/last_push_notif
@@ -1,7 +1,3 @@
/mob/living
var/singleton/maneuver/prepared_maneuver
var/list/available_maneuvers = list()
/mob/living/begin_falling(var/lastloc, var/below)
if(throwing)
return
-3
View File
@@ -25,9 +25,6 @@
message_admins(SPAN_WARNING("<B>Notice: </B></span><span class='notice'><A href='byond://?src=[REF(usr)];priv_msg=[REF(src)]'>[key_name_admin(src)]</A> has the same [matches] as [key_name_admin(M)] (no longer logged in). "), 1)
log_access("Notice: [key_name(src)] has the same [matches] as [key_name(M)] (no longer logged in).")
/mob
var/client/my_client // Need to keep track of this ourselves, since by the time Logout() is called the client has already been nulled
/**
* Currently marked as SHOULD_NOT_OVERRIDE.
*
+86 -46
View File
@@ -1,32 +1,90 @@
/mob/Destroy()//This makes sure that mobs with clients/keys are not just deleted from the game.
MOB_STOP_THINKING(src)
// Tell any mobs touching us that they're not pulling us anymore.
stop_pulling()
// Delete and null the grab objects that are touching this mob.
QDEL_LIST(grabbed_by)
GLOB.mob_list -= src
GLOB.dead_mob_list -= src
GLOB.living_mob_list -= src
GLOB.player_list -= src
unset_machine()
QDEL_NULL(hud_used)
QDEL_NULL(cells)
QDEL_NULL(flash)
QDEL_NULL(blind)
QDEL_NULL(hands)
QDEL_NULL(pullin)
QDEL_NULL(purged)
QDEL_NULL(internals)
QDEL_NULL(oxygen)
QDEL_NULL(paralysis_indicator)
QDEL_NULL(i_select)
QDEL_NULL(m_select)
QDEL_NULL(toxin)
QDEL_NULL(bodytemp)
QDEL_NULL(healths)
QDEL_NULL(throw_icon)
QDEL_NULL(nutrition_icon)
QDEL_NULL(hydration_icon)
QDEL_NULL(pressure)
QDEL_NULL(damageoverlay)
QDEL_NULL(pain)
QDEL_NULL(item_use_icon)
QDEL_NULL(radio_use_icon)
QDEL_NULL(gun_move_icon)
QDEL_NULL(gun_setting_icon)
QDEL_NULL(unique_action_icon)
QDEL_NULL(toggle_firing_mode)
QDEL_NULL(energy_display)
QDEL_NULL(instability_display)
QDEL_NULL(up_hint)
QDEL_NULL(robot_pain)
QDEL_LIST(spell_masters)
remove_screen_obj_references()
if(client)
for(var/atom/movable/AM in client.screen)
qdel(AM)
if (!QDELING(AM))
qdel(AM)
client.screen = list()
if (mind)
mind.handle_mob_deletion(src)
mind?.handle_mob_deletion(src)
mind = null
for(var/cc in client_colors)
qdel(cc)
QDEL_NULL(ability_master)
QDEL_NULL(zone_sel)
machine = null
client_colors = null
pulling?.pulledby = null
pulling = null
pullin?.icon_state = "pull0"
pullin = null
QDEL_LIST(client_colors)
additional_vision_handlers?.Cut()
pinned?.Cut()
QDEL_LIST(embedded)
languages?.Cut()
holo = null
l_hand = null
r_hand = null
back = null
internal = null
s_active = null
wear_mask = null
QDEL_NULL(dna)
QDEL_NULL(LAssailant)
spell_list?.Cut()
lastarea = null
control_object = null
teleop = null
listed_turf = null
item_verbs = null
// This is a nested assoc list, which must be cleared outside-in
if (length(progressbars))
for (var/location in progressbars)
for (var/ref in progressbars[location])
qdel(ref)
progressbars.Cut()
QDEL_NULL(typing_indicator)
//Added this to prevent nonliving mobs from ghostising
//The only non 'living' mobs are:
@@ -44,11 +102,21 @@
var/atom/movable/AM = src.loc
LAZYREMOVE(AM.contained_mobs, src)
QDEL_NULL(ability_master)
if(click_handlers)
QDEL_LIST(click_handlers)
QDEL_LIST(click_handlers)
vr_mob = null
old_mob = null
lastattacker = null
lastattacked = null
QDEL_NULL(pointing_effect)
QDEL_LIST(open_nanouis)
QDEL_LIST(tgui_open_uis)
QDEL_NULL(narsimage)
QDEL_NULL(narglow)
QDEL_NULL(riftimage)
QDEL_NULL(bloody_hands_mob)
QDEL_NULL(eyeobj)
QDEL_NULL(bg)
my_client = null
return ..()
/mob/New()
@@ -56,32 +124,6 @@
GenerateTag()
return ..()
/mob/proc/remove_screen_obj_references()
flash = null
blind = null
hands = null
pullin = null
purged = null
internals = null
oxygen = null
i_select = null
m_select = null
toxin = null
bodytemp = null
healths = null
throw_icon = null
nutrition_icon = null
hydration_icon = null
pressure = null
damageoverlay = null
pain = null
item_use_icon = null
gun_move_icon = null
gun_setting_icon = null
spell_masters = null
zone_sel = null
/mob/var/should_add_to_mob_list = TRUE
/mob/Initialize(mapload)
. = ..()
if(should_add_to_mob_list)
@@ -400,8 +442,6 @@
if(!. && iscarbon(loc) && isturf(loc.loc)) // We're inside someone, let us examine still.
return TRUE
/mob/var/obj/effect/decal/point/pointing_effect = null//Spam control, can only point when the previous pointer qdels
/mob/verb/pointed(atom/A as mob|obj|turf in view())
set name = "Point To"
set category = "Object"
@@ -730,8 +770,8 @@
if(pulling)
pulling.pulledby = null
pulling = null
if(pullin)
pullin.icon_state = "pull0"
if(pullin)
pullin.icon_state = "pull0"
/mob/proc/start_pulling(var/atom/movable/AM)
+79
View File
@@ -276,3 +276,82 @@
/// A assoc lazylist of to_chat notifications, key = string message, value = world time integer
var/list/message_notifications
var/mob/living/vr_mob = null // In which mob is our mind
var/mob/living/old_mob = null // Which mob is our old mob
/**
* LAZYLIST (Instances of `/datum/click_handler`). Click handlers for this mob that should intercept and handle click
* calls.
*
* The 'topmost'/'active' click handler for the mob is the handler currently at index `1`. By default, this will be
* `/datum/click_handler/default`.
*/
var/list/click_handlers
var/should_add_to_mob_list = TRUE
/// Integer. Unique sequential ID from the `do_after` proc used to validate `DO_USER_UNIQUE_ACT` flag checks.
var/do_unique_user_handle = 0
var/mob/lastattacker = null
var/mob/lastattacked = null
var/attack_log = list()
/// Spam control, can only point when the previous pointer qdels
var/obj/effect/decal/point/pointing_effect = null
/// 1 decisecond click delay (above and beyond mob/next_move)
var/next_click = 0
var/dizziness = 0//Carbon
var/is_dizzy = 0
var/is_jittery = 0
var/jitteriness = 0//Carbon
//handles up-down floaty effect in space and zero-gravity
var/is_floating = FALSE
// Used by the Nano UI Manager (/datum/SSnanoui) to track UIs opened by this mob
var/list/open_nanouis = list()
var/last_pain_message = ""
var/next_pain_time = 0
/**
* global
*
* Tracks open UIs for a user.
*/
var/list/tgui_open_uis = list()
var/tmp/last_airflow_stun = 0
//thou shall always be able to see the Geometer of Blood
var/image/narsimage = null
var/image/narglow = null
//thou shall always be able to see the rift
var/image/riftimage = null
var/list/client_colors = list()
var/bloody_hands = null
var/datum/weakref/bloody_hands_mob
var/track_footprint = 0
var/list/feet_blood_DNA
var/track_footprint_type
var/footprint_color
var/mob/abstract/eye/eyeobj
var/mob/living/brain_ghost/bg
var/list/default_emotes = list()
var/list/usable_emotes = list()
var/client/my_client // Need to keep track of this ourselves, since by the time Logout() is called the client has already been nulled
var/get_rig_stats = 0
var/thinking_enabled = FALSE
-3
View File
@@ -782,9 +782,6 @@
/mob/fall_get_specs(levels_fallen)
return list(mob_size, throw_range)
/mob/living
var/atom/movable/z_observer/z_eye
/atom/movable/z_observer
name = ""
simulated = FALSE
-3
View File
@@ -35,6 +35,3 @@
*/
/datum/proc/nanoui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/nanoui/master_ui = null, var/datum/ui_state/state = GLOB.default_state)
return
// Used by the Nano UI Manager (/datum/SSnanoui) to track UIs opened by this mob
/mob/var/list/open_nanouis = list()
-2
View File
@@ -2,8 +2,6 @@
BLOOD SYSTEM
****************************************************/
/mob/living/carbon/human/var/datum/reagents/vessel //Container for blood and BLOOD ONLY. Do not transfer other chems here.
//Initializes blood vessels
/mob/living/carbon/human/proc/make_blood()
if(vessel)
-3
View File
@@ -3,9 +3,6 @@
animate(pain, alpha = target, time = 15, easing = ELASTIC_EASING)
animate(pain, alpha = 0, time = 20)
/mob/var/last_pain_message = ""
/mob/var/next_pain_time = 0
// message is the custom message to be displayed
// power decides how much painkillers will stop the message
// force means it ignores anti-spam timer
@@ -1,10 +1,3 @@
/mob/living
///The obj to overlay on the aim target
var/obj/aiming_overlay/aiming
///A list of mobs the target is being aimed at by
var/list/aimed_at_by
/mob/verb/toggle_gun_mode()
set name = "Toggle Gun Mode"
set desc = "Begin or stop aiming."
-3
View File
@@ -1,6 +1,3 @@
/mob/living
var/datum/psi_complexus/psi
/mob/living/proc/set_psi_rank(var/rank, var/defer_update, var/temporary)
if(HAS_TRAIT(src, TRAIT_PSIONICALLY_DEAF))
to_chat(src, SPAN_WARNING("Something tingles in your head."))
-4
View File
@@ -58,10 +58,6 @@
SSradiation.resistance_cache[src] = (length(contents) + 1)
cached_rad_resistance = (density ? material.weight / RADIATION_MATERIAL_RESISTANCE_DIVISOR : 0)
/obj
/// Allow overriding rad resistance.
var/rad_resistance_modifier = 1
/**
* Retrieves the atom's current radiation level. By default, this will return `loc.get_rads()`.
*
@@ -4,9 +4,6 @@
// This could be extended to atoms, but it's bad enough as is
// I genuinely tried to Add and Remove them from var and proc lists, but just couldn't get it working
//for easy reference
/obj/var/datum/talking_atom/talking_atom
/datum/talking_atom
var/list/heard_words = list()
var/last_talk_time = 0
-7
View File
@@ -1,13 +1,6 @@
///A list of `/turf` where the Srom is located, and people entering the shared dream (presumably Skrells sleeping) will be casted to
GLOBAL_LIST_EMPTY_TYPED(dream_entries, /turf)
/mob
var/mob/living/brain_ghost/bg
/mob/living/carbon/human
var/datum/weakref/srom_pulled_by
var/datum/weakref/srom_pulling
/mob/living/carbon/human/proc/handle_shared_dreaming(var/force_wakeup = FALSE)
SHOULD_NOT_SLEEP(TRUE)
if(is_psi_blocked(src)) // Can't enter the dream if the caster is blocked from RECEIVING. It's a two-way street.
+2 -2
View File
@@ -193,5 +193,5 @@
var/list/in_progress = list()
/datum/surgery_status/Destroy(force)
in_progress = null
. = ..()
in_progress?.Cut()
return ..()
-7
View File
@@ -129,13 +129,6 @@
*/
/datum/var/list/tgui_shared_states
/**
* global
*
* Tracks open UIs for a user.
*/
/mob/var/list/tgui_open_uis = list()
/**
* global
*
@@ -0,0 +1,12 @@
author: Hellfirejag
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
delete-after: True
# Any changes you've made. See valid prefix list above.
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
# SCREW THIS UP AND IT WON'T WORK.
# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit.
# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog.
changes:
- bugfix: "Comprehensively destroyed an extremely large number of niche hard dels across the entire Atom-Human Hierarchy."