diff --git a/code/datums/spell.dm b/code/datums/spell.dm
index 3d00394d278..d8c7b26554c 100644
--- a/code/datums/spell.dm
+++ b/code/datums/spell.dm
@@ -62,6 +62,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
var/charge_type = "recharge" //can be recharge or charges, see charge_max and charge_counter descriptions; can also be based on the holder's vars now, use "holder_var" for that
var/charge_max = 100 //recharge time in deciseconds if charge_type = "recharge" or starting charges if charge_type = "charges"
+ var/starts_charged = TRUE //Does this spell start ready to go?
var/charge_counter = 0 //can only cast spells if it equals recharge, ++ each decisecond if charge_type = "recharge" or -- each cast if charge_type = "charges"
var/still_recharging_msg = "The spell is still recharging."
@@ -195,9 +196,11 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
/obj/effect/proc_holder/spell/New()
..()
action = new(src)
-
still_recharging_msg = "[name] is still recharging."
- charge_counter = charge_max
+ if(starts_charged)
+ charge_counter = charge_max
+ else
+ start_recharge()
/obj/effect/proc_holder/spell/Destroy()
QDEL_NULL(action)
@@ -214,9 +217,14 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
/obj/effect/proc_holder/spell/proc/start_recharge()
if(action)
action.UpdateButtonIcon()
- while(charge_counter < charge_max)
- sleep(1)
- charge_counter++
+ START_PROCESSING(SSfastprocess, src)
+
+/obj/effect/proc_holder/spell/process()
+ charge_counter += 2
+ if(charge_counter < charge_max)
+ return
+ STOP_PROCESSING(SSfastprocess, src)
+ charge_counter = charge_max
if(action)
action.UpdateButtonIcon()
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index f49cf05197a..889f32b3aee 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -337,6 +337,9 @@
if(AM && isturf(AM.loc))
step(AM, turn(AM.dir, 180))
+/atom/proc/get_spooked()
+ return
+
/atom/proc/add_hiddenprint(mob/living/M as mob)
if(isnull(M)) return
if(isnull(M.key)) return
@@ -655,7 +658,7 @@ var/list/blood_splatter_icons = list()
if(V.type == type)
V.reagents.add_reagent(vomit_reagent, 5)
return
-
+
var/obj/effect/decal/cleanable/vomit/this = new type(src)
// Make toxins vomit look different
diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm
index 05545e6a3d1..642676c6eff 100644
--- a/code/game/machinery/status_display.dm
+++ b/code/game/machinery/status_display.dm
@@ -78,6 +78,9 @@
set_picture("ai_bsod")
..(severity)
+/obj/machinery/status_display/get_spooked()
+ spookymode = TRUE
+
// set what is displayed
/obj/machinery/status_display/proc/update()
if(friendc && !ignore_friendc)
@@ -227,6 +230,9 @@
set_picture("ai_bsod")
..(severity)
+/obj/machinery/ai_status_display/get_spooked()
+ spookymode = TRUE
+
/obj/machinery/ai_status_display/proc/update()
if(mode==0) //Blank
overlays.Cut()
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 5e214e87d80..993cb458777 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -299,6 +299,10 @@
/turf/proc/Bless()
flags |= NOJAUNT
+/turf/get_spooked()
+ for(var/atom/movable/AM in contents)
+ AM.get_spooked()
+
/turf/proc/burn_down()
return
diff --git a/code/modules/mob/dead/observer/spells.dm b/code/modules/mob/dead/observer/spells.dm
index 620c1854e73..916ff9aa9b8 100644
--- a/code/modules/mob/dead/observer/spells.dm
+++ b/code/modules/mob/dead/observer/spells.dm
@@ -1,6 +1,4 @@
-
-
-var/global/list/boo_phrases=list(
+GLOBAL_LIST_INIT(boo_phrases, list(
"You feel a chill run down your spine.",
"You think you see a figure in your peripheral vision.",
"What was that?",
@@ -9,16 +7,17 @@ var/global/list/boo_phrases=list(
"Something doesn't feel right...",
"You feel a presence in the room.",
"It feels like someone's standing behind you.",
-)
+))
/obj/effect/proc_holder/spell/aoe_turf/boo
name = "Boo!"
desc = "Fuck with the living."
- ghost = 1
+ ghost = TRUE
school = "transmutation"
charge_max = 600
+ starts_charged = FALSE
clothes_req = 0
stat_allowed = 1
invocation = ""
@@ -27,26 +26,4 @@ var/global/list/boo_phrases=list(
/obj/effect/proc_holder/spell/aoe_turf/boo/cast(list/targets, mob/user = usr)
for(var/turf/T in targets)
- for(var/atom/A in T.contents)
-
- // Bug humans
- if(ishuman(A))
- var/mob/living/carbon/human/H = A
- if(H && H.client)
- to_chat(H, "[pick(boo_phrases)]")
-
- // Flicker unblessed lights in range
- if(istype(A,/obj/machinery/light))
- var/obj/machinery/light/L = A
- if(L)
- L.flicker()
-
- // OH GOD BLUE APC (single animation cycle)
- if(istype(A, /obj/machinery/power/apc))
- A:spookify()
-
- if(istype(A, /obj/machinery/status_display))
- A:spookymode=1
-
- if(istype(A, /obj/machinery/ai_status_display))
- A:spookymode=1
\ No newline at end of file
+ T.get_spooked()
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index e497fd04814..2cd524f8a15 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -2003,6 +2003,9 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
genemutcheck(src, block, null, MUTCHK_FORCED)
dna.UpdateSE()
+/mob/living/carbon/human/get_spooked()
+ to_chat(src, "[pick(GLOB.boo_phrases)]")
+
/mob/living/carbon/human/extinguish_light()
// Parent function handles stuff the human may be holding
..()
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index a3186b115a4..4b88ba41ef8 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -49,7 +49,6 @@
use_power = NO_POWER_USE
req_access = list(access_engine_equip)
siemens_strength = 1
- var/spooky=0
var/area/area
var/areastring = null
var/obj/item/stock_parts/cell/cell
@@ -248,9 +247,9 @@
// update the APC icon to show the three base states
// also add overlays for indicator lights
-/obj/machinery/power/apc/update_icon()
+/obj/machinery/power/apc/update_icon(force_update = FALSE)
- if(!status_overlays)
+ if(!status_overlays || force_update)
status_overlays = 1
status_overlays_lock = new
status_overlays_charging = new
@@ -291,10 +290,10 @@
var/update = check_updates() //returns 0 if no need to update icons.
// 1 if we need to update the icon_state
// 2 if we need to update the overlays
- if(!update)
+ if(!update && !force_update)
return
- if(update & 1) // Updating the icon state
+ if(force_update || update & 1) // Updating the icon state
if(update_state & UPSTATE_ALLGOOD)
icon_state = "apc0"
else if(update_state & (UPSTATE_OPENED1|UPSTATE_OPENED2))
@@ -322,7 +321,7 @@
- if(update & 2)
+ if(force_update || update & 2)
if(overlays.len)
overlays.len = 0
@@ -412,14 +411,17 @@
update_icon()
updating_icon = 0
-/obj/machinery/power/apc/proc/spookify()
- if(spooky) return // Fuck you we're already spooky
- spooky=1
- update_icon()
- spawn(10)
- spooky=0
- update_icon()
-
+/obj/machinery/power/apc/get_spooked(second_pass = FALSE)
+ if(opened || wiresexposed)
+ return
+ if(stat & (NOPOWER | BROKEN))
+ return
+ if(!second_pass) //The first time, we just cut overlays
+ addtimer(CALLBACK(src, .get_spooked, TRUE), 1)
+ cut_overlays()
+ else
+ flick("apcemag", src) //Second time we cause the APC to update its icon, then add a timer to update icon later
+ addtimer(CALLBACK(src, .proc/update_icon, TRUE), 10)
//attack with an item - open/close cover, insert cell, or (un)lock interface
/obj/machinery/power/apc/attackby(obj/item/W, mob/living/user, params)
diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm
index a0bee89e0be..b186e862f01 100644
--- a/code/modules/power/lighting.dm
+++ b/code/modules/power/lighting.dm
@@ -232,6 +232,9 @@
on = FALSE
return
+/obj/machinery/light/get_spooked()
+ flicker()
+
// update the icon_state and luminosity of the light depending on its state
/obj/machinery/light/proc/update(var/trigger = TRUE)
switch(status)