Updated SSgarbage (#18173)

* pain

* sadfas

* sdfa

* sdfasf

* sfa

* sdf

* might the lord have mercy on our soul

* i cri everidai

* adeste fideles

* sdf

* where will this lead, what's coming next, from your inventions

* dear lord

* gjvhk

* i cri everidai

* fsgf

* sdfa

* sdaf

* hiuhi
This commit is contained in:
Fluffy
2024-01-15 14:08:27 +00:00
committed by GitHub
parent 0c8bdbdd68
commit ca6b04e1d7
125 changed files with 1574 additions and 805 deletions
+3
View File
@@ -218,6 +218,7 @@ var/list/admin_verbs_debug = list(
/client/proc/lighting_show_verbs,
/client/proc/restart_controller,
/client/proc/cmd_display_del_log,
/client/proc/cmd_display_harddel_log,
/client/proc/cmd_display_init_log,
/client/proc/cmd_ss_panic,
/client/proc/reset_openturf,
@@ -388,6 +389,7 @@ var/list/admin_verbs_hideable = list(
/client/proc/kill_air,
/client/proc/kill_airgroup,
/client/proc/cmd_display_del_log,
/client/proc/cmd_display_harddel_log,
/datum/admins/proc/ccannoucment,
/client/proc/cmd_display_init_log,
/client/proc/getruntimelog,
@@ -476,6 +478,7 @@ var/list/admin_verbs_dev = list( //will need to be altered - Ryan784
/client/proc/cmd_dev_bst,
/client/proc/lighting_show_verbs,
/client/proc/cmd_display_del_log,
/client/proc/cmd_display_harddel_log,
/client/proc/cmd_display_init_log,
/client/proc/create_poll, //Allows to create polls
/client/proc/profiler_start,
+70 -11
View File
@@ -421,21 +421,80 @@
/client/proc/cmd_display_del_log()
set category = "Debug"
set name = "Display del() Log"
set desc = "Displays a list of things that have failed to GC this round"
set desc = "Display del's log of everything that's passed through it."
var/dat = "<B>List of things that failed to GC this round</B><BR><BR>"
for(var/path in SSgarbage.didntgc)
dat += "[path] - [SSgarbage.didntgc[path]] times<BR>"
var/list/dellog = list("<B>List of things that have gone through qdel this round</B><BR><BR><ol>")
sortTim(SSgarbage.items, cmp=/proc/cmp_qdel_item_time, associative = TRUE)
for(var/path in SSgarbage.items)
var/datum/qdel_item/I = SSgarbage.items[path]
dellog += "<li><u>[path]</u><ul>"
if (I.qdel_flags & QDEL_ITEM_SUSPENDED_FOR_LAG)
dellog += "<li>SUSPENDED FOR LAG</li>"
if (I.failures)
dellog += "<li>Failures: [I.failures]</li>"
dellog += "<li>qdel() Count: [I.qdels]</li>"
dellog += "<li>Destroy() Cost: [I.destroy_time]ms</li>"
if (I.hard_deletes)
dellog += "<li>Total Hard Deletes [I.hard_deletes]</li>"
dellog += "<li>Time Spent Hard Deleting: [I.hard_delete_time]ms</li>"
dellog += "<li>Highest Time Spent Hard Deleting: [I.hard_delete_max]ms</li>"
if (I.hard_deletes_over_threshold)
dellog += "<li>Hard Deletes Over Threshold: [I.hard_deletes_over_threshold]</li>"
if (I.slept_destroy)
dellog += "<li>Sleeps: [I.slept_destroy]</li>"
if (I.no_respect_force)
dellog += "<li>Ignored force: [I.no_respect_force]</li>"
if (I.no_hint)
dellog += "<li>No hint: [I.no_hint]</li>"
if(LAZYLEN(I.extra_details))
var/details = I.extra_details.Join("</li><li>")
dellog += "<li>Extra Info: <ul><li>[details]</li></ul>"
dellog += "</ul></li>"
dat += "<B>List of paths that did not return a qdel hint in Destroy()</B><BR><BR>"
for(var/path in SSgarbage.noqdelhint)
dat += "[path]<BR>"
dellog += "</ol>"
dat += "<B>List of paths that slept in Destroy()</B><BR><BR>"
for(var/path in SSgarbage.sleptDestroy)
dat += "[path]<BR>"
usr << browse(dellog.Join(), "window=dellog")
usr << browse(dat, "window=dellog")
/**
* Same as `cmd_display_del_log`, but only shows harddels
*/
/client/proc/cmd_display_harddel_log()
set category = "Debug"
set name = "Display harddel() Log"
set desc = "Display harddel's log."
var/list/dellog = list("<B>List of things that have harddel'd this round</B><BR><BR><ol>")
sortTim(SSgarbage.items, cmp=/proc/cmp_qdel_item_time, associative = TRUE)
for(var/path in SSgarbage.items)
var/datum/qdel_item/I = SSgarbage.items[path]
if(I.hard_deletes)
dellog += "<li><u>[path]</u><ul>"
if (I.qdel_flags & QDEL_ITEM_SUSPENDED_FOR_LAG)
dellog += "<li>SUSPENDED FOR LAG</li>"
if (I.failures)
dellog += "<li>Failures: [I.failures]</li>"
dellog += "<li>qdel() Count: [I.qdels]</li>"
dellog += "<li>Destroy() Cost: [I.destroy_time]ms</li>"
if (I.hard_deletes)
dellog += "<li>Total Hard Deletes [I.hard_deletes]</li>"
dellog += "<li>Time Spent Hard Deleting: [I.hard_delete_time]ms</li>"
dellog += "<li>Highest Time Spent Hard Deleting: [I.hard_delete_max]ms</li>"
if (I.hard_deletes_over_threshold)
dellog += "<li>Hard Deletes Over Threshold: [I.hard_deletes_over_threshold]</li>"
if (I.slept_destroy)
dellog += "<li>Sleeps: [I.slept_destroy]</li>"
if (I.no_respect_force)
dellog += "<li>Ignored force: [I.no_respect_force]</li>"
if (I.no_hint)
dellog += "<li>No hint: [I.no_hint]</li>"
if(LAZYLEN(I.extra_details))
var/details = I.extra_details.Join("</li><li>")
dellog += "<li>Extra Info: <ul><li>[details]</li></ul>"
dellog += "</ul></li>"
dellog += "</ol>"
usr << browse(dellog.Join(), "window=harddellog")
/client/proc/cmd_display_init_log()
set category = "Debug"
@@ -0,0 +1,170 @@
#ifdef REFERENCE_TRACKING
/datum/proc/find_references(skip_alert)
running_find_references = type
if(usr?.client)
if(usr.client.running_find_references)
log_subsystem_garbage_harddel("CANCELLED search for references to a [usr.client.running_find_references].")
usr.client.running_find_references = null
running_find_references = null
//restart the garbage collector
SSgarbage.can_fire = TRUE
SSgarbage.update_nextfire(reset_time = TRUE)
return
if(!skip_alert && tgui_alert(usr,"Running this will lock everything up for about 5 minutes. Would you like to begin the search?", "Find References", list("Yes", "No")) != "Yes")
running_find_references = null
return
//this keeps the garbage collector from failing to collect objects being searched for in here
SSgarbage.can_fire = FALSE
if(usr?.client)
usr.client.running_find_references = type
log_subsystem_garbage_harddel("Beginning search for references to a [type].")
var/starting_time = world.time
log_subsystem_garbage_harddel("Refcount for [type]: [refcount(src)]")
//Time to search the whole game for our ref
DoSearchVar(GLOB, "GLOB", search_time = starting_time) //globals
log_subsystem_garbage_harddel("Finished searching globals")
//Yes we do actually need to do this. The searcher refuses to read weird lists
//And global.vars is a really weird list
var/global_vars = list()
for(var/key in global.vars)
global_vars[key] = global.vars[key]
DoSearchVar(global_vars, "Native Global", search_time = starting_time)
log_subsystem_garbage_harddel("Finished searching native globals")
for(var/datum/thing in world) //atoms (don't beleive its lies)
DoSearchVar(thing, "World -> [thing.type]", search_time = starting_time)
log_subsystem_garbage_harddel("Finished searching atoms")
for(var/datum/thing) //datums
DoSearchVar(thing, "Datums -> [thing.type]", search_time = starting_time)
log_subsystem_garbage_harddel("Finished searching datums")
//Warning, attempting to search clients like this will cause crashes if done on live. Watch yourself
#ifndef REFERENCE_DOING_IT_LIVE
for(var/client/thing) //clients
DoSearchVar(thing, "Clients -> [thing.type]", search_time = starting_time)
log_subsystem_garbage_harddel("Finished searching clients")
#endif
log_subsystem_garbage_harddel("Completed search for references to a [type].")
if(usr?.client)
usr.client.running_find_references = null
running_find_references = null
//restart the garbage collector
SSgarbage.can_fire = TRUE
SSgarbage.update_nextfire(reset_time = TRUE)
/datum/proc/DoSearchVar(potential_container, container_name, recursive_limit = 64, search_time = world.time)
#ifdef REFERENCE_TRACKING_DEBUG
if(SSgarbage.should_save_refs && !found_refs)
found_refs = list()
#endif
if(usr?.client && !usr.client.running_find_references)
return
if(!recursive_limit)
log_subsystem_garbage_harddel("Recursion limit reached. [container_name]")
return
//Check each time you go down a layer. This makes it a bit slow, but it won't effect the rest of the game at all
#ifndef FIND_REF_NO_CHECK_TICK
CHECK_TICK
#endif
if(isdatum(potential_container))
var/datum/datum_container = potential_container
if(datum_container.last_find_references == search_time)
return
datum_container.last_find_references = search_time
var/container_print = datum_container.ref_search_details()
var/list/vars_list = datum_container.vars
for(var/varname in vars_list)
#ifndef FIND_REF_NO_CHECK_TICK
CHECK_TICK
#endif
if (varname == "vars" || varname == "vis_locs") //Fun fact, vis_locs don't count for references
continue
var/variable = vars_list[varname]
if(variable == src)
#ifdef REFERENCE_TRACKING_DEBUG
if(SSgarbage.should_save_refs)
found_refs[varname] = TRUE
continue //End early, don't want these logging
#endif
log_subsystem_garbage_harddel("Found [type] [text_ref(src)] in [datum_container.type]'s [container_print] [varname] var. [container_name]")
continue
if(islist(variable))
DoSearchVar(variable, "[container_name] [container_print] -> [varname] (list)", recursive_limit - 1, search_time)
else if(islist(potential_container))
var/normal = IS_NORMAL_LIST(potential_container)
var/list/potential_cache = potential_container
for(var/element_in_list in potential_cache)
#ifndef FIND_REF_NO_CHECK_TICK
CHECK_TICK
#endif
//Check normal entrys
if(element_in_list == src)
#ifdef REFERENCE_TRACKING_DEBUG
if(SSgarbage.should_save_refs)
found_refs[potential_cache] = TRUE
continue //End early, don't want these logging
#endif
log_subsystem_garbage_harddel("Found [type] [text_ref(src)] in list [container_name].")
continue
var/assoc_val = null
if(!isnum(element_in_list) && normal)
assoc_val = potential_cache[element_in_list]
//Check assoc entrys
if(assoc_val == src)
#ifdef REFERENCE_TRACKING_DEBUG
if(SSgarbage.should_save_refs)
found_refs[potential_cache] = TRUE
continue //End early, don't want these logging
#endif
log_subsystem_garbage_harddel("Found [type] [text_ref(src)] in list [container_name]\[[element_in_list]\]")
continue
//We need to run both of these checks, since our object could be hiding in either of them
//Check normal sublists
if(islist(element_in_list))
DoSearchVar(element_in_list, "[container_name] -> [element_in_list] (list)", recursive_limit - 1, search_time)
//Check assoc sublists
if(islist(assoc_val))
DoSearchVar(potential_container[element_in_list], "[container_name]\[[element_in_list]\] -> [assoc_val] (list)", recursive_limit - 1, search_time)
/proc/qdel_and_find_ref_if_fail(datum/thing_to_del, force = FALSE)
thing_to_del.qdel_and_find_ref_if_fail(force)
/datum/proc/qdel_and_find_ref_if_fail(force = FALSE)
SSgarbage.reference_find_on_fail[text_ref(src)] = TRUE
qdel(src, force)
#endif
// Kept outside the ifdef so overrides are easy to implement
/// Return info about us for reference searching purposes
/// Will be logged as a representation of this datum if it's a part of a search chain
/datum/proc/ref_search_details()
return text_ref(src)
/datum/callback/ref_search_details()
return "[text_ref(src)] (obj: [object] proc: [delegate] args: [json_encode(arguments)]" // Used to include `user: [user?.resolve() || "null"])` but dreamchecker no happy with non static ref
+9
View File
@@ -33,6 +33,15 @@
*/
var/wires = WIRE_RECEIVE_ASSEMBLY | WIRE_PULSE_ASSEMBLY
/obj/item/device/assembly/Destroy()
STOP_PROCESSING(SSprocessing, src)
holder = null
cut_overlays()
attached_overlays = null
. = ..()
/obj/item/device/assembly/proc/holder_movement()
return
+5 -2
View File
@@ -64,8 +64,11 @@
/obj/item/device/onetankbomb/receive_signal() //This is mainly called by the sensor through sense() to the holder, and from the holder to here.
visible_message("[icon2html(src, viewers(get_turf(src)))] *beep* *beep*", "*beep* *beep*")
sleep(10)
if(!src)
addtimer(CALLBACK(src, PROC_REF(delayed_explosion)), 10 SECONDS)
/obj/item/device/onetankbomb/proc/delayed_explosion()
if(QDELETED(src))
return
if(status)
bombtank.ignite() //if its not a dud, boom (or not boom if you made shitty mix) the ignite proc is below, in this file
+13 -11
View File
@@ -15,6 +15,19 @@
var/obj/item/device/assembly/a_right = null
var/obj/special_assembly = null
/obj/item/device/assembly_holder/Initialize(mapload, ...)
. = ..()
become_hearing_sensitive()
/obj/item/device/assembly_holder/Destroy()
lose_hearing_sensitivity()
QDEL_NULL(a_left)
QDEL_NULL(a_right)
QDEL_NULL(special_assembly)
. = ..()
/obj/item/device/assembly_holder/proc/detached()
if(a_left)
a_left.holder_movement()
@@ -174,17 +187,6 @@
master.receive_signal()
return TRUE
/obj/item/device/assembly_holder/Initialize(mapload, ...)
. = ..()
become_hearing_sensitive()
/obj/item/device/assembly_holder/Destroy()
if(a_left)
a_left.holder = null
if(a_right)
a_right.holder = null
return ..()
/obj/item/device/assembly_holder/hear_talk(mob/living/M, msg, verb, datum/language/speaking)
if(a_right)
a_right.hear_talk(M, msg, verb, speaking)
@@ -218,7 +218,8 @@
qdel(P.network)
P.node = null
return ..()
. = ..()
GC_TEMPORARY_HARDDEL
/obj/machinery/atmospherics/omni/atmos_init()
for(var/datum/omni_port/P in ports)
+1 -1
View File
@@ -14,7 +14,7 @@
var/list/contained_packages
/obj/item/cargo_backpack/Destroy()
QDEL_NULL_LIST(contained_packages)
QDEL_LIST(contained_packages)
return ..()
/obj/item/cargo_backpack/examine(mob/user, distance)
+1 -1
View File
@@ -211,7 +211,7 @@ var/list/preferences_datums = list()
/datum/preferences/Destroy()
. = ..()
QDEL_NULL_LIST(char_render_holders)
QDEL_LIST(char_render_holders)
/datum/preferences/proc/load_and_update_character(var/slot)
load_character(slot)
+1 -1
View File
@@ -50,7 +50,7 @@
/obj/item/clothing/Destroy()
STOP_PROCESSING(SSprocessing, src)
QDEL_NULL_LIST(accessories)
QDEL_LIST(accessories)
return ..()
//Updates the icons of the mob wearing the clothing item, if any.
@@ -19,6 +19,11 @@
pockets.max_w_class = storage_max_w_class
pockets.max_storage_space = storage_max_storage_space
/obj/item/rig_module/storage/Destroy()
QDEL_NULL(pockets)
. = ..()
/obj/item/rig/attack_hand(mob/user as mob)
var/obj/item/rig_module/storage/storage = locate() in installed_modules
@@ -30,6 +30,13 @@
var/device_type
var/obj/item/device
/obj/item/rig_module/device/Destroy()
if(!ispath(src.device))
QDEL_NULL(src.device)
src.device = null
. = ..()
/obj/item/rig_module/device/healthscanner
name = "health scanner module"
desc = "A hardsuit-mounted health scanner."
@@ -383,11 +390,17 @@
category = MODULE_SPECIAL
/obj/item/rig_module/voice/New()
..()
/obj/item/rig_module/voice/Initialize(mapload, ...)
. = ..()
voice_holder = new(src)
voice_holder.active = 0
/obj/item/rig_module/voice/Destroy()
QDEL_NULL(voice_holder)
. = ..()
/obj/item/rig_module/voice/installed()
..()
holder.speech = src
@@ -552,12 +565,19 @@
category = MODULE_GENERAL
/obj/item/rig_module/device/stamp/New()
..()
/obj/item/rig_module/device/stamp/Initialize()
. = ..()
iastamp = new /obj/item/stamp/internalaffairs(src)
deniedstamp = new /obj/item/stamp/denied(src)
device = iastamp
/obj/item/rig_module/device/stamp/Destroy()
QDEL_NULL(iastamp)
QDEL_NULL(deniedstamp)
. = ..()
/obj/item/rig_module/device/stamp/engage(atom/target, mob/user)
if(!..() || !device)
return FALSE
@@ -4,15 +4,37 @@
icon = 'icons/obj/rig_modules.dmi'
var/icon_base = null
w_class = ITEMSIZE_LARGE
var/obj/item/circuitboard/board_type = null
var/obj/item/circuitboard/target_board_type = null
var/obj/item/rig/rig_type = /obj/item/rig
///The type of board, a path of `/obj/item/circuitboard`
var/board_type = null
///The type of target board, a path of `/obj/item/circuitboard`
var/target_board_type = null
///The type of rig, a path of `/obj/item/rig`
var/rig_type = /obj/item/rig
obj_flags = OBJ_FLAG_CONDUCTABLE
origin_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3, TECH_MAGNET = 4, TECH_POWER = 4)
var/datum/construction/reversible/rig_assembly/construct
obj_flags = OBJ_FLAG_CONDUCTABLE
/obj/item/rig_assembly/Initialize(mapload, ...)
. = ..()
construct = new /datum/construction/reversible/rig_assembly/civilian(src)
construct.board_type = board_type
construct.steps[5]["key"] = board_type // defining board in construction step
construct.result = "[rig_type]"
/obj/item/rig_assembly/Destroy()
QDEL_NULL(construct)
. = ..()
/obj/item/rig_assembly/examine(mob/user, distance)
. = ..()
if(construct)
@@ -35,15 +57,10 @@
..()
return
/obj/item/rig_assembly/New()
..()
construct = new /datum/construction/reversible/rig_assembly/civilian(src)
construct.board_type = board_type
construct.steps[5]["key"] = board_type // defining board in construction step
construct.result = "[rig_type]"
/obj/item/rig_assembly/combat/New()
..()
/obj/item/rig_assembly/combat/Initialize(mapload, ...)
. = ..()
construct = new /datum/construction/reversible/rig_assembly/combat(src)
construct.board_type = board_type
construct.target_board_type = target_board_type
@@ -166,8 +183,12 @@
/datum/construction/reversible/rig_assembly
result = null
var/obj/item/circuitboard/rig_assembly/board_type = null
var/obj/item/circuitboard/rig_assembly/target_board_type = null
///The type of board, a path of `/obj/item/circuitboard`
var/board_type = null
///The type of target board, a path of `/obj/item/circuitboard`
var/target_board_type = null
/datum/construction/reversible/rig_assembly/custom_action(index as num, diff as num, atom/used_atom, mob/user as mob)
var/obj/item/I = used_atom
+1 -1
View File
@@ -59,7 +59,7 @@
rebuild_overlay_lists(TRUE)
/obj/compass_holder/Destroy()
QDEL_NULL_LIST(compass_waypoints)
QDEL_LIST(compass_waypoints)
. = ..()
/obj/compass_holder/proc/get_heading()
@@ -122,7 +122,7 @@
//Deletes contents of container.
//Used when food is burned, before replacing it with a burned mess
/obj/item/reagent_containers/cooking_container/proc/clear()
QDEL_NULL_LIST(contents)
QDEL_LIST(contents)
reagents.clear_reagents()
/obj/item/reagent_containers/cooking_container/proc/label(var/number, var/CT = null)
@@ -183,4 +183,5 @@
/mob/living/carbon/human/Destroy()
ghost_spawner = null
return ..()
. = ..()
GC_TEMPORARY_HARDDEL
@@ -160,7 +160,7 @@
return 1
/mob/living/heavy_vehicle/proc/remove_system(var/system_hardpoint, var/mob/user, var/force)
/mob/living/heavy_vehicle/proc/remove_system_interact(var/system_hardpoint, var/mob/user, var/force)
if((hardpoints_locked && !force) || !hardpoints[system_hardpoint])
return 0
@@ -172,6 +172,19 @@
if(!do_after(user, delay, src) || hardpoints[system_hardpoint] != system)
return FALSE
remove_system(system_hardpoint, force)
if(user)
system.forceMove(get_turf(user))
user.put_in_hands(system)
to_chat(user, "<span class='notice'>You remove \the [system] in \the [src]'s [system_hardpoint].</span>")
playsound(user.loc, 'sound/items/Screwdriver.ogg', 100, 1)
/mob/living/heavy_vehicle/proc/remove_system(var/system_hardpoint, var/force)
if((hardpoints_locked && !force) || !hardpoints[system_hardpoint])
return 0
var/obj/item/system = hardpoints[system_hardpoint]
hardpoints[system_hardpoint] = null
if(system_hardpoint == selected_hardpoint)
@@ -197,10 +210,4 @@
refresh_hud()
queue_icon_update()
if(user)
system.forceMove(get_turf(user))
user.put_in_hands(system)
to_chat(user, "<span class='notice'>You remove \the [system] in \the [src]'s [system_hardpoint].</span>")
playsound(user.loc, 'sound/items/Screwdriver.ogg', 100, 1)
return system
@@ -386,7 +386,7 @@
var/to_remove = tgui_input_list(user, "Which component would you like to remove?", "Remove Component", parts)
if(remove_system(to_remove, user))
if(remove_system_interact(to_remove, user))
return
to_chat(user, "<span class='warning'>\The [src] has no hardpoint systems to remove.</span>")
return
+3 -2
View File
@@ -94,7 +94,8 @@
for(var/hardpoint in hardpoints)
var/obj/item/S = remove_system(hardpoint, force = 1)
qdel(S)
if(S)
QDEL_NULL(S)
hardpoints = null
@@ -106,7 +107,7 @@
pilot.forceMove(get_turf(src))
pilots = null
QDEL_NULL_LIST(hud_elements)
QDEL_LIST(hud_elements)
if(remote_network)
SSvirtualreality.remove_mech(src, remote_network)
@@ -184,7 +184,7 @@
return ..()
/obj/item/integrated_circuit/passive/power/powernet/Destroy()
qdel(IO)
QDEL_NULL(IO)
return ..()
/obj/item/integrated_circuit/passive/power/powernet/on_anchored()
@@ -292,6 +292,10 @@
default_type = MATERIAL_PLASTEEL
icon_has_variants = TRUE
/obj/item/stack/material/plasteel/Destroy()
. = ..()
GC_TEMPORARY_HARDDEL
/obj/item/stack/material/plasteel/full/Initialize()
. = ..()
amount = max_amount
@@ -20,6 +20,7 @@
if(on_open_network)
GLOB.cameranet.remove_source(src)
. = ..()
GC_TEMPORARY_HARDDEL
/obj/machinery/camera/proc/update_coverage(var/network_change = 0)
if(network_change)
+2
View File
@@ -45,6 +45,8 @@
//This is just a commonly used configuration for the equip_to_slot_if_possible() proc, used to equip people when the rounds tarts and when events happen and such.
/mob/proc/equip_to_slot_or_del(obj/item/W as obj, slot)
SHOULD_NOT_SLEEP(TRUE)
. = equip_to_slot_if_possible(W, slot, TRUE, TRUE, FALSE, TRUE)
// Convinience proc. Collects crap that fails to equip either onto the mob's back, or drops it.
-1
View File
@@ -43,7 +43,6 @@
if(pAI)
if(isturf(loc))
drop_from_inventory(pAI, get_turf(src))
pAI.throw_at_random(FALSE, 3, 1)
else
drop_from_inventory(pAI, loc)
pAI = null
+5
View File
@@ -62,7 +62,11 @@ var/list/cleanbot_types // Going to use this to generate a list of types once th
patrol_path = null
target = null
ignorelist = null
next_dest_loc = null
QDEL_NULL(listener)
SSradio.remove_object(listener, beacon_freq)
GLOB.janitorial_supplies -= src
return ..()
@@ -353,6 +357,7 @@ var/list/cleanbot_types // Going to use this to generate a list of types once th
/obj/cleanbot_listener/Destroy()
cleanbot = null
SSradio.remove_object_all(src)
return ..()
/* Assembly */
@@ -50,6 +50,37 @@
var/can_attach = TRUE // Whether they can attach to a host
/mob/living/carbon/alien/diona/Initialize(var/mapload, var/flower_chance = 5)
if(prob(flower_chance))
flower_color = get_random_colour(1)
. = ..(mapload)
//species = GLOB.all_species[]
ingested = new /datum/reagents/metabolism(500, src, CHEM_INGEST)
reagents = ingested
set_species(SPECIES_DIONA)
setup_dionastats()
eat_types |= TYPE_ORGANIC
nutrition = 0 //We dont start with biomass
update_verbs()
/mob/living/carbon/alien/diona/Destroy()
cleanupTransfer()
QDEL_NULL(ingested)
QDEL_NULL(vessel)
QDEL_NULL(DS)
gestalt = null
master_nymph = null
hat = null
flower_color = null
flower_image = null
cut_overlays()
. = ..()
GC_TEMPORARY_HARDDEL
/mob/living/carbon/alien/diona/get_ingested_reagents()
return ingested
@@ -92,20 +123,6 @@
else
..()
/mob/living/carbon/alien/diona/Initialize(var/mapload, var/flower_chance = 5)
if(prob(flower_chance))
flower_color = get_random_colour(1)
. = ..(mapload)
//species = GLOB.all_species[]
ingested = new /datum/reagents/metabolism(500, src, CHEM_INGEST)
reagents = ingested
set_species(SPECIES_DIONA)
setup_dionastats()
eat_types |= TYPE_ORGANIC
nutrition = 0 //We dont start with biomass
update_verbs()
/mob/living/carbon/alien/diona/verb/check_light()
set category = "Abilities"
set name = "Check light level"
@@ -321,14 +338,6 @@
return TRUE
/mob/living/carbon/alien/diona/Destroy()
walk_to(src, 0)
cleanupTransfer()
QDEL_NULL(ingested)
QDEL_NULL(vessel)
QDEL_NULL(DS)
. = ..()
/mob/living/carbon/alien/diona/proc/wear_hat(var/obj/item/new_hat)
if(hat)
return
@@ -21,7 +21,8 @@
death(1) //Brains can die again. AND THEY SHOULD AHA HA HA HA HA HA
ghostize() //Ghostize checks for key so nothing else is necessary.
container = null
return ..()
. = ..()
GC_TEMPORARY_HARDDEL
/mob/living/carbon/brain/IsAdvancedToolUser() // to be able to use weapons when piloting a hardsuit
return TRUE
@@ -9,8 +9,6 @@
for(var/obj/item/organ/external/E in src.organs)
E.droplimb(0,DROPLIMB_EDGE,1)
sleep(1)
for(var/obj/item/I in src)
drop_from_inventory(I)
I.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)), rand(1,3), round(30/I.w_class))
@@ -104,7 +104,7 @@
/mob/living/carbon/human/Destroy()
GLOB.human_mob_list -= src
GLOB.intent_listener -= src
QDEL_NULL_LIST(organs)
QDEL_LIST(organs)
internal_organs_by_name = null
internal_organs = null
organs_by_name = null
@@ -130,7 +130,8 @@
// Do this last so the mob's stuff doesn't drop on del.
QDEL_NULL(w_uniform)
return ..()
. = ..()
GC_TEMPORARY_HARDDEL
/mob/living/carbon/human/can_devour(atom/movable/victim, var/silent = FALSE)
if(!should_have_organ(BP_STOMACH))
@@ -801,7 +801,7 @@
A.ex_act(2)
sleep(1)
if (A && !(A.gcDestroyed) && A.type == oldtype)
if (A && !(A.gc_destroyed) && A.type == oldtype)
src.visible_message("<span class='danger'>[src.name] plows into \the [aname]!</span>")
return 0
@@ -52,7 +52,7 @@
friends = null
target_mob = null
targets = null
QDEL_NULL_ASSOC(target_type_validator_map)
QDEL_LIST_ASSOC_VAL(target_type_validator_map)
return ..()
/mob/living/simple_animal/hostile/can_name(var/mob/living/M)
@@ -187,6 +187,14 @@
if(dead_on_map)
death()
/mob/living/simple_animal/Destroy()
cut_overlay(blood_overlay)
movement_target = null
QDEL_NULL(udder)
. = ..()
GC_TEMPORARY_HARDDEL
/mob/living/simple_animal/Move(NewLoc, direct)
. = ..()
if(.)
@@ -112,7 +112,7 @@
for(var/datum/computer_file/program/P in hard_drive.stored_files)
P.event_unregistered()
QDEL_NULL_LIST(hard_drive.stored_files)
QDEL_LIST(hard_drive.stored_files)
for(var/obj/item/computer_hardware/CH in src.get_all_components())
uninstall_component(null, CH)
@@ -130,8 +130,8 @@
service.service_deactivate()
service.service_state = PROGRAM_STATE_KILLED
QDEL_NULL_LIST(idle_threads)
QDEL_NULL_LIST(enabled_services)
QDEL_LIST(idle_threads)
QDEL_LIST(enabled_services)
if(looping_sound)
soundloop.stop(src)
@@ -237,6 +237,17 @@
ui_interact(user) // Re-open the UI on this computer. It should show the main screen now.
update_icon()
/**
* Same as `kill_program()` but does not try to reopen the window, also makes the linter happy as it does not sleep
*/
/obj/item/modular_computer/proc/kill_program_shutdown(forced = FALSE)
SHOULD_NOT_SLEEP(TRUE)
if(active_program && active_program.kill_program(forced))
active_program = null
else
return FALSE
// Returns 0 for No Signal, 1 for Low Signal and 2 for Good Signal. 3 is for wired connection (always-on)
/obj/item/modular_computer/proc/get_ntnet_status(var/specific_action = 0)
if(network_card)
@@ -251,7 +262,7 @@
/obj/item/modular_computer/proc/shutdown_computer(var/loud = TRUE)
SStgui.close_uis(active_program)
kill_program(TRUE)
kill_program_shutdown(TRUE)
for(var/datum/computer_file/program/P in idle_threads)
P.kill_program(TRUE)
idle_threads.Remove(P)
@@ -19,6 +19,10 @@
. = ..()
set_icon()
/obj/item/modular_computer/handheld/Destroy()
. = ..()
GC_TEMPORARY_HARDDEL
/obj/item/modular_computer/handheld/proc/set_icon()
icon_state_unpowered = icon_state
icon_state_broken = icon_state
@@ -19,11 +19,16 @@
. = computer_host
/obj/item/modular_computer/silicon/Initialize(mapload)
. = ..()
if(istype(loc, /mob/living/silicon))
computer_host = loc
else
return INITIALIZE_HINT_QDEL
/obj/item/modular_computer/silicon/Destroy()
computer_host = null
. = ..()
GC_TEMPORARY_HARDDEL
/obj/item/modular_computer/silicon/computer_use_power(power_usage)
// If we have host like AI, borg or pAI we handle there power
@@ -38,10 +43,6 @@
// If we don't have host, then we let regular computer code handle power - like batteries and tesla coils.
return ..()
/obj/item/modular_computer/silicon/Destroy()
computer_host = null
return ..()
/obj/item/modular_computer/silicon/Click(location, control, params)
return attack_self(usr)
@@ -3,6 +3,10 @@
screen_on = FALSE
icon_state = "laptop-closed"
/obj/item/modular_computer/laptop/preset/Destroy()
. = ..()
GC_TEMPORARY_HARDDEL
/obj/item/modular_computer/laptop/preset/install_default_hardware()
..()
processor_unit = new /obj/item/computer_hardware/processor_unit(src)
@@ -1,3 +1,7 @@
/obj/item/modular_computer/telescreen/preset/Destroy()
. = ..()
GC_TEMPORARY_HARDDEL
/obj/item/modular_computer/telescreen/preset/install_default_hardware()
..()
processor_unit = new/obj/item/computer_hardware/processor_unit(src)
@@ -54,6 +54,7 @@
computer.enabled_services -= src
computer = null
. = ..()
GC_TEMPORARY_HARDDEL
/datum/computer_file/program/ui_host()
if(computer)
@@ -31,6 +31,16 @@
"medical" = list("A-", "B-", "AB-", "O-", "A+", "B+", "AB+", "O+")
)
/datum/computer_file/program/records/New()
. = ..()
listener = new(src)
/datum/computer_file/program/records/Destroy()
active = null
QDEL_NULL(listener)
active_virus = null
. = ..()
/datum/computer_file/program/records/medical
filename = "medrec"
filedesc = "Medical Records"
@@ -82,22 +92,16 @@
program_key_icon_state = "lightblue_key"
color = LIGHT_COLOR_BLUE
/datum/computer_file/program/records/employment/Destroy()
. = ..()
/datum/computer_file/program/records/pai
available_on_ntnet = 1
extended_desc = "This program is used to view crew records."
usage_flags = PROGRAM_SILICON_PAI
edit_type = 0
/datum/computer_file/program/records/New()
. = ..()
listener = new(src)
/datum/computer_file/program/records/Destroy()
active = null
QDEL_NULL(listener)
active_virus = null
. = ..()
/datum/computer_file/program/records/ui_data(mob/user)
var/list/data = list(
"activeview" = "list",
@@ -156,7 +156,7 @@
/obj/item/computer_hardware/hard_drive/Destroy()
if(parent_computer?.hard_drive == src)
parent_computer.hard_drive = null
QDEL_NULL_LIST(stored_files)
QDEL_LIST(stored_files)
return ..()
/obj/item/computer_hardware/hard_drive/Initialize(mapload)
@@ -2,6 +2,10 @@
. = ..()
add_programs()
/obj/item/computer_hardware/hard_drive/portable/super/preset/all/Destroy()
. = ..()
GC_TEMPORARY_HARDDEL
/obj/item/computer_hardware/hard_drive/portable/super/preset/all/proc/add_programs()
for(var/F in typesof(/datum/computer_file/program))
var/datum/computer_file/program/prog = new F("Compless")
+4 -4
View File
@@ -197,10 +197,10 @@
cached_markings = null
mob_icon = null
QDEL_NULL_LIST(children)
QDEL_NULL_LIST(internal_organs)
QDEL_NULL_LIST(wounds)
QDEL_NULL_LIST(implants)
QDEL_LIST(children)
QDEL_LIST(internal_organs)
QDEL_LIST(wounds)
QDEL_LIST(implants)
infect_target_internal = null
infect_target_external = null
+1 -1
View File
@@ -109,5 +109,5 @@
marker = null
radar = null
QDEL_NULL_LIST(images)
QDEL_LIST(images)
. = ..()
@@ -49,6 +49,7 @@
destroy_dummies()
ammunition.Cut()
barrel = null
LAZYREMOVE(linked?.ship_weapons, src)
return ..()
/obj/machinery/ship_weapon/ex_act(severity)
@@ -288,6 +288,27 @@
..()
return INITIALIZE_HINT_LATELOAD
/obj/machinery/leviathan_safeguard/LateInitialize()
if(current_map.use_overmap && !linked)
var/my_sector = GLOB.map_sectors["[z]"]
if (istype(my_sector, /obj/effect/overmap/visitable))
attempt_hook_up(my_sector)
if(linked)
ASSERT(isnull(linked.levi_safeguard)) //There should only ever be one
linked.levi_safeguard = src
for(var/obj/machinery/leviathan_button/LB in range(3, src))
if(istype(LB))
button = LB
/obj/machinery/leviathan_safeguard/Destroy()
if(linked)
linked.levi_safeguard = null
QDEL_NULL(key)
button = null
. = ..()
/obj/machinery/leviathan_safeguard/ex_act(severity)
return
@@ -296,22 +317,6 @@
return
/obj/machinery/leviathan_safeguard/Destroy()
QDEL_NULL(key)
button = null
return ..()
/obj/machinery/leviathan_safeguard/LateInitialize()
if(current_map.use_overmap && !linked)
var/my_sector = GLOB.map_sectors["[z]"]
if (istype(my_sector, /obj/effect/overmap/visitable))
attempt_hook_up(my_sector)
if(linked)
linked.levi_safeguard = src
for(var/obj/machinery/leviathan_button/LB in range(3, src))
if(istype(LB))
button = LB
/obj/machinery/leviathan_safeguard/proc/open()
opened = TRUE
flick("safeguard_opening", src)
+6
View File
@@ -40,6 +40,12 @@ var/list/admin_departments
alldepartments |= department
destination = current_map.boss_name
/obj/machinery/photocopier/faxmachine/Destroy()
allfaxes -= src
QDEL_NULL(identification)
. = ..()
/obj/machinery/photocopier/faxmachine/ui_data(mob/user)
var/list/data = list()
data["destination"] = destination
+1 -1
View File
@@ -574,7 +574,7 @@
/obj/effect/fusion_em_field/Destroy()
set_light(0)
RadiateAll()
QDEL_NULL_LIST(particle_catchers)
QDEL_LIST(particle_catchers)
QDEL_NULL(radio)
if(owned_core)
owned_core.owned_field = null
+1 -1
View File
@@ -133,7 +133,7 @@
update_icon()
/obj/item/ammo_magazine/Destroy()
QDEL_NULL_LIST(stored_ammo)
QDEL_LIST(stored_ammo)
. = ..()
/obj/item/ammo_magazine/attackby(obj/item/W as obj, mob/user as mob)
+1 -1
View File
@@ -51,7 +51,7 @@
/obj/item/gun/projectile/Destroy()
chambered = null
QDEL_NULL(ammo_magazine)
QDEL_NULL_LIST(loaded)
QDEL_LIST(loaded)
. = ..()
/obj/item/gun/projectile/update_icon()
@@ -371,6 +371,11 @@
. = ..()
launcher = new(src)
/obj/item/gun/projectile/automatic/rifle/z8/Destroy()
QDEL_NULL(launcher)
. = ..()
/obj/item/gun/projectile/automatic/rifle/z8/attackby(obj/item/I, mob/user)
if((istype(I, /obj/item/grenade)))
launcher.load(I, user)
@@ -191,6 +191,12 @@
for(var/i in 1 to secondary_max_shells)
secondary_loaded += new secondary_ammo_type(src)
/obj/item/gun/projectile/revolver/lemat/Destroy()
QDEL_LIST(secondary_loaded)
QDEL_LIST(tertiary_loaded)
. = ..()
/obj/item/gun/projectile/revolver/lemat/unique_action(mob/living/user)
to_chat(user, "<span class='notice'>You change the firing mode on \the [src].</span>")
if(!flipped_firing)
@@ -45,7 +45,7 @@
qdel(aiming)
aiming = null
QDEL_NULL_LIST(aimed_at_by)
QDEL_LIST(aimed_at_by)
if(vr_mob)
vr_mob = null
@@ -66,7 +66,7 @@
w_class = n_ceil(Clamp((ingredients.len/2),2,4))
/obj/item/reagent_containers/food/snacks/csandwich/Destroy()
QDEL_NULL_LIST(ingredients)
QDEL_LIST(ingredients)
return ..()
/obj/item/reagent_containers/food/snacks/csandwich/examine(mob/user)
@@ -52,6 +52,12 @@
if(prob(75))
my_effect.trigger = rand(1,4)
/obj/machinery/artifact/Destroy()
QDEL_NULL(my_effect)
QDEL_NULL(secondary_effect)
. = ..()
/obj/machinery/artifact/process()
var/turf/L = loc
@@ -45,6 +45,11 @@
chargelevelmax = rand(20, 60)
effectrange = rand(15, 20)
/datum/artifact_effect/Destroy(force)
holder = null
. = ..()
/datum/artifact_effect/proc/ToggleActivate(var/reveal_toggle = 1)
//so that other stuff happens first
spawn(0)
+2 -1
View File
@@ -11,7 +11,8 @@ var/list/dream_entries = list()
srom_pulled_by = null
srom_pulling = null
bg = null //Just to be sure.
return ..()
. = ..()
GC_TEMPORARY_HARDDEL
/mob/living/carbon/human/proc/handle_shared_dreaming(var/force_wakeup = FALSE)
// If they're an Unconsious person with the abillity to do Skrellepathy.
+1 -1
View File
@@ -87,7 +87,7 @@
landing_indicators += new /obj/effect/shuttle_warning(target_turf)
/obj/effect/shuttle_landmark/proc/clear_landing_indicators()
QDEL_NULL_LIST(landing_indicators) // lazyclear but we delete the effects as well
QDEL_LIST(landing_indicators) // lazyclear but we delete the effects as well
/obj/effect/shuttle_landmark/proc/cannot_depart(datum/shuttle/shuttle)
return FALSE
+4
View File
@@ -182,3 +182,7 @@
var/head_reattach = 0
var/current_organ = "organ"
var/list/in_progress = list()
/datum/surgery_status/Destroy(force)
in_progress = null
. = ..()
@@ -46,7 +46,7 @@
/datum/musical_event_manager/Destroy(force)
. = ..()
deactivate()
QDEL_NULL_LIST(events)
QDEL_LIST(events)
/datum/musical_event_manager/proc/push_event(datum/sound_player/source, datum/sound_token/token, time, volume)
if (istype(source) && istype(token) && volume >= 0 && volume <= 100)