diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm
index 7fa8c2db77..3b08375d0d 100644
--- a/code/__DEFINES/combat.dm
+++ b/code/__DEFINES/combat.dm
@@ -20,6 +20,7 @@
#define TOXLOSS 4
#define OXYLOSS 8
#define SHAME 16
+#define MANUAL_SUICIDE 32 //suicide_act will do the actual killing.
//Citadel code
#define AROUSAL 32
diff --git a/code/datums/explosion.dm b/code/datums/explosion.dm
index b9ea00da22..4ba1627190 100644
--- a/code/datums/explosion.dm
+++ b/code/datums/explosion.dm
@@ -365,10 +365,13 @@ GLOBAL_LIST_EMPTY(explosions)
else
continue
- sleep(100)
- for(var/turf/T in wipe_colours)
- T.color = null
- T.maptext = ""
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/wipe_color_and_text, wipe_colours), 100)
+
+/proc/wipe_color_and_text(list/atom/wiping)
+ for(var/i in wiping)
+ var/atom/A = i
+ A.color = null
+ A.maptext = ""
/proc/dyn_explosion(turf/epicenter, power, flash_range, adminlog = 1, ignorecap = 1, flame_range = 0 ,silent = 0, smoke = 1)
if(!power)
diff --git a/code/game/gamemodes/miniantags/abduction/gland.dm b/code/game/gamemodes/miniantags/abduction/gland.dm
index 0458690a40..a9ca2ef802 100644
--- a/code/game/gamemodes/miniantags/abduction/gland.dm
+++ b/code/game/gamemodes/miniantags/abduction/gland.dm
@@ -241,11 +241,20 @@
/obj/item/organ/heart/gland/plasma/activate()
to_chat(owner, "You feel bloated.")
+<<<<<<< HEAD
sleep(150)
if(!owner) return
to_chat(owner, "A massive stomachache overcomes you.")
sleep(50)
if(!owner) return
+=======
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, owner, "A massive stomachache overcomes you."), 150)
+ addtimer(CALLBACK(src, .proc/vomit_plasma), 200)
+
+/obj/item/organ/heart/gland/plasma/proc/vomit_plasma()
+ if(!owner)
+ return
+>>>>>>> b83d777... Removes a bunch of sleeps/spawns and makes a few booleans defines (#31553)
owner.visible_message("[owner] vomits a cloud of plasma!")
var/turf/open/T = get_turf(owner)
if(istype(T))
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/pad.dm b/code/game/gamemodes/miniantags/abduction/machinery/pad.dm
index 71ec2859ce..dff2fe812e 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/pad.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/pad.dm
@@ -25,21 +25,24 @@
new /obj/effect/temp_visual/dir_setting/ninja(get_turf(target), target.dir)
Warp(target)
-/obj/machinery/abductor/pad/proc/MobToLoc(place,mob/living/target)
- new /obj/effect/temp_visual/teleport_abductor(place)
- sleep(80)
+/obj/machinery/abductor/pad/proc/doMobToLoc(place, atom/movable/target)
flick("alien-pad", src)
target.forceMove(place)
new /obj/effect/temp_visual/dir_setting/ninja(get_turf(target), target.dir)
-/obj/machinery/abductor/pad/proc/PadToLoc(place)
+/obj/machinery/abductor/pad/proc/MobToLoc(place,mob/living/target)
new /obj/effect/temp_visual/teleport_abductor(place)
- sleep(80)
+ addtimer(CALLBACK(src, .proc/doMobToLoc, place, target), 80)
+
+/obj/machinery/abductor/pad/proc/doPadToLoc(place)
flick("alien-pad", src)
for(var/mob/living/target in get_turf(src))
target.forceMove(place)
new /obj/effect/temp_visual/dir_setting/ninja(get_turf(target), target.dir)
+/obj/machinery/abductor/pad/proc/PadToLoc(place)
+ new /obj/effect/temp_visual/teleport_abductor(place)
+ addtimer(CALLBACK(src, .proc/doPadToLoc, place), 80)
/obj/effect/temp_visual/teleport_abductor
name = "Huh"
diff --git a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm
index 98102984ee..7bf3535032 100644
--- a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm
+++ b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm
@@ -205,20 +205,20 @@
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(4, 0, L)
s.start()
- new /obj/effect/temp_visual/revenant(L.loc)
- sleep(20)
- if(!L.on) //wait, wait, don't shock me
- return
- flick("[L.base_state]2", L)
- for(var/mob/living/carbon/human/M in view(shock_range, L))
- if(M == user)
- continue
- L.Beam(M,icon_state="purple_lightning",time=5)
- M.electrocute_act(shock_damage, L, safety=1)
- var/datum/effect_system/spark_spread/z = new /datum/effect_system/spark_spread
- z.set_up(4, 0, M)
- z.start()
- playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1)
+ new /obj/effect/temp_visual/revenant(get_turf(L))
+ addtimer(CALLBACK(src, .proc/overload_shock, L, user), 20)
+
+/obj/effect/proc_holder/spell/aoe_turf/revenant/overload/proc/overload_shock(obj/machinery/light/L, mob/user)
+ if(!L.on) //wait, wait, don't shock me
+ return
+ flick("[L.base_state]2", L)
+ for(var/mob/living/carbon/human/M in view(shock_range, L))
+ if(M == user)
+ continue
+ L.Beam(M,icon_state="purple_lightning",time=5)
+ M.electrocute_act(shock_damage, L, safety=1)
+ do_sparks(4, FALSE, M)
+ playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1)
//Defile: Corrupts nearby stuff, unblesses floor tiles.
/obj/effect/proc_holder/spell/aoe_turf/revenant/defile
diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm
index 8cae25eb38..0251d17398 100644
--- a/code/game/gamemodes/nuclear/nuclearbomb.dm
+++ b/code/game/gamemodes/nuclear/nuclearbomb.dm
@@ -434,14 +434,15 @@
sound_to_playing_players('sound/machines/alarm.ogg')
if(SSticker && SSticker.mode)
SSticker.roundend_check_paused = TRUE
- sleep(100)
+ addtimer(CALLBACK(src, .proc/actually_explode), 100)
+/obj/machinery/nuclearbomb/proc/actually_explode()
if(!core)
Cinematic(CINEMATIC_NUKE_NO_CORE,world)
SSticker.roundend_check_paused = FALSE
return
- GLOB.enter_allowed = 0
+ GLOB.enter_allowed = FALSE
var/off_station = 0
var/turf/bomb_location = get_turf(src)
@@ -533,9 +534,9 @@ This is here to make the tiles around the station mininuke change when it's arme
H.nuke_disk = null
return
user.visible_message("[user] captures [src]!", "You've got the disk! Defend it with your life!")
- loc = H
+ forceMove(H)
H.nuke_disk = src
- return 1
+ return TRUE
return ..()
/obj/item/disk/nuclear/Destroy(force=FALSE)
@@ -547,20 +548,13 @@ This is here to make the tiles around the station mininuke change when it's arme
/obj/item/disk/nuclear/suicide_act(mob/user)
user.visible_message("[user] is going delta! It looks like [user.p_theyre()] trying to commit suicide!")
playsound(user.loc, 'sound/machines/alarm.ogg', 50, -1, 1)
- var/end_time = world.time + 100
- var/newcolor = "#00FF00"
- while(world.time < end_time)
- if(!user)
- return
- if(newcolor == "#FF0000")
- newcolor = "#00FF00"
- else
- newcolor = "#FF0000"
- user.add_atom_colour(newcolor, ADMIN_COLOUR_PRIORITY)
- sleep(1)
- user.remove_atom_colour(ADMIN_COLOUR_PRIORITY)
- user.visible_message("[user] was destroyed by the nuclear blast!")
- return OXYLOSS
+ for(var/i in 1 to 100)
+ addtimer(CALLBACK(user, /atom/proc/add_atom_colour, (i % 2)? "#00FF00" : "#FF0000", ADMIN_COLOUR_PRIORITY), i)
+ addtimer(CALLBACK(user, /atom/proc/remove_atom_colour, ADMIN_COLOUR_PRIORITY), 101)
+ addtimer(CALLBACK(user, /atom/proc/visible_message, "[user] was destroyed by the nuclear blast!"), 101)
+ addtimer(CALLBACK(user, /mob/living/proc/adjustOxyLoss, 200), 101)
+ addtimer(CALLBACK(user, /mob/proc/death, 0), 101)
+ return MANUAL_SUICIDE
/obj/item/disk/fakenucleardisk
name = "cheap plastic imitation of the nuclear authentication disk"
diff --git a/code/modules/client/verbs/suicide.dm b/code/modules/client/verbs/suicide.dm
index cf0f9fe023..f4ebeda886 100644
--- a/code/modules/client/verbs/suicide.dm
+++ b/code/modules/client/verbs/suicide.dm
@@ -12,7 +12,7 @@
if(!canSuicide())
return
if(confirm == "Yes")
- suiciding = 1
+ suiciding = TRUE
log_game("[key_name(src)] (job: [job ? "[job]" : "None"]) committed suicide at [get_area(src)].")
message_admins("[key_name(src)] (job: [job ? "[job]" : "None"]) committed suicide at [get_area(src)].")
var/obj/item/held_item = get_active_held_item()
@@ -21,7 +21,7 @@
if(damagetype)
if(damagetype & SHAME)
adjustStaminaLoss(200)
- suiciding = 0
+ suiciding = FALSE
return
var/damage_mod = 0
for(var/T in list(BRUTELOSS, FIRELOSS, TOXLOSS, OXYLOSS))
@@ -41,11 +41,14 @@
if(damagetype & OXYLOSS)
adjustOxyLoss(200/damage_mod)
+ if(damagetype & MANUAL_SUICIDE) //Assume the object will handle the death.
+ return
+
//If something went wrong, just do normal oxyloss
if(!(damagetype & (BRUTELOSS | FIRELOSS | TOXLOSS | OXYLOSS) ))
adjustOxyLoss(max(200 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
- death(0)
+ death(FALSE)
return
var/suicide_message = pick("[src] is attempting to bite [p_their()] tongue off! It looks like [p_theyre()] trying to commit suicide.", \
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index d0ff023365..8030e97c1e 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -19,6 +19,7 @@
var/list/software = list()
var/userDNA // The DNA string of our assigned user
var/obj/item/device/paicard/card // The card we inhabit
+ var/hacking = FALSE //Are we hacking a door?
var/speakStatement = "states"
var/speakExclamation = "declares"
@@ -121,6 +122,29 @@
emittersemicd = TRUE
addtimer(CALLBACK(src, .proc/emittercool), 600)
+/mob/living/silicon/pai/Life()
+ if(hacking)
+ process_hack()
+ return ..()
+
+/mob/living/silicon/pai/proc/process_hack()
+
+ if(cable && cable.machine && istype(cable.machine, /obj/machinery/door) && cable.machine == hackdoor && get_dist(src, hackdoor) <= 1)
+ hackprogress = Clamp(hackprogress + 4, 0, 100)
+ else
+ temp = "Door Jack: Connection to airlock has been lost. Hack aborted."
+ hackprogress = 0
+ hacking = FALSE
+ hackdoor = null
+ return
+ if(screen == "doorjack" && subscreen == 0) // Update our view, if appropriate
+ paiInterface()
+ if(hackprogress >= 100)
+ hackprogress = 0
+ var/obj/machinery/door/D = cable.machine
+ D.open()
+ hacking = FALSE
+
/mob/living/silicon/pai/make_laws()
laws = new /datum/ai_laws/pai()
return TRUE
diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm
index 5d301776c6..8c05958cea 100644
--- a/code/modules/mob/living/silicon/pai/software.dm
+++ b/code/modules/mob/living/silicon/pai/software.dm
@@ -28,44 +28,44 @@
var/dat = ""
var/left_part = ""
var/right_part = softwareMenu()
- src.set_machine(src)
+ set_machine(src)
if(temp)
left_part = temp
- else if(src.stat == DEAD) // Show some flavor text if the pAI is dead
+ else if(stat == DEAD) // Show some flavor text if the pAI is dead
left_part = "�Rr�R �a�� ��Rr����o�"
right_part = "
Program index hash not found
"
else
- switch(src.screen) // Determine which interface to show here
+ switch(screen) // Determine which interface to show here
if("main")
left_part = ""
if("directives")
- left_part = src.directives()
+ left_part = directives()
if("pdamessage")
- left_part = src.pdamessage()
+ left_part = pdamessage()
if("buy")
left_part = downloadSoftware()
if("manifest")
- left_part = src.softwareManifest()
+ left_part = softwareManifest()
if("medicalrecord")
- left_part = src.softwareMedicalRecord()
+ left_part = softwareMedicalRecord()
if("securityrecord")
- left_part = src.softwareSecurityRecord()
+ left_part = softwareSecurityRecord()
if("translator")
- left_part = src.softwareTranslator()
+ left_part = softwareTranslator()
if("atmosensor")
- left_part = src.softwareAtmo()
+ left_part = softwareAtmo()
if("securityhud")
- left_part = src.facialRecognition()
+ left_part = facialRecognition()
if("medicalhud")
- left_part = src.medicalAnalysis()
+ left_part = medicalAnalysis()
if("doorjack")
- left_part = src.softwareDoor()
+ left_part = softwareDoor()
if("camerajack")
- left_part = src.softwareCamera()
+ left_part = softwareCamera()
if("signaller")
- left_part = src.softwareSignal()
+ left_part = softwareSignal()
//usr << browse_rsc('windowbak.png') // This has been moved to the mob's Login() proc
@@ -119,16 +119,16 @@
var/soft = href_list["software"]
var/sub = href_list["sub"]
if(soft)
- src.screen = soft
+ screen = soft
if(sub)
- src.subscreen = text2num(sub)
+ subscreen = text2num(sub)
switch(soft)
// Purchasing new software
if("buy")
if(subscreen == 1)
var/target = href_list["buy"]
if(available_software.Find(target) && !software.Find(target))
- var/cost = src.available_software[target]
+ var/cost = available_software[target]
if(ram >= cost)
software.Add(target)
ram -= cost
@@ -259,17 +259,17 @@
// this is PERMAMENT.
if("doorjack")
if(href_list["jack"])
- if(src.cable && src.cable.machine)
- src.hackdoor = src.cable.machine
- src.hackloop()
+ if(cable && cable.machine)
+ hackdoor = cable.machine
+ hackloop()
if(href_list["cancel"])
- src.hackdoor = null
+ hackdoor = null
if(href_list["cable"])
- var/turf/T = get_turf(src.loc)
+ var/turf/T = get_turf(loc)
cable = new /obj/item/pai_cable(T)
- T.visible_message("A port on [src] opens to reveal [src.cable], which promptly falls to the floor.", "You hear the soft click of something light and hard falling to the ground.")
- //src.updateUsrDialog() We only need to account for the single mob this is intended for, and he will *always* be able to call this window
- src.paiInterface() // So we'll just call the update directly rather than doing some default checks
+ T.visible_message("A port on [src] opens to reveal [cable], which promptly falls to the floor.", "You hear the soft click of something light and hard falling to the ground.")
+ //updateUsrDialog() We only need to account for the single mob this is intended for, and he will *always* be able to call this window
+ paiInterface() // So we'll just call the update directly rather than doing some default checks
return
// MENUS
@@ -287,7 +287,7 @@
// Basic
dat += "Basic
"
- for(var/s in src.software)
+ for(var/s in software)
if(s == "digital messenger")
dat += "Digital Messenger
"
if(s == "crew manifest")
@@ -304,15 +304,15 @@
// Advanced
dat += "Advanced
"
- for(var/s in src.software)
+ for(var/s in software)
if(s == "atmosphere sensor")
dat += "Atmospheric Sensor
"
if(s == "heartbeat sensor")
dat += "Heartbeat Sensor
"
if(s == "security HUD")
- dat += "Facial Recognition Suite[(src.secHUD) ? " On" : " Off"]
"
+ dat += "Facial Recognition Suite[(secHUD) ? " On" : " Off"]
"
if(s == "medical HUD")
- dat += "Medical Analysis Suite[(src.medHUD) ? " On" : " Off"]
"
+ dat += "Medical Analysis Suite[(medHUD) ? " On" : " Off"]
"
if(s == "universal translator")
var/translator_on = (flags_2 & OMNITONGUE_2)
dat += "Universal Translator[translator_on ? " On" : " Off"]
"
@@ -333,12 +333,12 @@
var/dat = ""
dat += "CentCom pAI Module Subversion Network
"
- dat += "Remaining Available Memory: [src.ram]
"
+ dat += "Remaining Available Memory: [ram]
"
dat += "Trunks available for checkout
"
for(var/s in available_software)
if(!software.Find(s))
- var/cost = src.available_software[s]
+ var/cost = available_software[s]
var/displayName = uppertext(s)
dat += "[displayName] ([cost])
"
else
@@ -351,12 +351,12 @@
/mob/living/silicon/pai/proc/directives()
var/dat = ""
- dat += "[(src.master) ? "Your master: [src.master] ([src.master_dna])" : "You are bound to no one."]"
+ dat += "[(master) ? "Your master: [master] ([master_dna])" : "You are bound to no one."]"
dat += "
"
dat += "Request carrier DNA sample
"
dat += "
Directives
"
dat += "Prime Directive
"
- dat += " [src.laws.zeroth]
"
+ dat += " [laws.zeroth]
"
dat += "Supplemental Directives
"
for(var/slaws in laws.supplied)
dat += " [slaws]
"
@@ -398,14 +398,14 @@
Frequency:
-
-
- [format_frequency(src.sradio.frequency)]
+ [format_frequency(sradio.frequency)]
+
+
Code:
-
-
- [src.sradio.code]
+ [sradio.code]
+
+
@@ -476,7 +476,7 @@
/mob/living/silicon/pai/proc/facialRecognition()
var/dat = {"Facial Recognition Suite
When enabled, this package will scan all viewable faces and compare them against the known criminal database, providing real-time graphical data about any detected persons of interest.
- The package is currently [ (src.secHUD) ? "en" : "dis" ]abled.
+ The package is currently [ (secHUD) ? "en" : "dis" ]abled.
Toggle Package
"}
return dat
@@ -484,16 +484,16 @@
// Medical HUD
/mob/living/silicon/pai/proc/medicalAnalysis()
var/dat = ""
- if(src.subscreen == 0)
+ if(subscreen == 0)
dat += {"Medical Analysis Suite
Visual Status Overlay
When enabled, this package will scan all nearby crewmembers' vitals and provide real-time graphical data about their state of health.
- The suite is currently [ (src.medHUD) ? "en" : "dis" ]abled.
+ The suite is currently [ (medHUD) ? "en" : "dis" ]abled.
Toggle Suite
Host Bioscan
"}
- if(src.subscreen == 1)
+ if(subscreen == 1)
dat += {"Medical Analysis Suite
Host Bioscan
"}
@@ -501,8 +501,8 @@
if(!isliving(M))
while(!isliving(M))
if(isturf(M))
- src.temp = "Error: No biological host found.
"
- src.subscreen = 0
+ temp = "Error: No biological host found.
"
+ subscreen = 0
return dat
M = M.loc
dat += {"Bioscan Results for [M]:
"
@@ -529,7 +529,7 @@
/mob/living/silicon/pai/proc/softwareAtmo()
var/dat = "Atmospheric Sensor"
- var/turf/T = get_turf(src.loc)
+ var/turf/T = get_turf(loc)
if (isnull(T))
dat += "Unable to obtain a reading.
"
else
@@ -556,14 +556,14 @@
var/dat = "Camera Jack
"
dat += "Cable status : "
- if(!src.cable)
+ if(!cable)
dat += "Retracted
"
return dat
- if(!src.cable.machine)
+ if(!cable.machine)
dat += "Extended
"
return dat
- var/obj/machinery/machine = src.cable.machine
+ var/obj/machinery/machine = cable.machine
dat += "Connected
"
if(!istype(machine, /obj/machinery/camera))
@@ -574,55 +574,37 @@
/mob/living/silicon/pai/proc/softwareDoor()
var/dat = "Airlock Jack
"
dat += "Cable status : "
- if(!src.cable)
+ if(!cable)
dat += "Retracted
"
dat += "Extend Cable
"
return dat
- if(!src.cable.machine)
+ if(!cable.machine)
dat += "Extended
"
return dat
- var/obj/machinery/machine = src.cable.machine
+ var/obj/machinery/machine = cable.machine
dat += "Connected
"
if(!istype(machine, /obj/machinery/door))
dat += "Connected device's firmware does not appear to be compatible with Airlock Jack protocols.
"
return dat
// var/obj/machinery/airlock/door = machine
- if(!src.hackdoor)
+ if(!hackdoor)
dat += "Begin Airlock Jacking
"
else
- dat += "Jack in progress... [src.hackprogress]% complete.
"
+ dat += "Jack in progress... [hackprogress]% complete.
"
dat += "Cancel Airlock Jack
"
- //src.hackdoor = machine
- //src.hackloop()
return dat
// Door Jack - supporting proc
/mob/living/silicon/pai/proc/hackloop()
- var/turf/T = get_turf(src.loc)
+ var/turf/T = get_turf(src)
for(var/mob/living/silicon/ai/AI in GLOB.player_list)
if(T.loc)
to_chat(AI, "Network Alert: Brute-force encryption crack in progress in [T.loc].")
else
to_chat(AI, "Network Alert: Brute-force encryption crack in progress. Unable to pinpoint location.")
- while(src.hackprogress < 100)
- if(src.cable && src.cable.machine && istype(src.cable.machine, /obj/machinery/door) && src.cable.machine == src.hackdoor && get_dist(src, src.hackdoor) <= 1)
- hackprogress += rand(1, 10)
- else
- src.temp = "Door Jack: Connection to airlock has been lost. Hack aborted."
- hackprogress = 0
- src.hackdoor = null
- return
- if(hackprogress >= 100) // This is clunky, but works. We need to make sure we don't ever display a progress greater than 100,
- hackprogress = 100 // but we also need to reset the progress AFTER it's been displayed
- if(src.screen == "doorjack" && src.subscreen == 0) // Update our view, if appropriate
- src.paiInterface()
- if(hackprogress >= 100)
- src.hackprogress = 0
- var/obj/machinery/door/D = cable.machine
- D.open()
- sleep(50) // Update every 5 seconds
+ hacking = TRUE
// Digital Messenger
/mob/living/silicon/pai/proc/pdamessage()
@@ -635,7 +617,7 @@
dat += ""
if(!pda.toff)
for (var/obj/item/device/pda/P in sortNames(get_viewable_pdas()))
- if (P == src.pda)
+ if (P == pda)
continue
dat += "- [P]"
dat += "
"
diff --git a/code/modules/ninja/suit/ninjaDrainAct.dm b/code/modules/ninja/suit/ninjaDrainAct.dm
index 31e6161e4e..4679b5ffbd 100644
--- a/code/modules/ninja/suit/ninjaDrainAct.dm
+++ b/code/modules/ninja/suit/ninjaDrainAct.dm
@@ -114,6 +114,11 @@ They *could* go in their appropriate files, but this is supposed to be modular
corrupt()
update_icon()
+/obj/machinery/proc/AI_notify_hack()
+ var/turf/location = get_turf(src)
+ var/alertstr = "Network Alert: Hacking attempt detected[location?" in [location]":". Unable to pinpoint location"]."
+ for(var/mob/living/silicon/ai/AI in GLOB.player_list)
+ to_chat(AI, alertstr)
//RDCONSOLE//
/obj/machinery/computer/rdconsole/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G)
@@ -123,10 +128,7 @@ They *could* go in their appropriate files, but this is supposed to be modular
. = DRAIN_RD_HACK_FAILED
to_chat(H, "Hacking \the [src]...")
- spawn(0)
- var/turf/location = get_turf(H)
- for(var/mob/living/silicon/ai/AI in GLOB.player_list)
- to_chat(AI, "Network Alert: Hacking attempt detected[location?" in [location]":". Unable to pinpoint location"].")
+ AI_notify_hack()
if(files && files.known_tech.len)
for(var/datum/tech/current_data in S.stored_research)
@@ -145,7 +147,6 @@ They *could* go in their appropriate files, but this is supposed to be modular
to_chat(H, "Data analyzed. Process finished.")
-
//RD SERVER//
//Shamelessly copypasted from above, since these two used to be the same proc, but with MANY colon operators
/obj/machinery/r_n_d/server/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G)
@@ -155,10 +156,7 @@ They *could* go in their appropriate files, but this is supposed to be modular
. = DRAIN_RD_HACK_FAILED
to_chat(H, "Hacking \the [src]...")
- spawn(0)
- var/turf/location = get_turf(H)
- for(var/mob/living/silicon/ai/AI in GLOB.player_list)
- to_chat(AI, "Network Alert: Hacking attempt detected[location?" in [location]":". Unable to pinpoint location"].")
+ AI_notify_hack()
if(files && files.known_tech.len)
for(var/datum/tech/current_data in S.stored_research)
diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm
index 5abf1b7998..ae6751f526 100644
--- a/code/modules/paperwork/paper.dm
+++ b/code/modules/paperwork/paper.dm
@@ -108,15 +108,16 @@
user.visible_message("[user] scratches a grid on [user.p_their()] wrist with the paper! It looks like [user.p_theyre()] trying to commit sudoku...")
return (BRUTELOSS)
+/obj/item/paper/proc/reset_spamflag()
+ spam_flag = FALSE
/obj/item/paper/attack_self(mob/user)
user.examinate(src)
if(rigged && (SSevents.holidays && SSevents.holidays[APRIL_FOOLS]))
- if(spam_flag == 0)
- spam_flag = 1
+ if(!spam_flag)
+ spam_flag = TRUE
playsound(loc, 'sound/items/bikehorn.ogg', 50, 1)
- spawn(20)
- spam_flag = 0
+ addtimer(CALLBACK(src, .proc/reset_spamflag), 20)
/obj/item/paper/attack_ai(mob/living/silicon/ai/user)
diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm
index 2693b5e5cf..48b045f680 100644
--- a/code/modules/paperwork/photography.dm
+++ b/code/modules/paperwork/photography.dm
@@ -443,9 +443,12 @@
to_chat(user, "[pictures_left] photos left.")
icon_state = "camera_off"
on = FALSE
- spawn(64)
- icon_state = "camera"
- on = TRUE
+ addtimer(CALLBACK(src, .proc/cooldown), 64)
+
+/obj/item/device/camera/proc/cooldown()
+ set waitfor = FALSE
+ icon_state = "camera"
+ on = TRUE
/obj/item/device/camera/siliconcam/proc/toggle_camera_mode()
if(in_camera_mode)
diff --git a/code/modules/power/antimatter/control.dm b/code/modules/power/antimatter/control.dm
index 7863f6a52f..29e7b53cd2 100644
--- a/code/modules/power/antimatter/control.dm
+++ b/code/modules/power/antimatter/control.dm
@@ -260,17 +260,15 @@
if(AMS.processing)
AMS.shutdown_core()
AMS.control_unit = null
- spawn(10)
- AMS.controllerscan()
+ addtimer(CALLBACK(AMS, /obj/machinery/am_shielding.proc/controllerscan), 10)
linked_shielding = list()
-
else
for(var/obj/machinery/am_shielding/AMS in linked_shielding)
AMS.update_icon()
- spawn(20)
- shield_icon_delay = 0
- return
+ addtimer(CALLBACK(src, .proc/reset_shield_icon_delay), 20)
+/obj/machinery/power/am_control_unit/proc/reset_shield_icon_delay()
+ shield_icon_delay = 0
/obj/machinery/power/am_control_unit/proc/check_core_stability()
if(stored_core_stability_delay || linked_cores.len <= 0)
@@ -280,10 +278,10 @@
for(var/obj/machinery/am_shielding/AMS in linked_cores)
stored_core_stability += AMS.stability
stored_core_stability/=linked_cores.len
- spawn(40)
- stored_core_stability_delay = 0
- return
+ addtimer(CALLBACK(src, .proc/reset_stored_core_stability_delay), 40)
+/obj/machinery/power/am_control_unit/proc/reset_stored_core_stability_delay()
+ stored_core_stability_delay = 0
/obj/machinery/power/am_control_unit/interact(mob/user)
if((get_dist(src, user) > 1) || (stat & (BROKEN|NOPOWER)))
diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm
index 503eb88cd2..2353a9fcc1 100644
--- a/code/modules/power/cable.dm
+++ b/code/modules/power/cable.dm
@@ -399,6 +399,11 @@ By design, d1 is the smallest direction and d2 is the highest
if(PN.is_empty()) //can happen with machines made nodeless when smoothing cables
qdel(PN)
+/obj/structure/cable/proc/auto_propogate_cut_cable(obj/O)
+ if(O && !QDELETED(O))
+ var/datum/powernet/newPN = new()// creates a new powernet...
+ propagate_network(O, newPN)//... and propagates it to the other side of the cable
+
// cut the cable's powernet at this cable and updates the powergrid
/obj/structure/cable/proc/cut_cable_from_powernet(remove=TRUE)
var/turf/T1 = loc
@@ -426,10 +431,7 @@ By design, d1 is the smallest direction and d2 is the highest
loc = null
powernet.remove_cable(src) //remove the cut cable from its powernet
- spawn(0) //so we don't rebuild the network X times when singulo/explosion destroys a line of X cables
- if(O && !QDELETED(O))
- var/datum/powernet/newPN = new()// creates a new powernet...
- propagate_network(O, newPN)//... and propagates it to the other side of the cable
+ addtimer(CALLBACK(src, .proc/auto_propogate_cut_cable, O), 0) //so we don't rebuild the network X times when singulo/explosion destroys a line of X cables
// Disconnect machines connected to nodes
if(d1 == 0) // if we cut a node (O-X) cable
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 5933046064..65b8366487 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -207,7 +207,38 @@
/obj/item/gun/proc/recharge_newshot()
return
-/obj/item/gun/proc/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override, bonus_spread = 0)
+/obj/item/gun/proc/process_burst(mob/living/user, atom/target, message = TRUE, params, zone_override, sprd = 0, randomized_gun_spread = 0, randomized_bonus_spread = 0, rand_spr = 0, iteration = 0)
+ if(!user || !firing_burst)
+ firing_burst = FALSE
+ return FALSE
+ if(!issilicon(user))
+ if( iteration > 1 && !(user.is_holding(src))) //for burst firing
+ firing_burst = FALSE
+ return FALSE
+ if(chambered && chambered.BB)
+ if(randomspread)
+ sprd = round((rand() - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread))
+ else //Smart spread
+ sprd = round((((rand_spr/burst_size) * iteration) - (0.5 + (rand_spr * 0.25))) * (randomized_gun_spread + randomized_bonus_spread))
+
+ if(!chambered.fire_casing(target, user, params, ,suppressed, zone_override, sprd))
+ shoot_with_empty_chamber(user)
+ firing_burst = FALSE
+ return FALSE
+ else
+ if(get_dist(user, target) <= 1) //Making sure whether the target is in vicinity for the pointblank shot
+ shoot_live_shot(user, 1, target, message)
+ else
+ shoot_live_shot(user, 0, target, message)
+ else
+ shoot_with_empty_chamber(user)
+ firing_burst = FALSE
+ return FALSE
+ process_chamber()
+ update_icon()
+ return TRUE
+
+/obj/item/gun/proc/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = TRUE, params, zone_override, bonus_spread = 0)
add_fingerprint(user)
if(semicd)
@@ -221,34 +252,10 @@
var/randomized_bonus_spread = rand(0, bonus_spread)
if(burst_size > 1)
- firing_burst = 1
+ firing_burst = TRUE
for(var/i = 1 to burst_size)
- if(!user)
- break
- if(!issilicon(user))
- if( i>1 && !(user.is_holding(src))) //for burst firing
- break
- if(chambered && chambered.BB)
- if(randomspread)
- sprd = round((rand() - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread))
- else //Smart spread
- sprd = round((((rand_spr/burst_size) * i) - (0.5 + (rand_spr * 0.25))) * (randomized_gun_spread + randomized_bonus_spread))
-
- if(!chambered.fire_casing(target, user, params, ,suppressed, zone_override, sprd))
- shoot_with_empty_chamber(user)
- break
- else
- if(get_dist(user, target) <= 1) //Making sure whether the target is in vicinity for the pointblank shot
- shoot_live_shot(user, 1, target, message)
- else
- shoot_live_shot(user, 0, target, message)
- else
- shoot_with_empty_chamber(user)
- break
- process_chamber()
- update_icon()
- sleep(fire_delay)
- firing_burst = 0
+ addtimer(CALLBACK(src, .proc/process_burst, user, target, message, params, zone_override, sprd, randomized_gun_spread, randomized_bonus_spread, rand_spr, i), min(fire_delay * (i - 1), 0))
+ firing_burst = FALSE
else
if(chambered)
sprd = round((rand() - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread))
@@ -265,14 +272,16 @@
return
process_chamber()
update_icon()
- semicd = 1
- spawn(fire_delay)
- semicd = 0
+ semicd = TRUE
+ addtimer(CALLBACK(src, .proc/reset_semicd), fire_delay)
if(user)
user.update_inv_hands()
SSblackbox.add_details("gun_fired","[src.type]")
- return 1
+ return TRUE
+
+/obj/item/gun/proc/reset_semicd()
+ semicd = FALSE
/obj/item/gun/update_icon()
..()
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index d73c978ed7..06fa4f6f8a 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -150,7 +150,7 @@
toggle_gunlight()
/obj/item/gun/energy/suicide_act(mob/user)
- if (src.can_shoot() && can_trigger_gun(user))
+ if (can_shoot() && can_trigger_gun(user))
user.visible_message("[user] is putting the barrel of [src] in [user.p_their()] mouth. It looks like [user.p_theyre()] trying to commit suicide!")
sleep(25)
if(user.is_holding(src))
diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm
index a5ba7c15a4..a6c0c75644 100644
--- a/code/modules/projectiles/projectile/special.dm
+++ b/code/modules/projectiles/projectile/special.dm
@@ -469,7 +469,9 @@
layer = ABOVE_MOB_LAYER
hal_target.client.images += blood
animate(blood, pixel_x = target_pixel_x, pixel_y = target_pixel_y, alpha = 0, time = 5)
- sleep(5)
+ addtimer(CALLBACK(src, .proc/cleanup_blood), 5)
+
+/obj/item/projectile/hallucination/proc/cleanup_blood(image/blood)
hal_target.client.images -= blood
qdel(blood)
diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm
index c6a01bc45f..f1da846ebc 100644
--- a/code/modules/reagents/chemistry/machinery/chem_master.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_master.dm
@@ -57,8 +57,7 @@
if(powered())
stat &= ~NOPOWER
else
- spawn(rand(0, 15))
- stat |= NOPOWER
+ stat |= NOPOWER
/obj/machinery/chem_master/attackby(obj/item/I, mob/user, params)
if(default_deconstruction_screwdriver(user, "mixer0_nopower", "mixer0", I))
diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm
index 54058b5a52..5ee18c2dba 100644
--- a/code/modules/reagents/reagent_containers/glass.dm
+++ b/code/modules/reagents/reagent_containers/glass.dm
@@ -49,8 +49,7 @@
to_chat(user, "You swallow a gulp of [src].")
var/fraction = min(5/reagents.total_volume, 1)
reagents.reaction(M, INGEST, fraction)
- spawn(5)
- reagents.trans_to(M, 5)
+ addtimer(CALLBACK(reagents, /datum/reagents.proc/trans_to, M, 5), 5)
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
/obj/item/reagent_containers/glass/afterattack(obj/target, mob/user, proximity)
diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm
index f236b83fa3..dff0869322 100644
--- a/code/modules/reagents/reagent_containers/hypospray.dm
+++ b/code/modules/reagents/reagent_containers/hypospray.dm
@@ -101,13 +101,14 @@
reagents.maximum_volume = 0 //Makes them useless afterwards
container_type = NONE
update_icon()
- spawn(80)
- if(iscyborg(user) && !reagents.total_volume)
- var/mob/living/silicon/robot/R = user
- if(R.cell.use(100))
- reagents.add_reagent_list(list_reagents)
- update_icon()
- return
+ addtimer(CALLBACK(src, .proc/cyborg_recharge, user), 80)
+
+/obj/item/reagent_containers/hypospray/medipen/proc/cyborg_recharge(mob/living/silicon/robot/user)
+ if(!reagents.total_volume && iscyborg(user))
+ var/mob/living/silicon/robot/R = user
+ if(R.cell.use(100))
+ reagents.add_reagent_list(list_reagents)
+ update_icon()
/obj/item/reagent_containers/hypospray/medipen/update_icon()
if(reagents.total_volume > 0)
diff --git a/code/modules/ruins/objects_and_mobs/sin_ruins.dm b/code/modules/ruins/objects_and_mobs/sin_ruins.dm
index a01a144bc3..f00c90bb25 100644
--- a/code/modules/ruins/objects_and_mobs/sin_ruins.dm
+++ b/code/modules/ruins/objects_and_mobs/sin_ruins.dm
@@ -24,7 +24,9 @@
know it'll be worth it.")
icon_state = "slots2"
playsound(src, 'sound/lavaland/cursed_slot_machine.ogg', 50, 0)
- sleep(50)
+ addtimer(CALLBACK(src, .proc/determine_victor, user), 50)
+
+/obj/structure/cursed_slot_machine/proc/determine_victor(mob/living/user)
icon_state = "slots1"
in_use = FALSE
if(prob(win_prob))
@@ -37,6 +39,7 @@
if(user)
to_chat(user, "Fucking machine! Must be rigged. Still... one more try couldn't hurt, right?")
+
/obj/structure/cursed_money
name = "bag of money"
desc = "RICH! YES! YOU KNEW IT WAS WORTH IT! YOU'RE RICH! RICH! RICH!"
@@ -65,8 +68,6 @@
user.put_in_hands(critical_fail)
qdel(src)
-
-
/obj/effect/gluttony //Gluttony's wall: Used in the Gluttony ruin. Only lets the overweight through.
name = "gluttony's wall"
desc = "Only those who truly indulge may pass."
diff --git a/code/modules/spells/spell_types/touch_attacks.dm b/code/modules/spells/spell_types/touch_attacks.dm
index 46563da53d..ffbee4789d 100644
--- a/code/modules/spells/spell_types/touch_attacks.dm
+++ b/code/modules/spells/spell_types/touch_attacks.dm
@@ -11,15 +11,15 @@
charge_counter = charge_max
attached_hand = null
to_chat(user, "You draw the power out of your hand.")
- return 0
+ return FALSE
..()
/obj/effect/proc_holder/spell/targeted/touch/cast(list/targets,mob/user = usr)
for(var/mob/living/carbon/C in targets)
if(!attached_hand)
if(!ChargeHand(C))
- return 0
- while(attached_hand) //hibernate untill the spell is actually used
+ return FALSE
+ while(attached_hand)
charge_counter = 0
stoplag(1)
@@ -30,9 +30,9 @@
charge_counter = charge_max
attached_hand = null
to_chat(user, "Your hands are full!")
- return 0
+ return FALSE
to_chat(user, "You channel the power of the spell to your hand.")
- return 1
+ return TRUE
/obj/effect/proc_holder/spell/targeted/touch/disintegrate
@@ -58,4 +58,4 @@
cooldown_min = 200 //100 deciseconds reduction per rank
action_icon_state = "statue"
- sound = 'sound/magic/fleshtostone.ogg'
\ No newline at end of file
+ sound = 'sound/magic/fleshtostone.ogg'
diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm
index 7fd09d69c2..6ebc278e53 100644
--- a/code/modules/surgery/organs/augments_chest.dm
+++ b/code/modules/surgery/organs/augments_chest.dm
@@ -24,8 +24,10 @@
synthesizing = TRUE
to_chat(owner, "You feel less hungry...")
owner.nutrition += 50
- sleep(50)
- synthesizing = FALSE
+ addtimer(CALLBACK(src, .proc/synth_cool), 50)
+
+/obj/item/organ/cyberimp/chest/nutriment/proc/synth_cool()
+ synthesizing = FALSE
/obj/item/organ/cyberimp/chest/nutriment/emp_act(severity)
if(!owner)
diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm
index eed05c6161..aa77370ea2 100644
--- a/code/modules/surgery/organs/vocal_cords.dm
+++ b/code/modules/surgery/organs/vocal_cords.dm
@@ -253,6 +253,7 @@
var/static/regex/honk_words = regex("ho+nk") //hooooooonk
var/static/regex/multispin_words = regex("like a record baby|right round")
+ var/i = 0
//STUN
if(findtext(message, stun_words))
cooldown = COOLDOWN_STUN
@@ -362,28 +363,30 @@
cooldown = COOLDOWN_MEME
for(var/V in listeners)
var/mob/living/L = V
+ var/text = ""
if(is_devil(L))
var/datum/antagonist/devil/devilinfo = is_devil(L)
- L.say("[devilinfo.truename]")
+ text = devilinfo.truename
else
- L.say("[L.real_name]")
- sleep(5) //So the chat flows more naturally
+ text = L.real_name
+ addtimer(CALLBACK(L, /atom/movable/proc/say, text), 5 * i)
+ i++
//SAY MY NAME
else if((findtext(message, saymyname_words)))
cooldown = COOLDOWN_MEME
for(var/V in listeners)
var/mob/living/L = V
- L.say("[user.name]!") //"Unknown!"
- sleep(5) //So the chat flows more naturally
+ addtimer(CALLBACK(L, /atom/movable/proc/say, user.name), 5 * i)
+ i++
//KNOCK KNOCK
else if((findtext(message, knockknock_words)))
cooldown = COOLDOWN_MEME
for(var/V in listeners)
var/mob/living/L = V
- L.say("Who's there?")
- sleep(5) //So the chat flows more naturally
+ addtimer(CALLBACK(L, /atom/movable/proc/say, "Who's there?"), 5 * i)
+ i++
//STATE LAWS
else if((findtext(message, statelaws_words)))
@@ -403,11 +406,10 @@
direction = WEST
else if(findtext(message, right_words))
direction = EAST
- for(var/i=1, i<=(5*power_multiplier), i++)
+ for(var/iter in 1 to 5 * power_multiplier)
for(var/V in listeners)
var/mob/living/L = V
- step(L, direction ? direction : pick(GLOB.cardinals))
- sleep(10)
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/_step, L, direction? direction : pick(GLOB.cardinals)), 10 * (iter - 1))
//WALK
else if((findtext(message, walk_words)))
@@ -429,33 +431,33 @@
else if((findtext(message, helpintent_words)))
cooldown = COOLDOWN_MEME
for(var/mob/living/carbon/human/H in listeners)
- H.a_intent_change(INTENT_HELP)
- H.click_random_mob()
- sleep(2) //delay to make it feel more natural
+ addtimer(CALLBACK(H, /mob/verb/a_intent_change, INTENT_HELP), i * 2)
+ addtimer(CALLBACK(H, /mob/proc/click_random_mob), i * 2)
+ i++
//DISARM INTENT
else if((findtext(message, disarmintent_words)))
cooldown = COOLDOWN_MEME
for(var/mob/living/carbon/human/H in listeners)
- H.a_intent_change(INTENT_DISARM)
- H.click_random_mob()
- sleep(2) //delay to make it feel more natural
+ addtimer(CALLBACK(H, /mob/verb/a_intent_change, INTENT_DISARM), i * 2)
+ addtimer(CALLBACK(H, /mob/proc/click_random_mob), i * 2)
+ i++
//GRAB INTENT
else if((findtext(message, grabintent_words)))
cooldown = COOLDOWN_MEME
for(var/mob/living/carbon/human/H in listeners)
- H.a_intent_change(INTENT_GRAB)
- H.click_random_mob()
- sleep(2) //delay to make it feel more natural
+ addtimer(CALLBACK(H, /mob/verb/a_intent_change, INTENT_GRAB), i * 2)
+ addtimer(CALLBACK(H, /mob/proc/click_random_mob), i * 2)
+ i++
//HARM INTENT
else if((findtext(message, harmintent_words)))
cooldown = COOLDOWN_MEME
for(var/mob/living/carbon/human/H in listeners)
- H.a_intent_change(INTENT_HARM)
- H.click_random_mob()
- sleep(2) //delay to make it feel more natural
+ addtimer(CALLBACK(H, /mob/verb/a_intent_change, INTENT_HARM), i * 2)
+ addtimer(CALLBACK(H, /mob/proc/click_random_mob), i * 2)
+ i++
//THROW/CATCH
else if((findtext(message, throwmode_words)))
@@ -475,8 +477,8 @@
cooldown = COOLDOWN_MEME
for(var/V in listeners)
var/mob/living/L = V
- L.say(pick_list_replacements(BRAIN_DAMAGE_FILE, "brain_damage"))
- sleep(5) //So the chat flows more naturally
+ addtimer(CALLBACK(L, /atom/movable/proc/say, pick_list_replacements(BRAIN_DAMAGE_FILE, "brain_damage")), 5 * i)
+ i++
//GET UP
else if((findtext(message, getup_words)))
@@ -511,8 +513,8 @@
cooldown = COOLDOWN_MEME
for(var/V in listeners)
var/mob/living/L = V
- L.emote("dance")
- sleep(5) //So the chat flows more naturally
+ addtimer(CALLBACK(L, /mob/living/.proc/emote, "dance"), 5 * i)
+ i++
//JUMP
else if((findtext(message, jump_words)))
@@ -520,33 +522,33 @@
for(var/V in listeners)
var/mob/living/L = V
if(prob(25))
- L.say("HOW HIGH?!!")
- L.emote("jump")
- sleep(5) //So the chat flows more naturally
+ addtimer(CALLBACK(L, /atom/movable/proc/say, "HOW HIGH?!!"), 5 * i)
+ addtimer(CALLBACK(L, /mob/living/.proc/emote, "jump"), 5 * i)
+ i++
//SALUTE
else if((findtext(message, salute_words)))
cooldown = COOLDOWN_MEME
for(var/V in listeners)
var/mob/living/L = V
- L.emote("salute")
- sleep(5) //So the chat flows more naturally
+ addtimer(CALLBACK(L, /mob/living/.proc/emote, "salute"), 5 * i)
+ i++
//PLAY DEAD
else if((findtext(message, deathgasp_words)))
cooldown = COOLDOWN_MEME
for(var/V in listeners)
var/mob/living/L = V
- L.emote("deathgasp")
- sleep(5) //So the chat flows more naturally
+ addtimer(CALLBACK(L, /mob/living/.proc/emote, "deathgasp"), 5 * i)
+ i++
//PLEASE CLAP
else if((findtext(message, clap_words)))
cooldown = COOLDOWN_MEME
for(var/V in listeners)
var/mob/living/L = V
- L.emote("clap")
- sleep(5) //So the chat flows more naturally
+ addtimer(CALLBACK(L, /mob/living/.proc/emote, "clap"), 5 * i)
+ i++
//HONK
else if((findtext(message, honk_words)))