From f8dccaaa2a504a792564acff7e96f30d25d20e48 Mon Sep 17 00:00:00 2001 From: CHOMPStation2StaffMirrorBot <94713762+CHOMPStation2StaffMirrorBot@users.noreply.github.com> Date: Tue, 6 Jan 2026 11:23:21 -0700 Subject: [PATCH] [MIRROR] Electrovore virgo (#12225) Co-authored-by: ShoanaeaCKeye <45808921+Shoanaea@users.noreply.github.com> Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com> --- code/__defines/traits/declarations.dm | 4 + code/datums/elements/electrovoreable.dm | 77 +++++++++++++++++++ .../human/species/station/traits/neutral.dm | 29 +++++++ code/modules/power/cell.dm | 5 +- vorestation.dme | 1 + 5 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 code/datums/elements/electrovoreable.dm 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"