diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm
index 6083b933145..195508298e0 100644
--- a/code/__DEFINES/dcs/signals.dm
+++ b/code/__DEFINES/dcs/signals.dm
@@ -199,6 +199,8 @@
// /area signals
+///from base of area/proc/power_change(): ()
+#define COMSIG_AREA_POWER_CHANGE "area_power_change"
///from base of area/Entered(): (atom/movable/M)
#define COMSIG_AREA_ENTERED "area_entered"
///from base of area/Exited(): (atom/movable/M)
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index ba8c3bdb41c..51cd935a45e 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -498,11 +498,12 @@ GLOBAL_LIST_EMPTY(teleportlocs)
/**
* Called when the area power status changes
*
- * Updates the area icon and calls power change on all machinees in the area
+ * Updates the area icon, calls power change on all machinees in the area, and sends the `COMSIG_AREA_POWER_CHANGE` signal.
*/
/area/proc/power_change()
for(var/obj/machinery/M in src) // for each machine in the area
M.power_change() // reverify power status (to update icons etc.)
+ SEND_SIGNAL(src, COMSIG_AREA_POWER_CHANGE)
update_icon()
diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm
index c4c976a7491..40a7fe08c54 100644
--- a/code/game/objects/items/devices/radio/intercom.dm
+++ b/code/game/objects/items/devices/radio/intercom.dm
@@ -5,49 +5,44 @@
anchored = TRUE
w_class = WEIGHT_CLASS_BULKY
canhear_range = 2
- var/number = 0
- var/anyai = 1
- var/mob/living/silicon/ai/ai = list()
- var/last_tick //used to delay the powercheck
dog_fashion = null
- var/unfastened = FALSE
+ unscrewed = FALSE
/obj/item/radio/intercom/unscrewed
- unfastened = TRUE
+ unscrewed = TRUE
/obj/item/radio/intercom/Initialize(mapload, ndir, building)
. = ..()
if(building)
setDir(ndir)
- START_PROCESSING(SSobj, src)
-
-/obj/item/radio/intercom/Destroy()
- STOP_PROCESSING(SSobj, src)
- return ..()
+ var/area/current_area = get_area(src)
+ if(!current_area)
+ return
+ RegisterSignal(current_area, COMSIG_AREA_POWER_CHANGE, .proc/AreaPowerCheck)
/obj/item/radio/intercom/examine(mob/user)
. = ..()
. += "Use [MODE_TOKEN_INTERCOM] when nearby to speak into it."
- if(!unfastened)
+ if(!unscrewed)
. += "It's screwed and secured to the wall."
else
. += "It's unscrewed from the wall, and can be detached."
/obj/item/radio/intercom/attackby(obj/item/I, mob/living/user, params)
if(I.tool_behaviour == TOOL_SCREWDRIVER)
- if(unfastened)
+ if(unscrewed)
user.visible_message("[user] starts tightening [src]'s screws...", "You start screwing in [src]...")
if(I.use_tool(src, user, 30, volume=50))
user.visible_message("[user] tightens [src]'s screws!", "You tighten [src]'s screws.")
- unfastened = FALSE
+ unscrewed = FALSE
else
user.visible_message("[user] starts loosening [src]'s screws...", "You start unscrewing [src]...")
if(I.use_tool(src, user, 40, volume=50))
user.visible_message("[user] loosens [src]'s screws!", "You unscrew [src], loosening it from the wall.")
- unfastened = TRUE
+ unscrewed = TRUE
return
else if(I.tool_behaviour == TOOL_WRENCH)
- if(!unfastened)
+ if(!unscrewed)
to_chat(user, "You need to unscrew [src] from the wall first!")
return
user.visible_message("[user] starts unsecuring [src]...", "You start unsecuring [src]...")
@@ -82,45 +77,52 @@
var/turf/position = get_turf(src)
if(isnull(position) || !(position.z in level))
return FALSE
- if(!src.listening)
+ if(!listening)
return FALSE
if(freq == FREQ_SYNDICATE)
- if(!(src.syndie))
+ if(!(syndie))
return FALSE//Prevents broadcast of messages over devices lacking the encryption
return TRUE
/obj/item/radio/intercom/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans, message_mode)
- if (message_mode == MODE_INTERCOM)
+ if(message_mode == MODE_INTERCOM)
return // Avoid hearing the same thing twice
- if(!anyai && !(speaker in ai))
- return
- ..()
+ return ..()
-/obj/item/radio/intercom/process()
- if(((world.timeofday - last_tick) > 30) || ((world.timeofday - last_tick) < 0))
- last_tick = world.timeofday
-
- var/area/A = get_area(src)
- if(!A || emped)
- on = FALSE
- else
- on = A.powered(AREA_USAGE_EQUIP) // set "on" to the power status
-
- if(!on)
- icon_state = "intercom-p"
- else
- icon_state = initial(icon_state)
-
-/obj/item/radio/intercom/add_blood_DNA(list/blood_dna)
- return FALSE
+/obj/item/radio/intercom/emp_act(severity)
+ . = ..() // Parent call here will set `on` to FALSE.
+ update_icon()
/obj/item/radio/intercom/end_emp_effect(curremp)
. = ..()
- if(!.)
- return
- on = FALSE
+ AreaPowerCheck() // Make sure the area/local APC is powered first before we actually turn back on.
+
+/obj/item/radio/intercom/update_icon()
+ . = ..()
+ if(on)
+ icon_state = initial(icon_state)
+ else
+ icon_state = "intercom-p"
+
+/**
+ * Proc called whenever the intercom's area loses or gains power. Responsible for setting the `on` variable and calling `update_icon()`.
+ *
+ * Normally called after the intercom's area recieves the `COMSIG_AREA_POWER_CHANGE` signal, but it can also be called directly.
+ * Arguments:
+ * * source - the area that just had a power change.
+ */
+/obj/item/radio/intercom/proc/AreaPowerCheck(datum/source)
+ var/area/current_area = get_area(src)
+ if(!current_area)
+ on = FALSE
+ else
+ on = current_area.powered(AREA_USAGE_EQUIP) // set "on" to the equipment power status of our area.
+ update_icon()
+
+/obj/item/radio/intercom/add_blood_DNA(list/blood_dna)
+ return FALSE
//Created through the autolathe or through deconstructing intercoms. Can be applied to wall to make a new intercom on it!
/obj/item/wallframe/intercom