Merge pull request #12217 from Putnam3145/putnamos-for-real
The real fastmos: C++ monstermos port
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user