diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 75b41b952b7..78a9fbc53f6 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -238,6 +238,9 @@ ///Calls the show_candidate_poll_window() to all eligible ghosts /proc/poll_candidates(question, jobban_type, be_special_flag = 0, poll_time = 300, ignore_category = null, flashwindow = TRUE, list/group = null) + if (group.len == 0) + return list() + var/time_passed = world.time if (!question) question = "Would you like to be a special role?" diff --git a/code/__HELPERS/varset_callback.dm b/code/__HELPERS/varset_callback.dm index 54fc821cacc..4f132b9e20f 100644 --- a/code/__HELPERS/varset_callback.dm +++ b/code/__HELPERS/varset_callback.dm @@ -1,12 +1,23 @@ #define VARSET_LIST_CALLBACK(target, var_name, var_value) CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(___callbackvarset), ##target, ##var_name, ##var_value) //dupe code because dm can't handle 3 level deep macros #define VARSET_CALLBACK(datum, var, var_value) CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(___callbackvarset), ##datum, NAMEOF(##datum, ##var), ##var_value) +/// Same as VARSET_CALLBACK, but uses a weakref to the datum. +/// Use this if the timer is exceptionally long. +#define VARSET_WEAK_CALLBACK(datum, var, var_value) CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(___callbackvarset), WEAKREF(##datum), NAMEOF(##datum, ##var), ##var_value) /proc/___callbackvarset(list_or_datum, var_name, var_value) if(length(list_or_datum)) list_or_datum[var_name] = var_value return + var/datum/datum = list_or_datum + + if (isweakref(datum)) + var/datum/weakref/datum_weakref = datum + datum = datum_weakref.resolve() + if (isnull(datum)) + return + if(IsAdminAdvancedProcCall()) datum.vv_edit_var(var_name, var_value) //same result generally, unless badmemes else diff --git a/code/game/objects/effects/anomalies/anomalies_ectoplasm.dm b/code/game/objects/effects/anomalies/anomalies_ectoplasm.dm index 554310bd08a..51fe6b8cc84 100644 --- a/code/game/objects/effects/anomalies/anomalies_ectoplasm.dm +++ b/code/game/objects/effects/anomalies/anomalies_ectoplasm.dm @@ -147,7 +147,7 @@ START_PROCESSING(SSobj, src) INVOKE_ASYNC(src, PROC_REF(make_ghost_swarm), candidate_list) playsound(src, pick(spooky_noises), 100, TRUE) - QDEL_IN(src, 2 MINUTES) + QDEL_IN(WEAKREF(src), 2 MINUTES) /obj/structure/ghost_portal/process(delta_time) . = ..() diff --git a/code/modules/pai/pai.dm b/code/modules/pai/pai.dm index acb1fba2a40..204b6fdcecf 100644 --- a/code/modules/pai/pai.dm +++ b/code/modules/pai/pai.dm @@ -219,7 +219,7 @@ pai_card.set_personality(src) forceMove(pai_card) card = pai_card - addtimer(VARSET_CALLBACK(src, holochassis_ready, TRUE), HOLOCHASSIS_INIT_TIME) + addtimer(VARSET_WEAK_CALLBACK(src, holochassis_ready, TRUE), HOLOCHASSIS_INIT_TIME) if(!holoform) add_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), PAI_FOLDED) desc = "A pAI hard-light holographics emitter. This one appears in the form of a [chassis]." diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index dfe244cda2d..f870ec15e77 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -107,6 +107,9 @@ summon_objective.summoned = FALSE summon_objective.killed = TRUE + if (GLOB.cult_narsie == src) + GLOB.cult_narsie = null + return ..() /obj/narsie/attack_ghost(mob/user) diff --git a/code/modules/unit_tests/create_and_destroy.dm b/code/modules/unit_tests/create_and_destroy.dm index f932098a368..79bd76b8b9b 100644 --- a/code/modules/unit_tests/create_and_destroy.dm +++ b/code/modules/unit_tests/create_and_destroy.dm @@ -157,13 +157,18 @@ GLOBAL_VAR_INIT(running_create_and_destroy, FALSE) GLOB.running_create_and_destroy = FALSE //Hell code, we're bound to have ended the round somehow so let's stop if from ending while we work SSticker.delay_end = TRUE + + // Drastically lower the amount of time it takes to GC, since we don't have clients that can hold it up. + SSgarbage.collection_timeout[GC_QUEUE_CHECK] = 10 SECONDS //Prevent the garbage subsystem from harddeling anything, if only to save time SSgarbage.collection_timeout[GC_QUEUE_HARDDELETE] = 10000 HOURS //Clear it, just in case cached_contents.Cut() //Now that we've qdel'd everything, let's sleep until the gc has processed all the shit we care about - var/time_needed = SSgarbage.collection_timeout[GC_QUEUE_CHECK] + // + 2 seconds to ensure that everything gets in the queue. + var/time_needed = SSgarbage.collection_timeout[GC_QUEUE_CHECK] + 2 SECONDS + var/start_time = world.time var/garbage_queue_processed = FALSE @@ -215,4 +220,5 @@ GLOBAL_VAR_INIT(running_create_and_destroy, FALSE) SSticker.delay_end = FALSE //This shouldn't be needed, but let's be polite - SSgarbage.collection_timeout[GC_QUEUE_HARDDELETE] = 10 SECONDS + SSgarbage.collection_timeout[GC_QUEUE_CHECK] = GC_CHECK_QUEUE + SSgarbage.collection_timeout[GC_QUEUE_HARDDELETE] = GC_DEL_QUEUE diff --git a/code/modules/unit_tests/unit_test.dm b/code/modules/unit_tests/unit_test.dm index ab2bc776a27..efd1290d00d 100644 --- a/code/modules/unit_tests/unit_test.dm +++ b/code/modules/unit_tests/unit_test.dm @@ -223,7 +223,7 @@ GLOBAL_VAR_INIT(focused_tests, focused_tests()) SSticker.force_ending = TRUE //We have to call this manually because del_text can preceed us, and SSticker doesn't fire in the post game - SSticker.standard_reboot() + SSticker.declare_completion() /datum/map_template/unit_tests name = "Unit Tests Zone"