Merge pull request #12217 from Putnam3145/putnamos-for-real

The real fastmos: C++ monstermos port
This commit is contained in:
silicons
2020-07-09 20:37:18 -07:00
committed by GitHub
120 changed files with 1483 additions and 1377 deletions

View File

@@ -573,7 +573,7 @@
if(Rad.anchored)
if(!Rad.loaded_tank)
var/obj/item/tank/internals/plasma/Plasma = new/obj/item/tank/internals/plasma(Rad)
Plasma.air_contents.gases[/datum/gas/plasma] = 70
Plasma.air_contents.set_moles(/datum/gas/plasma,70)
Rad.drainratio = 0
Rad.loaded_tank = Plasma
Plasma.forceMove(Rad)

View File

@@ -1,15 +1,14 @@
/proc/show_air_status_to(turf/target, mob/user)
var/datum/gas_mixture/env = target.return_air()
var/list/env_gases = env.gases
var/burning = FALSE
if(isopenturf(target))
var/turf/open/T = target
if(T.active_hotspot)
burning = TRUE
var/list/lines = list("<span class='adminnotice'>[AREACOORD(target)]: [env.temperature] K ([env.temperature - T0C] C), [env.return_pressure()] kPa[(burning)?(", <font color='red'>burning</font>"):(null)]</span>")
for(var/id in env_gases)
var/moles = env_gases[id]
var/list/lines = list("<span class='adminnotice'>[AREACOORD(target)]: [env.return_temperature()] K ([env.return_temperature() - T0C] C), [env.return_pressure()] kPa[(burning)?(", <font color='red'>burning</font>"):(null)]</span>")
for(var/id in env.get_gases())
var/moles = env.get_moles(id)
if (moles >= 0.00001)
lines += "[GLOB.meta_gas_names[id]]: [moles] mol"
to_chat(usr, lines.Join("\n"))

View File

@@ -53,8 +53,8 @@
return
if(I.use_tool(src, user, 0, volume=40))
status = TRUE
GLOB.bombers += "[key_name(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]"
message_admins("[ADMIN_LOOKUPFLW(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]")
GLOB.bombers += "[key_name(user)] welded a single tank bomb. Temp: [bombtank.air_contents.return_temperature()-T0C]"
message_admins("[ADMIN_LOOKUPFLW(user)] welded a single tank bomb. Temp: [bombtank.air_contents.return_temperature()-T0C]")
to_chat(user, "<span class='notice'>A pressure hole has been bored to [bombtank] valve. \The [bombtank] can now be ignited.</span>")
add_fingerprint(user)
return TRUE
@@ -145,8 +145,7 @@
return
/obj/item/tank/proc/ignite() //This happens when a bomb is told to explode
var/fuel_moles = air_contents.gases[/datum/gas/plasma] + air_contents.gases[/datum/gas/oxygen]/6
GAS_GARBAGE_COLLECT(air_contents.gases)
var/fuel_moles = air_contents.get_moles(/datum/gas/plasma) + air_contents.get_moles(/datum/gas/oxygen)/6
var/datum/gas_mixture/bomb_mixture = air_contents.copy()
var/strength = 1
@@ -156,7 +155,7 @@
qdel(master)
qdel(src)
if(bomb_mixture.temperature > (T0C + 400))
if(bomb_mixture.return_temperature() > (T0C + 400))
strength = (fuel_moles/15)
if(strength >=1)
@@ -169,7 +168,7 @@
ground_zero.assume_air(bomb_mixture)
ground_zero.hotspot_expose(1000, 125)
else if(bomb_mixture.temperature > (T0C + 250))
else if(bomb_mixture.return_temperature() > (T0C + 250))
strength = (fuel_moles/20)
if(strength >=1)
@@ -180,7 +179,7 @@
ground_zero.assume_air(bomb_mixture)
ground_zero.hotspot_expose(1000, 125)
else if(bomb_mixture.temperature > (T0C + 100))
else if(bomb_mixture.return_temperature() > (T0C + 100))
strength = (fuel_moles/25)
if (strength >=1)

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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)]")
*/

View File

@@ -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)

View File

@@ -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

View File

