From 1ba7fa7fa8e0bd9deec7d0e18ed9cc7579f820d9 Mon Sep 17 00:00:00 2001 From: Bloop Date: Mon, 13 Feb 2023 23:43:28 -0500 Subject: [PATCH] [NO GBP] Hotfixes lungless oxyloss immunity, and lungless plasmamen being able to be healed by salbutanol etc. (#73291) ## About The Pull Request I had thought I took care of this edge case but I was mistaken. ## Why It's Good For The Game Fixes the edge case of a removed lung preventing oxyloss damage in carbon mobs. Big derp. --- Also took care of the case of mobs without lungs being injected with oxyloss healing chems by adding a `mob_respiration_type` var. This essentially just makes it so that plasmamen without lungs can no longer be healed by salbutanol etc. They are currently the only mob with a different respiration type than the default, so this particular bug only affected them. In the future this will be important as chems that target other respiration types are added. The `mob_respiration_type` var also allows for simple mobs to have their own respiration types defined. By default everything is `RESPIRATION_OXYGEN,` so there is no difference from how it was before unless you specify a different type for that particular mob. ## Changelog :cl: fix: hotfix for lungless oxyloss immunity fix: hotfix for mobs being able to circumvent reagent respiration_type requirements by removing their lungs /:cl: --- code/_globalvars/bitfields.dm | 7 +++++ .../mob/living/carbon/human/species.dm | 3 ++ .../carbon/human/species_types/plasmamen.dm | 1 + code/modules/mob/living/damage_procs.dm | 30 ++++++++++++------- code/modules/mob/living/living_defines.dm | 3 ++ .../chemistry/reagents/medicine_reagents.dm | 24 ++++++++------- 6 files changed, 48 insertions(+), 20 deletions(-) diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index d4e521c52b4..803615b8204 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -257,6 +257,13 @@ DEFINE_BITFIELD(mob_biotypes, list( "MOB_PLANT" = MOB_PLANT )) +DEFINE_BITFIELD(mob_respiration_type, list( + "RESPIRATION_OXYGEN" = RESPIRATION_OXYGEN, + "RESPIRATION_CO2" = RESPIRATION_CO2, + "RESPIRATION_N2" = RESPIRATION_N2, + "RESPIRATION_PLASMA" = RESPIRATION_PLASMA, +)) + DEFINE_BITFIELD(mobility_flags, list( "MOVE" = MOBILITY_MOVE, "PICKUP" = MOBILITY_PICKUP, diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 513b513590d..732ff139be5 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -152,6 +152,8 @@ GLOBAL_LIST_EMPTY(features_by_species) var/list/inherent_traits = list() /// List of biotypes the mob belongs to. Used by diseases. var/inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID + /// The type of respiration the mob is capable of doing. Used by adjustOxyLoss. + var/inherent_respiration_type = RESPIRATION_OXYGEN ///List of factions the mob gain upon gaining this species. var/list/inherent_factions @@ -450,6 +452,7 @@ GLOBAL_LIST_EMPTY(features_by_species) C.adjustToxLoss(-C.getToxLoss(), forced = TRUE) // clear the organic toxin damage upon turning into a MOB_MINERAL, as they are now immune C.mob_biotypes = inherent_biotypes + C.mob_respiration_type = inherent_respiration_type if (old_species.type != type) replace_body(C, src) diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index 14c72099a02..eaf10de33a1 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -17,6 +17,7 @@ ) inherent_biotypes = MOB_HUMANOID|MOB_MINERAL + inherent_respiration_type = RESPIRATION_PLASMA mutantlungs = /obj/item/organ/internal/lungs/plasmaman mutanttongue = /obj/item/organ/internal/tongue/bone/plasmaman mutantliver = /obj/item/organ/internal/liver/plasmaman diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index 0c416c8f001..dc94dd17388 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -182,12 +182,17 @@ return oxyloss /mob/living/proc/adjustOxyLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype, required_respiration_type = ALL) - if(!forced && (status_flags & GODMODE)) - return - if(iscarbon(src)) - var/obj/item/organ/internal/lungs/affected_lungs = getorganslot(ORGAN_SLOT_LUNGS) - if(!forced && !(affected_lungs?.respiration_type & required_respiration_type)) + if(!forced) + if(status_flags & GODMODE) return + + var/obj/item/organ/internal/lungs/affected_lungs = getorganslot(ORGAN_SLOT_LUNGS) + if(isnull(affected_lungs)) + if(!(mob_respiration_type & required_respiration_type)) // if the mob has no lungs, use mob_respiration_type + return + else + if(!(affected_lungs.respiration_type & required_respiration_type)) // otherwise use the lungs' respiration_type + return . = oxyloss oxyloss = clamp((oxyloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) if(updating_health) @@ -195,12 +200,17 @@ /mob/living/proc/setOxyLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype, required_respiration_type = ALL) - if(!forced && (status_flags & GODMODE)) - return - if(iscarbon(src)) - var/obj/item/organ/internal/lungs/affected_lungs = getorganslot(ORGAN_SLOT_LUNGS) - if(!forced && !(affected_lungs?.respiration_type & required_respiration_type)) + if(!forced) + if(status_flags & GODMODE) return + + var/obj/item/organ/internal/lungs/affected_lungs = getorganslot(ORGAN_SLOT_LUNGS) + if(isnull(affected_lungs)) + if(!(mob_respiration_type & required_respiration_type)) + return + else + if(!(affected_lungs.respiration_type & required_respiration_type)) + return . = oxyloss oxyloss = amount if(updating_health) diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index f092f7f68cd..a3077c6e577 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -99,7 +99,10 @@ var/limb_destroyer = 0 var/mob_size = MOB_SIZE_HUMAN + /// List of biotypes the mob belongs to. Used by diseases and reagents mainly. var/mob_biotypes = MOB_ORGANIC + /// The type of respiration the mob is capable of doing. Used by adjustOxyLoss. + var/mob_respiration_type = RESPIRATION_OXYGEN ///more or less efficiency to metabolize helpful/harmful reagents and regulate body temperature.. var/metabolism_efficiency = 1 ///does the mob have distinct limbs?(arms,legs, chest,head) diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 18ed9ea39eb..34bad684029 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -493,9 +493,10 @@ /datum/reagent/medicine/salbutamol/on_mob_life(mob/living/carbon/affected_mob, delta_time, times_fired) affected_mob.adjustOxyLoss(-3 * REM * delta_time, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - var/obj/item/organ/internal/lungs/affected_lungs = affected_mob.getorganslot(ORGAN_SLOT_LUNGS) - if(affected_lungs?.respiration_type & affected_respiration_type) - if(affected_mob.losebreath >= 4) + if(affected_mob.losebreath >= 4) + var/obj/item/organ/internal/lungs/affected_lungs = affected_mob.getorganslot(ORGAN_SLOT_LUNGS) + var/our_respiration_type = affected_lungs ? affected_lungs.respiration_type : affected_mob.mob_respiration_type // use lungs' respiration type or mob_respiration_type if no lungs + if(our_respiration_type & affected_respiration_type) affected_mob.losebreath -= 2 * REM * delta_time ..() . = TRUE @@ -750,7 +751,8 @@ affected_mob.adjustOxyLoss(-5 * REM * delta_time, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) . = TRUE var/obj/item/organ/internal/lungs/affected_lungs = affected_mob.getorganslot(ORGAN_SLOT_LUNGS) - if(affected_lungs?.respiration_type & affected_respiration_type) + var/our_respiration_type = affected_lungs ? affected_lungs.respiration_type : affected_mob.mob_respiration_type + if(our_respiration_type & affected_respiration_type) affected_mob.losebreath = 0 if(DT_PROB(10, delta_time)) affected_mob.set_dizzy_if_lower(10 SECONDS) @@ -796,12 +798,13 @@ affected_mob.adjustBruteLoss(-0.5 * REM * delta_time, FALSE, required_bodytype = affected_bodytype) affected_mob.adjustFireLoss(-0.5 * REM * delta_time, FALSE, required_bodytype = affected_bodytype) affected_mob.adjustOxyLoss(-0.5 * REM * delta_time, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - var/obj/item/organ/internal/lungs/affected_lungs = affected_mob.getorganslot(ORGAN_SLOT_LUNGS) - if(affected_lungs?.respiration_type & affected_respiration_type) - if(affected_mob.losebreath >= 4) + if(affected_mob.losebreath >= 4) + var/obj/item/organ/internal/lungs/affected_lungs = affected_mob.getorganslot(ORGAN_SLOT_LUNGS) + var/our_respiration_type = affected_lungs ? affected_lungs.respiration_type : affected_mob.mob_respiration_type + if(our_respiration_type & affected_respiration_type) affected_mob.losebreath -= 2 * REM * delta_time - if(affected_mob.losebreath < 0) - affected_mob.losebreath = 0 + if(affected_mob.losebreath < 0) + affected_mob.losebreath = 0 affected_mob.adjustStaminaLoss(-0.5 * REM * delta_time, 0) if(DT_PROB(10, delta_time)) affected_mob.AdjustAllImmobility(-20) @@ -812,7 +815,8 @@ affected_mob.adjustStaminaLoss(2.5, 0) affected_mob.adjustToxLoss(1, FALSE, required_biotype = affected_biotype) var/obj/item/organ/internal/lungs/affected_lungs = affected_mob.getorganslot(ORGAN_SLOT_LUNGS) - if(affected_lungs?.respiration_type & affected_respiration_type) + var/our_respiration_type = affected_lungs ? affected_lungs.respiration_type : affected_mob.mob_respiration_type + if(our_respiration_type & affected_respiration_type) affected_mob.losebreath++ . = TRUE ..()