diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 8afbe19633f..01459010385 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -138,25 +138,13 @@ if(!(. & EMP_PROTECT_SELF)) if(prob(150/severity)) update_icon() - var/list/previous_network = network network = list() GLOB.cameranet.removeCamera(src) stat |= EMPED set_light(0) emped = emped+1 //Increase the number of consecutive EMP's update_icon() - var/thisemp = emped //Take note of which EMP this proc is for - spawn(900) - if(loc) //qdel limbo - triggerCameraAlarm() //camera alarm triggers even if multiple EMPs are in effect. - if(emped == thisemp) //Only fix it if the camera hasn't been EMP'd again - network = previous_network - stat &= ~EMPED - update_icon() - if(can_use()) - GLOB.cameranet.addCamera(src) - emped = 0 //Resets the consecutive EMP count - addtimer(CALLBACK(src, .proc/cancelCameraAlarm), 100) + addtimer(CALLBACK(src, .proc/post_emp_reset, emped, network), 90 SECONDS) for(var/i in GLOB.player_list) var/mob/M = i if (M.client.eye == src) @@ -164,6 +152,20 @@ M.reset_perspective(null) to_chat(M, "The screen bursts into static.") +/obj/machinery/camera/proc/post_emp_reset(thisemp, previous_network) + if(QDELETED(src)) + return + triggerCameraAlarm() //camera alarm triggers even if multiple EMPs are in effect. + if(emped != thisemp) //Only fix it if the camera hasn't been EMP'd again + return + network = previous_network + stat &= ~EMPED + update_icon() + if(can_use()) + GLOB.cameranet.addCamera(src) + emped = 0 //Resets the consecutive EMP count + addtimer(CALLBACK(src, .proc/cancelCameraAlarm), 100) + /obj/machinery/camera/ex_act(severity, target) if(invuln) return diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm index 1dbfe9d055b..26f08e0e295 100644 --- a/code/game/machinery/camera/tracking.dm +++ b/code/game/machinery/camera/tracking.dm @@ -86,39 +86,42 @@ to_chat(U, "Now tracking [target.get_visible_name()] on camera.") + INVOKE_ASYNC(src, .proc/do_track, target, U) + +/mob/living/silicon/ai/proc/do_track(mob/living/target, mob/living/silicon/ai/U) var/cameraticks = 0 - spawn(0) - while(U.cameraFollow == target) - if(U.cameraFollow == null) - return - if(!target.can_track(usr)) - U.tracking = 1 - if(!cameraticks) - to_chat(U, "Target is not near any active cameras. Attempting to reacquire...") - cameraticks++ - if(cameraticks > 9) - U.cameraFollow = null - to_chat(U, "Unable to reacquire, cancelling track...") - tracking = 0 - return - else - sleep(10) - continue + while(U.cameraFollow == target) + if(U.cameraFollow == null) + return - else - cameraticks = 0 - U.tracking = 0 - - if(U.eyeobj) - U.eyeobj.setLoc(get_turf(target)) - - else - view_core() + if(!target.can_track(usr)) + U.tracking = 1 + if(!cameraticks) + to_chat(U, "Target is not near any active cameras. Attempting to reacquire...") + cameraticks++ + if(cameraticks > 9) U.cameraFollow = null + to_chat(U, "Unable to reacquire, cancelling track...") + tracking = 0 return + else + sleep(10) + continue - sleep(10) + else + cameraticks = 0 + U.tracking = 0 + + if(U.eyeobj) + U.eyeobj.setLoc(get_turf(target)) + + else + view_core() + U.cameraFollow = null + return + + sleep(10) /proc/near_camera(mob/living/M) if (!isturf(M.loc)) diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 1dcb4875441..5abcdaeb9bc 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -276,8 +276,7 @@ air_update_turf(1) update_freelook_sight() if(autoclose) - spawn(autoclose) - close() + addtimer(CALLBACK(src, .proc/close), autoclose) return 1 /obj/machinery/door/proc/close() diff --git a/code/game/machinery/embedded_controller/access_controller.dm b/code/game/machinery/embedded_controller/access_controller.dm index 96f6b408cd8..6f4b228e162 100644 --- a/code/game/machinery/embedded_controller/access_controller.dm +++ b/code/game/machinery/embedded_controller/access_controller.dm @@ -209,11 +209,13 @@ goIdle(TRUE) return A.unbolt() - spawn() - if(A && A.open()) - if(stat | (NOPOWER) && !lostPower && A && !QDELETED(A)) - A.bolt() - goIdle(TRUE) + INVOKE_ASYNC(src, .proc/do_openDoor, A) + +/obj/machinery/doorButtons/airlock_controller/proc/do_openDoor(obj/machinery/door/airlock/A) + if(A && A.open()) + if(stat | (NOPOWER) && !lostPower && A && !QDELETED(A)) + A.bolt() + goIdle(TRUE) /obj/machinery/doorButtons/airlock_controller/proc/goIdle(update) lostPower = FALSE diff --git a/code/game/machinery/magnet.dm b/code/game/machinery/magnet.dm index 370621e0c86..05a167f5866 100644 --- a/code/game/machinery/magnet.dm +++ b/code/game/machinery/magnet.dm @@ -292,8 +292,7 @@ radio_connection.post_signal(src, signal, filter = RADIO_MAGNETS) - spawn(1) - updateUsrDialog() // pretty sure this increases responsiveness + updateUsrDialog() if(href_list["operation"]) switch(href_list["operation"]) @@ -316,7 +315,7 @@ if("togglemoving") moving = !moving if(moving) - spawn() MagnetMove() + INVOKE_ASYNC(src, .proc/MagnetMove) updateUsrDialog() @@ -353,8 +352,7 @@ pathpos++ // increase iterator // Broadcast the signal - spawn() - radio_connection.post_signal(src, signal, filter = RADIO_MAGNETS) + INVOKE_ASYNC(CALLBACK(radio_connection, /datum/radio_frequency.proc/post_signal, src, signal, RADIO_MAGNETS)) if(speed == 10) sleep(1) diff --git a/code/game/machinery/porta_turret/portable_turret_cover.dm b/code/game/machinery/porta_turret/portable_turret_cover.dm index 4df7001c11d..e03c56a92b6 100644 --- a/code/game/machinery/porta_turret/portable_turret_cover.dm +++ b/code/game/machinery/porta_turret/portable_turret_cover.dm @@ -92,6 +92,5 @@ to_chat(user, "You short out [parent_turret]'s threat assessment circuits.") visible_message("[parent_turret] hums oddly...") parent_turret.obj_flags |= EMAGGED - parent_turret.on = 0 - spawn(40) - parent_turret.on = 1 + parent_turret.on = FALSE + addtimer(VARSET_CALLBACK(parent_turret, on, TRUE), 4 SECONDS) diff --git a/code/game/machinery/slotmachine.dm b/code/game/machinery/slotmachine.dm index b15b2506e24..3a2cda5bf31 100644 --- a/code/game/machinery/slotmachine.dm +++ b/code/game/machinery/slotmachine.dm @@ -207,24 +207,28 @@ balance -= SPIN_PRICE money += SPIN_PRICE plays += 1 - working = 1 + working = TRUE toggle_reel_spin(1) update_icon() updateDialog() - spawn(0) - while(working) - randomize_reels() - updateDialog() - sleep(2) + var/spin_loop = addtimer(CALLBACK(src, .proc/do_spin), 2, TIMER_LOOP|TIMER_STOPPABLE) - spawn(SPIN_TIME - (REEL_DEACTIVATE_DELAY * reels.len)) //WARNING: no sanity checking for user since it's not needed and would complicate things (machine should still spin even if user is gone), be wary of this if you're changing this code. - toggle_reel_spin(0, REEL_DEACTIVATE_DELAY) - working = 0 - give_prizes(the_name, user) - update_icon() - updateDialog() + addtimer(CALLBACK(src, .proc/finish_spinning, spin_loop, user, the_name), SPIN_TIME - (REEL_DEACTIVATE_DELAY * reels.len)) + //WARNING: no sanity checking for user since it's not needed and would complicate things (machine should still spin even if user is gone), be wary of this if you're changing this code. + +/obj/machinery/computer/slot_machine/proc/do_spin() + randomize_reels() + updateDialog() + +/obj/machinery/computer/slot_machine/proc/finish_spinning(spin_loop, mob/user, the_name) + toggle_reel_spin(0, REEL_DEACTIVATE_DELAY) + working = FALSE + deltimer(spin_loop) + give_prizes(the_name, user) + update_icon() + updateDialog() /obj/machinery/computer/slot_machine/proc/can_spin(mob/user) if(stat & NOPOWER) diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/game/mecha/equipment/tools/other_tools.dm index 719c5ef474f..75f71f3dbff 100644 --- a/code/game/mecha/equipment/tools/other_tools.dm +++ b/code/game/mecha/equipment/tools/other_tools.dm @@ -121,15 +121,17 @@ var/mob/M = A if(M.mob_negates_gravity()) continue - spawn(0) - var/iter = 5-get_dist(A,target) - for(var/i=0 to iter) - step_away(A,target) - sleep(2) + INVOKE_ASYNC(src, .proc/do_scatter, A, target) + var/turf/T = get_turf(target) log_game("[key_name(chassis.occupant)] used a Gravitational Catapult repulse wave on [AREACOORD(T)]") return TRUE +/obj/item/mecha_parts/mecha_equipment/gravcatapult/proc/do_scatter(atom/movable/A, atom/movable/target) + var/iter = 5-get_dist(A,target) + for(var/i in 0 to iter) + step_away(A,target) + sleep(2) /obj/item/mecha_parts/mecha_equipment/gravcatapult/get_equip_info() return "[..()] [mode==1?"([locked||"Nothing"])":null] \[S|P\]" diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index bad714cc785..1f006967069 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -351,12 +351,7 @@ add_part_set_to_queue(href_list["partset_to_queue"]) return update_queue_on_page() if(href_list["process_queue"]) - spawn(0) - if(processing_queue || being_built) - return FALSE - processing_queue = 1 - process_queue() - processing_queue = 0 + INVOKE_ASYNC(src, .proc/do_process_queue) if(href_list["clear_temp"]) temp = null if(href_list["screen"]) @@ -394,6 +389,13 @@ updateUsrDialog() return +/obj/machinery/mecha_part_fabricator/proc/do_process_queue() + if(processing_queue || being_built) + return FALSE + processing_queue = 1 + process_queue() + processing_queue = 0 + /obj/machinery/mecha_part_fabricator/on_deconstruction() var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) materials.retrieve_all() diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 3ad94550953..1556afd80b1 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -619,15 +619,14 @@ /obj/mecha/Bump(var/atom/obstacle) if(phasing && get_charge() >= phasing_energy_drain && !throwing) - spawn() - if(can_move) - can_move = 0 - if(phase_state) - flick(phase_state, src) - forceMove(get_step(src,dir)) - use_power(phasing_energy_drain) - sleep(step_in*3) - can_move = 1 + if(!can_move) + return + can_move = 0 + if(phase_state) + flick(phase_state, src) + forceMove(get_step(src,dir)) + use_power(phasing_energy_drain) + addtimer(VARSET_CALLBACK(src, can_move, TRUE), step_in*3) else if(..()) //mech was thrown return diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm index 51927ce1cce..f05b4d602a2 100644 --- a/code/game/objects/effects/anomalies.dm +++ b/code/game/objects/effects/anomalies.dm @@ -235,21 +235,23 @@ if(!A.Move(newloc) && newloc) // if the atom, for some reason, can't move, FORCE them to move! :) We try Move() first to invoke any movement-related checks the atom needs to perform after moving A.forceMove(newloc) - spawn() - if(ismob(A) && !(A in flashers)) // don't flash if we're already doing an effect - var/mob/M = A - if(M.client) - var/obj/blueeffect = new /obj(src) - blueeffect.screen_loc = "WEST,SOUTH to EAST,NORTH" - blueeffect.icon = 'icons/effects/effects.dmi' - blueeffect.icon_state = "shieldsparkles" - blueeffect.layer = FLASH_LAYER - blueeffect.plane = FULLSCREEN_PLANE - blueeffect.mouse_opacity = MOUSE_OPACITY_TRANSPARENT - M.client.screen += blueeffect - sleep(20) - M.client.screen -= blueeffect - qdel(blueeffect) + if(ismob(A) && !(A in flashers)) // don't flash if we're already doing an effect + var/mob/M = A + if(M.client) + INVOKE_ASYNC(src, .proc/blue_effect, M) + +/obj/effect/anomaly/bluespace/proc/blue_effect(mob/M) + var/obj/blueeffect = new /obj(src) + blueeffect.screen_loc = "WEST,SOUTH to EAST,NORTH" + blueeffect.icon = 'icons/effects/effects.dmi' + blueeffect.icon_state = "shieldsparkles" + blueeffect.layer = FLASH_LAYER + blueeffect.plane = FULLSCREEN_PLANE + blueeffect.mouse_opacity = MOUSE_OPACITY_TRANSPARENT + M.client.screen += blueeffect + sleep(20) + M.client.screen -= blueeffect + qdel(blueeffect) ///////////////////// diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index 04f64a6e6de..484739a8423 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -232,17 +232,19 @@ return FALSE /obj/item/defibrillator/proc/cooldowncheck(mob/user) - spawn(50) - if(cell) - if(cell.charge >= paddles.revivecost) - user.visible_message("[src] beeps: Unit ready.") - playsound(src, 'sound/machines/defib_ready.ogg', 50, 0) - else - user.visible_message("[src] beeps: Charge depleted.") - playsound(src, 'sound/machines/defib_failed.ogg', 50, 0) - paddles.cooldown = FALSE - paddles.update_icon() - update_icon() + addtimer(CALLBACK(src, .proc/finish_charging), 5 SECONDS) + +/obj/item/defibrillator/proc/finish_charging() + if(cell) + if(cell.charge >= paddles.revivecost) + visible_message("[src] beeps: Unit ready.") + playsound(src, 'sound/machines/defib_ready.ogg', 50, 0) + else + visible_message("[src] beeps: Charge depleted.") + playsound(src, 'sound/machines/defib_failed.ogg', 50, 0) + paddles.cooldown = FALSE + paddles.update_icon() + update_icon() /obj/item/defibrillator/compact name = "compact defibrillator" diff --git a/code/game/objects/items/storage/bags.dm b/code/game/objects/items/storage/bags.dm index f006a36c974..19151dab924 100644 --- a/code/game/objects/items/storage/bags.dm +++ b/code/game/objects/items/storage/bags.dm @@ -298,11 +298,7 @@ STR.quick_empty() // Make each item scatter a bit for(var/obj/item/I in oldContents) - spawn() - for(var/i = 1, i <= rand(1,2), i++) - if(I) - step(I, pick(NORTH,SOUTH,EAST,WEST)) - sleep(rand(2,4)) + INVOKE_ASYNC(src, .proc/do_scatter, I) if(prob(50)) playsound(M, 'sound/items/trayhit1.ogg', 50, 1) @@ -314,6 +310,12 @@ M.Paralyze(40) update_icon() +/obj/item/storage/bag/tray/proc/do_scatter(obj/item/I) + for(var/i in 1 to rand(1,2)) + if(I) + step(I, pick(NORTH,SOUTH,EAST,WEST)) + sleep(rand(2,4)) + /obj/item/storage/bag/tray/update_icon() cut_overlays() for(var/obj/item/I in contents) diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm index added8e02e7..0c8d0938d6c 100644 --- a/code/game/objects/items/storage/firstaid.dm +++ b/code/game/objects/items/storage/firstaid.dm @@ -201,13 +201,13 @@ var/obj/item/bot_assembly/medbot/A = new if(istype(src, /obj/item/storage/firstaid/fire)) - A.skin = "ointment" + A.set_skin("ointment") else if(istype(src, /obj/item/storage/firstaid/toxin)) - A.skin = "tox" + A.set_skin("tox") else if(istype(src, /obj/item/storage/firstaid/o2)) - A.skin = "o2" + A.set_skin("o2") else if(istype(src, /obj/item/storage/firstaid/brute)) - A.skin = "brute" + A.set_skin("brute") user.put_in_hands(A) to_chat(user, "You add [S] to [src].") A.robot_arm = S.type diff --git a/code/game/objects/items/tanks/watertank.dm b/code/game/objects/items/tanks/watertank.dm index 76e00b98b66..4962cf45087 100644 --- a/code/game/objects/items/tanks/watertank.dm +++ b/code/game/objects/items/tanks/watertank.dm @@ -279,9 +279,7 @@ step_towards(A, target) sleep(2) A.Smoke() - spawn(100) - if(src) - resin_cooldown = FALSE + addtimer(VARSET_CALLBACK(src, resin_cooldown, FALSE), 10 SECONDS) return if(nozzle_mode == RESIN_FOAM) if(!Adj|| !isturf(target)) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 74144d762e2..64efa4a2565 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -553,14 +553,10 @@ /obj/item/toy/talking/attack_self(mob/user) if(!cooldown) - var/list/messages = generate_messages() activation_message(user) playsound(loc, 'sound/machines/click.ogg', 20, 1) - spawn(0) - for(var/message in messages) - toy_talk(user, message) - sleep(10) + INVOKE_ASYNC(src, .proc/do_toy_talk, user) cooldown = TRUE spawn(recharge_time) @@ -577,6 +573,11 @@ /obj/item/toy/talking/proc/generate_messages() return list(pick(messages)) +/obj/item/toy/talking/proc/do_toy_talk(mob/user) + for(var/message in generate_messages()) + toy_talk(user, message) + sleep(10) + /obj/item/toy/talking/proc/toy_talk(mob/user, message) user.loc.visible_message("[icon2html(src, viewers(user.loc))] [message]") if(chattering) @@ -1174,9 +1175,7 @@ var/list/possible_sounds = list('sound/voice/hiss1.ogg', 'sound/voice/hiss2.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss4.ogg') var/chosen_sound = pick(possible_sounds) playsound(get_turf(src), chosen_sound, 50, 1) - spawn(45) - if(src) - icon_state = "[initial(icon_state)]" + addtimer(VARSET_CALLBACK(src, icon_state, "[initial(icon_state)]"), 4.5 SECONDS) else to_chat(user, "The string on [src] hasn't rewound all the way!") return diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm index 7de9375f920..4e669dd819d 100644 --- a/code/game/objects/structures/musician.dm +++ b/code/game/objects/structures/musician.dm @@ -268,8 +268,7 @@ else if(href_list["play"]) playing = TRUE - spawn() - playsong(usr) + INVOKE_ASYNC(src, .proc/playsong, usr) else if(href_list["newline"]) var/newline = html_encode(input("Enter your line: ", instrumentObj.name) as text|null) diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm index 9f7d96bf90d..7595865f504 100644 --- a/code/game/objects/structures/statues.dm +++ b/code/game/objects/structures/statues.dm @@ -254,10 +254,9 @@ /obj/structure/statue/bananium/proc/honk() if(!spam_flag) - spam_flag = 1 + spam_flag = TRUE playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1) - spawn(20) - spam_flag = 0 + addtimer(VARSET_CALLBACK(src, spam_flag, FALSE), 2 SECONDS) /////////////////////sandstone///////////////////////////////////////// diff --git a/code/modules/admin/fun_balloon.dm b/code/modules/admin/fun_balloon.dm index 636d2934259..d4b7a66ce02 100644 --- a/code/modules/admin/fun_balloon.dm +++ b/code/modules/admin/fun_balloon.dm @@ -158,10 +158,11 @@ var/mob/living/M = AM M.forceMove(get_turf(LA)) to_chat(M, "You're trapped in a deadly arena! To escape, you'll need to drag a severed head to the escape portals.") - spawn() - var/obj/effect/mine/pickup/bloodbath/B = new (M) - B.mineEffect(M) + INVOKE_ASYNC(src, .proc/do_bloodbath, M) +/obj/effect/forcefield/arena_shuttle_entrance/proc/do_bloodbath(mob/living/L) + var/obj/effect/mine/pickup/bloodbath/B = new (L) + B.mineEffect(L) /area/shuttle_arena name = "arena" diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm index bbbc998b0c7..5e770e62144 100644 --- a/code/modules/admin/secrets.dm +++ b/code/modules/admin/secrets.dm @@ -288,8 +288,7 @@ return SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Monkeyize All Humans")) for(var/mob/living/carbon/human/H in GLOB.carbon_list) - spawn(0) - H.monkeyize() + INVOKE_ASYNC(H, /mob/living/carbon.proc/monkeyize) ok = 1 if("allspecies") diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index b5682b7b559..5040423141f 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -753,8 +753,7 @@ L.Unconscious(100) sleep(5) L.forceMove(pick(GLOB.tdome1)) - spawn(50) - to_chat(L, "You have been sent to the Thunderdome.") + addtimer(CALLBACK(GLOBAL_PROC, /proc/to_chat, L, "You have been sent to the Thunderdome."), 5 SECONDS) log_admin("[key_name(usr)] has sent [key_name(L)] to the thunderdome. (Team 1)") message_admins("[key_name_admin(usr)] has sent [key_name_admin(L)] to the thunderdome. (Team 1)") @@ -780,8 +779,7 @@ L.Unconscious(100) sleep(5) L.forceMove(pick(GLOB.tdome2)) - spawn(50) - to_chat(L, "You have been sent to the Thunderdome.") + addtimer(CALLBACK(GLOBAL_PROC, /proc/to_chat, L, "You have been sent to the Thunderdome."), 5 SECONDS) log_admin("[key_name(usr)] has sent [key_name(L)] to the thunderdome. (Team 2)") message_admins("[key_name_admin(usr)] has sent [key_name_admin(L)] to the thunderdome. (Team 2)") @@ -804,8 +802,7 @@ L.Unconscious(100) sleep(5) L.forceMove(pick(GLOB.tdomeadmin)) - spawn(50) - to_chat(L, "You have been sent to the Thunderdome.") + addtimer(CALLBACK(GLOBAL_PROC, /proc/to_chat, L, "You have been sent to the Thunderdome."), 5 SECONDS) log_admin("[key_name(usr)] has sent [key_name(L)] to the thunderdome. (Admin.)") message_admins("[key_name_admin(usr)] has sent [key_name_admin(L)] to the thunderdome. (Admin.)") @@ -835,8 +832,7 @@ L.Unconscious(100) sleep(5) L.forceMove(pick(GLOB.tdomeobserve)) - spawn(50) - to_chat(L, "You have been sent to the Thunderdome.") + addtimer(CALLBACK(GLOBAL_PROC, /proc/to_chat, L, "You have been sent to the Thunderdome."), 5 SECONDS) log_admin("[key_name(usr)] has sent [key_name(L)] to the thunderdome. (Observer.)") message_admins("[key_name_admin(usr)] has sent [key_name_admin(L)] to the thunderdome. (Observer.)") diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 762d66a5cfc..d8985391e63 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -245,8 +245,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) if(ishuman(M)) log_admin("[key_name(src)] has robotized [M.key].") var/mob/living/carbon/human/H = M - spawn(0) - H.Robotize() + INVOKE_ASYNC(H, /mob/living/carbon/human.proc/Robotize) else alert("Invalid mob") @@ -283,8 +282,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) return log_admin("[key_name(src)] has animalized [M.key].") - spawn(0) - M.Animalize() + INVOKE_ASYNC(M, /mob.proc/Animalize) /client/proc/makepAI(turf/T in GLOB.mob_list) diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index 500f6f03053..c7140087e68 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -100,8 +100,7 @@ Code: code = new_code if(href_list["send"]) - spawn( 0 ) - signal() + INVOKE_ASYNC(src, .proc/signal) if(usr) attack_self(usr) 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 8ad990b6095..97eba613358 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 @@ -167,13 +167,10 @@ if("set_external_pressure" in signal.data) external_pressure_bound = CLAMP(text2num(signal.data["set_external_pressure"]),0,ONE_ATMOSPHERE*50) - if("status" in signal.data) - spawn(2) - broadcast_status() - return //do not update_icon - spawn(2) - broadcast_status() - update_icon() + addtimer(CALLBACK(src, .proc/broadcast_status), 2) + + if(!("status" in signal.data)) //do not update_icon + update_icon() /obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume name = "large dual-port air vent" 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 f0c744d6823..436e80ae018 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm @@ -127,15 +127,10 @@ var/datum/gas_mixture/air_contents = airs[1] volume_rate = CLAMP(number, 0, air_contents.volume) - if("status" in signal.data) - spawn(2) - broadcast_status() - return //do not update_icon + addtimer(CALLBACK(src, .proc/broadcast_status), 2) - spawn(2) - broadcast_status() - - update_icon() + if(!("status" in signal.data)) //do not update_icon + update_icon() /obj/machinery/atmospherics/components/unary/outlet_injector/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ diff --git a/code/modules/clothing/suits/reactive_armour.dm b/code/modules/clothing/suits/reactive_armour.dm index 5a15cd1089e..fec931d54e9 100644 --- a/code/modules/clothing/suits/reactive_armour.dm +++ b/code/modules/clothing/suits/reactive_armour.dm @@ -141,8 +141,7 @@ E.Goto(owner, E.move_to_delay, E.minimum_distance) owner.alpha = 0 owner.visible_message("[owner] is hit by [attack_text] in the chest!") //We pretend to be hit, since blocking it would stop the message otherwise - spawn(40) - owner.alpha = initial(owner.alpha) + addtimer(VARSET_CALLBACK(owner, alpha, initial(owner.alpha)), 4 SECONDS) reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration return 1 diff --git a/code/modules/hydroponics/grown/tomato.dm b/code/modules/hydroponics/grown/tomato.dm index f4ca793be99..a399c074cba 100644 --- a/code/modules/hydroponics/grown/tomato.dm +++ b/code/modules/hydroponics/grown/tomato.dm @@ -134,13 +134,16 @@ to_chat(user, "You begin to awaken the Killer Tomato...") awakening = 1 - spawn(30) - if(!QDELETED(src)) - var/mob/living/simple_animal/hostile/killertomato/K = new /mob/living/simple_animal/hostile/killertomato(get_turf(src.loc)) - K.maxHealth += round(seed.endurance / 3) - K.melee_damage_lower += round(seed.potency / 10) - K.melee_damage_upper += round(seed.potency / 10) - K.move_to_delay -= round(seed.production / 50) - K.health = K.maxHealth - K.visible_message("The Killer Tomato growls as it suddenly awakens.") - qdel(src) + addtimer(CALLBACK(src, .proc/awaken), 3 SECONDS) + +/obj/item/reagent_containers/food/snacks/grown/tomato/killer/proc/awaken() + if(QDELETED(src)) + return + var/mob/living/simple_animal/hostile/killertomato/K = new /mob/living/simple_animal/hostile/killertomato(get_turf(src.loc)) + K.maxHealth += round(seed.endurance / 3) + K.melee_damage_lower += round(seed.potency / 10) + K.melee_damage_upper += round(seed.potency / 10) + K.move_to_delay -= round(seed.production / 50) + K.health = K.maxHealth + K.visible_message("The Killer Tomato growls as it suddenly awakens.") + qdel(src) diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index 85dab7a91a0..89a8ff447af 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -478,8 +478,7 @@ Pass a positive integer as an argument to override a bot's default speed. if(step_count >= 1 && tries < BOT_STEP_MAX_RETRIES) for(var/step_number = 0, step_number < step_count,step_number++) - spawn(BOT_STEP_DELAY*step_number) - bot_step(dest) + addtimer(CALLBACK(src, .proc/bot_step, dest), BOT_STEP_DELAY*step_number) else return FALSE return TRUE diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm index 9fc83576988..fd66395d044 100644 --- a/code/modules/mob/living/simple_animal/bot/construction.dm +++ b/code/modules/mob/living/simple_animal/bot/construction.dm @@ -258,11 +258,10 @@ var/healthanalyzer = /obj/item/healthanalyzer var/firstaid = /obj/item/storage/firstaid -/obj/item/bot_assembly/medbot/Initialize() - . = ..() - spawn(5) - if(skin) - add_overlay("kit_skin_[skin]") +/obj/item/bot_assembly/medbot/proc/set_skin(skin) + src.skin = skin + if(skin) + add_overlay("kit_skin_[skin]") /obj/item/bot_assembly/medbot/attackby(obj/item/W, mob/user, params) ..() diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm index 617963b8dcb..19ac3f75c77 100644 --- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm +++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm @@ -362,8 +362,7 @@ Auto Patrol[]"}, playsound(src, pick('sound/voice/ed209_20sec.ogg', 'sound/voice/edplaceholder.ogg'), 50, FALSE) visible_message("[src] points at [C.name]!") mode = BOT_HUNT - spawn(0) - handle_automated_action() // ensure bot quickly responds to a perp + INVOKE_ASYNC(src, .proc/handle_automated_action) // ensure bot quickly responds to a perp break else continue @@ -542,8 +541,7 @@ Auto Patrol[]"}, /mob/living/simple_animal/bot/ed209/proc/stun_attack(mob/living/carbon/C) playsound(src, 'sound/weapons/egloves.ogg', 50, TRUE, -1) icon_state = "[lasercolor]ed209-c" - spawn(2) - icon_state = "[lasercolor]ed209[on]" + addtimer(VARSET_CALLBACK(src, icon_state, "[lasercolor]ed209[on]"), 2) var/threat = 5 C.Paralyze(100) C.stuttering = 5 diff --git a/code/modules/mob/living/simple_animal/bot/floorbot.dm b/code/modules/mob/living/simple_animal/bot/floorbot.dm index 8b344ddaa6a..fd49d5c4be3 100644 --- a/code/modules/mob/living/simple_animal/bot/floorbot.dm +++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm @@ -239,10 +239,7 @@ mode = BOT_REPAIRING F.ReplaceWithLattice() audible_message("[src] makes an excited booping sound.") - spawn(5) - anchored = FALSE - mode = BOT_IDLE - target = null + addtimer(CALLBACK(src, .proc/go_idle), 0.5 SECONDS) path = list() return if(path.len == 0) @@ -266,6 +263,11 @@ oldloc = loc +/mob/living/simple_animal/bot/floorbot/proc/go_idle() + anchored = FALSE + mode = BOT_IDLE + target = null + /mob/living/simple_animal/bot/floorbot/proc/is_hull_breach(turf/t) //Ignore space tiles not considered part of a structure, also ignores shuttle docking areas. var/area/t_area = get_area(t) if(t_area && (t_area.name == "Space" || findtext(t_area.name, "huttle"))) diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 441e36e5465..bd88ccc168e 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -448,10 +448,8 @@ process_bot() num_steps-- if(mode != BOT_IDLE) - spawn(0) - for(var/i=num_steps,i>0,i--) - sleep(2) - process_bot() + var/process_timer = addtimer(CALLBACK(src, .proc/process_bot), 2, TIMER_LOOP|TIMER_STOPPABLE) + addtimer(CALLBACK(GLOBAL_PROC, /proc/deltimer, process_timer), (num_steps*2) + 1) /mob/living/simple_animal/bot/mulebot/proc/process_bot() if(!on || client) @@ -515,11 +513,7 @@ buzz(SIGH) mode = BOT_WAIT_FOR_NAV blockcount = 0 - spawn(20) - calc_path(avoid=next) - if(path.len > 0) - buzz(DELIGHT) - mode = BOT_BLOCKED + addtimer(CALLBACK(src, .proc/process_blocked, next), 2 SECONDS) return return else @@ -532,18 +526,26 @@ if(BOT_NAV) // calculate new path mode = BOT_WAIT_FOR_NAV - spawn(0) - calc_path() + INVOKE_ASYNC(src, .proc/process_nav) - if(path.len > 0) - blockcount = 0 - mode = BOT_BLOCKED - buzz(DELIGHT) +/mob/living/simple_animal/bot/mulebot/proc/process_blocked(turf/next) + calc_path(avoid=next) + if(path.len > 0) + buzz(DELIGHT) + mode = BOT_BLOCKED - else - buzz(SIGH) +/mob/living/simple_animal/bot/mulebot/proc/process_nav() + calc_path() - mode = BOT_NO_ROUTE + if(path.len > 0) + blockcount = 0 + mode = BOT_BLOCKED + buzz(DELIGHT) + + else + buzz(SIGH) + + mode = BOT_NO_ROUTE // calculates a path to the current destination // given an optional turf to avoid @@ -573,11 +575,13 @@ /mob/living/simple_animal/bot/mulebot/proc/start_home() if(!on) return - spawn(0) - set_destination(home_destination) - mode = BOT_BLOCKED + INVOKE_ASYNC(src, .proc/do_start_home) update_icon() +/mob/living/simple_animal/bot/mulebot/proc/do_start_home() + set_destination(home_destination) + mode = BOT_BLOCKED + // called when bot reaches current target /mob/living/simple_animal/bot/mulebot/proc/at_target() if(!reached_target) diff --git a/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm b/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm index b42627b2bbd..4294706cd3f 100644 --- a/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm +++ b/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm @@ -241,8 +241,7 @@ addtimer(CALLBACK(mecha.overload_action, /datum/action/innate/mecha/mech_defense_mode.proc/Activate, FALSE), 100) //10 seconds of speeeeed, then toggle off retreat_distance = 50 - spawn(100) - retreat_distance = 0 + addtimer(VARSET_CALLBACK(src, retreat_distance, 0), 10 SECONDS) @@ -292,4 +291,4 @@ if(mecha) walk_to(mecha, target, minimum_distance, mecha.step_in) else - ..() \ No newline at end of file + ..() diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm index 35f82beeead..33f51e19a28 100644 --- a/code/modules/mob/living/simple_animal/slime/life.dm +++ b/code/modules/mob/living/simple_animal/slime/life.dm @@ -66,9 +66,8 @@ if(Target in view(1,src)) if(!CanFeedon(Target)) //If they're not able to be fed upon, ignore them. if(!Atkcool) - Atkcool = 1 - spawn(45) - Atkcool = 0 + Atkcool = TRUE + addtimer(VARSET_CALLBACK(src, Atkcool, FALSE), 4.5 SECONDS) if(Target.Adjacent(src)) Target.attack_slime(src) @@ -77,9 +76,8 @@ if(Target.client && Target.health >= 20) if(!Atkcool) - Atkcool = 1 - spawn(45) - Atkcool = 0 + Atkcool = TRUE + addtimer(VARSET_CALLBACK(src, Atkcool, FALSE), 4.5 SECONDS) if(Target.Adjacent(src)) Target.attack_slime(src) diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index eb7695a3e24..cd5b9301a9f 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -222,9 +222,8 @@ if(nutrition <= get_hunger_nutrition() && !Atkcool) if (is_adult || prob(5)) O.attack_slime(src) - Atkcool = 1 - spawn(45) - Atkcool = 0 + Atkcool = TRUE + addtimer(VARSET_CALLBACK(src, Atkcool, FALSE), 4.5 SECONDS) /mob/living/simple_animal/slime/Process_Spacemove(movement_dir = 0) return 2