@@ -0,0 +1,304 @@
#ifdef EXTOOLS_BROKE
/datum/gas_mixture
var/list/gases = list()
var/temperature = 0 //kelvins
var/tmp/temperature_archived = 0
var/volume = CELL_VOLUME //liters
var/last_share = 0
/datum/gas_mixture/heat_capacity() //joules per kelvin
var/list/cached_gases = gases
var/list/cached_gasheats = GLOB.meta_gas_specific_heats
. = 0
for(var/id in cached_gases)
. += cached_gases[id] * cached_gasheats[id]
/datum/gas_mixture/turf/heat_capacity() // Same as above except vacuums return HEAT_CAPACITY_VACUUM
var/list/cached_gases = gases
var/list/cached_gasheats = GLOB.meta_gas_specific_heats
for(var/id in cached_gases)
. += cached_gases[id] * cached_gasheats[id]
if(!.)
. += HEAT_CAPACITY_VACUUM //we want vacuums in turfs to have the same heat capacity as space
//prefer this to gas_mixture/total_moles in performance critical areas
#define TOTAL_MOLES(cached_gases, out_var)\
out_var = 0;\
for(var/total_moles_id in cached_gases){\
out_var += cached_gases[total_moles_id];\
}
#define THERMAL_ENERGY(gas) (gas.temperature * gas.heat_capacity())
/datum/gas_mixture/total_moles()
var/cached_gases = gases
TOTAL_MOLES(cached_gases, .)
/datum/gas_mixture/return_pressure() //kilopascals
if(volume > 0) // to prevent division by zero
var/cached_gases = gases
TOTAL_MOLES(cached_gases, .)
. *= R_IDEAL_GAS_EQUATION * temperature / volume
return
return 0
/datum/gas_mixture/return_temperature() //kelvins
return temperature
/datum/gas_mixture/set_min_heat_capacity(n)
return
/datum/gas_mixture/set_temperature(new_temp)
temperature = new_temp
/datum/gas_mixture/set_volume(new_volume)
volume = new_volume
/datum/gas_mixture/get_moles(gas_type)
return gases[gas_type]
/datum/gas_mixture/set_moles(gas_type, moles)
gases[gas_type] = moles
/datum/gas_mixture/scrub_into(datum/gas_mixture/target, list/gases)
if(isnull(target))
return FALSE
var/list/removed_gases = target.gases
//Filter it
var/datum/gas_mixture/filtered_out = new
var/list/filtered_gases = filtered_out.gases
filtered_out.temperature = removed.temperature
for(var/gas in filter_types & removed_gases)
filtered_gases[gas] = removed_gases[gas]
removed_gases[gas] = 0
merge(filtered_out)
/datum/gas_mixture/mark_immutable()
return
/datum/gas_mixture/get_gases()
return gases
/datum/gas_mixture/multiply(factor)
for(var/id in gases)
gases[id] *= factor
/datum/gas_mixture/get_last_share()
return last_share
/datum/gas_mixture/clear()
gases.Cut()
/datum/gas_mixture/return_volume()
return volume // wow!
/datum/gas_mixture/thermal_energy()
return THERMAL_ENERGY(src)
/datum/gas_mixture/archive()
temperature_archived = temperature
gas_archive = gases.Copy()
return 1
/datum/gas_mixture/merge(datum/gas_mixture/giver)
if(!giver)
return 0
//heat transfer
if(abs(temperature - giver.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/self_heat_capacity = heat_capacity()
var/giver_heat_capacity = giver.heat_capacity()
var/combined_heat_capacity = giver_heat_capacity + self_heat_capacity
if(combined_heat_capacity)
temperature = (giver.temperature * giver_heat_capacity + temperature * self_heat_capacity) / combined_heat_capacity
var/list/cached_gases = gases //accessing datum vars is slower than proc vars
var/list/giver_gases = giver.gases
//gas transfer
for(var/giver_id in giver_gases)
cached_gases[giver_id] += giver_gases[giver_id]
return 1
/datum/gas_mixture/remove(amount)
var/sum
var/list/cached_gases = gases
TOTAL_MOLES(cached_gases, sum)
amount = min(amount, sum) //Can not take more air than tile has!
if(amount <= 0)
return null
var/datum/gas_mixture/removed = new type
var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars
removed.temperature = temperature
for(var/id in cached_gases)
removed_gases[id] = QUANTIZE((cached_gases[id] / sum) * amount)
cached_gases[id] -= removed_gases[id]
GAS_GARBAGE_COLLECT(gases)
return removed
/datum/gas_mixture/remove_ratio(ratio)
if(ratio <= 0)
return null
ratio = min(ratio, 1)
var/list/cached_gases = gases
var/datum/gas_mixture/removed = new type
var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars
removed.temperature = temperature
for(var/id in cached_gases)
removed_gases[id] = QUANTIZE(cached_gases[id] * ratio)
cached_gases[id] -= removed_gases[id]
GAS_GARBAGE_COLLECT(gases)
return removed
/datum/gas_mixture/copy()
var/list/cached_gases = gases
var/datum/gas_mixture/copy = new type
var/list/copy_gases = copy.gases
copy.temperature = temperature
for(var/id in cached_gases)
copy_gases[id] = cached_gases[id]
return copy
/datum/gas_mixture/copy_from(datum/gas_mixture/sample)
var/list/cached_gases = gases //accessing datum vars is slower than proc vars
var/list/sample_gases = sample.gases
temperature = sample.temperature
for(var/id in sample_gases)
cached_gases[id] = sample_gases[id]
//remove all gases not in the sample
cached_gases &= sample_gases
return 1
/datum/gas_mixture/copy_from_turf(turf/model)
parse_gas_string(model.initial_gas_mix)
//acounts for changes in temperature
var/turf/model_parent = model.parent_type
if(model.temperature != initial(model.temperature) || model.temperature != initial(model_parent.temperature))
temperature = model.temperature
return 1
/datum/gas_mixture/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4)
var/list/cached_gases = gases
var/list/sharer_gases = sharer.gases
var/temperature_delta = temperature_archived - sharer.temperature_archived
var/abs_temperature_delta = abs(temperature_delta)
var/old_self_heat_capacity = 0
var/old_sharer_heat_capacity = 0
if(abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
old_self_heat_capacity = heat_capacity()
old_sharer_heat_capacity = sharer.heat_capacity()
var/heat_capacity_self_to_sharer = 0 //heat capacity of the moles transferred from us to the sharer
var/heat_capacity_sharer_to_self = 0 //heat capacity of the moles transferred from the sharer to us
var/moved_moles = 0
var/abs_moved_moles = 0
//we're gonna define these vars outside of this for loop because as it turns out, var declaration is pricy
var/delta
var/gas_heat_capacity
//and also cache this shit rq because that results in sanic speed for reasons byond explanation
var/list/cached_gasheats = GLOB.meta_gas_specific_heats
//GAS TRANSFER
for(var/id in cached_gases | sharer_gases) // transfer gases
delta = QUANTIZE(gas_archive[id] - sharer.gas_archive[id])/(atmos_adjacent_turfs+1) //the amount of gas that gets moved between the mixtures
if(delta && abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
gas_heat_capacity = delta * cached_gasheats[id]
if(delta > 0)
heat_capacity_self_to_sharer += gas_heat_capacity
else
heat_capacity_sharer_to_self -= gas_heat_capacity //subtract here instead of adding the absolute value because we know that delta is negative.
cached_gases[id] -= delta
sharer_gases[id] += delta
moved_moles += delta
abs_moved_moles += abs(delta)
last_share = abs_moved_moles
//THERMAL ENERGY TRANSFER
if(abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/new_self_heat_capacity = old_self_heat_capacity + heat_capacity_sharer_to_self - heat_capacity_self_to_sharer
var/new_sharer_heat_capacity = old_sharer_heat_capacity + heat_capacity_self_to_sharer - heat_capacity_sharer_to_self
//transfer of thermal energy (via changed heat capacity) between self and sharer
if(new_self_heat_capacity > MINIMUM_HEAT_CAPACITY)
temperature = (old_self_heat_capacity*temperature - heat_capacity_self_to_sharer*temperature_archived + heat_capacity_sharer_to_self*sharer.temperature_archived)/new_self_heat_capacity
if(new_sharer_heat_capacity > MINIMUM_HEAT_CAPACITY)
sharer.temperature = (old_sharer_heat_capacity*sharer.temperature-heat_capacity_sharer_to_self*sharer.temperature_archived + heat_capacity_self_to_sharer*temperature_archived)/new_sharer_heat_capacity
//thermal energy of the system (self and sharer) is unchanged
if(abs(old_sharer_heat_capacity) > MINIMUM_HEAT_CAPACITY)
if(abs(new_sharer_heat_capacity/old_sharer_heat_capacity - 1) < 0.1) // <10% change in sharer heat capacity
temperature_share(sharer, OPEN_HEAT_TRANSFER_COEFFICIENT)
if (initial(sharer.gc_share))
GAS_GARBAGE_COLLECT(sharer.gases)
if(temperature_delta > MINIMUM_TEMPERATURE_TO_MOVE || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE)
var/our_moles
TOTAL_MOLES(cached_gases,our_moles)
var/their_moles
TOTAL_MOLES(sharer_gases,their_moles)
return (temperature_archived*(our_moles + moved_moles) - sharer.temperature_archived*(their_moles - moved_moles)) * R_IDEAL_GAS_EQUATION / volume
/datum/gas_mixture/temperature_share(datum/gas_mixture/sharer, conduction_coefficient, sharer_temperature, sharer_heat_capacity)
//transfer of thermal energy (via conduction) between self and sharer
if(sharer)
sharer_temperature = sharer.temperature_archived
var/temperature_delta = temperature_archived - sharer_temperature
if(abs(temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/self_heat_capacity = archived_heat_capacity()
sharer_heat_capacity = sharer_heat_capacity || sharer.archived_heat_capacity()
if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
var/heat = conduction_coefficient*temperature_delta* \
(self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity))
temperature = max(temperature - heat/self_heat_capacity, TCMB)
sharer_temperature = max(sharer_temperature + heat/sharer_heat_capacity, TCMB)
if(sharer)
sharer.temperature = sharer_temperature
return sharer_temperature
//thermal energy of the system (self and sharer) is unchanged
/datum/gas_mixture/compare(datum/gas_mixture/sample)
var/list/sample_gases = sample.gases //accessing datum vars is slower than proc vars
var/list/cached_gases = gases
for(var/id in cached_gases | sample_gases) // compare gases from either mixture
var/gas_moles = cached_gases[id]
var/sample_moles = sample_gases[id]
var/delta = abs(gas_moles - sample_moles)
if(delta > MINIMUM_MOLES_DELTA_TO_MOVE && \
delta > gas_moles * MINIMUM_AIR_RATIO_TO_MOVE)
return id
var/our_moles
TOTAL_MOLES(cached_gases, our_moles)
if(our_moles > MINIMUM_MOLES_DELTA_TO_MOVE)
var/temp = temperature
var/sample_temp = sample.temperature
var/temperature_delta = abs(temp - sample_temp)
if(temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
return "temp"
return ""
/datum/gas_mixture/transfer_to(datum/gas_mixture/target, amount)
return merge(target.remove(amount))
#endif

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

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

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

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

View File

@@ -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)]&deg;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)]&deg;C)."
else
. = "The sensor error light is blinking."
else

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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)]")

View File

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

View File

@@ -10,9 +10,7 @@
if(!..())
return FALSE
var/obj/item/tank/T = O
if(!T.air_contents.gases[gas_type])
return FALSE
return T.air_contents.gases[gas_type] >= moles_required
return T.air_contents.get_moles(gas_type) >= moles_required
//datum/bounty/item/engineering/gas/nitryl_tank
// name = "Full Tank of Nitryl"

View File

@@ -169,15 +169,13 @@
/datum/export/large/gas_canister/get_cost(obj/O)
var/obj/machinery/portable_atmospherics/canister/C = O
var/worth = 10
var/gases = C.air_contents.gases
worth += gases[/datum/gas/bz]*3
worth += gases[/datum/gas/stimulum]*25
worth += gases[/datum/gas/hypernoblium]*1000
worth += gases[/datum/gas/miasma]*2
worth += gases[/datum/gas/tritium]*7
worth += gases[/datum/gas/pluoxium]*6
worth += gases[/datum/gas/nitryl]*30
worth += C.air_contents.get_moles(/datum/gas/bz)*3
worth += C.air_contents.get_moles(/datum/gas/stimulum)*25
worth += C.air_contents.get_moles(/datum/gas/hypernoblium)*1000
worth += C.air_contents.get_moles(/datum/gas/miasma)*2
worth += C.air_contents.get_moles(/datum/gas/tritium)*7
worth += C.air_contents.get_moles(/datum/gas/pluoxium)*6
worth += C.air_contents.get_moles(/datum/gas/nitryl)*30
return worth

View File

@@ -171,10 +171,7 @@
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
if(!GM.gases[/datum/gas/oxygen])
return
GM.gases[/datum/gas/oxygen] = max(GM.gases[/datum/gas/oxygen] - severity * holder.energy, 0)
GAS_GARBAGE_COLLECT(GM.gases)
GM.set_moles(/datum/gas/oxygen, max(GM.get_moles(/datum/gas/oxygen) - severity * holder.energy, 0))
/datum/spacevine_mutation/nitro_eater
name = "nitrogen consuming"
@@ -186,10 +183,7 @@
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
if(!GM.gases[/datum/gas/nitrogen])
return
GM.gases[/datum/gas/nitrogen] = max(GM.gases[/datum/gas/nitrogen] - severity * holder.energy, 0)
GAS_GARBAGE_COLLECT(GM.gases)
GM.set_moles(/datum/gas/nitrogen, max(GM.get_moles(/datum/gas/nitrogen) - severity * holder.energy, 0))
/datum/spacevine_mutation/carbondioxide_eater
name = "CO2 consuming"
@@ -201,10 +195,7 @@
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
if(!GM.gases[/datum/gas/carbon_dioxide])
return
GM.gases[/datum/gas/carbon_dioxide] = max(GM.gases[/datum/gas/carbon_dioxide] - severity * holder.energy, 0)
GAS_GARBAGE_COLLECT(GM.gases)
GM.set_moles(/datum/gas/carbon_dioxide, max(GM.get_moles(/datum/gas/carbon_dioxide) - severity * holder.energy, 0))
/datum/spacevine_mutation/plasma_eater
name = "toxins consuming"
@@ -216,10 +207,7 @@
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
if(!GM.gases[/datum/gas/plasma])
return
GM.gases[/datum/gas/plasma] = max(GM.gases[/datum/gas/plasma] - severity * holder.energy, 0)
GAS_GARBAGE_COLLECT(GM.gases)
GM.set_moles(/datum/gas/plasma, max(GM.get_moles(/datum/gas/plasma) - severity * holder.energy, 0))
/datum/spacevine_mutation/thorns
name = "thorny"

