diff --git a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm index d36c6059c5f..1d2e0483563 100644 --- a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm @@ -42,6 +42,12 @@ id_tag = num2text(uid) icon = null +/obj/machinery/atmospherics/binary/dp_vent_pump/Destroy() + if(radio_controller) + radio_controller.remove_object(src, frequency) + radio_connection = null + return ..() + /obj/machinery/atmospherics/binary/dp_vent_pump/initialize() ..() if(frequency) diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm index bff752be688..5112326fe9e 100644 --- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm +++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm @@ -21,6 +21,12 @@ if(frequency) set_frequency(frequency) +/obj/machinery/atmospherics/binary/passive_gate/Destroy() + if(radio_controller) + radio_controller.remove_object(src, frequency) + radio_connection = null + return ..() + /obj/machinery/atmospherics/binary/passive_gate/update_icon() icon_state = "[on ? "on" : "off"]" diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm index 4acf261c205..a2e6a93ec0a 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm @@ -28,6 +28,12 @@ Thus, the two variables affect pump operation are set in New(): var/id = null var/datum/radio_frequency/radio_connection +/obj/machinery/atmospherics/binary/pump/Destroy() + if(radio_controller) + radio_controller.remove_object(src, frequency) + radio_connection = null + return ..() + /obj/machinery/atmospherics/binary/pump/highcap name = "High capacity gas pump" desc = "A high capacity pump" diff --git a/code/ATMOSPHERICS/components/binary_devices/valve.dm b/code/ATMOSPHERICS/components/binary_devices/valve.dm index 2737b7abfbd..0e06c5b55d5 100644 --- a/code/ATMOSPHERICS/components/binary_devices/valve.dm +++ b/code/ATMOSPHERICS/components/binary_devices/valve.dm @@ -44,10 +44,10 @@ update_icon() investigate_log("was closed by [usr ? key_name(usr) : "a remote signal"]", "atmos") return - + /obj/machinery/atmospherics/binary/valve/attack_ai(mob/user) return - + /obj/machinery/atmospherics/binary/valve/attack_ghost(mob/user) if(user.can_advanced_admin_interact()) return attack_hand(user) @@ -60,7 +60,7 @@ close() else open() - + /obj/machinery/atmospherics/binary/valve/digital // can be controlled by AI name = "digital valve" desc = "A digitally controlled valve." @@ -71,6 +71,12 @@ var/datum/radio_frequency/radio_connection settagwhitelist = list("id_tag") +/obj/machinery/atmospherics/binary/valve/digital/Destroy() + if(radio_controller) + radio_controller.remove_object(src, frequency) + radio_connection = null + return ..() + /obj/machinery/atmospherics/binary/valve/digital/attack_ai(mob/user) return attack_hand(user) diff --git a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm index f731efde5b7..049524d6e03 100644 --- a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm @@ -28,6 +28,12 @@ Thus, the two variables affect pump operation are set in New(): var/id = null var/datum/radio_frequency/radio_connection +/obj/machinery/atmospherics/binary/volume_pump/Destroy() + if(radio_controller) + radio_controller.remove_object(src, frequency) + radio_connection = null + return ..() + /obj/machinery/atmospherics/binary/volume_pump/on on = 1 icon_state = "map_on" diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm index 2bf8f249185..427c77e8246 100755 --- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm @@ -22,6 +22,13 @@ Filter types: var/frequency = 0 var/datum/radio_frequency/radio_connection + +/obj/machinery/atmospherics/trinary/filter/Destroy() + if(radio_controller) + radio_controller.remove_object(src, frequency) + radio_connection = null + return ..() + /obj/machinery/atmospherics/trinary/filter/flipped icon_state = "mmap" flipped = 1 diff --git a/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm b/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm index 0987561f94c..ad9561fbf1d 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm @@ -7,7 +7,7 @@ name = "manual switching valve" desc = "A pipe valve" - + can_unwrench = 1 var/state = TVALVE_STATE_STRAIGHT @@ -15,16 +15,16 @@ /obj/machinery/atmospherics/trinary/tvalve/bypass icon_state = "map_tvalve1" state = TVALVE_STATE_SIDE - + /obj/machinery/atmospherics/trinary/tvalve/flipped icon_state = "map_tvalvem0" flipped = 1 - + /obj/machinery/atmospherics/trinary/tvalve/flipped/bypass icon_state = "map_tvalvem1" flipped = 1 state = TVALVE_STATE_SIDE - + /obj/machinery/atmospherics/trinary/tvalve/update_icon(animation) var/flipstate = "" if(flipped) @@ -40,7 +40,7 @@ var/turf/T = get_turf(src) if(!istype(T)) return - + add_underlay(T, node1, turn(dir, -180)) if(flipped) @@ -49,7 +49,7 @@ add_underlay(T, node2, turn(dir, -90)) add_underlay(T, node3, dir) - + /obj/machinery/atmospherics/trinary/tvalve/proc/switch_side() if(state == TVALVE_STATE_STRAIGHT) go_to_side() @@ -57,7 +57,7 @@ go_straight() /obj/machinery/atmospherics/trinary/tvalve/proc/go_to_side() - if(state == TVALVE_STATE_SIDE) + if(state == TVALVE_STATE_SIDE) return 0 state = TVALVE_STATE_SIDE @@ -74,7 +74,7 @@ /obj/machinery/atmospherics/trinary/tvalve/proc/go_straight() if(state == TVALVE_STATE_STRAIGHT) return 0 - + state = TVALVE_STATE_STRAIGHT update_icon() @@ -82,13 +82,13 @@ parent2.update = 0 parent3.update = 0 parent1.reconcile_air() - + investigate_log("was set to straight by [usr ? key_name(usr) : "a remote signal"]", "atmos") return 1 /obj/machinery/atmospherics/trinary/tvalve/attack_ai(mob/user) return - + /obj/machinery/atmospherics/trinary/tvalve/attack_ghost(mob/user) if(user.can_advanced_admin_interact()) return attack_hand(user) @@ -108,14 +108,20 @@ var/id = null var/datum/radio_frequency/radio_connection +/obj/machinery/atmospherics/trinary/tvalve/digital/Destroy() + if(radio_controller) + radio_controller.remove_object(src, frequency) + radio_connection = null + return ..() + /obj/machinery/atmospherics/trinary/tvalve/digital/bypass icon_state = "map_tvalve1" state = TVALVE_STATE_SIDE - + /obj/machinery/atmospherics/trinary/tvalve/digital/flipped icon_state = "map_tvalvem0" flipped = 1 - + /obj/machinery/atmospherics/trinary/tvalve/digital/flipped/bypass icon_state = "map_tvalvem1" flipped = 1 diff --git a/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm b/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm index 63070b19538..f61275a8065 100644 --- a/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm +++ b/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm @@ -31,6 +31,12 @@ if(id && !id_tag)//I'm not dealing with any more merge conflicts id_tag = id +/obj/machinery/atmospherics/unary/outlet_injector/Destroy() + if(radio_controller) + radio_controller.remove_object(src, frequency) + radio_connection = null + return ..() + /obj/machinery/atmospherics/unary/outlet_injector/update_icon() if(!powered()) icon_state = "off" diff --git a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm index 662f5fe48f2..b6eafcf5ee4 100644 --- a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm @@ -433,4 +433,7 @@ if(initial_loc) initial_loc.air_vent_info -= id_tag initial_loc.air_vent_names -= id_tag + if(radio_controller) + radio_controller.remove_object(src, frequency) + radio_connection = null return ..() diff --git a/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm index e86b8caa722..83f9466a574 100644 --- a/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm +++ b/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm @@ -53,6 +53,9 @@ if(initial_loc && frequency == 1439) initial_loc.air_scrub_info -= id_tag initial_loc.air_scrub_names -= id_tag + if(radio_controller) + radio_controller.remove_object(src, frequency) + radio_connection = null return ..() /obj/machinery/atmospherics/unary/vent_pump/examine(mob/user) diff --git a/code/__DEFINES/qdel.dm b/code/__DEFINES/qdel.dm index 0d20e14a743..14fd6ea0e36 100644 --- a/code/__DEFINES/qdel.dm +++ b/code/__DEFINES/qdel.dm @@ -8,6 +8,7 @@ #define QDEL_HINT_HARDDEL_NOW 4 //qdel should assume this object won't gc, and hard del it post haste. #define QDEL_HINT_FINDREFERENCE 5 //functionally identical to QDEL_HINT_QUEUE if TESTING is not enabled in _compiler_options.dm. //if TESTING is enabled, qdel will call this object's find_references() verb. +#define QDEL_HINT_IFFAIL_FINDREFERENCE 6 //Above but only if gc fails. //defines for the gc_destroyed var #define GC_QUEUE_PREQUEUE 1 diff --git a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm index 5e336033b6e..05dab2bd97b 100644 --- a/code/controllers/subsystem/garbage.dm +++ b/code/controllers/subsystem/garbage.dm @@ -25,6 +25,10 @@ SUBSYSTEM_DEF(garbage) //Queue var/list/queues + #ifdef TESTING + var/list/reference_find_on_fail = list() + #endif + /datum/controller/subsystem/garbage/PreInit() queues = new(GC_QUEUE_COUNT) @@ -154,6 +158,9 @@ SUBSYSTEM_DEF(garbage) ++gcedlasttick ++totalgcs pass_counts[level]++ + #ifdef TESTING + reference_find_on_fail -= refID //It's deleted we don't care anymore. + #endif if(MC_TICK_CHECK) break continue @@ -162,8 +169,14 @@ SUBSYSTEM_DEF(garbage) fail_counts[level]++ switch(level) if(GC_QUEUE_CHECK) + #ifdef TESTING + if(reference_find_on_fail[refID]) + D.find_references() #ifdef GC_FAILURE_HARD_LOOKUP - D.find_references() + else + D.find_references() + #endif + reference_find_on_fail -= refID #endif var/type = D.type var/datum/qdel_item/I = items[type] @@ -263,6 +276,11 @@ SUBSYSTEM_DEF(garbage) /datum/qdel_item/New(mytype) name = "[mytype]" +#ifdef TESTING +/proc/qdel_and_find_ref_if_fail(datum/D, force = FALSE) + SSgarbage.reference_find_on_fail["\ref[D]"] = TRUE + qdel(D, force) +#endif // Should be treated as a replacement for the 'del' keyword. // Datums passed to this will be given a chance to clean up references to allow the GC to collect them. @@ -319,6 +337,11 @@ SUBSYSTEM_DEF(garbage) #ifdef TESTING D.find_references() #endif + if(QDEL_HINT_IFFAIL_FINDREFERENCE) + SSgarbage.PreQueue(D) + #ifdef TESTING + SSgarbage.reference_find_on_fail["\ref[D]"] = TRUE + #endif else #ifdef TESTING if(!I.no_hint) @@ -388,10 +411,17 @@ SUBSYSTEM_DEF(garbage) set name = "qdel() then Find References" set src in world - qdel(src) + qdel(src, TRUE) //Force. if(!running_find_references) find_references(TRUE) +/datum/verb/qdel_then_if_fail_find_references() + set category = "Debug" + set name = "qdel() then Find References if GC failure" + set src in world + + qdel_and_find_ref_if_fail(src, TRUE) + /datum/proc/DoSearchVar(X, Xname, recursive_limit = 64) if(usr && usr.client && !usr.client.running_find_references) return diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 748e5ac9bb6..0a6ea8c784d 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -1,6 +1,4 @@ /obj/machinery/bodyscanner - var/mob/living/carbon/occupant - var/locked name = "body scanner" icon = 'icons/obj/Cryogenic2.dmi' icon_state = "bodyscanner-open" @@ -11,6 +9,16 @@ active_power_usage = 2500 light_color = "#00FF00" + var/obj/machinery/body_scanconsole/console = null + var/mob/living/carbon/occupant = null + var/locked + +/obj/machinery/bodyscanner/Destroy() + go_out() + if(console) + console.connected = null + console = null + return ..() /obj/machinery/bodyscanner/power_change() ..() @@ -207,9 +215,6 @@ return /obj/machinery/body_scanconsole - var/obj/machinery/bodyscanner/connected - var/delete - var/temphtml name = "Body Scanner Console" icon = 'icons/obj/Cryogenic2.dmi' icon_state = "bodyscannerconsole" @@ -218,6 +223,9 @@ dir = 8 idle_power_usage = 250 active_power_usage = 500 + var/obj/machinery/bodyscanner/connected = null + var/delete + var/temphtml var/printing = null var/printing_text = null var/known_implants = list(/obj/item/weapon/implant/chem, /obj/item/weapon/implant/death_alarm, /obj/item/weapon/implant/mindshield, /obj/item/weapon/implant/tracking, /obj/item/weapon/implant/health) @@ -243,6 +251,12 @@ RefreshParts() findscanner() +/obj/machinery/body_scanconsole/Destroy() + if(connected) + connected.console = null + connected = null + return ..() + /obj/machinery/body_scanconsole/ex_act(severity) switch(severity) if(1.0) @@ -269,15 +283,13 @@ return /obj/machinery/body_scanconsole/proc/findscanner() - var/obj/machinery/bodyscanner/bodyscannernew = null - // Loop through every direction for(dir in list(NORTH,EAST,SOUTH,WEST)) // Try to find a scanner in that direction var/temp = locate(/obj/machinery/bodyscanner, get_step(src, dir)) - if(!isnull(temp)) - bodyscannernew = temp - src.connected = bodyscannernew - return + if(temp) + connected = temp + connected.console = src + break /obj/machinery/body_scanconsole/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob, params) diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index d0f75dbe9e1..c0197b136a3 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -212,6 +212,7 @@ air_alarms -= src if(radio_controller) radio_controller.remove_object(src, frequency) + radio_connection = null air_alarm_repository.update_cache(src) QDEL_NULL(wires) if(alarm_area && alarm_area.master_air_alarm == src) diff --git a/code/game/machinery/atmo_control.dm b/code/game/machinery/atmo_control.dm index fcb9bd0d28e..eebf66bc447 100644 --- a/code/game/machinery/atmo_control.dm +++ b/code/game/machinery/atmo_control.dm @@ -135,7 +135,8 @@ obj/machinery/air_sensor Destroy() SSair.atmos_machinery -= src if(radio_controller) - radio_controller.remove_object(src,frequency) + radio_controller.remove_object(src, frequency) + radio_connection = null return ..() @@ -156,6 +157,12 @@ obj/machinery/air_sensor var/list/sensor_information = list() var/datum/radio_frequency/radio_connection + Destroy() + if(radio_controller) + radio_controller.remove_object(src, frequency) + radio_connection = null + return ..() + attack_hand(mob/user) if(..(user)) return diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index 80cfef47d88..91852deaf73 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -48,13 +48,14 @@ /obj/machinery/driver_button/Destroy() if(radio_controller) - radio_controller.remove_object(src,frequency) + radio_controller.remove_object(src, frequency) + radio_connection = null return ..() /obj/machinery/driver_button/attack_ai(mob/user as mob) return attack_hand(user) - + /obj/machinery/driver_button/attack_ghost(mob/user) if(user.can_advanced_admin_interact()) return attack_hand(user) @@ -167,7 +168,7 @@ /obj/machinery/ignition_switch/attack_ai(mob/user) return attack_hand(user) - + /obj/machinery/ignition_switch/attack_ghost(mob/user) if(user.can_advanced_admin_interact()) return attack_hand(user) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 9ab55f0e1f5..074e29096a6 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -140,6 +140,7 @@ About the new airlock wires panel: /obj/machinery/door/airlock/Destroy() QDEL_NULL(electronics) QDEL_NULL(wires) + QDEL_NULL(note) if(main_power_timer) deltimer(main_power_timer) main_power_timer = null @@ -149,7 +150,9 @@ About the new airlock wires panel: if(electrified_timer) deltimer(electrified_timer) electrified_timer = null - qdel(note) + if(radio_controller) + radio_controller.remove_object(src, frequency) + radio_connection = null return ..() /obj/machinery/door/airlock/handle_atom_del(atom/A) diff --git a/code/game/machinery/doors/airlock_control.dm b/code/game/machinery/doors/airlock_control.dm index cc7da319ddd..8a53dd3de8c 100644 --- a/code/game/machinery/doors/airlock_control.dm +++ b/code/game/machinery/doors/airlock_control.dm @@ -216,6 +216,12 @@ if(radio_controller) set_frequency(frequency) +/obj/machinery/airlock_sensor/Destroy() + if(radio_controller) + radio_controller.remove_object(src, frequency) + radio_connection = null + return ..() + /obj/machinery/airlock_sensor/airlock_interior command = "cycle_interior" @@ -279,6 +285,12 @@ if(radio_controller) set_frequency(frequency) +/obj/machinery/access_button/Destroy() + if(radio_controller) + radio_controller.remove_object(src, frequency) + radio_connection = null + return ..() + /obj/machinery/access_button/airlock_interior frequency = 1379 command = "cycle_interior" diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm index a4a656fa5d6..08143524744 100644 --- a/code/game/machinery/embedded_controller/embedded_controller_base.dm +++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm @@ -58,6 +58,12 @@ ..() set_frequency(frequency) +/obj/machinery/embedded_controller/radio/Destroy() + if(radio_controller) + radio_controller.remove_object(src, frequency) + radio_connection = null + return ..() + /obj/machinery/embedded_controller/radio/update_icon() if(on && program) if(program.memory["processing"]) diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm index 644b5a73ab9..abe9f38f363 100644 --- a/code/game/machinery/lightswitch.dm +++ b/code/game/machinery/lightswitch.dm @@ -56,7 +56,8 @@ /obj/machinery/light_switch/Destroy() if(radio_controller) - radio_controller.remove_object(src,frequency) + radio_controller.remove_object(src, frequency) + radio_connection = null return ..() /obj/machinery/light_switch/proc/updateicon() @@ -75,7 +76,7 @@ /obj/machinery/light_switch/attack_ghost(mob/user) if(user.can_advanced_admin_interact()) return attack_hand(user) - + /obj/machinery/light_switch/attack_hand(mob/user) on = !on updateicon() diff --git a/code/game/machinery/magnet.dm b/code/game/machinery/magnet.dm index 362b9718b3a..0ff8847a8d8 100644 --- a/code/game/machinery/magnet.dm +++ b/code/game/machinery/magnet.dm @@ -236,6 +236,12 @@ filter_path() // renders rpath + Destroy() + if(radio_controller) + radio_controller.remove_object(src, frequency) + radio_connection = null + return ..() + process() if(magnets.len == 0 && autolink) for(var/obj/machinery/magnetic_module/M in world) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index e353834ca22..f10eeff1ebb 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -77,6 +77,7 @@ var/global/list/default_medbay_channels = list( radio_controller.remove_object(src, frequency) for(var/ch_name in channels) radio_controller.remove_object(src, radiochannels[ch_name]) + radio_connection = null global_radios -= src follow_target = null return ..() diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index 959a8d60452..6c94893d6db 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -29,7 +29,8 @@ /obj/item/device/assembly/signaler/Destroy() if(radio_controller) - radio_controller.remove_object(src,frequency) + radio_controller.remove_object(src, frequency) + radio_connection = null return ..() /obj/item/device/assembly/signaler/describe() diff --git a/code/modules/logic/logic_base.dm b/code/modules/logic/logic_base.dm index 926b8a1f129..abc80df5fca 100644 --- a/code/modules/logic/logic_base.dm +++ b/code/modules/logic/logic_base.dm @@ -62,7 +62,8 @@ /obj/machinery/logic_gate/Destroy() if(radio_controller) - radio_controller.remove_object(src,frequency) + radio_controller.remove_object(src, frequency) + radio_connection = null return ..() /obj/machinery/logic_gate/process() diff --git a/code/modules/pda/radio.dm b/code/modules/pda/radio.dm index 108dd4178fa..2a5e84bcac1 100644 --- a/code/modules/pda/radio.dm +++ b/code/modules/pda/radio.dm @@ -168,6 +168,7 @@ /obj/item/radio/integrated/signal/Destroy() if(radio_controller) radio_controller.remove_object(src, frequency) + radio_connection = null return ..() /obj/item/radio/integrated/signal/initialize() diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index 34dad709bd1..be39cb210de 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -117,6 +117,9 @@ update_icon() /obj/machinery/power/emitter/Destroy() + if(radio_controller) + radio_controller.remove_object(src, frequency) + radio_connection = null msg_admin_attack("Emitter deleted at ([x],[y],[z] - JMP)",0,1) log_game("Emitter deleted at ([x],[y],[z])") investigate_log("deleted at ([x],[y],[z])","singulo")