diff --git a/baystation12.dme b/baystation12.dme index 22b3d97333a..8bbc8b813b8 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1517,6 +1517,11 @@ #include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_dnaswitch.dm" #include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_emp.dm" #include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_forcefield.dm" +#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_gasco2.dm" +#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_gasnitro.dm" +#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_gasoxy.dm" +#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_gasplasma.dm" +#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_gassleeping.dm" #include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_goodfeeling.dm" #include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_heal.dm" #include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_heat.dm" @@ -1689,7 +1694,6 @@ #include "code\WorkInProgress\SkyMarshal\officer_stuff.dm" #include "code\WorkInProgress\SkyMarshal\Ultralight_procs.dm" #include "code\ZAS\_docs.dm" -#include "code\ZAS\_gas_datum.dm" #include "code\ZAS\_gas_mixture.dm" #include "code\ZAS\Airflow.dm" #include "code\ZAS\Atom.dm" diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm index 4460d6a1a20..fa8b485ed8c 100644 --- a/code/ATMOSPHERICS/atmospherics.dm +++ b/code/ATMOSPHERICS/atmospherics.dm @@ -155,7 +155,7 @@ Pipelines + Other Objects -> Pipe network var/datum/gas_mixture/int_air = return_air() var/datum/gas_mixture/env_air = loc.return_air() add_fingerprint(user) - if ((int_air.pressure-env_air.pressure) > 2*ONE_ATMOSPHERE) + if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE) if(istype(W, /obj/item/weapon/wrench/socket) && istype(src, /obj/machinery/atmospherics/pipe)) user << "You begin to open the pressure release valve on the pipe..." if(do_after(user, 50)) diff --git a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm index c9929c2938d..9dc885c9f63 100644 --- a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm +++ b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm @@ -31,8 +31,8 @@ air1 = new air2 = new - air1.set_volume(200) - air2.set_volume(200) + air1.volume = 200 + air2.volume = 200 /obj/machinery/atmospherics/binary/buildFrom(var/mob/usr,var/obj/item/pipe/pipe) dir = pipe.dir diff --git a/code/ATMOSPHERICS/components/binary_devices/circulator.dm b/code/ATMOSPHERICS/components/binary_devices/circulator.dm index 3852918de5b..c3e27234cbc 100644 --- a/code/ATMOSPHERICS/components/binary_devices/circulator.dm +++ b/code/ATMOSPHERICS/components/binary_devices/circulator.dm @@ -25,8 +25,8 @@ /obj/machinery/atmospherics/binary/circulator/proc/return_transfer_air() var/datum/gas_mixture/removed if(anchored && !(stat&BROKEN) ) - var/input_starting_pressure = air1.pressure - var/output_starting_pressure = air2.pressure + var/input_starting_pressure = air1.return_pressure() + var/output_starting_pressure = air2.return_pressure() last_pressure_delta = max(input_starting_pressure - output_starting_pressure + 10, 0) //only circulate air if there is a pressure difference (plus 10 kPa to represent friction in the machine) @@ -38,7 +38,7 @@ //Actually transfer the gas removed = air1.remove(recent_moles_transferred) if(removed) - last_heat_capacity = removed.heat_capacity + last_heat_capacity = removed.heat_capacity() last_temperature = removed.temperature //Update the gas networks. diff --git a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm index 39ad99628b8..4dc3f31a817 100644 --- a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm @@ -25,8 +25,6 @@ var/frequency = 0 var/id_tag = null var/datum/radio_frequency/radio_connection - - machine_flags = MULTITOOL_MENU /obj/machinery/atmospherics/binary/dp_vent_pump/high_volume name = "Large Dual Port Air Vent" @@ -34,8 +32,8 @@ /obj/machinery/atmospherics/binary/dp_vent_pump/high_volume/New() ..() - air1.set_volume(1000) - air2.set_volume(1000) + air1.volume = 1000 + air2.volume = 1000 /obj/machinery/atmospherics/binary/dp_vent_pump/update_icon() if(on) @@ -75,7 +73,7 @@ return var/datum/gas_mixture/environment = loc.return_air() - var/environment_pressure = environment.pressure + var/environment_pressure = environment.return_pressure() if(pump_direction) //input -> external var/pressure_delta = 10000 @@ -83,7 +81,7 @@ if(pressure_checks&1) pressure_delta = min(pressure_delta, (external_pressure_bound - environment_pressure)) if(pressure_checks&2) - pressure_delta = min(pressure_delta, (air1.pressure - input_pressure_min)) + pressure_delta = min(pressure_delta, (air1.return_pressure() - input_pressure_min)) if(pressure_delta > 0) if(air1.temperature > 0) @@ -102,7 +100,7 @@ if(pressure_checks&1) pressure_delta = min(pressure_delta, (environment_pressure - external_pressure_bound)) if(pressure_checks&4) - pressure_delta = min(pressure_delta, (output_pressure_max - air2.pressure)) + pressure_delta = min(pressure_delta, (output_pressure_max - air2.return_pressure())) if(pressure_delta > 0) if(environment.temperature > 0) @@ -220,6 +218,9 @@ update_icon() /obj/machinery/atmospherics/binary/dp_vent_pump/attackby(var/obj/item/W as obj, var/mob/user as mob) + if(istype(W, /obj/item/device/multitool)) + interact(user) + return 1 return ..() /obj/machinery/atmospherics/binary/dp_vent_pump/interact(var/mob/user) diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm index 9c6839ad1a2..c8827405ef3 100644 --- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm +++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm @@ -33,8 +33,8 @@ if(!on) return - var/output_starting_pressure = air2.pressure - var/input_starting_pressure = air1.pressure + var/output_starting_pressure = air2.return_pressure() + var/input_starting_pressure = air1.return_pressure() if(output_starting_pressure >= min(target_pressure,input_starting_pressure-10)) //No need to pump gas if target is already reached or input pressure is too low @@ -42,7 +42,7 @@ return //Calculate necessary moles to transfer using PV = nRT - if((air1.total_moles > 0) && (air1.temperature>0)) + if((air1.total_moles() > 0) && (air1.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 diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm index 1830c294fed..23c25451c1d 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm @@ -55,14 +55,14 @@ Thus, the two variables affect pump operation are set in New(): if((stat & (NOPOWER|BROKEN)) || !on) return - var/output_starting_pressure = air2.pressure + var/output_starting_pressure = air2.return_pressure() if( (target_pressure - output_starting_pressure) < 0.01) //No need to pump gas if target is already reached! return //Calculate necessary moles to transfer using PV=nRT - if((air1.total_moles > 0) && (air1.temperature>0)) + if((air1.total_moles() > 0) && (air1.temperature>0)) var/pressure_delta = target_pressure - output_starting_pressure var/transfer_moles = pressure_delta*air2.volume/(air1.temperature * R_IDEAL_GAS_EQUATION) diff --git a/code/ATMOSPHERICS/components/binary_devices/valve.dm b/code/ATMOSPHERICS/components/binary_devices/valve.dm index e1317d6cc36..f5033654b7b 100644 --- a/code/ATMOSPHERICS/components/binary_devices/valve.dm +++ b/code/ATMOSPHERICS/components/binary_devices/valve.dm @@ -116,8 +116,6 @@ var/frequency = 0 var/id_tag = null var/datum/radio_frequency/radio_connection - - machine_flags = MULTITOOL_MENU /obj/machinery/atmospherics/binary/valve/digital/attack_ai(mob/user as mob) src.add_hiddenprint(user) @@ -216,6 +214,9 @@ // Just for digital valves. /obj/machinery/atmospherics/binary/valve/digital/attackby(var/obj/item/W as obj, var/mob/user as mob) + if(istype(W, /obj/item/device/multitool)) + update_multitool_menu(user) + return 1 if(src.frequency && istype(W, /obj/item/weapon/wrench)) user << "You cannot unwrench this [src], it's digitally connected to another device." return 1 diff --git a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm index 5fe5a558583..84c7236ee04 100644 --- a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm @@ -51,8 +51,8 @@ Thus, the two variables affect pump operation are set in New(): // Pump mechanism just won't do anything if the pressure is too high/too low - var/input_starting_pressure = air1.pressure - var/output_starting_pressure = air2.pressure + var/input_starting_pressure = air1.return_pressure() + var/output_starting_pressure = air2.return_pressure() if((input_starting_pressure < 0.01) || (output_starting_pressure > 9000)) return diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm index 5fe3d6b893e..c499b4f2c64 100755 --- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm @@ -58,9 +58,9 @@ obj/machinery/atmospherics/trinary/filter/process() if(!on) return - var/output_starting_pressure = air3.pressure + var/output_starting_pressure = air3.return_pressure() - if(output_starting_pressure >= target_pressure || air2.pressure >= target_pressure ) + if(output_starting_pressure >= target_pressure || air2.return_pressure() >= target_pressure ) //No need to mix if target is already full! return @@ -80,32 +80,41 @@ obj/machinery/atmospherics/trinary/filter/process() if(!removed) return var/datum/gas_mixture/filtered_out = new - filtered_out.set_temperature(removed.temperature) - - var/list/gases_to_remove + filtered_out.temperature = removed.temperature switch(filter_type) if(0) //removing hydrocarbons - gases_to_remove = list(PLASMA /*, OXYGEN_AGENT_B*/) + filtered_out.toxins = removed.toxins + removed.toxins = 0 + + if(removed.trace_gases.len>0) + for(var/datum/gas/trace_gas in removed.trace_gases) + if(istype(trace_gas, /datum/gas/oxygen_agent_b)) + removed.trace_gases -= trace_gas + filtered_out.trace_gases += trace_gas if(1) //removing O2 - gases_to_remove = list(OXYGEN) + filtered_out.oxygen = removed.oxygen + removed.oxygen = 0 if(2) //removing N2 - gases_to_remove = list(NITROGEN) + filtered_out.nitrogen = removed.nitrogen + removed.nitrogen = 0 if(3) //removing CO2 - gases_to_remove = list(CARBON_DIOXIDE) + filtered_out.carbon_dioxide = removed.carbon_dioxide + removed.carbon_dioxide = 0 if(4)//removing N2O - gases_to_remove = list(NITROUS_OXIDE) + if(removed.trace_gases.len>0) + for(var/datum/gas/trace_gas in removed.trace_gases) + if(istype(trace_gas, /datum/gas/sleeping_agent)) + removed.trace_gases -= trace_gas + filtered_out.trace_gases += trace_gas else filtered_out = null - for(var/gasid in gases_to_remove) - filtered_out.adjust_gas(gasid, removed.gases[gasid]) - removed.set_gas(gasid, 0) air2.merge(filtered_out) air3.merge(removed) diff --git a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm index 0d1ed051c61..a1975011d7c 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm @@ -33,14 +33,14 @@ obj/machinery/atmospherics/trinary/mixer/power_change() obj/machinery/atmospherics/trinary/mixer/New() ..() - air3.set_volume(300) + air3.volume = 300 obj/machinery/atmospherics/trinary/mixer/process() . = ..() if(!on) return - var/output_starting_pressure = air3.pressure + var/output_starting_pressure = air3.return_pressure() if(output_starting_pressure >= target_pressure) //No need to mix if target is already full! @@ -58,8 +58,8 @@ obj/machinery/atmospherics/trinary/mixer/process() if(air2.temperature > 0) transfer_moles2 = (node2_concentration*pressure_delta)*air3.volume/(air2.temperature * R_IDEAL_GAS_EQUATION) - var/air1_moles = air1.total_moles - var/air2_moles = air2.total_moles + var/air1_moles = air1.total_moles() + var/air2_moles = air2.total_moles() if((air1_moles < transfer_moles1) || (air2_moles < transfer_moles2)) if(!transfer_moles1 || !transfer_moles2) return diff --git a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm index b394387ad1c..5dccfd5cecb 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm @@ -24,9 +24,9 @@ obj/machinery/atmospherics/trinary/New() air2 = new air3 = new - air1.set_volume(starting_volume) - air2.set_volume(starting_volume) - air3.set_volume(starting_volume) + air1.volume = starting_volume + air2.volume = starting_volume + air3.volume = starting_volume /obj/machinery/atmospherics/trinary/proc/initialize_directions() switch(dir) diff --git a/code/ATMOSPHERICS/components/unary/cold_sink.dm b/code/ATMOSPHERICS/components/unary/cold_sink.dm index a12a38900f0..ebe794ba8b2 100644 --- a/code/ATMOSPHERICS/components/unary/cold_sink.dm +++ b/code/ATMOSPHERICS/components/unary/cold_sink.dm @@ -26,13 +26,14 @@ . = ..() if(!on || !network) return - var/combined_heat_capacity = current_heat_capacity + air_contents.heat_capacity + var/air_heat_capacity = air_contents.heat_capacity() + var/combined_heat_capacity = current_heat_capacity + air_heat_capacity var/old_temperature = air_contents.temperature if(combined_heat_capacity > 0) - var/combined_energy = current_temperature*current_heat_capacity + air_contents.thermal_energy() + var/combined_energy = current_temperature*current_heat_capacity + air_heat_capacity*air_contents.temperature if(air_contents.temperature > current_temperature) //if it's hotter than we can cool it, cool it - air_contents.set_temperature(combined_energy/combined_heat_capacity) + air_contents.temperature = combined_energy/combined_heat_capacity //todo: have current temperature affected. require power to bring down current temperature again diff --git a/code/ATMOSPHERICS/components/unary/heat_exchanger.dm b/code/ATMOSPHERICS/components/unary/heat_exchanger.dm index 5d6ddd21b1b..82ddb66a70e 100644 --- a/code/ATMOSPHERICS/components/unary/heat_exchanger.dm +++ b/code/ATMOSPHERICS/components/unary/heat_exchanger.dm @@ -35,20 +35,22 @@ if(!partner || !air_master || air_master.current_cycle <= update_cycle) return - var/old_temperature = partner.air_contents.temperature - var/other_old_temperature = air_contents.temperature - update_cycle = air_master.current_cycle partner.update_cycle = air_master.current_cycle - var/combined_heat_capacity = partner.air_contents.heat_capacity + air_contents.heat_capacity + var/air_heat_capacity = air_contents.heat_capacity() + 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 if(combined_heat_capacity > 0) - var/combined_energy = partner.air_contents.thermal_energy() + air_contents.thermal_energy() + var/combined_energy = partner.air_contents.temperature*other_air_heat_capacity + air_heat_capacity*air_contents.temperature var/new_temperature = combined_energy/combined_heat_capacity - air_contents.set_temperature(new_temperature) - partner.air_contents.set_temperature(new_temperature) + air_contents.temperature = new_temperature + partner.air_contents.temperature = new_temperature if(network) if(abs(old_temperature-air_contents.temperature) > 1) diff --git a/code/ATMOSPHERICS/components/unary/heat_source.dm b/code/ATMOSPHERICS/components/unary/heat_source.dm index 6c8c02034c3..f95e457cda9 100644 --- a/code/ATMOSPHERICS/components/unary/heat_source.dm +++ b/code/ATMOSPHERICS/components/unary/heat_source.dm @@ -28,13 +28,14 @@ . = ..() if(!on) return - var/combined_heat_capacity = current_heat_capacity + air_contents.heat_capacity + var/air_heat_capacity = air_contents.heat_capacity() + var/combined_heat_capacity = current_heat_capacity + air_heat_capacity var/old_temperature = air_contents.temperature if(combined_heat_capacity > 0) - var/combined_energy = current_temperature*current_heat_capacity + air_contents.thermal_energy() + var/combined_energy = current_temperature*current_heat_capacity + air_heat_capacity*air_contents.temperature if(air_contents.temperature < current_temperature) //if its colder than we can heat it, heat it - air_contents.set_temperature(combined_energy/combined_heat_capacity) + air_contents.temperature = combined_energy/combined_heat_capacity //todo: have current temperature affected. require power to bring up current temperature again diff --git a/code/ATMOSPHERICS/components/unary/outlet_injector.dm b/code/ATMOSPHERICS/components/unary/outlet_injector.dm index b7c0d3fdc6e..16a4c47626f 100644 --- a/code/ATMOSPHERICS/components/unary/outlet_injector.dm +++ b/code/ATMOSPHERICS/components/unary/outlet_injector.dm @@ -17,8 +17,6 @@ var/datum/radio_frequency/radio_connection level = 1 - - machine_flags = MULTITOOL_MENU /obj/machinery/atmospherics/unary/outlet_injector/update_icon() if(node) @@ -47,7 +45,7 @@ return if(air_contents.temperature > 0) - var/transfer_moles = (air_contents.pressure)*volume_rate/(air_contents.temperature * R_IDEAL_GAS_EQUATION) + var/transfer_moles = (air_contents.return_pressure())*volume_rate/(air_contents.temperature * R_IDEAL_GAS_EQUATION) var/datum/gas_mixture/removed = air_contents.remove(transfer_moles) @@ -65,7 +63,7 @@ injecting = 1 if(air_contents.temperature > 0) - var/transfer_moles = (air_contents.pressure)*volume_rate/(air_contents.temperature * R_IDEAL_GAS_EQUATION) + var/transfer_moles = (air_contents.return_pressure())*volume_rate/(air_contents.temperature * R_IDEAL_GAS_EQUATION) var/datum/gas_mixture/removed = air_contents.remove(transfer_moles) @@ -160,6 +158,9 @@ "} /obj/machinery/atmospherics/unary/outlet_injector/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) + if(istype(W, /obj/item/device/multitool)) + interact(user) + return 1 if (!istype(W, /obj/item/weapon/wrench)) return ..() if (!(stat & NOPOWER) && on) diff --git a/code/ATMOSPHERICS/components/unary/oxygen_generator.dm b/code/ATMOSPHERICS/components/unary/oxygen_generator.dm index 848c29d03ed..355251849f4 100644 --- a/code/ATMOSPHERICS/components/unary/oxygen_generator.dm +++ b/code/ATMOSPHERICS/components/unary/oxygen_generator.dm @@ -26,22 +26,22 @@ obj/machinery/atmospherics/unary/oxygen_generator/update_icon() obj/machinery/atmospherics/unary/oxygen_generator/New() ..() - air_contents.set_volume(50) + air_contents.volume = 50 obj/machinery/atmospherics/unary/oxygen_generator/process() . = ..() if(!on) return - var/total_moles = air_contents.total_moles + var/total_moles = air_contents.total_moles() if(total_moles < oxygen_content) - var/current_heat_capacity = air_contents.heat_capacity + var/current_heat_capacity = air_contents.heat_capacity() var/added_oxygen = oxygen_content - total_moles - air_contents.set_temperature((current_heat_capacity*air_contents.temperature + 20*added_oxygen*T0C)/(current_heat_capacity+20*added_oxygen)) - air_contents.adjust_gas(OXYGEN, added_oxygen) + air_contents.temperature = (current_heat_capacity*air_contents.temperature + 20*added_oxygen*T0C)/(current_heat_capacity+20*added_oxygen) + air_contents.oxygen += added_oxygen if(network) network.update = 1 diff --git a/code/ATMOSPHERICS/components/unary/tank.dm b/code/ATMOSPHERICS/components/unary/tank.dm index 23b5502b579..ea994ad4921 100644 --- a/code/ATMOSPHERICS/components/unary/tank.dm +++ b/code/ATMOSPHERICS/components/unary/tank.dm @@ -28,7 +28,7 @@ /obj/machinery/atmospherics/unary/tank/carbon_dioxide/New() ..() - air_contents.set_gas(CARBON_DIOXIDE, (25*ONE_ATMOSPHERE)*(starting_volume)/(R_IDEAL_GAS_EQUATION*air_contents.temperature), 0) + air_contents.carbon_dioxide = (25*ONE_ATMOSPHERE)*(starting_volume)/(R_IDEAL_GAS_EQUATION*air_contents.temperature) /obj/machinery/atmospherics/unary/tank/toxins @@ -38,9 +38,8 @@ /obj/machinery/atmospherics/unary/tank/toxins/New() ..() - air_contents.set_gas(PLASMA, (25*ONE_ATMOSPHERE)*(starting_volume)/(R_IDEAL_GAS_EQUATION*air_contents.temperature), 0) + air_contents.toxins = (25*ONE_ATMOSPHERE)*(starting_volume)/(R_IDEAL_GAS_EQUATION*air_contents.temperature) -/* /obj/machinery/atmospherics/unary/tank/oxygen_agent_b icon = 'icons/obj/atmospherics/red_orange_pipe_tank.dmi' @@ -49,8 +48,11 @@ /obj/machinery/atmospherics/unary/tank/oxygen_agent_b/New() ..() - air_contents.set_gas(OXYGEN_AGENT_B, (25*ONE_ATMOSPHERE)*(starting_volume)/(R_IDEAL_GAS_EQUATION*air_contents.temperature), 0) -*/ + var/datum/gas/oxygen_agent_b/trace_gas = new + trace_gas.moles = (25*ONE_ATMOSPHERE)*(starting_volume)/(R_IDEAL_GAS_EQUATION*air_contents.temperature) + + air_contents.trace_gases += trace_gas + /obj/machinery/atmospherics/unary/tank/oxygen icon = 'icons/obj/atmospherics/blue_pipe_tank.dmi' @@ -59,7 +61,7 @@ /obj/machinery/atmospherics/unary/tank/oxygen/New() ..() - air_contents.set_gas(OXYGEN, (25*ONE_ATMOSPHERE)*(starting_volume)/(R_IDEAL_GAS_EQUATION*air_contents.temperature), 0) + air_contents.oxygen = (25*ONE_ATMOSPHERE)*(starting_volume)/(R_IDEAL_GAS_EQUATION*air_contents.temperature) /obj/machinery/atmospherics/unary/tank/nitrogen icon = 'icons/obj/atmospherics/red_pipe_tank.dmi' @@ -68,7 +70,7 @@ /obj/machinery/atmospherics/unary/tank/nitrogen/New() ..() - air_contents.set_gas(NITROGEN, (25*ONE_ATMOSPHERE)*(starting_volume)/(R_IDEAL_GAS_EQUATION*air_contents.temperature), 0) + air_contents.nitrogen = (25*ONE_ATMOSPHERE)*(starting_volume)/(R_IDEAL_GAS_EQUATION*air_contents.temperature) /obj/machinery/atmospherics/unary/tank/air icon = 'icons/obj/atmospherics/red_pipe_tank.dmi' @@ -77,8 +79,8 @@ /obj/machinery/atmospherics/unary/tank/air/New() ..() - air_contents.set_gas(OXYGEN, (25*ONE_ATMOSPHERE*O2STANDARD)*(starting_volume)/(R_IDEAL_GAS_EQUATION*air_contents.temperature), 0) - air_contents.set_gas(NITROGEN, (25*ONE_ATMOSPHERE*N2STANDARD)*(starting_volume)/(R_IDEAL_GAS_EQUATION*air_contents.temperature), 0) + air_contents.oxygen = (25*ONE_ATMOSPHERE*O2STANDARD)*(starting_volume)/(R_IDEAL_GAS_EQUATION*air_contents.temperature) + air_contents.nitrogen = (25*ONE_ATMOSPHERE*N2STANDARD)*(starting_volume)/(R_IDEAL_GAS_EQUATION*air_contents.temperature) /obj/machinery/atmospherics/unary/tank/update_icon() if(node) diff --git a/code/ATMOSPHERICS/components/unary/thermal_plate.dm b/code/ATMOSPHERICS/components/unary/thermal_plate.dm index b9347ded22c..8b066480bf8 100644 --- a/code/ATMOSPHERICS/components/unary/thermal_plate.dm +++ b/code/ATMOSPHERICS/components/unary/thermal_plate.dm @@ -26,34 +26,34 @@ //Get processable air sample and thermal info from environment - var/transfer_moles = 0.25 * environment.total_moles + var/transfer_moles = 0.25 * environment.total_moles() var/datum/gas_mixture/external_removed = environment.remove(transfer_moles) if (!external_removed) return radiate() - if (external_removed.total_moles < 10) + if (external_removed.total_moles() < 10) return radiate() //Get same info from connected gas - var/internal_transfer_moles = 0.25 * air_contents.total_moles + var/internal_transfer_moles = 0.25 * air_contents.total_moles() var/datum/gas_mixture/internal_removed = air_contents.remove(internal_transfer_moles) if (!internal_removed) environment.merge(external_removed) return - var/combined_heat_capacity = internal_removed.heat_capacity + external_removed.heat_capacity - var/combined_energy = internal_removed.thermal_energy() + external_removed.thermal_energy() + var/combined_heat_capacity = internal_removed.heat_capacity() + external_removed.heat_capacity() + var/combined_energy = internal_removed.temperature * internal_removed.heat_capacity() + external_removed.heat_capacity() * external_removed.temperature if(!combined_heat_capacity) combined_heat_capacity = 1 var/final_temperature = combined_energy / combined_heat_capacity - external_removed.set_temperature(final_temperature) + external_removed.temperature = final_temperature environment.merge(external_removed) - internal_removed.set_temperature(final_temperature) + internal_removed.temperature = final_temperature air_contents.merge(internal_removed) network.update = 1 @@ -73,18 +73,18 @@ air_contents.copy_from(network.radiate) //We can cut down on processing time by only calculating radiate() once and then applying the result return - var/internal_transfer_moles = 0.25 * air_contents.total_moles + var/internal_transfer_moles = 0.25 * air_contents.total_moles() var/datum/gas_mixture/internal_removed = air_contents.remove(internal_transfer_moles) if (!internal_removed) return - var/combined_heat_capacity = internal_removed.heat_capacity + RADIATION_CAPACITY - var/combined_energy = internal_removed.thermal_energy() + (RADIATION_CAPACITY * 6.4) + var/combined_heat_capacity = internal_removed.heat_capacity() + RADIATION_CAPACITY + var/combined_energy = internal_removed.temperature * internal_removed.heat_capacity() + (RADIATION_CAPACITY * 6.4) var/final_temperature = combined_energy / combined_heat_capacity - internal_removed.set_temperature(final_temperature) + internal_removed.temperature = final_temperature air_contents.merge(internal_removed) if (network) diff --git a/code/ATMOSPHERICS/components/unary/unary_base.dm b/code/ATMOSPHERICS/components/unary/unary_base.dm index a035c8a651f..57b4f8e1ae8 100644 --- a/code/ATMOSPHERICS/components/unary/unary_base.dm +++ b/code/ATMOSPHERICS/components/unary/unary_base.dm @@ -12,8 +12,8 @@ initialize_directions = dir air_contents = new - air_contents.set_temperature(T0C) - air_contents.set_volume(starting_volume) + air_contents.temperature = T0C + air_contents.volume = starting_volume /obj/machinery/atmospherics/unary/buildFrom(var/mob/usr,var/obj/item/pipe/pipe) dir = pipe.dir diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm index 644e042315b..b7b0270686d 100644 --- a/code/ATMOSPHERICS/components/unary/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm @@ -29,20 +29,18 @@ var/radio_filter_out var/radio_filter_in - - machine_flags = MULTITOOL_MENU -/obj/machinery/atmospherics/unary/vent_pump/on - on = 1 - icon_state = "out" + on + on = 1 + icon_state = "out" -/obj/machinery/atmospherics/unary/vent_pump/siphon - pump_direction = 0 - icon_state = "off" + siphon + pump_direction = 0 + icon_state = "off" -/obj/machinery/atmospherics/unary/vent_pump/siphon/on - on = 1 - icon_state = "in" + on + on = 1 + icon_state = "in" /obj/machinery/atmospherics/unary/vent_pump/New() ..() @@ -60,7 +58,7 @@ /obj/machinery/atmospherics/unary/vent_pump/high_volume/New() ..() - air_contents.set_volume(1000) + air_contents.volume = 1000 /obj/machinery/atmospherics/unary/vent_pump/update_icon() if(welded) @@ -95,7 +93,7 @@ if(!loc) return var/datum/gas_mixture/environment = loc.return_air() - var/environment_pressure = environment.pressure + var/environment_pressure = environment.return_pressure() if(pump_direction) //internal -> external var/pressure_delta = 10000 @@ -103,7 +101,7 @@ if(pressure_checks&1) pressure_delta = min(pressure_delta, (external_pressure_bound - environment_pressure)) if(pressure_checks&2) - pressure_delta = min(pressure_delta, (air_contents.pressure - internal_pressure_bound)) + pressure_delta = min(pressure_delta, (air_contents.return_pressure() - internal_pressure_bound)) if(pressure_delta > 0.1) if(air_contents.temperature > 0) @@ -121,7 +119,7 @@ if(pressure_checks&1) pressure_delta = min(pressure_delta, (environment_pressure - external_pressure_bound)) if(pressure_checks&2) - pressure_delta = min(pressure_delta, (internal_pressure_bound - air_contents.pressure)) + pressure_delta = min(pressure_delta, (internal_pressure_bound - air_contents.return_pressure())) if(pressure_delta > 0.1) if(environment.temperature > 0) @@ -339,6 +337,9 @@ else user << "You need more welding fuel to complete this task." return 1 + if(istype(W, /obj/item/device/multitool)) + update_multitool_menu(user) + return 1 if (!istype(W, /obj/item/weapon/wrench)) return ..() if (!(stat & NOPOWER) && on) diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm index 4d719d878d8..88dcbbc7d0f 100644 --- a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm +++ b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm @@ -14,10 +14,11 @@ var/on = 0 var/scrubbing = 1 //0 = siphoning, 1 = scrubbing - - var/list/scrubbing_gases = list(CARBON_DIOXIDE, //list of gas ids we scrub - PLASMA, - NITROUS_OXIDE) + var/scrub_CO2 = 1 + var/scrub_Toxins = 1 + var/scrub_N2O = 0 + var/scrub_O2 = 0 + var/scrub_N2 = 0 var/volume_rate = 1000 // 120 var/panic = 0 //is this scrubber panicked? @@ -26,8 +27,6 @@ var/area_uid var/radio_filter_out var/radio_filter_in - - machine_flags = MULTITOOL_MENU /obj/machinery/atmospherics/unary/vent_scrubber/New() ..() @@ -47,7 +46,7 @@ icon_state = "[hidden]weld" return var/suffix="" - if(OXYGEN in scrubbing_gases) + if(scrub_O2) suffix="1" if(node && on && !(stat & (NOPOWER|BROKEN))) if(scrubbing) @@ -83,11 +82,11 @@ "power" = on, "scrubbing" = scrubbing, "panic" = panic, - "filter_co2" = (CARBON_DIOXIDE in scrubbing_gases), - "filter_tox" = (PLASMA in scrubbing_gases), - "filter_n2o" = (NITROUS_OXIDE in scrubbing_gases), - "filter_o2" = (OXYGEN in scrubbing_gases), - "filter_n2" = (NITROGEN in scrubbing_gases), + "filter_co2" = scrub_CO2, + "filter_tox" = scrub_Toxins, + "filter_n2o" = scrub_N2O, + "filter_o2" = scrub_O2, + "filter_n2" = scrub_N2, "sigtype" = "status" ) if(!areaMaster.air_scrub_names[id_tag]) @@ -125,26 +124,48 @@ var/datum/gas_mixture/environment = loc.return_air() if(scrubbing) - if(scrubbing_gases.len) - var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles + // Are we scrubbing gasses that are present? + if(\ + (scrub_Toxins && environment.toxins > 0) ||\ + (scrub_CO2 && environment.carbon_dioxide > 0) ||\ + (scrub_N2O && environment.trace_gases.len > 0) ||\ + (scrub_O2 && environment.oxygen > 0) ||\ + (scrub_N2 && environment.nitrogen > 0)) + var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles() //Take a gas sample var/datum/gas_mixture/removed = loc.remove_air(transfer_moles) if (isnull(removed)) //in space return - var/datum/gas_mixture/filtered_out = new - - for(var/gasid in removed.gases) - if(!(gasid in scrubbing_gases)) - continue - - filtered_out.adjust_gas(gasid, removed.gases[gasid]) //move to filtered - removed.set_gas(gasid, 0) //set to 0 - //Filter it + var/datum/gas_mixture/filtered_out = new + filtered_out.temperature = removed.temperature - filtered_out.set_temperature(removed.temperature) + if(scrub_Toxins) + filtered_out.toxins = removed.toxins + removed.toxins = 0 + + if(scrub_CO2) + filtered_out.carbon_dioxide = removed.carbon_dioxide + removed.carbon_dioxide = 0 + + if(scrub_O2) + filtered_out.oxygen = removed.oxygen + removed.oxygen = 0 + + if(scrub_N2) + filtered_out.nitrogen = removed.nitrogen + removed.nitrogen = 0 + + if(removed.trace_gases.len>0) + for(var/datum/gas/trace_gas in removed.trace_gases) + if(istype(trace_gas, /datum/gas/oxygen_agent_b)) + removed.trace_gases -= trace_gas + filtered_out.trace_gases += trace_gas + else if(istype(trace_gas, /datum/gas/sleeping_agent) && scrub_N2O) + removed.trace_gases -= trace_gas + filtered_out.trace_gases += trace_gas //Remix the resulting gases @@ -156,10 +177,10 @@ network.update = 1 else //Just siphoning all air - if (air_contents.pressure>=50*ONE_ATMOSPHERE) + if (air_contents.return_pressure()>=50*ONE_ATMOSPHERE) return - var/transfer_moles = environment.total_moles*(volume_rate/environment.volume) + var/transfer_moles = environment.total_moles()*(volume_rate/environment.volume) var/datum/gas_mixture/removed = loc.remove_air(transfer_moles) @@ -218,29 +239,29 @@ scrubbing = !scrubbing if(signal.data["co2_scrub"] != null) - toggle_gas_scrub(CARBON_DIOXIDE, text2num(signal.data["co2_scrub"])) + scrub_CO2 = text2num(signal.data["co2_scrub"]) if(signal.data["toggle_co2_scrub"]) - toggle_gas_scrub(CARBON_DIOXIDE) + scrub_CO2 = !scrub_CO2 if(signal.data["tox_scrub"] != null) - toggle_gas_scrub(PLASMA, text2num(signal.data["tox_scrub"])) + scrub_Toxins = text2num(signal.data["tox_scrub"]) if(signal.data["toggle_tox_scrub"]) - toggle_gas_scrub(PLASMA) + scrub_Toxins = !scrub_Toxins if(signal.data["n2o_scrub"] != null) - toggle_gas_scrub(NITROUS_OXIDE, text2num(signal.data["n2o_scrub"])) + scrub_N2O = text2num(signal.data["n2o_scrub"]) if(signal.data["toggle_n2o_scrub"]) - toggle_gas_scrub(NITROUS_OXIDE) + scrub_N2O = !scrub_N2O if(signal.data["o2_scrub"] != null) - toggle_gas_scrub(OXYGEN, text2num(signal.data["o2_scrub"])) + scrub_O2 = text2num(signal.data["o2_scrub"]) if(signal.data["toggle_o2_scrub"]) - toggle_gas_scrub(OXYGEN) + scrub_O2 = !scrub_O2 if(signal.data["n2_scrub"] != null) - toggle_gas_scrub(NITROGEN, text2num(signal.data["n2_scrub"])) + scrub_N2 = text2num(signal.data["n2_scrub"]) if(signal.data["toggle_n2_scrub"]) - toggle_gas_scrub(NITROGEN) + scrub_N2 = !scrub_N2 if(signal.data["init"] != null) name = signal.data["init"] @@ -257,20 +278,6 @@ update_icon() return -//forcestate 1 turns scrubbing on, forcestate -1 turns scrubbing off. Otherwise, it toggles -/obj/machinery/atmospherics/unary/vent_scrubber/proc/toggle_gas_scrub(gasid, forcestate) - if(!forcestate) - if(gasid in scrubbing_gases) - scrubbing_gases -= gasid - else - scrubbing_gases += gasid - else - switch(forcestate) - if(1) - scrubbing_gases |= gasid //adds it if it's not added already - if(-1) - scrubbing_gases -= gasid //since this only works if it's in, we remove it - /obj/machinery/atmospherics/unary/vent_scrubber/power_change() if(powered(power_channel)) stat &= ~NOPOWER @@ -282,6 +289,9 @@ return !welded /obj/machinery/atmospherics/unary/vent_scrubber/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) + if(istype(W, /obj/item/device/multitool)) + update_multitool_menu(user) + return 1 if(istype(W, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/WT = W if (WT.remove_fuel(0,user)) diff --git a/code/ATMOSPHERICS/datum_pipe_network.dm b/code/ATMOSPHERICS/datum_pipe_network.dm index bd340131dab..b2da33fa451 100644 --- a/code/ATMOSPHERICS/datum_pipe_network.dm +++ b/code/ATMOSPHERICS/datum_pipe_network.dm @@ -102,69 +102,134 @@ //air_transient.volume = 0 var/air_transient_volume = 0 - for(var/gasid in air_transient.gases) - air_transient.set_gas(gasid, 0, 0) //sets them all to 0 + air_transient.oxygen = 0 + air_transient.nitrogen = 0 + air_transient.toxins = 0 + air_transient.carbon_dioxide = 0 + + + air_transient.trace_gases = list() for(var/datum/gas_mixture/gas in gases) air_transient_volume += gas.volume - var/temp_heatcap = gas.heat_capacity + var/temp_heatcap = gas.heat_capacity() total_thermal_energy += gas.temperature*temp_heatcap total_heat_capacity += temp_heatcap - air_transient.add(gas) + air_transient.oxygen += gas.oxygen + air_transient.nitrogen += gas.nitrogen + air_transient.toxins += gas.toxins + air_transient.carbon_dioxide += gas.carbon_dioxide - air_transient.set_volume(air_transient_volume) + if(gas.trace_gases.len) + for(var/datum/gas/trace_gas in gas.trace_gases) + var/datum/gas/corresponding = locate(trace_gas.type) in air_transient.trace_gases + if(!corresponding) + corresponding = new trace_gas.type() + air_transient.trace_gases += corresponding + + corresponding.moles += trace_gas.moles + + air_transient.volume = air_transient_volume if(air_transient_volume > 0) if(total_heat_capacity > 0) - air_transient.set_temperature(total_thermal_energy/total_heat_capacity) + air_transient.temperature = total_thermal_energy/total_heat_capacity //Allow air mixture to react if(air_transient.react()) update = 1 else - air_transient.set_temperature(0) + air_transient.temperature = 0 //Update individual gas_mixtures by volume ratio for(var/datum/gas_mixture/gas in gases) var/volume_ratio = gas.volume / air_transient.volume - gas.copy_from(air_transient) - gas.multiply(volume_ratio) + gas.oxygen = air_transient.oxygen * volume_ratio + gas.nitrogen = air_transient.nitrogen * volume_ratio + gas.toxins = air_transient.toxins * volume_ratio + gas.carbon_dioxide = air_transient.carbon_dioxide * volume_ratio + gas.temperature = air_transient.temperature + + if(air_transient.trace_gases.len) + for(var/datum/gas/trace_gas in air_transient.trace_gases) + var/datum/gas/corresponding = locate(trace_gas.type) in gas.trace_gases + + if(!corresponding) + corresponding = new trace_gas.type() + gas.trace_gases += corresponding + + corresponding.moles = trace_gas.moles * volume_ratio + + gas.update_values() + + air_transient.update_values() return 1 -proc/equalize_gases(list/datum/gas_mixture/gases) +proc/equalize_gases(datum/gas_mixture/list/gases) //Perfectly equalize all gases members instantly - var/datum/gas_mixture/total = new + //Calculate totals from individual components var/total_volume = 0 var/total_thermal_energy = 0 + var/total_heat_capacity = 0 + + var/total_oxygen = 0 + var/total_nitrogen = 0 + var/total_toxins = 0 + var/total_carbon_dioxide = 0 + + var/list/total_trace_gases = list() for(var/datum/gas_mixture/gas in gases) total_volume += gas.volume - total_thermal_energy += gas.temperature*gas.heat_capacity + var/temp_heatcap = gas.heat_capacity() + total_thermal_energy += gas.temperature*temp_heatcap + total_heat_capacity += temp_heatcap - total.add(gas) + total_oxygen += gas.oxygen + total_nitrogen += gas.nitrogen + total_toxins += gas.toxins + total_carbon_dioxide += gas.carbon_dioxide + if(gas.trace_gases.len) + for(var/datum/gas/trace_gas in gas.trace_gases) + var/datum/gas/corresponding = locate(trace_gas.type) in total_trace_gases + if(!corresponding) + corresponding = new trace_gas.type() + total_trace_gases += corresponding + + corresponding.moles += trace_gas.moles if(total_volume > 0) //Calculate temperature var/temperature = 0 - if(total.heat_capacity > 0) - temperature = total_thermal_energy/total.heat_capacity + if(total_heat_capacity > 0) + temperature = total_thermal_energy/total_heat_capacity //Update individual gas_mixtures by volume ratio - for(var/gasid in total.gases) //for each gas in the gas mix in our list of gas mixes - var/total_gas = total.gases[gasid] - for(var/datum/gas_mixture/gas_mix in gases) - gas_mix.set_gas(gasid, total_gas * gas_mix.volume / total_volume) + for(var/datum/gas_mixture/gas in gases) + gas.oxygen = total_oxygen*gas.volume/total_volume + gas.nitrogen = total_nitrogen*gas.volume/total_volume + gas.toxins = total_toxins*gas.volume/total_volume + gas.carbon_dioxide = total_carbon_dioxide*gas.volume/total_volume - for(var/datum/gas_mixture/gas_mix in gases) //cheaper to set here - gas_mix.set_temperature(temperature) + gas.temperature = temperature + + if(total_trace_gases.len) + for(var/datum/gas/trace_gas in total_trace_gases) + var/datum/gas/corresponding = locate(trace_gas.type) in gas.trace_gases + if(!corresponding) + corresponding = new trace_gas.type() + gas.trace_gases += corresponding + + corresponding.moles = trace_gas.moles*gas.volume/total_volume + gas.update_values() return 1 \ No newline at end of file diff --git a/code/ATMOSPHERICS/datum_pipeline.dm b/code/ATMOSPHERICS/datum_pipeline.dm index 9384bf26d86..e91ca41e0d1 100644 --- a/code/ATMOSPHERICS/datum_pipeline.dm +++ b/code/ATMOSPHERICS/datum_pipeline.dm @@ -29,7 +29,7 @@ /datum/pipeline/proc/process()//This use to be called called from the pipe networks if((world.timeofday - last_pressure_check) / 10 >= PRESSURE_CHECK_DELAY) //Check to see if pressure is within acceptable limits - var/pressure = air.pressure + var/pressure = air.return_pressure() if(pressure > alert_pressure) for(var/obj/machinery/atmospherics/pipe/member in members) if(!member.check_pressure(pressure)) @@ -46,11 +46,22 @@ for(var/obj/machinery/atmospherics/pipe/member in members) member.air_temporary = new - member.air_temporary.set_volume(member.volume) + member.air_temporary.volume = member.volume - member.air_temporary.copy_from(air) - member.air_temporary.multiply(member.volume/air.volume) + member.air_temporary.oxygen = air.oxygen*member.volume/air.volume + member.air_temporary.nitrogen = air.nitrogen*member.volume/air.volume + member.air_temporary.toxins = air.toxins*member.volume/air.volume + member.air_temporary.carbon_dioxide = air.carbon_dioxide*member.volume/air.volume + member.air_temporary.temperature = air.temperature + + if(air.trace_gases.len) + for(var/datum/gas/trace_gas in air.trace_gases) + var/datum/gas/corresponding = new trace_gas.type() + member.air_temporary.trace_gases += corresponding + + corresponding.moles = trace_gas.moles*member.volume/air.volume + member.air_temporary.update_values() /datum/pipeline/proc/build_pipeline(obj/machinery/atmospherics/pipe/base) var/list/possible_expansions = list(base) @@ -67,8 +78,6 @@ else air = new - air.set_volume(volume) - while(possible_expansions.len>0) for(var/obj/machinery/atmospherics/pipe/borderline in possible_expansions) @@ -96,6 +105,9 @@ possible_expansions -= borderline + air.volume = volume + air.update_values() + /datum/pipeline/proc/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) if(new_network.line_members.Find(src)) @@ -124,14 +136,14 @@ /datum/pipeline/proc/mingle_with_turf(turf/simulated/target, mingle_volume) var/datum/gas_mixture/air_sample = air.remove_ratio(mingle_volume/air.volume) - air_sample.set_volume(mingle_volume) + air_sample.volume = mingle_volume if(istype(target) && target.zone) //Have to consider preservation of group statuses var/datum/gas_mixture/turf_copy = new turf_copy.copy_from(target.zone.air) - turf_copy.set_volume(target.zone.air.volume) //Copy a good representation of the turf from parent group + turf_copy.volume = target.zone.air.volume //Copy a good representation of the turf from parent group equalize_gases(list(air_sample, turf_copy)) air.merge(air_sample) @@ -157,7 +169,7 @@ network.update = 1 /datum/pipeline/proc/temperature_interact(turf/target, share_volume, thermal_conductivity) - var/total_heat_capacity = air.heat_capacity + var/total_heat_capacity = air.heat_capacity() var/partial_heat_capacity = total_heat_capacity*(share_volume/air.volume) if(istype(target, /turf/simulated)) @@ -171,7 +183,7 @@ var/heat = thermal_conductivity*delta_temperature* \ (partial_heat_capacity*modeled_location.heat_capacity/(partial_heat_capacity+modeled_location.heat_capacity)) - air.set_temperature(air.temperature - heat/total_heat_capacity) + air.temperature -= heat/total_heat_capacity modeled_location.temperature += heat/modeled_location.heat_capacity else @@ -180,10 +192,10 @@ if(modeled_location.zone) delta_temperature = (air.temperature - modeled_location.zone.air.temperature) - sharer_heat_capacity = modeled_location.zone.air.heat_capacity + sharer_heat_capacity = modeled_location.zone.air.heat_capacity() else delta_temperature = (air.temperature - modeled_location.air.temperature) - sharer_heat_capacity = modeled_location.air.heat_capacity + sharer_heat_capacity = modeled_location.air.heat_capacity() var/self_temperature_delta = 0 var/sharer_temperature_delta = 0 @@ -197,12 +209,12 @@ else return 1 - air.set_temperature(air.temperature + self_temperature_delta) + air.temperature += self_temperature_delta if(modeled_location.zone) - modeled_location.zone.air.set_temperature(modeled_location.zone.air.temperature + sharer_temperature_delta/modeled_location.zone.air.group_multiplier) + modeled_location.zone.air.temperature += sharer_temperature_delta/modeled_location.zone.air.group_multiplier else - modeled_location.air.set_temperature(modeled_location.air.temperature + sharer_temperature_delta) + modeled_location.air.temperature += sharer_temperature_delta else @@ -212,6 +224,6 @@ var/heat = thermal_conductivity*delta_temperature* \ (partial_heat_capacity*target.heat_capacity/(partial_heat_capacity+target.heat_capacity)) - air.set_temperature( air.temperature - heat/total_heat_capacity) + air.temperature -= heat/total_heat_capacity if(network) network.update = 1 diff --git a/code/ATMOSPHERICS/he_pipes.dm b/code/ATMOSPHERICS/he_pipes.dm index 56b1ef5312c..37d44d2c9e9 100644 --- a/code/ATMOSPHERICS/he_pipes.dm +++ b/code/ATMOSPHERICS/he_pipes.dm @@ -56,12 +56,12 @@ // Get gas from pipenet var/datum/gas_mixture/internal = return_air() - var/internal_transfer_moles = 0.25 * internal.total_moles + var/internal_transfer_moles = 0.25 * internal.total_moles() var/datum/gas_mixture/internal_removed = internal.remove(internal_transfer_moles) //Get processable air sample and thermal info from environment var/datum/gas_mixture/environment = loc.return_air() - var/transfer_moles = 0.25 * environment.total_moles + var/transfer_moles = 0.25 * environment.total_moles() var/datum/gas_mixture/external_removed = environment.remove(transfer_moles) // No environmental gas? We radiate it, then. @@ -71,7 +71,7 @@ return radiate() // Not enough gas in the air around us to care about. Radiate. - if (external_removed.total_moles < 10) + if (external_removed.total_moles() < 10) if(internal_removed) internal.merge(internal_removed) environment.merge(external_removed) @@ -83,17 +83,17 @@ return //Get same info from connected gas - var/combined_heat_capacity = internal_removed.heat_capacity + external_removed.heat_capacity - var/combined_energy = internal_removed.thermal_energy() + external_removed.thermal_energy() + var/combined_heat_capacity = internal_removed.heat_capacity() + external_removed.heat_capacity() + var/combined_energy = internal_removed.temperature * internal_removed.heat_capacity() + external_removed.heat_capacity() * external_removed.temperature if(!combined_heat_capacity) combined_heat_capacity = 1 var/final_temperature = combined_energy / combined_heat_capacity - external_removed.set_temperature(final_temperature) + external_removed.temperature = final_temperature environment.merge(external_removed) - internal_removed.set_temperature(final_temperature) + internal_removed.temperature = final_temperature internal.merge(internal_removed) @@ -103,18 +103,18 @@ /obj/machinery/atmospherics/pipe/simple/heat_exchanging/proc/radiate() var/datum/gas_mixture/internal = return_air() - var/internal_transfer_moles = 0.25 * internal.total_moles + var/internal_transfer_moles = 0.25 * internal.total_moles() var/datum/gas_mixture/internal_removed = internal.remove(internal_transfer_moles) if (!internal_removed) return - var/combined_heat_capacity = internal_removed.heat_capacity + RADIATION_CAPACITY - var/combined_energy = internal_removed.thermal_energy() + (RADIATION_CAPACITY * ENERGY_MULT) + var/combined_heat_capacity = internal_removed.heat_capacity() + RADIATION_CAPACITY + var/combined_energy = internal_removed.temperature * internal_removed.heat_capacity() + (RADIATION_CAPACITY * ENERGY_MULT) var/final_temperature = combined_energy / combined_heat_capacity - internal_removed.set_temperature(final_temperature) + internal_removed.temperature = final_temperature internal.merge(internal_removed) if(parent && parent.network) diff --git a/code/ATMOSPHERICS/hvac/chiller.dm b/code/ATMOSPHERICS/hvac/chiller.dm index 3b9c03ce6ca..0e4af4c1e82 100644 --- a/code/ATMOSPHERICS/hvac/chiller.dm +++ b/code/ATMOSPHERICS/hvac/chiller.dm @@ -93,16 +93,17 @@ var/turf/simulated/L = loc if(istype(L)) var/datum/gas_mixture/env = L.return_air() - var/transfer_moles = 0.25 * env.total_moles + var/transfer_moles = 0.25 * env.total_moles() var/datum/gas_mixture/removed = env.remove(transfer_moles) if(removed) if(removed.temperature > (set_temperature + T0C)) - var/combined_heat_capacity = cooling_power + removed.heat_capacity + var/air_heat_capacity = removed.heat_capacity() + var/combined_heat_capacity = cooling_power + air_heat_capacity //var/old_temperature = removed.temperature if(combined_heat_capacity > 0) - var/combined_energy = set_temperature*cooling_power + removed.thermal_energy() - removed.set_temperature(combined_energy/combined_heat_capacity) + var/combined_energy = set_temperature*cooling_power + air_heat_capacity*removed.temperature + removed.temperature = combined_energy/combined_heat_capacity env.merge(removed) return 1 env.merge(removed) diff --git a/code/ATMOSPHERICS/hvac/spaceheater.dm b/code/ATMOSPHERICS/hvac/spaceheater.dm index 915fae5e343..8934b3f1edb 100644 --- a/code/ATMOSPHERICS/hvac/spaceheater.dm +++ b/code/ATMOSPHERICS/hvac/spaceheater.dm @@ -165,7 +165,7 @@ var/datum/gas_mixture/env = L.return_air() if(env.temperature != set_temperature + T0C) - var/transfer_moles = 0.25 * env.total_moles + var/transfer_moles = 0.25 * env.total_moles() var/datum/gas_mixture/removed = env.remove(transfer_moles) @@ -173,13 +173,13 @@ if(removed) - var/heat_capacity = removed.heat_capacity + var/heat_capacity = removed.heat_capacity() //world << "heating ([heat_capacity])" if(heat_capacity) // Added check to avoid divide by zero (oshi-) runtime errors -- TLE if(removed.temperature < set_temperature + T0C) - removed.set_temperature(min(removed.temperature + heating_power/heat_capacity, 1000)) // Added min() check to try and avoid wacky superheating issues in low gas scenarios -- TLE + removed.temperature = min(removed.temperature + heating_power/heat_capacity, 1000) // Added min() check to try and avoid wacky superheating issues in low gas scenarios -- TLE else - removed.set_temperature(max(removed.temperature - heating_power/heat_capacity, TCMB)) + removed.temperature = max(removed.temperature - heating_power/heat_capacity, TCMB) cell.use(heating_power/20000) //world << "now at [removed.temperature]" diff --git a/code/ATMOSPHERICS/pipes.dm b/code/ATMOSPHERICS/pipes.dm index 71fe65bf8e7..542b3f3fc44 100644 --- a/code/ATMOSPHERICS/pipes.dm +++ b/code/ATMOSPHERICS/pipes.dm @@ -12,9 +12,6 @@ // Insulated pipes #define IPIPE_COLOR_RED PIPE_COLOR_RED #define IPIPE_COLOR_BLUE "#4285F4" -/obj/machinery/atmospherics/pipe/process() - . = ..() - atmos_machines.Remove(src) /obj/machinery/atmospherics/pipe var/datum/gas_mixture/air_temporary //used when reconstructing a pipeline that broke @@ -201,7 +198,7 @@ // So, a pipe rated at 8,000 kPa in a 104kPa environment will explode at 8,104kPa. var/datum/gas_mixture/environment = loc.return_air() - var/pressure_difference = pressure - environment.pressure + var/pressure_difference = pressure - environment.return_pressure() // Burst check first. if(pressure_difference > maximum_pressure && prob(1)) diff --git a/code/WorkInProgress/Cael_Aislinn/Rust/core_field.dm b/code/WorkInProgress/Cael_Aislinn/Rust/core_field.dm index 41fac7a61ea..17c87e428a9 100644 --- a/code/WorkInProgress/Cael_Aislinn/Rust/core_field.dm +++ b/code/WorkInProgress/Cael_Aislinn/Rust/core_field.dm @@ -135,24 +135,25 @@ Deuterium-tritium fusion: 4.5 x 10^7 K //add plasma from the surrounding environment var/datum/gas_mixture/environment = loc.return_air() - var/held_plasma_moles = held_plasma.gases[PLASMA] //hack in some stuff to remove plasma from the air because SCIENCE //the amount of plasma pulled in each update is relative to the field strength, with 50T (max field strength) = 100% of area covered by the field //at minimum strength, 0.25% of the field volume is pulled in per update (?) //have a max of 1000 moles suspended - if(held_plasma_moles < transfer_ratio * 1000) - var/moles_covered = environment.pressure*volume_covered/(environment.temperature * R_IDEAL_GAS_EQUATION) + if(held_plasma.toxins < transfer_ratio * 1000) + var/moles_covered = environment.return_pressure()*volume_covered/(environment.temperature * R_IDEAL_GAS_EQUATION) //world << "moles_covered: [moles_covered]" // var/datum/gas_mixture/gas_covered = environment.remove(moles_covered) var/datum/gas_mixture/plasma_captured = new /datum/gas_mixture() // - plasma_captured.set_gas(PLASMA, round(gas_covered.gases[PLASMA] * transfer_ratio)) + plasma_captured.toxins = round(gas_covered.toxins * transfer_ratio) //world << "[plasma_captured.toxins] moles of plasma captured" - plasma_captured.set_temperature(gas_covered.temperature) + plasma_captured.temperature = gas_covered.temperature + plasma_captured.update_values() // - gas_covered.adjust_gas(PLASMA, -plasma_captured.gases[PLASMA]) + gas_covered.toxins -= plasma_captured.toxins + gas_covered.update_values() // held_plasma.merge(plasma_captured) // @@ -170,32 +171,32 @@ Deuterium-tritium fusion: 4.5 x 10^7 K //change held plasma temp according to energy levels //SPECIFIC_HEAT_TOXIN - if(mega_energy > 0 && held_plasma_moles) - var/heat_capacity = held_plasma.heat_capacity//200 * number of plasma moles + if(mega_energy > 0 && held_plasma.toxins) + var/heat_capacity = held_plasma.heat_capacity()//200 * number of plasma moles if(heat_capacity > 0.0003) //formerly MINIMUM_HEAT_CAPACITY - held_plasma.set_temperature((heat_capacity + mega_energy * 35000)/heat_capacity) + held_plasma.temperature = (heat_capacity + mega_energy * 35000)/heat_capacity //if there is too much plasma in the field, lose some /*if( held_plasma.toxins > (MOLES_CELLSTANDARD * 7) * (50 / field_strength) ) LosePlasma()*/ - if(held_plasma_moles > 1) + if(held_plasma.toxins > 1) //lose a random amount of plasma back into the air, increased by the field strength (want to switch this over to frequency eventually) var/loss_ratio = rand() * (0.05 + (0.05 * 50 / field_strength)) //world << "lost [loss_ratio*100]% of held plasma" // var/datum/gas_mixture/plasma_lost = new - plasma_lost.set_temperature(held_plasma.temperature) + plasma_lost.temperature = held_plasma.temperature // - plasma_lost.set_gas(PLASMA, held_plasma_moles * loss_ratio) + plasma_lost.toxins = held_plasma.toxins * loss_ratio //plasma_lost.update_values() - held_plasma.adjust_gas(PLASMA, -held_plasma_moles * loss_ratio) + held_plasma.toxins -= held_plasma.toxins * loss_ratio //held_plasma.update_values() // environment.merge(plasma_lost) radiation += loss_ratio * mega_energy * 0.1 mega_energy -= loss_ratio * mega_energy * 0.1 else - held_plasma.set_gas(PLASMA, 0) + held_plasma.toxins = 0 //held_plasma.update_values() //handle some reactants formatting diff --git a/code/WorkInProgress/pomf/spacepods/equipment.dm b/code/WorkInProgress/pomf/spacepods/equipment.dm index fc2095ef970..46596ab4a58 100644 --- a/code/WorkInProgress/pomf/spacepods/equipment.dm +++ b/code/WorkInProgress/pomf/spacepods/equipment.dm @@ -9,9 +9,7 @@ usr << "Missing equipment or weapons." my_atom.verbs -= /obj/item/device/spacepod_equipment/weaponry/proc/fire_weapon_system return - if(!my_atom.battery.use(shot_cost)) - usr << "\The [my_atom]'s cell is too low on charge!" - return + my_atom.battery.use(shot_cost) var/olddir dir = my_atom.dir for(var/i = 0; i < shots_per; i++) @@ -92,9 +90,8 @@ name = "\improper burst taser system" desc = "A weak taser system for space pods, this one fires 3 at a time." icon_state = "pod_b_taser" - shot_cost = 35 + shot_cost = 20 shots_per = 3 - fire_delay = 20 verb_name = "Fire Burst Taser System" verb_desc = "Fire ze tasers!" @@ -103,9 +100,9 @@ desc = "A weak laser system for space pods, fires concentrated bursts of energy" icon_state = "pod_w_laser" projectile_type = /obj/item/projectile/beam - shot_cost = 150 + shot_cost = 15 fire_sound = 'sound/weapons/Laser.ogg' - fire_delay = 15 + fire_delay = 25 verb_name = "Fire Laser System" verb_desc = "Fire ze lasers!" diff --git a/code/WorkInProgress/pomf/spacepods/spacepods.dm b/code/WorkInProgress/pomf/spacepods/spacepods.dm index 8089359f074..a55ef12555d 100644 --- a/code/WorkInProgress/pomf/spacepods/spacepods.dm +++ b/code/WorkInProgress/pomf/spacepods/spacepods.dm @@ -86,12 +86,12 @@ spawn(0) if(occupant) occupant << "Critical damage to the vessel detected, core explosion imminent!" - for(var/i = 10, i >= 0; --i) - if(occupant) - occupant << "[i]" - if(i == 0) - explosion(loc, 2, 4, 8) - sleep(10) + for(var/i = 10, i >= 0; --i) + if(occupant) + occupant << "[i]" + if(i == 0) + explosion(loc, 2, 4, 8) + sleep(10) update_icons() @@ -230,10 +230,10 @@ /obj/spacepod/proc/add_cabin() cabin_air = new - cabin_air.set_temperature(T20C) - cabin_air.set_volume(200) - cabin_air.adjust_gas(OXYGEN, O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)) - cabin_air.adjust_gas(NITROGEN, N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)) + cabin_air.temperature = T20C + cabin_air.volume = 200 + cabin_air.oxygen = O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature) + cabin_air.nitrogen = N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature) return cabin_air /obj/spacepod/proc/add_airtank() @@ -263,21 +263,21 @@ /obj/spacepod/proc/return_pressure() . = 0 if(use_internal_tank) - . = cabin_air.pressure + . = cabin_air.return_pressure() else var/datum/gas_mixture/t_air = get_turf_air() if(t_air) - . = t_air.pressure + . = t_air.return_pressure() return /obj/spacepod/proc/return_temperature() . = 0 if(use_internal_tank) - . = cabin_air.temperature + . = cabin_air.return_temperature() else var/datum/gas_mixture/t_air = get_turf_air() if(t_air) - . = t_air.temperature + . = t_air.return_temperature() return /obj/spacepod/proc/moved_inside(var/mob/living/carbon/human/H as mob) @@ -366,9 +366,9 @@ delay = 20 process(var/obj/spacepod/spacepod) - if(spacepod.cabin_air && spacepod.cabin_air.volume > 0) + if(spacepod.cabin_air && spacepod.cabin_air.return_volume() > 0) var/delta = spacepod.cabin_air.temperature - T20C - spacepod.cabin_air.set_temperature( spacepod.cabin_air.temperature - max(-10, min(10, round(delta/4,0.1)))) + spacepod.cabin_air.temperature -= max(-10, min(10, round(delta/4,0.1))) return /datum/global_iterator/pod_tank_give_air @@ -380,21 +380,21 @@ var/datum/gas_mixture/cabin_air = spacepod.cabin_air var/release_pressure = ONE_ATMOSPHERE - var/cabin_pressure = cabin_air.pressure - var/pressure_delta = min(release_pressure - cabin_pressure, (tank_air.pressure - cabin_pressure)/2) + var/cabin_pressure = cabin_air.return_pressure() + var/pressure_delta = min(release_pressure - cabin_pressure, (tank_air.return_pressure() - cabin_pressure)/2) var/transfer_moles = 0 if(pressure_delta > 0) //cabin pressure lower than release pressure - if(tank_air.temperature > 0) - transfer_moles = pressure_delta*cabin_air.volume/(cabin_air.temperature * R_IDEAL_GAS_EQUATION) + 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) else if(pressure_delta < 0) //cabin pressure higher than release pressure var/datum/gas_mixture/t_air = spacepod.get_turf_air() pressure_delta = cabin_pressure - release_pressure if(t_air) - pressure_delta = min(cabin_pressure - t_air.pressure, pressure_delta) + 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.volume/(cabin_air.temperature * R_IDEAL_GAS_EQUATION) + 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) diff --git a/code/ZAS/Airflow.dm b/code/ZAS/Airflow.dm index 85a5e941b85..66497632826 100644 --- a/code/ZAS/Airflow.dm +++ b/code/ZAS/Airflow.dm @@ -118,7 +118,7 @@ obj/item/check_airflow_movable(n) proc/Airflow(zone/A, zone/B) set background = 1 - var/n = B.air.pressure - A.air.pressure + var/n = B.air.return_pressure() - A.air.return_pressure() //Don't go any further if n is lower than the lowest value needed for airflow. if(abs(n) < zas_settings.Get(/datum/ZAS_Setting/airflow_lightest_pressure)) return @@ -199,7 +199,7 @@ proc/AirflowSpace(zone/A) spawn() //The space version of the Airflow(A,B,n) proc. - var/n = A.air.pressure + var/n = A.air.return_pressure() //Here, n is determined by only the pressure in the room. if(n < zas_settings.Get(/datum/ZAS_Setting/airflow_lightest_pressure)) return diff --git a/code/ZAS/ConnectionGroup.dm b/code/ZAS/ConnectionGroup.dm index 57c4cc7e879..bb818b673bf 100644 --- a/code/ZAS/ConnectionGroup.dm +++ b/code/ZAS/ConnectionGroup.dm @@ -182,7 +182,7 @@ Class Procs: air_master.mark_zone_update(B) //world << "equalized." - var/differential = A.air.pressure - B.air.pressure + var/differential = A.air.return_pressure() - B.air.return_pressure() if(abs(differential) < zas_settings.Get(/datum/ZAS_Setting/airflow_lightest_pressure)) return var/list/attracted @@ -241,7 +241,7 @@ Class Procs: ShareSpace(A.air,air,dbg_out) air_master.mark_zone_update(A) - var/differential = A.air.pressure - air.pressure + var/differential = A.air.return_pressure() - air.return_pressure() if(abs(differential) < zas_settings.Get(/datum/ZAS_Setting/airflow_lightest_pressure)) return var/list/attracted = A.movables() @@ -251,55 +251,113 @@ var/list/sharing_lookup_table = list(0.30, 0.40, 0.48, 0.54, 0.60, 0.66) proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles) //Shares a specific ratio of gas between mixtures using simple weighted averages. - + var //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD - var/ratio = sharing_lookup_table[6] + ratio = sharing_lookup_table[6] //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD - var/A_full_heat_capacity = A.heat_capacity * A.group_multiplier + size = max(1,A.group_multiplier) + share_size = max(1,B.group_multiplier) - var/B_full_heat_capacity = B.heat_capacity * B.group_multiplier + full_oxy = A.oxygen * size + full_nitro = A.nitrogen * size + full_co2 = A.carbon_dioxide * size + full_plasma = A.toxins * size - var/temp_avg = (A.temperature * A_full_heat_capacity + B.temperature * B_full_heat_capacity) / (A_full_heat_capacity + B_full_heat_capacity) + full_heat_capacity = A.heat_capacity() * size + + s_full_oxy = B.oxygen * share_size + s_full_nitro = B.nitrogen * share_size + s_full_co2 = B.carbon_dioxide * share_size + s_full_plasma = B.toxins * share_size + + s_full_heat_capacity = B.heat_capacity() * share_size + + oxy_avg = (full_oxy + s_full_oxy) / (size + share_size) + nit_avg = (full_nitro + s_full_nitro) / (size + share_size) + co2_avg = (full_co2 + s_full_co2) / (size + share_size) + plasma_avg = (full_plasma + s_full_plasma) / (size + share_size) + + temp_avg = (A.temperature * full_heat_capacity + B.temperature * s_full_heat_capacity) / (full_heat_capacity + s_full_heat_capacity) //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD if(sharing_lookup_table.len >= connecting_tiles) //6 or more interconnecting tiles will max at 42% of air moved per tick. ratio = sharing_lookup_table[connecting_tiles] //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD - A.set_temperature((A.temperature - temp_avg) * (1-ratio) + temp_avg) + A.oxygen = max(0, (A.oxygen - oxy_avg) * (1-ratio) + oxy_avg ) + A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1-ratio) + nit_avg ) + A.carbon_dioxide = max(0, (A.carbon_dioxide - co2_avg) * (1-ratio) + co2_avg ) + A.toxins = max(0, (A.toxins - plasma_avg) * (1-ratio) + plasma_avg ) - B.set_temperature((B.temperature - temp_avg) * (1-ratio) + temp_avg) + A.temperature = max(0, (A.temperature - temp_avg) * (1-ratio) + temp_avg ) - for(var/gasid in A.gases) - var/A_moles = A.gases[gasid] - var/B_moles = B.gases[gasid] - var/avg_gas = (A_moles * A.group_multiplier + B_moles * B.group_multiplier) / (A.group_multiplier + B.group_multiplier) + B.oxygen = max(0, (B.oxygen - oxy_avg) * (1-ratio) + oxy_avg ) + B.nitrogen = max(0, (B.nitrogen - nit_avg) * (1-ratio) + nit_avg ) + B.carbon_dioxide = max(0, (B.carbon_dioxide - co2_avg) * (1-ratio) + co2_avg ) + B.toxins = max(0, (B.toxins - plasma_avg) * (1-ratio) + plasma_avg ) - A.set_gas(gasid, avg_gas + ((A_moles - avg_gas) * (1 - ratio))) //we don't use adjust_gas because it interferes with the group multiplier - B.set_gas(gasid, avg_gas + ((B_moles - avg_gas) * (1 - ratio))) + B.temperature = max(0, (B.temperature - temp_avg) * (1-ratio) + temp_avg ) - return A.compare(B) + for(var/datum/gas/G in A.trace_gases) + var/datum/gas/H = locate(G.type) in B.trace_gases + if(H) + var/G_avg = (G.moles*size + H.moles*share_size) / (size+share_size) + G.moles = (G.moles - G_avg) * (1-ratio) + G_avg + + H.moles = (H.moles - G_avg) * (1-ratio) + G_avg + else + H = new G.type + B.trace_gases += H + var/G_avg = (G.moles*size) / (size+share_size) + G.moles = (G.moles - G_avg) * (1-ratio) + G_avg + H.moles = (H.moles - G_avg) * (1-ratio) + G_avg + + for(var/datum/gas/G in B.trace_gases) + var/datum/gas/H = locate(G.type) in A.trace_gases + if(!H) + H = new G.type + A.trace_gases += H + var/G_avg = (G.moles*size) / (size+share_size) + G.moles = (G.moles - G_avg) * (1-ratio) + G_avg + H.moles = (H.moles - G_avg) * (1-ratio) + G_avg + + A.update_values() + B.update_values() + + if(A.compare(B)) return 1 + else return 0 proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output) //A modified version of ShareRatio for spacing gas at the same rate as if it were going into a large airless room. if(!unsimulated_tiles) return 0 - var/datum/gas_mixture/unsim_mix = new + var + unsim_oxygen = 0 + unsim_nitrogen = 0 + unsim_co2 = 0 + unsim_plasma = 0 + unsim_heat_capacity = 0 + unsim_temperature = 0 + + size = max(1,A.group_multiplier) var/tileslen - var/size = A.group_multiplier var/share_size if(istype(unsimulated_tiles, /datum/gas_mixture)) var/datum/gas_mixture/avg_unsim = unsimulated_tiles - unsim_mix.copy_from(avg_unsim) + unsim_oxygen = avg_unsim.oxygen + unsim_co2 = avg_unsim.carbon_dioxide + unsim_nitrogen = avg_unsim.nitrogen + unsim_plasma = avg_unsim.toxins + unsim_temperature = avg_unsim.temperature share_size = max(1, max(size + 3, 1) + avg_unsim.group_multiplier) tileslen = avg_unsim.group_multiplier if(dbg_output) - world << "O2: [unsim_mix.gases[OXYGEN]] N2: [unsim_mix.gases[NITROGEN]] Size: [share_size] Tiles: [tileslen]" + world << "O2: [unsim_oxygen] N2: [unsim_nitrogen] Size: [share_size] Tiles: [tileslen]" else if(istype(unsimulated_tiles, /list)) if(!unsimulated_tiles.len) @@ -314,53 +372,79 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output) var/correction_ratio = share_size / unsimulated_tiles.len for(var/turf/T in unsimulated_tiles) - unsim_mix.add(T.return_air()) + unsim_oxygen += T.oxygen + unsim_co2 += T.carbon_dioxide + unsim_nitrogen += T.nitrogen + unsim_plasma += T.toxins + unsim_temperature += T.temperature/unsimulated_tiles.len //These values require adjustment in order to properly represent a room of the specified size. - unsim_mix.multiply(correction_ratio) + unsim_oxygen *= correction_ratio + unsim_co2 *= correction_ratio + unsim_nitrogen *= correction_ratio + unsim_plasma *= correction_ratio tileslen = unsimulated_tiles.len else //invalid input type return 0 - var/ratio = sharing_lookup_table[6] + unsim_heat_capacity = HEAT_CAPACITY_CALCULATION(unsim_oxygen, unsim_co2, unsim_nitrogen, unsim_plasma) - var/old_pressure = A.pressure + var + ratio = sharing_lookup_table[6] - var/full_heat_capacity = A.heat_capacity * A.group_multiplier + old_pressure = A.return_pressure() - var/temp_avg = 0 + full_oxy = A.oxygen * size + full_nitro = A.nitrogen * size + full_co2 = A.carbon_dioxide * size + full_plasma = A.toxins * size - if((full_heat_capacity + unsim_mix.heat_capacity) > 0) - temp_avg = (A.temperature * full_heat_capacity + unsim_mix.temperature * unsim_mix.heat_capacity) / (full_heat_capacity + unsim_mix.heat_capacity) + full_heat_capacity = A.heat_capacity() * size + + oxy_avg = (full_oxy + unsim_oxygen*share_size) / (size + share_size) + nit_avg = (full_nitro + unsim_nitrogen*share_size) / (size + share_size) + co2_avg = (full_co2 + unsim_co2*share_size) / (size + share_size) + plasma_avg = (full_plasma + unsim_plasma*share_size) / (size + share_size) + + temp_avg = 0 + + if((full_heat_capacity + unsim_heat_capacity) > 0) + temp_avg = (A.temperature * full_heat_capacity + unsim_temperature * unsim_heat_capacity) / (full_heat_capacity + unsim_heat_capacity) if(sharing_lookup_table.len >= tileslen) //6 or more interconnecting tiles will max at 42% of air moved per tick. ratio = sharing_lookup_table[tileslen] if(dbg_output) world << "Ratio: [ratio]" - //world << "Avg O2: [oxy_avg] N2: [nit_avg]" + world << "Avg O2: [oxy_avg] N2: [nit_avg]" - A.set_temperature(max(TCMB, (A.temperature - temp_avg) * (1 - ratio) + temp_avg )) + A.oxygen = max(0, (A.oxygen - oxy_avg) * (1 - ratio) + oxy_avg ) + A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1 - ratio) + nit_avg ) + A.carbon_dioxide = max(0, (A.carbon_dioxide - co2_avg) * (1 - ratio) + co2_avg ) + A.toxins = max(0, (A.toxins - plasma_avg) * (1 - ratio) + plasma_avg ) - for(var/gasid in A.gases) - var/gas_moles = A.gases[gasid] - var/avg_gas = (gas_moles + unsim_mix.gases[gasid]*share_size) / (size + share_size) - A.set_gas(gasid, (gas_moles - avg_gas) * (1 - ratio) + avg_gas, 0 ) + A.temperature = max(TCMB, (A.temperature - temp_avg) * (1 - ratio) + temp_avg ) - if(dbg_output) world << "Result: [abs(old_pressure - A.pressure)] kPa" + for(var/datum/gas/G in A.trace_gases) + var/G_avg = (G.moles * size) / (size + share_size) + G.moles = (G.moles - G_avg) * (1 - ratio) + G_avg - return abs(old_pressure - A.pressure) + A.update_values() + + if(dbg_output) world << "Result: [abs(old_pressure - A.return_pressure())] kPa" + + return abs(old_pressure - A.return_pressure()) proc/ShareHeat(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles) //This implements a simplistic version of the Stefan-Boltzmann law. var/energy_delta = ((A.temperature - B.temperature) ** 4) * 5.6704e-8 * connecting_tiles * 2.5 - var/maximum_energy_delta = max(0, min(A.temperature * A.heat_capacity * A.group_multiplier, B.temperature * B.heat_capacity * B.group_multiplier)) + var/maximum_energy_delta = max(0, min(A.temperature * A.heat_capacity() * A.group_multiplier, B.temperature * B.heat_capacity() * B.group_multiplier)) if(maximum_energy_delta > abs(energy_delta)) if(energy_delta < 0) maximum_energy_delta *= -1 energy_delta = maximum_energy_delta - A.set_temperature(A.temperature - energy_delta / (A.heat_capacity * A.group_multiplier)) - B.set_temperature(B.temperature + energy_delta / (B.heat_capacity * B.group_multiplier)) \ No newline at end of file + A.temperature -= energy_delta / (A.heat_capacity() * A.group_multiplier) + B.temperature += energy_delta / (B.heat_capacity() * B.group_multiplier) \ No newline at end of file diff --git a/code/ZAS/Controller.dm b/code/ZAS/Controller.dm index e85a00773c8..5f63d445c10 100644 --- a/code/ZAS/Controller.dm +++ b/code/ZAS/Controller.dm @@ -310,15 +310,11 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun return edge /datum/controller/air_system/proc/has_same_air(turf/A, turf/B) + if(A.oxygen != B.oxygen) return 0 + if(A.nitrogen != B.nitrogen) return 0 + if(A.toxins != B.toxins) return 0 + if(A.carbon_dioxide != B.carbon_dioxide) return 0 if(A.temperature != B.temperature) return 0 - - var/datum/gas_mixture/A_mix = A.return_air() - var/datum/gas_mixture/B_mix = B.return_air() - - for(var/gasid in A_mix.gases) - if(A_mix.gases[gasid] != B_mix.gases[gasid]) - return 0 - return 1 /datum/controller/air_system/proc/remove_edge(connection/c) diff --git a/code/ZAS/Diagnostic.dm b/code/ZAS/Diagnostic.dm index 09443f7c4ae..75e4ab50ce9 100644 --- a/code/ZAS/Diagnostic.dm +++ b/code/ZAS/Diagnostic.dm @@ -18,12 +18,8 @@ client/proc/Zone_Info(turf/T as null|turf) else mob << "No zone here." var/datum/gas_mixture/mix = T.return_air() - mob << "[mix.pressure] kPa [mix.temperature]C" - var/message = "" - for(var/gasid in mix.gases) - var/datum/gas/gas = mix.get_gas_by_id(gasid) - message += "[gas.display_short]: [mix.gases[gasid]]" - mob << message + mob << "[mix.return_pressure()] kPa [mix.temperature]C" + mob << "O2: [mix.oxygen] N2: [mix.nitrogen] CO2: [mix.carbon_dioxide] TX: [mix.toxins]" else if(zone_debug_images) for(var/zone in zone_debug_images) @@ -112,8 +108,8 @@ client/proc/Test_ZAS_Connection(var/turf/simulated/T as turf) client << "Plasma: [air.toxins]" client << "Carbon Dioxide: [air.carbon_dioxide]" client << "Temperature: [air.temperature] K" - client << "Heat Energy: [air.temperature * air.heat_capacity] J" - client << "Pressure: [air.pressure] KPa" + client << "Heat Energy: [air.temperature * air.heat_capacity()] J" + client << "Pressure: [air.return_pressure()] KPa" client << "" client << "Unsimulated Zone(space/catwalk) Tiles: [length(unsimulated_tiles)]" client << "Movable Objects: [length(movables())]" diff --git a/code/ZAS/Fire.dm b/code/ZAS/Fire.dm index b4a322c02a9..3e75e815199 100644 --- a/code/ZAS/Fire.dm +++ b/code/ZAS/Fire.dm @@ -140,8 +140,6 @@ Attach to transfer valve and open. BOOM. qdel(src) -#define FIRE_GAS_ROUNDING 0.1 //how much we round gas values to when fire updates a turf - /obj/fire/process() . = 1 @@ -158,9 +156,18 @@ Attach to transfer valve and open. BOOM. var/datum/gas_mixture/air_contents = S.return_air() + //and the volatile stuff from the air + var/datum/gas/volatile_fuel/fuel = locate() in air_contents.trace_gases + //since the air is processed in fractions, we need to make sure not to have any minuscle residue or //the amount of moles might get to low for some functions to catch them and thus result in wonky behaviour - air_contents.round_values(FIRE_GAS_ROUNDING) //the define is the level we clean to + if(air_contents.oxygen < 0.1) + air_contents.oxygen = 0 + if(air_contents.toxins < 0.1) + air_contents.toxins = 0 + if(fuel) + if(fuel.moles < 0.1) + air_contents.trace_gases.Remove(fuel) // Check if there is something to combust. if (!air_contents.check_recombustability(S)) @@ -183,14 +190,14 @@ Attach to transfer valve and open. BOOM. //im not sure how to implement a version that works for every creature so for now monkeys are firesafe for(var/mob/living/carbon/human/M in loc) - M.FireBurn(firelevel, air_contents.temperature, air_contents.pressure ) //Burn the humans! + M.FireBurn(firelevel, air_contents.temperature, air_contents.return_pressure() ) //Burn the humans! /*for(var/atom/A in loc) - A.fire_act(air_contents, air_contents.temperature, air_contents.volume) + A.fire_act(air_contents, air_contents.temperature, air_contents.return_volume()) */ // Burn the turf, too. - S.fire_act(air_contents, air_contents.temperature, air_contents.volume) + S.fire_act(air_contents, air_contents.temperature, air_contents.return_volume()) //spread for(var/direction in cardinal) @@ -249,21 +256,6 @@ turf/proc/apply_fire_protection() turf/simulated/apply_fire_protection() fire_protection = world.time -/datum/gas_mixture/proc/get_gas_fuel() - var/total_fuel = 0 - for(var/gasid in gases) - var/datum/gas/gas = get_gas_by_id(gasid) - if(gas.isFuel()) - total_fuel += gases[gasid] - return total_fuel - -/datum/gas_mixture/proc/get_gas_oxidiser() - var/total_oxidiser = 0 - for(var/gasid in gases) - var/datum/gas/gas = get_gas_by_id(gasid) - if(gas.isOxidiser()) - total_oxidiser += gases[gasid] - return total_oxidiser datum/gas_mixture/proc/zburn(var/turf/T, force_burn) // NOTE: zburn is also called from canisters and in tanks/pipes (via react()). Do NOT assume T is always a turf. @@ -271,8 +263,14 @@ datum/gas_mixture/proc/zburn(var/turf/T, force_burn) var/value = 0 if((temperature > PLASMA_MINIMUM_BURN_TEMPERATURE || force_burn) && check_recombustability(T)) - var/total_fuel = get_gas_fuel() - var/total_oxidiser = get_gas_oxidiser() + var/total_fuel = 0 + var/datum/gas/volatile_fuel/fuel = locate() in trace_gases + + total_fuel += toxins + + if(fuel) + //Volatile Fuel + total_fuel += fuel.moles var/can_use_turf=(T && istype(T)) if(can_use_turf) @@ -289,33 +287,32 @@ datum/gas_mixture/proc/zburn(var/turf/T, force_burn) //get the current inner energy of the gas mix //this must be taken here to prevent the addition or deletion of energy by a changing heat capacity - var/starting_energy = temperature * heat_capacity + var/starting_energy = temperature * heat_capacity() //determine the amount of oxygen used - total_oxidiser = min(total_oxidiser, 2 * total_fuel) + var/total_oxygen = min(oxygen, 2 * total_fuel) //determine the amount of fuel actually used - var/used_fuel_ratio = min(total_oxidiser / 2 , total_fuel) / total_fuel + var/used_fuel_ratio = min(oxygen / 2 , total_fuel) / total_fuel total_fuel = total_fuel * used_fuel_ratio - var/total_reactants = total_fuel + total_oxidiser + var/total_reactants = total_fuel + total_oxygen //determine the amount of reactants actually reacting var/used_reactants_ratio = Clamp(total_reactants * firelevel / zas_settings.Get(/datum/ZAS_Setting/fire_firelevel_multiplier), 0.2, total_reactants) / total_reactants //remove and add gasses as calculated - for(var/gasid in gases) - var/datum/gas/current_gas = get_gas_by_id(gasid) - if(current_gas.isOxidiser()) - adjust_gas(current_gas.gas_id, -gases[gasid] * used_reactants_ratio * current_gas.fuel_multiplier, 0) //take the cost of oxidiser + oxygen -= min(oxygen, total_oxygen * used_reactants_ratio ) - //fuels - for(var/gasid in gases) - var/datum/gas/current_gas = get_gas_by_id(gasid) - if(current_gas.isFuel()) - adjust_gas(current_gas.gas_id, -gases[gasid] * used_fuel_ratio * used_reactants_ratio * current_gas.fuel_multiplier, 0) //take the cost of fuel + toxins -= min(toxins, (toxins * used_fuel_ratio * used_reactants_ratio ) * 3) + if(toxins < 0) + toxins = 0 - adjust_gas(CARBON_DIOXIDE, max(2 * total_fuel, 0), 0) + carbon_dioxide += max(2 * total_fuel, 0) + + if(fuel) + fuel.moles -= (fuel.moles * used_fuel_ratio * used_reactants_ratio) * 5 //Fuel burns 5 times as quick + if(fuel.moles <= 0) del fuel if(can_use_turf) if(T.getFireFuel()>0) @@ -325,19 +322,21 @@ datum/gas_mixture/proc/zburn(var/turf/T, force_burn) A.burnFireFuel(used_fuel_ratio, used_reactants_ratio) //calculate the energy produced by the reaction and then set the new temperature of the mix - set_temperature((starting_energy + zas_settings.Get(/datum/ZAS_Setting/fire_fuel_energy_release) * total_fuel) / heat_capacity) + temperature = (starting_energy + zas_settings.Get(/datum/ZAS_Setting/fire_fuel_energy_release) * total_fuel) / heat_capacity() + update_values() value = total_reactants * used_reactants_ratio return value /datum/gas_mixture/proc/check_recombustability(var/turf/T) //this is a copy proc to continue a fire after its been started. - var/total_fuel = get_gas_fuel() - var/total_oxidiser = get_gas_oxidiser() + var/datum/gas/volatile_fuel/fuel = locate() in trace_gases - if(total_oxidiser && total_fuel) //have some fuel to burn - if(QUANTIZE(total_fuel * zas_settings.Get(/datum/ZAS_Setting/fire_consumption_rate)) >= BASE_ZAS_FUEL_REQ) + if(oxygen && (toxins || fuel)) + if(QUANTIZE(toxins * zas_settings.Get(/datum/ZAS_Setting/fire_consumption_rate)) >= BASE_ZAS_FUEL_REQ) + return 1 + if(fuel && QUANTIZE(fuel.moles * zas_settings.Get(/datum/ZAS_Setting/fire_consumption_rate)) >= BASE_ZAS_FUEL_REQ) return 1 // Check if we're actually in a turf or not before trying to check object fires. @@ -353,7 +352,7 @@ datum/gas_mixture/proc/zburn(var/turf/T, force_burn) var/still_burning=0 for(var/atom/A in T) if(!A) continue - if(!total_oxidiser/* || A.autoignition_temperature > temperature*/) + if(!oxygen/* || A.autoignition_temperature > temperature*/) A.extinguish() continue // if(!A.autoignition_temperature) @@ -374,16 +373,18 @@ datum/gas_mixture/proc/check_combustability(var/turf/T, var/objects) warning("check_combustability being asked to check a [T.type] instead of /turf.") return 0 */ - var/total_fuel = get_gas_fuel() - var/total_oxidiser = get_gas_oxidiser() - if(total_oxidiser && total_fuel) - if(QUANTIZE(total_fuel * zas_settings.Get(/datum/ZAS_Setting/fire_consumption_rate)) >= BASE_ZAS_FUEL_REQ) + var/datum/gas/volatile_fuel/fuel = locate() in trace_gases + + if(oxygen && (toxins || fuel)) + if(QUANTIZE(toxins * zas_settings.Get(/datum/ZAS_Setting/fire_consumption_rate)) >= BASE_ZAS_FUEL_REQ) + return 1 + if(fuel && QUANTIZE(fuel.moles * zas_settings.Get(/datum/ZAS_Setting/fire_consumption_rate)) >= BASE_ZAS_FUEL_REQ) return 1 if(objects && istype(T)) for(var/atom/A in T) - if(!A || !total_oxidiser || A.autoignition_temperature > temperature) continue + if(!A || !oxygen || A.autoignition_temperature > temperature) continue if(QUANTIZE(A.getFireFuel() * zas_settings.Get(/datum/ZAS_Setting/fire_consumption_rate)) >= A.volatility) return 1 @@ -391,23 +392,33 @@ datum/gas_mixture/proc/check_combustability(var/turf/T, var/objects) datum/gas_mixture/proc/calculate_firelevel(var/turf/T) //Calculates the firelevel based on one equation instead of having to do this multiple times in different areas. + + var/datum/gas/volatile_fuel/fuel = locate() in trace_gases var/total_fuel = 0 var/firelevel = 0 - var/total_oxidiser = 0 if(check_recombustability(T)) - total_fuel += get_gas_fuel() - total_oxidiser += get_gas_oxidiser() + total_fuel += toxins - var/total_combustables = (total_fuel + total_oxidiser) + if(T && istype(T)) + total_fuel += T.getFireFuel() - if(total_fuel > 0 && total_oxidiser > 0) + for(var/atom/A in T) + if(A) + total_fuel += A.getFireFuel() + + if(fuel) + total_fuel += fuel.moles + + var/total_combustables = (total_fuel + oxygen) + + if(total_fuel > 0 && oxygen > 0) //slows down the burning when the concentration of the reactants is low - var/dampening_multiplier = total_combustables / (total_moles) + var/dampening_multiplier = total_combustables / (total_combustables + nitrogen + carbon_dioxide) //calculates how close the mixture of the reactants is to the optimum - var/mix_multiplier = 1 / (1 + (5 * ((total_oxidiser / total_combustables) ** 2))) // Thanks, Mloc + var/mix_multiplier = 1 / (1 + (5 * ((oxygen / total_combustables) ** 2))) // Thanks, Mloc //toss everything together firelevel = zas_settings.Get(/datum/ZAS_Setting/fire_firelevel_multiplier) * mix_multiplier * dampening_multiplier diff --git a/code/ZAS/Plasma.dm b/code/ZAS/Plasma.dm index c6d5967bef4..dc1dc8d75bc 100644 --- a/code/ZAS/Plasma.dm +++ b/code/ZAS/Plasma.dm @@ -53,7 +53,7 @@ var/image/contamination_overlay = image('icons/effects/contamination.dmi') if(stat >= 2) return - if(species.breath_type != PLASMA) + if(species.breath_type != "plasma") //Burn skin if exposed. if(zas_settings.Get(/datum/ZAS_Setting/SKIN_BURNS)) @@ -124,6 +124,6 @@ var/image/contamination_overlay = image('icons/effects/contamination.dmi') if(istype(I) && zas_settings.Get(/datum/ZAS_Setting/CLOTH_CONTAMINATION)) var/datum/gas_mixture/environment = return_air() - if(environment.gases[PLASMA] > MOLES_PLASMA_VISIBLE + 1) + if(environment.toxins > MOLES_PLASMA_VISIBLE + 1) if(I.can_contaminate()) I.contaminate() diff --git a/code/ZAS/Turf.dm b/code/ZAS/Turf.dm index 4d22fba7e16..30320f71794 100644 --- a/code/ZAS/Turf.dm +++ b/code/ZAS/Turf.dm @@ -204,21 +204,41 @@ /turf/return_air() //Create gas mixture to hold data for passing - if(!air) - make_air() + var/datum/gas_mixture/GM = new - air.set_temperature(temperature) + GM.oxygen = oxygen + GM.carbon_dioxide = carbon_dioxide + GM.nitrogen = nitrogen + GM.toxins = toxins - return air + GM.temperature = temperature + GM.update_values() + + return GM /turf/remove_air(amount as num) - var/datum/gas_mixture/my_air = return_air() - return my_air.remove(amount) + var/datum/gas_mixture/GM = new + + var/sum = oxygen + carbon_dioxide + nitrogen + toxins + if(sum>0) + GM.oxygen = (oxygen/sum)*amount + GM.carbon_dioxide = (carbon_dioxide/sum)*amount + GM.nitrogen = (nitrogen/sum)*amount + GM.toxins = (toxins/sum)*amount + + GM.temperature = temperature + GM.update_values() + + return GM /turf/simulated/assume_air(datum/gas_mixture/giver) var/datum/gas_mixture/my_air = return_air() my_air.merge(giver) +/turf/simulated/remove_air(amount as num) + var/datum/gas_mixture/my_air = return_air() + return my_air.remove(amount) + /turf/simulated/return_air() if(zone) if(!zone.invalid) @@ -236,11 +256,10 @@ /turf/proc/make_air() air = new/datum/gas_mixture - air.set_temperature(temperature) + air.temperature = temperature + air.adjust(oxygen, carbon_dioxide, nitrogen, toxins) air.group_multiplier = 1 - air.set_volume(CELL_VOLUME) - if(starting_gases) - air.adjust(starting_gases) + air.volume = CELL_VOLUME /turf/simulated/proc/c_copy_air() if(!air) air = new/datum/gas_mixture diff --git a/code/ZAS/Zone.dm b/code/ZAS/Zone.dm index fcbaf396f1a..eb23fe7d1e5 100644 --- a/code/ZAS/Zone.dm +++ b/code/ZAS/Zone.dm @@ -50,9 +50,9 @@ Class Procs: /zone/New() air_master.add_zone(src) - air.set_temperature(TCMB) + air.temperature = TCMB air.group_multiplier = 1 - air.set_volume(CELL_VOLUME) + air.volume = CELL_VOLUME /zone/proc/add(turf/simulated/T) #ifdef ZASDBG @@ -128,13 +128,9 @@ Class Procs: /zone/proc/dbg_data(mob/M) M << name - var/gas_message = "" - for(var/gasid in air.gases) - var/datum/gas/gas = air.get_gas_by_id(gasid) - gas_message += "[gas.display_short]: [air.gases[gasid]]" - M << gas_message - M << "P: [air.pressure] kPa V: [air.volume]L T: [air.temperature]°K ([air.temperature - T0C]°C)" - M << "O2 per N2: [(air.gases[NITROGEN] ? air.gases[OXYGEN]/air.gases[NITROGEN] : "N/A")] Moles: [air.total_moles]" + M << "O2: [air.oxygen] N2: [air.nitrogen] CO2: [air.carbon_dioxide] P: [air.toxins]" + M << "P: [air.return_pressure()] kPa V: [air.volume]L T: [air.temperature]°K ([air.temperature - T0C]°C)" + M << "O2 per N2: [(air.nitrogen ? air.oxygen/air.nitrogen : "N/A")] Moles: [air.total_moles]" M << "Simulated: [contents.len] ([air.group_multiplier])" //M << "Unsimulated: [unsimulated_contents.len]" //M << "Edges: [edges.len]" @@ -147,7 +143,7 @@ Class Procs: else space_edges++ space_coefficient += E.coefficient - M << "[E:air:pressure]kPa" + M << "[E:air:return_pressure()]kPa" M << "Zone Edges: [zone_edges]" M << "Space Edges: [space_edges] ([space_coefficient] connections)" diff --git a/code/ZAS/_gas_datum.dm b/code/ZAS/_gas_datum.dm deleted file mode 100644 index 0bef446f2db..00000000000 --- a/code/ZAS/_gas_datum.dm +++ /dev/null @@ -1,73 +0,0 @@ -var/global/list/gas_datum_list -var/global/list/gas_specific_heat - -/datum/gas - var/display_name = "" - var/display_short = "" - - var/gas_id = "" //all ids must be unique - - var/specific_heat = 0 - - var/gas_flags = 0 - var/fuel_multiplier = 1 //multiplier of rate of burning - -/datum/gas/proc/isFuel() - return gas_flags & IS_FUEL - -/datum/gas/proc/isOxidiser() - return gas_flags & IS_OXIDISER - -/datum/gas/oxygen - display_name = "Oxygen" - display_short = "O2" - gas_id = OXYGEN - specific_heat = SPECIFIC_HEAT_AIR - gas_flags = IS_OXIDISER | ALWAYS_SHOW - -/datum/gas/nitrogen - display_name = "Nitrogen" - display_short = "N2" - gas_id = NITROGEN - specific_heat = SPECIFIC_HEAT_AIR - gas_flags = ALWAYS_SHOW - -/datum/gas/plasma - display_name = "Plasma" - display_short = "PL" - gas_id = PLASMA - specific_heat = SPECIFIC_HEAT_PLASMA - gas_flags = IS_FUEL | AUTO_FILTERED | AUTO_LOGGING | ALWAYS_SHOW - fuel_multiplier = 3 - -/datum/gas/co2 - display_name = "Carbon Dioxide" - display_short = "CO2" - gas_id = CARBON_DIOXIDE - specific_heat = SPECIFIC_HEAT_CDO - gas_flags = AUTO_FILTERED | AUTO_LOGGING | ALWAYS_SHOW - -/datum/gas/n2o - display_name = "Nitrous Oxide" - display_short = "N2O" - gas_id = NITROUS_OXIDE - specific_heat = SPECIFIC_HEAT_NIO - gas_flags = AUTO_FILTERED | AUTO_LOGGING - -//ping me when someone figures out what the hell this is for -/* -/datum/gas/oxygen_agent_b - display_name = "Oxygen Agent B" - display_short = "OAB" - gas_id = "oxygen_agent_b" - specific_heat = 300 -*/ - -/datum/gas/volatile_fuel - display_name = "Volatile Fuel" - display_short = "VF" - gas_id = VOLATILE_FUEL - specific_heat = 30 - gas_flags = IS_FUEL | AUTO_LOGGING - fuel_multiplier = 5 - diff --git a/code/ZAS/_gas_mixture.dm b/code/ZAS/_gas_mixture.dm index bebaf82d3d2..9bb1daa958b 100644 --- a/code/ZAS/_gas_mixture.dm +++ b/code/ZAS/_gas_mixture.dm @@ -4,10 +4,14 @@ What are the archived variables for? This prevents race conditions that arise based on the order of tile processing. */ -#define STANDARD_GAS_ROUNDING 0.0001 +#define SPECIFIC_HEAT_TOXIN 200 +#define SPECIFIC_HEAT_AIR 20 +#define SPECIFIC_HEAT_CDO 30 +#define HEAT_CAPACITY_CALCULATION(oxygen,carbon_dioxide,nitrogen,toxins) \ + max(0, carbon_dioxide * SPECIFIC_HEAT_CDO + (oxygen + nitrogen) * SPECIFIC_HEAT_AIR + toxins * SPECIFIC_HEAT_TOXIN) #define MINIMUM_HEAT_CAPACITY 0.0003 -#define QUANTIZE(variable) (round(variable,STANDARD_GAS_ROUNDING)) +#define QUANTIZE(variable) (round(variable,0.0001)) #define TRANSFER_FRACTION 5 //What fraction (1/#) of the air difference to try and transfer // /vg/ SHIT @@ -34,7 +38,27 @@ What are the archived variables for? slmaster.mouse_opacity = 0 return 1 -/datum/gas_mixture +/datum/gas/sleeping_agent/specific_heat = 40 //These are used for the "Trace Gases" stuff, but is buggy. + +/datum/gas/oxygen_agent_b/specific_heat = 300 + +/datum/gas/volatile_fuel/specific_heat = 30 + +/datum/gas + var/moles = 0 + + var/specific_heat = 0 + + var/moles_archived = 0 + +/datum/gas_mixture/ + var/oxygen = 0 //Holds the "moles" of each of the four gases. + var/carbon_dioxide = 0 + var/nitrogen = 0 + var/toxins = 0 + + var/total_moles = 0 //Updated when a reaction occurs. + var/volume = CELL_VOLUME var/temperature = 0 //in Kelvin, use calculate_temperature() to modify @@ -43,16 +67,16 @@ What are the archived variables for? //Size of the group this gas_mixture is representing. //=1 for singletons - var/total_moles = 0 - var/graphics=0 var/pressure=0 - var/heat_capacity = MINIMUM_HEAT_CAPACITY + var/list/datum/gas/trace_gases = list() //Seemed to be a good idea that was abandoned - var/list/gases //stores all the gas numbers for this mixture - var/list/archived_gases //archiving! + var/tmp/oxygen_archived //These are variables for use with the archived data + var/tmp/carbon_dioxide_archived + var/tmp/nitrogen_archived + var/tmp/toxins_archived var/tmp/temperature_archived @@ -60,132 +84,175 @@ What are the archived variables for? var/tmp/fuel_burnt = 0 //var/datum/reagents/aerosols - +/* /datum/gas_mixture/New() - gases = list() - if(!gas_datum_list) - for(var/newgas in (typesof(/datum/gas) - /datum/gas)) - var/datum/gas/new_datum_gas = new newgas() - gas_datum_list += list(new_datum_gas.gas_id = new_datum_gas) //associates the gas with its id - gas_specific_heat += list(new_datum_gas.gas_id = new_datum_gas.specific_heat) - - for(var/gasid in gas_datum_list) //initialise the gases themselves - gases += list("[gasid]" = 0) - - archived_gases = gases.Copy() - -//gets a gas in the gas list -/datum/gas_mixture/proc/get_gas_by_id(gasid) - if(gasid in gas_datum_list) - return gas_datum_list[gasid] - else - return null - + //create_reagents(10) +*/ //FOR THE LOVE OF GOD PLEASE USE THIS PROC //Call it with negative numbers to remove gases. -/datum/gas_mixture/proc/adjust(list/datum/gas/adjusts = list()) +/datum/gas_mixture/proc/adjust(o2 = 0, co2 = 0, n2 = 0, tx = 0, list/datum/gas/traces = list()) //Purpose: Adjusting the gases within a airmix //Called by: Nothing, yet! - //Inputs: The values of the gases to adjust done as a list(id = moles) + //Inputs: The values of the gases to adjust //Outputs: null - for(var/a_gas in adjusts) - adjust_gas(a_gas, adjusts[a_gas], 0) + oxygen = max(0, oxygen + o2) + carbon_dioxide = max(0, carbon_dioxide + co2) + nitrogen = max(0, nitrogen + n2) + toxins = max(0, toxins + tx) + + //handle trace gasses + for(var/datum/gas/G in traces) + var/datum/gas/T = locate(G.type) in trace_gases + if(T) + T.moles = max(G.moles + T.moles, 0) + else if(G.moles > 0) + trace_gases |= G + update_values() return -//Takes a gas string, and the amount of moles to adjust by. -//if use_group is 0, the group_multiplier isn't considered -//supports negative values -/datum/gas_mixture/proc/adjust_gas(gasid, moles, use_group = 1) +//Takes a gas string, and the amount of moles to adjust by. Calls update_values() if update isn't 0. +/datum/gas_mixture/proc/adjust_gas(gasid, moles, update = 1) if(moles == 0) return + switch(gasid) + if("oxygen") + if (group_multiplier != 1) + oxygen += moles/group_multiplier + else + oxygen += moles + if("plasma") + if (group_multiplier != 1) + toxins += moles/group_multiplier + else + toxins += moles + if("carbon_dioxide") + if (group_multiplier != 1) + carbon_dioxide += moles/group_multiplier + else + carbon_dioxide += moles + if("nitrogen") + if (group_multiplier != 1) + nitrogen += moles/group_multiplier + else + nitrogen += moles - if(group_multiplier != 1 && use_group) - set_gas(gasid, gases[gasid] + moles/group_multiplier) - else - set_gas(gasid, gases[gasid] + moles) -//Sets the value of a gas using a gas string and a mole number -//Note: this should be the only way in which gas numbers should ever be edited -//The gas system must be airtight - never bypass this -/datum/gas_mixture/proc/set_gas(gasid, moles) - ASSERT(gasid in gases) + if(update) + update_values() - if(moles < 0) - return +/* +/datum/gas_mixture/proc/create_reagents(var/max_vol) + aerosols = new /datum/reagents(max_vol) + aerosols.my_atom = src +*/ - var/old_moles = gases[gasid] +//tg seems to like using these a lot +/datum/gas_mixture/proc/return_temperature() + return temperature - gases[gasid] = max(0, moles) - pressure += ((moles - old_moles) * R_IDEAL_GAS_EQUATION * temperature) / volume //add the maths of the new gas - heat_capacity = max(MINIMUM_HEAT_CAPACITY, heat_capacity + (moles - old_moles) * gas_specific_heat[gasid]) - total_moles += (moles - old_moles) +/datum/gas_mixture/proc/return_volume() + return max(0, volume) + /datum/gas_mixture/proc/thermal_energy() - return temperature*heat_capacity + return temperature*heat_capacity() /////////////////////////////// //PV=nRT - related procedures// /////////////////////////////// -/datum/gas_mixture/proc/set_temperature(var/new_temperature) - //Purpose: Changes the temperature of a gas_mixture +/datum/gas_mixture/proc/heat_capacity() + //Purpose: Returning the heat capacity of the gas mix //Called by: UNKNOWN - //Inputs: New temperature to set to - //Outputs: None - new_temperature = max(0, new_temperature) - - var/old_temperature = temperature - - temperature = new_temperature - - if(old_temperature) //can't divide by 0 - and we only have pressure if T > 0 - pressure *= new_temperature/old_temperature //V is unchanging, T changes by a factor, P must change by the same factor - else - pressure = (total_moles * R_IDEAL_GAS_EQUATION * temperature) / volume //recalc - -/datum/gas_mixture/proc/set_volume(var/new_volume) - //Purpose: Changes the volume of a gas_mixture - //Called by: UNKNOWN - //Inputs: New volume to set to - //Outputs: None - new_volume = max(0, new_volume) - - var/old_volume = volume - - volume = new_volume - - if(old_volume && new_volume && pressure) //can't divide by 0 NO SHIT COMIC - pressure /= new_volume/old_volume //since PV is a constant, the ratio change in V is inverse for P - else - if(volume) - pressure = (total_moles * R_IDEAL_GAS_EQUATION * temperature) / volume //recalc - -/datum/gas_mixture/proc/heat_capacity_calc(var/list/hc_gases = gases) - //Purpose: Returning the heat capacity of a gas mix - //Called by: UNKNOWN - //Inputs: List of gases (or none, so the gas list itself) + //Inputs: None //Outputs: Heat capacity - var/hc_current + var/heat_capacity = HEAT_CAPACITY_CALCULATION(oxygen,carbon_dioxide,nitrogen,toxins) - for(var/gasid in hc_gases) - hc_current += gases[gasid] * gas_specific_heat[gasid] + if(trace_gases && trace_gases.len) //sanity check because somehow the tracegases gets nulled? + for(var/datum/gas/trace_gas in trace_gases) + heat_capacity += trace_gas.moles*trace_gas.specific_heat - return max(MINIMUM_HEAT_CAPACITY, hc_current) + return max(MINIMUM_HEAT_CAPACITY,heat_capacity) -/datum/gas_mixture/proc/round_values(var/rounding_error = STANDARD_GAS_ROUNDING) - //Purpose: Trims the fat off values - //Called by: Fire code that cleans up values after processing - //Inputs: Rounding error +/datum/gas_mixture/proc/heat_capacity_archived() + //Purpose: Returning the archived heat capacity of the gas mix + //Called by: UNKNOWN + //Inputs: None + //Outputs: Archived heat capacity + + var/heat_capacity_archived = HEAT_CAPACITY_CALCULATION(oxygen_archived,carbon_dioxide_archived,nitrogen_archived,toxins_archived) + + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + heat_capacity_archived += trace_gas.moles_archived*trace_gas.specific_heat + + return max(MINIMUM_HEAT_CAPACITY,heat_capacity_archived) + +/datum/gas_mixture/proc/total_moles() + return total_moles + /*var/moles = oxygen + carbon_dioxide + nitrogen + toxins + + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + moles += trace_gas.moles + return moles*/ + +/datum/gas_mixture/proc/return_pressure() + //Purpose: Calculating Current Pressure + //Called by: + //Inputs: None + //Outputs: Gas pressure. + return pressure + +// proc/return_temperature() + //Purpose: + //Inputs: + //Outputs: + +// return temperature + +// proc/return_volume() + //Purpose: + //Inputs: + //Outputs: + +// return max(0, volume) + +// proc/thermal_energy() + //Purpose: + //Inputs: + //Outputs: + +// return temperature*heat_capacity() + +/datum/gas_mixture/proc/update_values() + //Purpose: Calculating and storing values which were normally called CONSTANTLY + //Called by: Anything that changes values within a gas mix. + //Inputs: None //Outputs: None - for(var/gasid in gases) - adjust_gas(gasid, - (gases[gasid] - round(gases[gasid], rounding_error))) + total_moles = oxygen + carbon_dioxide + nitrogen + toxins + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + total_moles += trace_gas.moles + +/* + if(aerosols.total_volume) + total_moles += aerosols.total_volume +*/ + + if(volume>0) + pressure = total_moles()*R_IDEAL_GAS_EQUATION*temperature/volume + else + pressure = 0 + + return //////////////////////////////////////////// //Procedures used for very specific events// @@ -201,17 +268,19 @@ What are the archived variables for? // If configured and cold, maek ice if(zas_settings.Get(/datum/ZAS_Setting/ice_formation)) - if(temperature <= TEMPERATURE_ICE_FORMATION && pressure>MIN_PRESSURE_ICE_FORMATION) + if(temperature <= TEMPERATURE_ICE_FORMATION && return_pressure()>MIN_PRESSURE_ICE_FORMATION) // If we're just forming, do a probability check. Otherwise, KEEP IT ON~ // This ordering will hopefully keep it from sampling random noise every damn tick. //if(was_icy || (!was_icy && prob(25))) graphics |= GRAPHICS_COLD - if(gases[PLASMA] > MOLES_PLASMA_VISIBLE) + if(toxins > MOLES_PLASMA_VISIBLE) graphics |= GRAPHICS_PLASMA - if(gases[NITROUS_OXIDE] > MOLES_N2O_VISIBLE) - graphics |= GRAPHICS_N2O + if(length(trace_gases)) + var/datum/gas/sleeping_agent = locate(/datum/gas/sleeping_agent) in trace_gases + if(sleeping_agent && (sleeping_agent.moles > 1)) + graphics |= GRAPHICS_N2O /* if(aerosols && aerosols.total_volume >= 1) graphics |= GRAPHICS_REAGENTS @@ -238,7 +307,7 @@ What are the archived variables for? return zburn(null) /*var/energy_released = 0 - var/old_heat_capacity = heat_capacity + var/old_heat_capacity = heat_capacity() var/datum/gas/volatile_fuel/fuel_store = locate(/datum/gas/volatile_fuel) in trace_gases if(fuel_store) //General volatile gas burn @@ -283,7 +352,7 @@ What are the archived variables for? fuel_burnt += (plasma_burn_rate)*(1+oxygen_burn_rate) if(energy_released > 0) - var/new_heat_capacity = heat_capacity + var/new_heat_capacity = heat_capacity() if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) temperature = (temperature*old_heat_capacity + energy_released)/new_heat_capacity update_values() @@ -294,14 +363,21 @@ What are the archived variables for? //Procs for general gas spread calculations.// ////////////////////////////////////////////// + /datum/gas_mixture/proc/archive() //Purpose: Archives the current gas values //Called by: UNKNOWN //Inputs: None //Outputs: 1 - for(var/gasid in gases) - archived_gases[gasid] = gases[gasid] + oxygen_archived = oxygen + carbon_dioxide_archived = carbon_dioxide + nitrogen_archived = nitrogen + toxins_archived = toxins + + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + trace_gas.moles_archived = trace_gas.moles temperature_archived = temperature @@ -318,13 +394,19 @@ What are the archived variables for? if(!giver) return 0 - + if(((giver.oxygen > MINIMUM_AIR_TO_SUSPEND) && (giver.oxygen >= oxygen*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((giver.carbon_dioxide > MINIMUM_AIR_TO_SUSPEND) && (giver.carbon_dioxide >= carbon_dioxide*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((giver.nitrogen > MINIMUM_AIR_TO_SUSPEND) && (giver.nitrogen >= nitrogen*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((giver.toxins > MINIMUM_AIR_TO_SUSPEND) && (giver.toxins >= toxins*MINIMUM_AIR_RATIO_TO_SUSPEND))) + return 0 if(abs(giver.temperature - temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) return 0 - for(var/gasid in gases) - if((giver.gases[gasid] > MINIMUM_AIR_TO_SUSPEND) && (giver.gases[gasid] >= gases[gasid]*MINIMUM_AIR_RATIO_TO_SUSPEND)) - return 0 + if(giver.trace_gases.len) + for(var/datum/gas/trace_gas in giver.trace_gases) + var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases + if((trace_gas.moles > MINIMUM_AIR_TO_SUSPEND) && (!corresponding || (trace_gas.moles >= corresponding.moles*MINIMUM_AIR_RATIO_TO_SUSPEND))) + return 0 return merge(giver) @@ -338,18 +420,35 @@ What are the archived variables for? return 0 if(abs(temperature-giver.temperature)>MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) - var/self_heat_capacity = heat_capacity*group_multiplier - var/giver_heat_capacity = giver.heat_capacity*giver.group_multiplier + var/self_heat_capacity = heat_capacity()*group_multiplier + var/giver_heat_capacity = giver.heat_capacity()*giver.group_multiplier var/combined_heat_capacity = giver_heat_capacity + self_heat_capacity if(combined_heat_capacity != 0) - set_temperature((giver.temperature*giver_heat_capacity + temperature*self_heat_capacity)/combined_heat_capacity) + temperature = (giver.temperature*giver_heat_capacity + temperature*self_heat_capacity)/combined_heat_capacity - if(giver.group_multiplier>1) - for(var/gasid in gases) - adjust_gas(gasid, giver.gases[gasid] * giver.group_multiplier) + if((group_multiplier>1)||(giver.group_multiplier>1)) + oxygen += giver.oxygen*giver.group_multiplier/group_multiplier + carbon_dioxide += giver.carbon_dioxide*giver.group_multiplier/group_multiplier + nitrogen += giver.nitrogen*giver.group_multiplier/group_multiplier + toxins += giver.toxins*giver.group_multiplier/group_multiplier else - for(var/gasid in gases) - adjust_gas(gasid, giver.gases[gasid]) + oxygen += giver.oxygen + carbon_dioxide += giver.carbon_dioxide + nitrogen += giver.nitrogen + toxins += giver.toxins + + if(giver.trace_gases.len) + for(var/datum/gas/trace_gas in giver.trace_gases) + var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases + if(!corresponding) + corresponding = new trace_gas.type() + trace_gases += corresponding + corresponding.moles += trace_gas.moles*giver.group_multiplier/group_multiplier +/* + if(giver.aerosols.total_volume > 1) + giver.aerosols.trans_to_atmos(src,aerosols.total_volume) +*/ + update_values() // Let the garbage collector handle it, faster according to /tg/ testers //del(giver) @@ -365,19 +464,39 @@ What are the archived variables for? if(group_multiplier==0) return null - var/sum = total_moles + var/sum = total_moles() amount = min(amount,sum) //Can not take more air than tile has! if(amount <= 0) - return new/datum/gas_mixture + return null var/datum/gas_mixture/removed = new - removed.set_temperature(temperature) - for(var/gasid in gases) - var/taken_gas = QUANTIZE(gases[gasid] / sum) * amount //the gas we lose - not yet subtracted - adjust_gas(gasid, -taken_gas) //don't update just yet - negative subtracts - removed.adjust_gas(gasid, taken_gas) //slap the copied gas in + removed.oxygen = QUANTIZE((oxygen/sum)*amount) + removed.nitrogen = QUANTIZE((nitrogen/sum)*amount) + removed.carbon_dioxide = QUANTIZE((carbon_dioxide/sum)*amount) + removed.toxins = QUANTIZE((toxins/sum)*amount) + + oxygen -= removed.oxygen/group_multiplier + nitrogen -= removed.nitrogen/group_multiplier + carbon_dioxide -= removed.carbon_dioxide/group_multiplier + toxins -= removed.toxins/group_multiplier + + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + var/datum/gas/corresponding = new trace_gas.type() + removed.trace_gases += corresponding + + corresponding.moles = (trace_gas.moles/sum)*amount + trace_gas.moles -= corresponding.moles/group_multiplier +/* + if(aerosols.total_volume > 1) + removed.aerosols.trans_to_atmos(src,(aerosols.total_volume/sum)*amount) +*/ + + removed.temperature = temperature + update_values() + removed.update_values() return removed @@ -392,7 +511,31 @@ What are the archived variables for? ratio = min(ratio, 1) - return remove(total_moles * ratio) //use the sum removal + var/datum/gas_mixture/removed = new + + removed.oxygen = QUANTIZE(oxygen*ratio) + removed.nitrogen = QUANTIZE(nitrogen*ratio) + removed.carbon_dioxide = QUANTIZE(carbon_dioxide*ratio) + removed.toxins = QUANTIZE(toxins*ratio) + + oxygen -= removed.oxygen/group_multiplier + nitrogen -= removed.nitrogen/group_multiplier + carbon_dioxide -= removed.carbon_dioxide/group_multiplier + toxins -= removed.toxins/group_multiplier + + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + var/datum/gas/corresponding = new trace_gas.type() + removed.trace_gases += corresponding + + corresponding.moles = trace_gas.moles*ratio + trace_gas.moles -= corresponding.moles/group_multiplier + + removed.temperature = temperature + update_values() + removed.update_values() + + return removed /datum/gas_mixture/proc/check_then_remove(amount) //Purpose: Similar to remove(...) but first checks to see if the amount of air removed is small enough @@ -401,9 +544,9 @@ What are the archived variables for? //Inputs: Number of moles to remove //Outputs: Removed air or 0 if it can remove air or not. - amount = Clamp(amount, 0, total_moles) //Can not take more air than tile has! + amount = min(amount,total_moles()) //Can not take more air than tile has! - if((amount > MINIMUM_AIR_RATIO_TO_SUSPEND) && (amount > total_moles*MINIMUM_AIR_RATIO_TO_SUSPEND)) + if((amount > MINIMUM_AIR_RATIO_TO_SUSPEND) && (amount > total_moles()*MINIMUM_AIR_RATIO_TO_SUSPEND)) return 0 return remove(amount) @@ -414,10 +557,21 @@ What are the archived variables for? //Inputs: Gas to copy //Outputs: 1 - set_temperature(sample.temperature) + oxygen = sample.oxygen + carbon_dioxide = sample.carbon_dioxide + nitrogen = sample.nitrogen + toxins = sample.toxins + total_moles = sample.total_moles() - for(var/gasid in sample.gases) - set_gas(gasid, sample.gases[gasid], 0) + trace_gases.len=null + if(sample.trace_gases.len > 0) + for(var/datum/gas/trace_gas in sample.trace_gases) + var/datum/gas/corresponding = new trace_gas.type() + trace_gases += corresponding + + corresponding.moles = trace_gas.moles + + temperature = sample.temperature return 1 @@ -431,38 +585,82 @@ What are the archived variables for? if(!istype(sharer)) return - if(abs(temperature_archived - sharer.temperature_archived) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) + var/delta_oxygen = QUANTIZE(oxygen_archived - sharer.oxygen_archived)/TRANSFER_FRACTION + var/delta_carbon_dioxide = QUANTIZE(carbon_dioxide_archived - sharer.carbon_dioxide_archived)/TRANSFER_FRACTION + var/delta_nitrogen = QUANTIZE(nitrogen_archived - sharer.nitrogen_archived)/TRANSFER_FRACTION + var/delta_toxins = QUANTIZE(toxins_archived - sharer.toxins_archived)/TRANSFER_FRACTION + + var/delta_temperature = (temperature_archived - sharer.temperature_archived) + + if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((abs(delta_toxins) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_toxins) >= toxins_archived*MINIMUM_AIR_RATIO_TO_SUSPEND))) return 0 - for(var/gasid in gases) - var/archived_own_gas = archived_gases[gasid] - var/archived_sharer_gas = sharer.archived_gases[gasid] - var/gas_delta = abs(QUANTIZE(archived_own_gas - archived_sharer_gas)/TRANSFER_FRACTION) //the difference in gas moles + if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) + return 0 - if((gas_delta > MINIMUM_AIR_TO_SUSPEND) && (gas_delta >= archived_own_gas*MINIMUM_AIR_RATIO_TO_SUSPEND)) - return 0 + if(sharer.trace_gases.len) + for(var/datum/gas/trace_gas in sharer.trace_gases) + if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4) + var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases + if(corresponding) + if(trace_gas.moles_archived >= corresponding.moles_archived*MINIMUM_AIR_RATIO_TO_SUSPEND*4) + return 0 + else + return 0 - if((gas_delta > MINIMUM_AIR_TO_SUSPEND) && (gas_delta >= archived_sharer_gas*MINIMUM_AIR_RATIO_TO_SUSPEND)) - return -1 + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4) + if(!locate(trace_gas.type) in sharer.trace_gases) + return 0 + + if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= sharer.oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= sharer.carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= sharer.nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((abs(delta_toxins) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_toxins) >= sharer.toxins_archived*MINIMUM_AIR_RATIO_TO_SUSPEND))) + return -1 + + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4) + var/datum/gas/corresponding = locate(trace_gas.type) in sharer.trace_gases + if(corresponding) + if(trace_gas.moles_archived >= corresponding.moles_archived*MINIMUM_AIR_RATIO_TO_SUSPEND*4) + return -1 + else + return -1 return 1 -/datum/gas_mixture/proc/check_turf(turf/model_turf) +/datum/gas_mixture/proc/check_turf(turf/model) //Purpose: Used to compare the gases in an unsimulated turf with the gas in a simulated one. //Called by: Sharing air (mimicing) with adjacent unsimulated turfs //Inputs: Unsimulated turf //Outputs: 1 if safe to mimic, 0 if needs to break airgroup. - var/datum/gas_mixture/model = model_turf.return_air() + var/delta_oxygen = (oxygen_archived - model.oxygen)/TRANSFER_FRACTION + var/delta_carbon_dioxide = (carbon_dioxide_archived - model.carbon_dioxide)/TRANSFER_FRACTION + var/delta_nitrogen = (nitrogen_archived - model.nitrogen)/TRANSFER_FRACTION + var/delta_toxins = (toxins_archived - model.toxins)/TRANSFER_FRACTION - if(abs(temperature_archived - model.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) + var/delta_temperature = (temperature_archived - model.temperature) + + if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((abs(delta_toxins) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_toxins) >= toxins_archived*MINIMUM_AIR_RATIO_TO_SUSPEND))) + return 0 + if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) return 0 - for(var/gasid in gases) - var/archived_gas = archived_gases[gasid] - var/gas_delta = abs((archived_gas - model.gases[gasid])/TRANSFER_FRACTION) - if((gas_delta > MINIMUM_AIR_TO_SUSPEND) && (gas_delta >= archived_gas*MINIMUM_AIR_RATIO_TO_SUSPEND)) - return 0 + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4) + return 0 + return 1 /datum/gas_mixture/proc/share(datum/gas_mixture/sharer) @@ -476,6 +674,11 @@ What are the archived variables for? if(!istype(sharer)) return + var/delta_oxygen = QUANTIZE(oxygen_archived - sharer.oxygen_archived)/TRANSFER_FRACTION + var/delta_carbon_dioxide = QUANTIZE(carbon_dioxide_archived - sharer.carbon_dioxide_archived)/TRANSFER_FRACTION + var/delta_nitrogen = QUANTIZE(nitrogen_archived - sharer.nitrogen_archived)/TRANSFER_FRACTION + var/delta_toxins = QUANTIZE(toxins_archived - sharer.toxins_archived)/TRANSFER_FRACTION + var/delta_temperature = (temperature_archived - sharer.temperature_archived) var/old_self_heat_capacity = 0 @@ -486,58 +689,141 @@ What are the archived variables for? var/heat_sharer_to_self = 0 var/heat_capacity_sharer_to_self = 0 - var/moved_moles = 0 - - for(var/gasid in gases) - var/gas_delta = QUANTIZE(archived_gases[gasid] - sharer.archived_gases[gasid])/TRANSFER_FRACTION - if(gas_delta && abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) //difference in gases and temperature - var/datum/gas/current_gas = get_gas_by_id(gasid) - var/gas_heat_capacity = current_gas.specific_heat - if(gas_delta > 0) - heat_self_to_sharer += gas_heat_capacity * temperature_archived - heat_capacity_self_to_sharer += gas_heat_capacity - else - heat_sharer_to_self -= gas_heat_capacity * temperature_archived - heat_capacity_sharer_to_self -= gas_heat_capacity - - adjust_gas(gasid, -gas_delta) //delay update - adjust_gas handles the group multiplier - sharer.adjust_gas(gasid, gas_delta) - - moved_moles += gas_delta - if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) - old_self_heat_capacity = heat_capacity*group_multiplier - old_sharer_heat_capacity = sharer.heat_capacity*sharer.group_multiplier + var/delta_air = delta_oxygen+delta_nitrogen + if(delta_air) + var/air_heat_capacity = SPECIFIC_HEAT_AIR*delta_air + if(delta_air > 0) + heat_self_to_sharer += air_heat_capacity*temperature_archived + heat_capacity_self_to_sharer += air_heat_capacity + else + heat_sharer_to_self -= air_heat_capacity*sharer.temperature_archived + heat_capacity_sharer_to_self -= air_heat_capacity + + if(delta_carbon_dioxide) + var/carbon_dioxide_heat_capacity = SPECIFIC_HEAT_CDO*delta_carbon_dioxide + if(delta_carbon_dioxide > 0) + heat_self_to_sharer += carbon_dioxide_heat_capacity*temperature_archived + heat_capacity_self_to_sharer += carbon_dioxide_heat_capacity + else + heat_sharer_to_self -= carbon_dioxide_heat_capacity*sharer.temperature_archived + heat_capacity_sharer_to_self -= carbon_dioxide_heat_capacity + + if(delta_toxins) + var/toxins_heat_capacity = SPECIFIC_HEAT_TOXIN*delta_toxins + if(delta_toxins > 0) + heat_self_to_sharer += toxins_heat_capacity*temperature_archived + heat_capacity_self_to_sharer += toxins_heat_capacity + else + heat_sharer_to_self -= toxins_heat_capacity*sharer.temperature_archived + heat_capacity_sharer_to_self -= toxins_heat_capacity + + old_self_heat_capacity = heat_capacity()*group_multiplier + old_sharer_heat_capacity = sharer.heat_capacity()*sharer.group_multiplier + + oxygen -= delta_oxygen/group_multiplier + sharer.oxygen += delta_oxygen/sharer.group_multiplier + + carbon_dioxide -= delta_carbon_dioxide/group_multiplier + sharer.carbon_dioxide += delta_carbon_dioxide/sharer.group_multiplier + + nitrogen -= delta_nitrogen/group_multiplier + sharer.nitrogen += delta_nitrogen/sharer.group_multiplier + + toxins -= delta_toxins/group_multiplier + sharer.toxins += delta_toxins/sharer.group_multiplier + + var/moved_moles = (delta_oxygen + delta_carbon_dioxide + delta_nitrogen + delta_toxins) + + var/list/trace_types_considered = list() + + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + + var/datum/gas/corresponding = locate(trace_gas.type) in sharer.trace_gases + var/delta = 0 + + if(corresponding) + delta = QUANTIZE(trace_gas.moles_archived - corresponding.moles_archived)/TRANSFER_FRACTION + else + corresponding = new trace_gas.type() + sharer.trace_gases += corresponding + + delta = trace_gas.moles_archived/TRANSFER_FRACTION + + trace_gas.moles -= delta/group_multiplier + corresponding.moles += delta/sharer.group_multiplier + + if(delta) + var/individual_heat_capacity = trace_gas.specific_heat*delta + if(delta > 0) + heat_self_to_sharer += individual_heat_capacity*temperature_archived + heat_capacity_self_to_sharer += individual_heat_capacity + else + heat_sharer_to_self -= individual_heat_capacity*sharer.temperature_archived + heat_capacity_sharer_to_self -= individual_heat_capacity + + moved_moles += delta + + trace_types_considered += trace_gas.type + + + if(sharer.trace_gases.len) + for(var/datum/gas/trace_gas in sharer.trace_gases) + if(trace_gas.type in trace_types_considered) continue + else + var/datum/gas/corresponding + var/delta = 0 + + corresponding = new trace_gas.type() + trace_gases += corresponding + + delta = trace_gas.moles_archived/TRANSFER_FRACTION + + trace_gas.moles -= delta/sharer.group_multiplier + corresponding.moles += delta/group_multiplier + + //Guaranteed transfer from sharer to self + var/individual_heat_capacity = trace_gas.specific_heat*delta + heat_sharer_to_self += individual_heat_capacity*sharer.temperature_archived + heat_capacity_sharer_to_self += individual_heat_capacity + + moved_moles += -delta + update_values() + sharer.update_values() if(abs(delta_temperature) > 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 if(new_self_heat_capacity > MINIMUM_HEAT_CAPACITY) - set_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) + 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.set_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) + 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 if(abs(old_sharer_heat_capacity) > MINIMUM_HEAT_CAPACITY) if(abs(new_sharer_heat_capacity/old_sharer_heat_capacity - 1) < 0.10) // <10% change in sharer heat capacity temperature_share(sharer, OPEN_HEAT_TRANSFER_COEFFICIENT) if((delta_temperature > MINIMUM_TEMPERATURE_TO_MOVE) || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE) - var/delta_pressure = temperature_archived*(total_moles + moved_moles) - sharer.temperature_archived*(sharer.total_moles - moved_moles) + var/delta_pressure = temperature_archived*(total_moles() + moved_moles) - sharer.temperature_archived*(sharer.total_moles() - moved_moles) return delta_pressure*R_IDEAL_GAS_EQUATION/volume else return 0 -/datum/gas_mixture/proc/mimic(turf/model_turf, border_multiplier) +/datum/gas_mixture/proc/mimic(turf/model, border_multiplier) //Purpose: Used transfer gas from a more pressurised tile to a less presurised unsimulated tile. //Called by: "sharing" from unsimulated to simulated turfs. //Inputs: Unsimulated turf, Multiplier for gas transfer (optional) //Outputs: Amount of gas exchanged - var/datum/gas_mixture/model = model_turf.return_air() + var/delta_oxygen = QUANTIZE(oxygen_archived - model.oxygen)/TRANSFER_FRACTION + var/delta_carbon_dioxide = QUANTIZE(carbon_dioxide_archived - model.carbon_dioxide)/TRANSFER_FRACTION + var/delta_nitrogen = QUANTIZE(nitrogen_archived - model.nitrogen)/TRANSFER_FRACTION + var/delta_toxins = QUANTIZE(toxins_archived - model.toxins)/TRANSFER_FRACTION var/delta_temperature = (temperature_archived - model.temperature) @@ -545,39 +831,68 @@ What are the archived variables for? var/old_self_heat_capacity = 0 var/heat_capacity_transferred = 0 - var/moved_moles - - for(var/gasid in gases) - var/gas_delta = QUANTIZE(archived_gases[gasid] - model.gases[gasid])/TRANSFER_FRACTION - - if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) - var/gas_heat_capacity = gas_specific_heat[gasid] - heat_transferred -= gas_heat_capacity * model.temperature - heat_capacity_transferred -= gas_heat_capacity - - if(border_multiplier) - adjust_gas(gasid, -gas_delta*border_multiplier) - else - adjust_gas(gasid, -gas_delta) - - moved_moles += gas_delta - - if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) - old_self_heat_capacity = heat_capacity*group_multiplier + + var/delta_air = delta_oxygen+delta_nitrogen + if(delta_air) + var/air_heat_capacity = SPECIFIC_HEAT_AIR*delta_air + heat_transferred -= air_heat_capacity*model.temperature + heat_capacity_transferred -= air_heat_capacity + + if(delta_carbon_dioxide) + var/carbon_dioxide_heat_capacity = SPECIFIC_HEAT_CDO*delta_carbon_dioxide + heat_transferred -= carbon_dioxide_heat_capacity*model.temperature + heat_capacity_transferred -= carbon_dioxide_heat_capacity + + if(delta_toxins) + var/toxins_heat_capacity = SPECIFIC_HEAT_TOXIN*delta_toxins + heat_transferred -= toxins_heat_capacity*model.temperature + heat_capacity_transferred -= toxins_heat_capacity + + old_self_heat_capacity = heat_capacity()*group_multiplier + + if(border_multiplier) + oxygen -= delta_oxygen*border_multiplier/group_multiplier + carbon_dioxide -= delta_carbon_dioxide*border_multiplier/group_multiplier + nitrogen -= delta_nitrogen*border_multiplier/group_multiplier + toxins -= delta_toxins*border_multiplier/group_multiplier + else + oxygen -= delta_oxygen/group_multiplier + carbon_dioxide -= delta_carbon_dioxide/group_multiplier + nitrogen -= delta_nitrogen/group_multiplier + toxins -= delta_toxins/group_multiplier + + var/moved_moles = (delta_oxygen + delta_carbon_dioxide + delta_nitrogen + delta_toxins) + + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + var/delta = 0 + + delta = trace_gas.moles_archived/TRANSFER_FRACTION + + if(border_multiplier) + trace_gas.moles -= delta*border_multiplier/group_multiplier + else + trace_gas.moles -= delta/group_multiplier + + var/heat_cap_transferred = delta*trace_gas.specific_heat + heat_transferred += heat_cap_transferred*temperature_archived + heat_capacity_transferred += heat_cap_transferred + moved_moles += delta + update_values() if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) var/new_self_heat_capacity = old_self_heat_capacity - heat_capacity_transferred if(new_self_heat_capacity > MINIMUM_HEAT_CAPACITY) if(border_multiplier) - set_temperature((old_self_heat_capacity*temperature - heat_capacity_transferred*border_multiplier*temperature_archived)/new_self_heat_capacity) + temperature = (old_self_heat_capacity*temperature - heat_capacity_transferred*border_multiplier*temperature_archived)/new_self_heat_capacity else - set_temperature((old_self_heat_capacity*temperature - heat_capacity_transferred*border_multiplier*temperature_archived)/new_self_heat_capacity) + temperature = (old_self_heat_capacity*temperature - heat_capacity_transferred*border_multiplier*temperature_archived)/new_self_heat_capacity - temperature_mimic(model, model_turf.thermal_conductivity, border_multiplier) + temperature_mimic(model, model.thermal_conductivity, border_multiplier) if((delta_temperature > MINIMUM_TEMPERATURE_TO_MOVE) || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE) - var/delta_pressure = temperature_archived*(total_moles + moved_moles) - model.temperature*(model.total_moles) + var/delta_pressure = temperature_archived*(total_moles() + moved_moles) - model.temperature*(model.oxygen+model.carbon_dioxide+model.nitrogen+model.toxins) return delta_pressure*R_IDEAL_GAS_EQUATION/volume else return 0 @@ -585,8 +900,8 @@ What are the archived variables for? /datum/gas_mixture/proc/check_both_then_temperature_share(datum/gas_mixture/sharer, conduction_coefficient) var/delta_temperature = (temperature_archived - sharer.temperature_archived) - var/self_heat_capacity = heat_capacity_calc(archived_gases) - var/sharer_heat_capacity = sharer.heat_capacity_calc(archived_gases) + var/self_heat_capacity = heat_capacity_archived() + var/sharer_heat_capacity = sharer.heat_capacity_archived() var/self_temperature_delta = 0 var/sharer_temperature_delta = 0 @@ -608,8 +923,8 @@ What are the archived variables for? && (abs(sharer_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*sharer.temperature_archived)) return -1 - set_temperature(temperature + self_temperature_delta) - sharer.set_temperature(sharer.temperature + sharer_temperature_delta) + temperature += self_temperature_delta + sharer.temperature += sharer_temperature_delta return 1 //Logic integrated from: temperature_share(sharer, conduction_coefficient) for efficiency @@ -617,8 +932,8 @@ What are the archived variables for? /datum/gas_mixture/proc/check_me_then_temperature_share(datum/gas_mixture/sharer, conduction_coefficient) var/delta_temperature = (temperature_archived - sharer.temperature_archived) - var/self_heat_capacity = heat_capacity_calc(archived_gases) - var/sharer_heat_capacity = sharer.heat_capacity_calc(archived_gases) + var/self_heat_capacity = heat_capacity_archived() + var/sharer_heat_capacity = sharer.heat_capacity_archived() var/self_temperature_delta = 0 var/sharer_temperature_delta = 0 @@ -636,8 +951,8 @@ What are the archived variables for? && (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived)) return 0 - set_temperature(temperature + self_temperature_delta) - sharer.set_temperature(sharer.temperature + sharer_temperature_delta) + temperature += self_temperature_delta + sharer.temperature += sharer_temperature_delta return 1 //Logic integrated from: temperature_share(sharer, conduction_coefficient) for efficiency @@ -649,7 +964,7 @@ What are the archived variables for? var/sharer_temperature_delta = 0 if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) - var/self_heat_capacity = heat_capacity_calc(archived_gases) + var/self_heat_capacity = heat_capacity_archived() if((sharer.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) var/heat = conduction_coefficient*delta_temperature* \ @@ -664,7 +979,7 @@ What are the archived variables for? && (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived)) return 0 - set_temperature(temperature + self_temperature_delta) + temperature += self_temperature_delta sharer.temperature += sharer_temperature_delta return 1 @@ -675,7 +990,7 @@ What are the archived variables for? var/self_temperature_delta = 0 if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) - var/self_heat_capacity = heat_capacity_calc(archived_gases) + var/self_heat_capacity = heat_capacity_archived() if((model.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) var/heat = conduction_coefficient*delta_temperature* \ @@ -687,7 +1002,7 @@ What are the archived variables for? && (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived)) return 0 - set_temperature(temperature + self_temperature_delta) + temperature += self_temperature_delta return 1 //Logic integrated from: temperature_mimic(model, conduction_coefficient) for efficiency @@ -695,8 +1010,8 @@ What are the archived variables for? /datum/gas_mixture/proc/temperature_share(datum/gas_mixture/sharer, conduction_coefficient) var/delta_temperature = (temperature_archived - sharer.temperature_archived) if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) - var/self_heat_capacity = heat_capacity_calc(archived_gases) - var/sharer_heat_capacity = sharer.heat_capacity_calc(archived_gases) + var/self_heat_capacity = heat_capacity_archived() + var/sharer_heat_capacity = sharer.heat_capacity_archived() if(!group_multiplier) message_admins("Error! The gas mixture (ref \ref[src]) has no group multiplier!") return @@ -705,13 +1020,13 @@ What are the archived variables for? var/heat = conduction_coefficient*delta_temperature* \ (self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity)) - set_temperature(temperature - heat/(self_heat_capacity*group_multiplier)) - sharer.set_temperature( sharer.temperature + heat/(sharer_heat_capacity*sharer.group_multiplier)) + temperature -= heat/(self_heat_capacity*group_multiplier) + sharer.temperature += heat/(sharer_heat_capacity*sharer.group_multiplier) /datum/gas_mixture/proc/temperature_mimic(turf/model, conduction_coefficient, border_multiplier) var/delta_temperature = (temperature - model.temperature) if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) - var/self_heat_capacity = heat_capacity//_archived() + var/self_heat_capacity = heat_capacity()//_archived() if(!group_multiplier) message_admins("Error! The gas mixture (ref \ref[src]) has no group multiplier!") return @@ -721,19 +1036,20 @@ What are the archived variables for? (self_heat_capacity*model.heat_capacity/(self_heat_capacity+model.heat_capacity)) if(border_multiplier) - set_temperature(temperature - heat*border_multiplier/(self_heat_capacity*group_multiplier)) + temperature -= heat*border_multiplier/(self_heat_capacity*group_multiplier) else - set_temperature(temperature - heat/(self_heat_capacity*group_multiplier)) + temperature -= heat/(self_heat_capacity*group_multiplier) /datum/gas_mixture/proc/temperature_turf_share(turf/simulated/sharer, conduction_coefficient) var/delta_temperature = (temperature_archived - sharer.temperature) if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) - var/self_heat_capacity = heat_capacity + var/self_heat_capacity = heat_capacity() if((sharer.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) - var/heat = conduction_coefficient*delta_temperature * (self_heat_capacity*sharer.heat_capacity/(self_heat_capacity+sharer.heat_capacity)) + var/heat = conduction_coefficient*delta_temperature* \ + (self_heat_capacity*sharer.heat_capacity/(self_heat_capacity+sharer.heat_capacity)) - set_temperature(temperature - heat/(self_heat_capacity*group_multiplier)) + temperature -= heat/(self_heat_capacity*group_multiplier) sharer.temperature += heat/sharer.heat_capacity /datum/gas_mixture/proc/compare(datum/gas_mixture/sample) @@ -743,27 +1059,68 @@ What are the archived variables for? //Outputs: 1 if can rebuild, 0 if not. if(!sample) return 0 - for(var/gasid in gases) - var/current_gas = gases[gasid] - var/sample_gas = sample.gases[gasid] - if((abs(current_gas - sample_gas) > MINIMUM_AIR_TO_SUSPEND) && \ - ((current_gas < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample_gas) || (current_gas > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample_gas))) - return 0 + if((abs(oxygen-sample.oxygen) > MINIMUM_AIR_TO_SUSPEND) && \ + ((oxygen < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.oxygen) || (oxygen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.oxygen))) + return 0 + if((abs(nitrogen-sample.nitrogen) > MINIMUM_AIR_TO_SUSPEND) && \ + ((nitrogen < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.nitrogen) || (nitrogen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.nitrogen))) + return 0 + if((abs(carbon_dioxide-sample.carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && \ + ((carbon_dioxide < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide) || (carbon_dioxide > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide))) + return 0 + if((abs(toxins-sample.toxins) > MINIMUM_AIR_TO_SUSPEND) && \ + ((toxins < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.toxins) || (toxins > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.toxins))) + return 0 - if(total_moles > MINIMUM_AIR_TO_SUSPEND) + if(total_moles() > MINIMUM_AIR_TO_SUSPEND) if((abs(temperature-sample.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) && \ ((temperature < (1-MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND)*sample.temperature) || (temperature > (1+MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND)*sample.temperature))) //world << "temp fail [temperature] & [sample.temperature]" return 0 + var/check_moles + if(sample.trace_gases.len) + for(var/datum/gas/trace_gas in sample.trace_gases) + var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases + if(corresponding) + check_moles = corresponding.moles + else + check_moles = 0 + + if((abs(trace_gas.moles - check_moles) > MINIMUM_AIR_TO_SUSPEND) && \ + ((check_moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles) || (check_moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles))) + return 0 + + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases + if(corresponding) + check_moles = corresponding.moles + else + check_moles = 0 + + if((abs(trace_gas.moles - check_moles) > MINIMUM_AIR_TO_SUSPEND) && \ + ((trace_gas.moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*check_moles) || (trace_gas.moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*check_moles))) + return 0 + return 1 /datum/gas_mixture/proc/add(datum/gas_mixture/right_side) if(!right_side) return 0 + oxygen += right_side.oxygen + carbon_dioxide += right_side.carbon_dioxide + nitrogen += right_side.nitrogen + toxins += right_side.toxins - for(var/gasid in right_side.gases) - adjust_gas(gasid, right_side.gases[gasid], 0) + if(trace_gases.len || right_side.trace_gases.len) + for(var/datum/gas/trace_gas in right_side.trace_gases) + var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases + if(!corresponding) + corresponding = new trace_gas.type() + trace_gases += corresponding + corresponding.moles += trace_gas.moles + update_values() return 1 /datum/gas_mixture/proc/subtract(datum/gas_mixture/right_side) @@ -772,17 +1129,42 @@ What are the archived variables for? //Inputs: Gas mix to remove //Outputs: 1 - for(var/gasid in right_side.gases) - adjust_gas(gasid, -right_side.gases[gasid], 0) + oxygen = max(oxygen - right_side.oxygen) + carbon_dioxide = max(carbon_dioxide - right_side.carbon_dioxide) + nitrogen = max(nitrogen - right_side.nitrogen) + toxins = max(toxins - right_side.toxins) + if(trace_gases.len || right_side.trace_gases.len) + for(var/datum/gas/trace_gas in right_side.trace_gases) + var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases + if(corresponding) + corresponding.moles = max(0, corresponding.moles - trace_gas.moles) + + update_values() return 1 /datum/gas_mixture/proc/multiply(factor) + oxygen *= factor + carbon_dioxide *= factor + nitrogen *= factor + toxins *= factor - for(var/gasid in gases) - adjust_gas(gasid, (factor - 1) * gases[gasid], 0) + if(trace_gases && trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + trace_gas.moles *= factor + update_values() return 1 /datum/gas_mixture/proc/divide(factor) - return multiply(1/factor) + oxygen /= factor + carbon_dioxide /= factor + nitrogen /= factor + toxins /= factor + + if(trace_gases && trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + trace_gas.moles /= factor + + update_values() + return 1 diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 517757ddb9f..f3416255076 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -285,8 +285,8 @@ else var/list/nicename = null var/list/tankcheck = null - var/breathes = OXYGEN //default, we'll check later - var/list/tank_contents = list() + var/breathes = "oxygen" //default, we'll check later + var/list/contents = list() if(ishuman(C)) var/mob/living/carbon/human/H = C @@ -304,31 +304,50 @@ if (!isnull(t.manipulated_by) && t.manipulated_by != C.real_name) contents.Add(t.air_contents.total_moles) //Someone messed with the tank and put unknown gasses continue //in it, so we're going to believe the tank is what it says it is + switch(breathes) + //These tanks we're sure of their contents + if("nitrogen") //So we're a bit more picky about them. + + if(t.air_contents.nitrogen && !t.air_contents.oxygen) + contents.Add(t.air_contents.nitrogen) + else + contents.Add(0) + + if ("oxygen") + if(t.air_contents.oxygen && !t.air_contents.toxins) + contents.Add(t.air_contents.oxygen) + else + contents.Add(0) + + // No races breath this, but never know about downstream servers. + if ("carbon dioxide") + if(t.air_contents.carbon_dioxide && !t.air_contents.toxins) + contents.Add(t.air_contents.carbon_dioxide) + else + contents.Add(0) + + // ACK ACK ACK Plasmen + if ("plasma") + if(t.air_contents.toxins) + contents.Add(t.air_contents.toxins) + else + contents.Add(0) - if(t.air_contents.gases[breathes]) - var/toxic_found - for(var/toxicid in C.toxic_to_breathe) - if(t.air_contents.gases[toxicid]) - tank_contents.Add(0) - toxic_found = 1 - break - if(!toxic_found) - tank_contents.Add(t.air_contents.gases[breathes]) else //no tank so we set contents to 0 - tank_contents.Add(0) + contents.Add(0) //Alright now we know the contents of the tanks so we have to pick the best one. var/best = 0 var/bestcontents = 0 - for(var/i=1, i < tank_contents.len + 1 , ++i) - if(!tank_contents[i]) + for(var/i=1, i < contents.len + 1 , ++i) + if(!contents[i]) continue - if(tank_contents[i] > bestcontents) + if(contents[i] > bestcontents) best = i - bestcontents = tank_contents[i] + bestcontents = contents[i] //We've determined the best container now we set it as our internals @@ -342,7 +361,7 @@ if(C.internals) C.internals.icon_state = "internal1" else - C << "You don't have a[breathes==OXYGEN ? "n oxygen" : addtext(" ",breathes)] tank." + C << "You don't have a[breathes=="oxygen" ? "n oxygen" : addtext(" ",breathes)] tank." if("act_intent") usr.a_intent_change("right") if("help") diff --git a/code/controllers/Processes/pipenet.dm b/code/controllers/Processes/pipenet.dm index a25f51cc013..60c5d8d039c 100644 --- a/code/controllers/Processes/pipenet.dm +++ b/code/controllers/Processes/pipenet.dm @@ -6,10 +6,8 @@ var/global/list/obj/machinery/atmospherics/atmos_machines = list() schedule_interval = 20 // every 2 seconds /datum/controller/process/pipenet/doWork() - //world << atmos_machines.len - for(var/obj/machinery/atmosmachinery in atmos_machines) - //world << "processing [atmosmachinery]" - ASSERT(istype(atmosmachinery) || istype(atmosmachinery, /obj/machinery/portable_atmospherics)) + for(var/obj/machinery/atmospherics/atmosmachinery in atmos_machines) + ASSERT(istype(atmosmachinery)) if(!atmosmachinery.disposed) if(atmosmachinery.process()) scheck() diff --git a/code/controllers/_DynamicAreaLighting_TG.dm b/code/controllers/_DynamicAreaLighting_TG.dm index 06d093d7994..3f898980741 100644 --- a/code/controllers/_DynamicAreaLighting_TG.dm +++ b/code/controllers/_DynamicAreaLighting_TG.dm @@ -139,6 +139,12 @@ atom //Turfs with opacity when they are constructed will trigger nearby lights to update //Turfs and atoms with luminosity when they are constructed will create a light_source automatically +turf/New() + ..() + if(luminosity) + if(light) WARNING("[type] - Don't set lights up manually during New(), We do it automatically.") + trueLuminosity = luminosity * luminosity + light = new(src) //Movable atoms with opacity when they are constructed will trigger nearby lights to update //Movable atoms with luminosity when they are constructed will create a light_source automatically diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index e7ef277ce89..1d7fbe5f6c3 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -145,12 +145,12 @@ datum/controller/game_controller/proc/setup_objects() world << "Initializing pipe networks" sleep(-1) - for(var/obj/machinery/atmospherics/machine in atmos_machines) + for(var/obj/machinery/atmospherics/machine in machines) machine.build_network() world << "Initializing atmos machinery." sleep(-1) - for(var/obj/machinery/atmospherics/unary/U in atmos_machines) + for(var/obj/machinery/atmospherics/unary/U in machines) if(istype(U, /obj/machinery/atmospherics/unary/vent_pump)) var/obj/machinery/atmospherics/unary/vent_pump/T = U T.broadcast_status() diff --git a/code/game/dna/genes/disabilities.dm b/code/game/dna/genes/disabilities.dm index 556e7ac1e0c..5fbc872f762 100644 --- a/code/game/dna/genes/disabilities.dm +++ b/code/game/dna/genes/disabilities.dm @@ -56,7 +56,7 @@ M << "[deactivation_message]" else testing("[name] has no deactivation message.") - return ..() + ..() /datum/dna/gene/disability/hallucinate name="Hallucinate" diff --git a/code/game/gamemodes/events/ninja_equipment.dm b/code/game/gamemodes/events/ninja_equipment.dm index 64f29698408..38b6caf53eb 100644 --- a/code/game/gamemodes/events/ninja_equipment.dm +++ b/code/game/gamemodes/events/ninja_equipment.dm @@ -313,17 +313,27 @@ ________________________________________________________________________________ else var/datum/gas_mixture/environment = T.return_air() - var/pressure = environment.pressure - var/total_moles = environment.total_moles + var/pressure = environment.return_pressure() + var/total_moles = environment.total_moles() dat += "Air Pressure: [round(pressure,0.1)] kPa" - dat += "
Hidden Menu"
diff --git a/code/game/gamemodes/steal_items.dm b/code/game/gamemodes/steal_items.dm
index 61bc0af6d93..776e3826958 100644
--- a/code/game/gamemodes/steal_items.dm
+++ b/code/game/gamemodes/steal_items.dm
@@ -219,7 +219,7 @@
max=28
/datum/theft_objective/number/traitor/plasma_gas/getAmountStolen(var/obj/item/I)
- return I:air_contents:gases[PLASMA]
+ return I:air_contents:toxins
/datum/theft_objective/number/traitor/coins
name = "credits of coins (in bag)"
diff --git a/code/game/gamemodes/vampire/vampire.dm b/code/game/gamemodes/vampire/vampire.dm
index 13bf831a5ac..89883165ff7 100644
--- a/code/game/gamemodes/vampire/vampire.dm
+++ b/code/game/gamemodes/vampire/vampire.dm
@@ -164,7 +164,7 @@
var/icon/flat = getFlatIcon(Mind.current, SOUTH, 1, 1)
end_icons += flat
tempstate = end_icons.len
- text += {"
[Mind.key] was [Mind.name] ("}
+ text += {"
[Mind.key] was [Mind.name] ("}
if(Mind.current.stat == DEAD)
text += "died"
flat.Turn(90)
@@ -177,7 +177,7 @@
var/icon/sprotch = icon('icons/effects/blood.dmi', "floor1-old")
end_icons += sprotch
tempstate = end_icons.len
- text += {"
[Mind.key] was [Mind.name] ("}
+ text += {"
[Mind.key] was [Mind.name] ("}
text += "body destroyed"
text += ")"
diff --git a/code/game/machinery/Freezer.dm b/code/game/machinery/Freezer.dm
index 55798d5a1e1..5721baaeb0d 100644
--- a/code/game/machinery/Freezer.dm
+++ b/code/game/machinery/Freezer.dm
@@ -105,7 +105,7 @@
var/dat = {"Cryo gas cooling system