View File

@@ -57,8 +57,8 @@
return
var/datum/gas_mixture/stank = new
stank.gases[/datum/gas/miasma] = (yield + 6)*7*0.02 // this process is only being called about 2/7 as much as corpses so this is 12-32 times a corpses
stank.temperature = T20C // without this the room would eventually freeze and miasma mining would be easier
stank.adjust_moles(/datum/gas/miasma,(yield + 6)*7*0.02) // this process is only being called about 2/7 as much as corpses so this is 12-32 times a corpses
stank.set_temperature(T20C) // without this the room would eventually freeze and miasma mining would be easier
T.assume_air(stank)
T.air_update_turf()

View File

@@ -226,8 +226,8 @@
if(isopenturf(loc))
var/turf/open/O = loc
if(O.air)
var/loc_gases = O.air.gases
if(loc_gases[/datum/gas/oxygen] > 13)
var/datum/gas_mixture/loc_air = O.air
if(loc_air.get_moles(/datum/gas/oxygen) > 13)
return TRUE
return FALSE

View File

@@ -125,12 +125,12 @@
return
// Negative Kelvin temperatures should never happen and if they do, normalize them
if(source_air.temperature < TCMB)
source_air.temperature = TCMB
if(source_air.return_temperature() < TCMB)
source_air.set_temperature(TCMB)
var/pressure_delta = target_pressure - target_air.return_pressure()
if(pressure_delta > 0.1)
var/transfer_moles = (pressure_delta*target_air.volume/(source_air.temperature * R_IDEAL_GAS_EQUATION))*PUMP_EFFICIENCY
var/transfer_moles = (pressure_delta*target_air.return_volume()/(source_air.return_temperature() * R_IDEAL_GAS_EQUATION))*PUMP_EFFICIENCY
var/datum/gas_mixture/removed = source_air.remove(transfer_moles)
target_air.merge(removed)
@@ -171,14 +171,14 @@
return
// Negative Kelvin temperatures should never happen and if they do, normalize them
if(source_air.temperature < TCMB)
source_air.temperature = TCMB
if(source_air.return_temperature() < TCMB)
source_air.set_temperature(TCMB)
if((source_air.return_pressure() < 0.01) || (target_air.return_pressure() >= PUMP_MAX_PRESSURE))
return
//The second part of the min caps the pressure built by the volume pumps to the max pump pressure
var/transfer_ratio = min(transfer_rate,target_air.volume*PUMP_MAX_PRESSURE/source_air.return_pressure())/source_air.volume
var/transfer_ratio = min(transfer_rate,target_air.return_volume()*PUMP_MAX_PRESSURE/source_air.return_pressure())/source_air.return_volume()
var/datum/gas_mixture/removed = source_air.remove_ratio(transfer_ratio * PUMP_EFFICIENCY)
@@ -351,10 +351,10 @@ obj/item/integrated_circuit/atmospherics/connector/portableConnectorReturnAir()
var/transfer_moles
//Negative Kelvins are an anomaly and should be normalized if encountered
if(source_air.temperature < TCMB)
source_air.temperature = TCMB
if(source_air.return_temperature(TCMB))
source_air.set_temperature(TCMB)
transfer_moles = (pressure_delta*contaminated_air.volume/(source_air.temperature * R_IDEAL_GAS_EQUATION))*PUMP_EFFICIENCY
transfer_moles = (pressure_delta*contaminated_air.return_volume()/(source_air.return_temperature() * R_IDEAL_GAS_EQUATION))*PUMP_EFFICIENCY
//If there is nothing to transfer, just return
if(transfer_moles <= 0)
@@ -368,16 +368,15 @@ obj/item/integrated_circuit/atmospherics/connector/portableConnectorReturnAir()
//This is the gas that will be moved from source to filtered
var/datum/gas_mixture/filtered_out = new
for(var/filtered_gas in removed.gases)
for(var/filtered_gas in removed.get_gases())
//Get the name of the gas and see if it is in the list
if(GLOB.meta_gas_names[filtered_gas] in wanted)
//The gas that is put in all the filtered out gases
filtered_out.temperature = removed.temperature
filtered_out.gases[filtered_gas] = removed.gases[filtered_gas]
filtered_out.set_temperature(removed.return_temperature())
filtered_out.set_moles(filtered_gas, removed.get_moles(filtered_gas))
//The filtered out gas is entirely removed from the currently filtered gases
removed.gases[filtered_gas] = 0
GAS_GARBAGE_COLLECT(removed.gases)
removed.set_moles(filtered_gas, 0)
//Check if the pressure is high enough to put stuff in filtered, or else just put it back in the source
var/datum/gas_mixture/target = (filtered_air.return_pressure() < target_pressure ? filtered_air : source_air)
@@ -444,7 +443,7 @@ obj/item/integrated_circuit/atmospherics/connector/portableConnectorReturnAir()
var/gas_percentage = round(max(min(get_pin_data(IC_INPUT, 4),100),0) / 100)
//Basically: number of moles = percentage of pressure filled up * efficiency coefficient * (pressure from both gases * volume of output) / (R * Temperature)
var/transfer_moles = (get_pin_data(IC_INPUT, 5) / max(1,output_gases.return_pressure())) * PUMP_EFFICIENCY * (source_1_gases.return_pressure() * gas_percentage + source_2_gases.return_pressure() * (1 - gas_percentage)) * output_gases.volume/ (R_IDEAL_GAS_EQUATION * max(output_gases.temperature,TCMB))
var/transfer_moles = (get_pin_data(IC_INPUT, 5) / max(1,output_gases.return_pressure())) * PUMP_EFFICIENCY * (source_1_gases.return_pressure() * gas_percentage + source_2_gases.return_pressure() * (1 - gas_percentage)) * output_gases.return_volume()/ (R_IDEAL_GAS_EQUATION * max(output_gases.return_temperature(),TCMB))
if(transfer_moles <= 0)
@@ -544,10 +543,10 @@ obj/item/integrated_circuit/atmospherics/connector/portableConnectorReturnAir()
push_data()
//Cool the tank if the power is on and the temp is above
if(!power_draw_idle || air_contents.temperature < temperature)
if(!power_draw_idle || air_contents.return_temperature() < temperature)
return
air_contents.temperature = max(73.15,air_contents.temperature - (air_contents.temperature - temperature) * heater_coefficient)
air_contents.set_temperature(max(73.15,air_contents.return_temperature() - (air_contents.return_temperature() - temperature) * heater_coefficient))
// - heater tank - // **works**
@@ -574,10 +573,10 @@ obj/item/integrated_circuit/atmospherics/connector/portableConnectorReturnAir()
push_data()
//Heat the tank if the power is on or its temperature is below what is set
if(!power_draw_idle || air_contents.temperature > temperature)
if(!power_draw_idle || air_contents.return_temperature() > temperature)
return
air_contents.temperature = min(573.15,air_contents.temperature + (temperature - air_contents.temperature) * heater_coefficient)
air_contents.set_temperature(min(573.15,air_contents.return_temperature() + (temperature - air_contents.return_temperature()) * heater_coefficient))
// - atmospheric cooler - // **works**
@@ -621,11 +620,11 @@ obj/item/integrated_circuit/atmospherics/connector/portableConnectorReturnAir()
return
var/datum/gas_mixture/turf_air = current_turf.return_air()
if(!power_draw_idle || turf_air.temperature < temperature)
if(!power_draw_idle || turf_air.return_temperature() < temperature)
return
//Cool the gas
turf_air.temperature = max(243.15,turf_air.temperature - (turf_air.temperature - temperature) * heater_coefficient)
turf_air.set_temperature(max(243.15,turf_air.return_temperature() - (turf_air.return_temperature() - temperature) * heater_coefficient))
// - atmospheric heater - // **works**
@@ -650,11 +649,11 @@ obj/item/integrated_circuit/atmospherics/connector/portableConnectorReturnAir()
return
var/datum/gas_mixture/turf_air = current_turf.return_air()
if(!power_draw_idle || turf_air.temperature > temperature)
if(!power_draw_idle || turf_air.return_temperature() > temperature)
return
//Heat the gas
turf_air.temperature = min(323.15,turf_air.temperature + (temperature - turf_air.temperature) * heater_coefficient)
turf_air.set_temperature(min(323.15,turf_air.return_temperature() + (temperature - turf_air.return_temperature()) * heater_coefficient))
// - tank slot - // **works**

View File

@@ -1162,12 +1162,11 @@
activate_pin(3)
return
var/list/gases = air_contents.gases
var/list/gas_names = list()
var/list/gas_amounts = list()
for(var/id in gases)
for(var/id in air_contents.get_gases())
var/name = GLOB.meta_gas_names[id]
var/amt = round(gases[id], 0.001)
var/amt = round(air_contents.get_moles(id), 0.001)
gas_names.Add(name)
gas_amounts.Add(amt)
@@ -1175,7 +1174,7 @@
set_pin_data(IC_OUTPUT, 2, gas_amounts)
set_pin_data(IC_OUTPUT, 3, round(air_contents.total_moles(), 0.001))
set_pin_data(IC_OUTPUT, 4, round(air_contents.return_pressure(), 0.001))
set_pin_data(IC_OUTPUT, 5, round(air_contents.temperature, 0.001))
set_pin_data(IC_OUTPUT, 5, round(air_contents.return_temperature(), 0.001))
set_pin_data(IC_OUTPUT, 6, round(air_contents.return_volume(), 0.001))
push_data()
activate_pin(2)

