From 8a4613b980a156649e4cda844ed23874001e2467 Mon Sep 17 00:00:00 2001 From: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Date: Mon, 15 Sep 2025 18:38:54 -0500 Subject: [PATCH] Things that iterate cells avoid grabbing abstract cells (like Ethereal stomachs) (#92987) ## About The Pull Request Anything that iterates contents for all cells now use a new helper, `get_all_cells`, which only checks equipped items and storage contents for cells, rather than... everything This means we avoid grabbing abstract cells, and thus avoid this image Note: This means these random recharge-all objects (like Xenobio stuff) no longer recharges Ethereals If we want these objects recharging Ethereals, we should *probably* add a bespoke interaction ## Changelog :cl: Melbert fix: Things that recharge "all cells on your person" now avoid recharging Ethereal stomachs, and thus, will no longer cause spontaneous overcharge or weird chat messages /:cl: --- code/modules/hydroponics/plant_genes.dm | 2 +- code/modules/mob/inventory.dm | 16 ++++++++++++ code/modules/research/experimentor.dm | 25 ++++++------------- .../crossbreeding/_status_effects.dm | 2 +- .../xenobiology/crossbreeding/regenerative.dm | 2 +- .../organs/internal/heart/heart_anomalock.dm | 2 +- 6 files changed, 28 insertions(+), 21 deletions(-) diff --git a/code/modules/hydroponics/plant_genes.dm b/code/modules/hydroponics/plant_genes.dm index 0cc9d78bc39..107598cbff7 100644 --- a/code/modules/hydroponics/plant_genes.dm +++ b/code/modules/hydroponics/plant_genes.dm @@ -335,7 +335,7 @@ to_chat(eater, span_notice("You feel energized as you bite into [our_plant].")) var/batteries_recharged = FALSE var/obj/item/seeds/our_seed = our_plant.get_plant_seed() - for(var/obj/item/stock_parts/power_store/found_cell in eater.get_all_contents()) + for(var/obj/item/stock_parts/power_store/found_cell in eater.get_all_cells()) var/newcharge = min(our_seed.potency * 0.01 * found_cell.maxcharge, found_cell.maxcharge) if(found_cell.charge < newcharge) found_cell.charge = newcharge diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 9003730334d..11cbd18a371 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -684,3 +684,19 @@ . += item else if(del_if_nodrop && !(item.item_flags & ABSTRACT)) qdel(item) + +/** + * Iterates over all contents of the mob to find all items with a cell (or loose cells) + * Useful instead of iterating contents for cells, as it recurses storage and avoids returning abstract cells (like Ethereals) + * + * * max_percent: The maximum charge percent (0.0-1.0) the cell can have to be included in the results + * + * Returns an assoc list of item - its cell + */ +/mob/living/proc/get_all_cells(max_percent = 1.0) + var/list/cell_items = list() + for(var/obj/item/stored in get_all_gear()) + var/obj/item/stock_parts/power_store/stored_cell = stored.get_cell() + if(stored_cell && stored_cell.charge <= (stored_cell.maxcharge * max_percent)) + cell_items[stored] = stored_cell + return cell_items diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index b73ae51bdd7..4d0e4537f52 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -778,30 +778,21 @@ user.electrocute_act(15, src, flags = SHOCK_NOGLOVES) playsound(user, SFX_SPARKS, rand(25,50), TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - var/list/chargeable_batteries = list() - for(var/obj/item/stock_parts/power_store/C in user.get_all_contents()) - if(C.charge < (C.maxcharge * 0.95)) // otherwise the PDA always gets recharged - chargeable_batteries |= C + var/list/chargeable_items = user.get_all_cells(max_percent = 0.95) // otherwise the PDA always gets recharged lightning_fx(user, stunner) var/recharges = rand(1, 2) - if(!length(chargeable_batteries)) + if(!length(chargeable_items)) to_chat(user, span_notice("You have a strange feeling for a moment, but then it passes.")) return - for(var/obj/item/stock_parts/power_store/to_charge as anything in chargeable_batteries) - if(!recharges) - return + while(length(chargeable_items) && recharges) recharges-- - to_charge = pick(chargeable_batteries) + var/obj/item/to_charge_base = pick_n_take(chargeable_items) + var/obj/item/stock_parts/power_store/to_charge = chargeable_items[to_charge_base] to_charge.charge = to_charge.maxcharge - // The device powered by the cell is assumed to be its location. - var/obj/device = to_charge.loc - // If it's not an object, or the loc's assigned power_store isn't the cell, undo. - if(!istype(device) || (device.get_cell() != to_charge)) - device = to_charge - device.update_appearance(UPDATE_ICON|UPDATE_OVERLAYS) - to_chat(user, span_notice("[device] feels energized!")) - lightning_fx(device, 0.8 SECONDS) + to_charge_base.update_appearance(UPDATE_ICON|UPDATE_OVERLAYS) + to_chat(user, span_notice("[to_charge_base] feels energized!")) + lightning_fx(to_charge_base, 0.8 SECONDS) /obj/item/relic/proc/lightning_fx(atom/shocker, time) var/lightning = mutable_appearance('icons/effects/effects.dmi', "electricity3", layer = ABOVE_MOB_LAYER) diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm index 6d37ec13d01..3dd92891f51 100644 --- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm +++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm @@ -595,7 +595,7 @@ return ..() cooldown = max_cooldown var/list/batteries = list() - for(var/obj/item/stock_parts/power_store/C in owner.get_all_contents()) + for(var/obj/item/stock_parts/power_store/C in owner.get_all_cells()) if(C.charge < C.maxcharge) batteries += C if(batteries.len) diff --git a/code/modules/research/xenobiology/crossbreeding/regenerative.dm b/code/modules/research/xenobiology/crossbreeding/regenerative.dm index c153312cb75..7077b7a7b36 100644 --- a/code/modules/research/xenobiology/crossbreeding/regenerative.dm +++ b/code/modules/research/xenobiology/crossbreeding/regenerative.dm @@ -87,7 +87,7 @@ Regenerative extracts: /obj/item/slimecross/regenerative/yellow/core_effect(mob/living/target, mob/user) var/list/batteries = list() - for(var/obj/item/stock_parts/power_store/C in target.get_all_contents()) + for(var/obj/item/stock_parts/power_store/C in target.get_all_cells()) if(C.charge < C.maxcharge) batteries += C if(batteries.len) diff --git a/code/modules/surgery/organs/internal/heart/heart_anomalock.dm b/code/modules/surgery/organs/internal/heart/heart_anomalock.dm index 10fbc5f2f30..fe7b726d00a 100644 --- a/code/modules/surgery/organs/internal/heart/heart_anomalock.dm +++ b/code/modules/surgery/organs/internal/heart/heart_anomalock.dm @@ -108,7 +108,7 @@ return var/list/batteries = list() - for(var/obj/item/stock_parts/power_store/cell in owner.get_all_contents()) + for(var/obj/item/stock_parts/power_store/cell in owner.get_all_cells()) if(cell.used_charge()) batteries += cell