/* 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) \ max(0, carbon_dioxide * SPECIFIC_HEAT_CDO + (oxygen + nitrogen) * SPECIFIC_HEAT_AIR + toxins * SPECIFIC_HEAT_TOXIN) #define MINIMUM_HEAT_CAPACITY 0.0003 #define QUANTIZE(variable) (round(variable,0.0001)) #define TRANSFER_FRACTION 5 //What fraction (1/#) of the air difference to try and transfer // /vg/ SHIT #define TEMPERATURE_ICE_FORMATION 273.15 // 273 kelvin is the freezing point of water. #define MIN_PRESSURE_ICE_FORMATION 10 // 10kPa should be okay #define GRAPHICS_PLASMA 1 #define GRAPHICS_N2O 2 #define GRAPHICS_REAGENTS 4 // Not used. Yet. #define GRAPHICS_COLD 8 // END VGSHIT /hook/startup/proc/createGasOverlays() writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/hook/startup/proc/createGasOverlays() called tick#: [world.time]") plmaster = new /obj/effect/overlay() plmaster.icon = 'icons/effects/tile_effects.dmi' plmaster.icon_state = "plasma" plmaster.layer = FLY_LAYER plmaster.mouse_opacity = 0 slmaster = new /obj/effect/overlay() slmaster.icon = 'icons/effects/tile_effects.dmi' slmaster.icon_state = "sleeping_agent" slmaster.layer = FLY_LAYER slmaster.mouse_opacity = 0 return 1 /datum/gas/sleeping_agent/specific_heat = 40 //These are used for the "Trace Gases" stuff, but is buggy. /datum/gas/oxygen_agent_b/specific_heat = 300 /datum/gas/volatile_fuel/specific_heat = 30 /datum/gas var/moles = 0 var/specific_heat = 0 var/moles_archived = 0 /datum/gas_mixture/ var/oxygen = 0 //Holds the "moles" of each of the four gases. var/carbon_dioxide = 0 var/nitrogen = 0 var/toxins = 0 var/total_moles = 0 //Updated when a reaction occurs. var/volume = CELL_VOLUME var/temperature = 0 //in Kelvin, use calculate_temperature() to modify var/group_multiplier = 1 //Size of the group this gas_mixture is representing. //=1 for singletons var/graphics=0 var/pressure=0 var/list/datum/gas/trace_gases = list() //Seemed to be a good idea that was abandoned var/tmp/oxygen_archived //These are variables for use with the archived data var/tmp/carbon_dioxide_archived var/tmp/nitrogen_archived var/tmp/toxins_archived var/tmp/temperature_archived var/tmp/graphics_archived = 0 var/tmp/fuel_burnt = 0 //var/datum/reagents/aerosols /* /datum/gas_mixture/New() //create_reagents(10) */ //FOR THE LOVE OF GOD PLEASE USE THIS PROC //Call it with negative numbers to remove gases. /datum/gas_mixture/proc/adjust(o2 = 0, co2 = 0, n2 = 0, tx = 0, list/datum/gas/traces = list()) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/adjust() called tick#: [world.time]") //Purpose: Adjusting the gases within a airmix //Called by: Nothing, yet! //Inputs: The values of the gases to adjust //Outputs: null oxygen = max(0, oxygen + o2) carbon_dioxide = max(0, carbon_dioxide + co2) nitrogen = max(0, nitrogen + n2) toxins = max(0, toxins + tx) //handle trace gasses for(var/datum/gas/G in traces) var/datum/gas/T = locate(G.type) in trace_gases if(T) T.moles = max(G.moles + T.moles, 0) else if(G.moles > 0) trace_gases |= G update_values() return //Takes a gas string, and the amount of moles to adjust by. Calls update_values() if update isn't 0. /datum/gas_mixture/proc/adjust_gas(gasid, moles, update = 1) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/adjust_gas() called tick#: [world.time]") if(moles == 0) return switch(gasid) if("oxygen") if (group_multiplier != 1) oxygen += moles/group_multiplier else oxygen += moles if("plasma") if (group_multiplier != 1) toxins += moles/group_multiplier else toxins += moles if("carbon_dioxide") if (group_multiplier != 1) carbon_dioxide += moles/group_multiplier else carbon_dioxide += moles if("nitrogen") if (group_multiplier != 1) nitrogen += moles/group_multiplier else nitrogen += moles if(update) update_values() /* /datum/gas_mixture/proc/create_reagents(var/max_vol) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/create_reagents() called tick#: [world.time]") aerosols = new /datum/reagents(max_vol) aerosols.my_atom = src */ //tg seems to like using these a lot /datum/gas_mixture/proc/return_temperature() writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/return_temperature() called tick#: [world.time]") return temperature /datum/gas_mixture/proc/return_volume() writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/return_volume() called tick#: [world.time]") return max(0, volume) /datum/gas_mixture/proc/thermal_energy() writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/thermal_energy() called tick#: [world.time]") return temperature*heat_capacity() /////////////////////////////// //PV=nRT - related procedures// /////////////////////////////// /datum/gas_mixture/proc/heat_capacity() writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/heat_capacity() called tick#: [world.time]") //Purpose: Returning the heat capacity of the gas mix //Called by: UNKNOWN //Inputs: None //Outputs: Heat capacity var/heat_capacity = HEAT_CAPACITY_CALCULATION(oxygen,carbon_dioxide,nitrogen,toxins) if(trace_gases && trace_gases.len) //sanity check because somehow the tracegases gets nulled? for(var/datum/gas/trace_gas in trace_gases) heat_capacity += trace_gas.moles*trace_gas.specific_heat return max(MINIMUM_HEAT_CAPACITY,heat_capacity) /datum/gas_mixture/proc/heat_capacity_archived() writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/heat_capacity_archived() called tick#: [world.time]") //Purpose: Returning the archived heat capacity of the gas mix //Called by: UNKNOWN //Inputs: None //Outputs: Archived heat capacity var/heat_capacity_archived = HEAT_CAPACITY_CALCULATION(oxygen_archived,carbon_dioxide_archived,nitrogen_archived,toxins_archived) if(trace_gases.len) for(var/datum/gas/trace_gas in trace_gases) heat_capacity_archived += trace_gas.moles_archived*trace_gas.specific_heat return max(MINIMUM_HEAT_CAPACITY,heat_capacity_archived) /datum/gas_mixture/proc/total_moles() writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/total_moles() called tick#: [world.time]") return total_moles /*var/moles = oxygen + carbon_dioxide + nitrogen + toxins if(trace_gases.len) for(var/datum/gas/trace_gas in trace_gases) moles += trace_gas.moles return moles*/ /datum/gas_mixture/proc/return_pressure() writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/return_pressure() called tick#: [world.time]") //Purpose: Calculating Current Pressure //Called by: //Inputs: None //Outputs: Gas pressure. return pressure // proc/return_temperature() //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\// proc/return_temperature() called tick#: [world.time]") //Purpose: //Inputs: //Outputs: // return temperature // proc/return_volume() //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\// proc/return_volume() called tick#: [world.time]") //Purpose: //Inputs: //Outputs: // return max(0, volume) // proc/thermal_energy() //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\// proc/thermal_energy() called tick#: [world.time]") //Purpose: //Inputs: //Outputs: // return temperature*heat_capacity() /datum/gas_mixture/proc/update_values() writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/update_values() called tick#: [world.time]") //Purpose: Calculating and storing values which were normally called CONSTANTLY //Called by: Anything that changes values within a gas mix. //Inputs: None //Outputs: None total_moles = oxygen + carbon_dioxide + nitrogen + toxins if(trace_gases.len) for(var/datum/gas/trace_gas in trace_gases) total_moles += trace_gas.moles /* if(aerosols.total_volume) total_moles += aerosols.total_volume */ if(volume>0) pressure = total_moles()*R_IDEAL_GAS_EQUATION*temperature/volume else pressure = 0 return //////////////////////////////////////////// //Procedures used for very specific events// //////////////////////////////////////////// /datum/gas_mixture/proc/check_tile_graphic() writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/check_tile_graphic() called tick#: [world.time]") //Purpose: Calculating the graphic for a tile //Called by: Turfs updating //Inputs: None //Outputs: 1 if graphic changed, 0 if unchanged graphics = 0 // If configured and cold, maek ice if(zas_settings.Get(/datum/ZAS_Setting/ice_formation)) if(temperature <= TEMPERATURE_ICE_FORMATION && return_pressure()>MIN_PRESSURE_ICE_FORMATION) // If we're just forming, do a probability check. Otherwise, KEEP IT ON~ // This ordering will hopefully keep it from sampling random noise every damn tick. //if(was_icy || (!was_icy && prob(25))) graphics |= GRAPHICS_COLD if(toxins > MOLES_PLASMA_VISIBLE) graphics |= GRAPHICS_PLASMA if(length(trace_gases)) var/datum/gas/sleeping_agent = locate(/datum/gas/sleeping_agent) in trace_gases if(sleeping_agent && (sleeping_agent.moles > 1)) graphics |= GRAPHICS_N2O /* if(aerosols && aerosols.total_volume >= 1) graphics |= GRAPHICS_REAGENTS */ return graphics != graphics_archived /datum/gas_mixture/proc/react(atom/dump_location) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/react() called tick#: [world.time]") //Purpose: Calculating if it is possible for a fire to occur in the airmix //Called by: Air mixes updating? //Inputs: None //Outputs: If a fire occured //set to 1 if a notable reaction occured (used by pipe_network) return zburn(null) // ? (was: return reacting) /datum/gas_mixture/proc/fire() writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/fire() called tick#: [world.time]") //Purpose: Calculating any fire reactions. //Called by: react() (See above) //Inputs: None //Outputs: How much fuel burned return zburn(null) /*var/energy_released = 0 var/old_heat_capacity = heat_capacity() var/datum/gas/volatile_fuel/fuel_store = locate(/datum/gas/volatile_fuel) in trace_gases if(fuel_store) //General volatile gas burn var/burned_fuel = 0 if(oxygen < fuel_store.moles) burned_fuel = oxygen fuel_store.moles -= burned_fuel oxygen = 0 else burned_fuel = fuel_store.moles oxygen -= fuel_store.moles del(fuel_store) energy_released += FIRE_CARBON_ENERGY_RELEASED * burned_fuel carbon_dioxide += burned_fuel fuel_burnt += burned_fuel //Handle plasma burning if(toxins > MINIMUM_HEAT_CAPACITY) var/plasma_burn_rate = 0 var/oxygen_burn_rate = 0 //more plasma released at higher temperatures var/temperature_scale if(temperature > PLASMA_UPPER_TEMPERATURE) temperature_scale = 1 else temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE) if(temperature_scale > 0) oxygen_burn_rate = 1.4 - temperature_scale if(oxygen > toxins*PLASMA_OXYGEN_FULLBURN) plasma_burn_rate = (toxins*temperature_scale)/4 else plasma_burn_rate = (temperature_scale*(oxygen/PLASMA_OXYGEN_FULLBURN))/4 if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY) toxins -= plasma_burn_rate oxygen -= plasma_burn_rate*oxygen_burn_rate carbon_dioxide += plasma_burn_rate energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate) fuel_burnt += (plasma_burn_rate)*(1+oxygen_burn_rate) if(energy_released > 0) var/new_heat_capacity = heat_capacity() if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) temperature = (temperature*old_heat_capacity + energy_released)/new_heat_capacity update_values() return fuel_burnt*/ ////////////////////////////////////////////// //Procs for general gas spread calculations.// ////////////////////////////////////////////// /datum/gas_mixture/proc/archive() writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/archive() called tick#: [world.time]") //Purpose: Archives the current gas values //Called by: UNKNOWN //Inputs: None //Outputs: 1 oxygen_archived = oxygen carbon_dioxide_archived = carbon_dioxide nitrogen_archived = nitrogen toxins_archived = toxins if(trace_gases.len) for(var/datum/gas/trace_gas in trace_gases) trace_gas.moles_archived = trace_gas.moles temperature_archived = temperature graphics_archived = graphics return 1 /datum/gas_mixture/proc/check_then_merge(datum/gas_mixture/giver) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/check_then_merge() called tick#: [world.time]") //Purpose: Similar to merge(...) but first checks to see if the amount of air assumed is small enough // that group processing is still accurate for source (aborts if not) //Called by: airgroups/machinery expelling air, ? //Inputs: The gas to try and merge //Outputs: 1 on successful merge. 0 otherwise. if(!giver) return 0 if(((giver.oxygen > MINIMUM_AIR_TO_SUSPEND) && (giver.oxygen >= oxygen*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ || ((giver.carbon_dioxide > MINIMUM_AIR_TO_SUSPEND) && (giver.carbon_dioxide >= carbon_dioxide*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ || ((giver.nitrogen > MINIMUM_AIR_TO_SUSPEND) && (giver.nitrogen >= nitrogen*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ || ((giver.toxins > MINIMUM_AIR_TO_SUSPEND) && (giver.toxins >= toxins*MINIMUM_AIR_RATIO_TO_SUSPEND))) return 0 if(abs(giver.temperature - temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) return 0 if(giver.trace_gases.len) for(var/datum/gas/trace_gas in giver.trace_gases) var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases if((trace_gas.moles > MINIMUM_AIR_TO_SUSPEND) && (!corresponding || (trace_gas.moles >= corresponding.moles*MINIMUM_AIR_RATIO_TO_SUSPEND))) return 0 return merge(giver) /datum/gas_mixture/proc/merge(datum/gas_mixture/giver) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/merge() called tick#: [world.time]") //Purpose: Merges all air from giver into self. Deletes giver. //Called by: Machinery expelling air, check_then_merge, ? //Inputs: The gas to merge. //Outputs: 1 if(!giver) return 0 if(abs(temperature-giver.temperature)>MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) var/self_heat_capacity = heat_capacity()*group_multiplier var/giver_heat_capacity = giver.heat_capacity()*giver.group_multiplier var/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 if((group_multiplier>1)||(giver.group_multiplier>1)) oxygen += giver.oxygen*giver.group_multiplier/group_multiplier carbon_dioxide += giver.carbon_dioxide*giver.group_multiplier/group_multiplier nitrogen += giver.nitrogen*giver.group_multiplier/group_multiplier toxins += giver.toxins*giver.group_multiplier/group_multiplier else oxygen += giver.oxygen carbon_dioxide += giver.carbon_dioxide nitrogen += giver.nitrogen toxins += giver.toxins if(giver.trace_gases.len) for(var/datum/gas/trace_gas in giver.trace_gases) var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases if(!corresponding) corresponding = new trace_gas.type() trace_gases += corresponding corresponding.moles += trace_gas.moles*giver.group_multiplier/group_multiplier /* if(giver.aerosols.total_volume > 1) giver.aerosols.trans_to_atmos(src,aerosols.total_volume) */ update_values() // Let the garbage collector handle it, faster according to /tg/ testers //del(giver) return 1 /datum/gas_mixture/proc/remove(amount) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/remove() called tick#: [world.time]") //Purpose: Removes a certain number of moles from the air. //Called by: ? //Inputs: How many moles to remove. //Outputs: Removed air. // Fix a singuloth problem if(group_multiplier==0) return null var/sum = total_moles() amount = min(amount,sum) //Can not take more air than tile has! if(amount <= 0) return null var/datum/gas_mixture/removed = new removed.oxygen = QUANTIZE((oxygen/sum)*amount) removed.nitrogen = QUANTIZE((nitrogen/sum)*amount) removed.carbon_dioxide = QUANTIZE((carbon_dioxide/sum)*amount) removed.toxins = QUANTIZE((toxins/sum)*amount) oxygen -= removed.oxygen/group_multiplier nitrogen -= removed.nitrogen/group_multiplier carbon_dioxide -= removed.carbon_dioxide/group_multiplier toxins -= removed.toxins/group_multiplier if(trace_gases.len) for(var/datum/gas/trace_gas in trace_gases) var/datum/gas/corresponding = new trace_gas.type() removed.trace_gases += corresponding corresponding.moles = (trace_gas.moles/sum)*amount trace_gas.moles -= corresponding.moles/group_multiplier /* if(aerosols.total_volume > 1) removed.aerosols.trans_to_atmos(src,(aerosols.total_volume/sum)*amount) */ removed.temperature = temperature update_values() removed.update_values() return removed /datum/gas_mixture/proc/remove_ratio(ratio) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/remove_ratio() called tick#: [world.time]") //Purpose: Removes a certain ratio of the air. //Called by: ? //Inputs: Percentage to remove. //Outputs: Removed air. if(ratio <= 0) return null ratio = min(ratio, 1) var/datum/gas_mixture/removed = new removed.oxygen = QUANTIZE(oxygen*ratio) removed.nitrogen = QUANTIZE(nitrogen*ratio) removed.carbon_dioxide = QUANTIZE(carbon_dioxide*ratio) removed.toxins = QUANTIZE(toxins*ratio) oxygen -= removed.oxygen/group_multiplier nitrogen -= removed.nitrogen/group_multiplier carbon_dioxide -= removed.carbon_dioxide/group_multiplier toxins -= removed.toxins/group_multiplier if(trace_gases.len) for(var/datum/gas/trace_gas in trace_gases) var/datum/gas/corresponding = new trace_gas.type() removed.trace_gases += corresponding corresponding.moles = trace_gas.moles*ratio trace_gas.moles -= corresponding.moles/group_multiplier removed.temperature = temperature update_values() removed.update_values() return removed /datum/gas_mixture/proc/check_then_remove(amount) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/check_then_remove() called tick#: [world.time]") //Purpose: Similar to remove(...) but first checks to see if the amount of air removed is small enough // that group processing is still accurate for source (aborts if not) //Called by: ? //Inputs: Number of moles to remove //Outputs: Removed air or 0 if it can remove air or not. amount = min(amount,total_moles()) //Can not take more air than tile has! if((amount > MINIMUM_AIR_RATIO_TO_SUSPEND) && (amount > total_moles()*MINIMUM_AIR_RATIO_TO_SUSPEND)) return 0 return remove(amount) /datum/gas_mixture/proc/copy_from(datum/gas_mixture/sample) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/copy_from() called tick#: [world.time]") //Purpose: Duplicates the sample air mixture. //Called by: airgroups splitting, ? //Inputs: Gas to copy //Outputs: 1 oxygen = sample.oxygen carbon_dioxide = sample.carbon_dioxide nitrogen = sample.nitrogen toxins = sample.toxins total_moles = sample.total_moles() trace_gases.len=null if(sample.trace_gases.len > 0) for(var/datum/gas/trace_gas in sample.trace_gases) var/datum/gas/corresponding = new trace_gas.type() trace_gases += corresponding corresponding.moles = trace_gas.moles temperature = sample.temperature return 1 /datum/gas_mixture/proc/check_gas_mixture(datum/gas_mixture/sharer) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/check_gas_mixture() called tick#: [world.time]") //Purpose: Telling if one or both airgroups needs to disable group processing. //Called by: Airgroups sharing air, checking if group processing needs disabled. //Inputs: Gas to compare from other airgroup //Outputs: 0 if the self-check failed (local airgroup breaks?) // then -1 if sharer-check failed (sharing airgroup breaks?) // then 1 if both checks pass (share succesful?) if(!istype(sharer)) return var/delta_oxygen = QUANTIZE(oxygen_archived - sharer.oxygen_archived)/TRANSFER_FRACTION var/delta_carbon_dioxide = QUANTIZE(carbon_dioxide_archived - sharer.carbon_dioxide_archived)/TRANSFER_FRACTION var/delta_nitrogen = QUANTIZE(nitrogen_archived - sharer.nitrogen_archived)/TRANSFER_FRACTION var/delta_toxins = QUANTIZE(toxins_archived - sharer.toxins_archived)/TRANSFER_FRACTION var/delta_temperature = (temperature_archived - sharer.temperature_archived) if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ || ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ || ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ || ((abs(delta_toxins) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_toxins) >= toxins_archived*MINIMUM_AIR_RATIO_TO_SUSPEND))) return 0 if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) return 0 if(sharer.trace_gases.len) for(var/datum/gas/trace_gas in sharer.trace_gases) if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4) var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases if(corresponding) if(trace_gas.moles_archived >= corresponding.moles_archived*MINIMUM_AIR_RATIO_TO_SUSPEND*4) return 0 else return 0 if(trace_gases.len) for(var/datum/gas/trace_gas in trace_gases) if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4) if(!locate(trace_gas.type) in sharer.trace_gases) return 0 if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= sharer.oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ || ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= sharer.carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ || ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= sharer.nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ || ((abs(delta_toxins) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_toxins) >= sharer.toxins_archived*MINIMUM_AIR_RATIO_TO_SUSPEND))) return -1 if(trace_gases.len) for(var/datum/gas/trace_gas in trace_gases) if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4) var/datum/gas/corresponding = locate(trace_gas.type) in sharer.trace_gases if(corresponding) if(trace_gas.moles_archived >= corresponding.moles_archived*MINIMUM_AIR_RATIO_TO_SUSPEND*4) return -1 else return -1 return 1 /datum/gas_mixture/proc/check_turf(turf/model) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/check_turf() called tick#: [world.time]") //Purpose: Used to compare the gases in an unsimulated turf with the gas in a simulated one. //Called by: Sharing air (mimicing) with adjacent unsimulated turfs //Inputs: Unsimulated turf //Outputs: 1 if safe to mimic, 0 if needs to break airgroup. var/delta_oxygen = (oxygen_archived - model.oxygen)/TRANSFER_FRACTION var/delta_carbon_dioxide = (carbon_dioxide_archived - model.carbon_dioxide)/TRANSFER_FRACTION var/delta_nitrogen = (nitrogen_archived - model.nitrogen)/TRANSFER_FRACTION var/delta_toxins = (toxins_archived - model.toxins)/TRANSFER_FRACTION var/delta_temperature = (temperature_archived - model.temperature) if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ || ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ || ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ || ((abs(delta_toxins) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_toxins) >= toxins_archived*MINIMUM_AIR_RATIO_TO_SUSPEND))) return 0 if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) return 0 if(trace_gases.len) for(var/datum/gas/trace_gas in trace_gases) if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4) return 0 return 1 /datum/gas_mixture/proc/share(datum/gas_mixture/sharer) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/share() called tick#: [world.time]") //Purpose: Used to transfer gas from a more pressurised tile to a less presurised tile // (Two directional, if the other tile is more pressurised, air travels to current tile) //Called by: Sharing air with adjacent simulated turfs //Inputs: Air datum to share with //Outputs: Amount of gas exchanged (Negative if lost air, positive if gained.) if(!istype(sharer)) return var/delta_oxygen = QUANTIZE(oxygen_archived - sharer.oxygen_archived)/TRANSFER_FRACTION var/delta_carbon_dioxide = QUANTIZE(carbon_dioxide_archived - sharer.carbon_dioxide_archived)/TRANSFER_FRACTION var/delta_nitrogen = QUANTIZE(nitrogen_archived - sharer.nitrogen_archived)/TRANSFER_FRACTION var/delta_toxins = QUANTIZE(toxins_archived - sharer.toxins_archived)/TRANSFER_FRACTION var/delta_temperature = (temperature_archived - sharer.temperature_archived) var/old_self_heat_capacity = 0 var/old_sharer_heat_capacity = 0 var/heat_self_to_sharer = 0 var/heat_capacity_self_to_sharer = 0 var/heat_sharer_to_self = 0 var/heat_capacity_sharer_to_self = 0 if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) var/delta_air = delta_oxygen+delta_nitrogen if(delta_air) var/air_heat_capacity = SPECIFIC_HEAT_AIR*delta_air if(delta_air > 0) heat_self_to_sharer += air_heat_capacity*temperature_archived heat_capacity_self_to_sharer += air_heat_capacity else heat_sharer_to_self -= air_heat_capacity*sharer.temperature_archived heat_capacity_sharer_to_self -= air_heat_capacity if(delta_carbon_dioxide) var/carbon_dioxide_heat_capacity = SPECIFIC_HEAT_CDO*delta_carbon_dioxide if(delta_carbon_dioxide > 0) heat_self_to_sharer += carbon_dioxide_heat_capacity*temperature_archived heat_capacity_self_to_sharer += carbon_dioxide_heat_capacity else heat_sharer_to_self -= carbon_dioxide_heat_capacity*sharer.temperature_archived heat_capacity_sharer_to_self -= carbon_dioxide_heat_capacity if(delta_toxins) var/toxins_heat_capacity = SPECIFIC_HEAT_TOXIN*delta_toxins if(delta_toxins > 0) heat_self_to_sharer += toxins_heat_capacity*temperature_archived heat_capacity_self_to_sharer += toxins_heat_capacity else heat_sharer_to_self -= toxins_heat_capacity*sharer.temperature_archived heat_capacity_sharer_to_self -= toxins_heat_capacity old_self_heat_capacity = heat_capacity()*group_multiplier old_sharer_heat_capacity = sharer.heat_capacity()*sharer.group_multiplier oxygen -= delta_oxygen/group_multiplier sharer.oxygen += delta_oxygen/sharer.group_multiplier carbon_dioxide -= delta_carbon_dioxide/group_multiplier sharer.carbon_dioxide += delta_carbon_dioxide/sharer.group_multiplier nitrogen -= delta_nitrogen/group_multiplier sharer.nitrogen += delta_nitrogen/sharer.group_multiplier toxins -= delta_toxins/group_multiplier sharer.toxins += delta_toxins/sharer.group_multiplier var/moved_moles = (delta_oxygen + delta_carbon_dioxide + delta_nitrogen + delta_toxins) var/list/trace_types_considered = list() if(trace_gases.len) for(var/datum/gas/trace_gas in trace_gases) var/datum/gas/corresponding = locate(trace_gas.type) in sharer.trace_gases var/delta = 0 if(corresponding) delta = QUANTIZE(trace_gas.moles_archived - corresponding.moles_archived)/TRANSFER_FRACTION else corresponding = new trace_gas.type() sharer.trace_gases += corresponding delta = trace_gas.moles_archived/TRANSFER_FRACTION trace_gas.moles -= delta/group_multiplier corresponding.moles += delta/sharer.group_multiplier if(delta) var/individual_heat_capacity = trace_gas.specific_heat*delta if(delta > 0) heat_self_to_sharer += individual_heat_capacity*temperature_archived heat_capacity_self_to_sharer += individual_heat_capacity else heat_sharer_to_self -= individual_heat_capacity*sharer.temperature_archived heat_capacity_sharer_to_self -= individual_heat_capacity moved_moles += delta trace_types_considered += trace_gas.type if(sharer.trace_gases.len) for(var/datum/gas/trace_gas in sharer.trace_gases) if(trace_gas.type in trace_types_considered) continue else var/datum/gas/corresponding var/delta = 0 corresponding = new trace_gas.type() trace_gases += corresponding delta = trace_gas.moles_archived/TRANSFER_FRACTION trace_gas.moles -= delta/sharer.group_multiplier corresponding.moles += delta/group_multiplier //Guaranteed transfer from sharer to self var/individual_heat_capacity = trace_gas.specific_heat*delta heat_sharer_to_self += individual_heat_capacity*sharer.temperature_archived heat_capacity_sharer_to_self += individual_heat_capacity moved_moles += -delta update_values() sharer.update_values() if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) var/new_self_heat_capacity = old_self_heat_capacity + heat_capacity_sharer_to_self - heat_capacity_self_to_sharer var/new_sharer_heat_capacity = old_sharer_heat_capacity + heat_capacity_self_to_sharer - heat_capacity_sharer_to_self if(new_self_heat_capacity > MINIMUM_HEAT_CAPACITY) temperature = (old_self_heat_capacity*temperature - heat_capacity_self_to_sharer*temperature_archived + heat_capacity_sharer_to_self*sharer.temperature_archived)/new_self_heat_capacity if(new_sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) sharer.temperature = (old_sharer_heat_capacity*sharer.temperature-heat_capacity_sharer_to_self*sharer.temperature_archived + heat_capacity_self_to_sharer*temperature_archived)/new_sharer_heat_capacity if(abs(old_sharer_heat_capacity) > MINIMUM_HEAT_CAPACITY) if(abs(new_sharer_heat_capacity/old_sharer_heat_capacity - 1) < 0.10) // <10% change in sharer heat capacity temperature_share(sharer, OPEN_HEAT_TRANSFER_COEFFICIENT) if((delta_temperature > MINIMUM_TEMPERATURE_TO_MOVE) || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE) var/delta_pressure = temperature_archived*(total_moles() + moved_moles) - sharer.temperature_archived*(sharer.total_moles() - moved_moles) return delta_pressure*R_IDEAL_GAS_EQUATION/volume else return 0 /datum/gas_mixture/proc/mimic(turf/model, border_multiplier) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/mimic() called tick#: [world.time]") //Purpose: Used transfer gas from a more pressurised tile to a less presurised unsimulated tile. //Called by: "sharing" from unsimulated to simulated turfs. //Inputs: Unsimulated turf, Multiplier for gas transfer (optional) //Outputs: Amount of gas exchanged var/delta_oxygen = QUANTIZE(oxygen_archived - model.oxygen)/TRANSFER_FRACTION var/delta_carbon_dioxide = QUANTIZE(carbon_dioxide_archived - model.carbon_dioxide)/TRANSFER_FRACTION var/delta_nitrogen = QUANTIZE(nitrogen_archived - model.nitrogen)/TRANSFER_FRACTION var/delta_toxins = QUANTIZE(toxins_archived - model.toxins)/TRANSFER_FRACTION var/delta_temperature = (temperature_archived - model.temperature) var/heat_transferred = 0 var/old_self_heat_capacity = 0 var/heat_capacity_transferred = 0 if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) var/delta_air = delta_oxygen+delta_nitrogen if(delta_air) var/air_heat_capacity = SPECIFIC_HEAT_AIR*delta_air heat_transferred -= air_heat_capacity*model.temperature heat_capacity_transferred -= air_heat_capacity if(delta_carbon_dioxide) var/carbon_dioxide_heat_capacity = SPECIFIC_HEAT_CDO*delta_carbon_dioxide heat_transferred -= carbon_dioxide_heat_capacity*model.temperature heat_capacity_transferred -= carbon_dioxide_heat_capacity if(delta_toxins) var/toxins_heat_capacity = SPECIFIC_HEAT_TOXIN*delta_toxins heat_transferred -= toxins_heat_capacity*model.temperature heat_capacity_transferred -= toxins_heat_capacity old_self_heat_capacity = heat_capacity()*group_multiplier if(border_multiplier) oxygen -= delta_oxygen*border_multiplier/group_multiplier carbon_dioxide -= delta_carbon_dioxide*border_multiplier/group_multiplier nitrogen -= delta_nitrogen*border_multiplier/group_multiplier toxins -= delta_toxins*border_multiplier/group_multiplier else oxygen -= delta_oxygen/group_multiplier carbon_dioxide -= delta_carbon_dioxide/group_multiplier nitrogen -= delta_nitrogen/group_multiplier toxins -= delta_toxins/group_multiplier var/moved_moles = (delta_oxygen + delta_carbon_dioxide + delta_nitrogen + delta_toxins) if(trace_gases.len) for(var/datum/gas/trace_gas in trace_gases) var/delta = 0 delta = trace_gas.moles_archived/TRANSFER_FRACTION if(border_multiplier) trace_gas.moles -= delta*border_multiplier/group_multiplier else trace_gas.moles -= delta/group_multiplier var/heat_cap_transferred = delta*trace_gas.specific_heat heat_transferred += heat_cap_transferred*temperature_archived heat_capacity_transferred += heat_cap_transferred moved_moles += delta update_values() if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) var/new_self_heat_capacity = old_self_heat_capacity - heat_capacity_transferred if(new_self_heat_capacity > MINIMUM_HEAT_CAPACITY) if(border_multiplier) temperature = (old_self_heat_capacity*temperature - heat_capacity_transferred*border_multiplier*temperature_archived)/new_self_heat_capacity else temperature = (old_self_heat_capacity*temperature - heat_capacity_transferred*border_multiplier*temperature_archived)/new_self_heat_capacity temperature_mimic(model, model.thermal_conductivity, border_multiplier) if((delta_temperature > MINIMUM_TEMPERATURE_TO_MOVE) || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE) var/delta_pressure = temperature_archived*(total_moles() + moved_moles) - model.temperature*(model.oxygen+model.carbon_dioxide+model.nitrogen+model.toxins) return delta_pressure*R_IDEAL_GAS_EQUATION/volume else return 0 /datum/gas_mixture/proc/check_both_then_temperature_share(datum/gas_mixture/sharer, conduction_coefficient) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/check_both_then_temperature_share() called tick#: [world.time]") var/delta_temperature = (temperature_archived - sharer.temperature_archived) var/self_heat_capacity = heat_capacity_archived() var/sharer_heat_capacity = sharer.heat_capacity_archived() var/self_temperature_delta = 0 var/sharer_temperature_delta = 0 if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) var/heat = conduction_coefficient*delta_temperature* \ (self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity)) self_temperature_delta = -heat/(self_heat_capacity*group_multiplier) sharer_temperature_delta = heat/(sharer_heat_capacity*sharer.group_multiplier) else return 1 if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \ && (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived)) return 0 if((abs(sharer_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \ && (abs(sharer_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*sharer.temperature_archived)) return -1 temperature += self_temperature_delta sharer.temperature += sharer_temperature_delta return 1 //Logic integrated from: temperature_share(sharer, conduction_coefficient) for efficiency /datum/gas_mixture/proc/check_me_then_temperature_share(datum/gas_mixture/sharer, conduction_coefficient) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/check_me_then_temperature_share() called tick#: [world.time]") var/delta_temperature = (temperature_archived - sharer.temperature_archived) var/self_heat_capacity = heat_capacity_archived() var/sharer_heat_capacity = sharer.heat_capacity_archived() var/self_temperature_delta = 0 var/sharer_temperature_delta = 0 if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) var/heat = conduction_coefficient*delta_temperature* \ (self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity)) self_temperature_delta = -heat/(self_heat_capacity*group_multiplier) sharer_temperature_delta = heat/(sharer_heat_capacity*sharer.group_multiplier) else return 1 if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \ && (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived)) return 0 temperature += self_temperature_delta sharer.temperature += sharer_temperature_delta return 1 //Logic integrated from: temperature_share(sharer, conduction_coefficient) for efficiency /datum/gas_mixture/proc/check_me_then_temperature_turf_share(turf/simulated/sharer, conduction_coefficient) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/check_me_then_temperature_turf_share() called tick#: [world.time]") var/delta_temperature = (temperature_archived - sharer.temperature) var/self_temperature_delta = 0 var/sharer_temperature_delta = 0 if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) var/self_heat_capacity = heat_capacity_archived() if((sharer.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) var/heat = conduction_coefficient*delta_temperature* \ (self_heat_capacity*sharer.heat_capacity/(self_heat_capacity+sharer.heat_capacity)) self_temperature_delta = -heat/(self_heat_capacity*group_multiplier) sharer_temperature_delta = heat/sharer.heat_capacity else return 1 if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \ && (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived)) return 0 temperature += self_temperature_delta sharer.temperature += sharer_temperature_delta return 1 //Logic integrated from: temperature_turf_share(sharer, conduction_coefficient) for efficiency /datum/gas_mixture/proc/check_me_then_temperature_mimic(turf/model, conduction_coefficient) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/check_me_then_temperature_mimic() called tick#: [world.time]") var/delta_temperature = (temperature_archived - model.temperature) var/self_temperature_delta = 0 if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) var/self_heat_capacity = heat_capacity_archived() if((model.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) var/heat = conduction_coefficient*delta_temperature* \ (self_heat_capacity*model.heat_capacity/(self_heat_capacity+model.heat_capacity)) self_temperature_delta = -heat/(self_heat_capacity*group_multiplier) if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \ && (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived)) return 0 temperature += self_temperature_delta return 1 //Logic integrated from: temperature_mimic(model, conduction_coefficient) for efficiency /datum/gas_mixture/proc/temperature_share(datum/gas_mixture/sharer, conduction_coefficient) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/temperature_share() called tick#: [world.time]") var/delta_temperature = (temperature_archived - sharer.temperature_archived) if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) var/self_heat_capacity = heat_capacity_archived() var/sharer_heat_capacity = sharer.heat_capacity_archived() if(!group_multiplier) message_admins("Error! The gas mixture (ref \ref[src]) has no group multiplier!") return if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) var/heat = conduction_coefficient*delta_temperature* \ (self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity)) temperature -= heat/(self_heat_capacity*group_multiplier) sharer.temperature += heat/(sharer_heat_capacity*sharer.group_multiplier) /datum/gas_mixture/proc/temperature_mimic(turf/model, conduction_coefficient, border_multiplier) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/temperature_mimic() called tick#: [world.time]") var/delta_temperature = (temperature - model.temperature) if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) var/self_heat_capacity = heat_capacity()//_archived() if(!group_multiplier) message_admins("Error! The gas mixture (ref \ref[src]) has no group multiplier!") return if((model.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) var/heat = conduction_coefficient*delta_temperature* \ (self_heat_capacity*model.heat_capacity/(self_heat_capacity+model.heat_capacity)) if(border_multiplier) temperature -= heat*border_multiplier/(self_heat_capacity*group_multiplier) else temperature -= heat/(self_heat_capacity*group_multiplier) /datum/gas_mixture/proc/temperature_turf_share(turf/simulated/sharer, conduction_coefficient) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/temperature_turf_share() called tick#: [world.time]") var/delta_temperature = (temperature_archived - sharer.temperature) if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) var/self_heat_capacity = heat_capacity() if((sharer.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) var/heat = conduction_coefficient*delta_temperature* \ (self_heat_capacity*sharer.heat_capacity/(self_heat_capacity+sharer.heat_capacity)) temperature -= heat/(self_heat_capacity*group_multiplier) sharer.temperature += heat/sharer.heat_capacity /datum/gas_mixture/proc/compare(datum/gas_mixture/sample) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/compare() called tick#: [world.time]") //Purpose: Compares sample to self to see if within acceptable ranges that group processing may be enabled //Called by: Airgroups trying to rebuild //Inputs: Gas mix to compare //Outputs: 1 if can rebuild, 0 if not. if(!sample) return 0 if((abs(oxygen-sample.oxygen) > MINIMUM_AIR_TO_SUSPEND) && \ ((oxygen < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.oxygen) || (oxygen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.oxygen))) return 0 if((abs(nitrogen-sample.nitrogen) > MINIMUM_AIR_TO_SUSPEND) && \ ((nitrogen < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.nitrogen) || (nitrogen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.nitrogen))) return 0 if((abs(carbon_dioxide-sample.carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && \ ((carbon_dioxide < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide) || (carbon_dioxide > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide))) return 0 if((abs(toxins-sample.toxins) > MINIMUM_AIR_TO_SUSPEND) && \ ((toxins < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.toxins) || (toxins > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.toxins))) return 0 if(total_moles() > MINIMUM_AIR_TO_SUSPEND) if((abs(temperature-sample.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) && \ ((temperature < (1-MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND)*sample.temperature) || (temperature > (1+MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND)*sample.temperature))) //world << "temp fail [temperature] & [sample.temperature]" return 0 var/check_moles if(sample.trace_gases.len) for(var/datum/gas/trace_gas in sample.trace_gases) var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases if(corresponding) check_moles = corresponding.moles else check_moles = 0 if((abs(trace_gas.moles - check_moles) > MINIMUM_AIR_TO_SUSPEND) && \ ((check_moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles) || (check_moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles))) return 0 if(trace_gases.len) for(var/datum/gas/trace_gas in trace_gases) var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases if(corresponding) check_moles = corresponding.moles else check_moles = 0 if((abs(trace_gas.moles - check_moles) > MINIMUM_AIR_TO_SUSPEND) && \ ((trace_gas.moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*check_moles) || (trace_gas.moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*check_moles))) return 0 return 1 /datum/gas_mixture/proc/add(datum/gas_mixture/right_side) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/add() called tick#: [world.time]") if(!right_side) return 0 oxygen += right_side.oxygen carbon_dioxide += right_side.carbon_dioxide nitrogen += right_side.nitrogen toxins += right_side.toxins if(trace_gases.len || right_side.trace_gases.len) for(var/datum/gas/trace_gas in right_side.trace_gases) var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases if(!corresponding) corresponding = new trace_gas.type() trace_gases += corresponding corresponding.moles += trace_gas.moles update_values() return 1 /datum/gas_mixture/proc/subtract(datum/gas_mixture/right_side) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/subtract() called tick#: [world.time]") //Purpose: Subtracts right_side from air_mixture. Used to help turfs mingle //Called by: Pipelines ending in a break (or something) //Inputs: Gas mix to remove //Outputs: 1 oxygen = max(oxygen - right_side.oxygen) carbon_dioxide = max(carbon_dioxide - right_side.carbon_dioxide) nitrogen = max(nitrogen - right_side.nitrogen) toxins = max(toxins - right_side.toxins) if(trace_gases.len || right_side.trace_gases.len) for(var/datum/gas/trace_gas in right_side.trace_gases) var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases if(corresponding) corresponding.moles = max(0, corresponding.moles - trace_gas.moles) update_values() return 1 /datum/gas_mixture/proc/multiply(factor) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/multiply() called tick#: [world.time]") oxygen *= factor carbon_dioxide *= factor nitrogen *= factor toxins *= factor if(trace_gases && trace_gases.len) for(var/datum/gas/trace_gas in trace_gases) trace_gas.moles *= factor update_values() return 1 /datum/gas_mixture/proc/divide(factor) writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/gas_mixture/proc/divide() called tick#: [world.time]") oxygen /= factor carbon_dioxide /= factor nitrogen /= factor toxins /= factor if(trace_gases && trace_gases.len) for(var/datum/gas/trace_gas in trace_gases) trace_gas.moles /= factor update_values() return 1