diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm
index 536120f5c70..a031145efbc 100644
--- a/code/__defines/misc.dm
+++ b/code/__defines/misc.dm
@@ -327,3 +327,6 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
// Used for creating soft references to objects. A manner of storing an item reference
// as text so you don't necessarily fuck with an object's ability to be garbage collected.
#define SOFTREF(A) "\ref[A]"
+
+#define ADD_VERB_IN(the_atom,time,verb) addtimer(CALLBACK(the_atom, /atom/.proc/add_verb, verb), time, TIMER_UNIQUE | TIMER_OVERRIDE | TIMER_NO_HASH_WAIT)
+#define ADD_VERB_IN_IF(the_atom,time,verb,callback) addtimer(CALLBACK(the_atom, /atom/.proc/add_verb, verb, callback), time, TIMER_UNIQUE | TIMER_OVERRIDE | TIMER_NO_HASH_WAIT)
diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm
index fb420e19874..b60fb110e53 100644
--- a/code/_helpers/unsorted.dm
+++ b/code/_helpers/unsorted.dm
@@ -1191,3 +1191,10 @@ var/list/WALLITEMS = list(
while (world.tick_usage > min(TICK_LIMIT_TO_RUN, CURRENT_TICKLIMIT))
#undef DELTA_CALC
+
+// Helper for adding verbs with timers.
+/atom/proc/add_verb(the_verb, datum/callback/callback)
+ if (callback && !callback.Invoke())
+ return
+
+ verbs += the_verb
diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm
index a53f5c0365e..5ce2f3af20d 100644
--- a/code/game/gamemodes/changeling/changeling_powers.dm
+++ b/code/game/gamemodes/changeling/changeling_powers.dm
@@ -275,8 +275,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
handle_changeling_transform(chosen_dna)
src.verbs -= /mob/proc/changeling_transform
- spawn(10)
- src.verbs += /mob/proc/changeling_transform
+ ADD_VERB_IN(src, 10, /mob/proc/changeling_transform)
changeling_update_languages(changeling.absorbed_languages)
@@ -465,7 +464,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
src << "Your throat adjusts to launch the sting."
changeling.sting_range = 2
src.verbs -= /mob/proc/changeling_boost_range
- spawn(5) src.verbs += /mob/proc/changeling_boost_range
+ ADD_VERB_IN(src, 5, /mob/proc/changeling_boost_range)
feedback_add_details("changeling_powers","RS")
return 1
@@ -489,7 +488,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
C.update_canmove()
src.verbs -= /mob/proc/changeling_unstun
- spawn(5) src.verbs += /mob/proc/changeling_unstun
+ ADD_VERB_IN(src, 5, /mob/proc/changeling_unstun)
feedback_add_details("changeling_powers","UNS")
return 1
@@ -525,7 +524,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
sleep(40)
src.verbs -= /mob/proc/changeling_digitalcamo
- spawn(5) src.verbs += /mob/proc/changeling_digitalcamo
+ ADD_VERB_IN(src, 5, /mob/proc/changeling_digitalcamo)
feedback_add_details("changeling_powers","CAM")
return 1
@@ -551,7 +550,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
sleep(10)
src.verbs -= /mob/proc/changeling_rapidregen
- spawn(5) src.verbs += /mob/proc/changeling_rapidregen
+ ADD_VERB_IN(src, 5, /mob/proc/changeling_rapidregen)
feedback_add_details("changeling_powers","RR")
return 1
@@ -693,7 +692,7 @@ var/list/datum/absorbed_dna/hivemind_bank = list()
changeling.chem_charges -= required_chems
changeling.sting_range = 1
src.verbs -= verb_path
- spawn(10) src.verbs += verb_path
+ ADD_VERB_IN(src, 10, verb_path)
if(stealthy == 1)
src << "We stealthily sting [T]."
diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm
index 279b5c391f0..183d138941e 100644
--- a/code/game/gamemodes/vampire/vampire_powers.dm
+++ b/code/game/gamemodes/vampire/vampire_powers.dm
@@ -143,8 +143,7 @@
admin_attacker_log_many_victims(src, victims, "used glare to stun", "was stunned by [key_name(src)] using glare", "used glare to stun")
verbs -= /mob/living/carbon/human/proc/vampire_glare
- spawn(800)
- verbs += /mob/living/carbon/human/proc/vampire_glare
+ ADD_VERB_IN(src, 800, /mob/living/carbon/human/proc/vampire_glare)
// Targeted stun ability, moderate duration.
/mob/living/carbon/human/proc/vampire_hypnotise()
@@ -188,8 +187,7 @@
admin_attack_log(src, T, "used hypnotise to stun [key_name(T)]", "was stunned by [key_name(src)] using hypnotise", "used hypnotise on")
verbs -= /mob/living/carbon/human/proc/vampire_hypnotise
- spawn(1200)
- verbs += /mob/living/carbon/human/proc/vampire_hypnotise
+ ADD_VERB_IN(src, 1200, /mob/living/carbon/human/proc/vampire_hypnotise)
else
src << "You broke your gaze."
@@ -238,8 +236,7 @@
vampire.use_blood(20)
verbs -= /mob/living/carbon/human/proc/vampire_veilstep
- spawn(300)
- verbs += /mob/living/carbon/human/proc/vampire_veilstep
+ ADD_VERB_IN(src, 300, /mob/living/carbon/human/proc/vampire_veilstep)
// Summons bats.
/mob/living/carbon/human/proc/vampire_bats()
@@ -285,10 +282,7 @@
vampire.use_blood(60)
verbs -= /mob/living/carbon/human/proc/vampire_bats
- addtimer(CALLBACK(src, .proc/vampire_post_bats), 1200)
-
-/mob/living/carbon/human/proc/vampire_post_bats()
- verbs += /mob/living/carbon/human/proc/vampire_bats
+ ADD_VERB_IN(src, 1200, /mob/living/carbon/human/proc/vampire_bats)
// Chiropteran Screech
/mob/living/carbon/human/proc/vampire_screech()
@@ -337,8 +331,7 @@
log_and_message_admins("used chiropteran screech.")
verbs -= /mob/living/carbon/human/proc/vampire_screech
- spawn(3600)
- verbs += /mob/living/carbon/human/proc/vampire_screech
+ ADD_VERB_IN(src, 3600, /mob/living/carbon/human/proc/vampire_screech)
// Enables the vampire to be untouchable and walk through walls and other solid things.
/mob/living/carbon/human/proc/vampire_veilwalk()
@@ -628,8 +621,7 @@
vampire.use_blood(25)
verbs -= /mob/living/carbon/human/proc/vampire_dominate
- spawn(1800)
- verbs += /mob/living/carbon/human/proc/vampire_dominate
+ ADD_VERB_IN(src, 1800, /mob/living/carbon/human/proc/vampire_dominate)
// Enthralls a person, giving the vampire a mortal slave.
/mob/living/carbon/human/proc/vampire_enthrall()
@@ -681,8 +673,7 @@
vampire.use_blood(150)
verbs -= /mob/living/carbon/human/proc/vampire_enthrall
- spawn(2800)
- verbs += /mob/living/carbon/human/proc/vampire_enthrall
+ ADD_VERB_IN(src, 2800, /mob/living/carbon/human/proc/vampire_enthrall)
// Gives a lethal disease to the target.
/mob/living/carbon/human/proc/vampire_diseasedtouch()
@@ -725,8 +716,7 @@
vampire.use_blood(200)
verbs -= /mob/living/carbon/human/proc/vampire_diseasedtouch
- spawn(1800)
- verbs += /mob/living/carbon/human/proc/vampire_diseasedtouch
+ ADD_VERB_IN(src, 1800, /mob/living/carbon/human/proc/vampire_diseasedtouch)
// Makes the vampire appear 'friendlier' to others.
/mob/living/carbon/human/proc/vampire_presence()
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index af69165461a..c61e2d09d24 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -316,8 +316,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
usr << "Not when you're not dead!"
return
usr.verbs -= /mob/dead/observer/proc/dead_tele
- spawn(30)
- usr.verbs += /mob/dead/observer/proc/dead_tele
+ ADD_VERB_IN(usr, 30, /mob/dead/observer/proc/dead_tele)
var/area/thearea = ghostteleportlocs[A]
if(!thearea) return