mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-07-12 23:54:24 +01:00
Partial breathing refactor
Reorganizes breathing, and moves common human/monkey breathing code into carbon. handle_breath() is largely unchanged. Removes unnecessary handle_internal_lifeform(). Fixes monkies being held by people in mecha in space not being able to breathe.
This commit is contained in:
@@ -15,18 +15,6 @@
|
||||
processing_objects.Remove(src)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/holder/return_air()
|
||||
var/turf/T = get_turf(src)
|
||||
return T.return_air()
|
||||
|
||||
/obj/item/weapon/holder/handle_internal_lifeform(mob/lifeform_inside_me, breath_request)
|
||||
var/turf/T = get_turf(src)
|
||||
return T.remove_air(breath_request)
|
||||
|
||||
/obj/item/weapon/holder/assume_air(var/mixture)
|
||||
var/turf/T = get_turf(src)
|
||||
return T.assume_air(mixture)
|
||||
|
||||
/obj/item/weapon/holder/process()
|
||||
|
||||
if(istype(loc,/turf) || !(contents.len))
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
//Common breathing procs
|
||||
|
||||
/mob/living/carbon/proc/breathe()
|
||||
//if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return
|
||||
if(species && (species.flags & NO_BREATHE || species.flags & IS_SYNTHETIC)) return
|
||||
|
||||
var/datum/gas_mixture/breath = null
|
||||
|
||||
//First, check if we can breathe at all
|
||||
if(health < config.health_threshold_crit && !reagents.has_reagent("inaprovaline")) //crit aka circulatory shock
|
||||
losebreath++
|
||||
|
||||
if(losebreath>0) //Suffocating so do not take a breath
|
||||
losebreath--
|
||||
if (prob(10)) //Gasp per 10 ticks? Sounds about right.
|
||||
spawn emote("gasp")
|
||||
else
|
||||
//Okay, we can breathe, now check if we can get air
|
||||
breath = get_breath_from_internal() //First, check for air from internals
|
||||
if(!breath)
|
||||
breath = get_breath_from_environment() //No breath from internals so let's try to get air from our location
|
||||
|
||||
handle_breath(breath)
|
||||
handle_post_breath(breath)
|
||||
|
||||
/mob/living/carbon/proc/get_breath_from_internal(var/volume_needed=BREATH_VOLUME) //hopefully this will allow overrides to specify a different default volume without breaking any cases where volume is passed in.
|
||||
if(internal)
|
||||
if (!contents.Find(internal))
|
||||
internal = null
|
||||
if (!(wear_mask && (wear_mask.flags & AIRTIGHT)))
|
||||
internal = null
|
||||
if(internal)
|
||||
if (internals)
|
||||
internals.icon_state = "internal1"
|
||||
return internal.remove_air_volume(volume_needed)
|
||||
else
|
||||
if (internals)
|
||||
internals.icon_state = "internal0"
|
||||
return null
|
||||
|
||||
/mob/living/carbon/proc/get_breath_from_environment(var/volume_needed=BREATH_VOLUME)
|
||||
var/datum/gas_mixture/breath = null
|
||||
|
||||
var/datum/gas_mixture/environment
|
||||
if(loc)
|
||||
environment = loc.return_air_for_internal_lifeform()
|
||||
|
||||
if(environment)
|
||||
breath = environment.remove_volume(volume_needed)
|
||||
handle_chemical_smoke(environment) //handle chemical smoke while we're at it
|
||||
|
||||
if(breath)
|
||||
//handle mask filtering
|
||||
if(istype(wear_mask, /obj/item/clothing/mask) && breath)
|
||||
var/obj/item/clothing/mask/M = wear_mask
|
||||
var/datum/gas_mixture/filtered = M.filter_air(breath)
|
||||
loc.assume_air(filtered)
|
||||
return breath
|
||||
return null
|
||||
|
||||
//Handle possble chem smoke effect
|
||||
/mob/living/carbon/proc/handle_chemical_smoke(var/datum/gas_mixture/environment)
|
||||
if(wear_mask && (wear_mask.flags & BLOCK_GAS_SMOKE_EFFECT))
|
||||
return
|
||||
|
||||
for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
|
||||
if(smoke.reagents.total_volume)
|
||||
smoke.reagents.reaction(src, INGEST)
|
||||
spawn(5)
|
||||
if(smoke)
|
||||
//maybe check air pressure here or something to see if breathing in smoke is even possible.
|
||||
smoke.reagents.copy_to(src, 10) // I dunno, maybe the reagents enter the blood stream through the lungs?
|
||||
break // If they breathe in the nasty stuff once, no need to continue checking
|
||||
|
||||
/mob/living/carbon/proc/handle_breath(datum/gas_mixture/breath)
|
||||
return
|
||||
|
||||
/mob/living/carbon/proc/handle_post_breath(datum/gas_mixture/breath)
|
||||
if(breath)
|
||||
loc.assume_air(breath) //by default, exhale
|
||||
@@ -68,11 +68,6 @@
|
||||
if(air_master.current_cycle%4==2 || failed_last_breath || (health < config.health_threshold_crit)) //First, resolve location and get a breath
|
||||
breathe() //Only try to take a breath every 4 ticks, unless suffocating
|
||||
|
||||
else //Still give containing object the chance to interact
|
||||
if(istype(loc, /obj/))
|
||||
var/obj/location_as_object = loc
|
||||
location_as_object.handle_internal_lifeform(src, 0)
|
||||
|
||||
//Updates the number of stored chemicals for powers
|
||||
handle_changeling()
|
||||
|
||||
@@ -325,95 +320,26 @@
|
||||
var/datum/organ/external/O = pick(organs)
|
||||
if(istype(O)) O.add_autopsy_data("Radiation Poisoning", damage)
|
||||
|
||||
proc/breathe()
|
||||
if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return
|
||||
if(species && (species.flags & NO_BREATHE || species.flags & IS_SYNTHETIC)) return
|
||||
/** breathing **/
|
||||
|
||||
handle_chemical_smoke(var/datum/gas_mixture/environment)
|
||||
if(wear_mask && (wear_mask.flags & BLOCK_GAS_SMOKE_EFFECT))
|
||||
return
|
||||
if(glasses && (glasses.flags & BLOCK_GAS_SMOKE_EFFECT))
|
||||
return
|
||||
if(head && (head.flags & BLOCK_GAS_SMOKE_EFFECT))
|
||||
return
|
||||
..()
|
||||
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
var/datum/gas_mixture/breath
|
||||
|
||||
// HACK NEED CHANGING LATER
|
||||
if(health < config.health_threshold_crit && !reagents.has_reagent("inaprovaline"))
|
||||
losebreath++
|
||||
|
||||
if(losebreath>0) //Suffocating so do not take a breath
|
||||
losebreath--
|
||||
if (prob(10)) //Gasp per 10 ticks? Sounds about right.
|
||||
spawn emote("gasp")
|
||||
if(istype(loc, /obj/))
|
||||
var/obj/location_as_object = loc
|
||||
location_as_object.handle_internal_lifeform(src, 0)
|
||||
else
|
||||
//First, check for air from internal atmosphere (using an air tank and mask generally)
|
||||
breath = get_breath_from_internal(BREATH_VOLUME) // Super hacky -- TLE
|
||||
//breath = get_breath_from_internal(0.5) // Manually setting to old BREATH_VOLUME amount -- TLE
|
||||
|
||||
//No breath from internal atmosphere so get breath from location
|
||||
if(!breath)
|
||||
if(isobj(loc))
|
||||
var/obj/location_as_object = loc
|
||||
breath = location_as_object.handle_internal_lifeform(src, BREATH_MOLES)
|
||||
else if(isturf(loc))
|
||||
var/breath_moles = 0
|
||||
/*if(environment.return_pressure() > ONE_ATMOSPHERE)
|
||||
// Loads of air around (pressure effect will be handled elsewhere), so lets just take a enough to fill our lungs at normal atmos pressure (using n = Pv/RT)
|
||||
breath_moles = (ONE_ATMOSPHERE*BREATH_VOLUME/R_IDEAL_GAS_EQUATION*environment.temperature)
|
||||
else*/
|
||||
// Not enough air around, take a percentage of what's there to model this properly
|
||||
breath_moles = environment.total_moles*BREATH_PERCENTAGE
|
||||
|
||||
breath = loc.remove_air(breath_moles)
|
||||
|
||||
if(istype(wear_mask, /obj/item/clothing/mask) && breath)
|
||||
var/obj/item/clothing/mask/M = wear_mask
|
||||
var/datum/gas_mixture/filtered = M.filter_air(breath)
|
||||
loc.assume_air(filtered)
|
||||
|
||||
if(!is_lung_ruptured())
|
||||
if(!breath || breath.total_moles < BREATH_MOLES / 5 || breath.total_moles > BREATH_MOLES * 5)
|
||||
if(prob(5))
|
||||
rupture_lung()
|
||||
|
||||
// Handle filtering
|
||||
var/block = 0
|
||||
if(wear_mask)
|
||||
if(wear_mask.flags & BLOCK_GAS_SMOKE_EFFECT)
|
||||
block = 1
|
||||
if(glasses)
|
||||
if(glasses.flags & BLOCK_GAS_SMOKE_EFFECT)
|
||||
block = 1
|
||||
if(head)
|
||||
if(head.flags & BLOCK_GAS_SMOKE_EFFECT)
|
||||
block = 1
|
||||
|
||||
if(!block)
|
||||
|
||||
for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
|
||||
if(smoke.reagents.total_volume)
|
||||
smoke.reagents.reaction(src, INGEST)
|
||||
spawn(5)
|
||||
if(smoke)
|
||||
smoke.reagents.copy_to(src, 10) // I dunno, maybe the reagents enter the blood stream through the lungs?
|
||||
break // If they breathe in the nasty stuff once, no need to continue checking
|
||||
|
||||
else //Still give containing object the chance to interact
|
||||
if(istype(loc, /obj/))
|
||||
var/obj/location_as_object = loc
|
||||
location_as_object.handle_internal_lifeform(src, 0)
|
||||
|
||||
handle_breath(breath)
|
||||
|
||||
if(breath)
|
||||
loc.assume_air(breath)
|
||||
|
||||
//spread some viruses while we are at it
|
||||
if (virus2.len > 0 && prob(10))
|
||||
// log_debug("[src] : Exhaling some viruses")
|
||||
for(var/mob/living/carbon/M in view(1,src))
|
||||
src.spread_disease_to(M)
|
||||
handle_post_breath(datum/gas_mixture/breath)
|
||||
..()
|
||||
//spread some viruses while we are at it
|
||||
if(breath && virus2.len > 0 && prob(10))
|
||||
for(var/mob/living/carbon/M in view(1,src))
|
||||
src.spread_disease_to(M)
|
||||
|
||||
|
||||
proc/get_breath_from_internal(volume_needed)
|
||||
get_breath_from_internal(volume_needed=BREATH_VOLUME)
|
||||
if(internal)
|
||||
|
||||
var/obj/item/weapon/tank/rig_supply
|
||||
@@ -432,7 +358,7 @@
|
||||
return null
|
||||
|
||||
|
||||
proc/handle_breath(datum/gas_mixture/breath)
|
||||
handle_breath(datum/gas_mixture/breath)
|
||||
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
|
||||
@@ -27,10 +27,6 @@
|
||||
if(air_master.current_cycle%4==2)
|
||||
//Only try to take a breath every 4 seconds, unless suffocating
|
||||
breathe()
|
||||
else //Still give containing object the chance to interact
|
||||
if(istype(loc, /obj/))
|
||||
var/obj/location_as_object = loc
|
||||
location_as_object.handle_internal_lifeform(src, 0)
|
||||
|
||||
//Updates the number of stored chemicals for powers
|
||||
handle_changeling()
|
||||
@@ -152,85 +148,7 @@
|
||||
domutcheck(src,null)
|
||||
emote("gasp")
|
||||
|
||||
proc/breathe()
|
||||
if(reagents)
|
||||
|
||||
if(reagents.has_reagent("lexorin")) return
|
||||
|
||||
if(!loc) return //probably ought to make a proper fix for this, but :effort: --NeoFite
|
||||
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
var/datum/gas_mixture/breath
|
||||
if(health < 0)
|
||||
losebreath++
|
||||
if(losebreath>0) //Suffocating so do not take a breath
|
||||
losebreath--
|
||||
if (prob(75)) //High chance of gasping for air
|
||||
spawn emote("gasp")
|
||||
if(istype(loc, /obj/))
|
||||
var/obj/location_as_object = loc
|
||||
location_as_object.handle_internal_lifeform(src, 0)
|
||||
else
|
||||
//First, check for air from internal atmosphere (using an air tank and mask generally)
|
||||
breath = get_breath_from_internal(BREATH_VOLUME)
|
||||
|
||||
//No breath from internal atmosphere so get breath from location
|
||||
if(!breath)
|
||||
if(istype(loc, /obj/))
|
||||
var/obj/location_as_object = loc
|
||||
breath = location_as_object.handle_internal_lifeform(src, BREATH_VOLUME)
|
||||
else if(istype(loc, /turf/))
|
||||
var/breath_moles = environment.total_moles*BREATH_PERCENTAGE
|
||||
breath = loc.remove_air(breath_moles)
|
||||
|
||||
if(istype(wear_mask, /obj/item/clothing/mask) && breath)
|
||||
var/obj/item/clothing/mask/M = wear_mask
|
||||
var/datum/gas_mixture/filtered = M.filter_air(breath)
|
||||
loc.assume_air(filtered)
|
||||
|
||||
// Handle chem smoke effect -- Doohl
|
||||
var/block = 0
|
||||
if(wear_mask)
|
||||
if(istype(wear_mask, /obj/item/clothing/mask/gas))
|
||||
block = 1
|
||||
|
||||
if(!block)
|
||||
for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
|
||||
if(smoke.reagents.total_volume)
|
||||
smoke.reagents.reaction(src, INGEST)
|
||||
spawn(5)
|
||||
if(smoke)
|
||||
smoke.reagents.copy_to(src, 10) // I dunno, maybe the reagents enter the blood stream through the lungs?
|
||||
break // If they breathe in the nasty stuff once, no need to continue checking
|
||||
|
||||
|
||||
else //Still give containing object the chance to interact
|
||||
if(istype(loc, /obj/))
|
||||
var/obj/location_as_object = loc
|
||||
location_as_object.handle_internal_lifeform(src, 0)
|
||||
|
||||
handle_breath(breath)
|
||||
|
||||
if(breath)
|
||||
loc.assume_air(breath)
|
||||
|
||||
|
||||
proc/get_breath_from_internal(volume_needed)
|
||||
if(internal)
|
||||
if (!contents.Find(internal))
|
||||
internal = null
|
||||
if (!(wear_mask && (wear_mask.flags & AIRTIGHT)))
|
||||
internal = null
|
||||
if(internal)
|
||||
if (internals)
|
||||
internals.icon_state = "internal1"
|
||||
return internal.remove_air_volume(volume_needed)
|
||||
else
|
||||
if (internals)
|
||||
internals.icon_state = "internal0"
|
||||
return null
|
||||
|
||||
proc/handle_breath(datum/gas_mixture/breath)
|
||||
handle_breath(datum/gas_mixture/breath)
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
|
||||
|
||||
Reference in New Issue
Block a user