diff --git a/auxmos.dll b/auxmos.dll
index 34e83aecd7..8090faa086 100644
Binary files a/auxmos.dll and b/auxmos.dll differ
diff --git a/auxmos.pdb b/auxmos.pdb
index aadbd7917e..ce22da81ba 100644
Binary files a/auxmos.pdb and b/auxmos.pdb differ
diff --git a/code/controllers/subsystem/air.dm b/code/controllers/subsystem/air.dm
index bbf477b62c..86af777c44 100644
--- a/code/controllers/subsystem/air.dm
+++ b/code/controllers/subsystem/air.dm
@@ -281,12 +281,23 @@ SUBSYSTEM_DEF(air)
while(deferred_airs.len)
var/list/cur_op = deferred_airs[deferred_airs.len]
deferred_airs.len--
- var/turf/open/T = cur_op[1]
- if(istype(cur_op[2],/datum/gas_mixture))
- T.air.merge(cur_op[2])
- else if(istype(cur_op[2], /datum/callback))
- var/datum/callback/cb = cur_op[2]
- cb.Invoke(T)
+ var/datum/gas_mixture/air1
+ var/datum/gas_mixture/air2
+ if(isopenturf(cur_op[1]))
+ var/turf/open/T = cur_op[1]
+ air1 = T.return_air()
+ else
+ air1 = cur_op[1]
+ if(isopenturf(cur_op[2]))
+ var/turf/open/T = cur_op[2]
+ air2 = T.return_air()
+ else
+ air2 = cur_op[2]
+ if(istype(cur_op[3], /datum/callback))
+ var/datum/callback/cb = cur_op[3]
+ cb.Invoke(air1, air2)
+ else
+ air1.transfer_ratio_to(air2, cur_op[3])
if(MC_TICK_CHECK)
return
diff --git a/code/datums/elements/mob_holder.dm b/code/datums/elements/mob_holder.dm
index fdb292aee1..95334eb5c0 100644
--- a/code/datums/elements/mob_holder.dm
+++ b/code/datums/elements/mob_holder.dm
@@ -179,24 +179,37 @@
return location.loc.assume_air(env)
return location.assume_air(env)
-/obj/item/clothing/head/mob_holder/remove_air(amount)
+/obj/item/clothing/head/mob_holder/proc/get_loc_for_air()
var/atom/location = loc
if(!loc)
- return null
+ return //null
var/turf/T = get_turf(loc)
while(location != T)
location = location.loc
if(ismob(location))
- return location.loc.remove_air(amount)
+ return location.loc
+ return location
+
+/obj/item/clothing/head/mob_holder/assume_air_moles(datum/gas_mixture/env, moles)
+ var/atom/location = get_loc_for_air()
+ return location.assume_air_moles(env, moles)
+
+/obj/item/clothing/head/mob_holder/assume_air_ratio(datum/gas_mixture/env, ratio)
+ var/atom/location = get_loc_for_air()
+ return location.assume_air_ratio(env, ratio)
+
+/obj/item/clothing/head/mob_holder/remove_air(amount)
+ var/atom/location = get_loc_for_air()
return location.remove_air(amount)
/obj/item/clothing/head/mob_holder/remove_air_ratio(ratio)
- var/atom/location = loc
- if(!loc)
- return null
- var/turf/T = get_turf(loc)
- while(location != T)
- location = location.loc
- if(ismob(location))
- return location.loc.remove_air_ratio(ratio)
+ var/atom/location = get_loc_for_air()
return location.remove_air_ratio(ratio)
+
+/obj/item/clothing/head/mob_holder/transfer_air(datum/gas_mixture/taker, amount)
+ var/atom/location = get_loc_for_air()
+ return location.transfer_air(taker, amount)
+
+/obj/item/clothing/head/mob_holder/transfer_air_ratio(datum/gas_mixture/taker, ratio)
+ var/atom/location = get_loc_for_air()
+ return location.transfer_air(taker, ratio)
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index e1dc119930..4cda51dcc8 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -380,12 +380,24 @@
/atom/proc/assume_air(datum/gas_mixture/giver)
return null
+/atom/proc/assume_air_moles(datum/gas_mixture/giver, moles)
+ return null
+
+/atom/proc/assume_air_ratio(datum/gas_mixture/giver, ratio)
+ return null
+
/atom/proc/remove_air(amount)
return null
/atom/proc/remove_air_ratio(ratio)
return null
+/atom/proc/transfer_air(datum/gas_mixture/taker, amount)
+ return null
+
+/atom/proc/transfer_air_ratio(datum/gas_mixture/taker, ratio)
+ return null
+
/atom/proc/return_air()
if(loc)
return loc.return_air()
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index b7ca27eea5..33a89fe7ce 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -203,11 +203,7 @@
equipment.Cut()
cell = null
internal_tank = null
- if(loc)
- loc.assume_air(cabin_air)
- air_update_turf()
- else
- qdel(cabin_air)
+ assume_air(cabin_air)
cabin_air = null
qdel(spark_system)
spark_system = null
@@ -321,13 +317,7 @@
if(internal_damage & MECHA_INT_TANK_BREACH) //remove some air from internal tank
if(internal_tank)
- var/datum/gas_mixture/int_tank_air = internal_tank.return_air()
- var/datum/gas_mixture/leaked_gas = int_tank_air.remove_ratio(0.1)
- if(loc)
- loc.assume_air(leaked_gas)
- air_update_turf()
- else
- qdel(leaked_gas)
+ assume_air_ratio(internal_tank.return_air(), 0.1)
if(internal_damage & MECHA_INT_SHORT_CIRCUIT)
if(get_charge())
@@ -350,8 +340,7 @@
if(pressure_delta > 0) //cabin pressure lower than release pressure
if(tank_air.return_temperature() > 0)
transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION)
- var/datum/gas_mixture/removed = tank_air.remove(transfer_moles)
- cabin_air.merge(removed)
+ tank_air.transfer_to(cabin_air,transfer_moles)
else if(pressure_delta < 0) //cabin pressure higher than release pressure
var/datum/gas_mixture/t_air = return_air()
pressure_delta = cabin_pressure - release_pressure
@@ -359,11 +348,7 @@
pressure_delta = min(cabin_pressure - t_air.return_pressure(), pressure_delta)
if(pressure_delta > 0) //if location pressure is lower than cabin pressure
transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION)
- var/datum/gas_mixture/removed = cabin_air.remove(transfer_moles)
- if(t_air)
- t_air.merge(removed)
- else //just delete the cabin gas, we're in space or some shit
- qdel(removed)
+ cabin_air.transfer_to(t_air, transfer_moles)
if(occupant)
if(cell)
diff --git a/code/game/objects/items/chrono_eraser.dm b/code/game/objects/items/chrono_eraser.dm
index 16bc6897c8..7f2a23fb7c 100644
--- a/code/game/objects/items/chrono_eraser.dm
+++ b/code/game/objects/items/chrono_eraser.dm
@@ -242,7 +242,13 @@
return BULLET_ACT_HIT
/obj/effect/chrono_field/assume_air()
- return 0
+ return null
+
+/obj/effect/chrono_field/assume_air_moles()
+ return null
+
+/obj/effect/chrono_field/assume_air_ratio()
+ return null
/obj/effect/chrono_field/return_air() //we always have nominal air and temperature
var/datum/gas_mixture/GM = new
diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm
index 8b0d46be44..536209b575 100644
--- a/code/game/objects/items/devices/transfer_valve.dm
+++ b/code/game/objects/items/devices/transfer_valve.dm
@@ -172,20 +172,15 @@
if(!target_self)
target.set_volume(target.return_volume() + tank_two.volume)
target.set_volume(target.return_volume() + tank_one.air_contents.return_volume())
- var/datum/gas_mixture/temp
- temp = tank_one.air_contents.remove_ratio(1)
- target.merge(temp)
+ tank_one.air_contents.transfer_ratio_to(target, 1)
if(!target_self)
- temp = tank_two.air_contents.remove_ratio(1)
- target.merge(temp)
+ tank_two.air_contents.transfer_ratio_to(target, 1)
/obj/item/transfer_valve/proc/split_gases()
if (!valve_open || !tank_one || !tank_two)
return
var/ratio1 = tank_one.air_contents.return_volume()/tank_two.air_contents.return_volume()
- var/datum/gas_mixture/temp
- temp = tank_two.air_contents.remove_ratio(ratio1)
- tank_one.air_contents.merge(temp)
+ tank_two.air_contents.transfer_ratio_to(tank_one.air_contents, ratio1)
tank_two.air_contents.set_volume(tank_two.air_contents.return_volume() - tank_one.air_contents.return_volume())
/*
diff --git a/code/game/objects/items/powerfist.dm b/code/game/objects/items/powerfist.dm
index f95acd6018..569b11b8b0 100644
--- a/code/game/objects/items/powerfist.dm
+++ b/code/game/objects/items/powerfist.dm
@@ -79,27 +79,27 @@
var/weight = getweight(user, STAM_COST_ATTACK_MOB_MULT)
if(!user.UseStaminaBuffer(weight, warn = TRUE))
return FALSE
- var/datum/gas_mixture/gasused = tank.air_contents.remove(gasperfist * fisto_setting)
var/turf/T = get_turf(src)
if(!T)
return FALSE
var/totalitemdamage = target.pre_attacked_by(src, user)
- T.assume_air(gasused)
- T.air_update_turf()
- if(!gasused)
+ var/moles_used = gasperfist * fisto_setting
+ if(!moles_used)
to_chat(user, "\The [src]'s tank is empty!")
target.apply_damage((totalitemdamage / 5), BRUTE)
playsound(loc, 'sound/weapons/punch1.ogg', 50, 1)
target.visible_message("[user]'s powerfist lets out a dull thunk as [user.p_they()] punch[user.p_es()] [target.name]!", \
"[user]'s punches you!")
return
- if(gasused.total_moles() < gasperfist * fisto_setting)
+ if(tank.air_contents.total_moles() < moles_used)
to_chat(user, "\The [src]'s piston-ram lets out a weak hiss, it needs more gas!")
playsound(loc, 'sound/weapons/punch4.ogg', 50, 1)
target.apply_damage((totalitemdamage / 2), BRUTE)
target.visible_message("[user]'s powerfist lets out a weak hiss as [user.p_they()] punch[user.p_es()] [target.name]!", \
"[user]'s punch strikes with force!")
return
+ T.assume_air_moles(tank.air_contents, gasperfist * fisto_setting)
+ T.air_update_turf()
target.apply_damage(totalitemdamage * fisto_setting, BRUTE, wound_bonus = -25*fisto_setting**2)
target.visible_message("[user]'s powerfist lets out a loud hiss as [user.p_they()] punch[user.p_es()] [target.name]!", \
"You cry out in pain as [user]'s punch flings you backwards!")
diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm
index 92e0cee7e8..873ac15d56 100644
--- a/code/game/objects/items/tanks/jetpack.dm
+++ b/code/game/objects/items/tanks/jetpack.dm
@@ -77,13 +77,7 @@
turn_off(user)
return
- var/datum/gas_mixture/removed = air_contents.remove(num)
- if(removed.total_moles() < 0.005)
- turn_off(user)
- return
-
- var/turf/T = get_turf(user)
- T.assume_air(removed)
+ assume_air_moles(air_contents, num)
return TRUE
@@ -116,13 +110,7 @@
turn_off(user)
return
- var/datum/gas_mixture/removed = air_contents.remove(num)
- if(removed.total_moles() < 0.005)
- turn_off(user)
- return
-
- var/turf/T = get_turf(user)
- T.assume_air(removed)
+ assume_air_moles(air_contents, num)
return TRUE
diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm
index 01afa9fd66..01da046809 100644
--- a/code/game/objects/items/tanks/tanks.dm
+++ b/code/game/objects/items/tanks/tanks.dm
@@ -249,6 +249,18 @@
check_status()
return 1
+/obj/item/tank/assume_air_moles(datum/gas_mixture/giver, moles)
+ giver.transfer_to(air_contents, moles)
+
+ check_status()
+ return 1
+
+/obj/item/tank/assume_air_ratio(datum/gas_mixture/giver, ratio)
+ giver.transfer_ratio_to(air_contents, ratio)
+
+ check_status()
+ return 1
+
/obj/item/tank/proc/remove_air_volume(volume_to_return)
if(!air_contents)
return null
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index 159e64a55b..a9a891464b 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -96,6 +96,31 @@
else
return null
+/obj/assume_air_moles(datum/gas_mixture/giver, moles)
+ if(loc)
+ return loc.assume_air_moles(giver, moles)
+ else
+ return null
+
+/obj/assume_air_ratio(datum/gas_mixture/giver, ratio)
+ if(loc)
+ return loc.assume_air_ratio(giver, ratio)
+ else
+ return null
+
+/obj/transfer_air(datum/gas_mixture/taker, moles)
+ if(loc)
+ return loc.transfer_air(taker, moles)
+ else
+ return null
+
+/obj/transfer_air_ratio(datum/gas_mixture/taker, ratio)
+ if(loc)
+ return loc.transfer_air_ratio(taker, ratio)
+ else
+ return null
+
+
/obj/remove_air(amount)
if(loc)
return loc.remove_air(amount)
diff --git a/code/game/objects/structures/transit_tubes/station.dm b/code/game/objects/structures/transit_tubes/station.dm
index fb12db04cb..119026a66e 100644
--- a/code/game/objects/structures/transit_tubes/station.dm
+++ b/code/game/objects/structures/transit_tubes/station.dm
@@ -149,9 +149,7 @@
pod_moving = 0
if(!QDELETED(pod))
var/datum/gas_mixture/floor_mixture = loc.return_air()
- var/tot_volume = pod.air_contents.return_volume() + floor_mixture.return_volume()
- pod.air_contents.merge(floor_mixture.remove_ratio(1))
- floor_mixture.merge(pod.air_contents.remove_ratio(floor_mixture.return_volume()/tot_volume))
+ equalize_all_gases_in_list(list(pod.air_contents,floor_mixture))
air_update_turf()
/obj/structure/transit_tube/station/init_tube_dirs()
diff --git a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
index 1de0cdb66c..3ad014da8c 100644
--- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
+++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
@@ -153,12 +153,25 @@
/obj/structure/transit_tube_pod/assume_air(datum/gas_mixture/giver)
return air_contents.merge(giver)
+/obj/structure/transit_tube_pod/assume_air_moles(datum/gas_mixture/giver, moles)
+ return giver.transfer_to(air_contents, moles)
+
+/obj/structure/transit_tube_pod/assume_air_ratio(datum/gas_mixture/giver, ratio)
+ return giver.transfer_ratio_to(air_contents, ratio)
+
/obj/structure/transit_tube_pod/remove_air(amount)
return air_contents.remove(amount)
/obj/structure/transit_tube_pod/remove_air_ratio(ratio)
return air_contents.remove_ratio(ratio)
+/obj/structure/transit_tube_pod/transfer_air(datum/gas_mixture/taker, moles)
+ return air_contents.transfer_to(taker, moles)
+
+/obj/structure/transit_tube_pod/transfer_air_ratio(datum/gas_mixture/taker, ratio)
+ return air_contents.transfer_ratio_to(taker, ratio)
+
+
/obj/structure/transit_tube_pod/relaymove(mob/mob, direction)
if(istype(mob) && mob.client)
if(!moving)
diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm
index 1c814fa193..f7ae61dc96 100644
--- a/code/modules/assembly/bomb.dm
+++ b/code/modules/assembly/bomb.dm
@@ -196,9 +196,8 @@
ground_zero.air_update_turf()
/obj/item/tank/proc/release() //This happens when the bomb is not welded. Tank contents are just spat out.
- var/datum/gas_mixture/removed = air_contents.remove(air_contents.total_moles())
var/turf/T = get_turf(src)
if(!T)
return
- T.assume_air(removed)
+ T.assume_air(air_contents)
air_update_turf()
diff --git a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm
index 43884aa3bc..6b2d0c3c65 100644
--- a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm
+++ b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm
@@ -46,12 +46,45 @@
/////////////////GAS MIXTURE PROCS///////////////////
/turf/open/assume_air(datum/gas_mixture/giver) //use this for machines to adjust air
+ return assume_air_ratio(giver, 1)
+
+/turf/open/assume_air_moles(datum/gas_mixture/giver, moles)
if(!giver)
return FALSE
if(SSair.thread_running())
- SSair.deferred_airs += list(list(src, giver))
+ SSair.deferred_airs += list(list(giver, air, moles / giver.total_moles()))
else
- air.merge(giver)
+ giver.transfer_to(air, moles)
+ update_visuals()
+ return TRUE
+
+/turf/open/assume_air_ratio(datum/gas_mixture/giver, ratio)
+ if(!giver)
+ return FALSE
+ if(SSair.thread_running())
+ SSair.deferred_airs += list(list(giver, air, ratio))
+ else
+ giver.transfer_ratio_to(air, ratio)
+ update_visuals()
+ return TRUE
+
+/turf/open/transfer_air(datum/gas_mixture/taker, moles)
+ if(!taker || !return_air()) // shouldn't transfer from space
+ return FALSE
+ if(SSair.thread_running())
+ SSair.deferred_airs += list(list(air, taker, moles / air.total_moles()))
+ else
+ air.transfer_to(taker, moles)
+ update_visuals()
+ return TRUE
+
+/turf/open/transfer_air_ratio(datum/gas_mixture/taker, ratio)
+ if(!taker || !return_air())
+ return FALSE
+ if(SSair.thread_running())
+ SSair.deferred_airs += list(list(air, taker, ratio))
+ else
+ air.transfer_ratio_to(taker, ratio)
update_visuals()
return TRUE
diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm
index 65e718512c..9e3713ebf2 100644
--- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm
+++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm
@@ -155,7 +155,7 @@ GLOBAL_LIST_INIT(auxtools_atmos_initialized,FALSE)
/datum/gas_mixture/proc/vv_react(datum/holder)
return react(holder)
-/datum/gas_mixture/proc/scrub_into(datum/gas_mixture/target, list/gases)
+/datum/gas_mixture/proc/scrub_into(datum/gas_mixture/target, ratio, list/gases)
/datum/gas_mixture/proc/mark_immutable()
/datum/gas_mixture/proc/get_gases()
/datum/gas_mixture/proc/multiply(factor)
@@ -183,7 +183,9 @@ GLOBAL_LIST_INIT(auxtools_atmos_initialized,FALSE)
/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/transfer_ratio_to(datum/gas_mixture/target, ratio)
+ //Transfers ratio of gas to target. Equivalent to target.merge(remove_ratio(amount)) but faster.
/datum/gas_mixture/proc/remove_ratio(ratio)
//Proportionally removes amount of gas from the gas_mixture
@@ -402,8 +404,7 @@ get_true_breath_pressure(pp) --> gas_pp = pp/breath_pp*total_moles()
var/transfer_moles = pressure_delta*output_air.return_volume()/(input_air.return_temperature() * R_IDEAL_GAS_EQUATION)
//Actually transfer the gas
- var/datum/gas_mixture/removed = input_air.remove(transfer_moles)
- output_air.merge(removed)
+ input_air.transfer_to(output_air, transfer_moles)
return TRUE
return FALSE
diff --git a/code/modules/atmospherics/gasmixtures/zextools_broke.dm b/code/modules/atmospherics/gasmixtures/zextools_broke.dm
index eef6933edb..723336f2a2 100644
--- a/code/modules/atmospherics/gasmixtures/zextools_broke.dm
+++ b/code/modules/atmospherics/gasmixtures/zextools_broke.dm
@@ -56,20 +56,20 @@
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)
+/datum/gas_mixture/scrub_into(datum/gas_mixture/target, ratio, list/gases)
if(isnull(target))
return FALSE
- var/list/removed_gases = target.gases
+ var/list/removed_gases = 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)
+ filtered_gases[gas] = removed_gases[gas] * ratio
+ removed_gases[gas] = removed_gases[gas] * (1 - ratio)
+ target.merge(filtered_out)
/datum/gas_mixture/mark_immutable()
return
/datum/gas_mixture/get_gases()
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm
index 729a6886df..4dd7b672a7 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm
@@ -72,12 +72,7 @@
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
- if(!removed)
- return
-
- loc.assume_air(removed)
+ loc.assume_air_moles(air1, transfer_moles)
air_update_turf()
var/datum/pipeline/parent1 = parents[1]
@@ -93,11 +88,7 @@
moles_delta = min(moles_delta, (input_pressure_min - air2.return_pressure()) * our_multiplier)
if(moles_delta > 0)
- var/datum/gas_mixture/removed = loc.remove_air(moles_delta)
- if (isnull(removed)) // in space
- return
-
- air2.merge(removed)
+ loc.transfer_air(air2, moles_delta)
air_update_turf()
var/datum/pipeline/parent2 = parents[2]
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
index eb00e432b7..dc5a6eccd4 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
@@ -81,9 +81,7 @@
var/pressure_delta = target_pressure - output_starting_pressure
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)
- air2.merge(removed)
+ air1.transfer_to(air2,transfer_moles)
update_parents()
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
index 1b049322a1..46d584339b 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
@@ -67,9 +67,7 @@
var/transfer_ratio = transfer_rate/air1.return_volume()
- var/datum/gas_mixture/removed = air1.remove_ratio(transfer_ratio)
-
- air2.merge(removed)
+ air1.transfer_ratio_to(air2,transfer_ratio)
update_parents()
diff --git a/code/modules/atmospherics/machinery/components/components_base.dm b/code/modules/atmospherics/machinery/components/components_base.dm
index b6911a1709..f8866877fe 100644
--- a/code/modules/atmospherics/machinery/components/components_base.dm
+++ b/code/modules/atmospherics/machinery/components/components_base.dm
@@ -120,14 +120,9 @@
times_lost++
var/shared_loss = lost/times_lost
- var/datum/gas_mixture/to_release
for(var/i in 1 to device_type)
var/datum/gas_mixture/air = airs[i]
- if(!to_release)
- to_release = air.remove(shared_loss)
- continue
- to_release.merge(air.remove(shared_loss))
- T.assume_air(to_release)
+ T.assume_air_moles(air, shared_loss)
air_update_turf(1)
/obj/machinery/atmospherics/components/proc/safe_input(var/title, var/text, var/default_set)
diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
index 11c54409f6..cc1ba7df31 100644
--- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
+++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
@@ -98,11 +98,6 @@
//Actually transfer the gas
if(transfer_ratio > 0)
- var/datum/gas_mixture/removed = air1.remove_ratio(transfer_ratio)
-
- if(!removed)
- return
-
var/filtering = TRUE
if(!ispath(filter_type))
if(filter_type)
@@ -110,21 +105,10 @@
else
filtering = FALSE
- if(filtering && removed.get_moles(filter_type))
- var/datum/gas_mixture/filtered_out = new
-
- filtered_out.set_temperature(removed.return_temperature())
- filtered_out.set_moles(filter_type, removed.get_moles(filter_type))
-
- removed.set_moles(filter_type, 0)
-
- var/datum/gas_mixture/target = (air2.return_pressure() < 9000 ? air2 : air1)
- target.merge(filtered_out)
-
- if(air3.return_pressure() <= 9000)
- air3.merge(removed)
- else
- air1.merge(removed) // essentially just leaving it in
+ if(filtering && air3.return_pressure() <= 9000)
+ air1.scrub_into(air3, transfer_ratio, list(filter_type))
+ if(air2.return_pressure() <= 9000)
+ air1.transfer_ratio_to(air2, transfer_ratio)
update_parents()
diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
index 7dac6d540e..3296981e5e 100644
--- a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
+++ b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
@@ -110,14 +110,12 @@
//Actually transfer the gas
if(transfer_moles1)
- var/datum/gas_mixture/removed1 = air1.remove(transfer_moles1)
- air3.merge(removed1)
+ air1.transfer_to(air3, transfer_moles1)
var/datum/pipeline/parent1 = parents[1]
parent1.update = TRUE
if(transfer_moles2)
- var/datum/gas_mixture/removed2 = air2.remove(transfer_moles2)
- air3.merge(removed2)
+ air2.transfer_to(air3, transfer_moles2)
var/datum/pipeline/parent2 = parents[2]
parent2.update = TRUE
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm
index 477c72a8d9..b2fa26edba 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm
@@ -66,11 +66,7 @@
var/datum/gas_mixture/air_contents = airs[1]
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)
+ loc.assume_air_ratio(air_contents, volume_rate / air_contents.return_volume())
air_update_turf()
update_parents()
@@ -85,9 +81,7 @@
injecting = 1
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)
+ loc.assume_air_ratio(air_contents, volume_rate / air_contents.return_volume())
update_parents()
flick("inje_inject", src)
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/relief_valve.dm b/code/modules/atmospherics/machinery/components/unary_devices/relief_valve.dm
index d427a1abc3..ee4223b157 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/relief_valve.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/relief_valve.dm
@@ -50,14 +50,11 @@
else if(!opened && our_pressure >= open_pressure)
opened = TRUE
update_icon_nopipes()
- if(opened && air_contents.return_temperature() > 0)
+ if(opened)
var/datum/gas_mixture/environment = loc.return_air()
- var/pressure_delta = our_pressure - environment.return_pressure()
- 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)
-
- loc.assume_air(removed)
+ var/pressure_delta = abs(our_pressure - environment.return_pressure())
+ if(pressure_delta > 0.1)
+ equalize_all_gases_in_list(list(air_contents,environment))
air_update_turf()
update_parents()
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm
index e682b9160c..1a53a5299f 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm
@@ -109,9 +109,7 @@
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)
-
- loc.assume_air(removed)
+ loc.assume_air_moles(air_contents, transfer_moles)
air_update_turf()
else // external -> internal
@@ -124,11 +122,7 @@
moles_delta = min(moles_delta, (internal_pressure_bound - air_contents.return_pressure()) * our_multiplier)
if(moles_delta > 0)
- var/datum/gas_mixture/removed = loc.remove_air(moles_delta)
- if (isnull(removed)) // in space
- return
-
- air_contents.merge(removed)
+ loc.transfer_air(air_contents, moles_delta)
air_update_turf()
update_parents()
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
index 6192c904c4..502b958525 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
@@ -152,28 +152,17 @@
var/datum/gas_mixture/environment = tile.return_air()
var/datum/gas_mixture/air_contents = airs[1]
- if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE)
+ if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE || !islist(filter_types))
return FALSE
if(scrubbing & SCRUBBING)
- //Take a gas sample
- var/datum/gas_mixture/removed = tile.remove_air_ratio(volume_rate/environment.return_volume())
+ environment.scrub_into(air_contents, volume_rate/environment.return_volume(), filter_types)
- //Nothing left to remove from the tile
- if(isnull(removed))
- return FALSE
-
- removed.scrub_into(air_contents, filter_types)
-
- //Remix the resulting gases
- tile.assume_air(removed)
tile.air_update_turf()
else //Just siphoning all air
- var/datum/gas_mixture/removed = tile.remove_air_ratio((volume_rate/environment.return_volume()))
-
- air_contents.merge(removed)
+ environment.transfer_ratio_to(air_contents, volume_rate/environment.return_volume())
tile.air_update_turf()
update_parents()
diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm
index a287856db1..6d5fb7d478 100644
--- a/code/modules/atmospherics/machinery/portable/canister.dm
+++ b/code/modules/atmospherics/machinery/portable/canister.dm
@@ -287,9 +287,8 @@
/obj/machinery/portable_atmospherics/canister/proc/canister_break()
disconnect()
- var/datum/gas_mixture/expelled_gas = air_contents.remove(air_contents.total_moles())
var/turf/T = get_turf(src)
- T.assume_air(expelled_gas)
+ T.assume_air(air_contents)
air_update_turf()
obj_break()
diff --git a/code/modules/atmospherics/machinery/portable/scrubber.dm b/code/modules/atmospherics/machinery/portable/scrubber.dm
index 037e7fe1a1..08b181230f 100644
--- a/code/modules/atmospherics/machinery/portable/scrubber.dm
+++ b/code/modules/atmospherics/machinery/portable/scrubber.dm
@@ -42,12 +42,7 @@
scrub(T.return_air())
/obj/machinery/portable_atmospherics/scrubber/proc/scrub(var/datum/gas_mixture/mixture)
- var/datum/gas_mixture/filtering = mixture.remove_ratio(volume_rate / mixture.return_volume()) // Remove part of the mixture to filter.
- if(!filtering)
- return
-
- filtering.scrub_into(air_contents,scrubbing)
- mixture.merge(filtering) // Returned the cleaned gas.
+ mixture.scrub_into(air_contents, volume_rate / mixture.return_volume(), scrubbing)
if(!holding)
air_update_turf()
diff --git a/code/modules/hydroponics/grown/misc.dm b/code/modules/hydroponics/grown/misc.dm
index 74b5c19b88..9cadff9873 100644
--- a/code/modules/hydroponics/grown/misc.dm
+++ b/code/modules/hydroponics/grown/misc.dm
@@ -58,7 +58,7 @@
return
var/datum/gas_mixture/stank = new
- 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.adjust_moles(/datum/gas/miasma,(yield + 6)*0.14) // 0.14 = 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()
diff --git a/code/modules/integrated_electronics/subtypes/atmospherics.dm b/code/modules/integrated_electronics/subtypes/atmospherics.dm
index d449775bd1..e7b0f27b27 100644
--- a/code/modules/integrated_electronics/subtypes/atmospherics.dm
+++ b/code/modules/integrated_electronics/subtypes/atmospherics.dm
@@ -131,11 +131,10 @@
var/pressure_delta = target_pressure - target_air.return_pressure()
if(pressure_delta > 0.1)
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)
if(istype(snowflake)) //Snowflake check for tanks specifically, because tank ruptures are handled in a very snowflakey way that expects all tank interactions to be handled via the tank's procs
- snowflake.assume_air(removed)
+ snowflake.assume_air_moles(source_air, transfer_moles)
else
- target_air.merge(removed)
+ source_air.transfer_to(target_air, transfer_moles)
// - volume pump - // **Works**
@@ -183,12 +182,10 @@
//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.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)
-
if(istype(snowflake))
- snowflake.assume_air(removed)
+ snowflake.assume_air_ratio(source_air, transfer_ratio * PUMP_EFFICIENCY)
else
- target_air.merge(removed)
+ source_air.transfer_ratio_to(target_air, transfer_ratio * PUMP_EFFICIENCY)
// - gas vent - // **works**
@@ -468,16 +465,12 @@
var/snowflakecheck = istype(gas_output, /obj/item/tank)
- var/datum/gas_mixture/mix = source_1_gases.remove(transfer_moles * gas_percentage)
if(snowflakecheck)
- gas_output.assume_air(mix)
+ gas_output.assume_air_moles(source_1_gases, transfer_moles * gas_percentage)
+ gas_output.assume_air_moles(source_2_gases, transfer_moles * (1-gas_percentage))
else
- output_gases.merge(mix)
- mix = source_2_gases.remove(transfer_moles * (1-gas_percentage))
- if(snowflakecheck)
- gas_output.assume_air(mix)
- else
- output_gases.merge(mix)
+ source_1_gases.transfer_to(output_gases, transfer_moles * gas_percentage)
+ source_2_gases.transfer_to(output_gases, transfer_moles * (1-gas_percentage))
// - integrated tank - // **works**
diff --git a/code/modules/integrated_electronics/subtypes/weaponized.dm b/code/modules/integrated_electronics/subtypes/weaponized.dm
index 25fa7058fb..54b14cccbc 100644
--- a/code/modules/integrated_electronics/subtypes/weaponized.dm
+++ b/code/modules/integrated_electronics/subtypes/weaponized.dm
@@ -292,10 +292,7 @@
if(!source_air || !target_air)
return
- var/datum/gas_mixture/removed = source_air.remove(gas_per_throw)
- if(!removed)
- return
- target_air.merge(removed)
+ source_air.transfer_to(target_air, gas_per_throw)
// If the item is in a grabber circuit we'll update the grabber's outputs after we've thrown it.
var/obj/item/integrated_circuit/manipulation/grabber/G = A.loc
diff --git a/code/modules/power/turbine.dm b/code/modules/power/turbine.dm
index bb92da2f4f..dda7f27eee 100644
--- a/code/modules/power/turbine.dm
+++ b/code/modules/power/turbine.dm
@@ -131,8 +131,7 @@
// It's a simplified version taking only 1/10 of the moles from the turf nearby. It should be later changed into a better version
// above todo 7 years and counting
- var/datum/gas_mixture/removed = inturf.remove_air_ratio(0.1)
- gas_contained.merge(removed)
+ inturf.transfer_air_ratio(gas_contained, 0.1)
// RPM function to include compression friction - be advised that too low/high of a compfriction value can make things screwy
@@ -219,8 +218,7 @@
if(compressor.gas_contained.total_moles()>0)
var/oamount = min(compressor.gas_contained.total_moles(), (compressor.rpm+100)/35000*compressor.capacity)
- var/datum/gas_mixture/removed = compressor.gas_contained.remove(oamount)
- outturf.assume_air(removed)
+ outturf.assume_air_moles(compressor.gas_contained, oamount)
// If it works, put an overlay that it works!
diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm
index 303fd981fb..90082c464b 100644
--- a/code/modules/reagents/chemistry/reagents/food_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm
@@ -524,10 +524,9 @@
T.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = reac_volume*2 SECONDS)
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.set_temperature(max( min(lowertemp.return_temperature()-2000,lowertemp.return_temperature() / 2) ,0))
+ var/datum/gas_mixture/lowertemp = T.return_air()
+ lowertemp.set_temperature(max( min(lowertemp.return_temperature()-2000,lowertemp.return_temperature() / 2) ,TCMB))
lowertemp.react(src)
- T.assume_air(lowertemp)
qdel(hotspot)
/datum/reagent/consumable/enzyme
diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm
index 67af26e468..e6128ed5c2 100644
--- a/code/modules/research/experimentor.dm
+++ b/code/modules/research/experimentor.dm
@@ -362,14 +362,7 @@
else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff))
visible_message("[src] malfunctions, melting [exp_on] and leaking hot air!")
var/datum/gas_mixture/env = loc.return_air()
- var/transfer_moles = 0.25 * env.total_moles()
- var/datum/gas_mixture/removed = env.remove(transfer_moles)
- if(removed)
- var/heat_capacity = removed.heat_capacity()
- if(heat_capacity == 0 || heat_capacity == null)
- heat_capacity = 1
- removed.set_temperature(min((removed.return_temperature()*heat_capacity + 100000)/heat_capacity, 1000))
- env.merge(removed)
+ env.adjust_heat(100000)
air_update_turf()
investigate_log("Experimentor has released hot air.", INVESTIGATE_EXPERIMENTOR)
ejectItem(TRUE)
@@ -408,14 +401,7 @@
else if(prob(EFFECT_PROB_LOW-badThingCoeff))
visible_message("[src] malfunctions, shattering [exp_on] and leaking cold air!")
var/datum/gas_mixture/env = loc.return_air()
- var/transfer_moles = 0.25 * env.total_moles()
- var/datum/gas_mixture/removed = env.remove(transfer_moles)
- if(removed)
- var/heat_capacity = removed.heat_capacity()
- if(heat_capacity == 0 || heat_capacity == null)
- heat_capacity = 1
- removed.set_temperature((removed.return_temperature()*heat_capacity - 75000)/heat_capacity)
- env.merge(removed)
+ env.adjust_heat(-75000)
air_update_turf()
investigate_log("Experimentor has released cold air.", INVESTIGATE_EXPERIMENTOR)
ejectItem(TRUE)
diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm
index 657d3b2e12..beb3561025 100644
--- a/code/modules/research/server.dm
+++ b/code/modules/research/server.dm
@@ -7,12 +7,11 @@
circuit = /obj/item/circuitboard/machine/rdserver
var/datum/techweb/stored_research
- var/heat_health = 100
//Code for point mining here.
var/working = TRUE //temperature should break it.
var/server_id = 0
var/base_mining_income = 2
- var/heat_gen = 100
+ var/heat_gen = 1
var/heating_power = 40000
var/delay = 5
var/temp_tolerance_low = 0
@@ -32,7 +31,7 @@
var/tot_rating = 0
for(var/obj/item/stock_parts/SP in src)
tot_rating += SP.rating
- heat_gen /= max(1, tot_rating)
+ heat_gen = initial(src.heat_gen) / max(1, tot_rating)
/obj/machinery/rnd/server/proc/refresh_working()
if(stat & EMPED)
@@ -56,31 +55,19 @@
. = base_mining_income
var/penalty = max((get_env_temp() - temp_tolerance_high), 0) * temp_penalty_coefficient
. = max(. - penalty, 0)
+ produce_heat(. / base_mining_income)
/obj/machinery/rnd/server/proc/get_env_temp()
var/datum/gas_mixture/environment = loc.return_air()
return environment.return_temperature()
-/obj/machinery/rnd/server/proc/produce_heat(heat_amt)
+/obj/machinery/rnd/server/proc/produce_heat(perc)
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.return_temperature() < (heat_amt+T0C))
-
- var/transfer_moles = 0.25 * env.total_moles()
-
- var/datum/gas_mixture/removed = env.remove(transfer_moles)
-
- if(removed)
-
- var/heat_capacity = removed.heat_capacity()
- if(heat_capacity == 0 || heat_capacity == null)
- heat_capacity = 1
- removed.set_temperature(min((removed.return_temperature()*heat_capacity + heating_power)/heat_capacity, 1000))
-
- env.merge(removed)
- air_update_turf()
+ env.adjust_heat(heating_power * perc * heat_gen)
+ air_update_turf()
/proc/fix_noid_research_servers()
var/list/no_id_servers = list()
diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm
index ea8c188346..e1b198ade2 100644
--- a/code/modules/surgery/organs/augments_chest.dm
+++ b/code/modules/surgery/organs/augments_chest.dm
@@ -210,13 +210,9 @@
// Priority 3: use internals tank.
var/obj/item/tank/I = owner.internal
- if(I && I.air_contents && I.air_contents.total_moles() > num)
- var/datum/gas_mixture/removed = I.air_contents.remove(num)
- if(removed.total_moles() > 0.005)
- T.assume_air(removed)
- return 1
- else
- T.assume_air(removed)
+ if(I && I.air_contents && I.air_contents.total_moles() >= num)
+ T.assume_air_moles(I.air_contents, num)
+ return 1
toggle(silent = TRUE)
return 0