View File

@@ -213,6 +213,7 @@
var/list/modelCache = build_cache(no_changeturf)
var/space_key = modelCache[SPACE_KEY]
var/list/bounds
var/did_expand = FALSE
src.bounds = bounds = list(1.#INF, 1.#INF, 1.#INF, -1.#INF, -1.#INF, -1.#INF)
var/datum/map_orientation_pattern/mode = forced_pattern || GLOB.map_orientation_patterns["[orientation]"] || GLOB.map_orientation_patterns["[SOUTH]"]
var/invert_y = mode.invert_y
@@ -235,6 +236,7 @@
else
while(parsed_z > world.maxz)
world.incrementMaxZ()
did_expand = TRUE
if(!no_changeturf)
WARNING("Z-level expansion occurred without no_changeturf set, this may cause problems when /turf/AfterChange is called")
//these values are the same until a new gridset is reached.
@@ -256,11 +258,13 @@
continue
else
world.maxx = placement_x
did_expand = TRUE
if(placement_y > world.maxy)
if(cropMap)
break
else
world.maxy = placement_y
did_expand = TRUE
if(placement_x < 1)
actual_x += xi
continue
@@ -301,6 +305,9 @@
testing("Skipped loading [turfsSkipped] default turfs")
#endif
if(did_expand)
world.refresh_atmos_grid()
return TRUE
/datum/parsed_map/proc/build_cache(no_changeturf, bad_paths=null)

View File

@@ -7,6 +7,20 @@
return get_step(SSmapping.get_turf_below(get_turf(ref)), dir)
return get_step(ref, dir)
/proc/get_multiz_accessible_levels(center_z)
. = list(center_z)
var/other_z = center_z
var/offset
while((offset = SSmapping.level_trait(other_z, ZTRAIT_DOWN)))
other_z += offset
. += other_z
other_z = center_z
while((offset = SSmapping.level_trait(other_z, ZTRAIT_UP)))
other_z += offset
. += other_z
return .
/proc/get_dir_multiz(turf/us, turf/them)
us = get_turf(us)
them = get_turf(them)
@@ -32,16 +46,4 @@
/turf/proc/below()
return get_step_multiz(src, DOWN)
/proc/dir_inverse_multiz(dir)
var/holder = dir & (UP|DOWN)
if((holder == NONE) || (holder == (UP|DOWN)))
return turn(dir, 180)
dir &= ~(UP|DOWN)
dir = turn(dir, 180)
if(holder == UP)
holder = DOWN
else
holder = UP
dir |= holder
return dir

View File

@@ -13,26 +13,23 @@
var/toxins_used = 0
var/tox_detect_threshold = 0.02
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME
var/list/breath_gases = breath.gases
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.return_temperature())/BREATH_VOLUME
//Partial pressure of the toxins in our breath
var/Toxins_pp = (breath_gases[/datum/gas/plasma]/breath.total_moles())*breath_pressure
var/Toxins_pp = (breath.get_moles(/datum/gas/plasma)/breath.total_moles())*breath_pressure
if(Toxins_pp > tox_detect_threshold) // Detect toxins in air
adjustPlasma(breath_gases[/datum/gas/plasma]*250)
adjustPlasma(breath.get_moles(/datum/gas/plasma)*250)
throw_alert("alien_tox", /obj/screen/alert/alien_tox)
toxins_used = breath_gases[/datum/gas/plasma]
toxins_used = breath.get_moles(/datum/gas/plasma)
else
clear_alert("alien_tox")
//Breathe in toxins and out oxygen
breath_gases[/datum/gas/plasma] -= toxins_used
breath_gases[/datum/gas/oxygen] += toxins_used
GAS_GARBAGE_COLLECT(breath.gases)
breath.adjust_moles(/datum/gas/plasma, -toxins_used)
breath.adjust_moles(/datum/gas/oxygen, toxins_used)
//BREATH TEMPERATURE
handle_breath_temperature(breath)

View File

@@ -33,7 +33,7 @@
if((!istype(H.w_uniform, /obj/item/clothing/under/plasmaman) || !istype(H.head, /obj/item/clothing/head/helmet/space/plasmaman)) && !atmos_sealed)
if(environment)
if(environment.total_moles())
if(environment.gases[/datum/gas/oxygen] && (environment.gases[/datum/gas/oxygen]) >= 1) //Same threshhold that extinguishes fire
if(environment.get_moles(/datum/gas/oxygen) >= 1) //Same threshhold that extinguishes fire
H.adjust_fire_stacks(0.5)
if(!H.on_fire && H.fire_stacks > 0)
H.visible_message("<span class='danger'>[H]'s body reacts with the atmosphere and bursts into flames!</span>","<span class='userdanger'>Your body reacts with the atmosphere and bursts into flame!</span>")

View File

@@ -162,12 +162,11 @@
var/SA_para_min = 1
var/SA_sleep_min = 5
var/oxygen_used = 0
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.return_temperature())/BREATH_VOLUME
var/list/breath_gases = breath.gases
var/O2_partialpressure = (breath_gases[/datum/gas/oxygen]/breath.total_moles())*breath_pressure
var/Toxins_partialpressure = (breath_gases[/datum/gas/plasma]/breath.total_moles())*breath_pressure
var/CO2_partialpressure = (breath_gases[/datum/gas/carbon_dioxide]/breath.total_moles())*breath_pressure
var/O2_partialpressure = (breath.get_moles(/datum/gas/oxygen)/breath.total_moles())*breath_pressure
var/Toxins_partialpressure = (breath.get_moles(/datum/gas/plasma)/breath.total_moles())*breath_pressure
var/CO2_partialpressure = (breath.get_moles(/datum/gas/carbon_dioxide)/breath.total_moles())*breath_pressure
//OXYGEN
@@ -191,7 +190,7 @@
var/ratio = 1 - O2_partialpressure/safe_oxy_min
adjustOxyLoss(min(5*ratio, 3))
failed_last_breath = 1
oxygen_used = breath_gases[/datum/gas/oxygen]*ratio
oxygen_used = breath.get_moles(/datum/gas/oxygen)*ratio
else
adjustOxyLoss(3)
failed_last_breath = 1
@@ -203,12 +202,12 @@
o2overloadtime = 0 //reset our counter for this too
if(health >= crit_threshold)
adjustOxyLoss(-5)
oxygen_used = breath_gases[/datum/gas/oxygen]
oxygen_used = breath.get_moles(/datum/gas/oxygen)
clear_alert("not_enough_oxy")
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "suffocation")
breath_gases[/datum/gas/oxygen] -= oxygen_used
breath_gases[/datum/gas/carbon_dioxide] += oxygen_used
breath.adjust_moles(/datum/gas/oxygen, -oxygen_used)
breath.adjust_moles(/datum/gas/carbon_dioxide, oxygen_used)
//CARBON DIOXIDE
if(CO2_partialpressure > safe_co2_max)
@@ -227,15 +226,15 @@
//TOXINS/PLASMA
if(Toxins_partialpressure > safe_tox_max)
var/ratio = (breath_gases[/datum/gas/plasma]/safe_tox_max) * 10
var/ratio = (breath.get_moles(/datum/gas/plasma)/safe_tox_max) * 10
adjustToxLoss(clamp(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE))
throw_alert("too_much_tox", /obj/screen/alert/too_much_tox)
else
clear_alert("too_much_tox")
//NITROUS OXIDE
if(breath_gases[/datum/gas/nitrous_oxide])
var/SA_partialpressure = (breath_gases[/datum/gas/nitrous_oxide]/breath.total_moles())*breath_pressure
if(breath.get_moles(/datum/gas/nitrous_oxide))
var/SA_partialpressure = (breath.get_moles(/datum/gas/nitrous_oxide)/breath.total_moles())*breath_pressure
if(SA_partialpressure > SA_para_min)
Unconscious(60)
if(SA_partialpressure > SA_sleep_min)
@@ -248,26 +247,26 @@
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "chemical_euphoria")
//BZ (Facepunch port of their Agent B)
if(breath_gases[/datum/gas/bz])
var/bz_partialpressure = (breath_gases[/datum/gas/bz]/breath.total_moles())*breath_pressure
if(breath.get_moles(/datum/gas/bz))
var/bz_partialpressure = (breath.get_moles(/datum/gas/bz)/breath.total_moles())*breath_pressure
if(bz_partialpressure > 1)
hallucination += 10
else if(bz_partialpressure > 0.01)
hallucination += 5
//TRITIUM
if(breath_gases[/datum/gas/tritium])
var/tritium_partialpressure = (breath_gases[/datum/gas/tritium]/breath.total_moles())*breath_pressure
if(breath.get_moles(/datum/gas/tritium))
var/tritium_partialpressure = (breath.get_moles(/datum/gas/tritium)/breath.total_moles())*breath_pressure
radiation += tritium_partialpressure/10
//NITRYL
if(breath_gases[/datum/gas/nitryl])
var/nitryl_partialpressure = (breath_gases[/datum/gas/nitryl]/breath.total_moles())*breath_pressure
if(breath.get_moles(/datum/gas/nitryl))
var/nitryl_partialpressure = (breath.get_moles(/datum/gas/nitryl)/breath.total_moles())*breath_pressure
adjustFireLoss(nitryl_partialpressure/4)
//MIASMA
if(breath_gases[/datum/gas/miasma])
var/miasma_partialpressure = (breath_gases[/datum/gas/miasma]/breath.total_moles())*breath_pressure
if(breath.get_moles(/datum/gas/miasma))
var/miasma_partialpressure = (breath.get_moles(/datum/gas/miasma)/breath.total_moles())*breath_pressure
if(miasma_partialpressure > MINIMUM_MOLES_DELTA_TO_MOVE)
if(prob(0.05 * miasma_partialpressure))
@@ -307,11 +306,6 @@
else
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "smell")
GAS_GARBAGE_COLLECT(breath.gases)
//BREATH TEMPERATURE
handle_breath_temperature(breath)
@@ -370,9 +364,9 @@
var/datum/gas_mixture/stank = new
stank.gases[/datum/gas/miasma] = 0.1
stank.set_moles(/datum/gas/miasma,0.1)
stank.temperature = BODYTEMP_NORMAL
stank.set_temperature(BODYTEMP_NORMAL)
miasma_turf.assume_air(stank)

