diff --git a/code/game/machinery/computer/teleporter.dm b/code/game/machinery/computer/teleporter.dm
index 1e85a6d76f5..6be511f7851 100644
--- a/code/game/machinery/computer/teleporter.dm
+++ b/code/game/machinery/computer/teleporter.dm
@@ -90,16 +90,18 @@
say("Processing hub calibration to target...")
calibrating = TRUE
power_station.update_icon()
- spawn(50 * (3 - power_station.teleporter_hub.accuracy)) //Better parts mean faster calibration
- calibrating = FALSE
- if(check_hub_connection())
- power_station.teleporter_hub.calibrated = TRUE
- say("Calibration complete.")
- else
- say("Error: Unable to detect hub.")
- power_station.update_icon()
+ addtimer(CALLBACK(src, .proc/finish_calibration), 50 * (3 - power_station.teleporter_hub.accuracy)) //Better parts mean faster calibration
. = TRUE
+/obj/machinery/computer/teleporter/proc/finish_calibration()
+ calibrating = FALSE
+ if(check_hub_connection())
+ power_station.teleporter_hub.calibrated = TRUE
+ say("Calibration complete.")
+ else
+ say("Error: Unable to detect hub.")
+ power_station.update_icon()
+
/obj/machinery/computer/teleporter/proc/check_hub_connection()
if(!power_station)
return FALSE
diff --git a/code/game/machinery/telecomms/computers/message.dm b/code/game/machinery/telecomms/computers/message.dm
index ff9385d72ec..884ffd3ba56 100644
--- a/code/game/machinery/telecomms/computers/message.dm
+++ b/code/game/machinery/telecomms/computers/message.dm
@@ -348,9 +348,8 @@
hacking = TRUE
screen = MSG_MON_SCREEN_HACKED
//Time it takes to bruteforce is dependant on the password length.
- spawn(100*length(linkedServer.decryptkey))
- if(src && linkedServer && usr)
- BruteForce(usr)
+ addtimer(CALLBACK(src, .proc/finish_bruteforce, usr), 100*length(linkedServer.decryptkey))
+
//Delete the log.
if (href_list["delete_logs"])
//Are they on the view logs screen?
@@ -444,6 +443,13 @@
return attack_hand(usr)
+/obj/machinery/computer/message_monitor/proc/finish_bruteforce(mob/user)
+ if(!QDELETED(user))
+ BruteForce(user)
+ return
+ hacking = FALSE
+ screen = MSG_MON_SCREEN_MAIN
+
#undef MSG_MON_SCREEN_MAIN
#undef MSG_MON_SCREEN_LOGS
#undef MSG_MON_SCREEN_HACKED
diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm
index f9450681592..3ddcdd9730d 100644
--- a/code/game/objects/effects/spiders.dm
+++ b/code/game/objects/effects/spiders.dm
@@ -148,6 +148,36 @@
else
..()
+/obj/structure/spider/spiderling/proc/cancel_vent_move()
+ forceMove(entry_vent)
+ entry_vent = null
+
+/obj/structure/spider/spiderling/proc/vent_move(obj/machinery/atmospherics/components/unary/vent_pump/exit_vent)
+ if(QDELETED(exit_vent) || exit_vent.welded)
+ cancel_vent_move()
+ return
+
+ forceMove(exit_vent)
+ var/travel_time = round(get_dist(loc, exit_vent.loc) / 2)
+ addtimer(CALLBACK(src, .proc/do_vent_move, exit_vent, travel_time), travel_time)
+
+/obj/structure/spider/spiderling/proc/do_vent_move(obj/machinery/atmospherics/components/unary/vent_pump/exit_vent, travel_time)
+ if(QDELETED(exit_vent) || exit_vent.welded)
+ cancel_vent_move()
+ return
+
+ if(prob(50))
+ audible_message("You hear something scampering through the ventilation ducts.")
+
+ addtimer(CALLBACK(src, .proc/finish_vent_move, exit_vent), travel_time)
+
+/obj/structure/spider/spiderling/proc/finish_vent_move(obj/machinery/atmospherics/components/unary/vent_pump/exit_vent)
+ if(QDELETED(exit_vent) || exit_vent.welded)
+ cancel_vent_move()
+ return
+ forceMove(exit_vent.loc)
+ entry_vent = null
+
/obj/structure/spider/spiderling/process()
if(travelling_in_vent)
if(isturf(loc))
@@ -167,34 +197,8 @@
visible_message("[src] scrambles into the ventilation ducts!", \
"You hear something scampering through the ventilation ducts.")
- spawn(rand(20,60))
- if(!exit_vent || exit_vent.welded)
- forceMove(entry_vent)
- entry_vent = null
- return
+ addtimer(CALLBACK(src, .proc/vent_move, exit_vent), rand(20,60))
- forceMove(exit_vent)
- var/travel_time = round(get_dist(loc, exit_vent.loc) / 2)
- spawn(travel_time)
-
- if(!exit_vent || exit_vent.welded)
- forceMove(entry_vent)
- entry_vent = null
- return
-
- if(prob(50))
- audible_message("You hear something scampering through the ventilation ducts.")
- sleep(travel_time)
-
- if(!exit_vent || exit_vent.welded)
- forceMove(entry_vent)
- entry_vent = null
- return
- forceMove(exit_vent.loc)
- entry_vent = null
- var/area/new_area = get_area(loc)
- if(new_area)
- new_area.Entered(src)
//=================
else if(prob(33))
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index ae381240b2f..023cb58e5bc 100644
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -1081,9 +1081,11 @@ GLOBAL_LIST_EMPTY(PDAs)
for(var/atom/A in src)
A.emp_act(severity)
if (!(. & EMP_PROTECT_SELF))
- emped += 1
- spawn(200 * severity)
- emped -= 1
+ emped++
+ addtimer(CALLBACK(src, .proc/emp_end), 200 * severity)
+
+/obj/item/pda/proc/emp_end()
+ emped--
/proc/get_viewable_pdas(sort_by_job = FALSE)
. = list()
diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm
index d16cb5aa181..c5b09edaf1e 100644
--- a/code/game/objects/items/devices/traitordevices.dm
+++ b/code/game/objects/items/devices/traitordevices.dm
@@ -88,20 +88,19 @@ effective or pretty fucking useless.
var/cooldown = get_cooldown()
used = TRUE
icon_state = "health1"
- handle_cooldown(cooldown) // splits off to handle the cooldown while handling wavelength
+ addtimer(VARSET_CALLBACK(src, used, FALSE), cooldown)
+ addtimer(VARSET_CALLBACK(src, icon_state, "health"), cooldown)
to_chat(user, "Successfully irradiated [M].")
- spawn((wavelength+(intensity*4))*5)
- if(M)
- if(intensity >= 5)
- M.apply_effect(round(intensity/0.075), EFFECT_UNCONSCIOUS)
- M.rad_act(intensity*10)
+ addtimer(CALLBACK(src, .proc/radiation_aftereffect, M), (wavelength+(intensity*4))*5)
else
to_chat(user, "The radioactive microlaser is still recharging.")
-/obj/item/healthanalyzer/rad_laser/proc/handle_cooldown(cooldown)
- spawn(cooldown)
- used = FALSE
- icon_state = "health"
+/obj/item/healthanalyzer/rad_laser/proc/radiation_aftereffect(mob/living/M)
+ if(QDELETED(M))
+ return
+ if(intensity >= 5)
+ M.apply_effect(round(intensity/0.075), EFFECT_UNCONSCIOUS)
+ M.rad_act(intensity*10)
/obj/item/healthanalyzer/rad_laser/proc/get_cooldown()
return round(max(10, (stealth*30 + intensity*5 - wavelength/4)))
diff --git a/code/game/objects/structures/transit_tubes/station.dm b/code/game/objects/structures/transit_tubes/station.dm
index a2380aee8f5..b915879539d 100644
--- a/code/game/objects/structures/transit_tubes/station.dm
+++ b/code/game/objects/structures/transit_tubes/station.dm
@@ -109,21 +109,22 @@
if(open_status == STATION_TUBE_CLOSED)
icon_state = "opening_[base_icon]"
open_status = STATION_TUBE_OPENING
- spawn(OPEN_DURATION)
- if(open_status == STATION_TUBE_OPENING)
- icon_state = "open_[base_icon]"
- open_status = STATION_TUBE_OPEN
+ addtimer(CALLBACK(src, .proc/finish_animation), OPEN_DURATION)
+/obj/structure/transit_tube/station/proc/finish_animation()
+ switch(open_status)
+ if(STATION_TUBE_OPENING)
+ icon_state = "open_[base_icon]"
+ open_status = STATION_TUBE_OPEN
+ if(STATION_TUBE_CLOSING)
+ icon_state = "closed_[base_icon]"
+ open_status = STATION_TUBE_CLOSED
/obj/structure/transit_tube/station/proc/close_animation()
if(open_status == STATION_TUBE_OPEN)
icon_state = "closing_[base_icon]"
open_status = STATION_TUBE_CLOSING
- spawn(CLOSE_DURATION)
- if(open_status == STATION_TUBE_CLOSING)
- icon_state = "closed_[base_icon]"
- open_status = STATION_TUBE_CLOSED
-
+ addtimer(CALLBACK(src, .proc/finish_animation), CLOSE_DURATION)
/obj/structure/transit_tube/station/proc/launch_pod()
if(launch_cooldown >= world.time)
@@ -145,19 +146,25 @@
/obj/structure/transit_tube/station/pod_stopped(obj/structure/transit_tube_pod/pod, from_dir)
pod_moving = TRUE
- spawn(5)
- if(reverse_launch)
- pod.setDir(tube_dirs[1]) //turning the pod around for next launch.
- launch_cooldown = world.time + cooldown_delay
- open_animation()
- sleep(OPEN_DURATION + 2)
- pod_moving = FALSE
- if(!QDELETED(pod))
- var/datum/gas_mixture/floor_mixture = loc.return_air()
- floor_mixture.archive()
- pod.air_contents.archive()
- pod.air_contents.share(floor_mixture, 1) //mix the pod's gas mixture with the tile it's on
- air_update_turf()
+ addtimer(CALLBACK(src, .proc/start_stopped, pod), 5)
+
+/obj/structure/transit_tube/station/proc/start_stopped(obj/structure/transit_tube_pod/pod)
+ if(QDELETED(pod))
+ return
+ if(reverse_launch)
+ pod.setDir(tube_dirs[1]) //turning the pod around for next launch.
+ launch_cooldown = world.time + cooldown_delay
+ open_animation()
+ addtimer(CALLBACK(src, .proc/finish_stopped, pod), OPEN_DURATION + 2)
+
+/obj/structure/transit_tube/station/proc/finish_stopped(obj/structure/transit_tube_pod/pod)
+ pod_moving = FALSE
+ if(!QDELETED(pod))
+ var/datum/gas_mixture/floor_mixture = loc.return_air()
+ floor_mixture.archive()
+ pod.air_contents.archive()
+ pod.air_contents.share(floor_mixture, 1) //mix the pod's gas mixture with the tile it's on
+ air_update_turf()
/obj/structure/transit_tube/station/init_tube_dirs()
switch(dir)
diff --git a/code/modules/antagonists/wizard/equipment/artefact.dm b/code/modules/antagonists/wizard/equipment/artefact.dm
index 3aeaad2c098..c5833963262 100644
--- a/code/modules/antagonists/wizard/equipment/artefact.dm
+++ b/code/modules/antagonists/wizard/equipment/artefact.dm
@@ -340,9 +340,7 @@
if(BODY_ZONE_PRECISE_EYES)
user.set_machine(src)
user.reset_perspective(target)
- spawn(100)
- user.reset_perspective(null)
- user.unset_machine()
+ addtimer(CALLBACK(src, .proc/reset, user), 10 SECONDS)
if(BODY_ZONE_R_LEG,BODY_ZONE_L_LEG)
to_chat(user, "You move the doll's legs around.")
var/turf/T = get_step(target,pick(GLOB.cardinals))
@@ -357,6 +355,12 @@
GiveHint(target,user)
cooldown = world.time + cooldown_time
+/obj/item/voodoo/proc/reset(mob/user)
+ if(QDELETED(user))
+ return
+ user.reset_perspective(null)
+ user.unset_machine()
+
/obj/item/voodoo/proc/update_targets()
possible = list()
if(!voodoo_link)
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 6d0d3b4c4b1..67c9a29dbd3 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm
@@ -128,7 +128,7 @@
on = !on
if("inject" in signal.data)
- spawn inject()
+ INVOKE_ASYNC(src, .proc/inject)
return
if("set_volume_rate" in signal.data)
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index f820e9f3a91..3c4f27b464b 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -90,69 +90,72 @@
alarms_to_clear += message
alarm_types_clear[type] += 1
- if(!in_cooldown)
- spawn(3 * 10) // 3 seconds
+ if(in_cooldown)
+ return
- if(alarms_to_show.len < 5)
- for(var/msg in alarms_to_show)
- to_chat(src, msg)
- else if(alarms_to_show.len)
+ addtimer(CALLBACK(src, .proc/show_alarms), 3 SECONDS)
- var/msg = "--- "
+/mob/living/silicon/proc/show_alarms()
+ if(alarms_to_show.len < 5)
+ for(var/msg in alarms_to_show)
+ to_chat(src, msg)
+ else if(alarms_to_show.len)
- if(alarm_types_show["Burglar"])
- msg += "BURGLAR: [alarm_types_show["Burglar"]] alarms detected. - "
+ var/msg = "--- "
- if(alarm_types_show["Motion"])
- msg += "MOTION: [alarm_types_show["Motion"]] alarms detected. - "
+ if(alarm_types_show["Burglar"])
+ msg += "BURGLAR: [alarm_types_show["Burglar"]] alarms detected. - "
- if(alarm_types_show["Fire"])
- msg += "FIRE: [alarm_types_show["Fire"]] alarms detected. - "
+ if(alarm_types_show["Motion"])
+ msg += "MOTION: [alarm_types_show["Motion"]] alarms detected. - "
- if(alarm_types_show["Atmosphere"])
- msg += "ATMOSPHERE: [alarm_types_show["Atmosphere"]] alarms detected. - "
+ if(alarm_types_show["Fire"])
+ msg += "FIRE: [alarm_types_show["Fire"]] alarms detected. - "
- if(alarm_types_show["Power"])
- msg += "POWER: [alarm_types_show["Power"]] alarms detected. - "
+ if(alarm_types_show["Atmosphere"])
+ msg += "ATMOSPHERE: [alarm_types_show["Atmosphere"]] alarms detected. - "
- if(alarm_types_show["Camera"])
- msg += "CAMERA: [alarm_types_show["Camera"]] alarms detected. - "
+ if(alarm_types_show["Power"])
+ msg += "POWER: [alarm_types_show["Power"]] alarms detected. - "
- msg += "\[Show Alerts\]"
- to_chat(src, msg)
+ if(alarm_types_show["Camera"])
+ msg += "CAMERA: [alarm_types_show["Camera"]] alarms detected. - "
- if(alarms_to_clear.len < 3)
- for(var/msg in alarms_to_clear)
- to_chat(src, msg)
+ msg += "\[Show Alerts\]"
+ to_chat(src, msg)
- else if(alarms_to_clear.len)
- var/msg = "--- "
+ if(alarms_to_clear.len < 3)
+ for(var/msg in alarms_to_clear)
+ to_chat(src, msg)
- if(alarm_types_clear["Motion"])
- msg += "MOTION: [alarm_types_clear["Motion"]] alarms cleared. - "
+ else if(alarms_to_clear.len)
+ var/msg = "--- "
- if(alarm_types_clear["Fire"])
- msg += "FIRE: [alarm_types_clear["Fire"]] alarms cleared. - "
+ if(alarm_types_clear["Motion"])
+ msg += "MOTION: [alarm_types_clear["Motion"]] alarms cleared. - "
- if(alarm_types_clear["Atmosphere"])
- msg += "ATMOSPHERE: [alarm_types_clear["Atmosphere"]] alarms cleared. - "
+ if(alarm_types_clear["Fire"])
+ msg += "FIRE: [alarm_types_clear["Fire"]] alarms cleared. - "
- if(alarm_types_clear["Power"])
- msg += "POWER: [alarm_types_clear["Power"]] alarms cleared. - "
+ if(alarm_types_clear["Atmosphere"])
+ msg += "ATMOSPHERE: [alarm_types_clear["Atmosphere"]] alarms cleared. - "
- if(alarm_types_show["Camera"])
- msg += "CAMERA: [alarm_types_clear["Camera"]] alarms cleared. - "
+ if(alarm_types_clear["Power"])
+ msg += "POWER: [alarm_types_clear["Power"]] alarms cleared. - "
- msg += "\[Show Alerts\]"
- to_chat(src, msg)
+ if(alarm_types_show["Camera"])
+ msg += "CAMERA: [alarm_types_clear["Camera"]] alarms cleared. - "
+
+ msg += "\[Show Alerts\]"
+ to_chat(src, msg)
- alarms_to_show = list()
- alarms_to_clear = list()
- for(var/key in alarm_types_show)
- alarm_types_show[key] = 0
- for(var/key in alarm_types_clear)
- alarm_types_clear[key] = 0
+ alarms_to_show.Cut()
+ alarms_to_clear.Cut()
+ for(var/key in alarm_types_show)
+ alarm_types_show[key] = 0
+ for(var/key in alarm_types_clear)
+ alarm_types_clear[key] = 0
/mob/living/silicon/can_inject(mob/user, error_msg)
if(error_msg)
diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm
index c11bbd2c020..429f678c0ec 100644
--- a/code/modules/mob/living/simple_animal/bot/bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/bot.dm
@@ -357,10 +357,12 @@
ejectpai(0)
if(on)
turn_off()
- spawn(severity*300)
- stat &= ~EMPED
- if(was_on)
- turn_on()
+ addtimer(CALLBACK(src, .proc/emp_reset, was_on), severity*30 SECONDS)
+
+/mob/living/simple_animal/bot/proc/emp_reset(was_on)
+ stat &= ~EMPED
+ if(was_on)
+ turn_on()
/mob/living/simple_animal/bot/proc/set_custom_texts() //Superclass for setting hack texts. Appears only if a set is not given to a bot locally.
text_hack = "You hack [name]."
@@ -595,10 +597,11 @@ Pass a positive integer as an argument to override a bot's default speed.
/mob/living/simple_animal/bot/proc/bot_patrol()
patrol_step()
- spawn(5)
- if(mode == BOT_PATROL)
- patrol_step()
- return
+ addtimer(CALLBACK(src, .proc/do_patrol), 5)
+
+/mob/living/simple_animal/bot/proc/do_patrol()
+ if(mode == BOT_PATROL)
+ patrol_step()
/mob/living/simple_animal/bot/proc/start_patrol()
@@ -648,15 +651,17 @@ Pass a positive integer as an argument to override a bot's default speed.
var/moved = bot_move(patrol_target)//step_towards(src, next) // attempt to move
if(!moved) //Couldn't proceed the next step of the path BOT_STEP_MAX_RETRIES times
- spawn(2)
- calc_path()
- if(path.len == 0)
- find_patrol_target()
- tries = 0
+ addtimer(CALLBACK(src, .proc/patrol_step_not_moved), 2)
else // no path, so calculate new one
mode = BOT_START_PATROL
+/mob/living/simple_animal/bot/proc/patrol_step_not_moved()
+ calc_path()
+ if(!length(path))
+ find_patrol_target()
+ tries = 0
+
// finds the nearest beacon to self
/mob/living/simple_animal/bot/proc/find_patrol_target()
nearest_beacon = null
@@ -757,11 +762,13 @@ Pass a positive integer as an argument to override a bot's default speed.
/mob/living/simple_animal/bot/proc/calc_summon_path(turf/avoid)
check_bot_access()
- spawn()
- set_path(get_path_to(src, summon_target, /turf/proc/Distance_cardinal, 0, 150, id=access_card, exclude=avoid))
- if(!path.len) //Cannot reach target. Give up and announce the issue.
- speak("Summon command failed, destination unreachable.",radio_channel)
- bot_reset()
+ INVOKE_ASYNC(src, .proc/do_calc_summon_path, avoid)
+
+/mob/living/simple_animal/bot/proc/do_calc_summon_path(turf/avoid)
+ set_path(get_path_to(src, summon_target, /turf/proc/Distance_cardinal, 0, 150, id=access_card, exclude=avoid))
+ if(!length(path)) //Cannot reach target. Give up and announce the issue.
+ speak("Summon command failed, destination unreachable.",radio_channel)
+ bot_reset()
/mob/living/simple_animal/bot/proc/summon_step()
@@ -779,13 +786,15 @@ Pass a positive integer as an argument to override a bot's default speed.
var/moved = bot_move(summon_target, 3) // Move attempt
if(!moved)
- spawn(2)
- calc_summon_path()
- tries = 0
+ addtimer(CALLBACK(src, .proc/summon_step_not_moved), 2)
else // no path, so calculate new one
calc_summon_path()
+/mob/living/simple_animal/bot/proc/summon_step_not_moved()
+ calc_summon_path()
+ tries = 0
+
/mob/living/simple_animal/bot/Bump(atom/A) //Leave no door unopened!
. = ..()
if((istype(A, /obj/machinery/door/airlock) || istype(A, /obj/machinery/door/window)) && (!isnull(access_card)))
diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
index 419c0d5f411..d5732b9aeb2 100644
--- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
+++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
@@ -184,25 +184,28 @@
to_chat(src, "You are tipped over by [M]!")
Paralyze(60, ignore_canstun = TRUE)
icon_state = icon_dead
- spawn(rand(20,50))
- if(!stat && M)
- icon_state = icon_living
- var/external
- var/internal
- switch(pick(1,2,3,4))
- if(1,2,3)
- var/text = pick("imploringly.", "pleadingly.",
- "with a resigned expression.")
- external = "[src] looks at [M] [text]"
- internal = "You look at [M] [text]"
- if(4)
- external = "[src] seems resigned to its fate."
- internal = "You resign yourself to your fate."
- visible_message("[external]",
- "[internal]")
+ addtimer(CALLBACK(src, .proc/cow_tipped, M), rand(20,50))
+
else
..()
+/mob/living/simple_animal/cow/proc/cow_tipped(mob/living/carbon/M)
+ if(QDELETED(M) || stat)
+ return
+ icon_state = icon_living
+ var/external
+ var/internal
+ if(prob(75))
+ var/text = pick("imploringly.", "pleadingly.",
+ "with a resigned expression.")
+ external = "[src] looks at [M] [text]"
+ internal = "You look at [M] [text]"
+ else
+ external = "[src] seems resigned to its fate."
+ internal = "You resign yourself to your fate."
+ visible_message("[external]",
+ "[internal]")
+
///Wisdom cow, gives XP to a random skill and speaks wisdoms
/mob/living/simple_animal/cow/wisdom
name = "wisdom cow"