diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm index a3d0214b985..263d9da4462 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm @@ -1,10 +1,10 @@ -#define FILTER_NOTHING -1 -//very cleverly using the gas index defines so as to simplify a bunch of logic -#define FILTER_PLASMA GAS_PL -#define FILTER_OXYGEN GAS_O2 -#define FILTER_NITROGEN GAS_N2 -#define FILTER_CARBONDIOXIDE GAS_CO2 -#define FILTER_NITROUSOXIDE GAS_N2O +#define FILTER_NOTHING "" +//very cleverly using the gas IDs so as to simplify a bunch of logic +#define FILTER_PLASMA "plasma" +#define FILTER_OXYGEN "o2" +#define FILTER_NITROGEN "n2" +#define FILTER_CARBONDIOXIDE "co2" +#define FILTER_NITROUSOXIDE "n2o" /obj/machinery/atmospherics/components/trinary/filter icon_state = "filter_off" @@ -109,12 +109,15 @@ Filter types: var/datum/gas_mixture/filtered_out = new filtered_out.temperature = removed.temperature - if(filter_type > 0) + if(filter_type && removed.gases[filter_type]) + filtered_out.assert_gas(filter_type) filtered_out.gases[filter_type][MOLES] = removed.gases[filter_type][MOLES] removed.gases[filter_type][MOLES] = 0 - if(filter_type == FILTER_PLASMA) - filtered_out.gases[GAS_AGENT_B][MOLES] = removed.gases[GAS_AGENT_B][MOLES] - removed.gases[GAS_AGENT_B][MOLES] = 0 + if(filter_type == FILTER_PLASMA && removed.gases["agent_b"]) + filtered_out.assert_gas("agent_b") + filtered_out.gases["agent_b"][MOLES] = removed.gases["agent_b"][MOLES] + removed.gases["agent_b"][MOLES] = 0 + removed.garbage_collect() else filtered_out = null diff --git a/code/ATMOSPHERICS/components/unary_devices/cryo.dm b/code/ATMOSPHERICS/components/unary_devices/cryo.dm index 6c1361f3433..d1432314454 100644 --- a/code/ATMOSPHERICS/components/unary_devices/cryo.dm +++ b/code/ATMOSPHERICS/components/unary_devices/cryo.dm @@ -269,7 +269,7 @@ if(occupant.bodytemperature < T0C) occupant.sleeping = max(5 / efficiency, (1 / occupant.bodytemperature) * 2000 / efficiency) occupant.Paralyse(max(5 / efficiency, (1 / occupant.bodytemperature) * 3000 / efficiency)) - if(air_contents.gases[GAS_O2][MOLES] > 2) + if(air_contents.gases["o2"] && air_contents.gases["o2"][MOLES] > 2) if(occupant.getOxyLoss()) occupant.adjustOxyLoss(-1) else occupant.adjustOxyLoss(-1) diff --git a/code/ATMOSPHERICS/components/unary_devices/oxygen_generator.dm b/code/ATMOSPHERICS/components/unary_devices/oxygen_generator.dm index f0da2640824..55215da0753 100644 --- a/code/ATMOSPHERICS/components/unary_devices/oxygen_generator.dm +++ b/code/ATMOSPHERICS/components/unary_devices/oxygen_generator.dm @@ -46,7 +46,8 @@ var/added_oxygen = oxygen_content - total_moles air_contents.temperature = (current_heat_capacity*air_contents.temperature + 20*added_oxygen*T0C)/(current_heat_capacity+20*added_oxygen) - air_contents.gases[GAS_O2][MOLES] += added_oxygen + air_contents.assert_gas("o2") + air_contents.gases["o2"][MOLES] += added_oxygen update_parents() diff --git a/code/ATMOSPHERICS/components/unary_devices/tank.dm b/code/ATMOSPHERICS/components/unary_devices/tank.dm index d5ecc65b7e9..dfff3ced12f 100644 --- a/code/ATMOSPHERICS/components/unary_devices/tank.dm +++ b/code/ATMOSPHERICS/components/unary_devices/tank.dm @@ -14,27 +14,28 @@ air_contents.volume = volume air_contents.temperature = T20C if(gas_type) + air_contents.assert_gas(gas_type) air_contents.gases[gas_type][MOLES] = AIR_CONTENTS name = "[name] ([air_contents.gases[gas_type][GAS_NAME]])" /obj/machinery/atmospherics/components/unary/tank/carbon_dioxide - gas_type = GAS_CO2 + gas_type = "co2" /obj/machinery/atmospherics/components/unary/tank/toxins icon_state = "orange" - gas_type = GAS_PL + gas_type = "plasma" /obj/machinery/atmospherics/components/unary/tank/oxygen_agent_b icon_state = "orange_2" - gas_type = GAS_AGENT_B + gas_type = "agent_b" /obj/machinery/atmospherics/components/unary/tank/oxygen icon_state = "blue" - gas_type = GAS_O2 + gas_type = "o2" /obj/machinery/atmospherics/components/unary/tank/nitrogen icon_state = "red" - gas_type = GAS_N2 + gas_type = "n2" /obj/machinery/atmospherics/components/unary/tank/air icon_state = "grey" @@ -43,5 +44,6 @@ /obj/machinery/atmospherics/components/unary/tank/air/New() ..() var/datum/gas_mixture/air_contents = AIR1 - air_contents.gases[GAS_O2][MOLES] = AIR_CONTENTS * 0.2 - air_contents.gases[GAS_N2][MOLES] = AIR_CONTENTS * 0.8 \ No newline at end of file + air_contents.assert_gases("o2", "n2") + air_contents.gases["o2"][MOLES] = AIR_CONTENTS * 0.2 + air_contents.gases["n2"][MOLES] = AIR_CONTENTS * 0.8 \ No newline at end of file diff --git a/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm index 74e4d62fe1e..08d0b46e308 100644 --- a/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm +++ b/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm @@ -171,7 +171,7 @@ if(scrubbing & SCRUBBING) var/should_we_scrub = FALSE for(var/gas in environment.gases) - if(gas[GAS_INDEX] <= 2) + if(gas[GAS_ID] == "nitrogen" || gas[GAS_ID] == "oxygen") continue if(gas[MOLES]) should_we_scrub = TRUE @@ -181,24 +181,36 @@ //Take a gas sample var/datum/gas_mixture/removed = tile.remove_air(transfer_moles) + var/list/removed_gases = removed.gases if (isnull(removed)) //in space return //Filter it var/datum/gas_mixture/filtered_out = new + var/list/filtered_gases = filtered_out.gases filtered_out.temperature = removed.temperature - if(scrub_Toxins) - filtered_out.gases[GAS_PL][MOLES] = removed.gases[GAS_PL][MOLES] - removed.gases[GAS_PL][MOLES] = 0 - if(scrub_CO2) - filtered_out.gases[GAS_CO2][MOLES] = removed.gases[GAS_CO2][MOLES] - removed.gases[GAS_CO2][MOLES] = 0 - if(TRUE) //no var for scrubbing agent b but I wanted the indentation to line up - filtered_out.gases[GAS_AGENT_B][MOLES] = removed.gases[GAS_AGENT_B][MOLES] - removed.gases[GAS_AGENT_B][MOLES] = 0 - if(scrub_N2O) - filtered_out.gases[GAS_N2O][MOLES] = removed.gases[GAS_N2O][MOLES] - removed.gases[GAS_AGENT_B][MOLES] = 0 + + if(scrub_Toxins && removed_gases["plasma"]) + filtered_out.assert_gas("plasma") + filtered_gases["plasma"][MOLES] = removed_gases["plasma"][MOLES] + removed.gases["plasma"][MOLES] = 0 + + if(scrub_CO2 && removed_gases["co2"]) + filtered_out.assert_gas("co2") + filtered_out.gases["co2"][MOLES] = removed_gases["co2"][MOLES] + removed.gases["co2"][MOLES] = 0 + + if(removed_gases["agent_b"]) + filtered_out.assert_gas("agent_b") + filtered_out.gases["agent_b"][MOLES] = removed_gases["agent_b"][MOLES] + removed.gases["agent_b"][MOLES] = 0 + + if(scrub_N2O && removed_gases["n2o"]) + filtered_out.assert_gas("n2o") + filtered_out.gases["n2o"][MOLES] = removed_gases["n2o"][MOLES] + removed.gases["n2o"][MOLES] = 0 + + removed.garbage_collect() //Remix the resulting gases air_contents.merge(filtered_out) diff --git a/code/LINDA/LINDA_fire.dm b/code/LINDA/LINDA_fire.dm index a8b0799fc96..52ea8059ee0 100644 --- a/code/LINDA/LINDA_fire.dm +++ b/code/LINDA/LINDA_fire.dm @@ -11,9 +11,13 @@ var/datum/gas_mixture/air_contents = return_air() if(!air_contents) return 0 + + var/oxy = air_contents.gases["o2"] ? air_contents.gases["o2"][MOLES] : 0 + var/tox = air_contents.gases["plasma"] ? air_contents.gases["plasma"][MOLES] : 0 + if(active_hotspot) if(soh) - if(air_contents.gases[GAS_PL][MOLES] > 0.5 && air_contents.gases[GAS_O2][MOLES] > 0.5) + if(tox > 0.5 && oxy > 0.5) if(active_hotspot.temperature < exposed_temperature) active_hotspot.temperature = exposed_temperature if(active_hotspot.volume < exposed_volume) @@ -22,11 +26,11 @@ var/igniting = 0 - if((exposed_temperature > PLASMA_MINIMUM_BURN_TEMPERATURE) && air_contents.gases[GAS_PL][MOLES] > 0.5) + if((exposed_temperature > PLASMA_MINIMUM_BURN_TEMPERATURE) && tox > 0.5) igniting = 1 if(igniting) - if(air_contents.gases[GAS_O2][MOLES] < 0.5 || air_contents.gases[GAS_PL][MOLES] < 0.5) + if(oxy < 0.5 || tox < 0.5) return 0 active_hotspot = PoolOrNew(/obj/effect/hotspot, src) @@ -104,7 +108,7 @@ qdel(src) return - if(!(location.air) || location.air.gases[GAS_PL][MOLES] < 0.5 || location.air.gases[GAS_O2][MOLES] < 0.5) + if(!(location.air) || !location.air.gases["plasma"] || !location.air.gases["o2"] || location.air.gases["plasma"][MOLES] < 0.5 || location.air.gases["o2"][MOLES] < 0.5) qdel(src) return diff --git a/code/LINDA/LINDA_system.dm b/code/LINDA/LINDA_system.dm index 6eace742248..a3a972aba68 100644 --- a/code/LINDA/LINDA_system.dm +++ b/code/LINDA/LINDA_system.dm @@ -164,20 +164,29 @@ var/const/SPAWN_AIR = 256 G.temperature += 1000 if(flag & SPAWN_TOXINS) - new_gases[GAS_PL][MOLES] += amount + G.assert_gas("plasma") + new_gases["plasma"][MOLES] += amount + if(flag & SPAWN_OXYGEN) - new_gases[GAS_O2][MOLES] += amount + G.assert_gas("o2") + new_gases["o2"][MOLES] += amount + if(flag & SPAWN_CO2) - new_gases[GAS_CO2][MOLES] += amount + G.assert_gas("co2") + new_gases["co2"][MOLES] += amount + if(flag & SPAWN_NITROGEN) - new_gases[GAS_N2][MOLES] += amount + G.assert_gas("n2") + new_gases["n2"][MOLES] += amount if(flag & SPAWN_N2O) - new_gases[GAS_N2O][MOLES] += amount + G.assert_gas("n2o") + new_gases["n2o"][MOLES] += amount if(flag & SPAWN_AIR) - new_gases[GAS_O2][MOLES] += MOLES_O2STANDARD * amount - new_gases[GAS_N2][MOLES] += MOLES_N2STANDARD * amount + G.assert_gases("o2","n2") + new_gases["o2"][MOLES] += MOLES_O2STANDARD * amount + new_gases["n2"][MOLES] += MOLES_N2STANDARD * amount air.merge(G) SSair.add_to_active(src, 0) \ No newline at end of file diff --git a/code/LINDA/LINDA_turf_tile.dm b/code/LINDA/LINDA_turf_tile.dm index 8b16f41b45d..e1fe47217aa 100644 --- a/code/LINDA/LINDA_turf_tile.dm +++ b/code/LINDA/LINDA_turf_tile.dm @@ -238,10 +238,10 @@ return null /turf/simulated/proc/tile_graphic() - if(air.gases[GAS_PL][MOLES] > MOLES_PLASMA_VISIBLE) + if(air.gases["plasma"] && air.gases["plasma"][MOLES] > MOLES_PLASMA_VISIBLE) return "plasma" - if(air.gases[GAS_N2O][MOLES] > 1) + if(air.gases["n2o"] && air.gases["n2o"][MOLES] > 1) return "sleeping_agent" return null @@ -320,7 +320,7 @@ for(var/turf/simulated/T in turf_list) for(var/gas in T.air.gases) - gas[MOLES] = A_gases[gas[GAS_INDEX]][MOLES]/turf_list.len + gas[MOLES] = A_gases[gas[GAS_ID]][MOLES]/turf_list.len T.update_visuals() diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index 5b0d2034026..8ec54e6237c 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -8,21 +8,14 @@ #define MOLES_O2STANDARD (MOLES_CELLSTANDARD*O2STANDARD) // O2 standard value (21%) #define MOLES_N2STANDARD (MOLES_CELLSTANDARD*N2STANDARD) // N2 standard value (79%) -//indices of specific gases. used by listmos. -#define GAS_O2 1 -#define GAS_N2 2 -#define GAS_CO2 3 -#define GAS_PL 4 -#define GAS_N2O 5 -#define GAS_AGENT_B 6 -#define GAS_V_FUEL 7 - //indices of values in gas lists. used by listmos. #define MOLES 1 #define ARCHIVE 2 -#define GAS_INDEX 3 -#define SPECIFIC_HEAT 4 -#define GAS_NAME 5 +#define GAS_META 3 +//this is kinda hacky... but it means I don't have to change every single time they're called. +#define GAS_ID GAS_META][1 +#define SPECIFIC_HEAT GAS_META][2 +#define GAS_NAME GAS_META][3 //stuff you should probably leave well alone! //ATMOS diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index d4e24de2e82..04f72e27d11 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -948,7 +948,7 @@ var/list/WALLITEMS_INVERSE = list( for(var/gas in air_contents.gases) var/gas_concentration = gas[MOLES]/total_moles - if(gas[GAS_INDEX] <= 4 || gas_concentration > 0.01) //ensures the four primary gases are always shown. + if(gas[GAS_ID] in hardcoded_gases || gas_concentration > 0.01) //ensures the four primary gases are always shown. user << "[gas[GAS_NAME]]: [round(gas_concentration*100)] %" user << "Temperature: [round(air_contents.temperature-T0C)] °C" diff --git a/code/datums/gas_mixture.dm b/code/datums/gas_mixture.dm index 553b7ab79da..ab37dc1d745 100644 --- a/code/datums/gas_mixture.dm +++ b/code/datums/gas_mixture.dm @@ -3,44 +3,23 @@ What are the archived variables for? Calculations are done using the archived variables with the results merged into the regular variables. This prevents race conditions that arise based on the order of tile processing. */ - -#define SPECIFIC_HEAT_TOXIN 200 -#define SPECIFIC_HEAT_AIR 20 -#define SPECIFIC_HEAT_CDO 30 -#define HEAT_CAPACITY_CALCULATION(oxygen,carbon_dioxide,nitrogen,toxins) \ - (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,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */ -/* -/datum/gas - var/moles = 0 - var/specific_heat = 0 - var/moles_archived = 0 - -/datum/gas/sleeping_agent - specific_heat = 40 - -/datum/gas/oxygen_agent_b - specific_heat = 300 - -/datum/gas/volatile_fuel - specific_heat = 30 -*/ -var/list/meta_gas_info = list( //this is also the list that decides what gases exist and in what order - list(20, "Oxygen"), //GAS_O2 - list(20, "Nitrogen"), //GAS_N2 - list(30, "Carbon Dioxide"), //GAS_C02 - list(200, "Plasma"), //GAS_PLASMA - list(40, "Nitrous Oxide"), //GAS_N20 - list(300, "Oxygen Agent B"), //GAS_AGENT_B - list(30, "Volatile Fuel") //GAS_V_FUEL +var/list/meta_gas_info = list( //this is the list that decides what gases exist and all their meta information + "o2" = list("o2", 20, "Oxygen"), //GAS_O2 + "n2" = list("n2", 20, "Nitrogen"), //GAS_N2 + "co2" = list("co2", 30, "Carbon Dioxide"), //GAS_C02 + "plasma" = list("plasma", 200, "Plasma"), //GAS_PLASMA + "n2o" = list("n2o", 40, "Nitrous Oxide"), //GAS_N20 + "agent_b" = list("agent_b", 300, "Oxygen Agent B"), //GAS_AGENT_B + "v_fuel" = list("v_fuel", 30, "Volatile Fuel") //GAS_V_FUEL ) -var/list/cached_gases_list = null +var/list/hardcoded_gases = list("o2","n2","co2","plasma") //the main four gases, which were at one time hardcoded +var/list/cached_gases_list = null /proc/gaseslist() var/gascount = meta_gas_info.len @@ -50,52 +29,52 @@ var/list/cached_gases_list = null /proc/gaslist(gasid) - if (!cached_gases_list) + if(!cached_gases_list) cached_gases_list = new /list(meta_gas_info.len) - if (!cached_gases_list[gasid]) + if(!cached_gases_list[gasid]) + if(!meta_gas_info[gasid]) + CRASH("Error: no such gas type! Type : [gasid]") cached_gases_list[gasid] = list ( 0, //MOLES 0, //ARCHIVE - gasid, //GAS_INDEX ) - cached_gases_list[gasid] += meta_gas_info[gasid] //All the rest + cached_gases_list[gasid][GAS_META] = meta_gas_info[gasid] //All the rest var/list/gas = cached_gases_list[gasid] . = gas.Copy() /datum/gas_mixture - /* - var/oxygen = 0 - var/carbon_dioxide = 0 - var/nitrogen = 0 - var/toxins = 0 - */ - var/volume = CELL_VOLUME - - var/temperature //in Kelvin - - var/last_share - - //var/list/datum/gas/trace_gases = list() var/list/gases - - /* - var/tmp/oxygen_archived - var/tmp/carbon_dioxide_archived - var/tmp/nitrogen_archived - var/tmp/toxins_archived - */ + var/temperature //in Kelvin var/tmp/temperature_archived - + var/volume + var/last_share var/tmp/fuel_burnt /datum/gas_mixture/New(Volume = CELL_VOLUME) . = ..() - gases = gaseslist() + gases = new temperature = 0 temperature_archived = 0 volume = Volume last_share = 0 fuel_burnt = 0 + + //listmos procs +/datum/gas_mixture/proc/assert_gas(gas_id) + var/cached_gases = gases + if(cached_gases[gas_id]) + return + cached_gases[gas_id] = gaslist(gas_id) + +/datum/gas_mixture/proc/assert_gases() + for(var/id in args) + assert_gas(id) + +/datum/gas_mixture/proc/garbage_collect() + for(var/gas in gases) + if(QUANTIZE(gas[MOLES]) <= 0 && QUANTIZE(gas[ARCHIVE]) <= 0) + gases -= gas + //PV=nRT - related procedures /datum/gas_mixture/proc/heat_capacity() for(var/gas in gases) @@ -134,51 +113,61 @@ var/list/cached_gases_list = null var/reacting = 0 //set to 1 if a notable reaction occured (used by pipe_network) if(temperature < TCMB) temperature = TCMB - if(temperature > 900) - if(procgases[GAS_PL][MOLES] > MINIMUM_HEAT_CAPACITY && procgases[GAS_CO2][MOLES] > MINIMUM_HEAT_CAPACITY) - if(procgases[GAS_AGENT_B][MOLES]) - var/reaction_rate = min(procgases[GAS_CO2][MOLES]*0.75, procgases[GAS_PL][MOLES]*0.25, procgases[GAS_AGENT_B][MOLES]*0.05) - procgases[GAS_CO2][MOLES] -= reaction_rate - procgases[GAS_O2][MOLES] += reaction_rate + if(procgases["agent_b"] && temperature > 900 && procgases["plasma"] && procgases["co2"]) + if(procgases["plasma"][MOLES] > MINIMUM_HEAT_CAPACITY && procgases["co2"][MOLES] > MINIMUM_HEAT_CAPACITY) + var/reaction_rate = min(procgases["co2"][MOLES]*0.75, procgases["plasma"][MOLES]*0.25, procgases["agent_b"][MOLES]*0.05) - procgases[GAS_AGENT_B][MOLES] -= reaction_rate*0.05 + procgases["co2"][MOLES] -= reaction_rate - temperature -= (reaction_rate*20000)/heat_capacity() + assert_gas("o2") //only need to assert oxygen, as this reaction doesn't occur without the other gases existing + procgases["o2"][MOLES] += reaction_rate - reacting = 1 + procgases["agent_b"][MOLES] -= reaction_rate*0.05 + + temperature -= (reaction_rate*20000)/heat_capacity() + + garbage_collect() + + reacting = 1 if(thermal_energy() > (PLASMA_BINDING_ENERGY*10)) - if(procgases[GAS_PL][MOLES] > MINIMUM_HEAT_CAPACITY && procgases[GAS_CO2][MOLES] > MINIMUM_HEAT_CAPACITY && (procgases[GAS_PL][MOLES]+procgases[GAS_CO2][MOLES])/total_moles() >= FUSION_PURITY_THRESHOLD)//Fusion wont occur if the level of impurities is too high. - //world << "pre [temperature, [toxins], [carbon_dioxide] + if(procgases["plasma"] && procgases["co2"] && procgases["plasma"][MOLES] > MINIMUM_HEAT_CAPACITY && procgases["co2"][MOLES] > MINIMUM_HEAT_CAPACITY && (procgases["plasma"][MOLES]+procgases["co2"][MOLES])/total_moles() >= FUSION_PURITY_THRESHOLD)//Fusion wont occur if the level of impurities is too high. + //world << "pre [temperature, [procgases["plasma"][MOLES]], [procgases["co2"][MOLES]] var/old_heat_capacity = heat_capacity() - var/carbon_efficency = min(procgases[GAS_PL][MOLES]/procgases[GAS_CO2][MOLES],MAX_CARBON_EFFICENCY) + var/carbon_efficency = min(procgases["plasma"][MOLES]/procgases["co2"][MOLES],MAX_CARBON_EFFICENCY) var/reaction_energy = thermal_energy() - var/moles_impurities = total_moles()-(procgases[GAS_PL][MOLES]+procgases[GAS_CO2][MOLES]) + var/moles_impurities = total_moles()-(procgases["plasma"][MOLES]+procgases["co2"][MOLES]) + var/plasma_fused = (PLASMA_FUSED_COEFFICENT*carbon_efficency)*(temperature/PLASMA_BINDING_ENERGY) var/carbon_catalyzed = (CARBON_CATALYST_COEFFICENT*carbon_efficency)*(temperature/PLASMA_BINDING_ENERGY) var/oxygen_added = carbon_catalyzed var/nitrogen_added = (plasma_fused-oxygen_added)-(thermal_energy()/PLASMA_BINDING_ENERGY) - reaction_energy = max(reaction_energy+((carbon_efficency*procgases[GAS_PL][MOLES])/((moles_impurities/carbon_efficency)+2)*10)+((plasma_fused/(moles_impurities/carbon_efficency))*PLASMA_BINDING_ENERGY),0) - procgases[GAS_PL][MOLES] = max(procgases[GAS_PL][MOLES]-plasma_fused,0) - procgases[GAS_CO2][MOLES] = max(procgases[GAS_CO2][MOLES]-carbon_catalyzed,0) - procgases[GAS_O2][MOLES] = max(procgases[GAS_O2][MOLES]+oxygen_added,0) - procgases[GAS_N2][MOLES] = max(procgases[GAS_N2][MOLES]+nitrogen_added,0) + reaction_energy = max(reaction_energy+((carbon_efficency*procgases["plasma"][MOLES])/((moles_impurities/carbon_efficency)+2)*10)+((plasma_fused/(moles_impurities/carbon_efficency))*PLASMA_BINDING_ENERGY),0) + + assert_gas("o2") + assert_gas("n2") + + procgases["plasma"][MOLES] -= plasma_fused + procgases["co2"][MOLES] -= carbon_catalyzed + procgases["o2"][MOLES] += oxygen_added + procgases["n2"][MOLES] += nitrogen_added + + garbage_collect() + if(reaction_energy > 0) reacting = 1 var/new_heat_capacity = heat_capacity() if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) temperature = max(((temperature*old_heat_capacity + reaction_energy)/new_heat_capacity),TCMB) //Prevents whatever mechanism is causing it to hit negative temperatures. - //world << "post [temperature], [toxins], [carbon_dioxide] - - + //world << "post [temperature], [procgases["plasma"][MOLES]], [procgases["co2"][MOLES]] fuel_burnt = 0 if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST) - //world << "pre [temperature], [oxygen], [toxins]" + //world << "pre [temperature], [procgases["o2"][MOLES]], [procgases["plasma"][MOLES]]" if(fire()) reacting = 1 - //world << "post [temperature], [oxygen], [toxins]" + //world << "post [temperature], [procgases["o2"][MOLES]], [procgases["plasma"][MOLES]]" return reacting @@ -187,23 +176,29 @@ var/list/cached_gases_list = null var/old_heat_capacity = heat_capacity() var/list/procgases = gases //this speeds things up because accessing datum vars is slow - if(procgases[GAS_V_FUEL][MOLES]) //General volatile gas burn - var/burned_fuel = 0 + if(procgases["v_fuel"] && procgases["v_fuel"][MOLES]) //General volatile gas burn + var/burned_fuel - if(procgases[GAS_O2][MOLES] < procgases[GAS_V_FUEL][MOLES]) - burned_fuel = procgases[GAS_O2][MOLES] - procgases[GAS_V_FUEL][MOLES] -= burned_fuel - procgases[GAS_O2][MOLES] = 0 + if(!procgases["o2"]) + burned_fuel = 0 + else if(procgases["o2"][MOLES] < procgases["v_fuel"][MOLES]) + burned_fuel = procgases["o2"][MOLES] + procgases["v_fuel"][MOLES] -= burned_fuel + procgases["o2"][MOLES] = 0 else - burned_fuel = procgases[GAS_V_FUEL][MOLES] - procgases[GAS_O2][MOLES] -= procgases[GAS_V_FUEL][MOLES] + burned_fuel = procgases["v_fuel"][MOLES] + procgases["o2"][MOLES] -= procgases["v_fuel"][MOLES] - energy_released += FIRE_CARBON_ENERGY_RELEASED * burned_fuel - procgases[GAS_CO2][MOLES] += burned_fuel - fuel_burnt += burned_fuel + if(burned_fuel) + energy_released += FIRE_CARBON_ENERGY_RELEASED * burned_fuel + + assert_gas("co2") + procgases["co2"][MOLES] += burned_fuel + + fuel_burnt += burned_fuel //Handle plasma burning - if(procgases[GAS_PL][MOLES] > MINIMUM_HEAT_CAPACITY) + if(procgases["plasma"] && procgases["plasma"][MOLES] > MINIMUM_HEAT_CAPACITY) var/plasma_burn_rate = 0 var/oxygen_burn_rate = 0 //more plasma released at higher temperatures @@ -213,19 +208,22 @@ var/list/cached_gases_list = null else temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE) if(temperature_scale > 0) + assert_gas("o2") + assert_gas("co2") oxygen_burn_rate = OXYGEN_BURN_RATE_BASE - temperature_scale - if(procgases[GAS_O2][MOLES] > procgases[GAS_PL][MOLES]*PLASMA_OXYGEN_FULLBURN) - plasma_burn_rate = (procgases[GAS_PL][MOLES]*temperature_scale)/PLASMA_BURN_RATE_DELTA + if(procgases["o2"][MOLES] > procgases["plasma"][MOLES]*PLASMA_OXYGEN_FULLBURN) + plasma_burn_rate = (procgases["plasma"][MOLES]*temperature_scale)/PLASMA_BURN_RATE_DELTA else - plasma_burn_rate = (temperature_scale*(procgases[GAS_O2][MOLES]/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA + plasma_burn_rate = (temperature_scale*(procgases["o2"][MOLES]/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY) - procgases[GAS_PL][MOLES] -= plasma_burn_rate - procgases[GAS_O2][MOLES] -= plasma_burn_rate*oxygen_burn_rate - procgases[GAS_CO2][MOLES] += plasma_burn_rate + procgases["plasma"][MOLES] -= plasma_burn_rate + procgases["o2"][MOLES] -= plasma_burn_rate*oxygen_burn_rate + procgases["co2"][MOLES] += plasma_burn_rate energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate) fuel_burnt += (plasma_burn_rate)*(1+oxygen_burn_rate) + garbage_collect() if(energy_released > 0) var/new_heat_capacity = heat_capacity() @@ -291,9 +289,10 @@ var/list/cached_gases_list = null var/combined_heat_capacity = giver_heat_capacity + self_heat_capacity if(combined_heat_capacity != 0) temperature = (giver.temperature*giver_heat_capacity + temperature*self_heat_capacity)/combined_heat_capacity - var/list/giver_gases = giver.gases //accessing datum vars is slower than proc vars - for(var/gas in gases) - gas[MOLES] += giver_gases[gas[GAS_INDEX]][MOLES] + var/list/cached_gases = gases //accessing datum vars is slower than proc vars + for(var/giver_gas in giver.gases) + assert_gas(giver_gas[GAS_ID]) + cached_gases[giver_gas[GAS_ID]][MOLES] += giver_gas[MOLES] . = 1 @@ -301,41 +300,54 @@ var/list/cached_gases_list = null var/sum = total_moles() amount = min(amount,sum) //Can not take more air than tile has! - if(amount <= 0) - return null + + ASSERT(amount > 0) var/datum/gas_mixture/removed = new var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars for(var/gas in gases) - removed_gases[gas[GAS_INDEX]][MOLES] = QUANTIZE((gas[MOLES]/sum)*amount) - gas[MOLES] -= removed_gases[gas[GAS_INDEX]][MOLES] + removed.assert_gas(gas[GAS_ID]) + removed_gases[gas[GAS_ID]][MOLES] = QUANTIZE((gas[MOLES]/sum)*amount) + gas[MOLES] -= removed_gases[gas[GAS_ID]][MOLES] removed.temperature = temperature + garbage_collect() + . = removed /datum/gas_mixture/remove_ratio(ratio) - - if(ratio <= 0) - return null + ASSERT(ratio > 0) ratio = min(ratio, 1) var/datum/gas_mixture/removed = new var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars for(var/gas in gases) - removed_gases[gas[GAS_INDEX]][MOLES] = QUANTIZE(gas[MOLES]*ratio) - gas[MOLES] -= removed_gases[gas[GAS_INDEX]][MOLES] + removed.assert_gas(gas[GAS_ID]) + removed_gases[gas[GAS_ID]][MOLES] = QUANTIZE(gas[MOLES]*ratio) + gas[MOLES] -= removed_gases[gas[GAS_ID]][MOLES] removed.temperature = temperature + garbage_collect() + . = removed /datum/gas_mixture/copy_from(datum/gas_mixture/sample) - var/list/sample_gases = sample.gases //accessing datum vars is slower than proc vars - for(var/gas in gases) - gas[MOLES] = sample_gases[gas[GAS_INDEX]][MOLES] + var/list/cached_gases = gases //accessing datum vars is slower than proc vars + var/list/copied_gases + for(var/sample_gas in sample.gases) + cached_gases[sample_gas[GAS_ID]][MOLES] = sample_gas[MOLES] + copied_gases += sample_gas[GAS_ID] + for(var/gas in cached_gases) + if(gas[GAS_ID] in copied_gases) + continue + gas[MOLES] = 0 + + garbage_collect() + temperature = sample.temperature return 1 @@ -366,8 +378,11 @@ var/list/cached_gases_list = null var/heat_capacity_self_to_sharer = 0 var/heat_capacity_sharer_to_self = 0 + for(var/sharer_gas in sharercache) + assert_gas(sharer_gas[GAS_ID]) for(var/gas in gases) - var/sharergas = sharercache[gas[GAS_INDEX]] + sharer.assert_gas(gas[GAS_ID]) + var/sharergas = sharercache[gas[GAS_ID]] var/delta = QUANTIZE(gas[ARCHIVE] - sharergas[ARCHIVE])/(atmos_adjacent_turfs+1) if(delta && abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) @@ -400,6 +415,8 @@ var/list/cached_gases_list = null var/delta_pressure = temperature_archived*(total_moles() + moved_moles) - sharer.temperature_archived*(sharer.total_moles() - moved_moles) . = delta_pressure*R_IDEAL_GAS_EQUATION/volume + garbage_collect() + /datum/gas_mixture/mimic(turf/model, atmos_adjacent_turfs = 4) var/datum/gas_mixture/copied = new copied.copy_from_turf(model) @@ -445,11 +462,24 @@ var/list/cached_gases_list = null /datum/gas_mixture/compare(datum/gas_mixture/sample, datatype = MOLES, adjacents = 0) . = 0 var/list/sample_gases = sample.gases //accessing datum vars is slower than proc vars - for(var/gas in gases) - var/delta = abs(gas[datatype] - sample_gases[gas[GAS_INDEX]][datatype])/(adjacents+1) + var/list/cached_gases = gases + var/list/gases_considered = new + for(var/gas in cached_gases) + var/sample_moles = sample_gases[gas[GAS_ID]][datatype] ? sample_gases[gas[GAS_ID]][datatype] : 0 + var/delta = abs(gas[datatype] - sample_moles)/(adjacents+1) if(delta > MINIMUM_AIR_TO_SUSPEND && \ delta > gas[datatype]*MINIMUM_AIR_RATIO_TO_SUSPEND) return + gases_considered += gas[GAS_ID] + + for(var/sample_gas in sample_gases) //I'd rather have copy-paste than slow this down with a proc call... is there a better solution? + if(sample_gas[GAS_ID] in gases_considered) + continue + var/gas_moles = cached_gases[sample_gas[GAS_ID]][datatype] ? cached_gases[sample_gas[GAS_ID]][datatype] : 0 + var/delta = abs(sample_gas[datatype] - gas_moles)/(adjacents+1) + if(delta > MINIMUM_AIR_TO_SUSPEND && \ + delta > sample_gas[datatype]*MINIMUM_AIR_RATIO_TO_SUSPEND) + return if(total_moles() > MINIMUM_AIR_TO_SUSPEND) var/temp @@ -469,12 +499,14 @@ var/list/cached_gases_list = null /datum/gas_mixture/copy_from_turf(turf/model) - gases[GAS_O2][MOLES] = model.oxygen - gases[GAS_N2][MOLES] = model.nitrogen - gases[GAS_PL][MOLES] = model.toxins - gases[GAS_CO2][MOLES] = model.carbon_dioxide - for(var/i in 5 to gases.len) - gases[i][MOLES] = 0 //turfs don't account for anything other than the four old hardcoded gases + gases["o2"][MOLES] = model.oxygen + gases["n2"][MOLES] = model.nitrogen + gases["plasma"][MOLES] = model.toxins + gases["co2"][MOLES] = model.carbon_dioxide + for(var/gas in gases) + if(gas[GAS_ID] in hardcoded_gases) + continue + gas[MOLES] = 0 //turfs don't account for anything other than the four old hardcoded gases temperature = model.temperature //Takes the amount of the gas you want to PP as an argument diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm index 9b0513817a5..f1923270f42 100644 --- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm +++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm @@ -292,11 +292,12 @@ var/datum/gas_mixture/A = F.air var/list/A_gases = A.gases var/trace_gases - for(var/i in 5 to A_gases.len) - if(A_gases[i][MOLES]) - trace_gases = TRUE - break - if(A_gases[GAS_O2][MOLES] >= 16 && !A_gases[GAS_PL][MOLES] && A_gases[GAS_CO2][MOLES] < 10 && !trace_gases)//Can most things breathe in this location? + for(var/gas in A_gases) + if(gas[GAS_ID] in hardcoded_gases) + continue + trace_gases = TRUE + break + if((A_gases["o2"] && A_gases["o2"][MOLES] >= 16) && !A_gases["plasma"] && (!A_gases["co2"] || A_gases["co2"][MOLES] < 10) && !trace_gases)//Can most things breathe in this location? if((A.temperature > 270) && (A.temperature < 360))//Not too hot, not too cold var/pressure = A.return_pressure() if((pressure > 20) && (pressure < 550))//Account for crushing pressure or vaccuums diff --git a/code/game/gamemodes/objective_items.dm b/code/game/gamemodes/objective_items.dm index 4de36883eff..c3121978a60 100644 --- a/code/game/gamemodes/objective_items.dm +++ b/code/game/gamemodes/objective_items.dm @@ -94,7 +94,7 @@ /datum/objective_item/steal/plasma/check_special_completion(obj/item/weapon/tank/T) var/target_amount = text2num(name) var/found_amount = 0 - found_amount += T.air_contents.gases[GAS_PL][MOLES] + found_amount += T.air_contents.gases["plasma"][MOLES] return found_amount>=target_amount diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index dfc643b8f17..79e14fedf2f 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -273,26 +273,32 @@ var/pressure_danger = cur_tlv.get_danger_level(pressure) environment_data += list(list("name" = "Pressure", "value" = pressure, "unit" = "kPa", "danger_level" = pressure_danger)) + environment.assert_gases(arglist(hardcoded_gases)) + cur_tlv = TLV["oxygen"] - var/oxygen_danger = cur_tlv.get_danger_level(env_gases[GAS_O2][MOLES]*partial_pressure) - environment_data += list(list("name" = "Oxygen", "value" = env_gases[GAS_O2][MOLES] / total * 100, "unit" = "%", "danger_level" = oxygen_danger)) + var/oxygen_danger = cur_tlv.get_danger_level(env_gases["o2"][MOLES]*partial_pressure) + environment_data += list(list("name" = "Oxygen", "value" = env_gases["o2"][MOLES] / total * 100, "unit" = "%", "danger_level" = oxygen_danger)) cur_tlv = TLV["nitrogen"] - var/nitrogen_danger = cur_tlv.get_danger_level(env_gases[GAS_N2][MOLES]*partial_pressure) - environment_data += list(list("name" = "Nitrogen", "value" = env_gases[GAS_N2][MOLES] / total * 100, "unit" = "%", "danger_level" = nitrogen_danger)) + var/nitrogen_danger = cur_tlv.get_danger_level(env_gases["n2"][MOLES]*partial_pressure) + environment_data += list(list("name" = "Nitrogen", "value" = env_gases["n2"][MOLES] / total * 100, "unit" = "%", "danger_level" = nitrogen_danger)) cur_tlv = TLV["carbon dioxide"] - var/carbon_dioxide_danger = cur_tlv.get_danger_level(env_gases[GAS_CO2][MOLES]*partial_pressure) - environment_data += list(list("name" = "Carbon Dioxide", "value" = env_gases[GAS_CO2][MOLES] / total * 100, "unit" = "%", "danger_level" = carbon_dioxide_danger)) + var/carbon_dioxide_danger = cur_tlv.get_danger_level(env_gases["co2"][MOLES]*partial_pressure) + environment_data += list(list("name" = "Carbon Dioxide", "value" = env_gases["co2"][MOLES] / total * 100, "unit" = "%", "danger_level" = carbon_dioxide_danger)) cur_tlv = TLV["plasma"] - var/plasma_danger = cur_tlv.get_danger_level(env_gases[GAS_PL][MOLES]*partial_pressure) - environment_data += list(list("name" = "Toxins", "value" = env_gases[GAS_PL][MOLES] / total * 100, "unit" = "%", "danger_level" = plasma_danger)) + var/plasma_danger = cur_tlv.get_danger_level(env_gases["plasma"][MOLES]*partial_pressure) + environment_data += list(list("name" = "Toxins", "value" = env_gases["plasma"][MOLES] / total * 100, "unit" = "%", "danger_level" = plasma_danger)) + + environment.garbage_collect() cur_tlv = TLV["other"] var/other_moles = 0 - for(var/i in 5 to env_gases.len) - other_moles+=env_gases[i][MOLES] + for(var/gas in env_gases) + if(gas[GAS_ID] in hardcoded_gases) + continue + other_moles += gas[MOLES] var/other_danger = cur_tlv.get_danger_level(other_moles*partial_pressure) environment_data += list(list("name" = "Other", "value" = other_moles / total * 100, "unit" = "%", "danger_level" = other_danger)) @@ -613,19 +619,25 @@ var/environment_pressure = environment.return_pressure() var/pressure_dangerlevel = cur_tlv.get_danger_level(environment_pressure) + environment.assert_gases(arglist(hardcoded_gases)) + cur_tlv = TLV["oxygen"] - var/oxygen_dangerlevel = cur_tlv.get_danger_level(env_gases[GAS_O2][MOLES]*GET_PP) + var/oxygen_dangerlevel = cur_tlv.get_danger_level(env_gases["o2"][MOLES]*GET_PP) cur_tlv = TLV["carbon dioxide"] - var/co2_dangerlevel = cur_tlv.get_danger_level(env_gases[GAS_CO2][MOLES]*GET_PP) + var/co2_dangerlevel = cur_tlv.get_danger_level(env_gases["co2"][MOLES]*GET_PP) cur_tlv = TLV["plasma"] - var/plasma_dangerlevel = cur_tlv.get_danger_level(env_gases[GAS_PL][MOLES]*GET_PP) + var/plasma_dangerlevel = cur_tlv.get_danger_level(env_gases["plasma"][MOLES]*GET_PP) + + environment.garbage_collect() cur_tlv = TLV["other"] var/other_moles = 0 - for(var/i in 5 to env_gases.len) - other_moles+=env_gases[i][MOLES] + for(var/gas in env_gases) + if(gas[GAS_ID] in hardcoded_gases) + continue + other_moles += gas[MOLES] var/other_dangerlevel = cur_tlv.get_danger_level(other_moles*GET_PP) cur_tlv = TLV["temperature"] diff --git a/code/game/machinery/atmo_control.dm b/code/game/machinery/atmo_control.dm index 964818f06c6..0b9f6633758 100644 --- a/code/game/machinery/atmo_control.dm +++ b/code/game/machinery/atmo_control.dm @@ -47,14 +47,16 @@ if(output>4) var/total_moles = air_sample.total_moles() if(total_moles > 0) + air_sample.assert_gases(arglist(hardcoded_gases)) if(output&4) - signal.data["oxygen"] = round(100*sample_gases[GAS_O2][MOLES]/total_moles,0.1) + signal.data["oxygen"] = round(100*sample_gases["o2"][MOLES]/total_moles,0.1) if(output&8) - signal.data["toxins"] = round(100*sample_gases[GAS_PL][MOLES]/total_moles,0.1) + signal.data["toxins"] = round(100*sample_gases["plasma"][MOLES]/total_moles,0.1) if(output&16) - signal.data["nitrogen"] = round(100*sample_gases[GAS_N2][MOLES]/total_moles,0.1) + signal.data["nitrogen"] = round(100*sample_gases["n2"][MOLES]/total_moles,0.1) if(output&32) - signal.data["carbon_dioxide"] = round(100*sample_gases[GAS_CO2][MOLES]/total_moles,0.1) + signal.data["carbon_dioxide"] = round(100*sample_gases["co2"][MOLES]/total_moles,0.1) + air_sample.garbage_collect() else signal.data["oxygen"] = 0 signal.data["toxins"] = 0 diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 9828774c9ad..c951f0adb00 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -22,6 +22,7 @@ use_power = 0 var/release_log = "" var/update_flag = 0 + var/gas_type /obj/machinery/portable_atmospherics/canister/sleeping_agent @@ -30,18 +31,21 @@ icon_state = "redws" canister_color = "redws" can_label = 0 + gas_type = "n2o" /obj/machinery/portable_atmospherics/canister/nitrogen name = "canister: \[N2\]" desc = "Nitrogen gas. Reportedly useful for something." icon_state = "red" canister_color = "red" can_label = 0 + gas_type = "n2" /obj/machinery/portable_atmospherics/canister/oxygen name = "canister: \[O2\]" desc = "Oxygen. Necessary for human life." icon_state = "blue" canister_color = "blue" can_label = 0 + gas_type = "o2" /obj/machinery/portable_atmospherics/canister/toxins name = "canister \[Plasma\]" desc = "Plasma gas. The reason YOU are here. Highly toxic." @@ -54,6 +58,7 @@ icon_state = "black" canister_color = "black" can_label = 0 + gas_type = "co2" /obj/machinery/portable_atmospherics/canister/air name = "canister \[Air\]" desc = "Pre-mixed air." @@ -344,10 +349,10 @@ update_flag logmsg = "Valve was opened by [key_name(usr)], starting the transfer into the [holding]
" else logmsg = "Valve was opened by [key_name(usr)], starting the transfer into the air
" - if(air_contents.gases[GAS_PL][MOLES] > 0) + if(air_contents.gases["plasma"]) message_admins("[key_name_admin(usr)] (?) (FLW) opened a canister that contains plasma! (JMP)") log_admin("[key_name(usr)] opened a canister that contains plasma at [x], [y], [z]") - if(air_contents.gases[GAS_N2O][MOLES] > 1) + if(air_contents.gases["n2o"]) message_admins("[key_name_admin(usr)] (?) (FLW) opened a canister that contains N2O! (JMP)") log_admin("[key_name(usr)] opened a canister that contains N2O at [x], [y], [z]") investigate_log(logmsg, "atmos") @@ -363,37 +368,22 @@ update_flag update_icon() return 1 -/obj/machinery/portable_atmospherics/canister/toxins/New() +/obj/machinery/portable_atmospherics/canister/New() ..() - air_contents.gases[GAS_PL][MOLES] = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) - - update_icon() - return 1 - -/obj/machinery/portable_atmospherics/canister/oxygen/New() - ..() - - air_contents.gases[GAS_O2][MOLES] = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) - - update_icon() - return 1 - -/obj/machinery/portable_atmospherics/canister/sleeping_agent/New() - ..() - - air_contents.gases[GAS_N2O][MOLES] = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) + if(gas_type) + air_contents.assert_gas(gas_type) + air_contents.gases[gas_type][MOLES] = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) update_icon() return 1 //Dirty way to fill room with gas. However it is a bit easier to do than creating some floor/engine/n2o -rastaf0 -/* + /obj/machinery/portable_atmospherics/canister/sleeping_agent/roomfiller/New() ..() - var/datum/gas/sleeping_agent/trace_gas = air_contents.trace_gases[1] - trace_gas.moles = 9*4000 + air_contents.gases["n2o"][MOLES] = 9*4000 spawn(10) var/turf/simulated/location = src.loc if (istype(src.loc)) @@ -402,31 +392,9 @@ update_flag location.assume_air(air_contents) air_contents = new return 1 -*/ - -/obj/machinery/portable_atmospherics/canister/nitrogen/New() - - ..() - - air_contents.gases[GAS_N2][MOLES] = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) - - update_icon() - return 1 - -/obj/machinery/portable_atmospherics/canister/carbon_dioxide/New() - - ..() - air_contents.gases[GAS_CO2][MOLES] = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) - - update_icon() - return 1 - /obj/machinery/portable_atmospherics/canister/air/New() - - ..() - air_contents.gases[GAS_O2][MOLES] = (O2STANDARD*src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) - air_contents.gases[GAS_N2][MOLES] = (N2STANDARD*src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) - - update_icon() - return 1 + . = ..() + air_contents.assert_gases("o2","n2") + air_contents.gases["o2"][MOLES] = (O2STANDARD*src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) + air_contents.gases["n2"][MOLES] = (N2STANDARD*src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) diff --git a/code/game/machinery/atmoalter/scrubber.dm b/code/game/machinery/atmoalter/scrubber.dm index d850a556c83..2bd2649d799 100644 --- a/code/game/machinery/atmoalter/scrubber.dm +++ b/code/game/machinery/atmoalter/scrubber.dm @@ -75,20 +75,26 @@ var/list/filtered_gases = filtered_out.gases var/list/removed_gases = removed.gases + filtered_out.assert_gases(arglist(hardcoded_gases)) + removed.assert_gases(arglist(hardcoded_gases)) + filtered_out.temperature = removed.temperature - filtered_gases[GAS_PL][MOLES] = removed_gases[GAS_PL][MOLES] - removed_gases[GAS_PL][MOLES] = 0 + filtered_gases["plasma"][MOLES] = removed_gases["plasma"][MOLES] + removed_gases["plasma"][MOLES] = 0 - filtered_gases[GAS_CO2][MOLES] = removed_gases[GAS_CO2][MOLES] - removed_gases[GAS_CO2][MOLES] = 0 + filtered_gases["co2"][MOLES] = removed_gases["co2"][MOLES] + removed_gases["co2"][MOLES] = 0 - filtered_gases[GAS_AGENT_B][MOLES] = removed_gases[GAS_AGENT_B][MOLES] - removed_gases[GAS_AGENT_B][MOLES] = 0 + filtered_gases["agent_b"][MOLES] = removed_gases["agent_b"][MOLES] + removed_gases["agent_b"][MOLES] = 0 - filtered_gases[GAS_N2O][MOLES] = removed_gases[GAS_N2O][MOLES] - removed_gases[GAS_AGENT_B][MOLES] = 0 + filtered_gases["n2o"][MOLES] = removed_gases["n2o"][MOLES] + removed_gases["n2o"][MOLES] = 0 + + filtered_out.garbage_collect() + removed.garbage_collect() //Remix the resulting gases air_contents.merge(filtered_out) diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/game/mecha/equipment/tools/other_tools.dm index c6c85b66a5d..a1ce789e73a 100644 --- a/code/game/mecha/equipment/tools/other_tools.dm +++ b/code/game/mecha/equipment/tools/other_tools.dm @@ -436,13 +436,14 @@ if(!T) return var/datum/gas_mixture/GM = new + GM.assert_gas("plasma") if(prob(10)) - GM.gases[GAS_PL][MOLES] += 100 + GM.gases["plasma"][MOLES] += 100 GM.temperature = 1500+T0C //should be enough to start a fire T.visible_message("The [src] suddenly disgorges a cloud of heated plasma.") qdel(src) else - GM.gases[GAS_PL][MOLES] += 5 + GM.gases["plasma"][MOLES] += 5 GM.temperature = istype(T) ? T.air.return_temperature() : T20C T.visible_message("The [src] suddenly disgorges a cloud of plasma.") T.assume_air(GM) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index f4a3bfbbf04..3a5f8df7da2 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -177,8 +177,9 @@ cabin_air = new cabin_air.temperature = T20C cabin_air.volume = 200 - cabin_air.gases[GAS_O2][MOLES] = O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature) - cabin_air.gases[GAS_N2][MOLES] = N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature) + cabin_air.assert_gases("o2","n2") + cabin_air.gases["o2"][MOLES] = O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature) + cabin_air.gases["n2"][MOLES] = N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature) return cabin_air /obj/mecha/proc/add_radio() diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm index d75a9705556..a3b42392f70 100644 --- a/code/game/objects/effects/effect_system/effects_smoke.dm +++ b/code/game/objects/effects/effect_system/effects_smoke.dm @@ -164,9 +164,11 @@ for(var/obj/effect/hotspot/H in T) qdel(H) var/list/G_gases = G.gases - if(G_gases[GAS_PL][MOLES]) - G_gases[GAS_N2][MOLES] += (G_gases[GAS_PL][MOLES]) - G_gases[GAS_PL][MOLES] = 0 + if(G_gases["plasma"]) + G.assert_gas("n2") + G_gases["n2"][MOLES] += (G_gases["plasma"][MOLES]) + G_gases["plasma"][MOLES] = 0 + G.garbage_collect() for(var/obj/machinery/atmospherics/components/unary/U in T) if(!isnull(U.welded) && !U.welded) //must be an unwelded vent pump or vent scrubber. U.welded = 1 diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 327ba3fa09d..d0c161a7613 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -423,7 +423,7 @@ var/global/list/obj/item/device/pda/PDAs = list() if (total_moles) for(var/gas in environment.gases) var/gas_level = gas[MOLES]/total_moles - if(gas[GAS_INDEX] <= 4 || gas_level > 0.01) + if(gas[GAS_ID] in hardcoded_gases || gas_level > 0.01) dat += "[gas[GAS_NAME]]: [round(gas_level*100)]%
" dat += "Temperature: [round(environment.temperature-T0C)]°C
" diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 8f68ea886fd..365fe8dd09f 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -269,10 +269,13 @@ MASS SPECTROMETER user.show_message("Pressure: [round(pressure,0.1)] kPa", 1) if(total_moles) var/list/env_gases = environment.gases - var/o2_concentration = env_gases[GAS_O2][MOLES]/total_moles - var/n2_concentration = env_gases[GAS_N2][MOLES]/total_moles - var/co2_concentration = env_gases[GAS_CO2][MOLES]/total_moles - var/plasma_concentration = env_gases[GAS_PL][MOLES]/total_moles + + environment.assert_gases(arglist(hardcoded_gases)) + var/o2_concentration = env_gases["o2"][MOLES]/total_moles + var/n2_concentration = env_gases["n2"][MOLES]/total_moles + var/co2_concentration = env_gases["co2"][MOLES]/total_moles + var/plasma_concentration = env_gases["plasma"][MOLES]/total_moles + environment.garbage_collect() if(abs(n2_concentration - N2STANDARD) < 20) user.show_message("Nitrogen: [round(n2_concentration*100)] %", 1) @@ -292,9 +295,11 @@ MASS SPECTROMETER if(plasma_concentration > 0.01) user.show_message("Plasma: [round(plasma_concentration*100)] %", 1) - for(var/i in 5 to environment.gases.len) - var/gas_concentration = environment.gases[i][MOLES]/total_moles - user.show_message("[environment.gases[i][GAS_NAME]]: [round(gas_concentration*100)] %", 1) + for(var/gas in env_gases) + if(gas[GAS_ID] in hardcoded_gases) + continue + var/gas_concentration = gas[MOLES]/total_moles + user.show_message("[gas[GAS_NAME]]: [round(gas_concentration*100)] %", 1) user.show_message("Temperature: [round(environment.temperature-T0C)] °C", 1) diff --git a/code/game/objects/items/weapons/chrono_eraser.dm b/code/game/objects/items/weapons/chrono_eraser.dm index 7ecf363f140..2695041736a 100644 --- a/code/game/objects/items/weapons/chrono_eraser.dm +++ b/code/game/objects/items/weapons/chrono_eraser.dm @@ -239,8 +239,9 @@ /obj/effect/chrono_field/return_air() //we always have nominal air and temperature var/datum/gas_mixture/GM = new - GM.gases[GAS_O2][MOLES] = MOLES_O2STANDARD - GM.gases[GAS_N2][MOLES] = MOLES_N2STANDARD + GM.assert_gases("o2","n2") + GM.gases["o2"][MOLES] = MOLES_O2STANDARD + GM.gases["n2"][MOLES] = MOLES_N2STANDARD GM.temperature = T20C return GM diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm index 64b9ca2636d..9607bdb7f1f 100644 --- a/code/game/objects/items/weapons/flamethrower.dm +++ b/code/game/objects/items/weapons/flamethrower.dm @@ -194,7 +194,8 @@ //TODO: DEFERRED Consider checking to make sure tank pressure is high enough before doing this... //Transfer 5% of current tank air contents to turf var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(release_amount) - air_transfer.gases[GAS_PL][MOLES] *= 5 + if(air_transfer.gases["plasma"]) + air_transfer.gases["plasma"][MOLES] *= 5 target.assume_air(air_transfer) //Burn it based on transfered gas target.hotspot_expose((ptank.air_contents.temperature*2) + 380,500) diff --git a/code/game/objects/items/weapons/tanks/jetpack.dm b/code/game/objects/items/weapons/tanks/jetpack.dm index 1d6c042c9c2..fea4e6db9fc 100644 --- a/code/game/objects/items/weapons/tanks/jetpack.dm +++ b/code/game/objects/items/weapons/tanks/jetpack.dm @@ -73,7 +73,8 @@ /obj/item/weapon/tank/jetpack/void/New() ..() - air_contents.gases[GAS_O2][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.assert_gas("o2") + air_contents.gases["o2"][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) /obj/item/weapon/tank/jetpack/oxygen @@ -84,7 +85,8 @@ /obj/item/weapon/tank/jetpack/oxygen/New() ..() - air_contents.gases[GAS_O2][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.assert_gas("o2") + air_contents.gases["o2"][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) /obj/item/weapon/tank/jetpack/oxygen/harness name = "jet harness (oxygen)" @@ -114,7 +116,8 @@ ..() ion_trail = new /datum/effect_system/trail_follow/ion() ion_trail.set_up(src) - air_contents.gases[GAS_CO2][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.assert_gas("co2") + air_contents.gases["co2"][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) /obj/item/weapon/tank/jetpack/suit diff --git a/code/game/objects/items/weapons/tanks/tank_types.dm b/code/game/objects/items/weapons/tanks/tank_types.dm index f2b018dc493..9fe72a6ddfa 100644 --- a/code/game/objects/items/weapons/tanks/tank_types.dm +++ b/code/game/objects/items/weapons/tanks/tank_types.dm @@ -20,7 +20,8 @@ /obj/item/weapon/tank/internals/oxygen/New() ..() - air_contents.gases[GAS_O2][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.assert_gas("o2") + air_contents.gases["o2"][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -45,8 +46,9 @@ /obj/item/weapon/tank/internals/anesthetic/New() ..() - air_contents.gases[GAS_O2][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD - air_contents.gases[GAS_N2O][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD + air_contents.assert_gases("o2", "n2o") + air_contents.gases["o2"][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD + air_contents.gases["n2o"][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD return /* @@ -61,9 +63,9 @@ /obj/item/weapon/tank/internals/air/New() ..() - - air_contents.gases[GAS_O2][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD - air_contents.gases[GAS_N2][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD + air_contents.assert_gases("o2","n2") + air_contents.gases["o2"][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD + air_contents.gases["n2"][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD return @@ -81,8 +83,8 @@ /obj/item/weapon/tank/internals/plasma/New() ..() - - air_contents.gases[GAS_PL][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.assert_gas("plasma") + air_contents.gases["plasma"][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return /obj/item/weapon/tank/internals/plasma/attackby(obj/item/weapon/W, mob/user, params) @@ -100,7 +102,8 @@ /obj/item/weapon/tank/internals/plasma/full/New() ..() - air_contents.gases[GAS_PL][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.assert_gas("plasma") + air_contents.gases["plasma"][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -115,14 +118,14 @@ /obj/item/weapon/tank/internals/plasmaman/New() ..() - - air_contents.gases[GAS_PL][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.assert_gas("plasma") + air_contents.gases["plasma"][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return /obj/item/weapon/tank/internals/plasmaman/full/New() ..() - - air_contents.gases[GAS_PL][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.assert_gas("plasma") + air_contents.gases["plasma"][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -134,8 +137,8 @@ /obj/item/weapon/tank/internals/plasmaman/belt/full/New() ..() - - air_contents.gases[GAS_PL][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.assert_gas("plasma") + air_contents.gases["plasma"][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -157,7 +160,8 @@ /obj/item/weapon/tank/internals/emergency_oxygen/New() ..() - air_contents.gases[GAS_O2][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.assert_gas("o2") + air_contents.gases["o2"][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return /obj/item/weapon/tank/internals/emergency_oxygen/engi diff --git a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm index 2644b756170..eb8962025e6 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm @@ -11,8 +11,9 @@ /obj/structure/transit_tube_pod/New(loc) ..(loc) - air_contents.gases[GAS_O2][MOLES] = MOLES_O2STANDARD * 2 - air_contents.gases[GAS_N2][MOLES] = MOLES_N2STANDARD + air_contents.assert_gases("o2", "n2") + air_contents.gases["o2"][MOLES] = MOLES_O2STANDARD * 2 + air_contents.gases["n2"][MOLES] = MOLES_N2STANDARD air_contents.temperature = T20C // Give auto tubes time to align before trying to start moving diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm index 9a118b04874..74a8646f323 100644 --- a/code/game/turfs/simulated/floor/plating.dm +++ b/code/game/turfs/simulated/floor/plating.dm @@ -135,7 +135,8 @@ ..() var/datum/gas_mixture/adding = new - adding.gases[GAS_N2O][MOLES] = 6000 + adding.assert_gas("n2o") + adding.gases["n2o"][MOLES] = 6000 adding.temperature = T20C assume_air(adding) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index c900568cbfd..8c48d4bafb7 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -155,11 +155,11 @@ if(S.air)//Add the air's contents to the holders var/list/S_gases = S.air.gases for(var/gas in a_gases) - gas[MOLES] += S_gases[gas[GAS_INDEX]][MOLES] + gas[MOLES] += S_gases[gas[GAS_ID]][MOLES] a_gas_mixture.temperature += S.air.temperature turf_count ++ for(var/gas in air.gases) - gas[MOLES] = (a_gases[gas[GAS_INDEX]][MOLES]/max(turf_count,1))//Averages contents of the turfs, ignoring walls and the like + gas[MOLES] = (a_gases[gas[GAS_ID]][MOLES]/max(turf_count,1))//Averages contents of the turfs, ignoring walls and the like air.temperature = (a_gas_mixture.temperature/max(turf_count,1))//Trace gases can get bant SSair.add_to_active(src) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 7d5963e7a28..6de16fec891 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -190,7 +190,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that var/t = "" for(var/gas in env.gases) - if(gas[GAS_INDEX] <= 4 || gas[MOLES]) + if(gas[GAS_ID] in hardcoded_gases || gas[MOLES]) t+= "[gas[GAS_NAME]] : [gas[MOLES]]\n" usr.show_message(t, 1) @@ -630,7 +630,8 @@ var/global/list/g_fancy_list_of_types = null if(Rad.anchored) if(!Rad.P) var/obj/item/weapon/tank/internals/plasma/Plasma = new/obj/item/weapon/tank/internals/plasma(Rad) - Plasma.air_contents.gases[GAS_PL][MOLES] = 70 + Plasma.air_contents.assert_gas("plasma") + Plasma.air_contents.gases["plasma"][MOLES] = 70 Rad.drainratio = 0 Rad.P = Plasma Plasma.loc = Rad diff --git a/code/modules/admin/verbs/diagnostics.dm b/code/modules/admin/verbs/diagnostics.dm index e6ee935b9d0..32852f4dcd2 100644 --- a/code/modules/admin/verbs/diagnostics.dm +++ b/code/modules/admin/verbs/diagnostics.dm @@ -14,7 +14,7 @@ usr << "@[target.x],[target.y]: [GM.temperature] Kelvin, [GM.return_pressure()] kPa [(burning)?("\red BURNING"):(null)]" for(var/gas in GM.gases) - if(gas[GAS_INDEX] <= 4 || gas[MOLES]) + if(gas[GAS_ID] in hardcoded_gases || gas[MOLES]) usr << "[gas[GAS_NAME]]: [gas[MOLES]]" feedback_add_details("admin_verb","DAST") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm index 9424b141538..3a446749607 100644 --- a/code/modules/assembly/bomb.dm +++ b/code/modules/assembly/bomb.dm @@ -108,7 +108,10 @@ return /obj/item/weapon/tank/proc/ignite() //This happens when a bomb is told to explode - var/fuel_moles = air_contents.gases[GAS_PL][MOLES] + air_contents.gases[GAS_O2][MOLES]/6 + air_contents.assert_gases("plasma", "o2") + var/fuel_moles = air_contents.gases["plasma"][MOLES] + air_contents.gases["o2"][MOLES]/6 + air_contents.garbage_collect() + var/strength = 1 var/turf/ground_zero = get_turf(loc) diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index 56745637b03..7149bfe7a5d 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -228,7 +228,10 @@ var/turf/simulated/floor/T = holder.loc if(istype(T)) var/datum/gas_mixture/GM = T.air - GM.gases[GAS_O2][MOLES] = max(0, GM.gases[GAS_O2][MOLES] - severity * holder.energy) + if(!GM.gases["o2"]) + return + GM.gases["o2"][MOLES] -= severity * holder.energy + GM.garbage_collect() /datum/spacevine_mutation/nitro_eater name = "nitrogen consuming" @@ -240,7 +243,10 @@ var/turf/simulated/floor/T = holder.loc if(istype(T)) var/datum/gas_mixture/GM = T.air - GM.gases[GAS_N2][MOLES] = max(0, GM.gases[GAS_N2][MOLES] - severity * holder.energy) + if(!GM.gases["n2"]) + return + GM.gases["n2"][MOLES] -= severity * holder.energy + GM.garbage_collect() /datum/spacevine_mutation/carbondioxide_eater name = "CO2 consuming" @@ -252,7 +258,10 @@ var/turf/simulated/floor/T = holder.loc if(istype(T)) var/datum/gas_mixture/GM = T.air - GM.gases[GAS_CO2][MOLES] = max(0, GM.gases[GAS_CO2][MOLES] - severity * holder.energy) + if(!GM.gases["co2"]) + return + GM.gases["co2"][MOLES] -= severity * holder.energy + GM.garbage_collect() /datum/spacevine_mutation/plasma_eater name = "toxins consuming" @@ -264,7 +273,10 @@ var/turf/simulated/floor/T = holder.loc if(istype(T)) var/datum/gas_mixture/GM = T.air - GM.gases[GAS_PL][MOLES] = max(0, GM.gases[GAS_PL][MOLES] - severity * holder.energy) + if(!GM.gases["plasma"]) + return + GM.gases["plasma"][MOLES] -= severity * holder.energy + GM.garbage_collect() /datum/spacevine_mutation/thorns name = "thorny" diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm index 0d77114d345..ac23410cc38 100644 --- a/code/modules/mob/living/carbon/alien/life.dm +++ b/code/modules/mob/living/carbon/alien/life.dm @@ -11,21 +11,25 @@ var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME var/list/breath_gases = breath.gases + breath.assert_gases("plasma", "o2") + //Partial pressure of the toxins in our breath - var/Toxins_pp = (breath_gases[GAS_PL][MOLES]/breath.total_moles())*breath_pressure + var/Toxins_pp = (breath_gases["plasma"][MOLES]/breath.total_moles())*breath_pressure if(Toxins_pp) // Detect toxins in air - adjustPlasma(breath_gases[GAS_PL][MOLES]*250) + adjustPlasma(breath_gases["plasma"][MOLES]*250) throw_alert("alien_tox", /obj/screen/alert/alien_tox) - toxins_used = breath_gases[GAS_PL][MOLES] + toxins_used = breath_gases["plasma"][MOLES] else clear_alert("alien_tox") //Breathe in toxins and out oxygen - breath_gases[GAS_PL][MOLES] -= toxins_used - breath_gases[GAS_O2][MOLES] += toxins_used + breath_gases["plasma"][MOLES] -= toxins_used + breath_gases["o2"][MOLES] += toxins_used + + breath.garbage_collect() //BREATH TEMPERATURE handle_breath_temperature(breath) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 202f9b26282..97afcbb9e2c 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1169,10 +1169,12 @@ var/list/breath_gases = breath.gases + breath.assert_gases("o2", "plasma", "co2", "n2o") + //Partial pressures in our breath - var/O2_pp = breath.get_breath_partial_pressure(breath_gases[GAS_O2][MOLES]) - var/Toxins_pp = breath.get_breath_partial_pressure(breath_gases[GAS_PL][MOLES]) - var/CO2_pp = breath.get_breath_partial_pressure(breath_gases[GAS_CO2][MOLES]) + var/O2_pp = breath.get_breath_partial_pressure(breath_gases["o2"][MOLES]) + var/Toxins_pp = breath.get_breath_partial_pressure(breath_gases["plasma"][MOLES]) + var/CO2_pp = breath.get_breath_partial_pressure(breath_gases["co2"][MOLES]) //-- OXY --// @@ -1180,7 +1182,7 @@ //Too much oxygen! //Yes, some species may not like it. if(safe_oxygen_max) if(O2_pp > safe_oxygen_max && !(NOBREATH in specflags)) - var/ratio = (breath_gases[GAS_O2][MOLES]/safe_oxygen_max) * 10 + var/ratio = (breath_gases["o2"][MOLES]/safe_oxygen_max) * 10 H.adjustOxyLoss(Clamp(ratio,oxy_breath_dam_min,oxy_breath_dam_max)) H.throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy) else @@ -1189,17 +1191,17 @@ //Too little oxygen! if(safe_oxygen_min) if(O2_pp < safe_oxygen_min) - gas_breathed = handle_too_little_breath(H,O2_pp,safe_oxygen_min,breath_gases[GAS_O2][MOLES]) + gas_breathed = handle_too_little_breath(H,O2_pp,safe_oxygen_min,breath_gases["o2"][MOLES]) H.throw_alert("oxy", /obj/screen/alert/oxy) else H.failed_last_breath = 0 H.adjustOxyLoss(-5) - gas_breathed = breath_gases[GAS_O2][MOLES]/6 + gas_breathed = breath_gases["o2"][MOLES]/6 H.clear_alert("oxy") //Exhale - breath_gases[GAS_O2][MOLES] -= gas_breathed - breath_gases[GAS_CO2][MOLES] += gas_breathed + breath_gases["o2"][MOLES] -= gas_breathed + breath_gases["co2"][MOLES] += gas_breathed gas_breathed = 0 @@ -1226,17 +1228,17 @@ //Too little CO2! if(safe_co2_min) if(CO2_pp < safe_co2_min) - gas_breathed = handle_too_little_breath(H,CO2_pp, safe_co2_min,breath_gases[GAS_CO2][MOLES]) + gas_breathed = handle_too_little_breath(H,CO2_pp, safe_co2_min,breath_gases["co2"][MOLES]) H.throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2) else H.failed_last_breath = 0 H.adjustOxyLoss(-5) - gas_breathed = breath_gases[GAS_CO2][MOLES]/6 + gas_breathed = breath_gases["co2"][MOLES]/6 H.clear_alert("not_enough_co2") //Exhale - breath_gases[GAS_CO2][MOLES] -= gas_breathed - breath_gases[GAS_O2][MOLES] += gas_breathed + breath_gases["co2"][MOLES] -= gas_breathed + breath_gases["o2"][MOLES] += gas_breathed gas_breathed = 0 @@ -1245,7 +1247,7 @@ //Too much toxins! if(safe_toxins_max) if(Toxins_pp > safe_toxins_max && !(NOBREATH in specflags)) - var/ratio = (breath_gases[GAS_PL][MOLES]/safe_toxins_max) * 10 + var/ratio = (breath_gases["plasma"][MOLES]/safe_toxins_max) * 10 if(H.reagents) H.reagents.add_reagent("plasma", Clamp(ratio, tox_breath_dam_min, tox_breath_dam_max)) H.throw_alert("tox_in_air", /obj/screen/alert/tox_in_air) @@ -1256,24 +1258,24 @@ //Too little toxins! if(safe_toxins_min) if(Toxins_pp < safe_toxins_min && !(NOBREATH in specflags)) - gas_breathed = handle_too_little_breath(H,Toxins_pp, safe_toxins_min, breath_gases[GAS_PL][MOLES]) + gas_breathed = handle_too_little_breath(H,Toxins_pp, safe_toxins_min, breath_gases["plasma"][MOLES]) H.throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox) else H.failed_last_breath = 0 H.adjustOxyLoss(-5) - gas_breathed = breath_gases[GAS_PL][MOLES]/6 + gas_breathed = breath_gases["plasma"][MOLES]/6 H.clear_alert("not_enough_tox") //Exhale - breath_gases[GAS_PL][MOLES] -= gas_breathed - breath_gases[GAS_CO2][MOLES] += gas_breathed + breath_gases["plasma"][MOLES] -= gas_breathed + breath_gases["co2"][MOLES] += gas_breathed gas_breathed = 0 //-- TRACES --// if(breath && !(NOBREATH in specflags)) // If there's some other shit in the air lets deal with it here. - var/SA_pp = breath.get_breath_partial_pressure(breath_gases[GAS_N2O][MOLES]) + var/SA_pp = breath.get_breath_partial_pressure(breath_gases["n2o"][MOLES]) if(SA_pp > SA_para_min) // Enough to make us paralysed for a bit H.Paralyse(3) // 3 gives them one second to wake up and run away a bit! if(SA_pp > SA_sleep_min) // Enough to make us sleep as well @@ -1284,6 +1286,7 @@ H.emote(pick("giggle", "laugh")) handle_breath_temperature(breath, H) + breath.garbage_collect() return 1 diff --git a/code/modules/mob/living/carbon/human/species_types.dm b/code/modules/mob/living/carbon/human/species_types.dm index e9e1cca013e..ab022a31876 100644 --- a/code/modules/mob/living/carbon/human/species_types.dm +++ b/code/modules/mob/living/carbon/human/species_types.dm @@ -505,7 +505,7 @@ var/global/image/plasmaman_on_fire = image("icon"='icons/mob/OnFire.dmi', "icon_ if(environment) var/total_moles = environment.total_moles() if(total_moles) - if((environment.gases[GAS_O2][MOLES] /total_moles) >= 0.01) + if(environment.gases["o2"] && (environment.gases["o2"][MOLES] /total_moles) >= 0.01) H.adjust_fire_stacks(0.5) if(!H.on_fire && H.fire_stacks > 0) H.visible_message("[H]'s body reacts with the atmosphere and bursts into flames!","Your body reacts with the atmosphere and bursts into flame!") diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index f96fc2c6960..8f460db1de8 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -106,10 +106,11 @@ var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME var/list/breath_gases = breath.gases + breath.assert_gases("o2","plasma","co2","n2o") - var/O2_partialpressure = (breath_gases[GAS_O2][MOLES]/breath.total_moles())*breath_pressure - var/Toxins_partialpressure = (breath_gases[GAS_PL][MOLES]/breath.total_moles())*breath_pressure - var/CO2_partialpressure = (breath_gases[GAS_CO2][MOLES]/breath.total_moles())*breath_pressure + var/O2_partialpressure = (breath_gases["o2"][MOLES]/breath.total_moles())*breath_pressure + var/Toxins_partialpressure = (breath_gases["plasma"][MOLES]/breath.total_moles())*breath_pressure + var/CO2_partialpressure = (breath_gases["co2"][MOLES]/breath.total_moles())*breath_pressure //OXYGEN @@ -121,7 +122,7 @@ var/ratio = safe_oxy_min/O2_partialpressure adjustOxyLoss(min(5*ratio, 3)) failed_last_breath = 1 - oxygen_used = breath_gases[GAS_O2][MOLES]*ratio/6 + oxygen_used = breath_gases["o2"][MOLES]*ratio/6 else adjustOxyLoss(3) failed_last_breath = 1 @@ -130,11 +131,11 @@ else //Enough oxygen failed_last_breath = 0 adjustOxyLoss(-5) - oxygen_used = breath_gases[GAS_O2][MOLES]/6 + oxygen_used = breath_gases["o2"][MOLES]/6 clear_alert("oxy") - breath_gases[GAS_O2][MOLES] -= oxygen_used - breath_gases[GAS_CO2][MOLES] += oxygen_used + breath_gases["o2"][MOLES] -= oxygen_used + breath_gases["co2"][MOLES] += oxygen_used //CARBON DIOXIDE if(CO2_partialpressure > safe_co2_max) @@ -153,7 +154,7 @@ //TOXINS/PLASMA if(Toxins_partialpressure > safe_tox_max) - var/ratio = (breath_gases[GAS_PL][MOLES]/safe_tox_max) * 10 + var/ratio = (breath_gases["plasma"][MOLES]/safe_tox_max) * 10 if(reagents) reagents.add_reagent("plasma", Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE)) throw_alert("tox_in_air", /obj/screen/alert/tox_in_air) @@ -161,8 +162,8 @@ clear_alert("tox_in_air") //NITROUS OXIDE - if(breath_gases[GAS_N2O][MOLES]) - var/SA_partialpressure = (breath_gases[GAS_N2O][MOLES]/breath.total_moles())*breath_pressure + if(breath_gases["n2o"]) + var/SA_partialpressure = (breath_gases["n2o"][MOLES]/breath.total_moles())*breath_pressure if(SA_partialpressure > SA_para_min) Paralyse(3) if(SA_partialpressure > SA_sleep_min) @@ -171,6 +172,8 @@ if(prob(20)) spawn(0) emote(pick("giggle","laugh")) + breath.garbage_collect() + //BREATH TEMPERATURE handle_breath_temperature(breath) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 82a41f3dd6d..786b3b1007e 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -142,7 +142,7 @@ ExtinguishMob() return var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment - if(G.gases[GAS_O2][MOLES] < 1) + if(!G.gases["o2"] || G.gases["o2"][MOLES] < 1) ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire return var/turf/location = get_turf(src) diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index a4cf27c51be..0e7a86fe771 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -536,7 +536,7 @@ if (total_moles) for(var/gas in environment.gases) var/gas_level = gas[MOLES]/total_moles - if(gas[GAS_INDEX] <= 4 || gas_level > 0.01) + if(gas[GAS_ID] in hardcoded_gases || gas_level > 0.01) dat += "[gas[GAS_NAME]]: [round(gas_level*100)]%
" dat += "Temperature: [round(environment.temperature-T0C)]°C
" dat += "Refresh Reading
" diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index 04315cc6d01..5603b7c125b 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -389,11 +389,12 @@ var/list/Z_gases = Z.gases var/trace_gases = FALSE - for(var/i in 5 to Z.gases.len) - if(Z_gases[i][MOLES]) - trace_gases = TRUE - break - if(Z_gases[GAS_O2][MOLES] >= 16 && !Z_gases[GAS_PL][MOLES] && Z_gases[GAS_CO2][MOLES] < 10 && !trace_gases) + for(var/gas in Z_gases) + if(gas[GAS_ID] in hardcoded_gases) + continue + trace_gases = TRUE + break + if((Z_gases["o2"] && Z_gases["o2"][MOLES] >= 16) && !Z_gases["plasma"] && (!Z_gases["co2"] || Z_gases["co2"][MOLES] < 10) && !trace_gases) if((Z.temperature > 270) && (Z.temperature < 360)) var/pressure = Z.return_pressure() if((pressure > 20) && (pressure < 550)) diff --git a/code/modules/mob/living/simple_animal/hostile/tree.dm b/code/modules/mob/living/simple_animal/hostile/tree.dm index 422e435695c..26817a3f3c9 100644 --- a/code/modules/mob/living/simple_animal/hostile/tree.dm +++ b/code/modules/mob/living/simple_animal/hostile/tree.dm @@ -41,12 +41,12 @@ ..() if(istype(src.loc, /turf/simulated)) var/turf/simulated/T = src.loc - if(T.air) - var/co2 = T.air.gases[GAS_CO2][MOLES] + if(T.air && T.air.gases["co2"]) + var/co2 = T.air.gases["co2"][MOLES] if(co2 > 0) if(prob(25)) var/amt = min(co2, 9) - T.air.gases[GAS_CO2][MOLES] -= amt + T.air.gases["co2"][MOLES] -= amt T.atmos_spawn_air(SPAWN_OXYGEN, amt) /mob/living/simple_animal/hostile/tree/AttackingTarget() diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index d906d58a3ec..fbb1d8fc11a 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -197,10 +197,14 @@ var/turf/simulated/ST = T if(ST.air) var/ST_gases = ST.air.gases - var/tox = ST_gases[GAS_PL][MOLES] - var/oxy = ST_gases[GAS_O2][MOLES] - var/n2 = ST_gases[GAS_N2][MOLES] - var/co2 = ST_gases[GAS_CO2][MOLES] + ST.air.assert_gases(arglist(hardcoded_gases)) + + var/tox = ST_gases["plasma"][MOLES] + var/oxy = ST_gases["o2"][MOLES] + var/n2 = ST_gases["n2"][MOLES] + var/co2 = ST_gases["co2"][MOLES] + + ST.air.garbage_collect() if(atmos_requirements["min_oxy"] && oxy < atmos_requirements["min_oxy"]) atmos_suitable = 0 diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm index 6901140a0b9..304e5a37a1f 100644 --- a/code/modules/power/singularity/collector.dm +++ b/code/modules/power/singularity/collector.dm @@ -26,12 +26,12 @@ var/global/list/rad_collectors = list() /obj/machinery/power/rad_collector/process() if(P) - if(P.air_contents.gases[GAS_PL][MOLES] <= 0) + if(!P.air_contents.gases["plasma"]) investigate_log("out of fuel.","singulo") - P.air_contents.gases[GAS_PL][MOLES] = 0 eject() else - P.air_contents.gases[GAS_PL][MOLES] -= 0.001*drainratio + P.air_contents.gases["plasma"][MOLES] -= 0.001*drainratio + P.air_contents.garbage_collect() return @@ -43,7 +43,7 @@ var/global/list/rad_collectors = list() toggle_power() user.visible_message("[user.name] turns the [src.name] [active? "on":"off"].", \ "You turn the [src.name] [active? "on":"off"].") - investigate_log("turned [active?"on":"off"] by [user.key]. [P?"Fuel: [round(P.air_contents.gases[GAS_PL][MOLES]/0.29)]%":"It is empty"].","singulo") + investigate_log("turned [active?"on":"off"] by [user.key]. [P?"Fuel: [round(P.air_contents.gases["plasma"][MOLES]/0.29)]%":"It is empty"].","singulo") return else user << "The controls are locked!" @@ -129,8 +129,8 @@ var/global/list/rad_collectors = list() /obj/machinery/power/rad_collector/proc/receive_pulse(pulse_strength) if(P && active) - var/power_produced = 0 - power_produced = P.air_contents.gases[GAS_PL][MOLES]*pulse_strength*20 + var/power_produced = P.air_contents.gases["plasma"] ? P.air_contents.gases["plasma"][MOLES] : 0 + power_produced *= pulse_strength*20 add_avail(power_produced) last_power = power_produced return diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 8b70dc80e59..4cc508f6f37 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -138,7 +138,13 @@ damage = max( damage + ( (removed.temperature - 800) / 150 ) , 0 ) //Ok, 100% oxygen atmosphere = best reaction //Maxes out at 100% oxygen pressure - oxygen = max(min((removed.gases[GAS_O2][MOLES] - (removed.gases[GAS_N2][MOLES] * NITROGEN_RETARDATION_FACTOR)) / MOLES_CELLSTANDARD, 1), 0) + var/removed_nitrogen = 0 + if(removed.gases["n2"]) + removed_nitrogen = (removed.gases["n2"][MOLES] * NITROGEN_RETARDATION_FACTOR) + + removed.assert_gases("o2", "plasma") + + oxygen = max(min((removed.gases["o2"][MOLES] - removed_nitrogen) / MOLES_CELLSTANDARD, 1), 0) var/temp_factor = 50 @@ -169,9 +175,9 @@ removed.temperature = max(0, min(removed.temperature, 2500)) //Calculate how much gas to release - removed.gases[GAS_PL][MOLES] += max(device_energy / PLASMA_RELEASE_MODIFIER, 0) + removed.gases["plasma"][MOLES] += max(device_energy / PLASMA_RELEASE_MODIFIER, 0) - removed.gases[GAS_O2][MOLES] += max((device_energy + removed.temperature - T0C) / OXYGEN_RELEASE_MODIFIER, 0) + removed.gases["o2"][MOLES] += max((device_energy + removed.temperature - T0C) / OXYGEN_RELEASE_MODIFIER, 0) env.merge(removed)