View File

@@ -46,8 +46,8 @@
return ..()
/mob/living/carbon/monkey/handle_breath_temperature(datum/gas_mixture/breath)
if(abs(BODYTEMP_NORMAL - breath.temperature) > 50)
switch(breath.temperature)
if(abs(BODYTEMP_NORMAL - breath.return_temperature()) > 50)
switch(breath.return_temperature())
if(-INFINITY to 120)
adjustFireLoss(3)
if(120 to 200)

View File

@@ -134,7 +134,7 @@
ExtinguishMob()
return
var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment
if(G.gases[/datum/gas/oxygen] < 1)
if(G.get_moles(/datum/gas/oxygen, 1))
ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire
return
var/turf/location = get_turf(src)

View File

@@ -914,7 +914,7 @@
floating_need_update = TRUE
/mob/living/proc/get_temperature(datum/gas_mixture/environment)
var/loc_temp = environment ? environment.temperature : T0C
var/loc_temp = environment ? environment.return_temperature() : T0C
if(isobj(loc))
var/obj/oloc = loc
var/obj_temp = oloc.return_temperature()

View File

@@ -565,7 +565,6 @@
dat += "Unable to obtain a reading.<br>"
else
var/datum/gas_mixture/environment = T.return_air()
var/list/env_gases = environment.gases
var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles()
@@ -573,11 +572,11 @@
dat += "Air Pressure: [round(pressure,0.1)] kPa<br>"
if (total_moles)
for(var/id in env_gases)
var/gas_level = env_gases[id]/total_moles
for(var/id in environment.get_gases())
var/gas_level = environment.get_moles(id)/total_moles
if(gas_level > 0.01)
dat += "[GLOB.meta_gas_names[id]]: [round(gas_level*100)]%<br>"
dat += "Temperature: [round(environment.temperature-T0C)]&deg;C<br>"
dat += "Temperature: [round(environment.return_temperature()-T0C)]&deg;C<br>"
dat += "<a href='byond://?src=[REF(src)];software=atmosensor;sub=0'>Refresh Reading</a> <br>"
dat += "<br>"
return dat

View File

@@ -49,12 +49,12 @@
return
if(isopenturf(loc))
var/turf/open/T = src.loc
if(T.air && T.air.gases[/datum/gas/carbon_dioxide])
var/co2 = T.air.gases[/datum/gas/carbon_dioxide]
if(T.air)
var/co2 = T.air.get_moles(/datum/gas/carbon_dioxide)
if(co2 > 0)
if(prob(25))
var/amt = min(co2, 9)
T.air.gases[/datum/gas/carbon_dioxide] -= amt
T.air.adjust_moles(/datum/gas/carbon_dioxide, -amt)
T.atmos_spawn_air("o2=[amt]")
/mob/living/simple_animal/hostile/tree/AttackingTarget()

View File

@@ -252,14 +252,11 @@
if(isturf(src.loc) && isopenturf(src.loc))
var/turf/open/ST = src.loc
if(ST.air)
var/ST_gases = ST.air.gases
var/tox = ST_gases[/datum/gas/plasma]
var/oxy = ST_gases[/datum/gas/oxygen]
var/n2 = ST_gases[/datum/gas/nitrogen]
var/co2 = ST_gases[/datum/gas/carbon_dioxide]
GAS_GARBAGE_COLLECT(ST.air.gases)
var/tox = ST.air.get_moles(/datum/gas/plasma)
var/oxy = ST.air.get_moles(/datum/gas/oxygen)
var/n2 = ST.air.get_moles(/datum/gas/nitrogen)
var/co2 = ST.air.get_moles(/datum/gas/carbon_dioxide)
if(atmos_requirements["min_oxy"] && oxy < atmos_requirements["min_oxy"])
. = FALSE

View File

@@ -128,9 +128,7 @@
Tempstun = 0
if(stat != DEAD)
var/bz_percentage =0
if(environment.gases[/datum/gas/bz])
bz_percentage = environment.gases[/datum/gas/bz] / environment.total_moles()
var/bz_percentage = environment.total_moles() ? (environment.get_moles(/datum/gas/bz) / environment.total_moles()) : 0
var/stasis = (bz_percentage >= 0.05 && bodytemperature < (T0C + 100)) || force_stasis
if(stat == CONSCIOUS && stasis)

View File

@@ -66,11 +66,10 @@
var/datum/gas_mixture/environment = loc.return_air()
var/t = "<span class='notice'>Coordinates: [x],[y] \n</span>"
t += "<span class='danger'>Temperature: [environment.temperature] \n</span>"
for(var/id in environment.gases)
var/gas = environment.gases[id]
if(gas)
t+="<span class='notice'>[GLOB.meta_gas_names[id]]: [gas] \n</span>"
t += "<span class='danger'>Temperature: [environment.return_temperature()] \n</span>"
for(var/id in environment.get_gases())
if(environment.get_moles(id))
t+="<span class='notice'>[GLOB.meta_gas_names[id]]: [environment.get_moles(id)] \n</span>"
to_chat(usr, t)

View File

@@ -73,20 +73,22 @@
data["active"] = TRUE
data["SM_integrity"] = active.get_integrity()
data["SM_power"] = active.power
data["SM_ambienttemp"] = air.temperature
data["SM_ambienttemp"] = air.return_temperature()
data["SM_ambientpressure"] = air.return_pressure()
//data["SM_EPR"] = round((air.total_moles / air.group_multiplier) / 23.1, 0.01)
var/list/gasdata = list()
if(air.total_moles())
for(var/gasid in air.gases)
gasdata.Add(list(list(
"name"= GLOB.meta_gas_names[gasid],
"amount" = round(100*air.gases[gasid]/air.total_moles(),0.01))))
for(var/gasid in air.get_gases())
var/amount = air.get_moles(gasid)
if(amount)
gasdata.Add(list(list(
"name"= GLOB.meta_gas_names[gasid],
"amount" = round(100*amount/air.total_moles(),0.01))))
else
for(var/gasid in air.gases)
for(var/gasid in air.get_gases())
gasdata.Add(list(list(
"name"= GLOB.meta_gas_names[gasid],
"amount" = 0)))
@@ -124,4 +126,4 @@
for(var/obj/machinery/power/supermatter_crystal/S in supermatters)
if(S.uid == newuid)
active = S
return TRUE
return TRUE

View File

@@ -57,7 +57,7 @@
var/cold_air_heat_capacity = cold_air.heat_capacity()
var/hot_air_heat_capacity = hot_air.heat_capacity()
var/delta_temperature = hot_air.temperature - cold_air.temperature
var/delta_temperature = hot_air.return_temperature() - cold_air.return_temperature()
if(delta_temperature > 0 && cold_air_heat_capacity > 0 && hot_air_heat_capacity > 0)
@@ -68,8 +68,8 @@
var/heat = energy_transfer*(1-efficiency)
lastgen += energy_transfer*efficiency
hot_air.temperature = hot_air.temperature - energy_transfer/hot_air_heat_capacity
cold_air.temperature = cold_air.temperature + heat/cold_air_heat_capacity
hot_air.set_temperature(hot_air.return_temperature() - energy_transfer/hot_air_heat_capacity)
cold_air.set_temperature(cold_air.return_temperature() + heat/cold_air_heat_capacity)
//add_avail(lastgen) This is done in process now
// update icon overlays only if displayed level has changed
@@ -116,11 +116,11 @@
t += "<BR>"
t += "<B><font color='blue'>Cold loop</font></B><BR>"
t += "Temperature Inlet: [round(cold_circ_air2.temperature, 0.1)] K / Outlet: [round(cold_circ_air1.temperature, 0.1)] K<BR>"
t += "Temperature Inlet: [round(cold_circ_air2.return_temperature(), 0.1)] K / Outlet: [round(cold_circ_air1.return_temperature(), 0.1)] K<BR>"
t += "Pressure Inlet: [round(cold_circ_air2.return_pressure(), 0.1)] kPa / Outlet: [round(cold_circ_air1.return_pressure(), 0.1)] kPa<BR>"
t += "<B><font color='red'>Hot loop</font></B><BR>"
t += "Temperature Inlet: [round(hot_circ_air2.temperature, 0.1)] K / Outlet: [round(hot_circ_air1.temperature, 0.1)] K<BR>"
t += "Temperature Inlet: [round(hot_circ_air2.return_temperature(), 0.1)] K / Outlet: [round(hot_circ_air1.return_temperature(), 0.1)] K<BR>"
t += "Pressure Inlet: [round(hot_circ_air2.return_pressure(), 0.1)] kPa / Outlet: [round(hot_circ_air1.return_pressure(), 0.1)] kPa<BR>"
t += "</div>"

