diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index d76ffc005a0..263eb595b15 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -339,16 +339,6 @@
O.screen_loc = screen_loc
return O
-/proc/Show2Group4Delay(obj/O, list/group, delay=0)
- if(!isobj(O)) return
- if(!group) group = GLOB.clients
- for(var/client/C in group)
- C.screen += O
- if(delay)
- spawn(delay)
- for(var/client/C in group)
- C.screen -= O
-
/proc/remove_images_from_clients(image/I, list/show_to)
for(var/client/C in show_to)
C.images -= I
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index a6918b665c7..e4f5a6d6ecf 100644
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -125,14 +125,14 @@ SUBSYSTEM_DEF(ticker)
current_state = GAME_STATE_FINISHED
Master.SetRunLevel(RUNLEVEL_POSTGAME) // This shouldnt process more than once, but you never know
auto_toggle_ooc(TRUE) // Turn it on
-
declare_completion()
+ addtimer(CALLBACK(src, .proc/call_reboot), 5 SECONDS)
- spawn(50)
- if(mode.station_was_nuked)
- reboot_helper("Station destroyed by Nuclear Device.", "nuke")
- else
- reboot_helper("Round ended.", "proper completion")
+/datum/controller/subsystem/ticker/proc/call_reboot()
+ if(mode.station_was_nuked)
+ reboot_helper("Station destroyed by Nuclear Device.", "nuke")
+ else
+ reboot_helper("Round ended.", "proper completion")
/datum/controller/subsystem/ticker/proc/setup()
cultdat = setupcult()
diff --git a/code/datums/diseases/advance/symptoms/shedding.dm b/code/datums/diseases/advance/symptoms/shedding.dm
index c3a64501759..087231017b4 100644
--- a/code/datums/diseases/advance/symptoms/shedding.dm
+++ b/code/datums/diseases/advance/symptoms/shedding.dm
@@ -36,15 +36,18 @@ BONUS
if(3, 4)
if(!(head_organ.h_style == "Bald") && !(head_organ.h_style == "Balding Hair"))
to_chat(H, "Your hair starts to fall out in clumps...")
- spawn(50)
- head_organ.h_style = "Balding Hair"
- H.update_hair()
+ addtimer(CALLBACK(src, .proc/change_hair, H, head_organ, null, "Balding Hair"), 5 SECONDS)
if(5)
if(!(head_organ.f_style == "Shaved") || !(head_organ.h_style == "Bald"))
to_chat(H, "Your hair starts to fall out in clumps...")
- spawn(50)
- head_organ.f_style = "Shaved"
- head_organ.h_style = "Bald"
- H.update_hair()
- H.update_fhair()
- return
+ addtimer(CALLBACK(src, .proc/change_hair, H, head_organ, "Shaved", "Bald"), 5 SECONDS)
+
+/datum/symptom/shedding/proc/change_hair(mob/living/carbon/human/H, obj/item/organ/external/head/head_organ, f_style, h_style)
+ if(!H || !head_organ)
+ return
+ if(f_style)
+ head_organ.f_style = f_style
+ H.update_fhair()
+ if(h_style)
+ head_organ.h_style = h_style
+ H.update_hair()
diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm
index 4609075ddd7..49c38103d56 100644
--- a/code/datums/helper_datums/teleport.dm
+++ b/code/datums/helper_datums/teleport.dm
@@ -84,14 +84,12 @@
/datum/teleport/proc/playSpecials(atom/location,datum/effect_system/effect,sound)
if(location)
if(effect)
- spawn(-1)
- src = null
- effect.attach(location)
- effect.start()
+ src = null
+ effect.attach(location)
+ effect.start()
if(sound)
- spawn(-1)
- src = null
- playsound(location,sound,60,1)
+ src = null
+ playsound(location,sound,60,1)
return
//do the monkey dance
diff --git a/code/datums/spells/conjure.dm b/code/datums/spells/conjure.dm
index 4c15353e6c4..be716536aff 100644
--- a/code/datums/spells/conjure.dm
+++ b/code/datums/spells/conjure.dm
@@ -44,9 +44,7 @@
summoned_object.admin_spawned = TRUE
if(summon_lifespan)
- spawn(summon_lifespan)
- if(summoned_object)
- qdel(summoned_object)
+ QDEL_IN(summoned_object, summon_lifespan)
else
switch(charge_type)
if("recharge")
diff --git a/code/datums/spells/knock.dm b/code/datums/spells/knock.dm
index e4c652ae1d3..072bbf244e2 100644
--- a/code/datums/spells/knock.dm
+++ b/code/datums/spells/knock.dm
@@ -16,19 +16,23 @@
/obj/effect/proc_holder/spell/aoe_turf/knock/cast(list/targets, mob/user = usr)
for(var/turf/T in targets)
for(var/obj/machinery/door/door in T.contents)
- spawn(1)
- if(istype(door,/obj/machinery/door/airlock/hatch/gamma))
- return
- if(istype(door,/obj/machinery/door/airlock))
- var/obj/machinery/door/airlock/A = door
- A.unlock(1) //forced because it's magic!
- door.open()
+ INVOKE_ASYNC(src, .proc/try_open_airlock, door)
for(var/obj/structure/closet/C in T.contents)
- spawn(1)
- if(istype(C, /obj/structure/closet/secure_closet))
- var/obj/structure/closet/secure_closet/SC = C
- SC.locked = 0
- C.open()
+ INVOKE_ASYNC(src, .proc/try_open_closet, C)
+
+/obj/effect/proc_holder/spell/aoe_turf/knock/proc/try_open_airlock(obj/machinery/door/door)
+ if(istype(door, /obj/machinery/door/airlock/hatch/gamma))
+ return
+ if(istype(door, /obj/machinery/door/airlock))
+ var/obj/machinery/door/airlock/A = door
+ A.unlock(TRUE) //forced because it's magic!
+ door.open()
+
+/obj/effect/proc_holder/spell/aoe_turf/knock/proc/try_open_closet(obj/structure/closet/C)
+ if(istype(C, /obj/structure/closet/secure_closet))
+ var/obj/structure/closet/secure_closet/SC = C
+ SC.locked = FALSE
+ C.open()
/obj/effect/proc_holder/spell/aoe_turf/knock/greater
name = "Greater Knock"
diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm
index b4214fe3b23..541a544c02b 100644
--- a/code/game/machinery/firealarm.dm
+++ b/code/game/machinery/firealarm.dm
@@ -220,11 +220,9 @@ FIRE ALARM
/obj/machinery/firealarm/power_change()
if(powered(ENVIRON))
stat &= ~NOPOWER
- update_icon()
else
- spawn(rand(0,15))
- stat |= NOPOWER
- update_icon()
+ stat |= NOPOWER
+ update_icon()
/obj/machinery/firealarm/attack_hand(mob/user)
if(stat & (NOPOWER|BROKEN) || buildstage != 2)
diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm
index 9a94d8e83fa..29352c5884e 100644
--- a/code/game/machinery/portable_turret.dm
+++ b/code/game/machinery/portable_turret.dm
@@ -317,11 +317,9 @@ GLOBAL_LIST_EMPTY(turret_icons)
/obj/machinery/porta_turret/power_change()
if(powered() || !use_power)
stat &= ~NOPOWER
- update_icon()
else
- spawn(rand(0, 15))
- stat |= NOPOWER
- update_icon()
+ stat |= NOPOWER
+ update_icon()
/obj/machinery/porta_turret/attackby(obj/item/I, mob/user)
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index 122b85c3d2e..5be9f9996c4 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -806,11 +806,9 @@
/obj/machinery/vending/power_change()
if(powered())
stat &= ~NOPOWER
- update_icon()
else
- spawn(rand(0, 15))
- stat |= NOPOWER
- update_icon()
+ stat |= NOPOWER
+ update_icon()
/obj/machinery/vending/obj_break(damage_flag)
if(!(stat & BROKEN))
diff --git a/code/game/objects/items/devices/whistle.dm b/code/game/objects/items/devices/whistle.dm
index 754c0676b71..0850dd29a76 100644
--- a/code/game/objects/items/devices/whistle.dm
+++ b/code/game/objects/items/devices/whistle.dm
@@ -1,3 +1,6 @@
+
+#define USE_COOLDOWN 2 SECONDS
+
/obj/item/hailer
name = "hailer"
desc = "Used by obese officers to save their breath for running."
@@ -6,11 +9,11 @@
item_state = "flashtool" //looks exactly like a flash (and nothing like a flashbang)
w_class = WEIGHT_CLASS_TINY
flags = CONDUCT
-
+ var/next_use_time
var/spamcheck = 0
/obj/item/hailer/attack_self(mob/living/carbon/user as mob)
- if(spamcheck)
+ if(world.time < next_use_time)
return
if(emagged)
@@ -20,11 +23,11 @@
playsound(get_turf(src), 'sound/voice/halt.ogg', 100, 1, vary = 0)
user.visible_message("[user]'s [name] rasps, \"Halt! Security!\"")
- spamcheck = 1
- spawn(20)
- spamcheck = 0
+ next_use_time = world.time + USE_COOLDOWN
/obj/item/hailer/emag_act(user as mob)
if(!emagged)
to_chat(user, "You overload \the [src]'s voice synthesizer.")
emagged = 1
+
+#undef USE_COOLDOWN
diff --git a/code/game/objects/structures/inflatable.dm b/code/game/objects/structures/inflatable.dm
index d3cf5b0dd96..785d6894215 100644
--- a/code/game/objects/structures/inflatable.dm
+++ b/code/game/objects/structures/inflatable.dm
@@ -59,10 +59,12 @@
qdel(src)
else
visible_message("[src] slowly deflates.")
- spawn(50)
- var/obj/item/inflatable/R = new intact(loc)
- transfer_fingerprints_to(R)
- qdel(src)
+ addtimer(CALLBACK(src, .proc/deflate), 5 SECONDS)
+
+/obj/structure/inflatable/proc/deflate()
+ var/obj/item/inflatable/R = new intact(loc)
+ transfer_fingerprints_to(R)
+ qdel(src)
/obj/structure/inflatable/verb/hand_deflate()
set name = "Deflate"
diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm
index 35eafba791b..32b8ac967a8 100644
--- a/code/modules/atmospherics/machinery/airalarm.dm
+++ b/code/modules/atmospherics/machinery/airalarm.dm
@@ -1052,8 +1052,7 @@
stat &= ~NOPOWER
else
stat |= NOPOWER
- spawn(rand(0,15))
- update_icon()
+ update_icon()
/obj/machinery/alarm/obj_break(damage_flag)
..()
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm
index 11e9897136f..205c120c55b 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm
@@ -227,12 +227,10 @@
)
if(signal.data["status"])
- spawn(2)
- broadcast_status()
+ broadcast_status()
return //do not update_icon
- spawn(2)
- broadcast_status()
+ broadcast_status()
update_icon()
/obj/machinery/atmospherics/binary/dp_vent_pump/attackby(var/obj/item/W as obj, var/mob/user as mob)
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm
index 2dd2705901d..2c12b3fa6a6 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm
@@ -110,12 +110,10 @@
investigate_log("was turned [on ? "on" : "off"] by a remote signal", "atmos")
if("status" in signal.data)
- spawn(2)
- broadcast_status()
+ broadcast_status()
return //do not update_icon
- spawn(2)
- broadcast_status()
+ broadcast_status()
update_icon()
return
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
index c8d96628433..fec536ad0c9 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
@@ -165,12 +165,10 @@ Thus, the two variables affect pump operation are set in New():
investigate_log("was turned [on ? "on" : "off"] by a remote signal", "atmos")
if(signal.data["status"])
- spawn(2)
- broadcast_status()
+ broadcast_status()
return //do not update_icon
- spawn(2)
- broadcast_status()
+ broadcast_status()
update_icon()
return
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
index 7f6cc228844..83d01cb20aa 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
@@ -163,12 +163,10 @@ Thus, the two variables affect pump operation are set in New():
investigate_log("was turned [on ? "on" : "off"] by a remote signal", "atmos")
if(signal.data["status"])
- spawn(2)
- broadcast_status()
+ broadcast_status()
return //do not update_icon
- spawn(2)
- broadcast_status()
+ broadcast_status()
update_icon()
/obj/machinery/atmospherics/binary/volume_pump/attack_hand(mob/user)
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm
index 8a2e383a710..598073ef1c5 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm
@@ -138,14 +138,12 @@
volume_rate = between(0, number, air_contents.volume)
if(signal.data["status"])
- spawn(2)
- broadcast_status()
+ broadcast_status()
return //do not update_icon
//log_admin("DEBUG \[[world.timeofday]\]: outlet_injector/receive_signal: unknown command \"[signal.data["command"]]\"\n[signal.debug_print()]")
//return
- spawn(2)
- broadcast_status()
+ broadcast_status()
update_icon()
/*hide(var/i) //to make the little pipe section invisible, the icon changes.
diff --git a/code/modules/events/tear.dm b/code/modules/events/tear.dm
index 19805dabe63..85976290f9c 100644
--- a/code/modules/events/tear.dm
+++ b/code/modules/events/tear.dm
@@ -34,8 +34,7 @@
animation.icon_state = "newtear"
animation.icon = 'icons/effects/tear.dmi'
animation.master = src
- QDEL_IN(animation, 15)
-
+ QDEL_IN(animation, 1.5 SECONDS)
addtimer(CALLBACK(src, .proc/spew_critters), rand(30, 120))
/obj/effect/tear/proc/spew_critters()
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 5f597aab1d8..222290d30f6 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -35,6 +35,8 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
subject.attack_ai(M)
return is_in_use
+#define TEXT_ANNOUNCEMENT_COOLDOWN 1 MINUTES
+
/mob/living/silicon/ai
name = "AI"
icon = 'icons/mob/ai.dmi'//
@@ -109,6 +111,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
var/arrivalmsg = "$name, $rank, has arrived on the station."
var/list/all_eyes = list()
+ var/next_text_announcement
/mob/living/silicon/ai/proc/add_ai_verbs()
verbs |= GLOB.ai_verbs_default
@@ -508,7 +511,6 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
set category = "AI Commands"
show_station_manifest()
-/mob/living/silicon/ai/var/message_cooldown = 0
/mob/living/silicon/ai/proc/ai_announcement_text()
set category = "AI Commands"
set name = "Make Station Announcement"
@@ -516,7 +518,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
if(check_unable(AI_CHECK_WIRELESS | AI_CHECK_RADIO))
return
- if(message_cooldown)
+ if(world.time < next_text_announcement)
to_chat(src, "Please allow one minute to pass between announcements.")
return
@@ -528,9 +530,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
return
announcement.Announce(input)
- message_cooldown = 1
- spawn(600)//One minute cooldown
- message_cooldown = 0
+ next_text_announcement = world.time + TEXT_ANNOUNCEMENT_COOLDOWN
/mob/living/silicon/ai/proc/ai_call_shuttle()
set name = "Call Emergency Shuttle"
@@ -1395,3 +1395,5 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
runechat_msg_location = loc
else
runechat_msg_location = src
+
+#undef TEXT_ANNOUNCEMENT_COOLDOWN
diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
index 4f45e7d1570..d05f7f4d8ea 100644
--- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
@@ -128,8 +128,7 @@
if(powered())
stat &= ~NOPOWER
else
- spawn(rand(0, 15))
- stat |= NOPOWER
+ stat |= NOPOWER
/obj/machinery/chem_dispenser/ex_act(severity)
if(severity < 3)
diff --git a/code/modules/reagents/chemistry/machinery/chem_heater.dm b/code/modules/reagents/chemistry/machinery/chem_heater.dm
index 5aa40e30e47..7db2037dbc8 100644
--- a/code/modules/reagents/chemistry/machinery/chem_heater.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_heater.dm
@@ -58,8 +58,7 @@
if(powered())
stat &= ~NOPOWER
else
- spawn(rand(0, 15))
- stat |= NOPOWER
+ stat |= NOPOWER
/obj/machinery/chem_heater/attackby(obj/item/I, mob/user)
if(isrobot(user))
diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm
index 4c56a2e2aeb..2a58eaaf223 100644
--- a/code/modules/reagents/chemistry/machinery/chem_master.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_master.dm
@@ -80,8 +80,7 @@
if(powered())
stat &= ~NOPOWER
else
- spawn(rand(0, 15))
- stat |= NOPOWER
+ stat |= NOPOWER
update_icon()
/obj/machinery/chem_master/attackby(obj/item/I, mob/user, params)