From 239b442bd08a91eaa3fa8156ca06d96f2118f73b Mon Sep 17 00:00:00 2001 From: Will <7099514+Willburd@users.noreply.github.com> Date: Sat, 18 Apr 2026 13:50:41 -0400 Subject: [PATCH] Medical Allergies (#19400) * curse of medical * no benefit * fix that * fix * small fixes * small tweaks * fix * fix --------- Co-authored-by: Cameron Lennox --- code/__defines/species_flags.dm | 8 ++++ code/controllers/subsystems/internal_wiki.dm | 29 ++++++++--- .../living/carbon/human/species/species.dm | 3 +- .../human/species/station/traits/negative.dm | 48 +++++++++++++++++++ code/modules/reagents/machinery/chemalyzer.dm | 2 +- code/modules/reagents/reagents/_reagents.dm | 7 ++- code/modules/reagents/reagents/dispenser.dm | 2 +- code/modules/reagents/reagents/drugs.dm | 1 + code/modules/reagents/reagents/food_drinks.dm | 5 +- code/modules/reagents/reagents/medicine.dm | 10 ++++ 10 files changed, 103 insertions(+), 12 deletions(-) diff --git a/code/__defines/species_flags.dm b/code/__defines/species_flags.dm index 199028181d..1cb97f1012 100644 --- a/code/__defines/species_flags.dm +++ b/code/__defines/species_flags.dm @@ -63,6 +63,14 @@ #define ALLERGEN_POLLEN 0x4000 // Teshari sneezes! Grasses and plants make you have a reaction. #define ALLERGEN_SALT 0x8000 // Chefs beware, can't have fast food! +// Medical allergies +#define MEDALLERGEN_TRICORD 0x1 +#define MEDALLERGEN_BICARD 0x2 +#define MEDALLERGEN_DYLO 0x4 +#define MEDALLERGEN_SPACACIL 0x8 +#define MEDALLERGEN_PERIDAX 0x10 +#define MEDALLERGEN_KELOTANE 0x20 + // Allergen reactions #define AG_PHYS_DMG 0x1 // brute #define AG_BURN_DMG 0x2 // burns diff --git a/code/controllers/subsystems/internal_wiki.dm b/code/controllers/subsystems/internal_wiki.dm index 180dd1b69c..5dcbadf5f5 100644 --- a/code/controllers/subsystems/internal_wiki.dm +++ b/code/controllers/subsystems/internal_wiki.dm @@ -400,9 +400,10 @@ SUBSYSTEM_DEF(internal_wiki) if(length(display_reactions) > 0) data["produces"] = display_reactions -/datum/controller/subsystem/internal_wiki/proc/assemble_allergens(var/allergens) - if(allergens > 0) +/datum/controller/subsystem/internal_wiki/proc/assemble_allergens(allergens,med_allergens) + if(allergens > 0 || med_allergens > 0) var/list/allergies = list() + // foods if(allergens & ALLERGEN_MEAT) allergies.Add("Meat protein") if(allergens & ALLERGEN_FISH) @@ -435,6 +436,19 @@ SUBSYSTEM_DEF(internal_wiki) allergies.Add("Pollen") if(allergens & ALLERGEN_SALT) allergies.Add("Salt") + // meds + if(med_allergens & MEDALLERGEN_TRICORD) + allergies.Add(REAGENT_TRICORDRAZINE) + if(med_allergens & MEDALLERGEN_BICARD) + allergies.Add(REAGENT_BICARIDINE) + if(med_allergens & MEDALLERGEN_DYLO) + allergies.Add(REAGENT_ANTITOXIN) + if(med_allergens & MEDALLERGEN_SPACACIL) + allergies.Add(REAGENT_SPACEACILLIN) + if(med_allergens & MEDALLERGEN_PERIDAX) + allergies.Add(REAGENT_PERIDAXON) + if(med_allergens & MEDALLERGEN_KELOTANE) + allergies.Add(REAGENT_KELOTANE) return allergies return null @@ -602,6 +616,7 @@ SUBSYSTEM_DEF(internal_wiki) "Coating" = R.coating, "Appliance" = R.appliance, "Allergens" = 0, + "Medallergens" = 0, "Price" = initial(res.price_tag), "Flags" = R.wiki_flag ) @@ -623,6 +638,7 @@ SUBSYSTEM_DEF(internal_wiki) "Ingredients" = list(), "Appliance" = 0, "Allergens" = 0, + "Medallergens" = 0, "Flags" = CR.wiki_flag ) //Items needs further processing into human-readability. @@ -676,6 +692,7 @@ SUBSYSTEM_DEF(internal_wiki) food_recipes[Rp]["Reagents"] -= rid food_recipes[Rp]["Reagents"][R_name] = amt food_recipes[Rp]["Allergens"] |= Rd.allergen_type + food_recipes[Rp]["Medallergens"] |= Rd.medallergen_type for(var/rid in food_recipes[Rp]["Catalysts"]) var/datum/reagent/Rd = SSchemistry.chemical_reagents[rid] if(!Rd) // Leaving this here in the event that if rd is ever invalid or there's a recipe issue, it'll be skipped and recipe dumps can still be ran. @@ -1173,7 +1190,7 @@ SUBSYSTEM_DEF(internal_wiki) data["sintering"] = SSinternal_wiki.assemble_sintering(GLOB.reagent_sheets[R.id]) data["overdose"] = R.overdose data["flavor"] = R.taste_description - data["allergen"] = SSinternal_wiki.assemble_allergens(R.allergen_type) + data["allergen"] = SSinternal_wiki.assemble_allergens(R.allergen_type, R.medallergen_type) SSinternal_wiki.assemble_reaction_data(data, R) /datum/internal_wiki/page/chemical/get_print() @@ -1221,7 +1238,7 @@ SUBSYSTEM_DEF(internal_wiki) // Get internal data data["description"] = R.description data["flavor"] = R.taste_description - data["allergen"] = SSinternal_wiki.assemble_allergens(R.allergen_type) + data["allergen"] = SSinternal_wiki.assemble_allergens(R.allergen_type, R.medallergen_type) SSinternal_wiki.assemble_reaction_data(data, R) /datum/internal_wiki/page/food/get_print() @@ -1248,7 +1265,7 @@ SUBSYSTEM_DEF(internal_wiki) // Get internal data data["description"] = R.description data["flavor"] = R.taste_description - data["allergen"] = SSinternal_wiki.assemble_allergens(R.allergen_type) + data["allergen"] = SSinternal_wiki.assemble_allergens(R.allergen_type, R.medallergen_type) SSinternal_wiki.assemble_reaction_data(data, R) /datum/internal_wiki/page/drink/get_print() @@ -1274,7 +1291,7 @@ SUBSYSTEM_DEF(internal_wiki) SSinternal_wiki.add_icon(data, initial(beaker_path.icon), initial(beaker_path.icon_state), "#ffffff") // Get internal data data["description"] = recipe["Desc"] - data["allergen"] = SSinternal_wiki.assemble_allergens(recipe["Allergens"]) + data["allergen"] = SSinternal_wiki.assemble_allergens(recipe["Allergens"], recipe["Medallergens"]) // No med allergens here... var/list/recipe_data = list() var/value = recipe["Price"] ? recipe["Price"] : 0 recipe_data["supply_points"] = value diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 031efd4996..9acd5c6de9 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -54,6 +54,7 @@ var/taste_sensitivity = TASTE_NORMAL // How sensitive the species is to minute tastes. var/allergens = null // Things that will make this species very sick + var/medallergens = null // Medication that will makes this species very sick var/allergen_reaction = AG_TOX_DMG|AG_OXY_DMG|AG_EMOTE|AG_PAIN|AG_BLURRY|AG_CONFUSE // What type of reactions will you have? These the 'main' options and are intended to approximate anaphylactic shock at high doses. var/allergen_damage_severity = 2.5 // How bad are reactions to the allergen? Touch with extreme caution. var/allergen_disable_severity = 10 // Whilst this determines how long nonlethal effects last and how common emotes are. @@ -838,7 +839,7 @@ if(H.species.has_vibration_sense) H.motiontracker_subscribe() - if(H.species.allergens) + if(H.species.allergens || H.species.medallergens) H.AddElement(/datum/element/allergy) else H.RemoveElement(/datum/element/allergy) diff --git a/code/modules/mob/living/carbon/human/species/station/traits/negative.dm b/code/modules/mob/living/carbon/human/species/station/traits/negative.dm index 82e5887a76..887a357845 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits/negative.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits/negative.dm @@ -768,3 +768,51 @@ desc = "You are approximately 50% more susceptible to radiation, and it dissipates slower from your body." cost = -2 var_changes = list("radiation_mod" = 1.5, "rad_removal_mod" = 0.5, "rad_levels" = WEAKENED_RADIATION_RESISTANCE) + +// medical allergens +/datum/trait/negative/medical_allergy + name = "Allergy: " + REAGENT_TRICORDRAZINE + desc = "You're highly allergic to " + REAGENT_TRICORDRAZINE + " and " + REAGENT_TRICORLIDAZE + ", be sure to write that in your medical record! NB: By taking this trait, you acknowledge there is a significant risk your character may suffer a fatal reaction if exposed to this substance." + cost = -1 + custom_only = FALSE + var/medallergen = MEDALLERGEN_TRICORD + + /* Lets show medical some mercy by not making these genes + is_genetrait = TRUE + hidden = FALSE + + activation_message="Something feels odd..." + */ + +/datum/trait/negative/medical_allergy/apply(var/datum/species/S,var/mob/living/carbon/human/H) + S.medallergens |= medallergen + ..() + +/datum/trait/negative/medical_allergy/unapply(var/datum/species/S,var/mob/living/carbon/human/H) + S.medallergens &= ~medallergen + ..() + +/datum/trait/negative/medical_allergy/bicard + name = "Allergy: " + REAGENT_BICARIDINE + desc = "You're highly allergic to " + REAGENT_BICARIDINE + " and " + REAGENT_BICARIDAZE + ", be sure to write that in your medical record! NB: By taking this trait, you acknowledge there is a significant risk your character may suffer a fatal reaction if exposed to this substance." + medallergen = MEDALLERGEN_BICARD + +/datum/trait/negative/medical_allergy/dylo + name = "Allergy: " + REAGENT_ANTITOXIN + desc = "You're highly allergic to " + REAGENT_ANTITOXIN + ", be sure to write that in your medical record! NB: By taking this trait, you acknowledge there is a significant risk your character may suffer a fatal reaction if exposed to this substance." + medallergen = MEDALLERGEN_DYLO + +/datum/trait/negative/medical_allergy/spacacillin + name = "Allergy: " + REAGENT_SPACEACILLIN + desc = "You're highly allergic to " + REAGENT_SPACEACILLIN + ", be sure to write that in your medical record! NB: By taking this trait, you acknowledge there is a significant risk your character may suffer a fatal reaction if exposed to this substance." + medallergen = MEDALLERGEN_SPACACIL + +/datum/trait/negative/medical_allergy/peridaxon + name = "Allergy: " + REAGENT_PERIDAXON + desc = "You're highly allergic to " + REAGENT_PERIDAXON + ", be sure to write that in your medical record! NB: By taking this trait, you acknowledge there is a significant risk your character may suffer a fatal reaction if exposed to this substance." + medallergen = MEDALLERGEN_PERIDAX + +/datum/trait/negative/medical_allergy/kelotane + name = "Allergy: " + REAGENT_KELOTANE + desc = "You're highly allergic to " + REAGENT_KELOTANE + ", " + REAGENT_DERMALINE + " and " + REAGENT_DERMALAZE + ", be sure to write that in your medical record! NB: By taking this trait, you acknowledge there is a significant risk your character may suffer a fatal reaction if exposed to this substance." + medallergen = MEDALLERGEN_KELOTANE diff --git a/code/modules/reagents/machinery/chemalyzer.dm b/code/modules/reagents/machinery/chemalyzer.dm index bc6ef3577f..1a6290c3d9 100644 --- a/code/modules/reagents/machinery/chemalyzer.dm +++ b/code/modules/reagents/machinery/chemalyzer.dm @@ -102,7 +102,7 @@ subdata["sintering"] = SSinternal_wiki.assemble_sintering(GLOB.reagent_sheets[R.id]) subdata["overdose"] = R.overdose subdata["flavor"] = R.taste_description - subdata["allergen"] = SSinternal_wiki.assemble_allergens(R.allergen_type) + subdata["allergen"] = SSinternal_wiki.assemble_allergens(R.allergen_type, R.medallergen_type) subdata["beakerAmount"] = found_reagents[ID] total_vol += found_reagents[ID] SSinternal_wiki.assemble_reaction_data(subdata, R) diff --git a/code/modules/reagents/reagents/_reagents.dm b/code/modules/reagents/reagents/_reagents.dm index a8eccfcca8..cfaaef795c 100644 --- a/code/modules/reagents/reagents/_reagents.dm +++ b/code/modules/reagents/reagents/_reagents.dm @@ -24,6 +24,7 @@ var/affects_robots = 0 // Does this chem process inside a Synth? var/allergen_type // What potential allergens does this contain? + var/medallergen_type // What potential medical allergens does this contain? var/allergen_factor = 2 // If the potential allergens are mixed and low-volume, they're a bit less dangerous. Needed for drinks because they're a single reagent compared to food which contains multiple seperate reagents. var/cup_icon_state = null @@ -179,6 +180,10 @@ removed = min(removed, volume) max_dose = max(volume, max_dose) dose = min(dose + removed, max_dose) + if(M.species.medallergens & medallergen_type) // Medical allergies don't gain ANY benefits... + M.add_chemical_effect(CE_ALLERGEN, allergen_factor * removed) + remove_self(removed) + return switch(active_metab.metabolism_class) if(CHEM_BLOOD) affect_blood(M, alien, removed) @@ -192,7 +197,7 @@ on_mob_metabolize(M, location) if(overdose && (volume > overdose * M?.species.chemOD_threshold) && (active_metab.metabolism_class != CHEM_TOUCH || can_overdose_touch)) overdose(M, alien, removed) - if(M.species.allergens & allergen_type) //uhoh, we can't handle this! + if((M.species.allergens & allergen_type)) //uhoh, we can't handle this! M.add_chemical_effect(CE_ALLERGEN, allergen_factor * removed) remove_self(removed) return diff --git a/code/modules/reagents/reagents/dispenser.dm b/code/modules/reagents/reagents/dispenser.dm index a82a8c8457..92623ab1c9 100644 --- a/code/modules/reagents/reagents/dispenser.dm +++ b/code/modules/reagents/reagents/dispenser.dm @@ -176,7 +176,7 @@ if(issmall(M)) removed *= 2 - if(!(M.species.allergens & allergen_type) && !(M.isSynthetic())) //assuming it doesn't cause a horrible reaction, we get the nutrition effects - VOREStation Edit (added synth check) + if(!(M.species.allergens & allergen_type) && !(M.species.medallergens & medallergen_type) && !(M.isSynthetic())) //assuming it doesn't cause a horrible reaction, we get the nutrition effects - VOREStation Edit (added synth check) M.adjust_nutrition(nutriment_factor * removed) if(M.isSynthetic() && M.nutrition < 500 && M.species.robo_ethanol_proc) diff --git a/code/modules/reagents/reagents/drugs.dm b/code/modules/reagents/reagents/drugs.dm index 46a33cd0de..4c9de3e73b 100644 --- a/code/modules/reagents/reagents/drugs.dm +++ b/code/modules/reagents/reagents/drugs.dm @@ -21,6 +21,7 @@ reagent_state = LIQUID metabolism = REM * 0.5 ingest_met = REM * 1.5 /// Be very careful with this, ingestion is weird and will spam high/sober messages horribly! + allergen_factor = 3 // Allergic reactions to concentrated medications should be pretty strong dermal_absorption = 0 mrate_static = TRUE overdose = REAGENTS_OVERDOSE diff --git a/code/modules/reagents/reagents/food_drinks.dm b/code/modules/reagents/reagents/food_drinks.dm index 2e512cd9ea..10cfd3b19a 100644 --- a/code/modules/reagents/reagents/food_drinks.dm +++ b/code/modules/reagents/reagents/food_drinks.dm @@ -62,7 +62,7 @@ if(issmall(M)) removed *= 2 // Small bodymass, more effect from lower volume. //VOREStation Edits Start if(!M.isSynthetic()) - if(!(M.species.allergens & allergen_type)) //assuming it doesn't cause a horrible reaction, we'll be ok! + if(!(M.species.allergens & allergen_type) && !(M.species.medallergens & medallergen_type)) //assuming it doesn't cause a horrible reaction, we'll be ok! M.heal_organ_damage(0.5 * removed, 0) M.adjust_nutrition(((nutriment_factor + M.food_preference(allergen_type)) * removed) * M.species.organic_food_coeff) //RS edit M.add_chemical_effect(CE_BLOODRESTORE, 4 * removed) @@ -1053,7 +1053,7 @@ return /datum/reagent/drink/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) - if(!(M.species.allergens & allergen_type)) + if(!(M.species.allergens & allergen_type) && !(M.species.medallergens & medallergen_type)) var/bonus = M.food_preference(allergen_type) M.adjust_nutrition((nutrition + bonus) * removed) M.make_dizzy(adj_dizzy) @@ -2544,6 +2544,7 @@ glass_name = REAGENT_DOCTORSDELIGHT glass_desc = "A healthy mixture of juices, guaranteed to keep you healthy until the next toolboxing takes place." allergen_type = ALLERGEN_FRUIT|ALLERGEN_DAIRY //Made from several fruit juices, and cream. + medallergen_type = MEDALLERGEN_TRICORD // this too! /datum/reagent/drink/doctor_delight/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) ..() diff --git a/code/modules/reagents/reagents/medicine.dm b/code/modules/reagents/reagents/medicine.dm index 3a1a373fdd..d7493a0277 100644 --- a/code/modules/reagents/reagents/medicine.dm +++ b/code/modules/reagents/reagents/medicine.dm @@ -59,6 +59,7 @@ scannable = SCANNABLE_BENEFICIAL supply_conversion_value = REFINERYEXPORT_VALUE_PROCESSED industrial_use = REFINERYEXPORT_REASON_DRUG + medallergen_type = MEDALLERGEN_BICARD /datum/reagent/bicaridine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) var/chem_effective = 1 * M.species.chem_strength_heal @@ -98,6 +99,7 @@ can_overdose_touch = TRUE supply_conversion_value = REFINERYEXPORT_VALUE_HIGHREFINED industrial_use = REFINERYEXPORT_REASON_SPECIALDRUG + medallergen_type = MEDALLERGEN_BICARD /datum/reagent/bicaridine/topical/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) var/chem_effective = 1 * M.species.chem_strength_heal @@ -148,6 +150,7 @@ scannable = SCANNABLE_BENEFICIAL supply_conversion_value = REFINERYEXPORT_VALUE_COMMON industrial_use = REFINERYEXPORT_REASON_DRUG + medallergen_type = MEDALLERGEN_KELOTANE /datum/reagent/kelotane/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) var/chem_effective = 1 * M.species.chem_strength_heal @@ -171,6 +174,7 @@ scannable = SCANNABLE_BENEFICIAL supply_conversion_value = REFINERYEXPORT_VALUE_PROCESSED industrial_use = REFINERYEXPORT_REASON_DRUG + medallergen_type = MEDALLERGEN_KELOTANE /datum/reagent/dermaline/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) var/chem_effective = 1 * M.species.chem_strength_heal @@ -193,6 +197,7 @@ can_overdose_touch = TRUE supply_conversion_value = REFINERYEXPORT_VALUE_HIGHREFINED industrial_use = REFINERYEXPORT_REASON_SPECIALDRUG + medallergen_type = MEDALLERGEN_KELOTANE /datum/reagent/dermaline/topical/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) var/chem_effective = 1 * M.species.chem_strength_heal @@ -220,6 +225,7 @@ scannable = SCANNABLE_BENEFICIAL supply_conversion_value = REFINERYEXPORT_VALUE_COMMON industrial_use = REFINERYEXPORT_REASON_DRUG + medallergen_type = MEDALLERGEN_DYLO /datum/reagent/dylovene/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) var/chem_effective = 1 * M.species.chem_strength_heal @@ -339,6 +345,7 @@ scannable = SCANNABLE_BENEFICIAL supply_conversion_value = REFINERYEXPORT_VALUE_PROCESSED industrial_use = REFINERYEXPORT_REASON_DRUG + medallergen_type = MEDALLERGEN_TRICORD /datum/reagent/tricordrazine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(alien != IS_DIONA) @@ -364,6 +371,7 @@ can_overdose_touch = TRUE supply_conversion_value = REFINERYEXPORT_VALUE_HIGHREFINED industrial_use = REFINERYEXPORT_REASON_SPECIALDRUG + medallergen_type = MEDALLERGEN_TRICORD /datum/reagent/tricorlidaze/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) if(alien != IS_DIONA) @@ -751,6 +759,7 @@ scannable = SCANNABLE_BENEFICIAL supply_conversion_value = REFINERYEXPORT_VALUE_HIGHREFINED industrial_use = REFINERYEXPORT_REASON_SPECIALDRUG + medallergen_type = MEDALLERGEN_PERIDAX /datum/reagent/peridaxon/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(ishuman(M)) @@ -1218,6 +1227,7 @@ data = 0 supply_conversion_value = REFINERYEXPORT_VALUE_COMMON industrial_use = REFINERYEXPORT_REASON_DRUG + medallergen_type = MEDALLERGEN_SPACACIL /datum/reagent/spaceacillin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) ..()