View File

@@ -47,31 +47,29 @@
if(!loaded_tank)
return
if(!bitcoinmining)
if(!loaded_tank.air_contents.gases[/datum/gas/plasma])
if(loaded_tank.air_contents.get_moles(/datum/gas/plasma) < 0.0001)
investigate_log("<font color='red'>out of fuel</font>.", INVESTIGATE_SINGULO)
playsound(src, 'sound/machines/ding.ogg', 50, 1)
Radio.talk_into(src, "Insufficient plasma in [get_area(src)] [src], ejecting \the [loaded_tank].", FREQ_ENGINEERING)
eject()
else
var/gasdrained = min(powerproduction_drain*drainratio,loaded_tank.air_contents.gases[/datum/gas/plasma])
loaded_tank.air_contents.gases[/datum/gas/plasma] -= 2.7 * gasdrained
loaded_tank.air_contents.gases[/datum/gas/tritium] += 2.7 * gasdrained
GAS_GARBAGE_COLLECT(loaded_tank.air_contents.gases)
var/gasdrained = min(powerproduction_drain*drainratio,loaded_tank.air_contents.get_moles(/datum/gas/plasma))
loaded_tank.air_contents.adjust_moles(/datum/gas/plasma, -gasdrained)
loaded_tank.air_contents.adjust_moles(/datum/gas/tritium, gasdrained)
var/power_produced = RAD_COLLECTOR_OUTPUT
add_avail(power_produced)
stored_power-=power_produced
else if(is_station_level(z) && SSresearch.science_tech)
if(!loaded_tank.air_contents.gases[/datum/gas/tritium] || !loaded_tank.air_contents.gases[/datum/gas/oxygen])
if(!loaded_tank.air_contents.get_moles(/datum/gas/tritium) || !loaded_tank.air_contents.get_moles(/datum/gas/oxygen))
playsound(src, 'sound/machines/ding.ogg', 50, 1)
Radio.talk_into(src, "Insufficient oxygen and tritium in [get_area(src)] [src] to produce research points, ejecting \the [loaded_tank].", FREQ_ENGINEERING)
eject()
else
var/gasdrained = bitcoinproduction_drain*drainratio
loaded_tank.air_contents.gases[/datum/gas/tritium] -= gasdrained
loaded_tank.air_contents.gases[/datum/gas/oxygen] -= gasdrained
loaded_tank.air_contents.gases[/datum/gas/carbon_dioxide] += gasdrained*2
GAS_GARBAGE_COLLECT(loaded_tank.air_contents.gases)
loaded_tank.air_contents.adjust_moles(/datum/gas/tritium, -gasdrained)
loaded_tank.air_contents.adjust_moles(/datum/gas/oxygen, -gasdrained)
loaded_tank.air_contents.adjust_moles(/datum/gas/carbon_dioxide, gasdrained*2)
var/bitcoins_mined = stored_power*RAD_COLLECTOR_MINING_CONVERSION_RATE
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_ENG)
if(D)
@@ -86,9 +84,7 @@
toggle_power()
user.visible_message("[user.name] turns the [src.name] [active? "on":"off"].", \
"<span class='notice'>You turn the [src.name] [active? "on":"off"].</span>")
var/fuel
if(loaded_tank)
fuel = loaded_tank.air_contents.gases[/datum/gas/plasma]
var/fuel = loaded_tank.air_contents.get_moles(/datum/gas/plasma)
investigate_log("turned [active?"<font color='green'>on</font>":"<font color='red'>off</font>"] by [key_name(user)]. [loaded_tank?"Fuel: [round(fuel/0.29)]%":"<font color='red'>It is empty</font>"].", INVESTIGATE_SINGULO)
return
else

View File

