Fixes changeling void adaption (#91626)

This PR changes `TRAIT_SPACEBREATHING` from a lung trait to a mob trait,
and simultaneously renames it to the much less snappy but simultaneously
more specific `TRAIT_NO_BREATHLESS_DAMAGE`
This proc technically does not allow you to breathe specifically in
space, it only bypasses any checks for minimum levels of gases
regardless of if you are in space or not

At the same time I implemented it for basic mobs, just because I can. I
don't think they have any way of gaining it, but if some future dev was
going to make a temporary buff that lets something breathe in space now
it could also work on basic mobs.

This is how developers expected the trait to work and no longer requires
that the mob have lungs to be used

🆑
fix: Changelings with Void Adaption can once again breathe in space
/🆑
This commit is contained in:
Jacquerel
2025-06-19 05:12:25 +01:00
committed by Roxy
parent b119bf3791
commit ab163f6516
9 changed files with 28 additions and 29 deletions

View File

@@ -410,6 +410,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// Increases chance of getting special traumas, makes them harder to cure
#define TRAIT_SPECIAL_TRAUMA_BOOST "special_trauma_boost"
#define TRAIT_SPACEWALK "spacewalk"
/// Mobs with this trait still breathe gas in and out but aren't harmed by lacking any particular gas mix. (You can still be hurt by TOO MUCH of a specific gas).
#define TRAIT_NO_BREATHLESS_DAMAGE "spacebreathing"
/// Sanity trait to keep track of when we're in hyperspace and add the appropriate element if we weren't
#define TRAIT_HYPERSPACED "hyperspaced"
///Gives the movable free hyperspace movement without being pulled during shuttle transit
@@ -654,10 +656,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_CORONER_METABOLISM "coroner_metabolism"
#define TRAIT_HUMAN_AI_METABOLISM "human_ai_metabolism"
//LUNG TRAITS
/// Lungs always breathe normally when in vacuum/space.
#define TRAIT_SPACEBREATHING "spacebreathing"
/// This mob can strip other mobs.
#define TRAIT_CAN_STRIP "can_strip"
/// Can use the nuclear device's UI, regardless of a lack of hands

View File

@@ -420,6 +420,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_NOSOFTCRIT" = TRAIT_NOSOFTCRIT,
"TRAIT_NO_AUGMENTS" = TRAIT_NO_AUGMENTS,
"TRAIT_NO_BLOOD_OVERLAY" = TRAIT_NO_BLOOD_OVERLAY,
"TRAIT_NO_BREATHLESS_DAMAGE" = TRAIT_NO_BREATHLESS_DAMAGE,
"TRAIT_NO_DAMAGE_OVERLAY" = TRAIT_NO_DAMAGE_OVERLAY,
"TRAIT_NO_DEBRAIN_OVERLAY" = TRAIT_NO_DEBRAIN_OVERLAY,
"TRAIT_NO_DNA_COPY" = TRAIT_NO_DNA_COPY,
@@ -763,9 +764,6 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_PRETENDER_ROYAL_METABOLISM" = TRAIT_PRETENDER_ROYAL_METABOLISM,
"TRAIT_ROYAL_METABOLISM" = TRAIT_ROYAL_METABOLISM,
),
/obj/item/organ/lungs = list(
"TRAIT_SPACEBREATHING" = TRAIT_SPACEBREATHING,
),
/obj/machinery/modular_computer = list(
"TRAIT_MODPC_INTERACTING_WITH_FRAME" = TRAIT_MODPC_INTERACTING_WITH_FRAME,
),

View File

