diff --git a/code/__defines/traits/declarations.dm b/code/__defines/traits/declarations.dm
index 19fb86cd51..1f2ce348ee 100644
--- a/code/__defines/traits/declarations.dm
+++ b/code/__defines/traits/declarations.dm
@@ -49,3 +49,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_MADNESS_IMMUNE "supermatter_madness_immune"
/// Owner is corrupted via redspace. Used downstream. SHOULD NOT BE USED LIGHTLY. HORROR THEMES.
#define TRAIT_REDSPACE_CORRUPTED "redspace_corrupted"
+// allows draining of power cells for nutrition
+#define TRAIT_ELECTROVORE "electrovore"
+// allows draining or recharging of power cells via nutrition
+#define TRAIT_ELECTROVORE_OBLIGATE "electrovore_obligate"
diff --git a/code/datums/elements/electrovoreable.dm b/code/datums/elements/electrovoreable.dm
new file mode 100644
index 0000000000..7e5e8d369a
--- /dev/null
+++ b/code/datums/elements/electrovoreable.dm
@@ -0,0 +1,77 @@
+/datum/element/electrovoreable
+ // Electrovore interaction handler for items (e.g. power cells).
+ // Logic is hooked via signals (COMSIG_ITEM_ATTACK_SELF).
+
+/datum/element/electrovoreable/Attach(datum/target)
+ . = ..()
+ if(!isitem(target))
+ return ELEMENT_INCOMPATIBLE
+
+ RegisterSignal(target, COMSIG_ITEM_ATTACK_SELF, PROC_REF(on_attack_self))
+
+/datum/element/electrovoreable/Detach(datum/target)
+ UnregisterSignal(target, COMSIG_ITEM_ATTACK_SELF)
+ return ..()
+
+/datum/element/electrovoreable/proc/on_attack_self(obj/item/source, mob/user)
+ SIGNAL_HANDLER
+
+ if(!isliving(user))
+ return
+ var/mob/living/living_user = user
+
+ // Must be some kind of electrovore to interact at all
+ if(!HAS_TRAIT(living_user, TRAIT_ELECTROVORE))
+ return
+
+ // Only cells should have special electrovore behavior
+ if(!istype(source, /obj/item/cell))
+ return
+ var/obj/item/cell/source_cell = source
+
+ // HELP: obligate electrovores only (charge the cell)
+ if(living_user.a_intent == I_HELP && HAS_TRAIT(living_user, TRAIT_ELECTROVORE_OBLIGATE))
+ if(source_cell.charge >= source_cell.maxcharge)
+ return COMPONENT_CANCEL_ATTACK_CHAIN
+
+ if(!living_user.nutrition)
+ living_user.show_message(span_warning("You feel too drained to charge [source_cell]."))
+ return COMPONENT_CANCEL_ATTACK_CHAIN
+
+ var/todrain = max(100, (living_user.nutrition * 0.2))
+ if(living_user.nutrition < todrain)
+ living_user.show_message(span_warning("You don't have enough energy to charge [source_cell]."))
+ return COMPONENT_CANCEL_ATTACK_CHAIN
+
+ living_user.show_message(span_warning("Power surges from you and flows into [source_cell], increasing its charge!"))
+ living_user.visible_message(span_notice("[living_user] squeezes [source_cell] tightly, charging it!"))
+
+ var/totransfer = min(todrain, ((source_cell.maxcharge - source_cell.charge) / 15))
+
+ living_user.adjust_nutrition(-todrain)
+ source_cell.give(min((totransfer * 15), (source_cell.maxcharge - source_cell.charge)))
+ source_cell.update_icon()
+
+ return COMPONENT_CANCEL_ATTACK_CHAIN
+
+ // HURT: drain energy for nutrition (obligate + freeform)
+ if(living_user.a_intent == I_HURT)
+ if(!source_cell.charge)
+ living_user.show_message(span_warning("You take a look at [source_cell] and notice it has nothing in it!"))
+ return COMPONENT_CANCEL_ATTACK_CHAIN
+
+ living_user.show_message(span_warning("Sparks fly from [source_cell] as you drain energy from it!"))
+ living_user.visible_message(span_danger("[living_user] causes sparks to emit from [source_cell] as it loses its charge!"))
+
+ var/coefficient = 0.9
+ var/totransfer = min(source_cell.charge, 1500)
+
+ living_user.adjust_nutrition((totransfer / 15) * coefficient)
+ source_cell.use(totransfer)
+ source_cell.update_icon()
+
+ var/datum/effect/effect/system/spark_spread/spark_effect = new /datum/effect/effect/system/spark_spread
+ spark_effect.set_up(3, 0, source_cell)
+ spark_effect.start()
+
+ return COMPONENT_CANCEL_ATTACK_CHAIN
diff --git a/code/modules/mob/living/carbon/human/species/station/traits/neutral.dm b/code/modules/mob/living/carbon/human/species/station/traits/neutral.dm
index 5e737d6b57..45dcf18528 100644
--- a/code/modules/mob/living/carbon/human/species/station/traits/neutral.dm
+++ b/code/modules/mob/living/carbon/human/species/station/traits/neutral.dm
@@ -259,6 +259,35 @@
..()
add_verb(H, /mob/living/carbon/human/proc/bloodsuck)
+/datum/trait/neutral/electrovore
+ name = "Electrovore, Obligate"
+ desc = "Makes you unable to gain nutrition from anything but electricity"
+ tutorial = "HELP intent lets you consume nutrition to charge a Cell by clicking it in your hand.
\
+ HARM intent drains battery charge and gives nutrition in exchange"
+
+ cost = 0
+ custom_only = FALSE
+ excludes = list(/datum/trait/neutral/electrovore_freeform)
+
+/datum/trait/neutral/electrovore/apply(var/datum/species/S, var/mob/living/carbon/human/human)
+ ..()
+ ADD_TRAIT(human, TRAIT_ELECTROVORE, ROUNDSTART_TRAIT)
+ ADD_TRAIT(human, TRAIT_ELECTROVORE_OBLIGATE, ROUNDSTART_TRAIT)
+
+/datum/trait/neutral/electrovore_freeform
+ name = "Electrovore"
+ desc = "Allows you to drain power cells for nutrition."
+ tutorial = "This trait allows you to consume electricity!
\
+ Clicking a power cell in your hand on HARM intent drains its power for nutrition"
+
+ cost = 0
+ custom_only = FALSE
+ excludes = list(/datum/trait/neutral/electrovore)
+
+/datum/trait/neutral/electrovore_freeform/apply(var/datum/species/S, var/mob/living/carbon/human/human)
+ ..()
+ ADD_TRAIT(human, TRAIT_ELECTROVORE, ROUNDSTART_TRAIT)
+
/datum/trait/neutral/succubus_drain
name = "Succubus Drain"
desc = "Makes you able to gain nutrition from draining prey in your grasp."
diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm
index 2a73fbdda4..be086db2b3 100644
--- a/code/modules/power/cell.dm
+++ b/code/modules/power/cell.dm
@@ -26,9 +26,11 @@
var/charge_amount = 25 // How much power to give, if self_recharge is true. The number is in absolute cell charge, as it gets divided by CELLRATE later.
var/last_use = 0 // A tracker for use in self-charging
var/connector_type = "standard" //What connector sprite to use when in a cell charger, null if no connectors
- var/charge_delay = 0 // How long it takes for the cell to start recharging after last use
+ var/charge_delay = 0 // How long it takes for the cell to start recharging after last use
var/robot_durability = 50
+
matter = list(MAT_STEEL = 700, MAT_GLASS = 50)
+
drop_sound = 'sound/items/drop/component.ogg'
pickup_sound = 'sound/items/pickup/component.ogg'
@@ -38,6 +40,7 @@
/obj/item/cell/Initialize(mapload)
. = ..()
+ AddElement(/datum/element/electrovoreable)
c_uid = cell_uid++
update_icon()
if(self_recharge)
diff --git a/vorestation.dme b/vorestation.dme
index 3672913b51..354a528c27 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -881,6 +881,7 @@
#include "code\datums\elements\climbable.dm"
#include "code\datums\elements\conflict_checking.dm"
#include "code\datums\elements\connect_loc.dm"
+#include "code\datums\elements\electrovoreable.dm"
#include "code\datums\elements\footstep.dm"
#include "code\datums\elements\footstep_override.dm"
#include "code\datums\elements\godmode.dm"