diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm
index 64f9949016d..d82444a1d0f 100644
--- a/code/__DEFINES/components.dm
+++ b/code/__DEFINES/components.dm
@@ -73,7 +73,9 @@
//End positions
#define COMPONENT_EXNAME_CHANGED 1
#define COMSIG_ATOM_UPDATE_ICON "atom_update_icon" //from base of atom/update_icon(): ()
- #define COMSIG_ATOM_NO_UPDATE_ICON_STATE 1
+ #define COMSIG_ATOM_NO_UPDATE_ICON_STATE 1
+ #define COMSIG_ATOM_NO_UPDATE_OVERLAYS 2
+#define COMSIG_ATOM_UPDATE_OVERLAYS "atom_update_overlays" //from base of atom/update_overlays(): (list/new_overlays)
#define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (atom/movable/entering, /atom)
#define COMSIG_ATOM_EXIT "atom_exit" //from base of atom/Exit(): (/atom/movable/exiting, /atom/newloc)
#define COMPONENT_ATOM_BLOCK_EXIT 1
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 5f8dfcb1220..0ad4be8fe7b 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -45,6 +45,8 @@
///vis overlays managed by SSvis_overlays to automaticaly turn them like other overlays
var/list/managed_vis_overlays
+ ///overlays managed by update_overlays() to prevent removing overlays that weren't added by the same proc
+ var/list/managed_overlays
///Proximity monitor associated with this atom
var/datum/proximity_monitor/proximity_monitor
@@ -487,14 +489,29 @@
/// Updates the icon of the atom
/atom/proc/update_icon()
- // I expect we're going to need more return flags and options in this proc
var/signalOut = SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_ICON)
+
if(!(signalOut & COMSIG_ATOM_NO_UPDATE_ICON_STATE))
update_icon_state()
+
+ if(!(signalOut & COMSIG_ATOM_NO_UPDATE_OVERLAYS))
+ var/list/new_overlays = update_overlays()
+ if(managed_overlays)
+ cut_overlay(managed_overlays)
+ managed_overlays = null
+ if(length(new_overlays))
+ managed_overlays = new_overlays
+ add_overlay(new_overlays)
/// Updates the icon state of the atom
/atom/proc/update_icon_state()
+/// Updates the overlays of the atom
+/atom/proc/update_overlays()
+ SHOULD_CALL_PARENT(1)
+ . = list()
+ SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_OVERLAYS, .)
+
/**
* An atom we are buckled or is contained within us has tried to move
*
diff --git a/code/game/machinery/ai_slipper.dm b/code/game/machinery/ai_slipper.dm
index 5f0661619f4..8fa3571674e 100644
--- a/code/game/machinery/ai_slipper.dm
+++ b/code/game/machinery/ai_slipper.dm
@@ -17,7 +17,7 @@
. = ..()
. += "It has [uses] uses of foam remaining."
-/obj/machinery/ai_slipper/update_icon()
+/obj/machinery/ai_slipper/update_icon_state()
if(stat & BROKEN)
return
if((stat & NOPOWER) || cooldown_time > world.time || !uses)
diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm
index 59825012d0f..c5f4148ff85 100644
--- a/code/game/machinery/buttons.dm
+++ b/code/game/machinery/buttons.dm
@@ -43,21 +43,22 @@
setup_device()
-
-/obj/machinery/button/update_icon()
- cut_overlays()
+/obj/machinery/button/update_icon_state()
if(panel_open)
icon_state = "button-open"
- if(device)
- add_overlay("button-device")
- if(board)
- add_overlay("button-board")
-
+ else if(stat & (NOPOWER|BROKEN))
+ icon_state = "[skin]-p"
else
- if(stat & (NOPOWER|BROKEN))
- icon_state = "[skin]-p"
- else
- icon_state = skin
+ icon_state = skin
+
+/obj/machinery/button/update_overlays()
+ . = ..()
+ if(!panel_open)
+ return
+ if(device)
+ . += "button-device"
+ if(board)
+ . += "button-board"
/obj/machinery/button/attackby(obj/item/W, mob/user, params)
if(W.tool_behaviour == TOOL_SCREWDRIVER)
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index 517d9cfba85..d21e287f290 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -346,7 +346,7 @@
new /obj/item/stack/cable_coil(loc, 2)
qdel(src)
-/obj/machinery/camera/update_icon() //TO-DO: Make panel open states, xray camera, and indicator lights overlays instead.
+/obj/machinery/camera/update_icon_state() //TO-DO: Make panel open states, xray camera, and indicator lights overlays instead.
var/xray_module
if(isXRay(TRUE))
xray_module = "xray"
diff --git a/code/game/machinery/defibrillator_mount.dm b/code/game/machinery/defibrillator_mount.dm
index 8a5a25b2e0a..f6cc265ee6a 100644
--- a/code/game/machinery/defibrillator_mount.dm
+++ b/code/game/machinery/defibrillator_mount.dm
@@ -38,17 +38,22 @@
defib.cell.give(180) //90% efficiency, slightly better than the cell charger's 87.5%
update_icon()
-/obj/machinery/defibrillator_mount/update_icon()
- cut_overlays()
- if(defib)
- add_overlay("defib")
- if(defib.powered)
- add_overlay(defib.safety ? "online" : "emagged")
- var/ratio = defib.cell.charge / defib.cell.maxcharge
- ratio = CEILING(ratio * 4, 1) * 25
- add_overlay("charge[ratio]")
- if(clamps_locked)
- add_overlay("clamps")
+/obj/machinery/defibrillator_mount/update_overlays()
+ . = ..()
+
+ if(!defib)
+ return
+
+ . += "defib"
+
+ if(defib.powered)
+ . += (defib.safety ? "online" : "emagged")
+ var/ratio = defib.cell.charge / defib.cell.maxcharge
+ ratio = CEILING(ratio * 4, 1) * 25
+ . += "charge[ratio]"
+
+ if(clamps_locked)
+ . += "clamps"
/obj/machinery/defibrillator_mount/get_cell()
if(defib)
diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm
index 59e8f5f7bc3..cd6196e75a6 100644
--- a/code/game/objects/items/defib.dm
+++ b/code/game/objects/items/defib.dm
@@ -53,8 +53,7 @@
/obj/item/defibrillator/update_icon()
update_power()
- update_overlays()
- update_charge()
+ return ..()
/obj/item/defibrillator/proc/update_power()
if(!QDELETED(cell))
@@ -65,23 +64,21 @@
else
powered = FALSE
-/obj/item/defibrillator/proc/update_overlays()
- cut_overlays()
- if(!on)
- add_overlay("[initial(icon_state)]-paddles")
- if(powered)
- add_overlay("[initial(icon_state)]-powered")
- if(!cell)
- add_overlay("[initial(icon_state)]-nocell")
- if(!safety)
- add_overlay("[initial(icon_state)]-emagged")
+/obj/item/defibrillator/update_overlays()
+ . = ..()
-/obj/item/defibrillator/proc/update_charge()
- if(powered) //so it doesn't show charge if it's unpowered
+ if(!on)
+ . += "[initial(icon_state)]-paddles"
+ if(powered)
+ . += "[initial(icon_state)]-powered"
if(!QDELETED(cell))
var/ratio = cell.charge / cell.maxcharge
ratio = CEILING(ratio*4, 1) * 25
- add_overlay("[initial(icon_state)]-charge[ratio]")
+ . += "[initial(icon_state)]-charge[ratio]"
+ if(!cell)
+ . += "[initial(icon_state)]-nocell"
+ if(!safety)
+ . += "[initial(icon_state)]-emagged"
/obj/item/defibrillator/CheckParts(list/parts_list)
..()
diff --git a/code/modules/food_and_drinks/food/customizables.dm b/code/modules/food_and_drinks/food/customizables.dm
index 73ec0ec9cc9..0a9a5e1ca29 100644
--- a/code/modules/food_and_drinks/food/customizables.dm
+++ b/code/modules/food_and_drinks/food/customizables.dm
@@ -53,7 +53,7 @@
mix_filling_color(S)
S.reagents.trans_to(src,min(S.reagents.total_volume, 15), transfered_by = user) //limit of 15, we don't want our custom food to be completely filled by just one ingredient with large reagent volume.
foodtype |= S.foodtype
- update_overlays(S)
+ update_snack_overlays(S)
to_chat(user, "You add the [I.name] to the [name].")
update_name(S)
else
@@ -101,7 +101,7 @@
rgbcolor[4] = (customcolor[4]+ingcolor[4])/2
filling_color = rgb(rgbcolor[1], rgbcolor[2], rgbcolor[3], rgbcolor[4])
-/obj/item/reagent_containers/food/snacks/customizable/update_overlays(obj/item/reagent_containers/food/snacks/S)
+/obj/item/reagent_containers/food/snacks/customizable/update_snack_overlays(obj/item/reagent_containers/food/snacks/S)
var/mutable_appearance/filling = mutable_appearance(icon, "[initial(icon_state)]_filling")
if(S.filling_color == "#FFFFFF")
filling.color = pick("#FF0000","#0000FF","#008000","#FFFF00")
@@ -137,7 +137,7 @@
/obj/item/reagent_containers/food/snacks/customizable/initialize_slice(obj/item/reagent_containers/food/snacks/slice, reagents_per_slice)
..()
slice.filling_color = filling_color
- slice.update_overlays(src)
+ slice.update_snack_overlays(src)
/obj/item/reagent_containers/food/snacks/customizable/Destroy()
diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm
index 9295b55acbd..da427e9a69a 100644
--- a/code/modules/food_and_drinks/food/snacks.dm
+++ b/code/modules/food_and_drinks/food/snacks.dm
@@ -270,7 +270,7 @@ All foods are distributed among various categories. Use common sense.
trash = null
return
-/obj/item/reagent_containers/food/snacks/proc/update_overlays(obj/item/reagent_containers/food/snacks/S)
+/obj/item/reagent_containers/food/snacks/proc/update_snack_overlays(obj/item/reagent_containers/food/snacks/S)
cut_overlays()
var/mutable_appearance/filling = mutable_appearance(icon, "[initial(icon_state)]_filling")
if(S.filling_color == "#FFFFFF")
diff --git a/code/modules/food_and_drinks/food/snacks_pastry.dm b/code/modules/food_and_drinks/food/snacks_pastry.dm
index 643fe8e5dbb..2df67cc7914 100644
--- a/code/modules/food_and_drinks/food/snacks_pastry.dm
+++ b/code/modules/food_and_drinks/food/snacks_pastry.dm
@@ -671,13 +671,13 @@
to_chat(user, "You add the [I] to the [name].")
P.name = initial(P.name)
contents += P
- update_overlays(P)
+ update_snack_overlays(P)
if (P.contents.len)
for(var/V in P.contents)
P = V
P.name = initial(P.name)
contents += P
- update_overlays(P)
+ update_snack_overlays(P)
P = I
clearlist(P.contents)
return
@@ -686,7 +686,7 @@
return O.attackby(I, user, params)
..()
-/obj/item/reagent_containers/food/snacks/pancakes/update_overlays(obj/item/reagent_containers/food/snacks/P)
+/obj/item/reagent_containers/food/snacks/pancakes/update_snack_overlays(obj/item/reagent_containers/food/snacks/P)
var/mutable_appearance/pancake = mutable_appearance(icon, "[P.item_state]_[rand(1,3)]")
pancake.pixel_x = rand(-1,1)
pancake.pixel_y = 3 * contents.len - 1