diff --git a/code/modules/hallucinations/hallucination_manager.dm b/code/modules/hallucinations/hallucination_manager.dm new file mode 100644 index 00000000000..b436653a4a0 --- /dev/null +++ b/code/modules/hallucinations/hallucination_manager.dm @@ -0,0 +1,57 @@ +/* + * Hallucination manager + * Automatically spawns a hallucination effect according to `get_spawn_location` and `initial_hallucination` + * By default invokes a 10 second trigger. By default that trigger will delete the manager and thus the hallucination + */ + +/datum/hallucination_manager + /// Person on who this hallucination is + var/mob/living/owner + /// Reference to the timer that will do the first trigger + var/trigger_timer + /// How fast do we need to start our first trigger + var/trigger_time = 10 SECONDS + /// A list with all of our hallucinations + var/list/hallucination_list = list() + /// A list with any images that we made separately from our hallucinations + var/list/images = list() + /// The first hallucination that we spawn. Also doubles as a reference to our hallucination + var/obj/effect/hallucination/no_delete/initial_hallucination + +// `ignore_this_argument` is here because there are still old hallucinations which require a location passed +/datum/hallucination_manager/New(turf/ignore_this_argument, mob/living/hallucinator) + . = ..() + owner = hallucinator + if(QDELETED(owner)) + qdel(src) + return + RegisterSignal(owner, COMSIG_PARENT_QDELETING, PROC_REF(signal_qdel)) + spawn_hallucination() + +/datum/hallucination_manager/Destroy(force, ...) + . = ..() + owner = null + deltimer(trigger_timer) + QDEL_NULL(hallucination_list) + QDEL_NULL(images) + +/datum/hallucination_manager/proc/spawn_hallucination() + var/turf/spawn_location = get_spawn_location() + initial_hallucination = new(spawn_location, owner) + hallucination_list |= initial_hallucination + on_spawn() + trigger_timer = addtimer(CALLBACK(src, PROC_REF(on_trigger)), trigger_time, TIMER_DELETE_ME) + +/// Returns a turf on where to spawn a hallucination +/datum/hallucination_manager/proc/get_spawn_location() + var/list/turfs = view(5, owner) + return pick(turfs) + +/// The proc that runs when our hallucination is first spawned +/datum/hallucination_manager/proc/on_spawn() + return + +/// Trigger. By default will delete the manager +/datum/hallucination_manager/proc/on_trigger() + // If you want to have more behaviour after this callback, define a new proc on your own manager + qdel(src) diff --git a/code/modules/hallucinations/hallucinations.dm b/code/modules/hallucinations/hallucinations.dm index aefeb0d1e4e..7e4a4917ada 100644 --- a/code/modules/hallucinations/hallucinations.dm +++ b/code/modules/hallucinations/hallucinations.dm @@ -51,6 +51,8 @@ GLOBAL_LIST_INIT(hallucinations, list( var/mob/living/carbon/target = null /// Lazy list of images created as part of the hallucination. Cleared on destruction. var/list/image/images = null + /// Should this hallucination delete itself + var/should_delete = TRUE /obj/effect/hallucination/Initialize(mapload, mob/living/carbon/hallucination_target) . = ..() @@ -66,7 +68,8 @@ GLOBAL_LIST_INIT(hallucinations, list( // Lifetime if(islist(duration)) duration = rand(duration[1], duration[2]) - QDEL_IN(src, duration) + if(should_delete) + QDEL_IN(src, duration) /obj/effect/hallucination/Destroy() clear_icons() @@ -145,3 +148,8 @@ GLOBAL_LIST_INIT(hallucinations, list( target?.playsound_local(source, snd, volume, vary, frequency) return addtimer(CALLBACK(target, TYPE_PROC_REF(/mob, playsound_local), source, snd, volume, vary, frequency), time) + +/// Subtype that doesn't delete itself. +/// Mostly used for hallucination managers because they delete the hallucinations when required +/obj/effect/hallucination/no_delete + should_delete = FALSE diff --git a/paradise.dme b/paradise.dme index ba811d7f5cf..d544ef15127 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1961,6 +1961,7 @@ #include "code\modules\games\cards.dm" #include "code\modules\games\tarot.dm" #include "code\modules\games\unum.dm" +#include "code\modules\hallucinations\hallucination_manager.dm" #include "code\modules\hallucinations\hallucinations.dm" #include "code\modules\hallucinations\effects\common.dm" #include "code\modules\hallucinations\effects\major.dm"