diff --git a/code/datums/components/material_container.dm b/code/datums/components/material_container.dm
index f4b8e84204f..2ea582aab62 100644
--- a/code/datums/components/material_container.dm
+++ b/code/datums/components/material_container.dm
@@ -49,6 +49,10 @@
var/mat_path = possible_mats[id]
materials[id] = new mat_path()
+/datum/component/material_container/Destroy(force, silent)
+ QDEL_LIST_ASSOC_VAL(materials)
+ return ..()
+
/datum/component/material_container/proc/OnExamine(datum/source, mob/user, list/examine_list)
if(show_on_examine)
for(var/I in materials)
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index e8d5cfcf437..79785006452 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -100,6 +100,7 @@ GLOBAL_LIST_INIT(cloner_biomass_items, list(\
/obj/machinery/clonepod/Destroy()
if(connected)
connected.pods -= src
+ connected = null
if(clonemind)
UnregisterSignal(clonemind.current, COMSIG_LIVING_REVIVE)
UnregisterSignal(clonemind, COMSIG_MIND_TRANSER_TO)
diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm
index a7345522b25..10e36785369 100644
--- a/code/game/machinery/computer/message.dm
+++ b/code/game/machinery/computer/message.dm
@@ -34,6 +34,24 @@
light_color = LIGHT_COLOR_DARKGREEN
+/obj/machinery/computer/message_monitor/Initialize()
+ ..()
+ return INITIALIZE_HINT_LATELOAD // Give the message server time to initialize
+
+/obj/machinery/computer/message_monitor/LateInitialize()
+ //If the monitor isn't linked to a server, and there's a server available, default it to the first one in the list.
+ if(!linkedServer && length(GLOB.message_servers))
+ linkedServer = GLOB.message_servers[1]
+ RegisterSignal(linkedServer, COMSIG_PARENT_QDELETING, .proc/unlink_server)
+
+/obj/machinery/computer/message_monitor/proc/unlink_server()
+ SIGNAL_HANDLER
+ linkedServer = null
+
+/obj/machinery/computer/message_monitor/Destroy()
+ customrecepient = null
+ linkedServer = null
+ return ..()
/obj/machinery/computer/message_monitor/screwdriver_act(mob/user, obj/item/I)
if(emag) //Stops people from just unscrewing the monitor and putting it back to get the console working again.
@@ -71,14 +89,6 @@
..()
-/obj/machinery/computer/message_monitor/Initialize()
- ..()
- //Is the server isn't linked to a server, and there's a server available, default it to the first one in the list.
- if(!linkedServer)
- if(GLOB.message_servers && GLOB.message_servers.len > 0)
- linkedServer = GLOB.message_servers[1]
- return
-
/obj/machinery/computer/message_monitor/attack_hand(mob/user as mob)
if(..())
return
diff --git a/code/modules/arcade/mob_hunt/mob_avatar.dm b/code/modules/arcade/mob_hunt/mob_avatar.dm
index 7f7f53d3199..19f792af763 100644
--- a/code/modules/arcade/mob_hunt/mob_avatar.dm
+++ b/code/modules/arcade/mob_hunt/mob_avatar.dm
@@ -1,4 +1,3 @@
-
/obj/effect/nanomob
name = "Nano-Mob Avatar" //will be overridden by the mob datum name value when created
desc = "A wild Nano-Mob appeared! Hit it with your PDA with the game open to attempt to capture it!"
@@ -12,17 +11,29 @@
var/list/clients_encountered = list() //tracks who has already interacted with us, so they can't attempt a second capture
var/image/avatar
-/obj/effect/nanomob/New(loc, datum/mob_hunt/new_info)
- ..()
+/obj/effect/nanomob/Initialize(mapload, datum/mob_hunt/new_info)
+ . = ..()
if(!new_info)
- qdel(src)
- return
+ return INITIALIZE_HINT_QDEL
mob_info = new_info
+ RegisterSignal(mob_info, COMSIG_PARENT_QDELETING, .proc/delete_wrapper)
update_self()
forceMove(mob_info.spawn_point)
if(!mob_info.is_trap)
addtimer(CALLBACK(src, .proc/despawn), mob_info.lifetime)
+/obj/effect/nanomob/Destroy()
+ SSmob_hunt.trap_spawns -= src
+ SSmob_hunt.normal_spawns -= src
+ mob_info = null // Can't delete this since multiple players can get the exact same /datum/mob_hunt. (This should be refactored)
+ clients_encountered.Cut()
+ QDEL_NULL(avatar)
+ return ..()
+
+/obj/effect/nanomob/proc/delete_wrapper()
+ SIGNAL_HANDLER
+ qdel(src)
+
/obj/effect/nanomob/proc/update_self()
if(!mob_info)
return
@@ -132,12 +143,6 @@
icon_state = "placeholder"
var/obj/machinery/computer/mob_battle_terminal/my_terminal
-/obj/effect/nanomob/battle/New(loc, datum/mob_hunt/new_info)
- . = ..()
- if(new_info)
- mob_info = new_info
- update_self()
-
/obj/effect/nanomob/battle/update_self()
if(!mob_info)
name = "Nano-Mob Battle Avatar"
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 6c646d2509e..5d20cb66209 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -212,6 +212,20 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
GLOB.shuttle_caller_list += src
..()
+/mob/living/silicon/ai/Destroy()
+ GLOB.ai_list -= src
+ GLOB.shuttle_caller_list -= src
+ SSshuttle.autoEvac()
+ if(malfhacking)
+ deltimer(malfhacking)
+ malfhacking = null
+ QDEL_NULL(eyeobj) // No AI, no Eye
+ QDEL_NULL(aiPDA)
+ QDEL_NULL(aiMulti)
+ QDEL_NULL(aiRadio)
+ QDEL_NULL(builtInCamera)
+ return ..()
+
/mob/living/silicon/ai/proc/on_mob_init()
to_chat(src, "You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras).")
to_chat(src, "To look at other parts of the station, click on yourself to get a camera menu.")
@@ -314,17 +328,6 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
return TRUE
-/mob/living/silicon/ai/Destroy()
- GLOB.ai_list -= src
- GLOB.shuttle_caller_list -= src
- SSshuttle.autoEvac()
- QDEL_NULL(eyeobj) // No AI, no Eye
- if(malfhacking)
- deltimer(malfhacking)
- malfhacking = null
- malfhack = null
- return ..()
-
/*
The AI Power supply is a dummy object used for powering the AI since only machinery should be using power.
diff --git a/code/modules/mob/living/simple_animal/hostile/bat.dm b/code/modules/mob/living/simple_animal/hostile/bat.dm
index 1cc904f1017..9e5ae1e2ec1 100644
--- a/code/modules/mob/living/simple_animal/hostile/bat.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bat.dm
@@ -33,27 +33,16 @@
// break_stuff_probability = 2
faction = list("scarybat")
- var/mob/living/owner
gold_core_spawnable = HOSTILE_SPAWN
-/mob/living/simple_animal/hostile/scarybat/New(loc, mob/living/L as mob)
- ..()
+/mob/living/simple_animal/hostile/scarybat/Initialize(mapload, mob/living/L)
+ . = ..()
if(istype(L))
- owner = L
+ faction += "\ref[L]"
/mob/living/simple_animal/hostile/scarybat/Process_Spacemove(check_drift = 0)
return ..() //No drifting in space for space carp! //original comments do not steal
-/mob/living/simple_animal/hostile/scarybat/Found(atom/A)//This is here as a potential override to pick a specific target if available
- if(istype(A) && A == owner)
- return 0
- return ..()
-
-/mob/living/simple_animal/hostile/scarybat/CanAttack(atom/the_target)//This is here as a potential override to pick a specific target if available
- if(istype(the_target) && the_target == owner)
- return 0
- return ..()
-
/mob/living/simple_animal/hostile/scarybat/AttackingTarget()
. =..()
var/mob/living/L = .
diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm
index 76a5dd4dc03..a3a4d0c58c4 100644
--- a/code/modules/paperwork/faxmachine.dm
+++ b/code/modules/paperwork/faxmachine.dm
@@ -40,11 +40,15 @@ GLOBAL_LIST_EMPTY(fax_blacklist)
/// Target department to send outgoing faxes to
var/destination
-/obj/machinery/photocopier/faxmachine/New()
- ..()
+/obj/machinery/photocopier/faxmachine/Initialize(mapload)
+ . = ..()
GLOB.allfaxes += src
update_network()
+/obj/machinery/photocopier/faxmachine/Destroy()
+ GLOB.allfaxes -= src
+ return ..()
+
/obj/machinery/photocopier/faxmachine/proc/update_network()
if(department != "Unknown")
if(!(("[department]" in GLOB.alldepartments) || ("[department]" in GLOB.hidden_departments) || ("[department]" in GLOB.admin_departments) || ("[department]" in GLOB.hidden_admin_departments)))
diff --git a/code/modules/pda/mob_hunt_game_app.dm b/code/modules/pda/mob_hunt_game_app.dm
index 5db744c37ef..fe4ef7962f3 100644
--- a/code/modules/pda/mob_hunt_game_app.dm
+++ b/code/modules/pda/mob_hunt_game_app.dm
@@ -28,6 +28,11 @@
disconnect("Program Terminated")
STOP_PROCESSING(SSobj, pda)
+/datum/data/pda/app/mob_hunter_game/Destroy()
+ STOP_PROCESSING(SSobj, pda)
+ SSmob_hunt.connected_clients -= src
+ return ..()
+
/datum/data/pda/app/mob_hunter_game/proc/scan_nearby()
if(!SSmob_hunt || !connected)
return
@@ -74,13 +79,14 @@
return
scan_nearby()
-/datum/data/pda/app/mob_hunter_game/proc/register_capture(datum/mob_hunt/captured, wild = 0)
+/datum/data/pda/app/mob_hunter_game/proc/register_capture(datum/mob_hunt/captured, wild = FALSE)
if(!captured)
- return 0
- my_collection.Add(captured)
+ return FALSE
+ my_collection += captured
+ RegisterSignal(captured, COMSIG_PARENT_QDELETING, .proc/remove_mob)
if(wild)
wild_captures++
- return 1
+ return TRUE
/datum/data/pda/app/mob_hunter_game/update_ui(mob/user, list/data)
if(!SSmob_hunt || !(src in SSmob_hunt.connected_clients))
@@ -138,12 +144,27 @@
card.forceMove(get_turf(pda))
remove_mob()
-/datum/data/pda/app/mob_hunter_game/proc/remove_mob()
- if(!my_collection.len)
+/**
+ * Removes a Nanomob from the [my_collection] list.
+ *
+ * The Nanomob that is currently selected in the app ([current_index]) will be removed from the list unless a `mob_override` argument is given, in which case that will be removed instead.
+ *
+ * Arguments:
+ * * mob_override - A specific Nanomob to remove from the list. (Optional)
+ */
+/datum/data/pda/app/mob_hunter_game/proc/remove_mob(datum/mob_hunt/mob_override = null)
+ SIGNAL_HANDLER
+ if(!length(my_collection))
return
- my_collection.Remove(my_collection[current_index])
- if(current_index > my_collection.len)
- current_index = my_collection.len
+
+ if(mob_override)
+ my_collection -= mob_override
+ else
+ my_collection -= my_collection[current_index]
+
+ var/collection_length = length(my_collection)
+ if(current_index > collection_length)
+ current_index = collection_length
/datum/data/pda/app/mob_hunter_game/proc/set_trap()
if(!my_collection.len || !pda || !hacked)
diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm
index 83b09e5c228..4c7f1e94ca1 100644
--- a/code/modules/research/circuitprinter.dm
+++ b/code/modules/research/circuitprinter.dm
@@ -11,19 +11,17 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis).
container_type = OPENCONTAINER
categories = list(
- "AI Modules",
- "Computer Boards",
- "Engineering Machinery",
- "Exosuit Modules",
- "Hydroponics Machinery",
- "Medical Machinery",
- "Misc. Machinery",
- "Research Machinery",
- "Subspace Telecomms",
- "Teleportation Machinery"
- )
-
- reagents = new()
+ "AI Modules",
+ "Computer Boards",
+ "Engineering Machinery",
+ "Exosuit Modules",
+ "Hydroponics Machinery",
+ "Medical Machinery",
+ "Misc. Machinery",
+ "Research Machinery",
+ "Subspace Telecomms",
+ "Teleportation Machinery"
+ )
/obj/machinery/r_n_d/circuit_imprinter/New()
..()
@@ -33,8 +31,8 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis).
component_parts += new /obj/item/stock_parts/manipulator(null)
component_parts += new /obj/item/reagent_containers/glass/beaker(null)
component_parts += new /obj/item/reagent_containers/glass/beaker(null)
+ create_reagents()
RefreshParts()
- reagents.my_atom = src
/obj/machinery/r_n_d/circuit_imprinter/upgraded/New()
..()
@@ -45,7 +43,11 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis).
component_parts += new /obj/item/reagent_containers/glass/beaker/large(null)
component_parts += new /obj/item/reagent_containers/glass/beaker/large(null)
RefreshParts()
- reagents.my_atom = src
+
+/obj/machinery/r_n_d/circuit_imprinter/Destroy()
+ if(linked_console)
+ linked_console.linked_imprinter = null
+ return ..()
/obj/machinery/r_n_d/circuit_imprinter/RefreshParts()
reagents.maximum_volume = 0
diff --git a/code/modules/research/destructive_analyzer.dm b/code/modules/research/destructive_analyzer.dm
index 41b7fedd6db..5423f41a236 100644
--- a/code/modules/research/destructive_analyzer.dm
+++ b/code/modules/research/destructive_analyzer.dm
@@ -29,6 +29,11 @@ Note: Must be placed within 3 tiles of the R&D Console
component_parts += new /obj/item/stock_parts/micro_laser/ultra(null)
RefreshParts()
+/obj/machinery/r_n_d/destructive_analyzer/Destroy()
+ if(linked_console)
+ linked_console.linked_destroy = null
+ return ..()
+
/obj/machinery/r_n_d/destructive_analyzer/RefreshParts()
var/T = 0
for(var/obj/item/stock_parts/S in component_parts)
diff --git a/code/modules/research/message_server.dm b/code/modules/research/message_server.dm
index 3c2e2cfda0c..4ceacf94301 100644
--- a/code/modules/research/message_server.dm
+++ b/code/modules/research/message_server.dm
@@ -60,14 +60,16 @@ GLOBAL_LIST_EMPTY(message_servers)
var/active = TRUE
var/decryptkey = "password"
-/obj/machinery/message_server/New()
+/obj/machinery/message_server/Initialize(mapload)
+ . = ..()
GLOB.message_servers += src
decryptkey = GenerateKey()
send_pda_message("System Administrator", "system", "This is an automated message. The messaging system is functioning correctly.")
- ..()
/obj/machinery/message_server/Destroy()
GLOB.message_servers -= src
+ QDEL_LIST(pda_msgs)
+ QDEL_LIST(rc_msgs)
return ..()
/obj/machinery/message_server/process()
diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm
index 263e67dd795..0f69a938734 100644
--- a/code/modules/research/protolathe.dm
+++ b/code/modules/research/protolathe.dm
@@ -14,19 +14,16 @@ Note: Must be placed west/left of and R&D console to function.
container_type = OPENCONTAINER
categories = list(
- "Bluespace",
- "Equipment",
- "Janitorial",
- "Medical",
- "Mining",
- "Miscellaneous",
- "Power",
- "Stock Parts",
- "Weapons"
- )
-
- reagents = new()
-
+ "Bluespace",
+ "Equipment",
+ "Janitorial",
+ "Medical",
+ "Mining",
+ "Miscellaneous",
+ "Power",
+ "Stock Parts",
+ "Weapons"
+ )
/obj/machinery/r_n_d/protolathe/New()
..()
@@ -38,10 +35,9 @@ Note: Must be placed west/left of and R&D console to function.
component_parts += new /obj/item/stock_parts/manipulator(null)
component_parts += new /obj/item/reagent_containers/glass/beaker/large(null)
component_parts += new /obj/item/reagent_containers/glass/beaker/large(null)
+ create_reagents()
RefreshParts()
- reagents.my_atom = src
-
/obj/machinery/r_n_d/protolathe/upgraded/New()
..()
component_parts = list()
@@ -54,7 +50,10 @@ Note: Must be placed west/left of and R&D console to function.
component_parts += new /obj/item/reagent_containers/glass/beaker/large(null)
RefreshParts()
- reagents.my_atom = src
+/obj/machinery/r_n_d/protolathe/Destroy()
+ if(linked_console)
+ linked_console.linked_lathe = null
+ return ..()
/obj/machinery/r_n_d/protolathe/RefreshParts()
var/T = 0
diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm
index ffa8ac763de..03c916e8b69 100644
--- a/code/modules/research/rdconsole.dm
+++ b/code/modules/research/rdconsole.dm
@@ -176,6 +176,20 @@ won't update every console in existence) but it's more of a hassle to do. Also,
SyncRDevices()
/obj/machinery/computer/rdconsole/Destroy()
+ QDEL_NULL(files)
+ QDEL_NULL(t_disk)
+ QDEL_NULL(d_disk)
+ QDEL_LIST(matching_designs)
+ if(linked_destroy)
+ linked_destroy.linked_console = null
+ linked_destroy = null
+ if(linked_lathe)
+ linked_lathe.linked_console = null
+ linked_lathe = null
+ if(linked_imprinter)
+ linked_imprinter.linked_console = null
+ linked_imprinter = null
+
if(wait_message_timer)
deltimer(wait_message_timer)
wait_message_timer = 0
diff --git a/code/modules/research/rdmachines.dm b/code/modules/research/rdmachines.dm
index ac78e892c7e..3fba5e8093a 100644
--- a/code/modules/research/rdmachines.dm
+++ b/code/modules/research/rdmachines.dm
@@ -32,12 +32,17 @@
wires["Black"] = 0
wires["White"] = 0
var/list/w = list("Red","Blue","Green","Yellow","Black","White")
- src.hack_wire = pick(w)
- w -= src.hack_wire
- src.shock_wire = pick(w)
- w -= src.shock_wire
- src.disable_wire = pick(w)
- w -= src.disable_wire
+ hack_wire = pick_n_take(w)
+ shock_wire = pick_n_take(w)
+ disable_wire = pick_n_take(w)
+
+/obj/machinery/r_n_d/Destroy()
+ if(loaded_item)
+ loaded_item.forceMove(get_turf(src))
+ loaded_item = null
+ linked_console = null
+ materials = null
+ return ..()
/obj/machinery/r_n_d/attack_hand(mob/user as mob)
if(shocked)
diff --git a/code/modules/vehicle/ambulance.dm b/code/modules/vehicle/ambulance.dm
index 87323fc2042..e5d089c7fe9 100644
--- a/code/modules/vehicle/ambulance.dm
+++ b/code/modules/vehicle/ambulance.dm
@@ -12,6 +12,11 @@
AA = new(src)
soundloop = new(list(src), FALSE)
+/obj/vehicle/ambulance/Destroy()
+ QDEL_NULL(AA)
+ QDEL_NULL(soundloop)
+ return ..()
+
/datum/action/ambulance_alarm
name = "Toggle Sirens"
icon_icon = 'icons/obj/vehicles.dmi'