@@ -188,6 +188,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list(
"TRAIT_NIGHT_VISION" = TRAIT_NIGHT_VISION,
"TRAIT_NO_AUGMENTS" = TRAIT_NO_AUGMENTS,
"TRAIT_NO_BLOOD_OVERLAY" = TRAIT_NO_BLOOD_OVERLAY,
"TRAIT_NO_BREATHLESS_DAMAGE" = TRAIT_NO_BREATHLESS_DAMAGE,
"TRAIT_NO_DNA_COPY" = TRAIT_NO_DNA_COPY,
"TRAIT_NO_EXTINGUISH" = TRAIT_NO_EXTINGUISH,
"TRAIT_NO_GLIDE" = TRAIT_NO_GLIDE,
@@ -409,9 +410,6 @@ GLOBAL_LIST_INIT(admin_visible_traits, list(
"TRAIT_PRETENDER_ROYAL_METABOLISM" = TRAIT_PRETENDER_ROYAL_METABOLISM,
"TRAIT_ROYAL_METABOLISM" = TRAIT_ROYAL_METABOLISM,
),
/obj/item/organ/lungs = list(
"TRAIT_SPACEBREATHING" = TRAIT_SPACEBREATHING,
),
// SKYRAT EDIT ADDITION START - SKYRAT TRAITS
/obj/item/toy/plush/skyrat = list(
"TRAIT_AFFECTION_AVERSION" = TRAIT_AFFECTION_AVERSION,

View File

@@ -49,21 +49,30 @@
if(!isopenturf(target.loc))
return TRUE
var/can_breathe_vacuum = HAS_TRAIT(target, TRAIT_NO_BREATHLESS_DAMAGE)
var/min_oxy = can_breathe_vacuum ? 0 : atmos_requirements["min_oxy"]
var/min_plasma = can_breathe_vacuum ? 0 : atmos_requirements["min_plas"]
var/min_n2 = can_breathe_vacuum ? 0 : atmos_requirements["min_n2"]
var/min_co2 = can_breathe_vacuum ? 0 : atmos_requirements["min_co2"]
var/turf/open/open_turf = target.loc
if(isnull(open_turf.air))
if(atmos_requirements["min_oxy"] || atmos_requirements["min_plas"] || atmos_requirements["min_n2"] || atmos_requirements["min_co2"])
if (can_breathe_vacuum)
return TRUE
if(min_oxy || min_plasma || min_n2 || min_co2)
return FALSE
return TRUE
var/list/gases = get_atmos_req_list(open_turf)
if(!ISINRANGE(gases["oxy"], atmos_requirements["min_oxy"], (atmos_requirements["max_oxy"] || INFINITY)))
if(!ISINRANGE(gases["oxy"], min_oxy, (atmos_requirements["max_oxy"] || INFINITY)))
return FALSE
if(!ISINRANGE(gases["plas"], atmos_requirements["min_plas"], (atmos_requirements["max_plas"] || INFINITY)))
if(!ISINRANGE(gases["plas"], min_plasma, (atmos_requirements["max_plas"] || INFINITY)))
return FALSE
if(!ISINRANGE(gases["n2"], atmos_requirements["min_n2"], (atmos_requirements["max_n2"] || INFINITY)))
if(!ISINRANGE(gases["n2"], min_n2, (atmos_requirements["max_n2"] || INFINITY)))
return FALSE
if(!ISINRANGE(gases["co2"], atmos_requirements["min_co2"], (atmos_requirements["max_co2"] || INFINITY)))
if(!ISINRANGE(gases["co2"], min_co2, (atmos_requirements["max_co2"] || INFINITY)))
return FALSE
return TRUE

View File

@@ -28,13 +28,12 @@
post_init_icon_state = "lungs"
greyscale_config = /datum/greyscale_config/mutant_organ
greyscale_colors = CARP_COLORS
organ_traits = list(TRAIT_NODROWN)
organ_traits = list(TRAIT_NODROWN, TRAIT_NO_BREATHLESS_DAMAGE)
/obj/item/organ/lungs/carp/Initialize(mapload)
. = ..()
AddElement(/datum/element/noticable_organ, "%PRONOUN_Their neck has odd gills.", BODY_ZONE_HEAD)
AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/carp)
ADD_TRAIT(src, TRAIT_SPACEBREATHING, REF(src))
///occasionally sheds carp teeth, stronger melee (bite) attacks, but you can't cover your mouth anymore.
/obj/item/organ/tongue/carp

View File

@@ -306,7 +306,7 @@
/// Requires the spaceman to have either water vapor or be wet.
/obj/item/organ/lungs/fish/proc/breathe_water(mob/living/carbon/breather, datum/gas_mixture/breath, water_pp, old_water_pp)
var/need_to_breathe = !HAS_TRAIT(src, TRAIT_SPACEBREATHING) && !HAS_TRAIT(breather, TRAIT_IS_WET)
var/need_to_breathe = !HAS_TRAIT(breather, TRAIT_NO_BREATHLESS_DAMAGE) && !HAS_TRAIT(breather, TRAIT_IS_WET)
if(water_pp < safe_water_level && need_to_breathe)
on_low_water(breather, breath, water_pp)
return

View File

@@ -8,7 +8,7 @@
dna_cost = 2
/// Traits we apply to become immune to the environment
var/static/list/gain_traits = list(TRAIT_SPACEBREATHING, TRAIT_RESISTCOLD, TRAIT_RESISTLOWPRESSURE, TRAIT_SNOWSTORM_IMMUNE)
var/static/list/gain_traits = list(TRAIT_NO_BREATHLESS_DAMAGE, TRAIT_RESISTCOLD, TRAIT_RESISTLOWPRESSURE, TRAIT_SNOWSTORM_IMMUNE)
/// How much we slow chemical regeneration while active, in chems per second
var/recharge_slowdown = 0.25
/// Are we currently protecting our user?

View File

@@ -198,12 +198,7 @@
var/obj/item/organ/lungs = get_organ_slot(ORGAN_SLOT_LUNGS)
// Indicates if lungs can breathe without gas.
var/can_breathe_vacuum = FALSE
if(lungs)
// Breathing with lungs.
// Check for vacuum-adapted lungs.
can_breathe_vacuum = HAS_TRAIT(lungs, TRAIT_SPACEBREATHING)
else
if(!lungs)
// Lungs are missing! Can't breathe.
// Simulates breathing zero moles of gas.
has_moles = FALSE
@@ -236,6 +231,8 @@
var/nitrium_pp = 0
var/miasma_pp = 0
var/can_breathe_vacuum = HAS_TRAIT(src, TRAIT_NO_BREATHLESS_DAMAGE)
// Check for moles of gas and handle partial pressures / special conditions.
if(has_moles)
// Breath has more than 0 moles of gas.

View File

@@ -235,7 +235,7 @@
/// Handles oxygen breathing. Always called by things that need o2, no matter what
/obj/item/organ/lungs/proc/breathe_oxygen(mob/living/carbon/breather, datum/gas_mixture/breath, o2_pp, old_o2_pp)
if(o2_pp < safe_oxygen_min && !HAS_TRAIT(src, TRAIT_SPACEBREATHING))
if(o2_pp < safe_oxygen_min && !HAS_TRAIT(breather, TRAIT_NO_BREATHLESS_DAMAGE))
// Not safe to check the old pp because of can_breath_vacuum
breather.throw_alert(ALERT_NOT_ENOUGH_OXYGEN, /atom/movable/screen/alert/not_enough_oxy)
@@ -282,7 +282,7 @@
/// If the lungs need Nitrogen to breathe properly, N2 is exchanged with CO2.
/obj/item/organ/lungs/proc/breathe_nitro(mob/living/carbon/breather, datum/gas_mixture/breath, nitro_pp, old_nitro_pp)
if(nitro_pp < safe_nitro_min && !HAS_TRAIT(src, TRAIT_SPACEBREATHING))
if(nitro_pp < safe_nitro_min && !HAS_TRAIT(breather, TRAIT_NO_BREATHLESS_DAMAGE))
// Suffocation side-effects.
// Not safe to check the old pp because of can_breath_vacuum
if(!HAS_TRAIT(breather, TRAIT_ANOSMIA))
@@ -337,7 +337,7 @@
/// If the lungs need Plasma to breathe properly, Plasma is exchanged with CO2.
/obj/item/organ/lungs/proc/breathe_plasma(mob/living/carbon/breather, datum/gas_mixture/breath, plasma_pp, old_plasma_pp)
// Suffocation side-effects.
if(plasma_pp < safe_plasma_min && !HAS_TRAIT(src, TRAIT_SPACEBREATHING))
if(plasma_pp < safe_plasma_min && !HAS_TRAIT(breather, TRAIT_NO_BREATHLESS_DAMAGE))
// Could check old_plasma_pp but vacuum breathing hates me
if(!HAS_TRAIT(breather, TRAIT_ANOSMIA))
breather.throw_alert(ALERT_NOT_ENOUGH_PLASMA, /atom/movable/screen/alert/not_enough_plas)
@@ -616,7 +616,7 @@
if(istype(breather.wear_mask) && (breather.wear_mask.clothing_flags & GAS_FILTERING) && breather.wear_mask.has_filter)
breath = breather.wear_mask.consume_filter(breath)
// Breath has 0 moles of gas, and we can breathe space
else if(HAS_TRAIT(src, TRAIT_SPACEBREATHING))
else if(HAS_TRAIT(breather, TRAIT_NO_BREATHLESS_DAMAGE))
// The lungs can breathe anyways. What are you? Some bottom-feeding, scum-sucking algae eater?
breather.failed_last_breath = FALSE
// Vacuum-adapted lungs regenerate oxyloss even when breathing nothing.