diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm
index a5aa63e6a1..caf7c13ac2 100644
--- a/code/__DEFINES/components.dm
+++ b/code/__DEFINES/components.dm
@@ -86,6 +86,7 @@
#define COMSIG_MOVABLE_UNBUCKLE "unbuckle" //from base of atom/movable/unbuckle_mob(): (mob, force)
#define COMSIG_MOVABLE_THROW "movable_throw" //from base of atom/movable/throw_at(): (datum/thrownthing, spin)
#define COMSIG_MOVABLE_Z_CHANGED "movable_ztransit" //from base of atom/movable/onTransitZ(): (old_z, new_z)
+
// /obj signals
#define COMSIG_OBJ_DECONSTRUCT "obj_deconstruct" //from base of obj/deconstruct(): (disassembled)
diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm
index e298e63675..e78ec9e905 100644
--- a/code/__DEFINES/flags.dm
+++ b/code/__DEFINES/flags.dm
@@ -32,10 +32,6 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define BANG_PROTECT_2 (1<<6)
-// An item worn in the ear slot with HEALS_EARS will heal your ears each
-// Life() tick, even if normally your ears would be too damaged to heal.
-#define HEALS_EARS_2 (1<<7)
-
// A mob with OMNITONGUE has no restriction in the ability to speak
// languages that they know. So even if they wouldn't normally be able to
// through mob or tongue restrictions, this flag allows them to ignore
diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm
index a447df4045..1e23eef04f 100644
--- a/code/_globalvars/bitfields.dm
+++ b/code/_globalvars/bitfields.dm
@@ -123,7 +123,6 @@ GLOBAL_LIST_INIT(bitfields, list(
"NO_EMP_WIRES_2" = NO_EMP_WIRES_2,
"HOLOGRAM_2" = HOLOGRAM_2,
"BANG_PROTECT_2" = BANG_PROTECT_2,
- "HEALS_EARS_2" = HEALS_EARS_2,
"OMNITONGUE_2" = OMNITONGUE_2,
"TESLA_IGNORE_2" = TESLA_IGNORE_2
),
diff --git a/code/datums/components/earhealing.dm b/code/datums/components/earhealing.dm
new file mode 100644
index 0000000000..79303ff701
--- /dev/null
+++ b/code/datums/components/earhealing.dm
@@ -0,0 +1,30 @@
+// An item worn in the ear slot with this component will heal your ears each
+// Life() tick, even if normally your ears would be too damaged to heal.
+
+/datum/component/earhealing
+ var/mob/living/carbon/wearer
+
+/datum/component/earhealing/Initialize()
+ if(!isitem(parent))
+ return COMPONENT_INCOMPATIBLE
+ RegisterSignal(list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED), .proc/equippedChanged)
+
+/datum/component/earhealing/proc/equippedChanged(mob/living/carbon/user, slot)
+ if (slot == SLOT_EARS && istype(user))
+ if (!wearer)
+ START_PROCESSING(SSobj, src)
+ wearer = user
+ else
+ if (wearer)
+ STOP_PROCESSING(SSobj, src)
+ wearer = null
+
+/datum/component/earhealing/process()
+ if (!wearer)
+ STOP_PROCESSING(SSobj, src)
+ return
+ if(!wearer.has_trait(TRAIT_DEAF))
+ var/obj/item/organ/ears/ears = wearer.getorganslot(ORGAN_SLOT_EARS)
+ if (ears)
+ ears.deaf = max(ears.deaf - 1, (ears.ear_damage < UNHEALING_EAR_DAMAGE ? 0 : 1)) // Do not clear deafness while above the unhealing ear damage threshold
+ ears.ear_damage = max(ears.ear_damage - 0.1, 0)
diff --git a/code/datums/components/wearertargeting.dm b/code/datums/components/wearertargeting.dm
new file mode 100644
index 0000000000..adf8acceb9
--- /dev/null
+++ b/code/datums/components/wearertargeting.dm
@@ -0,0 +1,26 @@
+// A dummy parent type used for easily making components that target an item's wearer rather than the item itself.
+
+/datum/component/wearertargeting
+ var/datum/component/mobhook
+ var/list/valid_slots = list()
+ var/list/signals = list()
+ var/datum/callback/callback = CALLBACK(GLOBAL_PROC, .proc/pass)
+ var/mobtype = /mob/living
+
+/datum/component/wearertargeting/Initialize()
+ if(!isitem(parent))
+ return COMPONENT_INCOMPATIBLE
+ RegisterSignal(list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED), .proc/checkMobHook)
+
+/datum/component/wearertargeting/Destroy()
+ QDEL_NULL(mobhook)
+ return ..()
+
+/datum/component/wearertargeting/proc/checkMobHook(mob/user, slot)
+ if ((slot in valid_slots) && istype(user, mobtype))
+ if (mobhook && mobhook.parent != user)
+ QDEL_NULL(mobhook)
+ if (!mobhook)
+ mobhook = user.AddComponent(/datum/component/redirect, signals, callback)
+ else
+ QDEL_NULL(mobhook)
diff --git a/code/modules/clothing/ears/_ears.dm b/code/modules/clothing/ears/_ears.dm
index 3a1e246d04..f22fa8b9dc 100644
--- a/code/modules/clothing/ears/_ears.dm
+++ b/code/modules/clothing/ears/_ears.dm
@@ -1,46 +1,50 @@
-//Ears: currently only used for headsets and earmuffs
-
/obj/item/clothing/ears
-
name = "ears"
-
w_class = WEIGHT_CLASS_TINY
-
throwforce = 0
-
slot_flags = ITEM_SLOT_EARS
-
resistance_flags = NONE
-
/obj/item/clothing/ears/earmuffs
-
name = "earmuffs"
-
desc = "Protects your hearing from loud noises, and quiet ones as well."
-
icon_state = "earmuffs"
-
item_state = "earmuffs"
-
strip_delay = 15
-
equip_delay_other = 25
-
resistance_flags = FLAMMABLE
-
flags_2 = BANG_PROTECT_2|HEALS_EARS_2
+//Ears: currently only used for headsets and earmuffs
+/obj/item/clothing/ears
+ name = "ears"
+ w_class = WEIGHT_CLASS_TINY
+ throwforce = 0
+ slot_flags = ITEM_SLOT_EARS
+ resistance_flags = NONE
-
/obj/item/clothing/ears/headphones
-
name = "headphones"
-
desc = "Unce unce unce unce. Boop!"
-
icon = 'icons/obj/clothing/accessories.dmi'
-
icon_state = "headphones"
-
item_state = "headphones"
-
slot_flags = ITEM_SLOT_EARS | ITEM_SLOT_HEAD | ITEM_SLOT_NECK //Fluff item, put it whereever you want!
-
actions_types = list(/datum/action/item_action/toggle_headphones)
-
var/headphones_on = FALSE
+/obj/item/clothing/ears/earmuffs
+ name = "earmuffs"
+ desc = "Protects your hearing from loud noises, and quiet ones as well."
+ icon_state = "earmuffs"
+ item_state = "earmuffs"
+ strip_delay = 15
+ equip_delay_other = 25
+ resistance_flags = FLAMMABLE
+ flags_2 = BANG_PROTECT_2
-
/obj/item/clothing/ears/headphones/Initialize()
-
. = ..()
-
update_icon()
+/obj/item/clothing/ears/earmuffs/ComponentInitialize()
+ . = ..()
+ AddComponent(/datum/component/earhealing)
-
/obj/item/clothing/ears/headphones/update_icon()
-
icon_state = "[initial(icon_state)]_[headphones_on? "on" : "off"]"
-
item_state = "[initial(item_state)]_[headphones_on? "on" : "off"]"
+/obj/item/clothing/ears/headphones
+ name = "headphones"
+ desc = "Unce unce unce unce. Boop!"
+ icon = 'icons/obj/clothing/accessories.dmi'
+ icon_state = "headphones"
+ item_state = "headphones"
+ slot_flags = ITEM_SLOT_EARS | ITEM_SLOT_HEAD | ITEM_SLOT_NECK //Fluff item, put it whereever you want!
+ actions_types = list(/datum/action/item_action/toggle_headphones)
+ var/headphones_on = FALSE
-
/obj/item/clothing/ears/headphones/proc/toggle(owner)
-
headphones_on = !headphones_on
-
update_icon()
-
var/mob/living/carbon/human/H = owner
-
if(istype(H))
-
H.update_inv_ears()
-
H.update_inv_neck()
-
H.update_inv_head()
-
to_chat(owner, "You turn the music [headphones_on? "on. Untz Untz Untz!" : "off."]")
-
\ No newline at end of file
+/obj/item/clothing/ears/headphones/Initialize()
+ . = ..()
+ update_icon()
+
+/obj/item/clothing/ears/headphones/update_icon()
+ icon_state = "[initial(icon_state)]_[headphones_on? "on" : "off"]"
+ item_state = "[initial(item_state)]_[headphones_on? "on" : "off"]"
+
+/obj/item/clothing/ears/headphones/proc/toggle(owner)
+ headphones_on = !headphones_on
+ update_icon()
+ var/mob/living/carbon/human/H = owner
+ if(istype(H))
+ H.update_inv_ears()
+ H.update_inv_neck()
+ H.update_inv_head()
+ to_chat(owner, "You turn the music [headphones_on? "on. Untz Untz Untz!" : "off."]")
diff --git a/code/modules/surgery/organs/ears.dm b/code/modules/surgery/organs/ears.dm
index fff342a101..c54d3bb532 100644
--- a/code/modules/surgery/organs/ears.dm
+++ b/code/modules/surgery/organs/ears.dm
@@ -27,14 +27,9 @@
// genetic deafness prevents the body from using the ears, even if healthy
if(C.has_trait(TRAIT_DEAF))
deaf = max(deaf, 1)
- else
- if(C.ears && (C.ears.flags_2 & HEALS_EARS_2))
- deaf = max(deaf - 1, 1)
- ear_damage = max(ear_damage - 0.1, 0)
- // if higher than UNHEALING_EAR_DAMAGE, no natural healing occurs.
- if(ear_damage < UNHEALING_EAR_DAMAGE)
- ear_damage = max(ear_damage - 0.05, 0)
- deaf = max(deaf - 1, 0)
+ else if(ear_damage < UNHEALING_EAR_DAMAGE) // if higher than UNHEALING_EAR_DAMAGE, no natural healing occurs.
+ ear_damage = max(ear_damage - 0.05, 0)
+ deaf = max(deaf - 1, 0)
/obj/item/organ/ears/proc/restoreEars()
deaf = 0
diff --git a/tgstation.dme b/tgstation.dme
index 1267dcd53e..e532dcb6d8 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -325,6 +325,7 @@
#include "code\datums\components\cleaning.dm"
#include "code\datums\components\construction.dm"
#include "code\datums\components\decal.dm"
+#include "code\datums\components\earhealing.dm"
#include "code\datums\components\forensics.dm"
#include "code\datums\components\infective.dm"
#include "code\datums\components\jousting.dm"
@@ -346,6 +347,7 @@
#include "code\datums\components\stationloving.dm"
#include "code\datums\components\swarming.dm"
#include "code\datums\components\thermite.dm"
+#include "code\datums\components\wearertargeting.dm"
#include "code\datums\components\wet_floor.dm"
#include "code\datums\components\decals\blood.dm"
#include "code\datums\components\storage\storage.dm"