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 ..()