From 959b1728d96f5fef59a31329e230c43cf1717eb5 Mon Sep 17 00:00:00 2001 From: ShadowLarkens Date: Fri, 23 May 2025 08:21:06 -0700 Subject: [PATCH] Fix gas overlays (#17735) * Fix gas overlays not working * Make gas_data a GLOB * Just get rid of this entire cursed Initialize proc --- .../binary_devices/algae_generator_vr.dm | 6 +-- code/ZAS/Fire.dm | 12 ++--- code/ZAS/Phoron.dm | 2 +- code/ZAS/Zone.dm | 2 +- code/_helpers/atmospherics.dm | 2 +- code/controllers/subsystems/internal_wiki.dm | 4 +- code/controllers/verbs.dm | 1 - code/game/machinery/bomb_tester_vr.dm | 2 +- code/modules/admin/verbs/grief_fixers.dm | 4 +- code/modules/events/atmos_leak.dm | 2 +- code/modules/events/supply_demand_vr.dm | 4 +- .../event2/events/engineering/gas_leak.dm | 2 +- code/modules/hydroponics/trays/tray_tools.dm | 4 +- code/modules/mob/dead/observer/observer.dm | 2 +- code/modules/mob/living/carbon/human/life.dm | 2 +- .../silicon/robot/dogborg/dog_modules.dm | 2 +- code/modules/xgm/xgm_gas_data.dm | 48 +++++++++---------- code/modules/xgm/xgm_gas_mixture.dm | 28 +++++------ 18 files changed, 63 insertions(+), 66 deletions(-) diff --git a/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm b/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm index b74a5249ae0..aa7f9a2f7f3 100644 --- a/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm +++ b/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm @@ -92,7 +92,7 @@ // STEP 3 - Convert CO2 to O2 (Note: We know our internal group multipier is 1, so just be cool) var/co2_moles = internal.gas[input_gas] if(co2_moles < MINIMUM_MOLES_TO_FILTER) - ui_error = "Insufficient [gas_data.name[input_gas]] to process." + ui_error = "Insufficient [GLOB.gas_data.name[input_gas]] to process." update_icon() return @@ -194,13 +194,13 @@ if(air1 && network1 && node1) data["input"] = list( "pressure" = air1.return_pressure(), - "name" = gas_data.name[input_gas], + "name" = GLOB.gas_data.name[input_gas], "percent" = air1.total_moles > 0 ? round((air1.gas[input_gas] / air1.total_moles) * 100) : 0, "moles" = round(air1.gas[input_gas], 0.01)) if(air2 && network2 && node2) data["output"] = list( "pressure" = air2.return_pressure(), - "name" = gas_data.name[output_gas], + "name" = GLOB.gas_data.name[output_gas], "percent" = air2.total_moles ? round((air2.gas[output_gas] / air2.total_moles) * 100) : 0, "moles" = round(air2.gas[output_gas], 0.01)) diff --git a/code/ZAS/Fire.dm b/code/ZAS/Fire.dm index f594a3c313a..e7212190792 100644 --- a/code/ZAS/Fire.dm +++ b/code/ZAS/Fire.dm @@ -236,9 +236,9 @@ If it gains pressure too slowly, it may leak or just rupture instead of explodin //*** Get the fuel and oxidizer amounts for(var/g in gas) - if(gas_data.flags[g] & XGM_GAS_FUEL) + if(GLOB.gas_data.flags[g] & XGM_GAS_FUEL) gas_fuel += gas[g] - if(gas_data.flags[g] & XGM_GAS_OXIDIZER) + if(GLOB.gas_data.flags[g] & XGM_GAS_OXIDIZER) total_oxidizers += gas[g] gas_fuel *= group_multiplier total_oxidizers *= group_multiplier @@ -323,7 +323,7 @@ If it gains pressure too slowly, it may leak or just rupture instead of explodin /datum/gas_mixture/proc/check_recombustability(list/fuel_objs) . = 0 for(var/g in gas) - if(gas_data.flags[g] & XGM_GAS_OXIDIZER && gas[g] >= 0.1) + if(GLOB.gas_data.flags[g] & XGM_GAS_OXIDIZER && gas[g] >= 0.1) . = 1 break @@ -335,14 +335,14 @@ If it gains pressure too slowly, it may leak or just rupture instead of explodin . = 0 for(var/g in gas) - if(gas_data.flags[g] & XGM_GAS_FUEL && gas[g] >= 0.1) + if(GLOB.gas_data.flags[g] & XGM_GAS_FUEL && gas[g] >= 0.1) . = 1 break /datum/gas_mixture/proc/check_combustability(obj/effect/decal/cleanable/liquid_fuel/liquid=null) . = 0 for(var/g in gas) - if(gas_data.flags[g] & XGM_GAS_OXIDIZER && QUANTIZE(gas[g] * vsc.fire_consuption_rate) >= 0.1) + if(GLOB.gas_data.flags[g] & XGM_GAS_OXIDIZER && QUANTIZE(gas[g] * vsc.fire_consuption_rate) >= 0.1) . = 1 break @@ -354,7 +354,7 @@ If it gains pressure too slowly, it may leak or just rupture instead of explodin . = 0 for(var/g in gas) - if(gas_data.flags[g] & XGM_GAS_FUEL && QUANTIZE(gas[g] * vsc.fire_consuption_rate) >= 0.005) + if(GLOB.gas_data.flags[g] & XGM_GAS_FUEL && QUANTIZE(gas[g] * vsc.fire_consuption_rate) >= 0.005) . = 1 break diff --git a/code/ZAS/Phoron.dm b/code/ZAS/Phoron.dm index b4af8c2bec5..84ff99e9177 100644 --- a/code/ZAS/Phoron.dm +++ b/code/ZAS/Phoron.dm @@ -192,6 +192,6 @@ var/image/contamination_overlay = image('icons/effects/contamination.dmi') if(!env) return for(var/g in env.gas) - if(gas_data.flags[g] & XGM_GAS_CONTAMINANT && env.gas[g] > gas_data.overlay_limit[g] + 1) + if(GLOB.gas_data.flags[g] & XGM_GAS_CONTAMINANT && env.gas[g] > GLOB.gas_data.overlay_limit[g] + 1) I.contaminate() break diff --git a/code/ZAS/Zone.dm b/code/ZAS/Zone.dm index c38b92199e9..ef7c62812e8 100644 --- a/code/ZAS/Zone.dm +++ b/code/ZAS/Zone.dm @@ -170,7 +170,7 @@ Class Procs: /zone/proc/dbg_data(mob/M) to_chat(M,name) for(var/g in air.gas) - to_chat(M, "[gas_data.name[g]]: [air.gas[g]]") + to_chat(M, "[GLOB.gas_data.name[g]]: [air.gas[g]]") to_chat(M, "P: [air.return_pressure()] kPa V: [air.volume]L T: [air.temperature]°K ([air.temperature - T0C]°C)") to_chat(M, "O2 per N2: [(air.gas[GAS_N2] ? air.gas[GAS_O2]/air.gas[GAS_N2] : "N/A")] Moles: [air.total_moles]") to_chat(M, "Simulated: [contents.len] ([air.group_multiplier])") diff --git a/code/_helpers/atmospherics.dm b/code/_helpers/atmospherics.dm index c3f2ee05169..c2e8491915d 100644 --- a/code/_helpers/atmospherics.dm +++ b/code/_helpers/atmospherics.dm @@ -21,7 +21,7 @@ var/total_moles = mixture.total_moles results += span_notice("Pressure: [round(pressure,0.1)] kPa") for(var/mix in mixture.gas) - results += span_notice("[gas_data.name[mix]]: [round((mixture.gas[mix] / total_moles) * 100)]% ([round(mixture.gas[mix], 0.01)] moles)") + results += span_notice("[GLOB.gas_data.name[mix]]: [round((mixture.gas[mix] / total_moles) * 100)]% ([round(mixture.gas[mix], 0.01)] moles)") results += span_notice("Temperature: [round(mixture.temperature-T0C)]°C") results += span_notice("Heat Capacity: [round(mixture.heat_capacity(),0.1)]") else diff --git a/code/controllers/subsystems/internal_wiki.dm b/code/controllers/subsystems/internal_wiki.dm index 400acb65d86..69f3fa83433 100644 --- a/code/controllers/subsystems/internal_wiki.dm +++ b/code/controllers/subsystems/internal_wiki.dm @@ -955,14 +955,14 @@ SUBSYSTEM_DEF(internal_wiki) if(S.consume_gasses && S.consume_gasses.len > 0) var/list/consumed = list() for(var/CG in S.consume_gasses) - consumed["[gas_data.name[CG]]"] = S.consume_gasses[CG] + consumed["[GLOB.gas_data.name[CG]]"] = S.consume_gasses[CG] data["gas_consumed"] = consumed data["gas_exuded"] = null if(S.exude_gasses && S.exude_gasses.len > 0) var/list/exude = list() for(var/EG in S.exude_gasses) - exude["[gas_data.name[EG]]"] = S.exude_gasses[EG] + exude["[GLOB.gas_data.name[EG]]"] = S.exude_gasses[EG] data["gas_exuded"] = exude data["mutations"] = null diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index b0b913a189c..0d9371f65d1 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -96,7 +96,6 @@ INITIALIZE_IMMEDIATE(/obj/effect/statclick) options["LEGACY: paiController"] = paiController options["LEGACY: cameranet"] = cameranet options["LEGACY: transfer_controller"] = transfer_controller - options["LEGACY: gas_data"] = gas_data var/pick = tgui_input_list(mob, "Choose a controller to debug/view variables of.", "VV controller:", options) if(!pick) diff --git a/code/game/machinery/bomb_tester_vr.dm b/code/game/machinery/bomb_tester_vr.dm index 3bdf6432dc9..b5e68fc00a0 100644 --- a/code/game/machinery/bomb_tester_vr.dm +++ b/code/game/machinery/bomb_tester_vr.dm @@ -371,7 +371,7 @@ if(G.total_moles) results += "
Temperature: [round(G.temperature-T0C)]°C" for(var/mix in G.gas) - results += "
[gas_data.name[mix]]: [round((G.gas[mix] / G.total_moles) * 100)]%" + results += "
[GLOB.gas_data.name[mix]]: [round((G.gas[mix] / G.total_moles) * 100)]%" return results diff --git a/code/modules/admin/verbs/grief_fixers.dm b/code/modules/admin/verbs/grief_fixers.dm index e7370574812..d4391200a37 100644 --- a/code/modules/admin/verbs/grief_fixers.dm +++ b/code/modules/admin/verbs/grief_fixers.dm @@ -34,8 +34,8 @@ to_chat(usr, "\[3/5\] - All ZAS Zones removed.") var/list/unsorted_overlays = list() - for(var/id in gas_data.tile_overlay) - unsorted_overlays |= gas_data.tile_overlay[id] + for(var/id in GLOB.gas_data.tile_overlay) + unsorted_overlays |= GLOB.gas_data.tile_overlay[id] for(var/turf/simulated/T in world) diff --git a/code/modules/events/atmos_leak.dm b/code/modules/events/atmos_leak.dm index b9ca0ca20f9..64825b4d725 100644 --- a/code/modules/events/atmos_leak.dm +++ b/code/modules/events/atmos_leak.dm @@ -52,7 +52,7 @@ return /datum/event/atmos_leak/announce() - command_announcement.Announce("Warning, hazardous [gas_data.name[gas_type]] gas leak detected in \the [target_area], evacuate the area and contain the damage!", "Hazard Alert") + command_announcement.Announce("Warning, hazardous [GLOB.gas_data.name[gas_type]] gas leak detected in \the [target_area], evacuate the area and contain the damage!", "Hazard Alert") /datum/event/atmos_leak/start() // Okay, time to actually put the gas in the room! diff --git a/code/modules/events/supply_demand_vr.dm b/code/modules/events/supply_demand_vr.dm index 1439356fc66..dda2d8b6b75 100644 --- a/code/modules/events/supply_demand_vr.dm +++ b/code/modules/events/supply_demand_vr.dm @@ -224,7 +224,7 @@ var/total_moles = mixture.total_moles var desc = "Canister filled to [round(pressure,0.1)] kPa with gas mixture:\n" for(var/gas in mixture.gas) - desc += "
- [gas_data.name[gas]]: [round((mixture.gas[gas] / total_moles) * 100)]%\n" + desc += "
- [GLOB.gas_data.name[gas]]: [round((mixture.gas[gas] / total_moles) * 100)]%\n" return desc /datum/supply_demand_order/gas/match_item(var/obj/machinery/portable_atmospherics/canister) @@ -314,7 +314,7 @@ /datum/event/supply_demand/proc/choose_atmos_items(var/differentTypes) var/datum/gas_mixture/mixture = new mixture.temperature = T20C - var/unpickedTypes = gas_data.gases.Copy() + var/unpickedTypes = GLOB.gas_data.gases.Copy() unpickedTypes -= GAS_VOLATILE_FUEL // Don't do that one for(var/i in 1 to differentTypes) var/gasId = pick(unpickedTypes) diff --git a/code/modules/gamemaster/event2/events/engineering/gas_leak.dm b/code/modules/gamemaster/event2/events/engineering/gas_leak.dm index 0782e07b06c..4ef1f536775 100644 --- a/code/modules/gamemaster/event2/events/engineering/gas_leak.dm +++ b/code/modules/gamemaster/event2/events/engineering/gas_leak.dm @@ -31,7 +31,7 @@ /datum/event2/event/gas_leak/announce() if(chosen_turf) - command_announcement.Announce("Warning, hazardous [lowertext(gas_data.name[chosen_gas])] gas leak detected in \the [chosen_turf.loc], evacuate the area.", "Hazard Alert") + command_announcement.Announce("Warning, hazardous [lowertext(GLOB.gas_data.name[chosen_gas])] gas leak detected in \the [chosen_turf.loc], evacuate the area.", "Hazard Alert") /datum/event2/event/gas_leak/start() // Okay, time to actually put the gas in the room! diff --git a/code/modules/hydroponics/trays/tray_tools.dm b/code/modules/hydroponics/trays/tray_tools.dm index 088fc260b4e..9c35bca89a8 100644 --- a/code/modules/hydroponics/trays/tray_tools.dm +++ b/code/modules/hydroponics/trays/tray_tools.dm @@ -297,7 +297,7 @@ amount = "large amounts of " else if (exude_gasses[gas] < 5) amount = "small amounts of " - data["trait_info"] += "It will release [amount][gas_data.name[gas]] into the environment." + data["trait_info"] += "It will release [amount][GLOB.gas_data.name[gas]] into the environment." if(consume_gasses && consume_gasses.len) for(var/gas in consume_gasses) @@ -306,6 +306,6 @@ amount = "large amounts of " else if (consume_gasses[gas] < 5) amount = "small amounts of " - data["trait_info"] += "It will consume [amount][gas_data.name[gas]] from the environment." + data["trait_info"] += "It will consume [amount][GLOB.gas_data.name[gas]] from the environment." return data diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 9ad34e88c42..9594c1457d7 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -683,7 +683,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp gas_analyzing += span_red("Pressure: [round(pressure,0.1)] kPa") if(total_moles) for(var/g in environment.gas) - gas_analyzing += "[gas_data.name[g]]: [round((environment.gas[g] / total_moles) * 100)]% ([round(environment.gas[g], 0.01)] moles)" + gas_analyzing += "[GLOB.gas_data.name[g]]: [round((environment.gas[g] / total_moles) * 100)]% ([round(environment.gas[g], 0.01)] moles)" gas_analyzing += "Temperature: [round(environment.temperature-T0C,0.1)]°C ([round(environment.temperature,0.1)]K)" gas_analyzing += "Heat Capacity: [round(environment.heat_capacity(),0.1)]" to_chat(src, span_notice("[jointext(gas_analyzing, "
")]")) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 12a093ff338..6deca9c03e8 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -866,7 +866,7 @@ //Check for contaminants before anything else because we don't want to skip it. for(var/g in environment.gas) - if(gas_data.flags[g] & XGM_GAS_CONTAMINANT && environment.gas[g] > gas_data.overlay_limit[g] + 1) + if(GLOB.gas_data.flags[g] & XGM_GAS_CONTAMINANT && environment.gas[g] > GLOB.gas_data.overlay_limit[g] + 1) pl_effects() break diff --git a/code/modules/mob/living/silicon/robot/dogborg/dog_modules.dm b/code/modules/mob/living/silicon/robot/dogborg/dog_modules.dm index 3869da94b4d..7d8bd2ad173 100644 --- a/code/modules/mob/living/silicon/robot/dogborg/dog_modules.dm +++ b/code/modules/mob/living/silicon/robot/dogborg/dog_modules.dm @@ -29,7 +29,7 @@ to_chat(user, span_warning("Pressure: [round(pressure,0.1)] kPa")) if(total_moles) for(var/g in environment.gas) - to_chat(user, span_notice("[gas_data.name[g]]: [round((environment.gas[g] / total_moles) * 100)]%")) + to_chat(user, span_notice("[GLOB.gas_data.name[g]]: [round((environment.gas[g] / total_moles) * 100)]%")) to_chat(user, span_notice("Temperature: [round(environment.temperature-T0C,0.1)]°C ([round(environment.temperature,0.1)]K)")) /obj/item/boop_module/afterattack(obj/O, mob/user as mob, proximity) diff --git a/code/modules/xgm/xgm_gas_data.dm b/code/modules/xgm/xgm_gas_data.dm index 488477401ee..1041793928f 100644 --- a/code/modules/xgm/xgm_gas_data.dm +++ b/code/modules/xgm/xgm_gas_data.dm @@ -1,4 +1,4 @@ -/var/datum/xgm_gas_data/gas_data +GLOBAL_DATUM_INIT(gas_data, /datum/xgm_gas_data, new()) /datum/xgm_gas_data //Simple list of all the gas IDs. @@ -16,6 +16,28 @@ //Flags. var/list/flags = list() +/datum/xgm_gas_data/New() + . = ..() + for(var/p in subtypesof(/decl/xgm_gas)) + var/decl/xgm_gas/gas = new p //avoid initial() because of potential New() actions + + if(gas.id in gases) + error("Duplicate gas id `[gas.id]` in `[p]`") + + gases += gas.id + name[gas.id] = gas.name + specific_heat[gas.id] = gas.specific_heat + molar_mass[gas.id] = gas.molar_mass + if(gas.tile_overlay) + var/atom/movable/gas_visuals/GV = new(null) + GV.icon_state = gas.tile_overlay + tile_overlay[gas.id] = GV + if(gas.overlay_limit) + overlay_limit[gas.id] = gas.overlay_limit + flags[gas.id] = gas.flags + + return 1 + /decl/xgm_gas var/id = "" var/name = "Unnamed Gas" @@ -27,31 +49,7 @@ var/flags = 0 -/hook/startup/proc/generateGasData() - gas_data = new - for(var/p in subtypesof(/decl/xgm_gas)) - var/decl/xgm_gas/gas = new p //avoid initial() because of potential New() actions - - if(gas.id in gas_data.gases) - error("Duplicate gas id `[gas.id]` in `[p]`") - - gas_data.gases += gas.id - gas_data.name[gas.id] = gas.name - gas_data.specific_heat[gas.id] = gas.specific_heat - gas_data.molar_mass[gas.id] = gas.molar_mass - if(gas.tile_overlay) - gas_data.tile_overlay[gas.id] = new /atom/movable/gas_visuals(null, gas.tile_overlay) - if(gas.overlay_limit) - gas_data.overlay_limit[gas.id] = gas.overlay_limit - gas_data.flags[gas.id] = gas.flags - - return 1 - /atom/movable/gas_visuals icon = 'icons/effects/tile_effects.dmi' mouse_opacity = 0 plane = ABOVE_MOB_PLANE - -/atom/movable/gas_visuals/Initialize(mapload, ico) - . = ..() - icon_state = ico diff --git a/code/modules/xgm/xgm_gas_mixture.dm b/code/modules/xgm/xgm_gas_mixture.dm index 4c134e56121..d73ec26e80d 100644 --- a/code/modules/xgm/xgm_gas_mixture.dm +++ b/code/modules/xgm/xgm_gas_mixture.dm @@ -40,7 +40,7 @@ if(moles > 0 && abs(temperature - temp) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) var/self_heat_capacity = heat_capacity() - var/giver_heat_capacity = gas_data.specific_heat[gasid] * moles + var/giver_heat_capacity = GLOB.gas_data.specific_heat[gasid] * moles var/combined_heat_capacity = giver_heat_capacity + self_heat_capacity if(combined_heat_capacity != 0) temperature = (temp * giver_heat_capacity + temperature * self_heat_capacity) / combined_heat_capacity @@ -127,7 +127,7 @@ /datum/gas_mixture/proc/heat_capacity() . = 0 for(var/g in gas) - . += gas_data.specific_heat[g] * gas[g] + . += GLOB.gas_data.specific_heat[g] * gas[g] . *= group_multiplier @@ -182,8 +182,8 @@ return SPECIFIC_ENTROPY_VACUUM //that gas isn't here //group_multiplier gets divided out in volume/gas[gasid] - also, V/(m*T) = R/(partial pressure) - var/molar_mass = gas_data.molar_mass[gasid] - var/specific_heat = gas_data.specific_heat[gasid] + var/molar_mass = GLOB.gas_data.molar_mass[gasid] + var/specific_heat = GLOB.gas_data.specific_heat[gasid] return R_IDEAL_GAS_EQUATION * ( log( (IDEAL_GAS_ENTROPY_CONSTANT*volume/(gas[gasid] * temperature)) * (molar_mass*specific_heat*temperature)**(2/3) + 1 ) + 15 ) //alternative, simpler equation @@ -263,13 +263,13 @@ var/sum = 0 for(var/g in gas) - if(gas_data.flags[g] & flag) + if(GLOB.gas_data.flags[g] & flag) sum += gas[g] var/datum/gas_mixture/removed = new for(var/g in gas) - if(gas_data.flags[g] & flag) + if(GLOB.gas_data.flags[g] & flag) removed.gas[g] = QUANTIZE((gas[g] / sum) * amount) gas[g] -= removed.gas[g] / group_multiplier @@ -283,7 +283,7 @@ /datum/gas_mixture/proc/get_by_flag(flag) . = 0 for(var/g in gas) - if(gas_data.flags[g] & flag) + if(GLOB.gas_data.flags[g] & flag) . += gas[g] //Copies gas and temperature from another gas_mixture. @@ -339,15 +339,15 @@ //Two lists can be passed by reference if you need know specifically which graphics were added and removed. /datum/gas_mixture/proc/check_tile_graphic(list/graphic_add = null, list/graphic_remove = null) var/list/cur_graphic = graphic // Cache for sanic speed - for(var/g in gas_data.overlay_limit) - if(cur_graphic && cur_graphic.Find(gas_data.tile_overlay[g])) + for(var/g in GLOB.gas_data.overlay_limit) + if(cur_graphic && cur_graphic.Find(GLOB.gas_data.tile_overlay[g])) //Overlay is already applied for this gas, check if it's still valid. - if(gas[g] <= gas_data.overlay_limit[g]) - LAZYADD(graphic_remove, gas_data.tile_overlay[g]) + if(gas[g] <= GLOB.gas_data.overlay_limit[g]) + LAZYADD(graphic_remove, GLOB.gas_data.tile_overlay[g]) else //Overlay isn't applied for this gas, check if it's valid and needs to be added. - if(gas[g] > gas_data.overlay_limit[g]) - LAZYADD(graphic_add, gas_data.tile_overlay[g]) + if(gas[g] > GLOB.gas_data.overlay_limit[g]) + LAZYADD(graphic_add, GLOB.gas_data.tile_overlay[g]) . = 0 //Apply changes @@ -489,4 +489,4 @@ /datum/gas_mixture/proc/get_mass() for(var/g in gas) - . += gas[g] * gas_data.molar_mass[g] * group_multiplier + . += gas[g] * GLOB.gas_data.molar_mass[g] * group_multiplier