diff --git a/code/__DEFINES/dcs/area_signals.dm b/code/__DEFINES/dcs/area_signals.dm
new file mode 100644
index 00000000000..d3ece784043
--- /dev/null
+++ b/code/__DEFINES/dcs/area_signals.dm
@@ -0,0 +1,12 @@
+/**
+ * Signals for /area and subtypes that have too few related signals to put in separate files.
+ * Doc format: `/// when the signal is called: (signal arguments)`.
+ * All signals send the source datum of the signal as the first argument
+ */
+
+// /area
+
+/// From obj/machinery/light_switch/Destroy(): ()
+#define COMSIG_AREA_LIGHTSWITCH_DELETING "area_lightswitch_deleting"
+ /// Stop all area lightswitches from turning back on.
+ #define COMSIG_AREA_LIGHTSWITCH_CANCEL (1<<0)
diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm
index 778be4f2648..2114d35c892 100644
--- a/code/game/machinery/lightswitch.dm
+++ b/code/game/machinery/lightswitch.dm
@@ -26,6 +26,23 @@
dir = WEST
update_icon(UPDATE_ICON_STATE|UPDATE_OVERLAYS)
+ var/area/A = get_area(src)
+ // Yes, we're listening to the area to update its signal.
+ RegisterSignal(A, COMSIG_ATOM_UPDATED_ICON, PROC_REF(signal_lightswitch_icon_update))
+ RegisterSignal(A, COMSIG_AREA_LIGHTSWITCH_DELETING, PROC_REF(lightswitch_cancel_autoswitch))
+
+/obj/machinery/light_switch/Destroy()
+ var/area/A = get_area(src)
+ UnregisterSignal(A, COMSIG_AREA_LIGHTSWITCH_DELETING) // make sure src isnt included, if we're the last light switch to go the lights will turn back on
+ if(SEND_SIGNAL(A, COMSIG_AREA_LIGHTSWITCH_DELETING) & COMSIG_AREA_LIGHTSWITCH_CANCEL)
+ return ..()
+
+ // Toggle the lights on if there are no other light switches
+ set_area_lightswitch(TRUE)
+ return ..()
+
+/obj/machinery/light_switch/proc/signal_lightswitch_icon_update()
+ update_icon(UPDATE_ICON_STATE|UPDATE_OVERLAYS)
/obj/machinery/light_switch/update_icon_state()
if(stat & NOPOWER)
@@ -54,18 +71,9 @@
return attack_hand(user)
/obj/machinery/light_switch/attack_hand(mob/user)
- playsound(src, 'sound/machines/lightswitch.ogg', 10, TRUE)
- update_icon(UPDATE_ICON_STATE|UPDATE_OVERLAYS)
-
var/area/A = get_area(src)
-
- A.lightswitch = !A.lightswitch
- A.update_icon(UPDATE_ICON_STATE)
-
- for(var/obj/machinery/light_switch/L in A)
- L.update_icon(UPDATE_ICON_STATE|UPDATE_OVERLAYS)
-
- machine_powernet.power_change()
+ set_area_lightswitch(!A.lightswitch)
+ playsound(src, 'sound/machines/lightswitch.ogg', 10, TRUE)
/obj/machinery/light_switch/power_change()
if(!..())
@@ -92,9 +100,22 @@
return
user.visible_message("[user] starts unwrenching [src] from the wall...", "You are unwrenching [src] from the wall...", "You hear ratcheting.")
- if(!I.use_tool(src, user, 30, volume = I.tool_volume))
+ if(!I.use_tool(src, user, 3 SECONDS, volume = I.tool_volume))
return
WRENCH_UNANCHOR_WALL_MESSAGE
new/obj/item/mounted/frame/light_switch(get_turf(src))
qdel(src)
+
+/obj/machinery/light_switch/proc/set_area_lightswitch(new_state)
+ var/area/A = get_area(src)
+ A.lightswitch = new_state
+ // Sends an area signal to all lightswitches in our area to update their icons and overlays
+ A.update_icon(UPDATE_ICON_STATE)
+
+ // Update all the lights in our area
+ machine_powernet.power_change()
+
+/obj/machinery/light_switch/proc/lightswitch_cancel_autoswitch()
+ SIGNAL_HANDLER // COMSIG_AREA_LIGHTSWITCH_DELETING
+ return COMSIG_AREA_LIGHTSWITCH_CANCEL
diff --git a/paradise.dme b/paradise.dme
index ae0e12111fb..ee53a7e3c8c 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -152,6 +152,7 @@
#include "code\__DEFINES\ai\ai_defines.dm"
#include "code\__DEFINES\ai\blackboard_defines.dm"
#include "code\__DEFINES\dcs\ai_signals.dm"
+#include "code\__DEFINES\dcs\area_signals.dm"
#include "code\__DEFINES\dcs\atom_signals.dm"
#include "code\__DEFINES\dcs\attack_chain_signals.dm"
#include "code\__DEFINES\dcs\basetype_signals.dm"