So basically I made a thread asking what I could do to fix the issue*- but I think the issue stems from me just not doing it right. SO basically how would you program this system? I want it to fill rooms evenly and be effected by vacuums.
*The issue is the gas keeps on cycling non-stop AND doesn't work correctly when it has to fill a room near by which is a vacuum.
turf
/*Oxygen
Nitrogen
Hydrogen
CarbonDioxide*/
var
O2 = 0//Only using O2 atm, upon getting proper dispersion I'll handle multiple gas types
H2 = 0
CO2 = 0
proc/Disperse(var/mother=null)
spawn(1)
//if(O2<=0) return
var/list/directions = list(NORTH,SOUTH,EAST,WEST)//,NORTHWEST,SOUTHWEST,NORTHEAST,SOUTHEAST)
var/turf/LeastPressure = null
var/turf/MostPressure = null
//Initially I had it disperse into all 8 directions evenly but this causes alot of CPU ussage
//Then I got the idea to limit that to just the 4 cardinal directions and then one tile at a time.
while(directions.len)
//this portion checks the 4 cardinal tiles and checks which has the lowest ammount of "pressure"/"O2"
var/DIR = directions[rand(1,directions.len)]
var/turf/Ta = get_step(src,DIR)
directions -= DIR
if(Ta)
var/dense=0
for(var/obj/A in locate(Ta.x,Ta.y,Ta.z)) if(A.density>0) dense++
if(Ta!=mother && dense<=0 && (Ta.O2>O2) && (abs(O2-Ta.O2)>=1) && !(MostPressure && MostPressure.O2 > Ta.O2)) MostPressure=Ta
if(Ta!=mother && dense<=0 && (Ta.O2<O2) && (abs(O2-Ta.O2)>=1) && !(LeastPressure && LeastPressure.O2 < Ta.O2)) LeastPressure=Ta
if(LeastPressure)//handles the transfer and sets up both tiles involved to re_transfer
var/O2transfer = round(((O2-LeastPressure.O2)/2)+0.5)
LeastPressure.O2 += O2transfer
O2 -= O2transfer
IconDisperse()
LeastPressure.IconDisperse()
LeastPressure.Disperse(src)
if(MostPressure)
var/O2transfer = round(((MostPressure.O2-O2)/2)+0.5)
MostPressure.O2 -= O2transfer
O2 += O2transfer
IconDisperse()
MostPressure.IconDisperse()
MostPressure.Disperse(src)
There are significant problems with airflow. First of all, don't think about individual gas transfer. Think about pressure.
Total your pressure based on molar mass in a space, not based on the amount of gases in a space.
Don't worry about equalizing individual gases until you equalize the pressure. If you move 50% of the pressure out of a room, assume that 50% of the molar mass of a particular gas also moves with it.
Second, you want to stop thinking about your individual tiles. You want to gather the entire map into a series of rooms and breaches. This will cut down on the complexity of your simulation and give you the needed horsepower to perform a full simulation.
Next, you need to run through a list of breaches currently open in the region. Calculate pressure from high to low, not low to high.
Once you've figured out the relative pressure venting out of a room from each breach, you can figure out where it will meet equilibrium.
Once you figure out the relative strength of each breach in a room, you can figure out how to move objects in the room, and you can also figure out the maximum weight of objects it will move.
The only issue you need to prevent with this issue, is that you can wind up causing backflow in a complex system of depressurizations, which I honestly didn't have a problem with. I found that the backflow made for some interesting vortex-like effects.
This system isn't easy to design at all, though. I'd suggest taking your time to draw out a few diagrams. you'll see what I mean.