Extremely minor reagent optimization (#93645)

## About The Pull Request

Saves us like, 10,000 - 20,000 lists per round by not initing a list for
every reagent

Uses a signal to handle allergic reactions blocking metabolism rather
than adding behavior `/reagent`

## Why It's Good For The Game

Will it matter? Probably not, is it cleaner? Heck yeah

## Changelog

🆑 Melbert
qol: Tox damage from allergic reactions is affected by tox damage
modifiers
refactor: Changed how allergic reactions to chem pause metabolism,
report any oddities
/🆑
This commit is contained in:
MrMelbert
2025-10-29 22:39:48 +01:00
committed by GitHub
parent 5780aed466
commit 5cffc0d169
4 changed files with 25 additions and 26 deletions
@@ -12,6 +12,8 @@
#define COMSIG_MOB_REAGENT_TICK "mob_reagent_tick"
///stops the reagent check call
#define COMSIG_MOB_STOP_REAGENT_TICK (1<<0)
///Allows for most on_life calls BUT metabolize()
#define COMSIG_MOB_STOP_REAGENT_METABOLISM (1<<1)
///from base of mob/clickon(): (atom/A, list/modifiers)
#define COMSIG_MOB_CLICKON "mob_clickon"
///from base of mob/MiddleClickOn(): (atom/A)
+20 -20
View File
@@ -44,28 +44,28 @@
give_item_to_holder(dogtag, list(LOCATION_BACKPACK, LOCATION_HANDS), flavour_text = "Make sure medical staff can see this...", notify_player = TRUE)
/datum/quirk/item_quirk/allergic/add()
RegisterSignal(quirk_holder, COMSIG_MOB_REAGENT_TICK, PROC_REF(block_metab))
/datum/quirk/item_quirk/allergic/remove()
UnregisterSignal(quirk_holder, COMSIG_MOB_REAGENT_TICK)
/datum/quirk/item_quirk/allergic/post_add()
quirk_holder.add_mob_memory(/datum/memory/key/quirk_allergy, allergy_string = allergy_string)
to_chat(quirk_holder, span_boldnotice("You are allergic to [allergy_string], make sure not to consume any of these!"))
/datum/quirk/item_quirk/allergic/process(seconds_per_tick)
var/mob/living/carbon/carbon_quirk_holder = quirk_holder
//Just halts the progression, I'd suggest you run to medbay asap to get it fixed
if(carbon_quirk_holder.reagents.has_reagent(/datum/reagent/medicine/epinephrine))
for(var/allergy in allergies)
var/datum/reagent/instantiated_med = carbon_quirk_holder.reagents.has_reagent(allergy)
if(!instantiated_med)
continue
instantiated_med.reagent_removal_skip_list |= ALLERGIC_REMOVAL_SKIP
return //block damage so long as epinephrine exists
/datum/quirk/item_quirk/allergic/proc/block_metab(mob/living/carbon/source, datum/reagent/chem, seconds_per_tick, times_fired)
SIGNAL_HANDLER
for(var/allergy in allergies)
var/datum/reagent/instantiated_med = carbon_quirk_holder.reagents.has_reagent(allergy)
if(!instantiated_med)
continue
instantiated_med.reagent_removal_skip_list -= ALLERGIC_REMOVAL_SKIP
carbon_quirk_holder.adjustToxLoss(3 * seconds_per_tick)
carbon_quirk_holder.reagents.add_reagent(/datum/reagent/toxin/histamine, 3 * seconds_per_tick)
if(SPT_PROB(10, seconds_per_tick))
carbon_quirk_holder.vomit(VOMIT_CATEGORY_DEFAULT)
carbon_quirk_holder.adjustOrganLoss(pick(ORGAN_SLOT_BRAIN,ORGAN_SLOT_APPENDIX,ORGAN_SLOT_LUNGS,ORGAN_SLOT_HEART,ORGAN_SLOT_LIVER,ORGAN_SLOT_STOMACH),10)
if(!is_type_in_list(chem, allergies))
return NONE
// Having epinephrine stops metabolization of an allergen, but doesn't remove it from the system
if(source.reagents.has_reagent(/datum/reagent/medicine/epinephrine))
return COMSIG_MOB_STOP_REAGENT_METABOLISM
// Otherwise the allergen causes a ton of damage though otherwise processes normally
source.apply_damage(3 * seconds_per_tick, TOX)
source.reagents.add_reagent(/datum/reagent/toxin/histamine, 3 * seconds_per_tick)
if(SPT_PROB(10, seconds_per_tick))
source.vomit(VOMIT_CATEGORY_DEFAULT)
source.adjustOrganLoss(pick(ORGAN_SLOT_BRAIN, ORGAN_SLOT_APPENDIX, ORGAN_SLOT_LUNGS, ORGAN_SLOT_HEART, ORGAN_SLOT_LIVER, ORGAN_SLOT_STOMACH), 10)
return NONE
@@ -95,7 +95,8 @@
if(!owner || !reagent || (dead && !(reagent.chemical_flags & REAGENT_DEAD_PROCESS)))
return FALSE
if(owner.reagent_tick(reagent, seconds_per_tick, times_fired))
var/tick_return = owner.reagent_tick(reagent, seconds_per_tick, times_fired)
if(tick_return & COMSIG_MOB_STOP_REAGENT_TICK)
return FALSE
if(liverless && !reagent.self_consuming) //need to be metabolized
@@ -124,7 +125,7 @@
if(dead && !QDELETED(owner) && !QDELETED(reagent))
need_mob_update += reagent.on_mob_dead(owner, seconds_per_tick)
if(!QDELETED(owner) && !QDELETED(reagent))
if(!QDELETED(owner) && !QDELETED(reagent) && !(tick_return & COMSIG_MOB_STOP_REAGENT_METABOLISM))
reagent.metabolize_reagent(owner, seconds_per_tick, times_fired)
return need_mob_update
@@ -42,8 +42,6 @@
var/metabolizing = FALSE
/// Are we from a material? We might wanna know that for special stuff. Like metalgen. Is replaced with a ref of the material on New()
var/datum/material/material
///A list of causes why this chem should skip being removed, if the length is 0 it will be removed from holder naturally, if this is >0 it will not be removed from the holder.
var/list/reagent_removal_skip_list = list()
///The set of exposure methods this penetrates skin with.
var/penetrates_skin = VAPOR
/// See fermi_readme.dm REAGENT_DEAD_PROCESS, REAGENT_INVISIBLE, REAGENT_SNEAKYNAME, REAGENT_SPLITRETAINVOL, REAGENT_CANSYNTH, REAGENT_IMPURE
@@ -170,8 +168,6 @@
///Metabolizes a portion of the reagent after on_mob_life() is called
/datum/reagent/proc/metabolize_reagent(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
if(length(reagent_removal_skip_list))
return
if(isnull(holder))
return