@@ -211,10 +211,10 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
if(get_integrity() < SUPERMATTER_DANGER_PERCENT)
return SUPERMATTER_DANGER
if((get_integrity() < SUPERMATTER_WARNING_PERCENT) || (air.temperature > CRITICAL_TEMPERATURE))
if((get_integrity() < SUPERMATTER_WARNING_PERCENT) || (air.return_temperature() > CRITICAL_TEMPERATURE))
return SUPERMATTER_WARNING
if(air.temperature > (CRITICAL_TEMPERATURE * 0.8))
if(air.return_temperature() > (CRITICAL_TEMPERATURE * 0.8))
return SUPERMATTER_NOTIFY
if(power > 5)
@@ -342,13 +342,13 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
else
if(takes_damage)
//causing damage
damage = max(damage + (max(clamp(removed.total_moles() / 200, 0.5, 1) * removed.temperature - ((T0C + HEAT_PENALTY_THRESHOLD)*dynamic_heat_resistance), 0) * mole_heat_penalty / 150 ) * DAMAGE_INCREASE_MULTIPLIER, 0)
damage = max(damage + (max(clamp(removed.total_moles() / 200, 0.5, 1) * removed.return_temperature() - ((T0C + HEAT_PENALTY_THRESHOLD)*dynamic_heat_resistance), 0) * mole_heat_penalty / 150 ) * DAMAGE_INCREASE_MULTIPLIER, 0)
damage = max(damage + (max(power - POWER_PENALTY_THRESHOLD, 0)/500) * DAMAGE_INCREASE_MULTIPLIER, 0)
damage = max(damage + (max(combined_gas - MOLE_PENALTY_THRESHOLD, 0)/80) * DAMAGE_INCREASE_MULTIPLIER, 0)
//healing damage
if(combined_gas < MOLE_PENALTY_THRESHOLD)
damage = max(damage + (min(removed.temperature - (T0C + HEAT_PENALTY_THRESHOLD), 0) / 150 ), 0)
damage = max(damage + (min(removed.return_temperature() - (T0C + HEAT_PENALTY_THRESHOLD), 0) / 150 ), 0)
//capping damage
damage = min(damage_archived + (DAMAGE_HARDCAP * explosion_point),damage)
@@ -358,15 +358,15 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
//calculating gas related values
combined_gas = max(removed.total_moles(), 0)
plasmacomp = max(removed.gases[/datum/gas/plasma]/combined_gas, 0)
o2comp = max(removed.gases[/datum/gas/oxygen]/combined_gas, 0)
co2comp = max(removed.gases[/datum/gas/carbon_dioxide]/combined_gas, 0)
pluoxiumcomp = max(removed.gases[/datum/gas/pluoxium]/combined_gas, 0)
tritiumcomp = max(removed.gases[/datum/gas/tritium]/combined_gas, 0)
bzcomp = max(removed.gases[/datum/gas/bz]/combined_gas, 0)
plasmacomp = max(removed.get_moles(/datum/gas/plasma)/combined_gas, 0)
o2comp = max(removed.get_moles(/datum/gas/oxygen)/combined_gas, 0)
co2comp = max(removed.get_moles(/datum/gas/carbon_dioxide)/combined_gas, 0)
tritiumcomp = max(removed.get_moles(/datum/gas/tritium)/combined_gas, 0)
bzcomp = max(removed.get_moles(/datum/gas/bz)/combined_gas, 0)
n2ocomp = max(removed.gases[/datum/gas/nitrous_oxide]/combined_gas, 0)
n2comp = max(removed.gases[/datum/gas/nitrogen]/combined_gas, 0)
pluoxiumcomp = max(removed.get_moles(/datum/gas/pluoxium)/combined_gas, 0)
n2ocomp = max(removed.get_moles(/datum/gas/nitrous_oxide)/combined_gas, 0)
n2comp = max(removed.get_moles(/datum/gas/nitrogen)/combined_gas, 0)
if(pluoxiumcomp >= 0.15)
pluoxiumbonus = 1 //makes pluoxium only work at 15%+
@@ -404,7 +404,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
temp_factor = 30
icon_state = base_icon_state
power = max( (removed.temperature * temp_factor / T0C) * gasmix_power_ratio + power, 0) //Total laser power plus an overload
power = max( (removed.return_temperature() * temp_factor / T0C) * gasmix_power_ratio + power, 0) //Total laser power plus an overload
if(prob(50))
radiation_pulse(src, power * (1 + (tritiumcomp * TRITIUM_RADIOACTIVITY_MODIFIER) + ((pluoxiumcomp * PLUOXIUM_RADIOACTIVITY_MODIFIER) * pluoxiumbonus) * (power_transmission_bonus/(10-(bzcomp * BZ_RADIOACTIVITY_MODIFIER))))) // Rad Modifiers BZ(500%), Tritium(300%), and Pluoxium(-200%)
@@ -420,14 +420,14 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
//Also keep in mind we are only adding this temperature to (efficiency)% of the one tile the rock
//is on. An increase of 4*C @ 25% efficiency here results in an increase of 1*C / (#tilesincore) overall.
removed.temperature += ((device_energy * dynamic_heat_modifier) / THERMAL_RELEASE_MODIFIER)
removed.set_temperature(removed.return_temperature() + ((device_energy * dynamic_heat_modifier) / THERMAL_RELEASE_MODIFIER))
removed.temperature = max(0, min(removed.temperature, 2500 * dynamic_heat_modifier))
removed.set_temperature(max(0, min(removed.return_temperature(), 2500 * dynamic_heat_modifier)))
//Calculate how much gas to release
removed.gases[/datum/gas/plasma] += max((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0)
removed.adjust_moles(/datum/gas/plasma, max((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0))
removed.gases[/datum/gas/oxygen] += max(((device_energy + removed.temperature * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER, 0)
removed.adjust_moles(/datum/gas/oxygen, max(((device_energy + removed.return_temperature() * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER, 0))
if(produces_gas)
env.merge(removed)

View File

@@ -205,7 +205,7 @@
// Weird function but it works. Should be something else...
var/newrpm = ((compressor.gas_contained.temperature) * compressor.gas_contained.total_moles())/4
var/newrpm = ((compressor.gas_contained.return_temperature()) * compressor.gas_contained.total_moles())/4
newrpm = max(0, newrpm)
@@ -333,7 +333,7 @@
data["power"] = DisplayPower(compressor?.turbine?.lastgen)
data["rpm"] = compressor?.rpm
data["temp"] = compressor?.gas_contained.temperature
data["temp"] = compressor?.gas_contained.return_temperature()
return data

View File

@@ -16,7 +16,7 @@
if(T.air)
if(T.initial_gas_mix)
T.air.parse_gas_string(T.initial_gas_mix)
T.temperature = T.air.temperature
T.temperature = T.air.return_temperature()
else
T.air.copy_from_turf(T)
SSair.add_to_active(T)

View File

@@ -271,7 +271,7 @@
if(isopenturf(T))
var/turf/open/OT = T
OT.MakeSlippery(wet_setting=TURF_WET_ICE, min_wet_time=100, wet_time_to_add=reac_volume SECONDS) // Is less effective in high pressure/high heat capacity environments. More effective in low pressure.
OT.air.temperature -= MOLES_CELLSTANDARD*100*reac_volume/OT.air.heat_capacity() // reduces environment temperature by 5K per unit.
OT.air.set_temperature(OT.air.return_temperature() - MOLES_CELLSTANDARD*100*reac_volume/OT.air.heat_capacity()) // reduces environment temperature by 5K per unit.
/datum/reagent/consumable/condensedcapsaicin
name = "Condensed Capsaicin"
@@ -506,7 +506,7 @@
var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T)
if(hotspot)
var/datum/gas_mixture/lowertemp = T.remove_air(T.air.total_moles())
lowertemp.temperature = max( min(lowertemp.temperature-2000,lowertemp.temperature / 2) ,0)
lowertemp.set_temperature(max( min(lowertemp.return_temperature()-2000,lowertemp.return_temperature() / 2) ,0))
lowertemp.react(src)
T.assume_air(lowertemp)
qdel(hotspot)

View File

@@ -263,7 +263,7 @@
if(hotspot && !isspaceturf(T))
if(T.air)
var/datum/gas_mixture/G = T.air
G.temperature = max(min(G.temperature-(CT*1000),G.temperature/CT),TCMB)
G.set_temperature(max(min(G.return_temperature()-(CT*1000),G.return_temperature()/CT),TCMB))
G.react(src)
qdel(hotspot)
var/obj/effect/acid/A = (locate(/obj/effect/acid) in T)

View File

@@ -281,8 +281,8 @@
if(hotspot && !isspaceturf(T))
if(T.air)
var/datum/gas_mixture/G = T.air
if(G.temperature > T20C)
G.temperature = max(G.temperature/2,T20C)
if(G.return_temperature() > T20C)
G.set_temperature(max(G.return_temperature()/2,T20C))
G.react(src)
qdel(hotspot)

View File

@@ -40,7 +40,7 @@
trunk_check()
air_contents = new /datum/gas_mixture()
//gas.volume = 1.05 * CELLSTANDARD
//air_contents.set_volume(1.05 * CELLSTANDARD)
update_icon()
return INITIALIZE_HINT_LATELOAD //we need turfs to have air
@@ -443,8 +443,8 @@
var/datum/gas_mixture/env = L.return_air()
var/pressure_delta = (SEND_PRESSURE*1.01) - air_contents.return_pressure()
if(env.temperature > 0)
var/transfer_moles = 0.1 * pressure_delta*air_contents.volume/(env.temperature * R_IDEAL_GAS_EQUATION)
if(env.return_temperature() > 0)
var/transfer_moles = 0.1 * pressure_delta*air_contents.return_volume()/(env.return_temperature() * R_IDEAL_GAS_EQUATION)
//Actually transfer the gas
var/datum/gas_mixture/removed = env.remove(transfer_moles)

View File

@@ -368,7 +368,7 @@
var/heat_capacity = removed.heat_capacity()
if(heat_capacity == 0 || heat_capacity == null)
heat_capacity = 1
removed.temperature = min((removed.temperature*heat_capacity + 100000)/heat_capacity, 1000)
removed.set_temperature(min((removed.return_temperature()*heat_capacity + 100000)/heat_capacity, 1000))
env.merge(removed)
air_update_turf()
investigate_log("Experimentor has released hot air.", INVESTIGATE_EXPERIMENTOR)
@@ -414,7 +414,7 @@
var/heat_capacity = removed.heat_capacity()
if(heat_capacity == 0 || heat_capacity == null)
heat_capacity = 1
removed.temperature = (removed.temperature*heat_capacity - 75000)/heat_capacity
removed.set_temperature((removed.return_temperature()*heat_capacity - 75000)/heat_capacity)
env.merge(removed)
air_update_turf()
investigate_log("Experimentor has released cold air.", INVESTIGATE_EXPERIMENTOR)

View File

@@ -59,14 +59,14 @@
/obj/machinery/rnd/server/proc/get_env_temp()
var/datum/gas_mixture/environment = loc.return_air()
return environment.temperature
return environment.return_temperature()
/obj/machinery/rnd/server/proc/produce_heat(heat_amt)
if(!(stat & (NOPOWER|BROKEN))) //Blatently stolen from space heater.
var/turf/L = loc
if(istype(L))
var/datum/gas_mixture/env = L.return_air()
if(env.temperature < (heat_amt+T0C))
if(env.return_temperature() < (heat_amt+T0C))
var/transfer_moles = 0.25 * env.total_moles()
@@ -77,7 +77,7 @@
var/heat_capacity = removed.heat_capacity()
if(heat_capacity == 0 || heat_capacity == null)
heat_capacity = 1
removed.temperature = min((removed.temperature*heat_capacity + heating_power)/heat_capacity, 1000)
removed.set_temperature(min((removed.return_temperature()*heat_capacity + heating_power)/heat_capacity, 1000))
env.merge(removed)
air_update_turf()

View File

@@ -100,9 +100,8 @@ Chilling extracts:
for(var/turf/open/T in A)
var/datum/gas_mixture/G = T.air
if(istype(G))
G.gases[/datum/gas/plasma] = 0
G.set_moles(/datum/gas/plasma, 0)
filtered = TRUE
GAS_GARBAGE_COLLECT(G.gases)
T.air_update_turf()
if(filtered)
user.visible_message("<span class='notice'>Cracks spread throughout [src], and some air is sucked in!</span>")
@@ -308,4 +307,4 @@ Chilling extracts:
user.visible_message("<span class='warning'>[src] reflects an array of dazzling colors and light, energy rushing to nearby doors!</span>")
for(var/obj/machinery/door/airlock/door in area)
new /obj/effect/forcefield/slimewall/rainbow(door.loc)
return ..()
return ..()

View File

@@ -133,13 +133,11 @@
var/gas_breathed = 0
var/list/breath_gases = breath.gases
//Partial pressures in our breath
var/O2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/oxygen])+(8*breath.get_breath_partial_pressure(breath_gases[/datum/gas/pluoxium]))
var/N2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/nitrogen])
var/Toxins_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/plasma])
var/CO2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/carbon_dioxide])
var/O2_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/oxygen))+(8*breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/pluoxium)))
var/N2_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/nitrogen))
var/Toxins_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/plasma))
var/CO2_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/carbon_dioxide))
//-- OXY --//
@@ -147,7 +145,7 @@
//Too much oxygen! //Yes, some species may not like it.
if(safe_oxygen_max)
if((O2_pp > safe_oxygen_max) && safe_oxygen_max == 0) //I guess plasma men technically need to have a check.
var/ratio = (breath_gases[/datum/gas/oxygen]/safe_oxygen_max) * 10
var/ratio = (breath.get_moles(/datum/gas/oxygen)/safe_oxygen_max) * 10
H.apply_damage_type(clamp(ratio, oxy_breath_dam_min, oxy_breath_dam_max), oxy_damage_type)
H.throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy)
@@ -170,18 +168,18 @@
//Too little oxygen!
if(safe_oxygen_min)
if(O2_pp < safe_oxygen_min)
gas_breathed = handle_too_little_breath(H, O2_pp, safe_oxygen_min, breath_gases[/datum/gas/oxygen])
gas_breathed = handle_too_little_breath(H, O2_pp, safe_oxygen_min, breath.get_moles(/datum/gas/oxygen))
H.throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy)
else
H.failed_last_breath = FALSE
if(H.health >= H.crit_threshold)
H.adjustOxyLoss(-breathModifier) //More damaged lungs = slower oxy rate up to a factor of half
gas_breathed = breath_gases[/datum/gas/oxygen]
gas_breathed = breath.get_moles(/datum/gas/oxygen)
H.clear_alert("not_enough_oxy")
//Exhale
breath_gases[/datum/gas/oxygen] -= gas_breathed
breath_gases[/datum/gas/carbon_dioxide] += gas_breathed
breath.adjust_moles(/datum/gas/oxygen, -gas_breathed)
breath.adjust_moles(/datum/gas/carbon_dioxide, gas_breathed)
gas_breathed = 0
//-- Nitrogen --//
@@ -189,7 +187,7 @@
//Too much nitrogen!
if(safe_nitro_max)
if(N2_pp > safe_nitro_max)
var/ratio = (breath_gases[/datum/gas/nitrogen]/safe_nitro_max) * 10
var/ratio = (breath.get_moles(/datum/gas/nitrogen)/safe_nitro_max) * 10
H.apply_damage_type(clamp(ratio, nitro_breath_dam_min, nitro_breath_dam_max), nitro_damage_type)
H.throw_alert("too_much_nitro", /obj/screen/alert/too_much_nitro)
H.losebreath += 2
@@ -199,18 +197,18 @@
//Too little nitrogen!
if(safe_nitro_min)
if(N2_pp < safe_nitro_min)
gas_breathed = handle_too_little_breath(H, N2_pp, safe_nitro_min, breath_gases[/datum/gas/nitrogen])
gas_breathed = handle_too_little_breath(H, N2_pp, safe_nitro_min, breath.get_moles(/datum/gas/nitrogen))
H.throw_alert("nitro", /obj/screen/alert/not_enough_nitro)
else
H.failed_last_breath = FALSE
if(H.health >= H.crit_threshold)
H.adjustOxyLoss(-breathModifier)
gas_breathed = breath_gases[/datum/gas/nitrogen]
gas_breathed = breath.get_moles(/datum/gas/nitrogen)
H.clear_alert("nitro")
//Exhale
breath_gases[/datum/gas/nitrogen] -= gas_breathed
breath_gases[/datum/gas/carbon_dioxide] += gas_breathed
breath.adjust_moles(/datum/gas/nitrogen, -gas_breathed)
breath.adjust_moles(/datum/gas/carbon_dioxide, gas_breathed)
gas_breathed = 0
//-- CO2 --//
@@ -236,18 +234,18 @@
//Too little CO2!
if(safe_co2_min)
if(CO2_pp < safe_co2_min)
gas_breathed = handle_too_little_breath(H, CO2_pp, safe_co2_min, breath_gases[/datum/gas/carbon_dioxide])
gas_breathed = handle_too_little_breath(H, CO2_pp, safe_co2_min, breath.get_moles(/datum/gas/carbon_dioxide))
H.throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2)
else
H.failed_last_breath = FALSE
if(H.health >= H.crit_threshold)
H.adjustOxyLoss(-breathModifier)
gas_breathed = breath_gases[/datum/gas/carbon_dioxide]
gas_breathed = breath.get_moles(/datum/gas/carbon_dioxide)
H.clear_alert("not_enough_co2")
//Exhale
breath_gases[/datum/gas/carbon_dioxide] -= gas_breathed
breath_gases[/datum/gas/oxygen] += gas_breathed
breath.adjust_moles(/datum/gas/carbon_dioxide, -gas_breathed)
breath.adjust_moles(/datum/gas/oxygen, gas_breathed)
gas_breathed = 0
@@ -256,7 +254,7 @@
//Too much toxins!
if(safe_toxins_max)
if(Toxins_pp > safe_toxins_max)
var/ratio = (breath_gases[/datum/gas/plasma]/safe_toxins_max) * 10
var/ratio = (breath.get_moles(/datum/gas/plasma)/safe_toxins_max) * 10
H.apply_damage_type(clamp(ratio, tox_breath_dam_min, tox_breath_dam_max), tox_damage_type)
H.throw_alert("too_much_tox", /obj/screen/alert/too_much_tox)
else
@@ -266,18 +264,18 @@
//Too little toxins!
if(safe_toxins_min)
if(Toxins_pp < safe_toxins_min)
gas_breathed = handle_too_little_breath(H, Toxins_pp, safe_toxins_min, breath_gases[/datum/gas/plasma])
gas_breathed = handle_too_little_breath(H, Toxins_pp, safe_toxins_min, breath.get_moles(/datum/gas/plasma))
H.throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox)
else
H.failed_last_breath = FALSE
if(H.health >= H.crit_threshold)
H.adjustOxyLoss(-breathModifier)
gas_breathed = breath_gases[/datum/gas/plasma]
gas_breathed = breath.get_moles(/datum/gas/plasma)
H.clear_alert("not_enough_tox")
//Exhale
breath_gases[/datum/gas/plasma] -= gas_breathed
breath_gases[/datum/gas/carbon_dioxide] += gas_breathed
breath.adjust_moles(/datum/gas/plasma, -gas_breathed)
breath.adjust_moles(/datum/gas/carbon_dioxide, gas_breathed)
gas_breathed = 0
@@ -287,7 +285,7 @@
// N2O
var/SA_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/nitrous_oxide])
var/SA_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/nitrous_oxide))
if(SA_pp > SA_para_min) // Enough to make us stunned for a bit
H.Unconscious(60) // 60 gives them one second to wake up and run away a bit!
if(SA_pp > SA_sleep_min) // Enough to make us sleep as well
@@ -301,7 +299,7 @@
// BZ
var/bz_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/bz])
var/bz_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/bz))
if(bz_pp > BZ_trip_balls_min)
H.hallucination += 10
H.reagents.add_reagent(/datum/reagent/bz_metabolites,5)
@@ -314,14 +312,14 @@
// Tritium
var/trit_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/tritium])
var/trit_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/tritium))
if (trit_pp > 50)
H.radiation += trit_pp/2 //If you're breathing in half an atmosphere of radioactive gas, you fucked up.
else
H.radiation += trit_pp/10
// Nitryl
var/nitryl_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/nitryl])
var/nitryl_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/nitryl))
if (prob(nitryl_pp))
to_chat(H, "<span class='alert'>Your mouth feels like it's burning!</span>")
if (nitryl_pp >40)
@@ -332,22 +330,22 @@
H.silent = max(H.silent, 3)
else
H.adjustFireLoss(nitryl_pp/4)
gas_breathed = breath_gases[/datum/gas/nitryl]
gas_breathed = breath.get_moles(/datum/gas/nitryl)
if (gas_breathed > gas_stimulation_min)
H.reagents.add_reagent(/datum/reagent/nitryl,1)
breath_gases[/datum/gas/nitryl]-=gas_breathed
breath.adjust_moles(/datum/gas/nitryl, -gas_breathed)
// Stimulum
gas_breathed = breath_gases[/datum/gas/stimulum]
gas_breathed = breath.get_moles(/datum/gas/stimulum)
if (gas_breathed > gas_stimulation_min)
var/existing = H.reagents.get_reagent_amount(/datum/reagent/stimulum)
H.reagents.add_reagent(/datum/reagent/stimulum, max(0, 5 - existing))
breath_gases[/datum/gas/stimulum]-=gas_breathed
breath.adjust_moles(/datum/gas/stimulum, -gas_breathed)
// Miasma
if (breath_gases[/datum/gas/miasma])
var/miasma_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/miasma])
if (breath.get_moles(/datum/gas/miasma))
var/miasma_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/miasma))
if(miasma_pp > MINIMUM_MOLES_DELTA_TO_MOVE)
//Miasma sickness
@@ -387,14 +385,13 @@
// Then again, this is a purely hypothetical scenario and hardly reachable
owner.adjust_disgust(0.1 * miasma_pp)
breath_gases[/datum/gas/miasma]-=gas_breathed
breath.adjust_moles(/datum/gas/miasma, -gas_breathed)
// Clear out moods when no miasma at all
else
SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "smell")
handle_breath_temperature(breath, H)
GAS_GARBAGE_COLLECT(breath.gases)
return TRUE
@@ -416,7 +413,7 @@
/obj/item/organ/lungs/proc/handle_breath_temperature(datum/gas_mixture/breath, mob/living/carbon/human/H) // called by human/life, handles temperatures
var/breath_temperature = breath.temperature
var/breath_temperature = breath.return_temperature()
if(!HAS_TRAIT(H, TRAIT_RESISTCOLD)) // COLD DAMAGE
var/cold_modifier = H.dna.species.coldmod
@@ -533,8 +530,8 @@
/obj/item/organ/lungs/slime/check_breath(datum/gas_mixture/breath, mob/living/carbon/human/H)
. = ..()
if (breath && breath.gases[/datum/gas/plasma])
var/plasma_pp = breath.get_breath_partial_pressure(breath.gases[/datum/gas/plasma])
if (breath)
var/plasma_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/plasma))
owner.blood_volume += (0.2 * plasma_pp) // 10/s when breathing literally nothing but plasma, which will suffocate you.
/obj/item/organ/lungs/yamerol

View File

@@ -122,7 +122,7 @@
if(istype(loc, /turf/))//Only concern is adding an organ to a freezer when the area around it is cold.
var/turf/T = loc
var/datum/gas_mixture/enviro = T.return_air()
local_temp = enviro.temperature
local_temp = enviro.return_temperature()
else if(!owner && ismob(loc))
var/mob/M = loc
@@ -132,7 +132,7 @@
return TRUE
var/turf/T = M.loc
var/datum/gas_mixture/enviro = T.return_air()
local_temp = enviro.temperature
local_temp = enviro.return_temperature()
if(owner)
//Don't interfere with bodies frozen by structures.