Merge pull request #12217 from Putnam3145/putnamos-for-real
The real fastmos: C++ monstermos port
This commit is contained in:
@@ -573,7 +573,7 @@
|
||||
if(Rad.anchored)
|
||||
if(!Rad.loaded_tank)
|
||||
var/obj/item/tank/internals/plasma/Plasma = new/obj/item/tank/internals/plasma(Rad)
|
||||
Plasma.air_contents.gases[/datum/gas/plasma] = 70
|
||||
Plasma.air_contents.set_moles(/datum/gas/plasma,70)
|
||||
Rad.drainratio = 0
|
||||
Rad.loaded_tank = Plasma
|
||||
Plasma.forceMove(Rad)
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
/proc/show_air_status_to(turf/target, mob/user)
|
||||
var/datum/gas_mixture/env = target.return_air()
|
||||
var/list/env_gases = env.gases
|
||||
var/burning = FALSE
|
||||
if(isopenturf(target))
|
||||
var/turf/open/T = target
|
||||
if(T.active_hotspot)
|
||||
burning = TRUE
|
||||
|
||||
var/list/lines = list("<span class='adminnotice'>[AREACOORD(target)]: [env.temperature] K ([env.temperature - T0C] C), [env.return_pressure()] kPa[(burning)?(", <font color='red'>burning</font>"):(null)]</span>")
|
||||
for(var/id in env_gases)
|
||||
var/moles = env_gases[id]
|
||||
var/list/lines = list("<span class='adminnotice'>[AREACOORD(target)]: [env.return_temperature()] K ([env.return_temperature() - T0C] C), [env.return_pressure()] kPa[(burning)?(", <font color='red'>burning</font>"):(null)]</span>")
|
||||
for(var/id in env.get_gases())
|
||||
var/moles = env.get_moles(id)
|
||||
if (moles >= 0.00001)
|
||||
lines += "[GLOB.meta_gas_names[id]]: [moles] mol"
|
||||
to_chat(usr, lines.Join("\n"))
|
||||
|
||||
@@ -53,8 +53,8 @@
|
||||
return
|
||||
if(I.use_tool(src, user, 0, volume=40))
|
||||
status = TRUE
|
||||
GLOB.bombers += "[key_name(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]"
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]")
|
||||
GLOB.bombers += "[key_name(user)] welded a single tank bomb. Temp: [bombtank.air_contents.return_temperature()-T0C]"
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] welded a single tank bomb. Temp: [bombtank.air_contents.return_temperature()-T0C]")
|
||||
to_chat(user, "<span class='notice'>A pressure hole has been bored to [bombtank] valve. \The [bombtank] can now be ignited.</span>")
|
||||
add_fingerprint(user)
|
||||
return TRUE
|
||||
@@ -145,8 +145,7 @@
|
||||
return
|
||||
|
||||
/obj/item/tank/proc/ignite() //This happens when a bomb is told to explode
|
||||
var/fuel_moles = air_contents.gases[/datum/gas/plasma] + air_contents.gases[/datum/gas/oxygen]/6
|
||||
GAS_GARBAGE_COLLECT(air_contents.gases)
|
||||
var/fuel_moles = air_contents.get_moles(/datum/gas/plasma) + air_contents.get_moles(/datum/gas/oxygen)/6
|
||||
var/datum/gas_mixture/bomb_mixture = air_contents.copy()
|
||||
var/strength = 1
|
||||
|
||||
@@ -156,7 +155,7 @@
|
||||
qdel(master)
|
||||
qdel(src)
|
||||
|
||||
if(bomb_mixture.temperature > (T0C + 400))
|
||||
if(bomb_mixture.return_temperature() > (T0C + 400))
|
||||
strength = (fuel_moles/15)
|
||||
|
||||
if(strength >=1)
|
||||
@@ -169,7 +168,7 @@
|
||||
ground_zero.assume_air(bomb_mixture)
|
||||
ground_zero.hotspot_expose(1000, 125)
|
||||
|
||||
else if(bomb_mixture.temperature > (T0C + 250))
|
||||
else if(bomb_mixture.return_temperature() > (T0C + 250))
|
||||
strength = (fuel_moles/20)
|
||||
|
||||
if(strength >=1)
|
||||
@@ -180,7 +179,7 @@
|
||||
ground_zero.assume_air(bomb_mixture)
|
||||
ground_zero.hotspot_expose(1000, 125)
|
||||
|
||||
else if(bomb_mixture.temperature > (T0C + 100))
|
||||
else if(bomb_mixture.return_temperature() > (T0C + 100))
|
||||
strength = (fuel_moles/25)
|
||||
|
||||
if (strength >=1)
|
||||
|
||||
@@ -9,46 +9,31 @@
|
||||
return
|
||||
|
||||
|
||||
/turf/open/hotspot_expose(exposed_temperature, exposed_volume, soh = FALSE, holo = FALSE)
|
||||
var/datum/gas_mixture/air_contents = return_air()
|
||||
if(!air_contents)
|
||||
return 0
|
||||
/turf/open/hotspot_expose(exposed_temperature, exposed_volume, soh)
|
||||
if(!air)
|
||||
return
|
||||
|
||||
var/oxy = air_contents.gases[/datum/gas/oxygen]
|
||||
var/tox = air_contents.gases[/datum/gas/plasma]
|
||||
var/trit = air_contents.gases[/datum/gas/tritium]
|
||||
var/oxy = air.get_moles(/datum/gas/oxygen)
|
||||
if (oxy < 0.5)
|
||||
return
|
||||
var/tox = air.get_moles(/datum/gas/plasma)
|
||||
var/trit = air.get_moles(/datum/gas/tritium)
|
||||
if(active_hotspot)
|
||||
if(soh)
|
||||
if((tox > 0.5 || trit > 0.5) && oxy > 0.5)
|
||||
if(active_hotspot.temperature < exposed_temperature*50)
|
||||
active_hotspot.temperature = exposed_temperature*50
|
||||
if(tox > 0.5 || trit > 0.5)
|
||||
if(active_hotspot.temperature < exposed_temperature)
|
||||
active_hotspot.temperature = exposed_temperature
|
||||
if(active_hotspot.volume < exposed_volume)
|
||||
active_hotspot.volume = exposed_volume
|
||||
return 1
|
||||
|
||||
var/igniting = 0
|
||||
return
|
||||
|
||||
if((exposed_temperature > PLASMA_MINIMUM_BURN_TEMPERATURE) && (tox > 0.5 || trit > 0.5))
|
||||
igniting = 1
|
||||
|
||||
if(igniting)
|
||||
if(oxy < 0.5)
|
||||
return 0
|
||||
|
||||
active_hotspot = new /obj/effect/hotspot(src, holo)
|
||||
active_hotspot.temperature = exposed_temperature*50
|
||||
active_hotspot.volume = exposed_volume*25
|
||||
active_hotspot = new /obj/effect/hotspot(src, exposed_volume*25, exposed_temperature)
|
||||
|
||||
active_hotspot.just_spawned = (current_cycle < SSair.times_fired)
|
||||
//remove just_spawned protection if no longer processing this cell
|
||||
SSair.add_to_active(src, 0)
|
||||
else
|
||||
var/datum/gas_mixture/heating = air_contents.remove_ratio(exposed_volume/air_contents.volume)
|
||||
heating.temperature = exposed_temperature
|
||||
heating.react()
|
||||
assume_air(heating)
|
||||
air_update_turf()
|
||||
return igniting
|
||||
|
||||
//This is the icon for fire on turfs, also helps for nurturing small fires until they are full tile
|
||||
/obj/effect/hotspot
|
||||
@@ -67,11 +52,13 @@
|
||||
var/bypassing = FALSE
|
||||
var/visual_update_tick = 0
|
||||
|
||||
/obj/effect/hotspot/Initialize(mapload, holo = FALSE)
|
||||
/obj/effect/hotspot/Initialize(mapload, starting_volume, starting_temperature)
|
||||
. = ..()
|
||||
if(holo)
|
||||
flags_1 |= HOLOGRAM_1
|
||||
SSair.hotspots += src
|
||||
if(!isnull(starting_volume))
|
||||
volume = starting_volume
|
||||
if(!isnull(starting_temperature))
|
||||
temperature = starting_temperature
|
||||
perform_exposure()
|
||||
setDir(pick(GLOB.cardinals))
|
||||
air_update_turf()
|
||||
@@ -83,22 +70,19 @@
|
||||
|
||||
location.active_hotspot = src
|
||||
|
||||
if(volume > CELL_VOLUME*0.95)
|
||||
bypassing = TRUE
|
||||
else
|
||||
bypassing = FALSE
|
||||
bypassing = !just_spawned && (volume > CELL_VOLUME*0.95)
|
||||
|
||||
if(bypassing)
|
||||
if(!just_spawned)
|
||||
volume = location.air.reaction_results["fire"]*FIRE_GROWTH_RATE
|
||||
temperature = location.air.temperature
|
||||
volume = location.air.reaction_results["fire"]*FIRE_GROWTH_RATE
|
||||
temperature = location.air.return_temperature()
|
||||
else
|
||||
var/datum/gas_mixture/affected = location.air.remove_ratio(volume/location.air.volume)
|
||||
affected.temperature = temperature
|
||||
affected.react(src)
|
||||
temperature = affected.temperature
|
||||
volume = affected.reaction_results["fire"]*FIRE_GROWTH_RATE
|
||||
location.assume_air(affected)
|
||||
var/datum/gas_mixture/affected = location.air.remove_ratio(volume/location.air.return_volume())
|
||||
if(affected) //in case volume is 0
|
||||
affected.set_temperature(temperature)
|
||||
affected.react(src)
|
||||
temperature = affected.return_temperature()
|
||||
volume = affected.reaction_results["fire"]*FIRE_GROWTH_RATE
|
||||
location.assume_air(affected)
|
||||
|
||||
for(var/A in location)
|
||||
var/atom/AT = A
|
||||
@@ -164,7 +148,7 @@
|
||||
color = list(LERP(0.3, 1, 1-greyscale_fire) * heat_r,0.3 * heat_g * greyscale_fire,0.3 * heat_b * greyscale_fire, 0.59 * heat_r * greyscale_fire,LERP(0.59, 1, 1-greyscale_fire) * heat_g,0.59 * heat_b * greyscale_fire, 0.11 * heat_r * greyscale_fire,0.11 * heat_g * greyscale_fire,LERP(0.11, 1, 1-greyscale_fire) * heat_b, 0,0,0)
|
||||
alpha = heat_a
|
||||
|
||||
#define INSUFFICIENT(path) (location.air.gases[path] < 0.5)
|
||||
#define INSUFFICIENT(path) (location.air.get_moles(path) < 0.5)
|
||||
/obj/effect/hotspot/process()
|
||||
if(just_spawned)
|
||||
just_spawned = FALSE
|
||||
@@ -175,8 +159,7 @@
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if(location.excited_group)
|
||||
location.excited_group.reset_cooldowns()
|
||||
location.eg_reset_cooldowns()
|
||||
|
||||
if((temperature < FIRE_MINIMUM_TEMPERATURE_TO_EXIST) || (volume <= 1))
|
||||
qdel(src)
|
||||
@@ -186,7 +169,8 @@
|
||||
return
|
||||
|
||||
//Not enough to burn
|
||||
if((location.air.gases[/datum/gas/plasma] < 0.5 && location.air.gases[/datum/gas/tritium] < 0.5) || location.air.gases[/datum/gas/oxygen] < 0.5)
|
||||
// god damn it previous coder you made the INSUFFICIENT macro for a fucking reason why didn't you use it here smh
|
||||
if((INSUFFICIENT(/datum/gas/plasma) && INSUFFICIENT(/datum/gas/tritium)) || INSUFFICIENT(/datum/gas/oxygen))
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
@@ -194,16 +178,15 @@
|
||||
|
||||
if(bypassing)
|
||||
icon_state = "3"
|
||||
if(!(flags_1 & HOLOGRAM_1))
|
||||
location.burn_tile()
|
||||
location.burn_tile()
|
||||
|
||||
//Possible spread due to radiated heat
|
||||
if(location.air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_SPREAD)
|
||||
var/radiated_temperature = location.air.temperature*FIRE_SPREAD_RADIOSITY_SCALE
|
||||
if(location.air.return_temperature() > FIRE_MINIMUM_TEMPERATURE_TO_SPREAD)
|
||||
var/radiated_temperature = location.air.return_temperature()*FIRE_SPREAD_RADIOSITY_SCALE
|
||||
for(var/t in location.atmos_adjacent_turfs)
|
||||
var/turf/open/T = t
|
||||
if(!T.active_hotspot)
|
||||
T.hotspot_expose(radiated_temperature, CELL_VOLUME/4, flags_1 & HOLOGRAM_1)
|
||||
T.hotspot_expose(radiated_temperature, CELL_VOLUME/4)
|
||||
|
||||
else
|
||||
if(volume > CELL_VOLUME*0.4)
|
||||
@@ -227,14 +210,13 @@
|
||||
var/turf/open/T = loc
|
||||
if(istype(T) && T.active_hotspot == src)
|
||||
T.active_hotspot = null
|
||||
if(!(flags_1 & HOLOGRAM_1))
|
||||
DestroyTurf()
|
||||
DestroyTurf()
|
||||
return ..()
|
||||
|
||||
/obj/effect/hotspot/proc/DestroyTurf()
|
||||
if(isturf(loc))
|
||||
var/turf/T = loc
|
||||
if(T.to_be_destroyed)
|
||||
if(T.to_be_destroyed && !T.changing_turf)
|
||||
var/chance_of_deletion
|
||||
if (T.heat_capacity) //beware of division by zero
|
||||
chance_of_deletion = T.max_fire_temperature_sustained / T.heat_capacity * 8 //there is no problem with prob(23456), min() was redundant --rastaf0
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
/turf/open/CanAtmosPass(turf/T, vertical = FALSE)
|
||||
var/dir = vertical? get_dir_multiz(src, T) : get_dir(src, T)
|
||||
var/opp = dir_inverse_multiz(dir)
|
||||
var/opp = REVERSE_DIR(dir)
|
||||
var/R = FALSE
|
||||
if(vertical && !(zAirOut(dir, T) && T.zAirIn(dir, src)))
|
||||
R = TRUE
|
||||
@@ -44,25 +44,32 @@
|
||||
return FALSE
|
||||
|
||||
/turf/proc/ImmediateCalculateAdjacentTurfs()
|
||||
var/canpass = CANATMOSPASS(src, src)
|
||||
var/canpass = CANATMOSPASS(src, src)
|
||||
var/canvpass = CANVERTICALATMOSPASS(src, src)
|
||||
for(var/direction in GLOB.cardinals_multiz)
|
||||
var/turf/T = get_step_multiz(src, direction)
|
||||
var/opp_dir = REVERSE_DIR(direction)
|
||||
if(!isopenturf(T))
|
||||
continue
|
||||
if(!(blocks_air || T.blocks_air) && ((direction & (UP|DOWN))? (canvpass && CANVERTICALATMOSPASS(T, src)) : (canpass && CANATMOSPASS(T, src))) )
|
||||
LAZYINITLIST(atmos_adjacent_turfs)
|
||||
LAZYINITLIST(T.atmos_adjacent_turfs)
|
||||
atmos_adjacent_turfs[T] = TRUE
|
||||
T.atmos_adjacent_turfs[src] = TRUE
|
||||
atmos_adjacent_turfs[T] = direction
|
||||
T.atmos_adjacent_turfs[src] = opp_dir
|
||||
T.__update_extools_adjacent_turfs()
|
||||
else
|
||||
if (atmos_adjacent_turfs)
|
||||
atmos_adjacent_turfs -= T
|
||||
if (T.atmos_adjacent_turfs)
|
||||
T.atmos_adjacent_turfs -= src
|
||||
T.__update_extools_adjacent_turfs()
|
||||
UNSETEMPTY(T.atmos_adjacent_turfs)
|
||||
UNSETEMPTY(atmos_adjacent_turfs)
|
||||
src.atmos_adjacent_turfs = atmos_adjacent_turfs
|
||||
__update_extools_adjacent_turfs()
|
||||
|
||||
/turf/proc/__update_extools_adjacent_turfs()
|
||||
|
||||
|
||||
//returns a list of adjacent turfs that can share air with this one.
|
||||
//alldir includes adjacent diagonal tiles that can share
|
||||
@@ -111,9 +118,9 @@
|
||||
SSair.add_to_active(src,command)
|
||||
|
||||
/atom/movable/proc/move_update_air(turf/T)
|
||||
if(isturf(T))
|
||||
T.air_update_turf(1)
|
||||
air_update_turf(1)
|
||||
if(isturf(T))
|
||||
T.air_update_turf(1)
|
||||
air_update_turf(1)
|
||||
|
||||
/atom/proc/atmos_spawn_air(text) //because a lot of people loves to copy paste awful code lets just make an easy proc to spawn your plasma fires
|
||||
var/turf/open/T = get_turf(src)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
var/list/atmos_adjacent_turfs
|
||||
//bitfield of dirs in which we are superconducitng
|
||||
var/atmos_supeconductivity = NONE
|
||||
var/is_openturf = FALSE // used by extools shizz.
|
||||
|
||||
//used to determine whether we should archive
|
||||
var/archived_cycle = 0
|
||||
@@ -23,21 +24,21 @@
|
||||
//used for spacewind
|
||||
var/pressure_difference = 0
|
||||
var/pressure_direction = 0
|
||||
var/turf/pressure_specific_target
|
||||
|
||||
var/datum/excited_group/excited_group
|
||||
var/excited = FALSE
|
||||
var/datum/gas_mixture/turf/air
|
||||
|
||||
var/obj/effect/hotspot/active_hotspot
|
||||
var/atmos_cooldown = 0
|
||||
var/planetary_atmos = FALSE //air will revert to initial_gas_mix over time
|
||||
|
||||
var/list/atmos_overlay_types //gas IDs of current active gas overlays
|
||||
is_openturf = TRUE
|
||||
|
||||
/turf/open/Initialize()
|
||||
if(!blocks_air)
|
||||
air = new
|
||||
air.copy_from_turf(src)
|
||||
update_air_ref()
|
||||
. = ..()
|
||||
|
||||
/turf/open/Destroy()
|
||||
@@ -48,6 +49,8 @@
|
||||
SSair.add_to_active(T)
|
||||
return ..()
|
||||
|
||||
/turf/proc/update_air_ref()
|
||||
|
||||
/////////////////GAS MIXTURE PROCS///////////////////
|
||||
|
||||
/turf/open/assume_air(datum/gas_mixture/giver) //use this for machines to adjust air
|
||||
@@ -89,15 +92,37 @@
|
||||
temperature_archived = temperature
|
||||
|
||||
/turf/open/archive()
|
||||
ARCHIVE(air)
|
||||
air.archive()
|
||||
archived_cycle = SSair.times_fired
|
||||
temperature_archived = temperature
|
||||
|
||||
/turf/open/proc/eg_reset_cooldowns()
|
||||
/turf/open/proc/eg_garbage_collect()
|
||||
/turf/open/proc/get_excited()
|
||||
/turf/open/proc/set_excited()
|
||||
|
||||
/////////////////////////GAS OVERLAYS//////////////////////////////
|
||||
|
||||
|
||||
/turf/open/proc/update_visuals()
|
||||
var/list/new_overlay_types = tile_graphic()
|
||||
|
||||
var/list/atmos_overlay_types = src.atmos_overlay_types // Cache for free performance
|
||||
var/list/new_overlay_types = list()
|
||||
var/static/list/nonoverlaying_gases = typecache_of_gases_with_no_overlays()
|
||||
|
||||
if(!air) // 2019-05-14: was not able to get this path to fire in testing. Consider removing/looking at callers -Naksu
|
||||
if (atmos_overlay_types)
|
||||
for(var/overlay in atmos_overlay_types)
|
||||
vis_contents -= overlay
|
||||
src.atmos_overlay_types = null
|
||||
return
|
||||
|
||||
for(var/id in air.get_gases())
|
||||
if (nonoverlaying_gases[id])
|
||||
continue
|
||||
var/gas_overlay = GLOB.meta_gas_overlays[id]
|
||||
if(gas_overlay && air.get_moles(id) > GLOB.meta_gas_visibility[META_GAS_MOLES_VISIBLE])
|
||||
new_overlay_types += gas_overlay[min(FACTOR_GAS_VISIBLE_MAX, CEILING(air.get_moles(id) / MOLES_GAS_VISIBLE_STEP, 1))]
|
||||
|
||||
if (atmos_overlay_types)
|
||||
for(var/overlay in atmos_overlay_types-new_overlay_types) //doesn't remove overlays that would only be added
|
||||
@@ -112,19 +137,18 @@
|
||||
UNSETEMPTY(new_overlay_types)
|
||||
src.atmos_overlay_types = new_overlay_types
|
||||
|
||||
/turf/open/proc/tile_graphic()
|
||||
var/static/list/nonoverlaying_gases = typecache_of_gases_with_no_overlays()
|
||||
if(!air)
|
||||
return
|
||||
. = new /list
|
||||
var/list/gases = air.gases
|
||||
for(var/id in gases)
|
||||
if (nonoverlaying_gases[id])
|
||||
continue
|
||||
var/gas = gases[id]
|
||||
var/gas_overlay = GLOB.meta_gas_overlays[id]
|
||||
if(gas_overlay && gas > GLOB.meta_gas_visibility[id])
|
||||
. += gas_overlay[min(FACTOR_GAS_VISIBLE_MAX, CEILING(gas / MOLES_GAS_VISIBLE_STEP, 1))]
|
||||
/turf/open/proc/set_visuals(list/new_overlay_types)
|
||||
if (atmos_overlay_types)
|
||||
for(var/overlay in atmos_overlay_types-new_overlay_types) //doesn't remove overlays that would only be added
|
||||
vis_contents -= overlay
|
||||
|
||||
if (length(new_overlay_types))
|
||||
if (atmos_overlay_types)
|
||||
vis_contents += new_overlay_types - atmos_overlay_types //don't add overlays that already exist
|
||||
else
|
||||
vis_contents += new_overlay_types
|
||||
UNSETEMPTY(new_overlay_types)
|
||||
src.atmos_overlay_types = new_overlay_types
|
||||
|
||||
/proc/typecache_of_gases_with_no_overlays()
|
||||
. = list()
|
||||
@@ -135,8 +159,8 @@
|
||||
|
||||
/////////////////////////////SIMULATION///////////////////////////////////
|
||||
|
||||
#define LAST_SHARE_CHECK \
|
||||
var/last_share = our_air.last_share;\
|
||||
/*#define LAST_SHARE_CHECK \
|
||||
var/last_share = our_air.get_last_share();\
|
||||
if(last_share > MINIMUM_AIR_TO_SUSPEND){\
|
||||
our_excited_group.reset_cooldowns();\
|
||||
cached_atmos_cooldown = 0;\
|
||||
@@ -144,107 +168,32 @@
|
||||
our_excited_group.dismantle_cooldown = 0;\
|
||||
cached_atmos_cooldown = 0;\
|
||||
}
|
||||
|
||||
*/
|
||||
/turf/proc/process_cell(fire_count)
|
||||
SSair.remove_from_active(src)
|
||||
|
||||
/turf/open/process_cell(fire_count)
|
||||
if(archived_cycle < fire_count) //archive self if not already done
|
||||
archive()
|
||||
|
||||
current_cycle = fire_count
|
||||
|
||||
//cache for sanic speed
|
||||
var/list/adjacent_turfs = atmos_adjacent_turfs
|
||||
var/datum/excited_group/our_excited_group = excited_group
|
||||
var/adjacent_turfs_length = LAZYLEN(adjacent_turfs)
|
||||
var/cached_atmos_cooldown = atmos_cooldown + 1
|
||||
|
||||
var/planet_atmos = planetary_atmos
|
||||
if (planet_atmos)
|
||||
adjacent_turfs_length++
|
||||
|
||||
var/datum/gas_mixture/our_air = air
|
||||
|
||||
for(var/t in adjacent_turfs)
|
||||
var/turf/open/enemy_tile = t
|
||||
|
||||
if(fire_count <= enemy_tile.current_cycle)
|
||||
/turf/open/proc/equalize_pressure_in_zone(cyclenum)
|
||||
/turf/open/proc/consider_firelocks(turf/T2)
|
||||
var/reconsider_adj = FALSE
|
||||
for(var/obj/machinery/door/firedoor/FD in T2)
|
||||
if((FD.flags_1 & ON_BORDER_1) && get_dir(T2, src) != FD.dir)
|
||||
continue
|
||||
enemy_tile.archive()
|
||||
FD.emergency_pressure_stop()
|
||||
reconsider_adj = TRUE
|
||||
for(var/obj/machinery/door/firedoor/FD in src)
|
||||
if((FD.flags_1 & ON_BORDER_1) && get_dir(src, T2) != FD.dir)
|
||||
continue
|
||||
FD.emergency_pressure_stop()
|
||||
reconsider_adj = TRUE
|
||||
if(reconsider_adj)
|
||||
T2.ImmediateCalculateAdjacentTurfs() // We want those firelocks closed yesterday.
|
||||
|
||||
/******************* GROUP HANDLING START *****************************************************************/
|
||||
/turf/proc/handle_decompression_floor_rip()
|
||||
/turf/open/floor/handle_decompression_floor_rip(sum)
|
||||
if(sum > 20 && prob(clamp(sum / 10, 0, 30)))
|
||||
remove_tile()
|
||||
|
||||
var/should_share_air = FALSE
|
||||
var/datum/gas_mixture/enemy_air = enemy_tile.air
|
||||
|
||||
//cache for sanic speed
|
||||
var/datum/excited_group/enemy_excited_group = enemy_tile.excited_group
|
||||
|
||||
if(our_excited_group && enemy_excited_group)
|
||||
if(our_excited_group != enemy_excited_group)
|
||||
//combine groups (this also handles updating the excited_group var of all involved turfs)
|
||||
our_excited_group.merge_groups(enemy_excited_group)
|
||||
our_excited_group = excited_group //update our cache
|
||||
should_share_air = TRUE
|
||||
|
||||
else if(our_air.compare(enemy_air))
|
||||
if(!enemy_tile.excited)
|
||||
SSair.add_to_active(enemy_tile)
|
||||
var/datum/excited_group/EG = our_excited_group || enemy_excited_group || new
|
||||
if(!our_excited_group)
|
||||
EG.add_turf(src)
|
||||
if(!enemy_excited_group)
|
||||
EG.add_turf(enemy_tile)
|
||||
our_excited_group = excited_group
|
||||
should_share_air = TRUE
|
||||
|
||||
//air sharing
|
||||
if(should_share_air)
|
||||
var/difference = our_air.share(enemy_air, adjacent_turfs_length)
|
||||
if(difference)
|
||||
if(difference > 0)
|
||||
consider_pressure_difference(enemy_tile, difference)
|
||||
else
|
||||
enemy_tile.consider_pressure_difference(src, -difference)
|
||||
LAST_SHARE_CHECK
|
||||
|
||||
|
||||
/******************* GROUP HANDLING FINISH *********************************************************************/
|
||||
|
||||
if (planet_atmos) //share our air with the "atmosphere" "above" the turf
|
||||
var/datum/gas_mixture/G = new
|
||||
G.copy_from_turf(src)
|
||||
ARCHIVE(G)
|
||||
if(our_air.compare(G))
|
||||
if(!our_excited_group)
|
||||
var/datum/excited_group/EG = new
|
||||
EG.add_turf(src)
|
||||
our_excited_group = excited_group
|
||||
our_air.share(G, adjacent_turfs_length)
|
||||
LAST_SHARE_CHECK
|
||||
|
||||
SSair.add_to_react_queue(src)
|
||||
|
||||
if((!our_excited_group && !(our_air.temperature > MINIMUM_TEMPERATURE_START_SUPERCONDUCTION && consider_superconductivity(starting = TRUE))) \
|
||||
|| (cached_atmos_cooldown > (EXCITED_GROUP_DISMANTLE_CYCLES * 2)))
|
||||
SSair.remove_from_active(src)
|
||||
|
||||
atmos_cooldown = cached_atmos_cooldown
|
||||
|
||||
/turf/open/space/process_cell(fire_count) //dumb hack to prevent space pollution
|
||||
. = ..()
|
||||
var/datum/gas_mixture/immutable/I = space_gas
|
||||
I.after_process_cell()
|
||||
|
||||
/turf/proc/process_cell_reaction()
|
||||
SSair.remove_from_react_queue(src)
|
||||
|
||||
/turf/open/process_cell_reaction()
|
||||
air.react(src)
|
||||
update_visuals()
|
||||
SSair.remove_from_react_queue(src)
|
||||
return
|
||||
/turf/open/process_cell(fire_count)
|
||||
|
||||
//////////////////////////SPACEWIND/////////////////////////////
|
||||
|
||||
@@ -256,15 +205,22 @@
|
||||
|
||||
/turf/open/proc/high_pressure_movements()
|
||||
var/atom/movable/M
|
||||
var/multiplier = 1
|
||||
if(locate(/obj/structure/rack) in src)
|
||||
multiplier *= 0.1
|
||||
else if(locate(/obj/structure/table) in src)
|
||||
multiplier *= 0.2
|
||||
for(var/thing in src)
|
||||
M = thing
|
||||
if (!M.anchored && !M.pulledby && M.last_high_pressure_movement_air_cycle < SSair.times_fired)
|
||||
M.experience_pressure_difference(pressure_difference, pressure_direction)
|
||||
M.experience_pressure_difference(pressure_difference * multiplier, pressure_direction, 0, pressure_specific_target)
|
||||
if(pressure_difference > 100)
|
||||
new /obj/effect/temp_visual/dir_setting/space_wind(src, pressure_direction, clamp(round(sqrt(pressure_difference) * 2), 10, 255))
|
||||
|
||||
/atom/movable/var/pressure_resistance = 10
|
||||
/atom/movable/var/last_high_pressure_movement_air_cycle = 0
|
||||
|
||||
/atom/movable/proc/experience_pressure_difference(pressure_difference, direction, pressure_resistance_prob_delta = 0)
|
||||
/atom/movable/proc/experience_pressure_difference(pressure_difference, direction, pressure_resistance_prob_delta = 0, throw_target)
|
||||
var/const/PROBABILITY_OFFSET = 25
|
||||
var/const/PROBABILITY_BASE_PRECENT = 75
|
||||
var/max_force = sqrt(pressure_difference)*(MOVE_FORCE_DEFAULT / 5)
|
||||
@@ -275,93 +231,8 @@
|
||||
move_prob += pressure_resistance_prob_delta
|
||||
if (move_prob > PROBABILITY_OFFSET && prob(move_prob) && (move_resist != INFINITY) && (!anchored && (max_force >= (move_resist * MOVE_FORCE_PUSH_RATIO))) || (anchored && (max_force >= (move_resist * MOVE_FORCE_FORCEPUSH_RATIO))))
|
||||
step(src, direction)
|
||||
last_high_pressure_movement_air_cycle = SSair.times_fired
|
||||
|
||||
///////////////////////////EXCITED GROUPS/////////////////////////////
|
||||
|
||||
/datum/excited_group
|
||||
var/list/turf_list = list()
|
||||
var/breakdown_cooldown = 0
|
||||
var/dismantle_cooldown = 0
|
||||
|
||||
/datum/excited_group/New()
|
||||
SSair.excited_groups += src
|
||||
|
||||
/datum/excited_group/proc/add_turf(turf/open/T)
|
||||
turf_list += T
|
||||
T.excited_group = src
|
||||
reset_cooldowns()
|
||||
|
||||
/datum/excited_group/proc/merge_groups(datum/excited_group/E)
|
||||
if(turf_list.len > E.turf_list.len)
|
||||
SSair.excited_groups -= E
|
||||
for(var/t in E.turf_list)
|
||||
var/turf/open/T = t
|
||||
T.excited_group = src
|
||||
turf_list += T
|
||||
reset_cooldowns()
|
||||
else
|
||||
SSair.excited_groups -= src
|
||||
for(var/t in turf_list)
|
||||
var/turf/open/T = t
|
||||
T.excited_group = E
|
||||
E.turf_list += T
|
||||
E.reset_cooldowns()
|
||||
|
||||
/datum/excited_group/proc/reset_cooldowns()
|
||||
breakdown_cooldown = 0
|
||||
dismantle_cooldown = 0
|
||||
|
||||
//argument is so world start can clear out any turf differences quickly.
|
||||
/datum/excited_group/proc/self_breakdown(space_is_all_consuming = FALSE)
|
||||
var/datum/gas_mixture/A = new
|
||||
|
||||
//make local for sanic speed
|
||||
var/list/A_gases = A.gases
|
||||
var/list/turf_list = src.turf_list
|
||||
var/turflen = turf_list.len
|
||||
var/space_in_group = FALSE
|
||||
|
||||
for(var/t in turf_list)
|
||||
var/turf/open/T = t
|
||||
if (space_is_all_consuming && !space_in_group && istype(T.air, /datum/gas_mixture/immutable/space))
|
||||
space_in_group = TRUE
|
||||
qdel(A)
|
||||
A = new /datum/gas_mixture/immutable/space()
|
||||
A_gases = A.gases //update the cache
|
||||
break
|
||||
A.merge(T.air)
|
||||
|
||||
for(var/id in A_gases)
|
||||
A_gases[id] /= turflen
|
||||
|
||||
for(var/t in turf_list)
|
||||
var/turf/open/T = t
|
||||
T.air.copy_from(A)
|
||||
T.atmos_cooldown = 0
|
||||
T.update_visuals()
|
||||
|
||||
breakdown_cooldown = 0
|
||||
|
||||
/datum/excited_group/proc/dismantle()
|
||||
for(var/t in turf_list)
|
||||
var/turf/open/T = t
|
||||
T.excited = FALSE
|
||||
T.excited_group = null
|
||||
SSair.active_turfs -= T
|
||||
garbage_collect()
|
||||
|
||||
/datum/excited_group/proc/garbage_collect()
|
||||
for(var/t in turf_list)
|
||||
var/turf/open/T = t
|
||||
T.excited_group = null
|
||||
turf_list.Cut()
|
||||
SSair.excited_groups -= src
|
||||
|
||||
////////////////////////SUPERCONDUCTIVITY/////////////////////////////
|
||||
/atom/movable/proc/blocksTemperature()
|
||||
return FALSE
|
||||
|
||||
/turf/proc/conductivity_directions()
|
||||
if(archived_cycle < SSair.times_fired)
|
||||
archive()
|
||||
@@ -376,9 +247,6 @@
|
||||
. |= direction
|
||||
|
||||
/turf/proc/neighbor_conduct_with_src(turf/open/other)
|
||||
for (var/atom/movable/G in src)
|
||||
if (G.blocksTemperature())
|
||||
return
|
||||
if(!other.blocks_air) //Open but neighbor is solid
|
||||
other.temperature_share_open_to_solid(src)
|
||||
else //Both tiles are solid
|
||||
@@ -389,9 +257,7 @@
|
||||
if(blocks_air)
|
||||
..()
|
||||
return
|
||||
for (var/atom/movable/G in src)
|
||||
if (G.blocksTemperature())
|
||||
return
|
||||
|
||||
if(!other.blocks_air) //Both tiles are open
|
||||
var/turf/open/T = other
|
||||
T.air.temperature_share(air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
|
||||
@@ -410,8 +276,10 @@
|
||||
|
||||
if(!neighbor.thermal_conductivity)
|
||||
continue
|
||||
|
||||
if(neighbor.archived_cycle < SSair.times_fired)
|
||||
neighbor.archive()
|
||||
|
||||
neighbor.neighbor_conduct_with_src(src)
|
||||
|
||||
neighbor.consider_superconductivity()
|
||||
@@ -430,7 +298,7 @@
|
||||
//Conduct with air on my tile if I have it
|
||||
if(!blocks_air)
|
||||
temperature = air.temperature_share(null, thermal_conductivity, temperature, heat_capacity)
|
||||
..((blocks_air ? temperature : air.temperature))
|
||||
..((blocks_air ? temperature : air.return_temperature()))
|
||||
|
||||
/turf/proc/consider_superconductivity()
|
||||
if(!thermal_conductivity)
|
||||
@@ -440,7 +308,7 @@
|
||||
return TRUE
|
||||
|
||||
/turf/open/consider_superconductivity(starting)
|
||||
if(air.temperature < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
|
||||
if(air.return_temperature() < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
|
||||
return FALSE
|
||||
if(air.heat_capacity() < M_CELL_WITH_RATIO) // Was: MOLES_CELLSTANDARD*0.1*0.05 Since there are no variables here we can make this a constant.
|
||||
return FALSE
|
||||
|
||||
@@ -16,90 +16,80 @@ GLOBAL_LIST_INIT(meta_gas_dangers, meta_gas_danger_list())
|
||||
GLOBAL_LIST_INIT(meta_gas_ids, meta_gas_id_list())
|
||||
GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
|
||||
/datum/gas_mixture
|
||||
var/list/gases = list()
|
||||
var/list/gas_archive = list()
|
||||
var/temperature = 0 //kelvins
|
||||
var/tmp/temperature_archived = 0
|
||||
var/volume = CELL_VOLUME //liters
|
||||
var/last_share = 0
|
||||
var/list/reaction_results = list()
|
||||
var/initial_volume = CELL_VOLUME //liters
|
||||
var/list/reaction_results
|
||||
var/list/analyzer_results //used for analyzer feedback - not initialized until its used
|
||||
var/gc_share = FALSE // Whether to call garbage_collect() on the sharer during shares, used for immutable mixtures
|
||||
var/_extools_pointer_gasmixture = 0 // Contains the memory address of the shared_ptr object for this gas mixture in c++ land. Don't. Touch. This. Var.
|
||||
|
||||
/datum/gas_mixture/New(volume)
|
||||
if (!isnull(volume))
|
||||
src.volume = volume
|
||||
initial_volume = volume
|
||||
ATMOS_EXTOOLS_CHECK
|
||||
__gasmixture_register()
|
||||
reaction_results = new
|
||||
|
||||
//PV = nRT
|
||||
/datum/gas_mixture/vv_edit_var(var_name, var_value)
|
||||
if(var_name == "_extools_pointer_gasmixture")
|
||||
return FALSE // please no. segfaults bad.
|
||||
return ..()
|
||||
/*
|
||||
/datum/gas_mixture/Del()
|
||||
__gasmixture_unregister()
|
||||
. = ..()*/
|
||||
|
||||
/datum/gas_mixture/proc/heat_capacity()
|
||||
/datum/gas_mixture/proc/__gasmixture_unregister()
|
||||
/datum/gas_mixture/proc/__gasmixture_register()
|
||||
|
||||
/datum/gas_mixture/proc/archived_heat_capacity()
|
||||
/proc/gas_types()
|
||||
var/list/L = subtypesof(/datum/gas)
|
||||
for(var/gt in L)
|
||||
var/datum/gas/G = gt
|
||||
L[gt] = initial(G.specific_heat)
|
||||
return L
|
||||
|
||||
/datum/gas_mixture/heat_capacity() //joules per kelvin
|
||||
var/list/cached_gases = gases
|
||||
var/list/cached_gasheats = GLOB.meta_gas_specific_heats
|
||||
. = 0
|
||||
for(var/id in cached_gases)
|
||||
. += cached_gases[id] * cached_gasheats[id]
|
||||
|
||||
/datum/gas_mixture/archived_heat_capacity()
|
||||
// lots of copypasta but heat_capacity is the single proc called the most in a regular round, bar none, so performance loss adds up
|
||||
var/list/cached_gases = gas_archive
|
||||
var/list/cached_gasheats = GLOB.meta_gas_specific_heats
|
||||
. = 0
|
||||
for(var/id in cached_gases)
|
||||
. += cached_gases[id] * cached_gasheats[id]
|
||||
|
||||
/datum/gas_mixture/turf/heat_capacity() // Same as above except vacuums return HEAT_CAPACITY_VACUUM
|
||||
var/list/cached_gases = gases
|
||||
var/list/cached_gasheats = GLOB.meta_gas_specific_heats
|
||||
for(var/id in cached_gases)
|
||||
. += cached_gases[id] * cached_gasheats[id]
|
||||
if(!.)
|
||||
. += HEAT_CAPACITY_VACUUM //we want vacuums in turfs to have the same heat capacity as space
|
||||
|
||||
/datum/gas_mixture/turf/archived_heat_capacity() // Same as above except vacuums return HEAT_CAPACITY_VACUUM
|
||||
var/list/cached_gases = gas_archive
|
||||
var/list/cached_gasheats = GLOB.meta_gas_specific_heats
|
||||
for(var/id in cached_gases)
|
||||
. += cached_gases[id] * cached_gasheats[id]
|
||||
if(!.)
|
||||
. += HEAT_CAPACITY_VACUUM //we want vacuums in turfs to have the same heat capacity as space
|
||||
/datum/gas_mixture/proc/heat_capacity() //joules per kelvin
|
||||
|
||||
/datum/gas_mixture/proc/total_moles()
|
||||
var/cached_gases = gases
|
||||
TOTAL_MOLES(cached_gases, .)
|
||||
|
||||
/datum/gas_mixture/proc/return_pressure() //kilopascals
|
||||
if(volume > 0) // to prevent division by zero
|
||||
var/cached_gases = gases
|
||||
TOTAL_MOLES(cached_gases, .)
|
||||
. *= R_IDEAL_GAS_EQUATION * temperature / volume
|
||||
return
|
||||
return 0
|
||||
|
||||
/datum/gas_mixture/proc/return_temperature() //kelvins
|
||||
return temperature
|
||||
|
||||
/datum/gas_mixture/proc/set_min_heat_capacity(n)
|
||||
/datum/gas_mixture/proc/set_temperature(new_temp)
|
||||
/datum/gas_mixture/proc/set_volume(new_volume)
|
||||
/datum/gas_mixture/proc/get_moles(gas_type)
|
||||
/datum/gas_mixture/proc/set_moles(gas_type, moles)
|
||||
/datum/gas_mixture/proc/scrub_into(datum/gas_mixture/target, list/gases)
|
||||
/datum/gas_mixture/proc/mark_immutable()
|
||||
/datum/gas_mixture/proc/get_gases()
|
||||
/datum/gas_mixture/proc/multiply(factor)
|
||||
/datum/gas_mixture/proc/get_last_share()
|
||||
/datum/gas_mixture/proc/clear()
|
||||
|
||||
/datum/gas_mixture/proc/adjust_moles(gas_type, amt = 0)
|
||||
set_moles(gas_type, get_moles(gas_type) + amt)
|
||||
|
||||
/datum/gas_mixture/proc/return_volume() //liters
|
||||
return max(0, volume)
|
||||
|
||||
/datum/gas_mixture/proc/thermal_energy() //joules
|
||||
return THERMAL_ENERGY(src) //see code/__DEFINES/atmospherics.dm; use the define in performance critical areas
|
||||
|
||||
/datum/gas_mixture/proc/archive()
|
||||
//Update archived versions of variables
|
||||
//Returns: 1 in all cases
|
||||
|
||||
/datum/gas_mixture/proc/merge(datum/gas_mixture/giver)
|
||||
//Merges all air from giver into self. Deletes giver.
|
||||
//Merges all air from giver into self. giver is untouched.
|
||||
//Returns: 1 if we are mutable, 0 otherwise
|
||||
|
||||
/datum/gas_mixture/proc/remove(amount)
|
||||
//Proportionally removes amount of gas from the gas_mixture
|
||||
//Removes amount of gas from the gas_mixture
|
||||
//Returns: gas_mixture with the gases removed
|
||||
|
||||
/datum/gas_mixture/proc/transfer_to(datum/gas_mixture/target, amount)
|
||||
//Transfers amount of gas to target. Equivalent to target.merge(remove(amount)) but faster.
|
||||
//Removes amount of gas from the gas_mixture
|
||||
|
||||
/datum/gas_mixture/proc/remove_ratio(ratio)
|
||||
//Proportionally removes amount of gas from the gas_mixture
|
||||
//Returns: gas_mixture with the gases removed
|
||||
@@ -136,245 +126,63 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
|
||||
//Performs various reactions such as combustion or fusion (LOL)
|
||||
//Returns: 1 if any reaction took place; 0 otherwise
|
||||
|
||||
/datum/gas_mixture/archive()
|
||||
temperature_archived = temperature
|
||||
gas_archive = gases.Copy()
|
||||
return 1
|
||||
|
||||
/datum/gas_mixture/merge(datum/gas_mixture/giver)
|
||||
if(!giver)
|
||||
return 0
|
||||
|
||||
//heat transfer
|
||||
if(abs(temperature - giver.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/self_heat_capacity = heat_capacity()
|
||||
var/giver_heat_capacity = giver.heat_capacity()
|
||||
var/combined_heat_capacity = giver_heat_capacity + self_heat_capacity
|
||||
if(combined_heat_capacity)
|
||||
temperature = (giver.temperature * giver_heat_capacity + temperature * self_heat_capacity) / combined_heat_capacity
|
||||
|
||||
var/list/cached_gases = gases //accessing datum vars is slower than proc vars
|
||||
var/list/giver_gases = giver.gases
|
||||
//gas transfer
|
||||
for(var/giver_id in giver_gases)
|
||||
cached_gases[giver_id] += giver_gases[giver_id]
|
||||
|
||||
return 1
|
||||
|
||||
/datum/gas_mixture/proc/__remove()
|
||||
/datum/gas_mixture/remove(amount)
|
||||
var/sum
|
||||
var/list/cached_gases = gases
|
||||
TOTAL_MOLES(cached_gases, sum)
|
||||
amount = min(amount, sum) //Can not take more air than tile has!
|
||||
if(amount <= 0)
|
||||
return null
|
||||
var/datum/gas_mixture/removed = new type
|
||||
var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars
|
||||
|
||||
removed.temperature = temperature
|
||||
for(var/id in cached_gases)
|
||||
removed_gases[id] = QUANTIZE((cached_gases[id] / sum) * amount)
|
||||
cached_gases[id] -= removed_gases[id]
|
||||
GAS_GARBAGE_COLLECT(gases)
|
||||
__remove(removed, amount)
|
||||
|
||||
return removed
|
||||
|
||||
/datum/gas_mixture/proc/__remove_ratio()
|
||||
/datum/gas_mixture/remove_ratio(ratio)
|
||||
if(ratio <= 0)
|
||||
return null
|
||||
ratio = min(ratio, 1)
|
||||
|
||||
var/list/cached_gases = gases
|
||||
var/datum/gas_mixture/removed = new type
|
||||
var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars
|
||||
|
||||
removed.temperature = temperature
|
||||
for(var/id in cached_gases)
|
||||
removed_gases[id] = QUANTIZE(cached_gases[id] * ratio)
|
||||
cached_gases[id] -= removed_gases[id]
|
||||
|
||||
GAS_GARBAGE_COLLECT(gases)
|
||||
__remove_ratio(removed, ratio)
|
||||
|
||||
return removed
|
||||
|
||||
/datum/gas_mixture/copy()
|
||||
var/list/cached_gases = gases
|
||||
var/datum/gas_mixture/copy = new type
|
||||
var/list/copy_gases = copy.gases
|
||||
|
||||
copy.temperature = temperature
|
||||
for(var/id in cached_gases)
|
||||
copy_gases[id] = cached_gases[id]
|
||||
copy.copy_from(src)
|
||||
|
||||
return copy
|
||||
|
||||
|
||||
/datum/gas_mixture/copy_from(datum/gas_mixture/sample)
|
||||
var/list/cached_gases = gases //accessing datum vars is slower than proc vars
|
||||
var/list/sample_gases = sample.gases
|
||||
|
||||
temperature = sample.temperature
|
||||
for(var/id in sample_gases)
|
||||
cached_gases[id] = sample_gases[id]
|
||||
|
||||
//remove all gases not in the sample
|
||||
cached_gases &= sample_gases
|
||||
|
||||
return 1
|
||||
|
||||
/datum/gas_mixture/copy_from_turf(turf/model)
|
||||
parse_gas_string(model.initial_gas_mix)
|
||||
|
||||
//acounts for changes in temperature
|
||||
var/turf/model_parent = model.parent_type
|
||||
if(model.temperature != initial(model.temperature) || model.temperature != initial(model_parent.temperature))
|
||||
temperature = model.temperature
|
||||
set_temperature(model.temperature)
|
||||
|
||||
return 1
|
||||
|
||||
/datum/gas_mixture/parse_gas_string(gas_string)
|
||||
var/list/gases = src.gases
|
||||
var/list/gas = params2list(gas_string)
|
||||
if(gas["TEMP"])
|
||||
temperature = text2num(gas["TEMP"])
|
||||
set_temperature(text2num(gas["TEMP"]))
|
||||
gas -= "TEMP"
|
||||
gases.Cut()
|
||||
clear()
|
||||
for(var/id in gas)
|
||||
var/path = id
|
||||
if(!ispath(path))
|
||||
path = gas_id2path(path) //a lot of these strings can't have embedded expressions (especially for mappers), so support for IDs needs to stick around
|
||||
gases[path] = text2num(gas[id])
|
||||
set_moles(path, text2num(gas[id]))
|
||||
archive()
|
||||
return 1
|
||||
|
||||
/datum/gas_mixture/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4)
|
||||
|
||||
var/list/cached_gases = gases
|
||||
var/list/sharer_gases = sharer.gases
|
||||
|
||||
var/temperature_delta = temperature_archived - sharer.temperature_archived
|
||||
var/abs_temperature_delta = abs(temperature_delta)
|
||||
|
||||
var/old_self_heat_capacity = 0
|
||||
var/old_sharer_heat_capacity = 0
|
||||
if(abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
old_self_heat_capacity = heat_capacity()
|
||||
old_sharer_heat_capacity = sharer.heat_capacity()
|
||||
|
||||
var/heat_capacity_self_to_sharer = 0 //heat capacity of the moles transferred from us to the sharer
|
||||
var/heat_capacity_sharer_to_self = 0 //heat capacity of the moles transferred from the sharer to us
|
||||
|
||||
var/moved_moles = 0
|
||||
var/abs_moved_moles = 0
|
||||
|
||||
//we're gonna define these vars outside of this for loop because as it turns out, var declaration is pricy
|
||||
var/delta
|
||||
var/gas_heat_capacity
|
||||
//and also cache this shit rq because that results in sanic speed for reasons byond explanation
|
||||
var/list/cached_gasheats = GLOB.meta_gas_specific_heats
|
||||
//GAS TRANSFER
|
||||
for(var/id in cached_gases | sharer_gases) // transfer gases
|
||||
|
||||
delta = QUANTIZE(gas_archive[id] - sharer.gas_archive[id])/(atmos_adjacent_turfs+1) //the amount of gas that gets moved between the mixtures
|
||||
|
||||
if(delta && abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
gas_heat_capacity = delta * cached_gasheats[id]
|
||||
if(delta > 0)
|
||||
heat_capacity_self_to_sharer += gas_heat_capacity
|
||||
else
|
||||
heat_capacity_sharer_to_self -= gas_heat_capacity //subtract here instead of adding the absolute value because we know that delta is negative.
|
||||
|
||||
cached_gases[id] -= delta
|
||||
sharer_gases[id] += delta
|
||||
moved_moles += delta
|
||||
abs_moved_moles += abs(delta)
|
||||
|
||||
last_share = abs_moved_moles
|
||||
|
||||
//THERMAL ENERGY TRANSFER
|
||||
if(abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/new_self_heat_capacity = old_self_heat_capacity + heat_capacity_sharer_to_self - heat_capacity_self_to_sharer
|
||||
var/new_sharer_heat_capacity = old_sharer_heat_capacity + heat_capacity_self_to_sharer - heat_capacity_sharer_to_self
|
||||
|
||||
//transfer of thermal energy (via changed heat capacity) between self and sharer
|
||||
if(new_self_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
temperature = (old_self_heat_capacity*temperature - heat_capacity_self_to_sharer*temperature_archived + heat_capacity_sharer_to_self*sharer.temperature_archived)/new_self_heat_capacity
|
||||
|
||||
if(new_sharer_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
sharer.temperature = (old_sharer_heat_capacity*sharer.temperature-heat_capacity_sharer_to_self*sharer.temperature_archived + heat_capacity_self_to_sharer*temperature_archived)/new_sharer_heat_capacity
|
||||
//thermal energy of the system (self and sharer) is unchanged
|
||||
|
||||
if(abs(old_sharer_heat_capacity) > MINIMUM_HEAT_CAPACITY)
|
||||
if(abs(new_sharer_heat_capacity/old_sharer_heat_capacity - 1) < 0.1) // <10% change in sharer heat capacity
|
||||
temperature_share(sharer, OPEN_HEAT_TRANSFER_COEFFICIENT)
|
||||
|
||||
if (initial(sharer.gc_share))
|
||||
GAS_GARBAGE_COLLECT(sharer.gases)
|
||||
if(temperature_delta > MINIMUM_TEMPERATURE_TO_MOVE || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE)
|
||||
var/our_moles
|
||||
TOTAL_MOLES(cached_gases,our_moles)
|
||||
var/their_moles
|
||||
TOTAL_MOLES(sharer_gases,their_moles)
|
||||
return (temperature_archived*(our_moles + moved_moles) - sharer.temperature_archived*(their_moles - moved_moles)) * R_IDEAL_GAS_EQUATION / volume
|
||||
|
||||
/datum/gas_mixture/temperature_share(datum/gas_mixture/sharer, conduction_coefficient, sharer_temperature, sharer_heat_capacity)
|
||||
//transfer of thermal energy (via conduction) between self and sharer
|
||||
if(sharer)
|
||||
sharer_temperature = sharer.temperature_archived
|
||||
var/temperature_delta = temperature_archived - sharer_temperature
|
||||
if(abs(temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/self_heat_capacity = archived_heat_capacity()
|
||||
sharer_heat_capacity = sharer_heat_capacity || sharer.archived_heat_capacity()
|
||||
|
||||
if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
|
||||
var/heat = conduction_coefficient*temperature_delta* \
|
||||
(self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity))
|
||||
|
||||
temperature = max(temperature - heat/self_heat_capacity, TCMB)
|
||||
sharer_temperature = max(sharer_temperature + heat/sharer_heat_capacity, TCMB)
|
||||
if(sharer)
|
||||
sharer.temperature = sharer_temperature
|
||||
return sharer_temperature
|
||||
//thermal energy of the system (self and sharer) is unchanged
|
||||
|
||||
/datum/gas_mixture/compare(datum/gas_mixture/sample)
|
||||
var/list/sample_gases = sample.gases //accessing datum vars is slower than proc vars
|
||||
var/list/cached_gases = gases
|
||||
|
||||
for(var/id in cached_gases | sample_gases) // compare gases from either mixture
|
||||
var/gas_moles = cached_gases[id]
|
||||
var/sample_moles = sample_gases[id]
|
||||
var/delta = abs(gas_moles - sample_moles)
|
||||
if(delta > MINIMUM_MOLES_DELTA_TO_MOVE && \
|
||||
delta > gas_moles * MINIMUM_AIR_RATIO_TO_MOVE)
|
||||
return id
|
||||
|
||||
var/our_moles
|
||||
TOTAL_MOLES(cached_gases, our_moles)
|
||||
if(our_moles > MINIMUM_MOLES_DELTA_TO_MOVE)
|
||||
var/temp = temperature
|
||||
var/sample_temp = sample.temperature
|
||||
|
||||
var/temperature_delta = abs(temp - sample_temp)
|
||||
if(temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
|
||||
return "temp"
|
||||
|
||||
return ""
|
||||
|
||||
|
||||
/datum/gas_mixture/react(datum/holder)
|
||||
. = NO_REACTION
|
||||
var/list/cached_gases = gases
|
||||
if(!length(cached_gases))
|
||||
if(!total_moles())
|
||||
return
|
||||
var/list/reactions = list()
|
||||
for(var/datum/gas_reaction/G in SSair.gas_reactions)
|
||||
if(cached_gases[G.major_gas])
|
||||
if(get_moles(G.major_gas))
|
||||
reactions += G
|
||||
if(!length(reactions))
|
||||
return
|
||||
reaction_results = new
|
||||
var/temp = temperature
|
||||
var/ener = THERMAL_ENERGY(src)
|
||||
var/temp = return_temperature()
|
||||
var/ener = thermal_energy()
|
||||
|
||||
reaction_loop:
|
||||
for(var/r in reactions)
|
||||
@@ -388,14 +196,13 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
|
||||
for(var/id in min_reqs)
|
||||
if (id == "TEMP" || id == "ENER")
|
||||
continue
|
||||
if(cached_gases[id] < min_reqs[id])
|
||||
if(get_moles(id) < min_reqs[id])
|
||||
continue reaction_loop
|
||||
//at this point, all minimum requirements for the reaction are satisfied.
|
||||
|
||||
/* currently no reactions have maximum requirements, so we can leave the checks commented out for a slight performance boost
|
||||
PLEASE DO NOT REMOVE THIS CODE. the commenting is here only for a performance increase.
|
||||
enabling these checks should be as easy as possible and the fact that they are disabled should be as clear as possible
|
||||
|
||||
var/list/max_reqs = reaction.max_requirements
|
||||
if((max_reqs["TEMP"] && temp > max_reqs["TEMP"]) \
|
||||
|| (max_reqs["ENER"] && ener > max_reqs["ENER"]))
|
||||
@@ -410,8 +217,6 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
|
||||
. |= reaction.react(src, holder)
|
||||
if (. & STOP_REACTIONS)
|
||||
break
|
||||
if(.)
|
||||
GAS_GARBAGE_COLLECT(gases)
|
||||
|
||||
//Takes the amount of the gas you want to PP as an argument
|
||||
//So I don't have to do some hacky switches/defines/magic strings
|
||||
@@ -420,16 +225,50 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
|
||||
//O2_PP = get_partial_pressure(gas_mixture.oxygen)
|
||||
|
||||
/datum/gas_mixture/proc/get_breath_partial_pressure(gas_pressure)
|
||||
return (gas_pressure * R_IDEAL_GAS_EQUATION * temperature) / BREATH_VOLUME
|
||||
return (gas_pressure * R_IDEAL_GAS_EQUATION * return_temperature()) / BREATH_VOLUME
|
||||
//inverse
|
||||
/datum/gas_mixture/proc/get_true_breath_pressure(partial_pressure)
|
||||
return (partial_pressure * BREATH_VOLUME) / (R_IDEAL_GAS_EQUATION * temperature)
|
||||
return (partial_pressure * BREATH_VOLUME) / (R_IDEAL_GAS_EQUATION * return_temperature())
|
||||
|
||||
//Mathematical proofs:
|
||||
/*
|
||||
get_breath_partial_pressure(gas_pp) --> gas_pp/total_moles()*breath_pp = pp
|
||||
get_true_breath_pressure(pp) --> gas_pp = pp/breath_pp*total_moles()
|
||||
|
||||
10/20*5 = 2.5
|
||||
10 = 2.5/5*20
|
||||
*/
|
||||
|
||||
/datum/gas_mixture/turf
|
||||
|
||||
/*
|
||||
/mob/verb/profile_atmos()
|
||||
/world{loop_checks = 0;}
|
||||
var/datum/gas_mixture/A = new
|
||||
var/datum/gas_mixture/B = new
|
||||
A.parse_gas_string("o2=200;n2=800;TEMP=50")
|
||||
B.parse_gas_string("co2=500;plasma=500;TEMP=5000")
|
||||
var/pa
|
||||
var/pb
|
||||
pa = world.tick_usage
|
||||
for(var/I in 1 to 100000)
|
||||
B.transfer_to(A, 1)
|
||||
A.transfer_to(B, 1)
|
||||
pb = world.tick_usage
|
||||
var/total_time = (pb-pa) * world.tick_lag
|
||||
to_chat(src, "Total time (gas transfer): [total_time]ms")
|
||||
to_chat(src, "Operations per second: [100000 / (total_time/1000)]")
|
||||
pa = world.tick_usage
|
||||
for(var/I in 1 to 100000)
|
||||
B.total_moles();
|
||||
pb = world.tick_usage
|
||||
total_time = (pb-pa) * world.tick_lag
|
||||
to_chat(src, "Total time (total_moles): [total_time]ms")
|
||||
to_chat(src, "Operations per second: [100000 / (total_time/1000)]")
|
||||
pa = world.tick_usage
|
||||
for(var/I in 1 to 100000)
|
||||
new /datum/gas_mixture
|
||||
pb = world.tick_usage
|
||||
total_time = (pb-pa) * world.tick_lag
|
||||
to_chat(src, "Total time (new gas mixture): [total_time]ms")
|
||||
to_chat(src, "Operations per second: [100000 / (total_time/1000)]")
|
||||
*/
|
||||
|
||||
@@ -2,73 +2,29 @@
|
||||
//it can be changed, but any changes will ultimately be undone before they can have any effect
|
||||
|
||||
/datum/gas_mixture/immutable
|
||||
var/initial_temperature
|
||||
gc_share = TRUE
|
||||
var/initial_temperature = 0
|
||||
|
||||
/datum/gas_mixture/immutable/New()
|
||||
..()
|
||||
temperature = initial_temperature
|
||||
temperature_archived = initial_temperature
|
||||
gases.Cut()
|
||||
set_temperature(initial_temperature)
|
||||
populate()
|
||||
mark_immutable()
|
||||
|
||||
/datum/gas_mixture/immutable/merge()
|
||||
return 0 //we're immutable.
|
||||
/datum/gas_mixture/immutable/proc/populate()
|
||||
return
|
||||
|
||||
/datum/gas_mixture/immutable/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4)
|
||||
. = ..(sharer, 0)
|
||||
temperature = initial_temperature
|
||||
temperature_archived = initial_temperature
|
||||
gases.Cut()
|
||||
|
||||
/datum/gas_mixture/immutable/react()
|
||||
return 0 //we're immutable.
|
||||
|
||||
/datum/gas_mixture/immutable/copy()
|
||||
return new type //we're immutable, so we can just return a new instance.
|
||||
|
||||
/datum/gas_mixture/immutable/copy_from()
|
||||
return 0 //we're immutable.
|
||||
|
||||
/datum/gas_mixture/immutable/copy_from_turf()
|
||||
return 0 //we're immutable.
|
||||
|
||||
/datum/gas_mixture/immutable/parse_gas_string()
|
||||
return 0 //we're immutable.
|
||||
|
||||
/datum/gas_mixture/immutable/temperature_share(datum/gas_mixture/sharer, conduction_coefficient, sharer_temperature, sharer_heat_capacity)
|
||||
. = ..()
|
||||
temperature = initial_temperature
|
||||
|
||||
/datum/gas_mixture/immutable/proc/after_process_cell()
|
||||
temperature = initial_temperature
|
||||
temperature_archived = initial_temperature
|
||||
gases.Cut()
|
||||
|
||||
//used by space tiles
|
||||
/datum/gas_mixture/immutable/space
|
||||
initial_temperature = TCMB
|
||||
|
||||
/datum/gas_mixture/immutable/space/heat_capacity()
|
||||
return HEAT_CAPACITY_VACUUM
|
||||
|
||||
/datum/gas_mixture/immutable/space/remove()
|
||||
return copy() //we're always empty, so we can just return a copy.
|
||||
|
||||
/datum/gas_mixture/immutable/space/remove_ratio()
|
||||
return copy() //we're always empty, so we can just return a copy.
|
||||
|
||||
/datum/gas_mixture/immutable/space/populate()
|
||||
set_min_heat_capacity(HEAT_CAPACITY_VACUUM)
|
||||
|
||||
//used by cloners
|
||||
/datum/gas_mixture/immutable/cloner
|
||||
initial_temperature = T20C
|
||||
|
||||
/datum/gas_mixture/immutable/cloner/New()
|
||||
/datum/gas_mixture/immutable/cloner/populate()
|
||||
..()
|
||||
gases[/datum/gas/nitrogen] = MOLES_O2STANDARD + MOLES_N2STANDARD
|
||||
|
||||
/datum/gas_mixture/immutable/cloner/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4)
|
||||
. = ..(sharer, 0)
|
||||
gases[/datum/gas/nitrogen] = MOLES_O2STANDARD + MOLES_N2STANDARD
|
||||
|
||||
/datum/gas_mixture/immutable/cloner/heat_capacity()
|
||||
return (MOLES_O2STANDARD + MOLES_N2STANDARD)*20 //specific heat of nitrogen is 20
|
||||
set_moles(/datum/gas/nitrogen, MOLES_O2STANDARD + MOLES_N2STANDARD)
|
||||
|
||||
@@ -63,11 +63,11 @@
|
||||
/datum/gas_reaction/water_vapor/react(datum/gas_mixture/air, datum/holder)
|
||||
var/turf/open/location = isturf(holder) ? holder : null
|
||||
. = NO_REACTION
|
||||
if (air.temperature <= WATER_VAPOR_FREEZE)
|
||||
if (air.return_temperature() <= WATER_VAPOR_FREEZE)
|
||||
if(location && location.freon_gas_act())
|
||||
. = REACTING
|
||||
else if(location && location.water_vapor_gas_act())
|
||||
air.gases[/datum/gas/water_vapor] -= MOLES_GAS_VISIBLE
|
||||
air.adjust_moles(/datum/gas/water_vapor,-MOLES_GAS_VISIBLE)
|
||||
. = REACTING
|
||||
|
||||
//tritium combustion: combustion of oxygen and tritium (treated as hydrocarbons). creates hotspots. exothermic
|
||||
@@ -86,38 +86,37 @@
|
||||
/datum/gas_reaction/tritfire/react(datum/gas_mixture/air, datum/holder)
|
||||
var/energy_released = 0
|
||||
var/old_heat_capacity = air.heat_capacity()
|
||||
var/list/cached_gases = air.gases //this speeds things up because accessing datum vars is slow
|
||||
var/temperature = air.temperature
|
||||
var/temperature = air.return_temperature()
|
||||
var/list/cached_results = air.reaction_results
|
||||
cached_results["fire"] = 0
|
||||
var/turf/open/location = isturf(holder) ? holder : null
|
||||
|
||||
var/burned_fuel = 0
|
||||
if(cached_gases[/datum/gas/oxygen] < cached_gases[/datum/gas/tritium])
|
||||
burned_fuel = cached_gases[/datum/gas/oxygen]/TRITIUM_BURN_OXY_FACTOR
|
||||
cached_gases[/datum/gas/tritium] -= burned_fuel
|
||||
if(air.get_moles(/datum/gas/oxygen) < air.get_moles(/datum/gas/tritium))
|
||||
burned_fuel = air.get_moles(/datum/gas/oxygen)/TRITIUM_BURN_OXY_FACTOR
|
||||
air.adjust_moles(/datum/gas/tritium, -burned_fuel)
|
||||
else
|
||||
burned_fuel = cached_gases[/datum/gas/tritium]*TRITIUM_BURN_TRIT_FACTOR
|
||||
cached_gases[/datum/gas/tritium] -= cached_gases[/datum/gas/tritium]/TRITIUM_BURN_TRIT_FACTOR
|
||||
cached_gases[/datum/gas/oxygen] -= cached_gases[/datum/gas/tritium]
|
||||
burned_fuel = air.get_moles(/datum/gas/tritium)*TRITIUM_BURN_TRIT_FACTOR
|
||||
air.adjust_moles(/datum/gas/tritium, -air.get_moles(/datum/gas/tritium)/TRITIUM_BURN_TRIT_FACTOR)
|
||||
air.adjust_moles(/datum/gas/oxygen,-air.get_moles(/datum/gas/tritium))
|
||||
|
||||
if(burned_fuel)
|
||||
energy_released += (FIRE_HYDROGEN_ENERGY_RELEASED * burned_fuel)
|
||||
if(location && prob(10) && burned_fuel > TRITIUM_MINIMUM_RADIATION_ENERGY) //woah there let's not crash the server
|
||||
radiation_pulse(location, energy_released/TRITIUM_BURN_RADIOACTIVITY_FACTOR)
|
||||
|
||||
cached_gases[/datum/gas/water_vapor] += burned_fuel/TRITIUM_BURN_OXY_FACTOR
|
||||
air.adjust_moles(/datum/gas/water_vapor, burned_fuel/TRITIUM_BURN_OXY_FACTOR)
|
||||
|
||||
cached_results["fire"] += burned_fuel
|
||||
|
||||
if(energy_released > 0)
|
||||
var/new_heat_capacity = air.heat_capacity()
|
||||
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
air.temperature = (temperature*old_heat_capacity + energy_released)/new_heat_capacity
|
||||
air.set_temperature((temperature*old_heat_capacity + energy_released)/new_heat_capacity)
|
||||
|
||||
//let the floor know a fire is happening
|
||||
if(istype(location))
|
||||
temperature = air.temperature
|
||||
temperature = air.return_temperature()
|
||||
if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
|
||||
location.hotspot_expose(temperature, CELL_VOLUME)
|
||||
for(var/I in location)
|
||||
@@ -143,8 +142,7 @@
|
||||
/datum/gas_reaction/plasmafire/react(datum/gas_mixture/air, datum/holder)
|
||||
var/energy_released = 0
|
||||
var/old_heat_capacity = air.heat_capacity()
|
||||
var/list/cached_gases = air.gases //this speeds things up because accessing datum vars is slow
|
||||
var/temperature = air.temperature
|
||||
var/temperature = air.return_temperature()
|
||||
var/list/cached_results = air.reaction_results
|
||||
cached_results["fire"] = 0
|
||||
var/turf/open/location = isturf(holder) ? holder : null
|
||||
@@ -163,21 +161,21 @@
|
||||
temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE)
|
||||
if(temperature_scale > 0)
|
||||
oxygen_burn_rate = OXYGEN_BURN_RATE_BASE - temperature_scale
|
||||
if(cached_gases[/datum/gas/oxygen] / cached_gases[/datum/gas/plasma] > SUPER_SATURATION_THRESHOLD) //supersaturation. Form Tritium.
|
||||
if(air.get_moles(/datum/gas/oxygen) / air.get_moles(/datum/gas/plasma) > SUPER_SATURATION_THRESHOLD) //supersaturation. Form Tritium.
|
||||
super_saturation = TRUE
|
||||
if(cached_gases[/datum/gas/oxygen] > cached_gases[/datum/gas/plasma]*PLASMA_OXYGEN_FULLBURN)
|
||||
plasma_burn_rate = (cached_gases[/datum/gas/plasma]*temperature_scale)/PLASMA_BURN_RATE_DELTA
|
||||
if(air.get_moles(/datum/gas/oxygen) > air.get_moles(/datum/gas/plasma)*PLASMA_OXYGEN_FULLBURN)
|
||||
plasma_burn_rate = (air.get_moles(/datum/gas/plasma)*temperature_scale)/PLASMA_BURN_RATE_DELTA
|
||||
else
|
||||
plasma_burn_rate = (temperature_scale*(cached_gases[/datum/gas/oxygen]/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA
|
||||
plasma_burn_rate = (temperature_scale*(air.get_moles(/datum/gas/oxygen)/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA
|
||||
|
||||
if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY)
|
||||
plasma_burn_rate = min(plasma_burn_rate,cached_gases[/datum/gas/plasma],cached_gases[/datum/gas/oxygen]/oxygen_burn_rate) //Ensures matter is conserved properly
|
||||
cached_gases[/datum/gas/plasma] = QUANTIZE(cached_gases[/datum/gas/plasma] - plasma_burn_rate)
|
||||
cached_gases[/datum/gas/oxygen] = QUANTIZE(cached_gases[/datum/gas/oxygen] - (plasma_burn_rate * oxygen_burn_rate))
|
||||
plasma_burn_rate = min(plasma_burn_rate,air.get_moles(/datum/gas/plasma),air.get_moles(/datum/gas/oxygen)/oxygen_burn_rate) //Ensures matter is conserved properly
|
||||
air.set_moles(/datum/gas/plasma, QUANTIZE(air.get_moles(/datum/gas/plasma) - plasma_burn_rate))
|
||||
air.set_moles(/datum/gas/oxygen, QUANTIZE(air.get_moles(/datum/gas/oxygen) - (plasma_burn_rate * oxygen_burn_rate)))
|
||||
if (super_saturation)
|
||||
cached_gases[/datum/gas/tritium] += plasma_burn_rate
|
||||
air.adjust_moles(/datum/gas/tritium, plasma_burn_rate)
|
||||
else
|
||||
cached_gases[/datum/gas/carbon_dioxide] += plasma_burn_rate
|
||||
air.adjust_moles(/datum/gas/carbon_dioxide, plasma_burn_rate)
|
||||
|
||||
energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate)
|
||||
|
||||
@@ -186,11 +184,11 @@
|
||||
if(energy_released > 0)
|
||||
var/new_heat_capacity = air.heat_capacity()
|
||||
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
air.temperature = (temperature*old_heat_capacity + energy_released)/new_heat_capacity
|
||||
air.set_temperature((temperature*old_heat_capacity + energy_released)/new_heat_capacity)
|
||||
|
||||
//let the floor know a fire is happening
|
||||
if(istype(location))
|
||||
temperature = air.temperature
|
||||
temperature = air.return_temperature()
|
||||
if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
|
||||
location.hotspot_expose(temperature, CELL_VOLUME)
|
||||
for(var/I in location)
|
||||
@@ -218,7 +216,6 @@
|
||||
/datum/gas/carbon_dioxide = FUSION_MOLE_THRESHOLD)
|
||||
|
||||
/datum/gas_reaction/fusion/react(datum/gas_mixture/air, datum/holder)
|
||||
var/list/cached_gases = air.gases
|
||||
var/turf/open/location
|
||||
if (istype(holder,/datum/pipeline)) //Find the tile the reaction is occuring on, or a random part of the network if it's a pipenet.
|
||||
var/datum/pipeline/fusion_pipenet = holder
|
||||
@@ -230,14 +227,14 @@
|
||||
var/list/cached_scan_results = air.analyzer_results
|
||||
var/old_heat_capacity = air.heat_capacity()
|
||||
var/reaction_energy = 0 //Reaction energy can be negative or positive, for both exothermic and endothermic reactions.
|
||||
var/initial_plasma = cached_gases[/datum/gas/plasma]
|
||||
var/initial_carbon = cached_gases[/datum/gas/carbon_dioxide]
|
||||
var/scale_factor = (air.volume)/(PI) //We scale it down by volume/Pi because for fusion conditions, moles roughly = 2*volume, but we want it to be based off something constant between reactions.
|
||||
var/toroidal_size = (2*PI)+TORADIANS(arctan((air.volume-TOROID_VOLUME_BREAKEVEN)/TOROID_VOLUME_BREAKEVEN)) //The size of the phase space hypertorus
|
||||
var/initial_plasma = air.get_moles(/datum/gas/plasma)
|
||||
var/initial_carbon = air.get_moles(/datum/gas/carbon_dioxide)
|
||||
var/scale_factor = (air.return_volume())/(PI) //We scale it down by volume/Pi because for fusion conditions, moles roughly = 2*volume, but we want it to be based off something constant between reactions.
|
||||
var/toroidal_size = (2*PI)+TORADIANS(arctan((air.return_volume()-TOROID_VOLUME_BREAKEVEN)/TOROID_VOLUME_BREAKEVEN)) //The size of the phase space hypertorus
|
||||
var/gas_power = 0
|
||||
var/list/gas_fusion_powers = GLOB.meta_gas_fusions
|
||||
for (var/gas_id in cached_gases)
|
||||
gas_power += (gas_fusion_powers[gas_id]*cached_gases[gas_id])
|
||||
for (var/gas_id in air.get_gases())
|
||||
gas_power += (gas_fusion_powers[gas_id]*air.get_moles(gas_id))
|
||||
var/instability = MODULUS((gas_power*INSTABILITY_GAS_POWER_FACTOR)**2,toroidal_size) //Instability effects how chaotic the behavior of the reaction is
|
||||
cached_scan_results[id] = instability//used for analyzer feedback
|
||||
|
||||
@@ -249,9 +246,9 @@
|
||||
carbon = MODULUS(carbon - plasma, toroidal_size)
|
||||
|
||||
|
||||
cached_gases[/datum/gas/plasma] = plasma*scale_factor + FUSION_MOLE_THRESHOLD //Scales the gases back up
|
||||
cached_gases[/datum/gas/carbon_dioxide] = carbon*scale_factor + FUSION_MOLE_THRESHOLD
|
||||
var/delta_plasma = initial_plasma - cached_gases[/datum/gas/plasma]
|
||||
air.set_moles(/datum/gas/plasma, plasma*scale_factor + FUSION_MOLE_THRESHOLD) //Scales the gases back up
|
||||
air.set_moles(/datum/gas/carbon_dioxide , carbon*scale_factor + FUSION_MOLE_THRESHOLD)
|
||||
var/delta_plasma = initial_plasma - air.get_moles(/datum/gas/plasma)
|
||||
|
||||
reaction_energy += delta_plasma*PLASMA_BINDING_ENERGY //Energy is gained or lost corresponding to the creation or destruction of mass.
|
||||
if(instability < FUSION_INSTABILITY_ENDOTHERMALITY)
|
||||
@@ -260,17 +257,17 @@
|
||||
reaction_energy *= (instability-FUSION_INSTABILITY_ENDOTHERMALITY)**0.5
|
||||
|
||||
if(air.thermal_energy() + reaction_energy < 0) //No using energy that doesn't exist.
|
||||
cached_gases[/datum/gas/plasma] = initial_plasma
|
||||
cached_gases[/datum/gas/carbon_dioxide] = initial_carbon
|
||||
air.set_moles(/datum/gas/plasma,initial_plasma)
|
||||
air.set_moles(/datum/gas/carbon_dioxide, initial_carbon)
|
||||
return NO_REACTION
|
||||
cached_gases[/datum/gas/tritium] -= FUSION_TRITIUM_MOLES_USED
|
||||
air.adjust_moles(/datum/gas/tritium, -FUSION_TRITIUM_MOLES_USED)
|
||||
//The decay of the tritium and the reaction's energy produces waste gases, different ones depending on whether the reaction is endo or exothermic
|
||||
if(reaction_energy > 0)
|
||||
cached_gases[/datum/gas/oxygen] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT)
|
||||
cached_gases[/datum/gas/nitrous_oxide] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT)
|
||||
air.adjust_moles(/datum/gas/oxygen, FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT))
|
||||
air.adjust_moles(/datum/gas/nitrous_oxide, FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT))
|
||||
else
|
||||
cached_gases[/datum/gas/bz] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT)
|
||||
cached_gases[/datum/gas/nitryl] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT)
|
||||
air.adjust_moles(/datum/gas/bz, FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT))
|
||||
air.adjust_moles(/datum/gas/nitryl, FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT))
|
||||
|
||||
if(reaction_energy)
|
||||
if(location)
|
||||
@@ -282,7 +279,7 @@
|
||||
|
||||
var/new_heat_capacity = air.heat_capacity()
|
||||
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
air.temperature = clamp(((air.temperature*old_heat_capacity + reaction_energy)/new_heat_capacity),TCMB,INFINITY)
|
||||
air.set_temperature(clamp(((air.return_temperature()*old_heat_capacity + reaction_energy)/new_heat_capacity),TCMB,INFINITY))
|
||||
return REACTING
|
||||
|
||||
/datum/gas_reaction/nitrylformation //The formation of nitryl. Endothermic. Requires N2O as a catalyst.
|
||||
@@ -299,22 +296,21 @@
|
||||
)
|
||||
|
||||
/datum/gas_reaction/nitrylformation/react(datum/gas_mixture/air)
|
||||
var/list/cached_gases = air.gases
|
||||
var/temperature = air.temperature
|
||||
var/temperature = air.return_temperature()
|
||||
|
||||
var/old_heat_capacity = air.heat_capacity()
|
||||
var/heat_efficency = min(temperature/(FIRE_MINIMUM_TEMPERATURE_TO_EXIST*100),cached_gases[/datum/gas/oxygen],cached_gases[/datum/gas/nitrogen])
|
||||
var/heat_efficency = min(temperature/(FIRE_MINIMUM_TEMPERATURE_TO_EXIST*100),air.get_moles(/datum/gas/oxygen),air.get_moles(/datum/gas/nitrogen))
|
||||
var/energy_used = heat_efficency*NITRYL_FORMATION_ENERGY
|
||||
if ((cached_gases[/datum/gas/oxygen] - heat_efficency < 0 )|| (cached_gases[/datum/gas/nitrogen] - heat_efficency < 0)) //Shouldn't produce gas from nothing.
|
||||
if ((air.get_moles(/datum/gas/oxygen) - heat_efficency < 0 )|| (air.get_moles(/datum/gas/nitrogen) - heat_efficency < 0)) //Shouldn't produce gas from nothing.
|
||||
return NO_REACTION
|
||||
cached_gases[/datum/gas/oxygen] -= heat_efficency
|
||||
cached_gases[/datum/gas/nitrogen] -= heat_efficency
|
||||
cached_gases[/datum/gas/nitryl] += heat_efficency*2
|
||||
air.adjust_moles(/datum/gas/oxygen, heat_efficency)
|
||||
air.adjust_moles(/datum/gas/nitrogen, heat_efficency)
|
||||
air.adjust_moles(/datum/gas/nitryl, heat_efficency*2)
|
||||
|
||||
if(energy_used > 0)
|
||||
var/new_heat_capacity = air.heat_capacity()
|
||||
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
air.temperature = max(((temperature*old_heat_capacity - energy_used)/new_heat_capacity),TCMB)
|
||||
air.set_temperature(max(((temperature*old_heat_capacity - energy_used)/new_heat_capacity),TCMB))
|
||||
return REACTING
|
||||
|
||||
/datum/gas_reaction/bzformation //Formation of BZ by combining plasma and tritium at low pressures. Exothermic.
|
||||
@@ -330,27 +326,26 @@
|
||||
|
||||
|
||||
/datum/gas_reaction/bzformation/react(datum/gas_mixture/air)
|
||||
var/list/cached_gases = air.gases
|
||||
var/temperature = air.temperature
|
||||
var/temperature = air.return_temperature()
|
||||
var/pressure = air.return_pressure()
|
||||
var/old_heat_capacity = air.heat_capacity()
|
||||
var/reaction_efficency = min(1/((pressure/(0.1*ONE_ATMOSPHERE))*(max(cached_gases[/datum/gas/plasma]/cached_gases[/datum/gas/nitrous_oxide],1))),cached_gases[/datum/gas/nitrous_oxide],cached_gases[/datum/gas/plasma]/2)
|
||||
var/reaction_efficency = min(1/((pressure/(0.1*ONE_ATMOSPHERE))*(max(air.get_moles(/datum/gas/plasma)/air.get_moles(/datum/gas/nitrous_oxide),1))),air.get_moles(/datum/gas/nitrous_oxide),air.get_moles(/datum/gas/plasma)/2)
|
||||
var/energy_released = 2*reaction_efficency*FIRE_CARBON_ENERGY_RELEASED
|
||||
if ((cached_gases[/datum/gas/nitrous_oxide] - reaction_efficency < 0 )|| (cached_gases[/datum/gas/plasma] - (2*reaction_efficency) < 0) || energy_released <= 0) //Shouldn't produce gas from nothing.
|
||||
if ((air.get_moles(/datum/gas/nitrous_oxide) - reaction_efficency < 0 )|| (air.get_moles(/datum/gas/plasma) - (2*reaction_efficency) < 0) || energy_released <= 0) //Shouldn't produce gas from nothing.
|
||||
return NO_REACTION
|
||||
cached_gases[/datum/gas/bz] += reaction_efficency
|
||||
if(reaction_efficency == cached_gases[/datum/gas/nitrous_oxide])
|
||||
cached_gases[/datum/gas/bz] -= min(pressure,1)
|
||||
cached_gases[/datum/gas/oxygen] += min(pressure,1)
|
||||
cached_gases[/datum/gas/nitrous_oxide] -= reaction_efficency
|
||||
cached_gases[/datum/gas/plasma] -= 2*reaction_efficency
|
||||
air.adjust_moles(/datum/gas/bz, reaction_efficency)
|
||||
if(reaction_efficency == air.get_moles(/datum/gas/nitrous_oxide))
|
||||
air.adjust_moles(/datum/gas/bz, -min(pressure,1))
|
||||
air.adjust_moles(/datum/gas/oxygen, min(pressure,1))
|
||||
air.adjust_moles(/datum/gas/nitrous_oxide, -reaction_efficency)
|
||||
air.adjust_moles(/datum/gas/plasma, -2*reaction_efficency)
|
||||
|
||||
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, min((reaction_efficency**2)*BZ_RESEARCH_SCALE),BZ_RESEARCH_MAX_AMOUNT)
|
||||
|
||||
if(energy_released > 0)
|
||||
var/new_heat_capacity = air.heat_capacity()
|
||||
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
air.temperature = max(((temperature*old_heat_capacity + energy_released)/new_heat_capacity),TCMB)
|
||||
air.set_temperature(max(((temperature*old_heat_capacity + energy_released)/new_heat_capacity),TCMB))
|
||||
return REACTING
|
||||
|
||||
/datum/gas_reaction/stimformation //Stimulum formation follows a strange pattern of how effective it will be at a given temperature, having some multiple peaks and some large dropoffs. Exo and endo thermic.
|
||||
@@ -367,24 +362,22 @@
|
||||
"TEMP" = STIMULUM_HEAT_SCALE/2)
|
||||
|
||||
/datum/gas_reaction/stimformation/react(datum/gas_mixture/air)
|
||||
var/list/cached_gases = air.gases
|
||||
|
||||
var/old_heat_capacity = air.heat_capacity()
|
||||
var/heat_scale = min(air.temperature/STIMULUM_HEAT_SCALE,cached_gases[/datum/gas/tritium],cached_gases[/datum/gas/plasma],cached_gases[/datum/gas/nitryl])
|
||||
var/heat_scale = min(air.return_temperature()/STIMULUM_HEAT_SCALE,air.get_moles(/datum/gas/tritium),air.get_moles(/datum/gas/plasma),air.get_moles(/datum/gas/nitryl))
|
||||
var/stim_energy_change = heat_scale + STIMULUM_FIRST_RISE*(heat_scale**2) - STIMULUM_FIRST_DROP*(heat_scale**3) + STIMULUM_SECOND_RISE*(heat_scale**4) - STIMULUM_ABSOLUTE_DROP*(heat_scale**5)
|
||||
|
||||
if ((cached_gases[/datum/gas/tritium] - heat_scale < 0 )|| (cached_gases[/datum/gas/plasma] - heat_scale < 0) || (cached_gases[/datum/gas/nitryl] - heat_scale < 0)) //Shouldn't produce gas from nothing.
|
||||
if ((air.get_moles(/datum/gas/tritium) - heat_scale < 0 )|| (air.get_moles(/datum/gas/plasma) - heat_scale < 0) || (air.get_moles(/datum/gas/nitryl) - heat_scale < 0)) //Shouldn't produce gas from nothing.
|
||||
return NO_REACTION
|
||||
cached_gases[/datum/gas/stimulum]+= heat_scale/10
|
||||
cached_gases[/datum/gas/tritium] -= heat_scale
|
||||
cached_gases[/datum/gas/plasma] -= heat_scale
|
||||
cached_gases[/datum/gas/nitryl] -= heat_scale
|
||||
air.adjust_moles(/datum/gas/stimulum, heat_scale/10)
|
||||
air.adjust_moles(/datum/gas/tritium, -heat_scale)
|
||||
air.adjust_moles(/datum/gas/plasma, -heat_scale)
|
||||
air.adjust_moles(/datum/gas/nitryl, -heat_scale)
|
||||
|
||||
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, STIMULUM_RESEARCH_AMOUNT*max(stim_energy_change,0))
|
||||
if(stim_energy_change)
|
||||
var/new_heat_capacity = air.heat_capacity()
|
||||
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
air.temperature = max(((air.temperature*old_heat_capacity + stim_energy_change)/new_heat_capacity),TCMB)
|
||||
air.set_temperature(max(((air.return_temperature()*old_heat_capacity + stim_energy_change)/new_heat_capacity),TCMB))
|
||||
return REACTING
|
||||
|
||||
/datum/gas_reaction/nobliumformation //Hyper-Noblium formation is extrememly endothermic, but requires high temperatures to start. Due to its high mass, hyper-nobelium uses large amounts of nitrogen and tritium. BZ can be used as a catalyst to make it less endothermic.
|
||||
@@ -399,22 +392,21 @@
|
||||
"TEMP" = 5000000)
|
||||
|
||||
/datum/gas_reaction/nobliumformation/react(datum/gas_mixture/air)
|
||||
var/list/cached_gases = air.gases
|
||||
var/old_heat_capacity = air.heat_capacity()
|
||||
var/nob_formed = min((cached_gases[/datum/gas/nitrogen]+cached_gases[/datum/gas/tritium])/100,cached_gases[/datum/gas/tritium]/10,cached_gases[/datum/gas/nitrogen]/20)
|
||||
var/energy_taken = nob_formed*(NOBLIUM_FORMATION_ENERGY/(max(cached_gases[/datum/gas/bz],1)))
|
||||
if ((cached_gases[/datum/gas/tritium] - 10*nob_formed < 0) || (cached_gases[/datum/gas/nitrogen] - 20*nob_formed < 0))
|
||||
var/nob_formed = min((air.get_moles(/datum/gas/nitrogen)+air.get_moles(/datum/gas/tritium))/100,air.get_moles(/datum/gas/tritium)/10,air.get_moles(/datum/gas/nitrogen)/20)
|
||||
var/energy_taken = nob_formed*(NOBLIUM_FORMATION_ENERGY/(max(air.get_moles(/datum/gas/bz),1)))
|
||||
if ((air.get_moles(/datum/gas/tritium) - 10*nob_formed < 0) || (air.get_moles(/datum/gas/nitrogen) - 20*nob_formed < 0))
|
||||
return NO_REACTION
|
||||
cached_gases[/datum/gas/tritium] -= 10*nob_formed
|
||||
cached_gases[/datum/gas/nitrogen] -= 20*nob_formed
|
||||
cached_gases[/datum/gas/hypernoblium]+= nob_formed
|
||||
air.adjust_moles(/datum/gas/tritium, -10*nob_formed)
|
||||
air.adjust_moles(/datum/gas/nitrogen, -20*nob_formed)
|
||||
air.adjust_moles(/datum/gas/hypernoblium,nob_formed)
|
||||
|
||||
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, nob_formed*NOBLIUM_RESEARCH_AMOUNT)
|
||||
|
||||
if (nob_formed)
|
||||
var/new_heat_capacity = air.heat_capacity()
|
||||
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
air.temperature = max(((air.temperature*old_heat_capacity - energy_taken)/new_heat_capacity),TCMB)
|
||||
air.set_temperature(max(((air.return_temperature()*old_heat_capacity - energy_taken)/new_heat_capacity),TCMB))
|
||||
|
||||
|
||||
/datum/gas_reaction/miaster //dry heat sterilization: clears out pathogens in the air
|
||||
@@ -429,16 +421,15 @@
|
||||
)
|
||||
|
||||
/datum/gas_reaction/miaster/react(datum/gas_mixture/air, datum/holder)
|
||||
var/list/cached_gases = air.gases
|
||||
// As the name says it, it needs to be dry
|
||||
if(cached_gases[/datum/gas/water_vapor] && cached_gases[/datum/gas/water_vapor]/air.total_moles() > 0.1)
|
||||
if(air.get_moles(/datum/gas/water_vapor) && air.get_moles(/datum/gas/water_vapor)/air.total_moles() > 0.1)
|
||||
return
|
||||
|
||||
//Replace miasma with oxygen
|
||||
var/cleaned_air = min(cached_gases[/datum/gas/miasma], 20 + (air.temperature - FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 70) / 20)
|
||||
cached_gases[/datum/gas/miasma] -= cleaned_air
|
||||
cached_gases[/datum/gas/oxygen] += cleaned_air
|
||||
var/cleaned_air = min(air.get_moles(/datum/gas/miasma), 20 + (air.return_temperature() - FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 70) / 20)
|
||||
air.adjust_moles(/datum/gas/miasma, -cleaned_air)
|
||||
air.adjust_moles(/datum/gas/oxygen, cleaned_air)
|
||||
|
||||
//Possibly burning a bit of organic matter through maillard reaction, so a *tiny* bit more heat would be understandable
|
||||
air.temperature += cleaned_air * 0.002
|
||||
air.set_temperature(air.return_temperature() + cleaned_air * 0.002)
|
||||
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, cleaned_air*MIASMA_RESEARCH_AMOUNT)//Turns out the burning of miasma is kinda interesting to scientists
|
||||
|
||||
304
code/modules/atmospherics/gasmixtures/zextools_broke.dm
Normal file
304
code/modules/atmospherics/gasmixtures/zextools_broke.dm
Normal file
@@ -0,0 +1,304 @@
|
||||
#ifdef EXTOOLS_BROKE
|
||||
|
||||
/datum/gas_mixture
|
||||
var/list/gases = list()
|
||||
var/temperature = 0 //kelvins
|
||||
var/tmp/temperature_archived = 0
|
||||
var/volume = CELL_VOLUME //liters
|
||||
var/last_share = 0
|
||||
|
||||
/datum/gas_mixture/heat_capacity() //joules per kelvin
|
||||
var/list/cached_gases = gases
|
||||
var/list/cached_gasheats = GLOB.meta_gas_specific_heats
|
||||
. = 0
|
||||
for(var/id in cached_gases)
|
||||
. += cached_gases[id] * cached_gasheats[id]
|
||||
|
||||
/datum/gas_mixture/turf/heat_capacity() // Same as above except vacuums return HEAT_CAPACITY_VACUUM
|
||||
var/list/cached_gases = gases
|
||||
var/list/cached_gasheats = GLOB.meta_gas_specific_heats
|
||||
for(var/id in cached_gases)
|
||||
. += cached_gases[id] * cached_gasheats[id]
|
||||
if(!.)
|
||||
. += HEAT_CAPACITY_VACUUM //we want vacuums in turfs to have the same heat capacity as space
|
||||
|
||||
//prefer this to gas_mixture/total_moles in performance critical areas
|
||||
#define TOTAL_MOLES(cached_gases, out_var)\
|
||||
out_var = 0;\
|
||||
for(var/total_moles_id in cached_gases){\
|
||||
out_var += cached_gases[total_moles_id];\
|
||||
}
|
||||
|
||||
#define THERMAL_ENERGY(gas) (gas.temperature * gas.heat_capacity())
|
||||
|
||||
/datum/gas_mixture/total_moles()
|
||||
var/cached_gases = gases
|
||||
TOTAL_MOLES(cached_gases, .)
|
||||
|
||||
/datum/gas_mixture/return_pressure() //kilopascals
|
||||
if(volume > 0) // to prevent division by zero
|
||||
var/cached_gases = gases
|
||||
TOTAL_MOLES(cached_gases, .)
|
||||
. *= R_IDEAL_GAS_EQUATION * temperature / volume
|
||||
return
|
||||
return 0
|
||||
|
||||
/datum/gas_mixture/return_temperature() //kelvins
|
||||
return temperature
|
||||
|
||||
/datum/gas_mixture/set_min_heat_capacity(n)
|
||||
return
|
||||
/datum/gas_mixture/set_temperature(new_temp)
|
||||
temperature = new_temp
|
||||
/datum/gas_mixture/set_volume(new_volume)
|
||||
volume = new_volume
|
||||
/datum/gas_mixture/get_moles(gas_type)
|
||||
return gases[gas_type]
|
||||
/datum/gas_mixture/set_moles(gas_type, moles)
|
||||
gases[gas_type] = moles
|
||||
/datum/gas_mixture/scrub_into(datum/gas_mixture/target, list/gases)
|
||||
if(isnull(target))
|
||||
return FALSE
|
||||
|
||||
var/list/removed_gases = target.gases
|
||||
|
||||
//Filter it
|
||||
var/datum/gas_mixture/filtered_out = new
|
||||
var/list/filtered_gases = filtered_out.gases
|
||||
filtered_out.temperature = removed.temperature
|
||||
for(var/gas in filter_types & removed_gases)
|
||||
filtered_gases[gas] = removed_gases[gas]
|
||||
removed_gases[gas] = 0
|
||||
merge(filtered_out)
|
||||
/datum/gas_mixture/mark_immutable()
|
||||
return
|
||||
/datum/gas_mixture/get_gases()
|
||||
return gases
|
||||
/datum/gas_mixture/multiply(factor)
|
||||
for(var/id in gases)
|
||||
gases[id] *= factor
|
||||
/datum/gas_mixture/get_last_share()
|
||||
return last_share
|
||||
/datum/gas_mixture/clear()
|
||||
gases.Cut()
|
||||
|
||||
/datum/gas_mixture/return_volume()
|
||||
return volume // wow!
|
||||
|
||||
/datum/gas_mixture/thermal_energy()
|
||||
return THERMAL_ENERGY(src)
|
||||
|
||||
/datum/gas_mixture/archive()
|
||||
temperature_archived = temperature
|
||||
gas_archive = gases.Copy()
|
||||
return 1
|
||||
|
||||
/datum/gas_mixture/merge(datum/gas_mixture/giver)
|
||||
if(!giver)
|
||||
return 0
|
||||
|
||||
//heat transfer
|
||||
if(abs(temperature - giver.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/self_heat_capacity = heat_capacity()
|
||||
var/giver_heat_capacity = giver.heat_capacity()
|
||||
var/combined_heat_capacity = giver_heat_capacity + self_heat_capacity
|
||||
if(combined_heat_capacity)
|
||||
temperature = (giver.temperature * giver_heat_capacity + temperature * self_heat_capacity) / combined_heat_capacity
|
||||
|
||||
var/list/cached_gases = gases //accessing datum vars is slower than proc vars
|
||||
var/list/giver_gases = giver.gases
|
||||
//gas transfer
|
||||
for(var/giver_id in giver_gases)
|
||||
cached_gases[giver_id] += giver_gases[giver_id]
|
||||
|
||||
return 1
|
||||
|
||||
/datum/gas_mixture/remove(amount)
|
||||
var/sum
|
||||
var/list/cached_gases = gases
|
||||
TOTAL_MOLES(cached_gases, sum)
|
||||
amount = min(amount, sum) //Can not take more air than tile has!
|
||||
if(amount <= 0)
|
||||
return null
|
||||
var/datum/gas_mixture/removed = new type
|
||||
var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars
|
||||
|
||||
removed.temperature = temperature
|
||||
for(var/id in cached_gases)
|
||||
removed_gases[id] = QUANTIZE((cached_gases[id] / sum) * amount)
|
||||
cached_gases[id] -= removed_gases[id]
|
||||
GAS_GARBAGE_COLLECT(gases)
|
||||
|
||||
return removed
|
||||
|
||||
/datum/gas_mixture/remove_ratio(ratio)
|
||||
if(ratio <= 0)
|
||||
return null
|
||||
ratio = min(ratio, 1)
|
||||
|
||||
var/list/cached_gases = gases
|
||||
var/datum/gas_mixture/removed = new type
|
||||
var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars
|
||||
|
||||
removed.temperature = temperature
|
||||
for(var/id in cached_gases)
|
||||
removed_gases[id] = QUANTIZE(cached_gases[id] * ratio)
|
||||
cached_gases[id] -= removed_gases[id]
|
||||
|
||||
GAS_GARBAGE_COLLECT(gases)
|
||||
|
||||
return removed
|
||||
|
||||
/datum/gas_mixture/copy()
|
||||
var/list/cached_gases = gases
|
||||
var/datum/gas_mixture/copy = new type
|
||||
var/list/copy_gases = copy.gases
|
||||
|
||||
copy.temperature = temperature
|
||||
for(var/id in cached_gases)
|
||||
copy_gases[id] = cached_gases[id]
|
||||
|
||||
return copy
|
||||
|
||||
|
||||
/datum/gas_mixture/copy_from(datum/gas_mixture/sample)
|
||||
var/list/cached_gases = gases //accessing datum vars is slower than proc vars
|
||||
var/list/sample_gases = sample.gases
|
||||
|
||||
temperature = sample.temperature
|
||||
for(var/id in sample_gases)
|
||||
cached_gases[id] = sample_gases[id]
|
||||
|
||||
//remove all gases not in the sample
|
||||
cached_gases &= sample_gases
|
||||
|
||||
return 1
|
||||
|
||||
/datum/gas_mixture/copy_from_turf(turf/model)
|
||||
parse_gas_string(model.initial_gas_mix)
|
||||
|
||||
//acounts for changes in temperature
|
||||
var/turf/model_parent = model.parent_type
|
||||
if(model.temperature != initial(model.temperature) || model.temperature != initial(model_parent.temperature))
|
||||
temperature = model.temperature
|
||||
|
||||
return 1
|
||||
|
||||
/datum/gas_mixture/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4)
|
||||
|
||||
var/list/cached_gases = gases
|
||||
var/list/sharer_gases = sharer.gases
|
||||
|
||||
var/temperature_delta = temperature_archived - sharer.temperature_archived
|
||||
var/abs_temperature_delta = abs(temperature_delta)
|
||||
|
||||
var/old_self_heat_capacity = 0
|
||||
var/old_sharer_heat_capacity = 0
|
||||
if(abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
old_self_heat_capacity = heat_capacity()
|
||||
old_sharer_heat_capacity = sharer.heat_capacity()
|
||||
|
||||
var/heat_capacity_self_to_sharer = 0 //heat capacity of the moles transferred from us to the sharer
|
||||
var/heat_capacity_sharer_to_self = 0 //heat capacity of the moles transferred from the sharer to us
|
||||
|
||||
var/moved_moles = 0
|
||||
var/abs_moved_moles = 0
|
||||
|
||||
//we're gonna define these vars outside of this for loop because as it turns out, var declaration is pricy
|
||||
var/delta
|
||||
var/gas_heat_capacity
|
||||
//and also cache this shit rq because that results in sanic speed for reasons byond explanation
|
||||
var/list/cached_gasheats = GLOB.meta_gas_specific_heats
|
||||
//GAS TRANSFER
|
||||
for(var/id in cached_gases | sharer_gases) // transfer gases
|
||||
|
||||
delta = QUANTIZE(gas_archive[id] - sharer.gas_archive[id])/(atmos_adjacent_turfs+1) //the amount of gas that gets moved between the mixtures
|
||||
|
||||
if(delta && abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
gas_heat_capacity = delta * cached_gasheats[id]
|
||||
if(delta > 0)
|
||||
heat_capacity_self_to_sharer += gas_heat_capacity
|
||||
else
|
||||
heat_capacity_sharer_to_self -= gas_heat_capacity //subtract here instead of adding the absolute value because we know that delta is negative.
|
||||
|
||||
cached_gases[id] -= delta
|
||||
sharer_gases[id] += delta
|
||||
moved_moles += delta
|
||||
abs_moved_moles += abs(delta)
|
||||
|
||||
last_share = abs_moved_moles
|
||||
|
||||
//THERMAL ENERGY TRANSFER
|
||||
if(abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/new_self_heat_capacity = old_self_heat_capacity + heat_capacity_sharer_to_self - heat_capacity_self_to_sharer
|
||||
var/new_sharer_heat_capacity = old_sharer_heat_capacity + heat_capacity_self_to_sharer - heat_capacity_sharer_to_self
|
||||
|
||||
//transfer of thermal energy (via changed heat capacity) between self and sharer
|
||||
if(new_self_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
temperature = (old_self_heat_capacity*temperature - heat_capacity_self_to_sharer*temperature_archived + heat_capacity_sharer_to_self*sharer.temperature_archived)/new_self_heat_capacity
|
||||
|
||||
if(new_sharer_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
sharer.temperature = (old_sharer_heat_capacity*sharer.temperature-heat_capacity_sharer_to_self*sharer.temperature_archived + heat_capacity_self_to_sharer*temperature_archived)/new_sharer_heat_capacity
|
||||
//thermal energy of the system (self and sharer) is unchanged
|
||||
|
||||
if(abs(old_sharer_heat_capacity) > MINIMUM_HEAT_CAPACITY)
|
||||
if(abs(new_sharer_heat_capacity/old_sharer_heat_capacity - 1) < 0.1) // <10% change in sharer heat capacity
|
||||
temperature_share(sharer, OPEN_HEAT_TRANSFER_COEFFICIENT)
|
||||
|
||||
if (initial(sharer.gc_share))
|
||||
GAS_GARBAGE_COLLECT(sharer.gases)
|
||||
if(temperature_delta > MINIMUM_TEMPERATURE_TO_MOVE || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE)
|
||||
var/our_moles
|
||||
TOTAL_MOLES(cached_gases,our_moles)
|
||||
var/their_moles
|
||||
TOTAL_MOLES(sharer_gases,their_moles)
|
||||
return (temperature_archived*(our_moles + moved_moles) - sharer.temperature_archived*(their_moles - moved_moles)) * R_IDEAL_GAS_EQUATION / volume
|
||||
|
||||
/datum/gas_mixture/temperature_share(datum/gas_mixture/sharer, conduction_coefficient, sharer_temperature, sharer_heat_capacity)
|
||||
//transfer of thermal energy (via conduction) between self and sharer
|
||||
if(sharer)
|
||||
sharer_temperature = sharer.temperature_archived
|
||||
var/temperature_delta = temperature_archived - sharer_temperature
|
||||
if(abs(temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/self_heat_capacity = archived_heat_capacity()
|
||||
sharer_heat_capacity = sharer_heat_capacity || sharer.archived_heat_capacity()
|
||||
|
||||
if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
|
||||
var/heat = conduction_coefficient*temperature_delta* \
|
||||
(self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity))
|
||||
|
||||
temperature = max(temperature - heat/self_heat_capacity, TCMB)
|
||||
sharer_temperature = max(sharer_temperature + heat/sharer_heat_capacity, TCMB)
|
||||
if(sharer)
|
||||
sharer.temperature = sharer_temperature
|
||||
return sharer_temperature
|
||||
//thermal energy of the system (self and sharer) is unchanged
|
||||
|
||||
/datum/gas_mixture/compare(datum/gas_mixture/sample)
|
||||
var/list/sample_gases = sample.gases //accessing datum vars is slower than proc vars
|
||||
var/list/cached_gases = gases
|
||||
|
||||
for(var/id in cached_gases | sample_gases) // compare gases from either mixture
|
||||
var/gas_moles = cached_gases[id]
|
||||
var/sample_moles = sample_gases[id]
|
||||
var/delta = abs(gas_moles - sample_moles)
|
||||
if(delta > MINIMUM_MOLES_DELTA_TO_MOVE && \
|
||||
delta > gas_moles * MINIMUM_AIR_RATIO_TO_MOVE)
|
||||
return id
|
||||
|
||||
var/our_moles
|
||||
TOTAL_MOLES(cached_gases, our_moles)
|
||||
if(our_moles > MINIMUM_MOLES_DELTA_TO_MOVE)
|
||||
var/temp = temperature
|
||||
var/sample_temp = sample.temperature
|
||||
|
||||
var/temperature_delta = abs(temp - sample_temp)
|
||||
if(temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
|
||||
return "temp"
|
||||
|
||||
return ""
|
||||
|
||||
/datum/gas_mixture/transfer_to(datum/gas_mixture/target, amount)
|
||||
return merge(target.remove(amount))
|
||||
|
||||
#endif
|
||||
@@ -269,7 +269,7 @@
|
||||
"unit" = "kPa",
|
||||
"danger_level" = cur_tlv.get_danger_level(pressure)
|
||||
))
|
||||
var/temperature = environment.temperature
|
||||
var/temperature = environment.return_temperature()
|
||||
cur_tlv = TLV["temperature"]
|
||||
data["environment_data"] += list(list(
|
||||
"name" = "Temperature",
|
||||
@@ -278,16 +278,16 @@
|
||||
"danger_level" = cur_tlv.get_danger_level(temperature)
|
||||
))
|
||||
var/total_moles = environment.total_moles()
|
||||
var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.temperature / environment.volume
|
||||
for(var/gas_id in environment.gases)
|
||||
var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.return_temperature() / environment.return_volume()
|
||||
for(var/gas_id in environment.get_gases())
|
||||
if(!(gas_id in TLV)) // We're not interested in this gas, it seems.
|
||||
continue
|
||||
cur_tlv = TLV[gas_id]
|
||||
data["environment_data"] += list(list(
|
||||
"name" = GLOB.meta_gas_names[gas_id],
|
||||
"value" = environment.gases[gas_id] / total_moles * 100,
|
||||
"value" = environment.get_moles(gas_id) / total_moles * 100,
|
||||
"unit" = "%",
|
||||
"danger_level" = cur_tlv.get_danger_level(environment.gases[gas_id] * partial_pressure)
|
||||
"danger_level" = cur_tlv.get_danger_level(environment.get_moles(gas_id) * partial_pressure)
|
||||
))
|
||||
|
||||
if(!locked || hasSiliconAccessInArea(user, PRIVILEDGES_SILICON|PRIVILEDGES_DRONE))
|
||||
@@ -684,24 +684,21 @@
|
||||
var/datum/tlv/cur_tlv
|
||||
|
||||
var/datum/gas_mixture/environment = location.return_air()
|
||||
var/list/env_gases = environment.gases
|
||||
var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.temperature / environment.volume
|
||||
var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.return_temperature() / environment.return_volume()
|
||||
|
||||
cur_tlv = TLV["pressure"]
|
||||
var/environment_pressure = environment.return_pressure()
|
||||
var/pressure_dangerlevel = cur_tlv.get_danger_level(environment_pressure)
|
||||
|
||||
cur_tlv = TLV["temperature"]
|
||||
var/temperature_dangerlevel = cur_tlv.get_danger_level(environment.temperature)
|
||||
var/temperature_dangerlevel = cur_tlv.get_danger_level(environment.return_temperature())
|
||||
|
||||
var/gas_dangerlevel = 0
|
||||
for(var/gas_id in env_gases)
|
||||
for(var/gas_id in environment.get_gases())
|
||||
if(!(gas_id in TLV)) // We're not interested in this gas, it seems.
|
||||
continue
|
||||
cur_tlv = TLV[gas_id]
|
||||
gas_dangerlevel = max(gas_dangerlevel, cur_tlv.get_danger_level(env_gases[gas_id] * partial_pressure))
|
||||
|
||||
GAS_GARBAGE_COLLECT(environment.gases)
|
||||
gas_dangerlevel = max(gas_dangerlevel, cur_tlv.get_danger_level(environment.get_moles(gas_id) * partial_pressure))
|
||||
|
||||
var/old_danger_level = danger_level
|
||||
danger_level = max(pressure_dangerlevel, temperature_dangerlevel, gas_dangerlevel)
|
||||
|
||||
@@ -52,10 +52,10 @@
|
||||
return null
|
||||
|
||||
//Calculate necessary moles to transfer using PV = nRT
|
||||
if(air2.temperature>0)
|
||||
if(air2.return_temperature()>0)
|
||||
var/pressure_delta = (input_starting_pressure - output_starting_pressure)/2
|
||||
|
||||
var/transfer_moles = pressure_delta*air1.volume/(air2.temperature * R_IDEAL_GAS_EQUATION)
|
||||
var/transfer_moles = pressure_delta*air1.return_volume()/(air2.return_temperature() * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
last_pressure_delta = pressure_delta
|
||||
|
||||
|
||||
@@ -66,8 +66,8 @@
|
||||
pressure_delta = min(pressure_delta, (air1.return_pressure() - input_pressure_min))
|
||||
|
||||
if(pressure_delta > 0)
|
||||
if(air1.temperature > 0)
|
||||
var/transfer_moles = pressure_delta*environment.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
|
||||
if(air1.return_temperature() > 0)
|
||||
var/transfer_moles = pressure_delta*environment.return_volume()/(air1.return_temperature() * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
var/datum/gas_mixture/removed = air1.remove(transfer_moles)
|
||||
//Removed can be null if there is no atmosphere in air1
|
||||
@@ -81,20 +81,17 @@
|
||||
parent1.update = 1
|
||||
|
||||
else //external -> output
|
||||
var/pressure_delta = 10000
|
||||
if(environment.return_pressure() > 0)
|
||||
var/our_multiplier = air2.return_volume() / (environment.return_temperature() * R_IDEAL_GAS_EQUATION)
|
||||
var/moles_delta = 10000 * our_multiplier
|
||||
if(pressure_checks&EXT_BOUND)
|
||||
moles_delta = min(moles_delta, (environment_pressure - output_pressure_max) * environment.return_volume() / (environment.return_temperature() * R_IDEAL_GAS_EQUATION))
|
||||
if(pressure_checks&INPUT_MIN)
|
||||
moles_delta = min(moles_delta, (input_pressure_min - air2.return_pressure()) * our_multiplier)
|
||||
|
||||
if(pressure_checks&EXT_BOUND)
|
||||
pressure_delta = min(pressure_delta, (environment_pressure - external_pressure_bound))
|
||||
if(pressure_checks&INPUT_MIN)
|
||||
pressure_delta = min(pressure_delta, (output_pressure_max - air2.return_pressure()))
|
||||
|
||||
if(pressure_delta > 0)
|
||||
if(environment.temperature > 0)
|
||||
var/transfer_moles = pressure_delta*air2.volume/(environment.temperature * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
var/datum/gas_mixture/removed = loc.remove_air(transfer_moles)
|
||||
//removed can be null if there is no air in the location
|
||||
if(!removed)
|
||||
if(moles_delta > 0)
|
||||
var/datum/gas_mixture/removed = loc.remove_air(moles_delta)
|
||||
if (isnull(removed)) // in space
|
||||
return
|
||||
|
||||
air2.merge(removed)
|
||||
@@ -182,8 +179,8 @@
|
||||
..()
|
||||
var/datum/gas_mixture/air1 = airs[1]
|
||||
var/datum/gas_mixture/air2 = airs[2]
|
||||
air1.volume = 1000
|
||||
air2.volume = 1000
|
||||
air1.set_volume(1000)
|
||||
air2.set_volume(1000)
|
||||
|
||||
// Mapping
|
||||
|
||||
|
||||
@@ -53,11 +53,11 @@ Passive gate is similar to the regular pump except:
|
||||
return
|
||||
|
||||
//Calculate necessary moles to transfer using PV = nRT
|
||||
if((air1.total_moles() > 0) && (air1.temperature>0))
|
||||
if((air1.total_moles() > 0) && (air1.return_temperature()>0))
|
||||
var/pressure_delta = min(target_pressure - output_starting_pressure, (input_starting_pressure - output_starting_pressure)/2)
|
||||
//Can not have a pressure delta that would cause output_pressure > input_pressure
|
||||
|
||||
var/transfer_moles = pressure_delta*air2.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
|
||||
var/transfer_moles = pressure_delta*air2.return_volume()/(air1.return_temperature() * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
//Actually transfer the gas
|
||||
var/datum/gas_mixture/removed = air1.remove(transfer_moles)
|
||||
@@ -172,4 +172,4 @@ Passive gate is similar to the regular pump except:
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/layer3
|
||||
piping_layer = 3
|
||||
icon_state = "passgate_map-3"
|
||||
icon_state = "passgate_map-3"
|
||||
|
||||
@@ -77,9 +77,9 @@
|
||||
return
|
||||
|
||||
//Calculate necessary moles to transfer using PV=nRT
|
||||
if((air1.total_moles() > 0) && (air1.temperature>0))
|
||||
if((air1.total_moles() > 0) && (air1.return_temperature()>0))
|
||||
var/pressure_delta = target_pressure - output_starting_pressure
|
||||
var/transfer_moles = pressure_delta*air2.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
|
||||
var/transfer_moles = pressure_delta*air2.return_volume()/(air1.return_temperature() * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
//Actually transfer the gas
|
||||
var/datum/gas_mixture/removed = air1.remove(transfer_moles)
|
||||
@@ -212,4 +212,4 @@
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/on/layer3
|
||||
piping_layer = 3
|
||||
icon_state= "pump_on_map-3"
|
||||
icon_state= "pump_on_map-3"
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
if((input_starting_pressure < 0.01) || (output_starting_pressure > 9000))
|
||||
return
|
||||
|
||||
var/transfer_ratio = transfer_rate/air1.volume
|
||||
var/transfer_ratio = transfer_rate/air1.return_volume()
|
||||
|
||||
var/datum/gas_mixture/removed = air1.remove_ratio(transfer_ratio)
|
||||
|
||||
@@ -153,7 +153,7 @@
|
||||
|
||||
if("set_transfer_rate" in signal.data)
|
||||
var/datum/gas_mixture/air1 = airs[1]
|
||||
transfer_rate = clamp(text2num(signal.data["set_transfer_rate"]),0,air1.volume)
|
||||
transfer_rate = clamp(text2num(signal.data["set_transfer_rate"]),0,air1.return_volume())
|
||||
|
||||
if(on != old_on)
|
||||
investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_ATMOS)
|
||||
@@ -200,4 +200,4 @@
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/on/layer3
|
||||
piping_layer = 3
|
||||
icon_state = "volpump_map-3"
|
||||
icon_state = "volpump_map-3"
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
..()
|
||||
|
||||
for(var/i in 1 to device_type)
|
||||
var/datum/gas_mixture/A = new
|
||||
A.volume = 200
|
||||
var/datum/gas_mixture/A = new(200)
|
||||
airs[i] = A
|
||||
|
||||
// Iconnery
|
||||
@@ -117,7 +116,7 @@
|
||||
var/times_lost = 0
|
||||
for(var/i in 1 to device_type)
|
||||
var/datum/gas_mixture/air = airs[i]
|
||||
lost += pressures*environment.volume/(air.temperature * R_IDEAL_GAS_EQUATION)
|
||||
lost += pressures*environment.return_volume()/(air.return_temperature() * R_IDEAL_GAS_EQUATION)
|
||||
times_lost++
|
||||
var/shared_loss = lost/times_lost
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
|
||||
//Calculate necessary moles to transfer using PV=nRT
|
||||
|
||||
var/transfer_ratio = transfer_rate/air1.volume
|
||||
var/transfer_ratio = transfer_rate/air1.return_volume()
|
||||
|
||||
//Actually transfer the gas
|
||||
|
||||
@@ -111,14 +111,13 @@
|
||||
else
|
||||
filtering = FALSE
|
||||
|
||||
if(filtering && removed.gases[filter_type])
|
||||
if(filtering && removed.get_moles(filter_type))
|
||||
var/datum/gas_mixture/filtered_out = new
|
||||
|
||||
filtered_out.temperature = removed.temperature
|
||||
filtered_out.gases[filter_type] = removed.gases[filter_type]
|
||||
filtered_out.set_temperature(removed.return_temperature())
|
||||
filtered_out.set_moles(filter_type, removed.get_moles(filter_type))
|
||||
|
||||
removed.gases[filter_type] = 0
|
||||
GAS_GARBAGE_COLLECT(removed.gases)
|
||||
removed.set_moles(filter_type, 0)
|
||||
|
||||
var/datum/gas_mixture/target = (air2.return_pressure() < 9000 ? air2 : air1)
|
||||
target.merge(filtered_out)
|
||||
@@ -280,4 +279,4 @@
|
||||
critical_machine = TRUE
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/filter/flipped/critical
|
||||
critical_machine = TRUE
|
||||
critical_machine = TRUE
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
/obj/machinery/atmospherics/components/trinary/mixer/New()
|
||||
..()
|
||||
var/datum/gas_mixture/air3 = airs[3]
|
||||
air3.volume = 300
|
||||
air3.set_volume(300)
|
||||
airs[3] = air3
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/mixer/process_atmos()
|
||||
@@ -81,26 +81,26 @@
|
||||
return
|
||||
|
||||
//Calculate necessary moles to transfer using PV=nRT
|
||||
var/general_transfer = (target_pressure - output_starting_pressure) * air3.volume / R_IDEAL_GAS_EQUATION
|
||||
var/general_transfer = (target_pressure - output_starting_pressure) * air3.return_volume() / R_IDEAL_GAS_EQUATION
|
||||
|
||||
var/transfer_moles1 = air1.temperature ? node1_concentration * general_transfer / air1.temperature : 0
|
||||
var/transfer_moles2 = air2.temperature ? node2_concentration * general_transfer / air2.temperature : 0
|
||||
var/transfer_moles1 = air1.return_temperature() ? node1_concentration * general_transfer / air1.return_temperature() : 0
|
||||
var/transfer_moles2 = air2.return_temperature() ? node2_concentration * general_transfer / air2.return_temperature() : 0
|
||||
|
||||
var/air1_moles = air1.total_moles()
|
||||
var/air2_moles = air2.total_moles()
|
||||
|
||||
if(!node2_concentration)
|
||||
if(air1.temperature <= 0)
|
||||
if(air1.return_temperature() <= 0)
|
||||
return
|
||||
transfer_moles1 = min(transfer_moles1, air1_moles)
|
||||
transfer_moles2 = 0
|
||||
else if(!node1_concentration)
|
||||
if(air2.temperature <= 0)
|
||||
if(air2.return_temperature() <= 0)
|
||||
return
|
||||
transfer_moles2 = min(transfer_moles2, air2_moles)
|
||||
transfer_moles1 = 0
|
||||
else
|
||||
if(air1.temperature <= 0 || air2.temperature <= 0)
|
||||
if(air1.return_temperature() <= 0 || air2.return_temperature() <= 0)
|
||||
return
|
||||
if((transfer_moles2 <= 0) || (transfer_moles1 <= 0))
|
||||
return
|
||||
@@ -248,4 +248,4 @@
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/mixer/airmix/flipped/inverse
|
||||
node1_concentration = O2STANDARD
|
||||
node2_concentration = N2STANDARD
|
||||
node2_concentration = N2STANDARD
|
||||
|
||||
@@ -186,7 +186,7 @@
|
||||
|
||||
var/datum/gas_mixture/air1 = airs[1]
|
||||
|
||||
if(air1.gases.len)
|
||||
if(air1.total_moles())
|
||||
if(mob_occupant.bodytemperature < T0C) // Sleepytime. Why? More cryo magic.
|
||||
// temperature factor goes from 1 to about 2.5
|
||||
var/amount = max(1, (4 * log(T0C - mob_occupant.bodytemperature)) - 20) * knockout_factor * base_knockout
|
||||
@@ -196,8 +196,7 @@
|
||||
if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic.
|
||||
beaker.reagents.trans_to(occupant, 1, efficiency * 0.25) // Transfer reagents.
|
||||
beaker.reagents.reaction(occupant, VAPOR)
|
||||
air1.gases[/datum/gas/oxygen] -= max(0,air1.gases[/datum/gas/oxygen] - 2 / efficiency) //Let's use gas for this
|
||||
GAS_GARBAGE_COLLECT(air1.gases)
|
||||
air1.adjust_moles(/datum/gas/oxygen, -max(0,air1.get_moles(/datum/gas/oxygen) - 2 / efficiency)) //Let's use gas for this
|
||||
if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker).
|
||||
reagent_transfer = 0
|
||||
|
||||
@@ -211,7 +210,7 @@
|
||||
|
||||
var/datum/gas_mixture/air1 = airs[1]
|
||||
|
||||
if(!nodes[1] || !airs[1] || !air1.gases.len || air1.gases[/datum/gas/oxygen] < 5) // Turn off if the machine won't work.
|
||||
if(!nodes[1] || !airs[1] || air1.get_moles(/datum/gas/oxygen) < 5) // Turn off if the machine won't work.
|
||||
on = FALSE
|
||||
update_icon()
|
||||
return
|
||||
@@ -219,22 +218,21 @@
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
var/cold_protection = 0
|
||||
var/temperature_delta = air1.temperature - mob_occupant.bodytemperature // The only semi-realistic thing here: share temperature between the cell and the occupant.
|
||||
var/temperature_delta = air1.return_temperature() - mob_occupant.bodytemperature // The only semi-realistic thing here: share temperature between the cell and the occupant.
|
||||
|
||||
if(ishuman(occupant))
|
||||
var/mob/living/carbon/human/H = occupant
|
||||
cold_protection = H.get_thermal_protection(air1.temperature, TRUE)
|
||||
cold_protection = H.get_thermal_protection(air1.return_temperature(), TRUE)
|
||||
|
||||
if(abs(temperature_delta) > 1)
|
||||
var/air_heat_capacity = air1.heat_capacity()
|
||||
|
||||
var/heat = ((1 - cold_protection) * 0.1 + conduction_coefficient) * temperature_delta * (air_heat_capacity * heat_capacity / (air_heat_capacity + heat_capacity))
|
||||
|
||||
air1.temperature = max(air1.temperature - heat / air_heat_capacity, TCMB)
|
||||
air1.set_temperature(max(air1.return_temperature() - heat / air_heat_capacity, TCMB))
|
||||
mob_occupant.adjust_bodytemperature(heat / heat_capacity, TCMB)
|
||||
|
||||
air1.gases[/datum/gas/oxygen] = max(0,air1.gases[/datum/gas/oxygen] - 0.5 / efficiency) // Magically consume gas? Why not, we run on cryo magic.
|
||||
GAS_GARBAGE_COLLECT(air1.gases)
|
||||
air1.set_temperature(max(air1.return_temperature() - 0.5 / efficiency)) // Magically consume gas? Why not, we run on cryo magic.
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/power_change()
|
||||
..()
|
||||
@@ -369,7 +367,7 @@
|
||||
data["occupant"]["temperaturestatus"] = "bad"
|
||||
|
||||
var/datum/gas_mixture/air1 = airs[1]
|
||||
data["cellTemperature"] = round(air1.temperature, 1)
|
||||
data["cellTemperature"] = round(air1.return_temperature(), 1)
|
||||
|
||||
data["isBeakerLoaded"] = beaker ? TRUE : FALSE
|
||||
var/beakerContents = list()
|
||||
@@ -439,7 +437,7 @@
|
||||
var/datum/gas_mixture/G = airs[1]
|
||||
|
||||
if(G.total_moles() > 10)
|
||||
return G.temperature
|
||||
return G.return_temperature()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/default_change_direction_wrench(mob/user, obj/item/wrench/W)
|
||||
|
||||
@@ -59,18 +59,18 @@
|
||||
var/other_air_heat_capacity = partner_air_contents.heat_capacity()
|
||||
var/combined_heat_capacity = other_air_heat_capacity + air_heat_capacity
|
||||
|
||||
var/old_temperature = air_contents.temperature
|
||||
var/other_old_temperature = partner_air_contents.temperature
|
||||
var/old_temperature = air_contents.return_temperature()
|
||||
var/other_old_temperature = partner_air_contents.return_temperature()
|
||||
|
||||
if(combined_heat_capacity > 0)
|
||||
var/combined_energy = partner_air_contents.temperature*other_air_heat_capacity + air_heat_capacity*air_contents.temperature
|
||||
var/combined_energy = partner_air_contents.return_temperature()*other_air_heat_capacity + air_heat_capacity*air_contents.return_temperature()
|
||||
|
||||
var/new_temperature = combined_energy/combined_heat_capacity
|
||||
air_contents.temperature = new_temperature
|
||||
partner_air_contents.temperature = new_temperature
|
||||
air_contents.set_temperature(new_temperature)
|
||||
partner_air_contents.set_temperature(new_temperature)
|
||||
|
||||
if(abs(old_temperature-air_contents.temperature) > 1)
|
||||
if(abs(old_temperature-air_contents.return_temperature()) > 1)
|
||||
update_parents()
|
||||
|
||||
if(abs(other_old_temperature-partner_air_contents.temperature) > 1)
|
||||
if(abs(other_old_temperature-partner_air_contents.return_temperature()) > 1)
|
||||
partner.update_parents()
|
||||
|
||||
@@ -52,8 +52,8 @@
|
||||
|
||||
var/datum/gas_mixture/air_contents = airs[1]
|
||||
|
||||
if(air_contents.temperature > 0)
|
||||
var/transfer_moles = (air_contents.return_pressure())*volume_rate/(air_contents.temperature * R_IDEAL_GAS_EQUATION)
|
||||
if(air_contents.return_temperature() > 0)
|
||||
var/transfer_moles = (air_contents.return_pressure())*volume_rate/(air_contents.return_temperature() * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
|
||||
|
||||
@@ -71,8 +71,8 @@
|
||||
|
||||
injecting = 1
|
||||
|
||||
if(air_contents.temperature > 0)
|
||||
var/transfer_moles = (air_contents.return_pressure())*volume_rate/(air_contents.temperature * R_IDEAL_GAS_EQUATION)
|
||||
if(air_contents.return_temperature() > 0)
|
||||
var/transfer_moles = (air_contents.return_pressure())*volume_rate/(air_contents.return_temperature() * R_IDEAL_GAS_EQUATION)
|
||||
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
|
||||
loc.assume_air(removed)
|
||||
update_parents()
|
||||
@@ -123,7 +123,7 @@
|
||||
if("set_volume_rate" in signal.data)
|
||||
var/number = text2num(signal.data["set_volume_rate"])
|
||||
var/datum/gas_mixture/air_contents = airs[1]
|
||||
volume_rate = clamp(number, 0, air_contents.volume)
|
||||
volume_rate = clamp(number, 0, air_contents.return_volume())
|
||||
|
||||
if("status" in signal.data)
|
||||
spawn(2)
|
||||
@@ -241,4 +241,4 @@
|
||||
id = ATMOS_GAS_MONITOR_INPUT_INCINERATOR
|
||||
/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/toxins_mixing_input
|
||||
name = "toxins mixing input injector"
|
||||
id = ATMOS_GAS_MONITOR_INPUT_TOXINS_LAB
|
||||
id = ATMOS_GAS_MONITOR_INPUT_TOXINS_LAB
|
||||
|
||||
@@ -30,14 +30,14 @@
|
||||
|
||||
if(pressure_delta > 0.5)
|
||||
if(external_pressure < internal_pressure)
|
||||
var/air_temperature = (external.temperature > 0) ? external.temperature : internal.temperature
|
||||
var/transfer_moles = (pressure_delta * external.volume) / (air_temperature * R_IDEAL_GAS_EQUATION)
|
||||
var/air_temperature = (external.return_temperature() > 0) ? external.return_temperature() : internal.return_temperature()
|
||||
var/transfer_moles = (pressure_delta * external.return_volume()) / (air_temperature * R_IDEAL_GAS_EQUATION)
|
||||
var/datum/gas_mixture/removed = internal.remove(transfer_moles)
|
||||
external.merge(removed)
|
||||
else
|
||||
var/air_temperature = (internal.temperature > 0) ? internal.temperature : external.temperature
|
||||
var/transfer_moles = (pressure_delta * internal.volume) / (air_temperature * R_IDEAL_GAS_EQUATION)
|
||||
transfer_moles = min(transfer_moles, external.total_moles() * internal.volume / external.volume)
|
||||
var/air_temperature = (internal.return_temperature() > 0) ? internal.return_temperature() : external.return_temperature()
|
||||
var/transfer_moles = (pressure_delta * internal.return_volume()) / (air_temperature * R_IDEAL_GAS_EQUATION)
|
||||
transfer_moles = min(transfer_moles, external.total_moles() * internal.return_volume() / external.return_volume())
|
||||
var/datum/gas_mixture/removed = external.remove(transfer_moles)
|
||||
if(isnull(removed))
|
||||
return
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
..()
|
||||
var/datum/gas_mixture/air_contents = airs[1]
|
||||
|
||||
air_contents.volume = 0
|
||||
air_contents.set_volume(0)
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/portables_connector/Destroy()
|
||||
if(connected_device)
|
||||
@@ -64,4 +64,4 @@
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/portables_connector/visible/layer3
|
||||
piping_layer = 3
|
||||
icon_state = "connector_map-3"
|
||||
icon_state = "connector_map-3"
|
||||
|
||||
@@ -49,10 +49,10 @@
|
||||
else if(!opened && our_pressure >= open_pressure)
|
||||
opened = TRUE
|
||||
update_icon_nopipes()
|
||||
if(opened && air_contents.temperature > 0)
|
||||
if(opened && air_contents.return_temperature() > 0)
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
var/pressure_delta = our_pressure - environment.return_pressure()
|
||||
var/transfer_moles = pressure_delta*200/(air_contents.temperature * R_IDEAL_GAS_EQUATION)
|
||||
var/transfer_moles = pressure_delta*200/(air_contents.return_temperature() * R_IDEAL_GAS_EQUATION)
|
||||
if(transfer_moles > 0)
|
||||
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#define AIR_CONTENTS ((25*ONE_ATMOSPHERE)*(air_contents.volume)/(R_IDEAL_GAS_EQUATION*air_contents.temperature))
|
||||
#define AIR_CONTENTS ((25*ONE_ATMOSPHERE)*(air_contents.return_volume())/(R_IDEAL_GAS_EQUATION*air_contents.return_temperature()))
|
||||
/obj/machinery/atmospherics/components/unary/tank
|
||||
icon = 'icons/obj/atmospherics/pipes/pressure_tank.dmi'
|
||||
icon_state = "generic"
|
||||
@@ -15,10 +15,10 @@
|
||||
/obj/machinery/atmospherics/components/unary/tank/New()
|
||||
..()
|
||||
var/datum/gas_mixture/air_contents = airs[1]
|
||||
air_contents.volume = volume
|
||||
air_contents.temperature = T20C
|
||||
air_contents.set_volume(volume)
|
||||
air_contents.set_temperature(T20C)
|
||||
if(gas_type)
|
||||
air_contents.gases[gas_type] = AIR_CONTENTS
|
||||
air_contents.set_moles(AIR_CONTENTS)
|
||||
name = "[name] ([GLOB.meta_gas_names[gas_type]])"
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/tank/air
|
||||
@@ -28,8 +28,8 @@
|
||||
/obj/machinery/atmospherics/components/unary/tank/air/New()
|
||||
..()
|
||||
var/datum/gas_mixture/air_contents = airs[1]
|
||||
air_contents.gases[/datum/gas/oxygen] = AIR_CONTENTS * 0.2
|
||||
air_contents.gases[/datum/gas/nitrogen] = AIR_CONTENTS * 0.8
|
||||
air_contents.set_moles(/datum/gas/oxygen, AIR_CONTENTS * 0.2)
|
||||
air_contents.set_moles(/datum/gas/nitrogen, AIR_CONTENTS * 0.8)
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/tank/carbon_dioxide
|
||||
gas_type = /datum/gas/carbon_dioxide
|
||||
|
||||
@@ -74,13 +74,13 @@
|
||||
|
||||
var/air_heat_capacity = air_contents.heat_capacity()
|
||||
var/combined_heat_capacity = heat_capacity + air_heat_capacity
|
||||
var/old_temperature = air_contents.temperature
|
||||
var/old_temperature = air_contents.return_temperature()
|
||||
|
||||
if(combined_heat_capacity > 0)
|
||||
var/combined_energy = heat_capacity * target_temperature + air_heat_capacity * air_contents.temperature
|
||||
air_contents.temperature = combined_energy/combined_heat_capacity
|
||||
var/combined_energy = heat_capacity * target_temperature + air_heat_capacity * air_contents.return_temperature()
|
||||
air_contents.set_temperature(combined_energy/combined_heat_capacity)
|
||||
|
||||
var/temperature_delta= abs(old_temperature - air_contents.temperature)
|
||||
var/temperature_delta= abs(old_temperature - air_contents.return_temperature())
|
||||
if(temperature_delta > 1)
|
||||
active_power_usage = (heat_capacity * temperature_delta) / 10 + idle_power_usage
|
||||
update_parents()
|
||||
@@ -142,7 +142,7 @@
|
||||
data["initial"] = initial(target_temperature)
|
||||
|
||||
var/datum/gas_mixture/air1 = airs[1]
|
||||
data["temperature"] = air1.temperature
|
||||
data["temperature"] = air1.return_temperature()
|
||||
data["pressure"] = air1.return_pressure()
|
||||
return data
|
||||
|
||||
|
||||
@@ -104,8 +104,8 @@
|
||||
pressure_delta = min(pressure_delta, (air_contents.return_pressure() - internal_pressure_bound))
|
||||
|
||||
if(pressure_delta > 0)
|
||||
if(air_contents.temperature > 0)
|
||||
var/transfer_moles = pressure_delta*environment.volume/(air_contents.temperature * R_IDEAL_GAS_EQUATION)
|
||||
if(air_contents.return_temperature() > 0)
|
||||
var/transfer_moles = pressure_delta*environment.return_volume()/(air_contents.return_temperature() * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
|
||||
|
||||
@@ -113,21 +113,21 @@
|
||||
air_update_turf()
|
||||
|
||||
else // external -> internal
|
||||
var/pressure_delta = 10000
|
||||
if(pressure_checks&EXT_BOUND)
|
||||
pressure_delta = min(pressure_delta, (environment_pressure - external_pressure_bound))
|
||||
if(pressure_checks&INT_BOUND)
|
||||
pressure_delta = min(pressure_delta, (internal_pressure_bound - air_contents.return_pressure()))
|
||||
if(environment.return_pressure() > 0)
|
||||
var/our_multiplier = air_contents.return_volume() / (environment.return_temperature() * R_IDEAL_GAS_EQUATION)
|
||||
var/moles_delta = 10000 * our_multiplier
|
||||
if(pressure_checks&EXT_BOUND)
|
||||
moles_delta = min(moles_delta, (environment_pressure - external_pressure_bound) * environment.return_volume() / (environment.return_temperature() * R_IDEAL_GAS_EQUATION))
|
||||
if(pressure_checks&INT_BOUND)
|
||||
moles_delta = min(moles_delta, (internal_pressure_bound - air_contents.return_pressure()) * our_multiplier)
|
||||
|
||||
if(pressure_delta > 0 && environment.temperature > 0)
|
||||
var/transfer_moles = pressure_delta * air_contents.volume / (environment.temperature * R_IDEAL_GAS_EQUATION)
|
||||
if(moles_delta > 0)
|
||||
var/datum/gas_mixture/removed = loc.remove_air(moles_delta)
|
||||
if (isnull(removed)) // in space
|
||||
return
|
||||
|
||||
var/datum/gas_mixture/removed = loc.remove_air(transfer_moles)
|
||||
if (isnull(removed)) // in space
|
||||
return
|
||||
|
||||
air_contents.merge(removed)
|
||||
air_update_turf()
|
||||
air_contents.merge(removed)
|
||||
air_update_turf()
|
||||
update_parents()
|
||||
|
||||
//Radio remote control
|
||||
@@ -295,7 +295,7 @@
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/New()
|
||||
..()
|
||||
var/datum/gas_mixture/air_contents = airs[1]
|
||||
air_contents.volume = 1000
|
||||
air_contents.set_volume(1000)
|
||||
|
||||
// mapping
|
||||
|
||||
|
||||
@@ -149,43 +149,29 @@
|
||||
return FALSE
|
||||
var/datum/gas_mixture/environment = tile.return_air()
|
||||
var/datum/gas_mixture/air_contents = airs[1]
|
||||
var/list/env_gases = environment.gases
|
||||
|
||||
if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE)
|
||||
return FALSE
|
||||
|
||||
if(scrubbing & SCRUBBING)
|
||||
if(length(env_gases & filter_types))
|
||||
var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles()
|
||||
var/transfer_moles = min(1, volume_rate/environment.return_volume())*environment.total_moles()
|
||||
|
||||
//Take a gas sample
|
||||
var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)
|
||||
//Take a gas sample
|
||||
var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)
|
||||
|
||||
//Nothing left to remove from the tile
|
||||
if(isnull(removed))
|
||||
return FALSE
|
||||
//Nothing left to remove from the tile
|
||||
if(isnull(removed))
|
||||
return FALSE
|
||||
|
||||
var/list/removed_gases = removed.gases
|
||||
removed.scrub_into(air_contents, filter_types)
|
||||
|
||||
//Filter it
|
||||
var/datum/gas_mixture/filtered_out = new
|
||||
var/list/filtered_gases = filtered_out.gases
|
||||
filtered_out.temperature = removed.temperature
|
||||
|
||||
for(var/gas in filter_types & removed_gases)
|
||||
filtered_gases[gas] = removed_gases[gas]
|
||||
removed_gases[gas] = 0
|
||||
|
||||
GAS_GARBAGE_COLLECT(removed.gases)
|
||||
|
||||
//Remix the resulting gases
|
||||
air_contents.merge(filtered_out)
|
||||
tile.assume_air(removed)
|
||||
tile.air_update_turf()
|
||||
//Remix the resulting gases
|
||||
tile.assume_air(removed)
|
||||
tile.air_update_turf()
|
||||
|
||||
else //Just siphoning all air
|
||||
|
||||
var/transfer_moles = environment.total_moles()*(volume_rate/environment.volume)
|
||||
var/transfer_moles = environment.total_moles()*(volume_rate/environment.return_volume())
|
||||
|
||||
var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
/datum/pipeline/Destroy()
|
||||
SSair.networks -= src
|
||||
if(air && air.volume)
|
||||
if(air && air.return_volume())
|
||||
temporarily_store_air()
|
||||
for(var/obj/machinery/atmospherics/pipe/P in members)
|
||||
P.parent = null
|
||||
@@ -76,7 +76,7 @@
|
||||
|
||||
possible_expansions -= borderline
|
||||
|
||||
air.volume = volume
|
||||
air.set_volume(volume)
|
||||
|
||||
/datum/pipeline/proc/addMachineryMember(obj/machinery/atmospherics/components/C)
|
||||
other_atmosmch |= C
|
||||
@@ -99,7 +99,7 @@
|
||||
merge(E)
|
||||
if(!members.Find(P))
|
||||
members += P
|
||||
air.volume += P.volume
|
||||
air.set_volume(air.return_volume() + P.volume)
|
||||
else
|
||||
A.setPipenet(src, N)
|
||||
addMachineryMember(A)
|
||||
@@ -107,7 +107,7 @@
|
||||
/datum/pipeline/proc/merge(datum/pipeline/E)
|
||||
if(E == src)
|
||||
return
|
||||
air.volume += E.air.volume
|
||||
air.set_volume(air.return_volume() + E.air.return_volume())
|
||||
members.Add(E.members)
|
||||
for(var/obj/machinery/atmospherics/pipe/S in E.members)
|
||||
S.parent = src
|
||||
@@ -139,18 +139,16 @@
|
||||
|
||||
for(var/obj/machinery/atmospherics/pipe/member in members)
|
||||
member.air_temporary = new
|
||||
member.air_temporary.volume = member.volume
|
||||
member.air_temporary.set_volume(member.volume)
|
||||
member.air_temporary.copy_from(air)
|
||||
var/member_gases = member.air_temporary.gases
|
||||
|
||||
for(var/id in member_gases)
|
||||
member_gases[id] *= member.volume/air.volume
|
||||
member.air_temporary.multiply(member.volume/air.return_volume())
|
||||
|
||||
member.air_temporary.temperature = air.temperature
|
||||
member.air_temporary.set_temperature(air.return_temperature())
|
||||
|
||||
/datum/pipeline/proc/temperature_interact(turf/target, share_volume, thermal_conductivity)
|
||||
var/total_heat_capacity = air.heat_capacity()
|
||||
var/partial_heat_capacity = total_heat_capacity*(share_volume/air.volume)
|
||||
var/partial_heat_capacity = total_heat_capacity*(share_volume/air.return_volume())
|
||||
var/target_temperature
|
||||
var/target_heat_capacity
|
||||
|
||||
@@ -163,19 +161,19 @@
|
||||
if(modeled_location.blocks_air)
|
||||
|
||||
if((modeled_location.heat_capacity>0) && (partial_heat_capacity>0))
|
||||
var/delta_temperature = air.temperature - target_temperature
|
||||
var/delta_temperature = air.return_temperature() - target_temperature
|
||||
|
||||
var/heat = thermal_conductivity*delta_temperature* \
|
||||
(partial_heat_capacity*target_heat_capacity/(partial_heat_capacity+target_heat_capacity))
|
||||
|
||||
air.temperature -= heat/total_heat_capacity
|
||||
air.set_temperature(air.return_temperature() - heat/total_heat_capacity)
|
||||
modeled_location.TakeTemperature(heat/target_heat_capacity)
|
||||
|
||||
else
|
||||
var/delta_temperature = 0
|
||||
var/sharer_heat_capacity = 0
|
||||
|
||||
delta_temperature = (air.temperature - target_temperature)
|
||||
delta_temperature = (air.return_temperature() - target_temperature)
|
||||
sharer_heat_capacity = target_heat_capacity
|
||||
|
||||
var/self_temperature_delta = 0
|
||||
@@ -190,18 +188,18 @@
|
||||
else
|
||||
return 1
|
||||
|
||||
air.temperature += self_temperature_delta
|
||||
air.set_temperature(air.return_temperature() + self_temperature_delta)
|
||||
modeled_location.TakeTemperature(sharer_temperature_delta)
|
||||
|
||||
|
||||
else
|
||||
if((target.heat_capacity>0) && (partial_heat_capacity>0))
|
||||
var/delta_temperature = air.temperature - target.temperature
|
||||
var/delta_temperature = air.return_temperature() - target.return_temperature()
|
||||
|
||||
var/heat = thermal_conductivity*delta_temperature* \
|
||||
(partial_heat_capacity*target.heat_capacity/(partial_heat_capacity+target.heat_capacity))
|
||||
|
||||
air.temperature -= heat/total_heat_capacity
|
||||
air.set_temperature(air.return_temperature() - heat/total_heat_capacity)
|
||||
update = TRUE
|
||||
|
||||
/datum/pipeline/proc/return_air()
|
||||
@@ -242,20 +240,18 @@
|
||||
|
||||
for(var/i in GL)
|
||||
var/datum/gas_mixture/G = i
|
||||
total_gas_mixture.volume += G.volume
|
||||
total_gas_mixture.set_volume(total_gas_mixture.return_volume() + G.return_volume())
|
||||
|
||||
total_gas_mixture.merge(G)
|
||||
|
||||
total_thermal_energy += THERMAL_ENERGY(G)
|
||||
total_thermal_energy += G.thermal_energy()
|
||||
total_heat_capacity += G.heat_capacity()
|
||||
|
||||
total_gas_mixture.temperature = total_heat_capacity ? total_thermal_energy/total_heat_capacity : 0
|
||||
total_gas_mixture.set_temperature(total_heat_capacity ? total_thermal_energy/total_heat_capacity : 0)
|
||||
|
||||
if(total_gas_mixture.volume > 0)
|
||||
if(total_gas_mixture.return_volume() > 0)
|
||||
//Update individual gas_mixtures by volume ratio
|
||||
for(var/i in GL)
|
||||
var/datum/gas_mixture/G = i
|
||||
G.copy_from(total_gas_mixture)
|
||||
var/list/G_gases = G.gases
|
||||
for(var/id in G_gases)
|
||||
G_gases[id] *= G.volume/total_gas_mixture.volume
|
||||
G.multiply(G.return_volume()/total_gas_mixture.return_volume())
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
if (target)
|
||||
var/datum/gas_mixture/environment = target.return_air()
|
||||
if(environment)
|
||||
. = "The pressure gauge reads [round(environment.return_pressure(), 0.01)] kPa; [round(environment.temperature,0.01)] K ([round(environment.temperature-T0C,0.01)]°C)."
|
||||
. = "The pressure gauge reads [round(environment.return_pressure(), 0.01)] kPa; [round(environment.return_temperature(),0.01)] K ([round(environment.return_temperature()-T0C,0.01)]°C)."
|
||||
else
|
||||
. = "The sensor error light is blinking."
|
||||
else
|
||||
|
||||
@@ -131,8 +131,8 @@
|
||||
if(!isopenturf(O))
|
||||
return FALSE
|
||||
var/datum/gas_mixture/merger = new
|
||||
merger.gases[spawn_id] = (spawn_mol)
|
||||
merger.temperature = spawn_temp
|
||||
merger.set_moles(spawn_id, spawn_mol)
|
||||
merger.set_temperature(spawn_temp)
|
||||
O.assume_air(merger)
|
||||
O.air_update_turf(TRUE)
|
||||
|
||||
|
||||
@@ -28,14 +28,14 @@
|
||||
if(islava(T))
|
||||
environment_temperature = 5000
|
||||
else if(T.blocks_air)
|
||||
environment_temperature = T.temperature
|
||||
environment_temperature = T.return_temperature()
|
||||
else
|
||||
var/turf/open/OT = T
|
||||
environment_temperature = OT.GetTemperature()
|
||||
else
|
||||
environment_temperature = T.temperature
|
||||
environment_temperature = T.return_temperature()
|
||||
|
||||
if(abs(environment_temperature-pipe_air.temperature) > minimum_temperature_difference)
|
||||
if(abs(environment_temperature-pipe_air.return_temperature()) > minimum_temperature_difference)
|
||||
parent.temperature_interact(T, volume, thermal_conductivity)
|
||||
|
||||
|
||||
@@ -44,11 +44,11 @@
|
||||
var/hc = pipe_air.heat_capacity()
|
||||
var/mob/living/heat_source = buckled_mobs[1]
|
||||
//Best guess-estimate of the total bodytemperature of all the mobs, since they share the same environment it's ~ok~ to guess like this
|
||||
var/avg_temp = (pipe_air.temperature * hc + (heat_source.bodytemperature * buckled_mobs.len) * 3500) / (hc + (buckled_mobs ? buckled_mobs.len * 3500 : 0))
|
||||
var/avg_temp = (pipe_air.return_temperature() * hc + (heat_source.bodytemperature * buckled_mobs.len) * 3500) / (hc + (buckled_mobs ? buckled_mobs.len * 3500 : 0))
|
||||
for(var/m in buckled_mobs)
|
||||
var/mob/living/L = m
|
||||
L.bodytemperature = avg_temp
|
||||
pipe_air.temperature = avg_temp
|
||||
pipe_air.set_temperature(avg_temp)
|
||||
|
||||
/obj/machinery/atmospherics/pipe/heat_exchanging/process()
|
||||
if(!parent)
|
||||
@@ -57,9 +57,9 @@
|
||||
var/datum/gas_mixture/pipe_air = return_air()
|
||||
|
||||
//Heat causes pipe to glow
|
||||
if(pipe_air.temperature && (icon_temperature > 500 || pipe_air.temperature > 500)) //glow starts at 500K
|
||||
if(abs(pipe_air.temperature - icon_temperature) > 10)
|
||||
icon_temperature = pipe_air.temperature
|
||||
if(pipe_air.return_temperature() && (icon_temperature > 500 || pipe_air.return_temperature() > 500)) //glow starts at 500K
|
||||
if(abs(pipe_air.return_temperature() - icon_temperature) > 10)
|
||||
icon_temperature = pipe_air.return_temperature()
|
||||
|
||||
var/h_r = heat2colour_r(icon_temperature)
|
||||
var/h_g = heat2colour_g(icon_temperature)
|
||||
@@ -76,7 +76,7 @@
|
||||
//burn any mobs buckled based on temperature
|
||||
if(has_buckled_mobs())
|
||||
var/heat_limit = 1000
|
||||
if(pipe_air.temperature > heat_limit + 1)
|
||||
if(pipe_air.return_temperature() > heat_limit + 1)
|
||||
for(var/m in buckled_mobs)
|
||||
var/mob/living/buckled_mob = m
|
||||
buckled_mob.apply_damage(4 * log(pipe_air.temperature - heat_limit), BURN, BODY_ZONE_CHEST)
|
||||
buckled_mob.apply_damage(4 * log(pipe_air.return_temperature() - heat_limit), BURN, BODY_ZONE_CHEST)
|
||||
|
||||
@@ -200,14 +200,14 @@
|
||||
/obj/machinery/portable_atmospherics/canister/proc/create_gas()
|
||||
if(gas_type)
|
||||
if(starter_temp)
|
||||
air_contents.temperature = starter_temp
|
||||
air_contents.gases[gas_type] = (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
|
||||
air_contents.set_temperature(starter_temp)
|
||||
air_contents.set_moles(gas_type,(maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
|
||||
if(starter_temp)
|
||||
air_contents.temperature = starter_temp
|
||||
air_contents.set_temperature(starter_temp)
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/air/create_gas()
|
||||
air_contents.gases[/datum/gas/oxygen] = (O2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
|
||||
air_contents.gases[/datum/gas/nitrogen] = (N2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
|
||||
air_contents.set_moles(/datum/gas/oxygen, (O2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
|
||||
air_contents.set_moles(/datum/gas/nitrogen, (N2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/update_icon_state()
|
||||
if(stat & BROKEN)
|
||||
@@ -397,8 +397,8 @@
|
||||
logmsg = "Valve was <b>opened</b> by [key_name(usr)], starting a transfer into \the [holding || "air"].<br>"
|
||||
if(!holding)
|
||||
var/list/danger = list()
|
||||
for(var/id in air_contents.gases)
|
||||
var/gas = air_contents.gases[id]
|
||||
for(var/id in air_contents.get_gases())
|
||||
var/gas = air_contents.get_moles(id)
|
||||
if(!GLOB.meta_gas_dangers[id])
|
||||
continue
|
||||
if(gas > (GLOB.meta_gas_visibility[id] || MOLES_GAS_VISIBLE)) //if moles_visible is undefined, default to default visibility
|
||||
|
||||
@@ -18,9 +18,8 @@
|
||||
..()
|
||||
SSair.atmos_machinery += src
|
||||
|
||||
air_contents = new
|
||||
air_contents.volume = volume
|
||||
air_contents.temperature = T20C
|
||||
air_contents = new(volume)
|
||||
air_contents.set_temperature(T20C)
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
@@ -115,8 +115,8 @@
|
||||
if("power")
|
||||
on = !on
|
||||
if(on && !holding)
|
||||
var/plasma = air_contents.gases[/datum/gas/plasma]
|
||||
var/n2o = air_contents.gases[/datum/gas/nitrous_oxide]
|
||||
var/plasma = air_contents.get_moles(/datum/gas/plasma)
|
||||
var/n2o = air_contents.get_moles(/datum/gas/nitrous_oxide)
|
||||
if(n2o || plasma)
|
||||
message_admins("[ADMIN_LOOKUPFLW(usr)] turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""] at [ADMIN_VERBOSEJMP(src)]")
|
||||
log_admin("[key_name(usr)] turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""] at [AREACOORD(src)]")
|
||||
|
||||
@@ -40,20 +40,13 @@
|
||||
scrub(T.return_air())
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/proc/scrub(var/datum/gas_mixture/mixture)
|
||||
var/transfer_moles = min(1, volume_rate / mixture.volume) * mixture.total_moles()
|
||||
var/transfer_moles = min(1, volume_rate / mixture.return_volume()) * mixture.total_moles()
|
||||
|
||||
var/datum/gas_mixture/filtering = mixture.remove(transfer_moles) // Remove part of the mixture to filter.
|
||||
var/datum/gas_mixture/filtered = new
|
||||
if(!filtering)
|
||||
return
|
||||
|
||||
filtered.temperature = filtering.temperature
|
||||
for(var/gas in filtering.gases & scrubbing)
|
||||
filtered.gases[gas] = filtering.gases[gas] // Shuffle the "bad" gasses to the filtered mixture.
|
||||
filtering.gases[gas] = 0
|
||||
GAS_GARBAGE_COLLECT(filtering.gases)
|
||||
|
||||
air_contents.merge(filtered) // Store filtered out gasses.
|
||||
filtering.scrub_into(air_contents,scrubbing)
|
||||
mixture.merge(filtering) // Returned the cleaned gas.
|
||||
if(!holding)
|
||||
air_update_turf()
|
||||
|
||||
@@ -10,9 +10,7 @@
|
||||
if(!..())
|
||||
return FALSE
|
||||
var/obj/item/tank/T = O
|
||||
if(!T.air_contents.gases[gas_type])
|
||||
return FALSE
|
||||
return T.air_contents.gases[gas_type] >= moles_required
|
||||
return T.air_contents.get_moles(gas_type) >= moles_required
|
||||
|
||||
//datum/bounty/item/engineering/gas/nitryl_tank
|
||||
// name = "Full Tank of Nitryl"
|
||||
|
||||
@@ -169,15 +169,13 @@
|
||||
/datum/export/large/gas_canister/get_cost(obj/O)
|
||||
var/obj/machinery/portable_atmospherics/canister/C = O
|
||||
var/worth = 10
|
||||
var/gases = C.air_contents.gases
|
||||
|
||||
worth += gases[/datum/gas/bz]*3
|
||||
worth += gases[/datum/gas/stimulum]*25
|
||||
worth += gases[/datum/gas/hypernoblium]*1000
|
||||
worth += gases[/datum/gas/miasma]*2
|
||||
worth += gases[/datum/gas/tritium]*7
|
||||
worth += gases[/datum/gas/pluoxium]*6
|
||||
worth += gases[/datum/gas/nitryl]*30
|
||||
worth += C.air_contents.get_moles(/datum/gas/bz)*3
|
||||
worth += C.air_contents.get_moles(/datum/gas/stimulum)*25
|
||||
worth += C.air_contents.get_moles(/datum/gas/hypernoblium)*1000
|
||||
worth += C.air_contents.get_moles(/datum/gas/miasma)*2
|
||||
worth += C.air_contents.get_moles(/datum/gas/tritium)*7
|
||||
worth += C.air_contents.get_moles(/datum/gas/pluoxium)*6
|
||||
worth += C.air_contents.get_moles(/datum/gas/nitryl)*30
|
||||
return worth
|
||||
|
||||
|
||||
|
||||
@@ -171,10 +171,7 @@
|
||||
var/turf/open/floor/T = holder.loc
|
||||
if(istype(T))
|
||||
var/datum/gas_mixture/GM = T.air
|
||||
if(!GM.gases[/datum/gas/oxygen])
|
||||
return
|
||||
GM.gases[/datum/gas/oxygen] = max(GM.gases[/datum/gas/oxygen] - severity * holder.energy, 0)
|
||||
GAS_GARBAGE_COLLECT(GM.gases)
|
||||
GM.set_moles(/datum/gas/oxygen, max(GM.get_moles(/datum/gas/oxygen) - severity * holder.energy, 0))
|
||||
|
||||
/datum/spacevine_mutation/nitro_eater
|
||||
name = "nitrogen consuming"
|
||||
@@ -186,10 +183,7 @@
|
||||
var/turf/open/floor/T = holder.loc
|
||||
if(istype(T))
|
||||
var/datum/gas_mixture/GM = T.air
|
||||
if(!GM.gases[/datum/gas/nitrogen])
|
||||
return
|
||||
GM.gases[/datum/gas/nitrogen] = max(GM.gases[/datum/gas/nitrogen] - severity * holder.energy, 0)
|
||||
GAS_GARBAGE_COLLECT(GM.gases)
|
||||
GM.set_moles(/datum/gas/nitrogen, max(GM.get_moles(/datum/gas/nitrogen) - severity * holder.energy, 0))
|
||||
|
||||
/datum/spacevine_mutation/carbondioxide_eater
|
||||
name = "CO2 consuming"
|
||||
@@ -201,10 +195,7 @@
|
||||
var/turf/open/floor/T = holder.loc
|
||||
if(istype(T))
|
||||
var/datum/gas_mixture/GM = T.air
|
||||
if(!GM.gases[/datum/gas/carbon_dioxide])
|
||||
return
|
||||
GM.gases[/datum/gas/carbon_dioxide] = max(GM.gases[/datum/gas/carbon_dioxide] - severity * holder.energy, 0)
|
||||
GAS_GARBAGE_COLLECT(GM.gases)
|
||||
GM.set_moles(/datum/gas/carbon_dioxide, max(GM.get_moles(/datum/gas/carbon_dioxide) - severity * holder.energy, 0))
|
||||
|
||||
/datum/spacevine_mutation/plasma_eater
|
||||
name = "toxins consuming"
|
||||
@@ -216,10 +207,7 @@
|
||||
var/turf/open/floor/T = holder.loc
|
||||
if(istype(T))
|
||||
var/datum/gas_mixture/GM = T.air
|
||||
if(!GM.gases[/datum/gas/plasma])
|
||||
return
|
||||
GM.gases[/datum/gas/plasma] = max(GM.gases[/datum/gas/plasma] - severity * holder.energy, 0)
|
||||
GAS_GARBAGE_COLLECT(GM.gases)
|
||||
GM.set_moles(/datum/gas/plasma, max(GM.get_moles(/datum/gas/plasma) - severity * holder.energy, 0))
|
||||
|
||||
/datum/spacevine_mutation/thorns
|
||||
name = "thorny"
|
||||
|
||||
@@ -57,8 +57,8 @@
|
||||
return
|
||||
|
||||
var/datum/gas_mixture/stank = new
|
||||
stank.gases[/datum/gas/miasma] = (yield + 6)*7*0.02 // this process is only being called about 2/7 as much as corpses so this is 12-32 times a corpses
|
||||
stank.temperature = T20C // without this the room would eventually freeze and miasma mining would be easier
|
||||
stank.adjust_moles(/datum/gas/miasma,(yield + 6)*7*0.02) // this process is only being called about 2/7 as much as corpses so this is 12-32 times a corpses
|
||||
stank.set_temperature(T20C) // without this the room would eventually freeze and miasma mining would be easier
|
||||
T.assume_air(stank)
|
||||
T.air_update_turf()
|
||||
|
||||
|
||||
@@ -226,8 +226,8 @@
|
||||
if(isopenturf(loc))
|
||||
var/turf/open/O = loc
|
||||
if(O.air)
|
||||
var/loc_gases = O.air.gases
|
||||
if(loc_gases[/datum/gas/oxygen] > 13)
|
||||
var/datum/gas_mixture/loc_air = O.air
|
||||
if(loc_air.get_moles(/datum/gas/oxygen) > 13)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -125,12 +125,12 @@
|
||||
return
|
||||
|
||||
// Negative Kelvin temperatures should never happen and if they do, normalize them
|
||||
if(source_air.temperature < TCMB)
|
||||
source_air.temperature = TCMB
|
||||
if(source_air.return_temperature() < TCMB)
|
||||
source_air.set_temperature(TCMB)
|
||||
|
||||
var/pressure_delta = target_pressure - target_air.return_pressure()
|
||||
if(pressure_delta > 0.1)
|
||||
var/transfer_moles = (pressure_delta*target_air.volume/(source_air.temperature * R_IDEAL_GAS_EQUATION))*PUMP_EFFICIENCY
|
||||
var/transfer_moles = (pressure_delta*target_air.return_volume()/(source_air.return_temperature() * R_IDEAL_GAS_EQUATION))*PUMP_EFFICIENCY
|
||||
var/datum/gas_mixture/removed = source_air.remove(transfer_moles)
|
||||
target_air.merge(removed)
|
||||
|
||||
@@ -171,14 +171,14 @@
|
||||
return
|
||||
|
||||
// Negative Kelvin temperatures should never happen and if they do, normalize them
|
||||
if(source_air.temperature < TCMB)
|
||||
source_air.temperature = TCMB
|
||||
if(source_air.return_temperature() < TCMB)
|
||||
source_air.set_temperature(TCMB)
|
||||
|
||||
if((source_air.return_pressure() < 0.01) || (target_air.return_pressure() >= PUMP_MAX_PRESSURE))
|
||||
return
|
||||
|
||||
//The second part of the min caps the pressure built by the volume pumps to the max pump pressure
|
||||
var/transfer_ratio = min(transfer_rate,target_air.volume*PUMP_MAX_PRESSURE/source_air.return_pressure())/source_air.volume
|
||||
var/transfer_ratio = min(transfer_rate,target_air.return_volume()*PUMP_MAX_PRESSURE/source_air.return_pressure())/source_air.return_volume()
|
||||
|
||||
var/datum/gas_mixture/removed = source_air.remove_ratio(transfer_ratio * PUMP_EFFICIENCY)
|
||||
|
||||
@@ -351,10 +351,10 @@ obj/item/integrated_circuit/atmospherics/connector/portableConnectorReturnAir()
|
||||
var/transfer_moles
|
||||
|
||||
//Negative Kelvins are an anomaly and should be normalized if encountered
|
||||
if(source_air.temperature < TCMB)
|
||||
source_air.temperature = TCMB
|
||||
if(source_air.return_temperature(TCMB))
|
||||
source_air.set_temperature(TCMB)
|
||||
|
||||
transfer_moles = (pressure_delta*contaminated_air.volume/(source_air.temperature * R_IDEAL_GAS_EQUATION))*PUMP_EFFICIENCY
|
||||
transfer_moles = (pressure_delta*contaminated_air.return_volume()/(source_air.return_temperature() * R_IDEAL_GAS_EQUATION))*PUMP_EFFICIENCY
|
||||
|
||||
//If there is nothing to transfer, just return
|
||||
if(transfer_moles <= 0)
|
||||
@@ -368,16 +368,15 @@ obj/item/integrated_circuit/atmospherics/connector/portableConnectorReturnAir()
|
||||
//This is the gas that will be moved from source to filtered
|
||||
var/datum/gas_mixture/filtered_out = new
|
||||
|
||||
for(var/filtered_gas in removed.gases)
|
||||
for(var/filtered_gas in removed.get_gases())
|
||||
//Get the name of the gas and see if it is in the list
|
||||
if(GLOB.meta_gas_names[filtered_gas] in wanted)
|
||||
//The gas that is put in all the filtered out gases
|
||||
filtered_out.temperature = removed.temperature
|
||||
filtered_out.gases[filtered_gas] = removed.gases[filtered_gas]
|
||||
filtered_out.set_temperature(removed.return_temperature())
|
||||
filtered_out.set_moles(filtered_gas, removed.get_moles(filtered_gas))
|
||||
|
||||
//The filtered out gas is entirely removed from the currently filtered gases
|
||||
removed.gases[filtered_gas] = 0
|
||||
GAS_GARBAGE_COLLECT(removed.gases)
|
||||
removed.set_moles(filtered_gas, 0)
|
||||
|
||||
//Check if the pressure is high enough to put stuff in filtered, or else just put it back in the source
|
||||
var/datum/gas_mixture/target = (filtered_air.return_pressure() < target_pressure ? filtered_air : source_air)
|
||||
@@ -444,7 +443,7 @@ obj/item/integrated_circuit/atmospherics/connector/portableConnectorReturnAir()
|
||||
var/gas_percentage = round(max(min(get_pin_data(IC_INPUT, 4),100),0) / 100)
|
||||
|
||||
//Basically: number of moles = percentage of pressure filled up * efficiency coefficient * (pressure from both gases * volume of output) / (R * Temperature)
|
||||
var/transfer_moles = (get_pin_data(IC_INPUT, 5) / max(1,output_gases.return_pressure())) * PUMP_EFFICIENCY * (source_1_gases.return_pressure() * gas_percentage + source_2_gases.return_pressure() * (1 - gas_percentage)) * output_gases.volume/ (R_IDEAL_GAS_EQUATION * max(output_gases.temperature,TCMB))
|
||||
var/transfer_moles = (get_pin_data(IC_INPUT, 5) / max(1,output_gases.return_pressure())) * PUMP_EFFICIENCY * (source_1_gases.return_pressure() * gas_percentage + source_2_gases.return_pressure() * (1 - gas_percentage)) * output_gases.return_volume()/ (R_IDEAL_GAS_EQUATION * max(output_gases.return_temperature(),TCMB))
|
||||
|
||||
|
||||
if(transfer_moles <= 0)
|
||||
@@ -544,10 +543,10 @@ obj/item/integrated_circuit/atmospherics/connector/portableConnectorReturnAir()
|
||||
push_data()
|
||||
|
||||
//Cool the tank if the power is on and the temp is above
|
||||
if(!power_draw_idle || air_contents.temperature < temperature)
|
||||
if(!power_draw_idle || air_contents.return_temperature() < temperature)
|
||||
return
|
||||
|
||||
air_contents.temperature = max(73.15,air_contents.temperature - (air_contents.temperature - temperature) * heater_coefficient)
|
||||
air_contents.set_temperature(max(73.15,air_contents.return_temperature() - (air_contents.return_temperature() - temperature) * heater_coefficient))
|
||||
|
||||
|
||||
// - heater tank - // **works**
|
||||
@@ -574,10 +573,10 @@ obj/item/integrated_circuit/atmospherics/connector/portableConnectorReturnAir()
|
||||
push_data()
|
||||
|
||||
//Heat the tank if the power is on or its temperature is below what is set
|
||||
if(!power_draw_idle || air_contents.temperature > temperature)
|
||||
if(!power_draw_idle || air_contents.return_temperature() > temperature)
|
||||
return
|
||||
|
||||
air_contents.temperature = min(573.15,air_contents.temperature + (temperature - air_contents.temperature) * heater_coefficient)
|
||||
air_contents.set_temperature(min(573.15,air_contents.return_temperature() + (temperature - air_contents.return_temperature()) * heater_coefficient))
|
||||
|
||||
|
||||
// - atmospheric cooler - // **works**
|
||||
@@ -621,11 +620,11 @@ obj/item/integrated_circuit/atmospherics/connector/portableConnectorReturnAir()
|
||||
return
|
||||
|
||||
var/datum/gas_mixture/turf_air = current_turf.return_air()
|
||||
if(!power_draw_idle || turf_air.temperature < temperature)
|
||||
if(!power_draw_idle || turf_air.return_temperature() < temperature)
|
||||
return
|
||||
|
||||
//Cool the gas
|
||||
turf_air.temperature = max(243.15,turf_air.temperature - (turf_air.temperature - temperature) * heater_coefficient)
|
||||
turf_air.set_temperature(max(243.15,turf_air.return_temperature() - (turf_air.return_temperature() - temperature) * heater_coefficient))
|
||||
|
||||
|
||||
// - atmospheric heater - // **works**
|
||||
@@ -650,11 +649,11 @@ obj/item/integrated_circuit/atmospherics/connector/portableConnectorReturnAir()
|
||||
return
|
||||
|
||||
var/datum/gas_mixture/turf_air = current_turf.return_air()
|
||||
if(!power_draw_idle || turf_air.temperature > temperature)
|
||||
if(!power_draw_idle || turf_air.return_temperature() > temperature)
|
||||
return
|
||||
|
||||
//Heat the gas
|
||||
turf_air.temperature = min(323.15,turf_air.temperature + (temperature - turf_air.temperature) * heater_coefficient)
|
||||
turf_air.set_temperature(min(323.15,turf_air.return_temperature() + (temperature - turf_air.return_temperature()) * heater_coefficient))
|
||||
|
||||
|
||||
// - tank slot - // **works**
|
||||
|
||||
@@ -1162,12 +1162,11 @@
|
||||
activate_pin(3)
|
||||
return
|
||||
|
||||
var/list/gases = air_contents.gases
|
||||
var/list/gas_names = list()
|
||||
var/list/gas_amounts = list()
|
||||
for(var/id in gases)
|
||||
for(var/id in air_contents.get_gases())
|
||||
var/name = GLOB.meta_gas_names[id]
|
||||
var/amt = round(gases[id], 0.001)
|
||||
var/amt = round(air_contents.get_moles(id), 0.001)
|
||||
gas_names.Add(name)
|
||||
gas_amounts.Add(amt)
|
||||
|
||||
@@ -1175,7 +1174,7 @@
|
||||
set_pin_data(IC_OUTPUT, 2, gas_amounts)
|
||||
set_pin_data(IC_OUTPUT, 3, round(air_contents.total_moles(), 0.001))
|
||||
set_pin_data(IC_OUTPUT, 4, round(air_contents.return_pressure(), 0.001))
|
||||
set_pin_data(IC_OUTPUT, 5, round(air_contents.temperature, 0.001))
|
||||
set_pin_data(IC_OUTPUT, 5, round(air_contents.return_temperature(), 0.001))
|
||||
set_pin_data(IC_OUTPUT, 6, round(air_contents.return_volume(), 0.001))
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
@@ -213,6 +213,7 @@
|
||||
var/list/modelCache = build_cache(no_changeturf)
|
||||
var/space_key = modelCache[SPACE_KEY]
|
||||
var/list/bounds
|
||||
var/did_expand = FALSE
|
||||
src.bounds = bounds = list(1.#INF, 1.#INF, 1.#INF, -1.#INF, -1.#INF, -1.#INF)
|
||||
var/datum/map_orientation_pattern/mode = forced_pattern || GLOB.map_orientation_patterns["[orientation]"] || GLOB.map_orientation_patterns["[SOUTH]"]
|
||||
var/invert_y = mode.invert_y
|
||||
@@ -235,6 +236,7 @@
|
||||
else
|
||||
while(parsed_z > world.maxz)
|
||||
world.incrementMaxZ()
|
||||
did_expand = TRUE
|
||||
if(!no_changeturf)
|
||||
WARNING("Z-level expansion occurred without no_changeturf set, this may cause problems when /turf/AfterChange is called")
|
||||
//these values are the same until a new gridset is reached.
|
||||
@@ -256,11 +258,13 @@
|
||||
continue
|
||||
else
|
||||
world.maxx = placement_x
|
||||
did_expand = TRUE
|
||||
if(placement_y > world.maxy)
|
||||
if(cropMap)
|
||||
break
|
||||
else
|
||||
world.maxy = placement_y
|
||||
did_expand = TRUE
|
||||
if(placement_x < 1)
|
||||
actual_x += xi
|
||||
continue
|
||||
@@ -301,6 +305,9 @@
|
||||
testing("Skipped loading [turfsSkipped] default turfs")
|
||||
#endif
|
||||
|
||||
if(did_expand)
|
||||
world.refresh_atmos_grid()
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/parsed_map/proc/build_cache(no_changeturf, bad_paths=null)
|
||||
|
||||
@@ -7,6 +7,20 @@
|
||||
return get_step(SSmapping.get_turf_below(get_turf(ref)), dir)
|
||||
return get_step(ref, dir)
|
||||
|
||||
/proc/get_multiz_accessible_levels(center_z)
|
||||
. = list(center_z)
|
||||
var/other_z = center_z
|
||||
var/offset
|
||||
while((offset = SSmapping.level_trait(other_z, ZTRAIT_DOWN)))
|
||||
other_z += offset
|
||||
. += other_z
|
||||
other_z = center_z
|
||||
while((offset = SSmapping.level_trait(other_z, ZTRAIT_UP)))
|
||||
other_z += offset
|
||||
. += other_z
|
||||
return .
|
||||
|
||||
|
||||
/proc/get_dir_multiz(turf/us, turf/them)
|
||||
us = get_turf(us)
|
||||
them = get_turf(them)
|
||||
@@ -32,16 +46,4 @@
|
||||
|
||||
/turf/proc/below()
|
||||
return get_step_multiz(src, DOWN)
|
||||
|
||||
/proc/dir_inverse_multiz(dir)
|
||||
var/holder = dir & (UP|DOWN)
|
||||
if((holder == NONE) || (holder == (UP|DOWN)))
|
||||
return turn(dir, 180)
|
||||
dir &= ~(UP|DOWN)
|
||||
dir = turn(dir, 180)
|
||||
if(holder == UP)
|
||||
holder = DOWN
|
||||
else
|
||||
holder = UP
|
||||
dir |= holder
|
||||
return dir
|
||||
|
||||
@@ -13,26 +13,23 @@
|
||||
|
||||
var/toxins_used = 0
|
||||
var/tox_detect_threshold = 0.02
|
||||
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME
|
||||
var/list/breath_gases = breath.gases
|
||||
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.return_temperature())/BREATH_VOLUME
|
||||
|
||||
//Partial pressure of the toxins in our breath
|
||||
var/Toxins_pp = (breath_gases[/datum/gas/plasma]/breath.total_moles())*breath_pressure
|
||||
var/Toxins_pp = (breath.get_moles(/datum/gas/plasma)/breath.total_moles())*breath_pressure
|
||||
|
||||
if(Toxins_pp > tox_detect_threshold) // Detect toxins in air
|
||||
adjustPlasma(breath_gases[/datum/gas/plasma]*250)
|
||||
adjustPlasma(breath.get_moles(/datum/gas/plasma)*250)
|
||||
throw_alert("alien_tox", /obj/screen/alert/alien_tox)
|
||||
|
||||
toxins_used = breath_gases[/datum/gas/plasma]
|
||||
toxins_used = breath.get_moles(/datum/gas/plasma)
|
||||
|
||||
else
|
||||
clear_alert("alien_tox")
|
||||
|
||||
//Breathe in toxins and out oxygen
|
||||
breath_gases[/datum/gas/plasma] -= toxins_used
|
||||
breath_gases[/datum/gas/oxygen] += toxins_used
|
||||
|
||||
GAS_GARBAGE_COLLECT(breath.gases)
|
||||
breath.adjust_moles(/datum/gas/plasma, -toxins_used)
|
||||
breath.adjust_moles(/datum/gas/oxygen, toxins_used)
|
||||
|
||||
//BREATH TEMPERATURE
|
||||
handle_breath_temperature(breath)
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
if((!istype(H.w_uniform, /obj/item/clothing/under/plasmaman) || !istype(H.head, /obj/item/clothing/head/helmet/space/plasmaman)) && !atmos_sealed)
|
||||
if(environment)
|
||||
if(environment.total_moles())
|
||||
if(environment.gases[/datum/gas/oxygen] && (environment.gases[/datum/gas/oxygen]) >= 1) //Same threshhold that extinguishes fire
|
||||
if(environment.get_moles(/datum/gas/oxygen) >= 1) //Same threshhold that extinguishes fire
|
||||
H.adjust_fire_stacks(0.5)
|
||||
if(!H.on_fire && H.fire_stacks > 0)
|
||||
H.visible_message("<span class='danger'>[H]'s body reacts with the atmosphere and bursts into flames!</span>","<span class='userdanger'>Your body reacts with the atmosphere and bursts into flame!</span>")
|
||||
|
||||
@@ -162,12 +162,11 @@
|
||||
var/SA_para_min = 1
|
||||
var/SA_sleep_min = 5
|
||||
var/oxygen_used = 0
|
||||
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME
|
||||
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.return_temperature())/BREATH_VOLUME
|
||||
|
||||
var/list/breath_gases = breath.gases
|
||||
var/O2_partialpressure = (breath_gases[/datum/gas/oxygen]/breath.total_moles())*breath_pressure
|
||||
var/Toxins_partialpressure = (breath_gases[/datum/gas/plasma]/breath.total_moles())*breath_pressure
|
||||
var/CO2_partialpressure = (breath_gases[/datum/gas/carbon_dioxide]/breath.total_moles())*breath_pressure
|
||||
var/O2_partialpressure = (breath.get_moles(/datum/gas/oxygen)/breath.total_moles())*breath_pressure
|
||||
var/Toxins_partialpressure = (breath.get_moles(/datum/gas/plasma)/breath.total_moles())*breath_pressure
|
||||
var/CO2_partialpressure = (breath.get_moles(/datum/gas/carbon_dioxide)/breath.total_moles())*breath_pressure
|
||||
|
||||
|
||||
//OXYGEN
|
||||
@@ -191,7 +190,7 @@
|
||||
var/ratio = 1 - O2_partialpressure/safe_oxy_min
|
||||
adjustOxyLoss(min(5*ratio, 3))
|
||||
failed_last_breath = 1
|
||||
oxygen_used = breath_gases[/datum/gas/oxygen]*ratio
|
||||
oxygen_used = breath.get_moles(/datum/gas/oxygen)*ratio
|
||||
else
|
||||
adjustOxyLoss(3)
|
||||
failed_last_breath = 1
|
||||
@@ -203,12 +202,12 @@
|
||||
o2overloadtime = 0 //reset our counter for this too
|
||||
if(health >= crit_threshold)
|
||||
adjustOxyLoss(-5)
|
||||
oxygen_used = breath_gases[/datum/gas/oxygen]
|
||||
oxygen_used = breath.get_moles(/datum/gas/oxygen)
|
||||
clear_alert("not_enough_oxy")
|
||||
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "suffocation")
|
||||
|
||||
breath_gases[/datum/gas/oxygen] -= oxygen_used
|
||||
breath_gases[/datum/gas/carbon_dioxide] += oxygen_used
|
||||
breath.adjust_moles(/datum/gas/oxygen, -oxygen_used)
|
||||
breath.adjust_moles(/datum/gas/carbon_dioxide, oxygen_used)
|
||||
|
||||
//CARBON DIOXIDE
|
||||
if(CO2_partialpressure > safe_co2_max)
|
||||
@@ -227,15 +226,15 @@
|
||||
|
||||
//TOXINS/PLASMA
|
||||
if(Toxins_partialpressure > safe_tox_max)
|
||||
var/ratio = (breath_gases[/datum/gas/plasma]/safe_tox_max) * 10
|
||||
var/ratio = (breath.get_moles(/datum/gas/plasma)/safe_tox_max) * 10
|
||||
adjustToxLoss(clamp(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE))
|
||||
throw_alert("too_much_tox", /obj/screen/alert/too_much_tox)
|
||||
else
|
||||
clear_alert("too_much_tox")
|
||||
|
||||
//NITROUS OXIDE
|
||||
if(breath_gases[/datum/gas/nitrous_oxide])
|
||||
var/SA_partialpressure = (breath_gases[/datum/gas/nitrous_oxide]/breath.total_moles())*breath_pressure
|
||||
if(breath.get_moles(/datum/gas/nitrous_oxide))
|
||||
var/SA_partialpressure = (breath.get_moles(/datum/gas/nitrous_oxide)/breath.total_moles())*breath_pressure
|
||||
if(SA_partialpressure > SA_para_min)
|
||||
Unconscious(60)
|
||||
if(SA_partialpressure > SA_sleep_min)
|
||||
@@ -248,26 +247,26 @@
|
||||
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "chemical_euphoria")
|
||||
|
||||
//BZ (Facepunch port of their Agent B)
|
||||
if(breath_gases[/datum/gas/bz])
|
||||
var/bz_partialpressure = (breath_gases[/datum/gas/bz]/breath.total_moles())*breath_pressure
|
||||
if(breath.get_moles(/datum/gas/bz))
|
||||
var/bz_partialpressure = (breath.get_moles(/datum/gas/bz)/breath.total_moles())*breath_pressure
|
||||
if(bz_partialpressure > 1)
|
||||
hallucination += 10
|
||||
else if(bz_partialpressure > 0.01)
|
||||
hallucination += 5
|
||||
|
||||
//TRITIUM
|
||||
if(breath_gases[/datum/gas/tritium])
|
||||
var/tritium_partialpressure = (breath_gases[/datum/gas/tritium]/breath.total_moles())*breath_pressure
|
||||
if(breath.get_moles(/datum/gas/tritium))
|
||||
var/tritium_partialpressure = (breath.get_moles(/datum/gas/tritium)/breath.total_moles())*breath_pressure
|
||||
radiation += tritium_partialpressure/10
|
||||
|
||||
//NITRYL
|
||||
if(breath_gases[/datum/gas/nitryl])
|
||||
var/nitryl_partialpressure = (breath_gases[/datum/gas/nitryl]/breath.total_moles())*breath_pressure
|
||||
if(breath.get_moles(/datum/gas/nitryl))
|
||||
var/nitryl_partialpressure = (breath.get_moles(/datum/gas/nitryl)/breath.total_moles())*breath_pressure
|
||||
adjustFireLoss(nitryl_partialpressure/4)
|
||||
|
||||
//MIASMA
|
||||
if(breath_gases[/datum/gas/miasma])
|
||||
var/miasma_partialpressure = (breath_gases[/datum/gas/miasma]/breath.total_moles())*breath_pressure
|
||||
if(breath.get_moles(/datum/gas/miasma))
|
||||
var/miasma_partialpressure = (breath.get_moles(/datum/gas/miasma)/breath.total_moles())*breath_pressure
|
||||
if(miasma_partialpressure > MINIMUM_MOLES_DELTA_TO_MOVE)
|
||||
|
||||
if(prob(0.05 * miasma_partialpressure))
|
||||
@@ -307,11 +306,6 @@
|
||||
else
|
||||
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "smell")
|
||||
|
||||
|
||||
|
||||
|
||||
GAS_GARBAGE_COLLECT(breath.gases)
|
||||
|
||||
//BREATH TEMPERATURE
|
||||
handle_breath_temperature(breath)
|
||||
|
||||
@@ -370,9 +364,9 @@
|
||||
|
||||
var/datum/gas_mixture/stank = new
|
||||
|
||||
stank.gases[/datum/gas/miasma] = 0.1
|
||||
stank.set_moles(/datum/gas/miasma,0.1)
|
||||
|
||||
stank.temperature = BODYTEMP_NORMAL
|
||||
stank.set_temperature(BODYTEMP_NORMAL)
|
||||
|
||||
miasma_turf.assume_air(stank)
|
||||
|
||||
|
||||
@@ -46,8 +46,8 @@
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/monkey/handle_breath_temperature(datum/gas_mixture/breath)
|
||||
if(abs(BODYTEMP_NORMAL - breath.temperature) > 50)
|
||||
switch(breath.temperature)
|
||||
if(abs(BODYTEMP_NORMAL - breath.return_temperature()) > 50)
|
||||
switch(breath.return_temperature())
|
||||
if(-INFINITY to 120)
|
||||
adjustFireLoss(3)
|
||||
if(120 to 200)
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
ExtinguishMob()
|
||||
return
|
||||
var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment
|
||||
if(G.gases[/datum/gas/oxygen] < 1)
|
||||
if(G.get_moles(/datum/gas/oxygen, 1))
|
||||
ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire
|
||||
return
|
||||
var/turf/location = get_turf(src)
|
||||
|
||||
@@ -914,7 +914,7 @@
|
||||
floating_need_update = TRUE
|
||||
|
||||
/mob/living/proc/get_temperature(datum/gas_mixture/environment)
|
||||
var/loc_temp = environment ? environment.temperature : T0C
|
||||
var/loc_temp = environment ? environment.return_temperature() : T0C
|
||||
if(isobj(loc))
|
||||
var/obj/oloc = loc
|
||||
var/obj_temp = oloc.return_temperature()
|
||||
|
||||
@@ -565,7 +565,6 @@
|
||||
dat += "Unable to obtain a reading.<br>"
|
||||
else
|
||||
var/datum/gas_mixture/environment = T.return_air()
|
||||
var/list/env_gases = environment.gases
|
||||
|
||||
var/pressure = environment.return_pressure()
|
||||
var/total_moles = environment.total_moles()
|
||||
@@ -573,11 +572,11 @@
|
||||
dat += "Air Pressure: [round(pressure,0.1)] kPa<br>"
|
||||
|
||||
if (total_moles)
|
||||
for(var/id in env_gases)
|
||||
var/gas_level = env_gases[id]/total_moles
|
||||
for(var/id in environment.get_gases())
|
||||
var/gas_level = environment.get_moles(id)/total_moles
|
||||
if(gas_level > 0.01)
|
||||
dat += "[GLOB.meta_gas_names[id]]: [round(gas_level*100)]%<br>"
|
||||
dat += "Temperature: [round(environment.temperature-T0C)]°C<br>"
|
||||
dat += "Temperature: [round(environment.return_temperature()-T0C)]°C<br>"
|
||||
dat += "<a href='byond://?src=[REF(src)];software=atmosensor;sub=0'>Refresh Reading</a> <br>"
|
||||
dat += "<br>"
|
||||
return dat
|
||||
|
||||
@@ -49,12 +49,12 @@
|
||||
return
|
||||
if(isopenturf(loc))
|
||||
var/turf/open/T = src.loc
|
||||
if(T.air && T.air.gases[/datum/gas/carbon_dioxide])
|
||||
var/co2 = T.air.gases[/datum/gas/carbon_dioxide]
|
||||
if(T.air)
|
||||
var/co2 = T.air.get_moles(/datum/gas/carbon_dioxide)
|
||||
if(co2 > 0)
|
||||
if(prob(25))
|
||||
var/amt = min(co2, 9)
|
||||
T.air.gases[/datum/gas/carbon_dioxide] -= amt
|
||||
T.air.adjust_moles(/datum/gas/carbon_dioxide, -amt)
|
||||
T.atmos_spawn_air("o2=[amt]")
|
||||
|
||||
/mob/living/simple_animal/hostile/tree/AttackingTarget()
|
||||
|
||||
@@ -252,14 +252,11 @@
|
||||
if(isturf(src.loc) && isopenturf(src.loc))
|
||||
var/turf/open/ST = src.loc
|
||||
if(ST.air)
|
||||
var/ST_gases = ST.air.gases
|
||||
|
||||
var/tox = ST_gases[/datum/gas/plasma]
|
||||
var/oxy = ST_gases[/datum/gas/oxygen]
|
||||
var/n2 = ST_gases[/datum/gas/nitrogen]
|
||||
var/co2 = ST_gases[/datum/gas/carbon_dioxide]
|
||||
|
||||
GAS_GARBAGE_COLLECT(ST.air.gases)
|
||||
var/tox = ST.air.get_moles(/datum/gas/plasma)
|
||||
var/oxy = ST.air.get_moles(/datum/gas/oxygen)
|
||||
var/n2 = ST.air.get_moles(/datum/gas/nitrogen)
|
||||
var/co2 = ST.air.get_moles(/datum/gas/carbon_dioxide)
|
||||
|
||||
if(atmos_requirements["min_oxy"] && oxy < atmos_requirements["min_oxy"])
|
||||
. = FALSE
|
||||
|
||||
@@ -128,9 +128,7 @@
|
||||
Tempstun = 0
|
||||
|
||||
if(stat != DEAD)
|
||||
var/bz_percentage =0
|
||||
if(environment.gases[/datum/gas/bz])
|
||||
bz_percentage = environment.gases[/datum/gas/bz] / environment.total_moles()
|
||||
var/bz_percentage = environment.total_moles() ? (environment.get_moles(/datum/gas/bz) / environment.total_moles()) : 0
|
||||
var/stasis = (bz_percentage >= 0.05 && bodytemperature < (T0C + 100)) || force_stasis
|
||||
|
||||
if(stat == CONSCIOUS && stasis)
|
||||
|
||||
@@ -66,11 +66,10 @@
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
|
||||
var/t = "<span class='notice'>Coordinates: [x],[y] \n</span>"
|
||||
t += "<span class='danger'>Temperature: [environment.temperature] \n</span>"
|
||||
for(var/id in environment.gases)
|
||||
var/gas = environment.gases[id]
|
||||
if(gas)
|
||||
t+="<span class='notice'>[GLOB.meta_gas_names[id]]: [gas] \n</span>"
|
||||
t += "<span class='danger'>Temperature: [environment.return_temperature()] \n</span>"
|
||||
for(var/id in environment.get_gases())
|
||||
if(environment.get_moles(id))
|
||||
t+="<span class='notice'>[GLOB.meta_gas_names[id]]: [environment.get_moles(id)] \n</span>"
|
||||
|
||||
to_chat(usr, t)
|
||||
|
||||
|
||||
@@ -73,20 +73,22 @@
|
||||
data["active"] = TRUE
|
||||
data["SM_integrity"] = active.get_integrity()
|
||||
data["SM_power"] = active.power
|
||||
data["SM_ambienttemp"] = air.temperature
|
||||
data["SM_ambienttemp"] = air.return_temperature()
|
||||
data["SM_ambientpressure"] = air.return_pressure()
|
||||
//data["SM_EPR"] = round((air.total_moles / air.group_multiplier) / 23.1, 0.01)
|
||||
var/list/gasdata = list()
|
||||
|
||||
|
||||
if(air.total_moles())
|
||||
for(var/gasid in air.gases)
|
||||
gasdata.Add(list(list(
|
||||
"name"= GLOB.meta_gas_names[gasid],
|
||||
"amount" = round(100*air.gases[gasid]/air.total_moles(),0.01))))
|
||||
for(var/gasid in air.get_gases())
|
||||
var/amount = air.get_moles(gasid)
|
||||
if(amount)
|
||||
gasdata.Add(list(list(
|
||||
"name"= GLOB.meta_gas_names[gasid],
|
||||
"amount" = round(100*amount/air.total_moles(),0.01))))
|
||||
|
||||
else
|
||||
for(var/gasid in air.gases)
|
||||
for(var/gasid in air.get_gases())
|
||||
gasdata.Add(list(list(
|
||||
"name"= GLOB.meta_gas_names[gasid],
|
||||
"amount" = 0)))
|
||||
@@ -124,4 +126,4 @@
|
||||
for(var/obj/machinery/power/supermatter_crystal/S in supermatters)
|
||||
if(S.uid == newuid)
|
||||
active = S
|
||||
return TRUE
|
||||
return TRUE
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
var/cold_air_heat_capacity = cold_air.heat_capacity()
|
||||
var/hot_air_heat_capacity = hot_air.heat_capacity()
|
||||
|
||||
var/delta_temperature = hot_air.temperature - cold_air.temperature
|
||||
var/delta_temperature = hot_air.return_temperature() - cold_air.return_temperature()
|
||||
|
||||
|
||||
if(delta_temperature > 0 && cold_air_heat_capacity > 0 && hot_air_heat_capacity > 0)
|
||||
@@ -68,8 +68,8 @@
|
||||
var/heat = energy_transfer*(1-efficiency)
|
||||
lastgen += energy_transfer*efficiency
|
||||
|
||||
hot_air.temperature = hot_air.temperature - energy_transfer/hot_air_heat_capacity
|
||||
cold_air.temperature = cold_air.temperature + heat/cold_air_heat_capacity
|
||||
hot_air.set_temperature(hot_air.return_temperature() - energy_transfer/hot_air_heat_capacity)
|
||||
cold_air.set_temperature(cold_air.return_temperature() + heat/cold_air_heat_capacity)
|
||||
|
||||
//add_avail(lastgen) This is done in process now
|
||||
// update icon overlays only if displayed level has changed
|
||||
@@ -116,11 +116,11 @@
|
||||
t += "<BR>"
|
||||
|
||||
t += "<B><font color='blue'>Cold loop</font></B><BR>"
|
||||
t += "Temperature Inlet: [round(cold_circ_air2.temperature, 0.1)] K / Outlet: [round(cold_circ_air1.temperature, 0.1)] K<BR>"
|
||||
t += "Temperature Inlet: [round(cold_circ_air2.return_temperature(), 0.1)] K / Outlet: [round(cold_circ_air1.return_temperature(), 0.1)] K<BR>"
|
||||
t += "Pressure Inlet: [round(cold_circ_air2.return_pressure(), 0.1)] kPa / Outlet: [round(cold_circ_air1.return_pressure(), 0.1)] kPa<BR>"
|
||||
|
||||
t += "<B><font color='red'>Hot loop</font></B><BR>"
|
||||
t += "Temperature Inlet: [round(hot_circ_air2.temperature, 0.1)] K / Outlet: [round(hot_circ_air1.temperature, 0.1)] K<BR>"
|
||||
t += "Temperature Inlet: [round(hot_circ_air2.return_temperature(), 0.1)] K / Outlet: [round(hot_circ_air1.return_temperature(), 0.1)] K<BR>"
|
||||
t += "Pressure Inlet: [round(hot_circ_air2.return_pressure(), 0.1)] kPa / Outlet: [round(hot_circ_air1.return_pressure(), 0.1)] kPa<BR>"
|
||||
|
||||
t += "</div>"
|
||||
|
||||
@@ -47,31 +47,29 @@
|
||||
if(!loaded_tank)
|
||||
return
|
||||
if(!bitcoinmining)
|
||||
if(!loaded_tank.air_contents.gases[/datum/gas/plasma])
|
||||
if(loaded_tank.air_contents.get_moles(/datum/gas/plasma) < 0.0001)
|
||||
investigate_log("<font color='red'>out of fuel</font>.", INVESTIGATE_SINGULO)
|
||||
playsound(src, 'sound/machines/ding.ogg', 50, 1)
|
||||
Radio.talk_into(src, "Insufficient plasma in [get_area(src)] [src], ejecting \the [loaded_tank].", FREQ_ENGINEERING)
|
||||
eject()
|
||||
else
|
||||
var/gasdrained = min(powerproduction_drain*drainratio,loaded_tank.air_contents.gases[/datum/gas/plasma])
|
||||
loaded_tank.air_contents.gases[/datum/gas/plasma] -= 2.7 * gasdrained
|
||||
loaded_tank.air_contents.gases[/datum/gas/tritium] += 2.7 * gasdrained
|
||||
GAS_GARBAGE_COLLECT(loaded_tank.air_contents.gases)
|
||||
var/gasdrained = min(powerproduction_drain*drainratio,loaded_tank.air_contents.get_moles(/datum/gas/plasma))
|
||||
loaded_tank.air_contents.adjust_moles(/datum/gas/plasma, -gasdrained)
|
||||
loaded_tank.air_contents.adjust_moles(/datum/gas/tritium, gasdrained)
|
||||
|
||||
var/power_produced = RAD_COLLECTOR_OUTPUT
|
||||
add_avail(power_produced)
|
||||
stored_power-=power_produced
|
||||
else if(is_station_level(z) && SSresearch.science_tech)
|
||||
if(!loaded_tank.air_contents.gases[/datum/gas/tritium] || !loaded_tank.air_contents.gases[/datum/gas/oxygen])
|
||||
if(!loaded_tank.air_contents.get_moles(/datum/gas/tritium) || !loaded_tank.air_contents.get_moles(/datum/gas/oxygen))
|
||||
playsound(src, 'sound/machines/ding.ogg', 50, 1)
|
||||
Radio.talk_into(src, "Insufficient oxygen and tritium in [get_area(src)] [src] to produce research points, ejecting \the [loaded_tank].", FREQ_ENGINEERING)
|
||||
eject()
|
||||
else
|
||||
var/gasdrained = bitcoinproduction_drain*drainratio
|
||||
loaded_tank.air_contents.gases[/datum/gas/tritium] -= gasdrained
|
||||
loaded_tank.air_contents.gases[/datum/gas/oxygen] -= gasdrained
|
||||
loaded_tank.air_contents.gases[/datum/gas/carbon_dioxide] += gasdrained*2
|
||||
GAS_GARBAGE_COLLECT(loaded_tank.air_contents.gases)
|
||||
loaded_tank.air_contents.adjust_moles(/datum/gas/tritium, -gasdrained)
|
||||
loaded_tank.air_contents.adjust_moles(/datum/gas/oxygen, -gasdrained)
|
||||
loaded_tank.air_contents.adjust_moles(/datum/gas/carbon_dioxide, gasdrained*2)
|
||||
var/bitcoins_mined = stored_power*RAD_COLLECTOR_MINING_CONVERSION_RATE
|
||||
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_ENG)
|
||||
if(D)
|
||||
@@ -86,9 +84,7 @@
|
||||
toggle_power()
|
||||
user.visible_message("[user.name] turns the [src.name] [active? "on":"off"].", \
|
||||
"<span class='notice'>You turn the [src.name] [active? "on":"off"].</span>")
|
||||
var/fuel
|
||||
if(loaded_tank)
|
||||
fuel = loaded_tank.air_contents.gases[/datum/gas/plasma]
|
||||
var/fuel = loaded_tank.air_contents.get_moles(/datum/gas/plasma)
|
||||
investigate_log("turned [active?"<font color='green'>on</font>":"<font color='red'>off</font>"] by [key_name(user)]. [loaded_tank?"Fuel: [round(fuel/0.29)]%":"<font color='red'>It is empty</font>"].", INVESTIGATE_SINGULO)
|
||||
return
|
||||
else
|
||||
|
||||
@@ -211,10 +211,10 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
|
||||
if(get_integrity() < SUPERMATTER_DANGER_PERCENT)
|
||||
return SUPERMATTER_DANGER
|
||||
|
||||
if((get_integrity() < SUPERMATTER_WARNING_PERCENT) || (air.temperature > CRITICAL_TEMPERATURE))
|
||||
if((get_integrity() < SUPERMATTER_WARNING_PERCENT) || (air.return_temperature() > CRITICAL_TEMPERATURE))
|
||||
return SUPERMATTER_WARNING
|
||||
|
||||
if(air.temperature > (CRITICAL_TEMPERATURE * 0.8))
|
||||
if(air.return_temperature() > (CRITICAL_TEMPERATURE * 0.8))
|
||||
return SUPERMATTER_NOTIFY
|
||||
|
||||
if(power > 5)
|
||||
@@ -342,13 +342,13 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
|
||||
else
|
||||
if(takes_damage)
|
||||
//causing damage
|
||||
damage = max(damage + (max(clamp(removed.total_moles() / 200, 0.5, 1) * removed.temperature - ((T0C + HEAT_PENALTY_THRESHOLD)*dynamic_heat_resistance), 0) * mole_heat_penalty / 150 ) * DAMAGE_INCREASE_MULTIPLIER, 0)
|
||||
damage = max(damage + (max(clamp(removed.total_moles() / 200, 0.5, 1) * removed.return_temperature() - ((T0C + HEAT_PENALTY_THRESHOLD)*dynamic_heat_resistance), 0) * mole_heat_penalty / 150 ) * DAMAGE_INCREASE_MULTIPLIER, 0)
|
||||
damage = max(damage + (max(power - POWER_PENALTY_THRESHOLD, 0)/500) * DAMAGE_INCREASE_MULTIPLIER, 0)
|
||||
damage = max(damage + (max(combined_gas - MOLE_PENALTY_THRESHOLD, 0)/80) * DAMAGE_INCREASE_MULTIPLIER, 0)
|
||||
|
||||
//healing damage
|
||||
if(combined_gas < MOLE_PENALTY_THRESHOLD)
|
||||
damage = max(damage + (min(removed.temperature - (T0C + HEAT_PENALTY_THRESHOLD), 0) / 150 ), 0)
|
||||
damage = max(damage + (min(removed.return_temperature() - (T0C + HEAT_PENALTY_THRESHOLD), 0) / 150 ), 0)
|
||||
|
||||
//capping damage
|
||||
damage = min(damage_archived + (DAMAGE_HARDCAP * explosion_point),damage)
|
||||
@@ -358,15 +358,15 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
|
||||
//calculating gas related values
|
||||
combined_gas = max(removed.total_moles(), 0)
|
||||
|
||||
plasmacomp = max(removed.gases[/datum/gas/plasma]/combined_gas, 0)
|
||||
o2comp = max(removed.gases[/datum/gas/oxygen]/combined_gas, 0)
|
||||
co2comp = max(removed.gases[/datum/gas/carbon_dioxide]/combined_gas, 0)
|
||||
pluoxiumcomp = max(removed.gases[/datum/gas/pluoxium]/combined_gas, 0)
|
||||
tritiumcomp = max(removed.gases[/datum/gas/tritium]/combined_gas, 0)
|
||||
bzcomp = max(removed.gases[/datum/gas/bz]/combined_gas, 0)
|
||||
plasmacomp = max(removed.get_moles(/datum/gas/plasma)/combined_gas, 0)
|
||||
o2comp = max(removed.get_moles(/datum/gas/oxygen)/combined_gas, 0)
|
||||
co2comp = max(removed.get_moles(/datum/gas/carbon_dioxide)/combined_gas, 0)
|
||||
tritiumcomp = max(removed.get_moles(/datum/gas/tritium)/combined_gas, 0)
|
||||
bzcomp = max(removed.get_moles(/datum/gas/bz)/combined_gas, 0)
|
||||
|
||||
n2ocomp = max(removed.gases[/datum/gas/nitrous_oxide]/combined_gas, 0)
|
||||
n2comp = max(removed.gases[/datum/gas/nitrogen]/combined_gas, 0)
|
||||
pluoxiumcomp = max(removed.get_moles(/datum/gas/pluoxium)/combined_gas, 0)
|
||||
n2ocomp = max(removed.get_moles(/datum/gas/nitrous_oxide)/combined_gas, 0)
|
||||
n2comp = max(removed.get_moles(/datum/gas/nitrogen)/combined_gas, 0)
|
||||
|
||||
if(pluoxiumcomp >= 0.15)
|
||||
pluoxiumbonus = 1 //makes pluoxium only work at 15%+
|
||||
@@ -404,7 +404,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
|
||||
temp_factor = 30
|
||||
icon_state = base_icon_state
|
||||
|
||||
power = max( (removed.temperature * temp_factor / T0C) * gasmix_power_ratio + power, 0) //Total laser power plus an overload
|
||||
power = max( (removed.return_temperature() * temp_factor / T0C) * gasmix_power_ratio + power, 0) //Total laser power plus an overload
|
||||
|
||||
if(prob(50))
|
||||
radiation_pulse(src, power * (1 + (tritiumcomp * TRITIUM_RADIOACTIVITY_MODIFIER) + ((pluoxiumcomp * PLUOXIUM_RADIOACTIVITY_MODIFIER) * pluoxiumbonus) * (power_transmission_bonus/(10-(bzcomp * BZ_RADIOACTIVITY_MODIFIER))))) // Rad Modifiers BZ(500%), Tritium(300%), and Pluoxium(-200%)
|
||||
@@ -420,14 +420,14 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
|
||||
|
||||
//Also keep in mind we are only adding this temperature to (efficiency)% of the one tile the rock
|
||||
//is on. An increase of 4*C @ 25% efficiency here results in an increase of 1*C / (#tilesincore) overall.
|
||||
removed.temperature += ((device_energy * dynamic_heat_modifier) / THERMAL_RELEASE_MODIFIER)
|
||||
removed.set_temperature(removed.return_temperature() + ((device_energy * dynamic_heat_modifier) / THERMAL_RELEASE_MODIFIER))
|
||||
|
||||
removed.temperature = max(0, min(removed.temperature, 2500 * dynamic_heat_modifier))
|
||||
removed.set_temperature(max(0, min(removed.return_temperature(), 2500 * dynamic_heat_modifier)))
|
||||
|
||||
//Calculate how much gas to release
|
||||
removed.gases[/datum/gas/plasma] += max((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0)
|
||||
removed.adjust_moles(/datum/gas/plasma, max((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0))
|
||||
|
||||
removed.gases[/datum/gas/oxygen] += max(((device_energy + removed.temperature * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER, 0)
|
||||
removed.adjust_moles(/datum/gas/oxygen, max(((device_energy + removed.return_temperature() * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER, 0))
|
||||
|
||||
if(produces_gas)
|
||||
env.merge(removed)
|
||||
|
||||
@@ -205,7 +205,7 @@
|
||||
|
||||
// Weird function but it works. Should be something else...
|
||||
|
||||
var/newrpm = ((compressor.gas_contained.temperature) * compressor.gas_contained.total_moles())/4
|
||||
var/newrpm = ((compressor.gas_contained.return_temperature()) * compressor.gas_contained.total_moles())/4
|
||||
|
||||
newrpm = max(0, newrpm)
|
||||
|
||||
@@ -333,7 +333,7 @@
|
||||
|
||||
data["power"] = DisplayPower(compressor?.turbine?.lastgen)
|
||||
data["rpm"] = compressor?.rpm
|
||||
data["temp"] = compressor?.gas_contained.temperature
|
||||
data["temp"] = compressor?.gas_contained.return_temperature()
|
||||
|
||||
return data
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
if(T.air)
|
||||
if(T.initial_gas_mix)
|
||||
T.air.parse_gas_string(T.initial_gas_mix)
|
||||
T.temperature = T.air.temperature
|
||||
T.temperature = T.air.return_temperature()
|
||||
else
|
||||
T.air.copy_from_turf(T)
|
||||
SSair.add_to_active(T)
|
||||
|
||||
@@ -271,7 +271,7 @@
|
||||
if(isopenturf(T))
|
||||
var/turf/open/OT = T
|
||||
OT.MakeSlippery(wet_setting=TURF_WET_ICE, min_wet_time=100, wet_time_to_add=reac_volume SECONDS) // Is less effective in high pressure/high heat capacity environments. More effective in low pressure.
|
||||
OT.air.temperature -= MOLES_CELLSTANDARD*100*reac_volume/OT.air.heat_capacity() // reduces environment temperature by 5K per unit.
|
||||
OT.air.set_temperature(OT.air.return_temperature() - MOLES_CELLSTANDARD*100*reac_volume/OT.air.heat_capacity()) // reduces environment temperature by 5K per unit.
|
||||
|
||||
/datum/reagent/consumable/condensedcapsaicin
|
||||
name = "Condensed Capsaicin"
|
||||
@@ -506,7 +506,7 @@
|
||||
var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T)
|
||||
if(hotspot)
|
||||
var/datum/gas_mixture/lowertemp = T.remove_air(T.air.total_moles())
|
||||
lowertemp.temperature = max( min(lowertemp.temperature-2000,lowertemp.temperature / 2) ,0)
|
||||
lowertemp.set_temperature(max( min(lowertemp.return_temperature()-2000,lowertemp.return_temperature() / 2) ,0))
|
||||
lowertemp.react(src)
|
||||
T.assume_air(lowertemp)
|
||||
qdel(hotspot)
|
||||
|
||||
@@ -263,7 +263,7 @@
|
||||
if(hotspot && !isspaceturf(T))
|
||||
if(T.air)
|
||||
var/datum/gas_mixture/G = T.air
|
||||
G.temperature = max(min(G.temperature-(CT*1000),G.temperature/CT),TCMB)
|
||||
G.set_temperature(max(min(G.return_temperature()-(CT*1000),G.return_temperature()/CT),TCMB))
|
||||
G.react(src)
|
||||
qdel(hotspot)
|
||||
var/obj/effect/acid/A = (locate(/obj/effect/acid) in T)
|
||||
|
||||
@@ -281,8 +281,8 @@
|
||||
if(hotspot && !isspaceturf(T))
|
||||
if(T.air)
|
||||
var/datum/gas_mixture/G = T.air
|
||||
if(G.temperature > T20C)
|
||||
G.temperature = max(G.temperature/2,T20C)
|
||||
if(G.return_temperature() > T20C)
|
||||
G.set_temperature(max(G.return_temperature()/2,T20C))
|
||||
G.react(src)
|
||||
qdel(hotspot)
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
trunk_check()
|
||||
|
||||
air_contents = new /datum/gas_mixture()
|
||||
//gas.volume = 1.05 * CELLSTANDARD
|
||||
//air_contents.set_volume(1.05 * CELLSTANDARD)
|
||||
update_icon()
|
||||
|
||||
return INITIALIZE_HINT_LATELOAD //we need turfs to have air
|
||||
@@ -443,8 +443,8 @@
|
||||
var/datum/gas_mixture/env = L.return_air()
|
||||
var/pressure_delta = (SEND_PRESSURE*1.01) - air_contents.return_pressure()
|
||||
|
||||
if(env.temperature > 0)
|
||||
var/transfer_moles = 0.1 * pressure_delta*air_contents.volume/(env.temperature * R_IDEAL_GAS_EQUATION)
|
||||
if(env.return_temperature() > 0)
|
||||
var/transfer_moles = 0.1 * pressure_delta*air_contents.return_volume()/(env.return_temperature() * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
//Actually transfer the gas
|
||||
var/datum/gas_mixture/removed = env.remove(transfer_moles)
|
||||
|
||||
@@ -368,7 +368,7 @@
|
||||
var/heat_capacity = removed.heat_capacity()
|
||||
if(heat_capacity == 0 || heat_capacity == null)
|
||||
heat_capacity = 1
|
||||
removed.temperature = min((removed.temperature*heat_capacity + 100000)/heat_capacity, 1000)
|
||||
removed.set_temperature(min((removed.return_temperature()*heat_capacity + 100000)/heat_capacity, 1000))
|
||||
env.merge(removed)
|
||||
air_update_turf()
|
||||
investigate_log("Experimentor has released hot air.", INVESTIGATE_EXPERIMENTOR)
|
||||
@@ -414,7 +414,7 @@
|
||||
var/heat_capacity = removed.heat_capacity()
|
||||
if(heat_capacity == 0 || heat_capacity == null)
|
||||
heat_capacity = 1
|
||||
removed.temperature = (removed.temperature*heat_capacity - 75000)/heat_capacity
|
||||
removed.set_temperature((removed.return_temperature()*heat_capacity - 75000)/heat_capacity)
|
||||
env.merge(removed)
|
||||
air_update_turf()
|
||||
investigate_log("Experimentor has released cold air.", INVESTIGATE_EXPERIMENTOR)
|
||||
|
||||
@@ -59,14 +59,14 @@
|
||||
|
||||
/obj/machinery/rnd/server/proc/get_env_temp()
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
return environment.temperature
|
||||
return environment.return_temperature()
|
||||
|
||||
/obj/machinery/rnd/server/proc/produce_heat(heat_amt)
|
||||
if(!(stat & (NOPOWER|BROKEN))) //Blatently stolen from space heater.
|
||||
var/turf/L = loc
|
||||
if(istype(L))
|
||||
var/datum/gas_mixture/env = L.return_air()
|
||||
if(env.temperature < (heat_amt+T0C))
|
||||
if(env.return_temperature() < (heat_amt+T0C))
|
||||
|
||||
var/transfer_moles = 0.25 * env.total_moles()
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
var/heat_capacity = removed.heat_capacity()
|
||||
if(heat_capacity == 0 || heat_capacity == null)
|
||||
heat_capacity = 1
|
||||
removed.temperature = min((removed.temperature*heat_capacity + heating_power)/heat_capacity, 1000)
|
||||
removed.set_temperature(min((removed.return_temperature()*heat_capacity + heating_power)/heat_capacity, 1000))
|
||||
|
||||
env.merge(removed)
|
||||
air_update_turf()
|
||||
|
||||
@@ -100,9 +100,8 @@ Chilling extracts:
|
||||
for(var/turf/open/T in A)
|
||||
var/datum/gas_mixture/G = T.air
|
||||
if(istype(G))
|
||||
G.gases[/datum/gas/plasma] = 0
|
||||
G.set_moles(/datum/gas/plasma, 0)
|
||||
filtered = TRUE
|
||||
GAS_GARBAGE_COLLECT(G.gases)
|
||||
T.air_update_turf()
|
||||
if(filtered)
|
||||
user.visible_message("<span class='notice'>Cracks spread throughout [src], and some air is sucked in!</span>")
|
||||
@@ -308,4 +307,4 @@ Chilling extracts:
|
||||
user.visible_message("<span class='warning'>[src] reflects an array of dazzling colors and light, energy rushing to nearby doors!</span>")
|
||||
for(var/obj/machinery/door/airlock/door in area)
|
||||
new /obj/effect/forcefield/slimewall/rainbow(door.loc)
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
@@ -133,13 +133,11 @@
|
||||
|
||||
var/gas_breathed = 0
|
||||
|
||||
var/list/breath_gases = breath.gases
|
||||
|
||||
//Partial pressures in our breath
|
||||
var/O2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/oxygen])+(8*breath.get_breath_partial_pressure(breath_gases[/datum/gas/pluoxium]))
|
||||
var/N2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/nitrogen])
|
||||
var/Toxins_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/plasma])
|
||||
var/CO2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/carbon_dioxide])
|
||||
var/O2_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/oxygen))+(8*breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/pluoxium)))
|
||||
var/N2_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/nitrogen))
|
||||
var/Toxins_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/plasma))
|
||||
var/CO2_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/carbon_dioxide))
|
||||
|
||||
|
||||
//-- OXY --//
|
||||
@@ -147,7 +145,7 @@
|
||||
//Too much oxygen! //Yes, some species may not like it.
|
||||
if(safe_oxygen_max)
|
||||
if((O2_pp > safe_oxygen_max) && safe_oxygen_max == 0) //I guess plasma men technically need to have a check.
|
||||
var/ratio = (breath_gases[/datum/gas/oxygen]/safe_oxygen_max) * 10
|
||||
var/ratio = (breath.get_moles(/datum/gas/oxygen)/safe_oxygen_max) * 10
|
||||
H.apply_damage_type(clamp(ratio, oxy_breath_dam_min, oxy_breath_dam_max), oxy_damage_type)
|
||||
H.throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy)
|
||||
|
||||
@@ -170,18 +168,18 @@
|
||||
//Too little oxygen!
|
||||
if(safe_oxygen_min)
|
||||
if(O2_pp < safe_oxygen_min)
|
||||
gas_breathed = handle_too_little_breath(H, O2_pp, safe_oxygen_min, breath_gases[/datum/gas/oxygen])
|
||||
gas_breathed = handle_too_little_breath(H, O2_pp, safe_oxygen_min, breath.get_moles(/datum/gas/oxygen))
|
||||
H.throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy)
|
||||
else
|
||||
H.failed_last_breath = FALSE
|
||||
if(H.health >= H.crit_threshold)
|
||||
H.adjustOxyLoss(-breathModifier) //More damaged lungs = slower oxy rate up to a factor of half
|
||||
gas_breathed = breath_gases[/datum/gas/oxygen]
|
||||
gas_breathed = breath.get_moles(/datum/gas/oxygen)
|
||||
H.clear_alert("not_enough_oxy")
|
||||
|
||||
//Exhale
|
||||
breath_gases[/datum/gas/oxygen] -= gas_breathed
|
||||
breath_gases[/datum/gas/carbon_dioxide] += gas_breathed
|
||||
breath.adjust_moles(/datum/gas/oxygen, -gas_breathed)
|
||||
breath.adjust_moles(/datum/gas/carbon_dioxide, gas_breathed)
|
||||
gas_breathed = 0
|
||||
|
||||
//-- Nitrogen --//
|
||||
@@ -189,7 +187,7 @@
|
||||
//Too much nitrogen!
|
||||
if(safe_nitro_max)
|
||||
if(N2_pp > safe_nitro_max)
|
||||
var/ratio = (breath_gases[/datum/gas/nitrogen]/safe_nitro_max) * 10
|
||||
var/ratio = (breath.get_moles(/datum/gas/nitrogen)/safe_nitro_max) * 10
|
||||
H.apply_damage_type(clamp(ratio, nitro_breath_dam_min, nitro_breath_dam_max), nitro_damage_type)
|
||||
H.throw_alert("too_much_nitro", /obj/screen/alert/too_much_nitro)
|
||||
H.losebreath += 2
|
||||
@@ -199,18 +197,18 @@
|
||||
//Too little nitrogen!
|
||||
if(safe_nitro_min)
|
||||
if(N2_pp < safe_nitro_min)
|
||||
gas_breathed = handle_too_little_breath(H, N2_pp, safe_nitro_min, breath_gases[/datum/gas/nitrogen])
|
||||
gas_breathed = handle_too_little_breath(H, N2_pp, safe_nitro_min, breath.get_moles(/datum/gas/nitrogen))
|
||||
H.throw_alert("nitro", /obj/screen/alert/not_enough_nitro)
|
||||
else
|
||||
H.failed_last_breath = FALSE
|
||||
if(H.health >= H.crit_threshold)
|
||||
H.adjustOxyLoss(-breathModifier)
|
||||
gas_breathed = breath_gases[/datum/gas/nitrogen]
|
||||
gas_breathed = breath.get_moles(/datum/gas/nitrogen)
|
||||
H.clear_alert("nitro")
|
||||
|
||||
//Exhale
|
||||
breath_gases[/datum/gas/nitrogen] -= gas_breathed
|
||||
breath_gases[/datum/gas/carbon_dioxide] += gas_breathed
|
||||
breath.adjust_moles(/datum/gas/nitrogen, -gas_breathed)
|
||||
breath.adjust_moles(/datum/gas/carbon_dioxide, gas_breathed)
|
||||
gas_breathed = 0
|
||||
|
||||
//-- CO2 --//
|
||||
@@ -236,18 +234,18 @@
|
||||
//Too little CO2!
|
||||
if(safe_co2_min)
|
||||
if(CO2_pp < safe_co2_min)
|
||||
gas_breathed = handle_too_little_breath(H, CO2_pp, safe_co2_min, breath_gases[/datum/gas/carbon_dioxide])
|
||||
gas_breathed = handle_too_little_breath(H, CO2_pp, safe_co2_min, breath.get_moles(/datum/gas/carbon_dioxide))
|
||||
H.throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2)
|
||||
else
|
||||
H.failed_last_breath = FALSE
|
||||
if(H.health >= H.crit_threshold)
|
||||
H.adjustOxyLoss(-breathModifier)
|
||||
gas_breathed = breath_gases[/datum/gas/carbon_dioxide]
|
||||
gas_breathed = breath.get_moles(/datum/gas/carbon_dioxide)
|
||||
H.clear_alert("not_enough_co2")
|
||||
|
||||
//Exhale
|
||||
breath_gases[/datum/gas/carbon_dioxide] -= gas_breathed
|
||||
breath_gases[/datum/gas/oxygen] += gas_breathed
|
||||
breath.adjust_moles(/datum/gas/carbon_dioxide, -gas_breathed)
|
||||
breath.adjust_moles(/datum/gas/oxygen, gas_breathed)
|
||||
gas_breathed = 0
|
||||
|
||||
|
||||
@@ -256,7 +254,7 @@
|
||||
//Too much toxins!
|
||||
if(safe_toxins_max)
|
||||
if(Toxins_pp > safe_toxins_max)
|
||||
var/ratio = (breath_gases[/datum/gas/plasma]/safe_toxins_max) * 10
|
||||
var/ratio = (breath.get_moles(/datum/gas/plasma)/safe_toxins_max) * 10
|
||||
H.apply_damage_type(clamp(ratio, tox_breath_dam_min, tox_breath_dam_max), tox_damage_type)
|
||||
H.throw_alert("too_much_tox", /obj/screen/alert/too_much_tox)
|
||||
else
|
||||
@@ -266,18 +264,18 @@
|
||||
//Too little toxins!
|
||||
if(safe_toxins_min)
|
||||
if(Toxins_pp < safe_toxins_min)
|
||||
gas_breathed = handle_too_little_breath(H, Toxins_pp, safe_toxins_min, breath_gases[/datum/gas/plasma])
|
||||
gas_breathed = handle_too_little_breath(H, Toxins_pp, safe_toxins_min, breath.get_moles(/datum/gas/plasma))
|
||||
H.throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox)
|
||||
else
|
||||
H.failed_last_breath = FALSE
|
||||
if(H.health >= H.crit_threshold)
|
||||
H.adjustOxyLoss(-breathModifier)
|
||||
gas_breathed = breath_gases[/datum/gas/plasma]
|
||||
gas_breathed = breath.get_moles(/datum/gas/plasma)
|
||||
H.clear_alert("not_enough_tox")
|
||||
|
||||
//Exhale
|
||||
breath_gases[/datum/gas/plasma] -= gas_breathed
|
||||
breath_gases[/datum/gas/carbon_dioxide] += gas_breathed
|
||||
breath.adjust_moles(/datum/gas/plasma, -gas_breathed)
|
||||
breath.adjust_moles(/datum/gas/carbon_dioxide, gas_breathed)
|
||||
gas_breathed = 0
|
||||
|
||||
|
||||
@@ -287,7 +285,7 @@
|
||||
|
||||
// N2O
|
||||
|
||||
var/SA_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/nitrous_oxide])
|
||||
var/SA_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/nitrous_oxide))
|
||||
if(SA_pp > SA_para_min) // Enough to make us stunned for a bit
|
||||
H.Unconscious(60) // 60 gives them one second to wake up and run away a bit!
|
||||
if(SA_pp > SA_sleep_min) // Enough to make us sleep as well
|
||||
@@ -301,7 +299,7 @@
|
||||
|
||||
// BZ
|
||||
|
||||
var/bz_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/bz])
|
||||
var/bz_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/bz))
|
||||
if(bz_pp > BZ_trip_balls_min)
|
||||
H.hallucination += 10
|
||||
H.reagents.add_reagent(/datum/reagent/bz_metabolites,5)
|
||||
@@ -314,14 +312,14 @@
|
||||
|
||||
|
||||
// Tritium
|
||||
var/trit_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/tritium])
|
||||
var/trit_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/tritium))
|
||||
if (trit_pp > 50)
|
||||
H.radiation += trit_pp/2 //If you're breathing in half an atmosphere of radioactive gas, you fucked up.
|
||||
else
|
||||
H.radiation += trit_pp/10
|
||||
|
||||
// Nitryl
|
||||
var/nitryl_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/nitryl])
|
||||
var/nitryl_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/nitryl))
|
||||
if (prob(nitryl_pp))
|
||||
to_chat(H, "<span class='alert'>Your mouth feels like it's burning!</span>")
|
||||
if (nitryl_pp >40)
|
||||
@@ -332,22 +330,22 @@
|
||||
H.silent = max(H.silent, 3)
|
||||
else
|
||||
H.adjustFireLoss(nitryl_pp/4)
|
||||
gas_breathed = breath_gases[/datum/gas/nitryl]
|
||||
gas_breathed = breath.get_moles(/datum/gas/nitryl)
|
||||
if (gas_breathed > gas_stimulation_min)
|
||||
H.reagents.add_reagent(/datum/reagent/nitryl,1)
|
||||
|
||||
breath_gases[/datum/gas/nitryl]-=gas_breathed
|
||||
breath.adjust_moles(/datum/gas/nitryl, -gas_breathed)
|
||||
|
||||
// Stimulum
|
||||
gas_breathed = breath_gases[/datum/gas/stimulum]
|
||||
gas_breathed = breath.get_moles(/datum/gas/stimulum)
|
||||
if (gas_breathed > gas_stimulation_min)
|
||||
var/existing = H.reagents.get_reagent_amount(/datum/reagent/stimulum)
|
||||
H.reagents.add_reagent(/datum/reagent/stimulum, max(0, 5 - existing))
|
||||
breath_gases[/datum/gas/stimulum]-=gas_breathed
|
||||
breath.adjust_moles(/datum/gas/stimulum, -gas_breathed)
|
||||
|
||||
// Miasma
|
||||
if (breath_gases[/datum/gas/miasma])
|
||||
var/miasma_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/miasma])
|
||||
if (breath.get_moles(/datum/gas/miasma))
|
||||
var/miasma_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/miasma))
|
||||
if(miasma_pp > MINIMUM_MOLES_DELTA_TO_MOVE)
|
||||
|
||||
//Miasma sickness
|
||||
@@ -387,14 +385,13 @@
|
||||
// Then again, this is a purely hypothetical scenario and hardly reachable
|
||||
owner.adjust_disgust(0.1 * miasma_pp)
|
||||
|
||||
breath_gases[/datum/gas/miasma]-=gas_breathed
|
||||
breath.adjust_moles(/datum/gas/miasma, -gas_breathed)
|
||||
|
||||
// Clear out moods when no miasma at all
|
||||
else
|
||||
SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "smell")
|
||||
|
||||
handle_breath_temperature(breath, H)
|
||||
GAS_GARBAGE_COLLECT(breath.gases)
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -416,7 +413,7 @@
|
||||
|
||||
|
||||
/obj/item/organ/lungs/proc/handle_breath_temperature(datum/gas_mixture/breath, mob/living/carbon/human/H) // called by human/life, handles temperatures
|
||||
var/breath_temperature = breath.temperature
|
||||
var/breath_temperature = breath.return_temperature()
|
||||
|
||||
if(!HAS_TRAIT(H, TRAIT_RESISTCOLD)) // COLD DAMAGE
|
||||
var/cold_modifier = H.dna.species.coldmod
|
||||
@@ -533,8 +530,8 @@
|
||||
|
||||
/obj/item/organ/lungs/slime/check_breath(datum/gas_mixture/breath, mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
if (breath && breath.gases[/datum/gas/plasma])
|
||||
var/plasma_pp = breath.get_breath_partial_pressure(breath.gases[/datum/gas/plasma])
|
||||
if (breath)
|
||||
var/plasma_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/plasma))
|
||||
owner.blood_volume += (0.2 * plasma_pp) // 10/s when breathing literally nothing but plasma, which will suffocate you.
|
||||
|
||||
/obj/item/organ/lungs/yamerol
|
||||
|
||||
@@ -122,7 +122,7 @@
|
||||
if(istype(loc, /turf/))//Only concern is adding an organ to a freezer when the area around it is cold.
|
||||
var/turf/T = loc
|
||||
var/datum/gas_mixture/enviro = T.return_air()
|
||||
local_temp = enviro.temperature
|
||||
local_temp = enviro.return_temperature()
|
||||
|
||||
else if(!owner && ismob(loc))
|
||||
var/mob/M = loc
|
||||
@@ -132,7 +132,7 @@
|
||||
return TRUE
|
||||
var/turf/T = M.loc
|
||||
var/datum/gas_mixture/enviro = T.return_air()
|
||||
local_temp = enviro.temperature
|
||||
local_temp = enviro.return_temperature()
|
||||
|
||||
if(owner)
|
||||
//Don't interfere with bodies frozen by structures.
|
||||
|
||||
Reference in New Issue
Block a user