diff --git a/src/simulation/Simulation.cpp b/src/simulation/Simulation.cpp index 2decc24a39..737002feca 100644 --- a/src/simulation/Simulation.cpp +++ b/src/simulation/Simulation.cpp @@ -4443,7 +4443,7 @@ void Simulation::update_particles_i(int start, int inc) else { s = 1; - r = (rand()%2)*2-1; + r = (rand()%2)*2-1;// position search direction (left/right first) if ((clear_x!=x || clear_y!=y || nt || surround_space) && (fabsf(parts[i].vx)>0.01f || fabsf(parts[i].vy)>0.01f)) { @@ -4531,12 +4531,15 @@ void Simulation::update_particles_i(int start, int inc) rt = 30;//slight less water lag, although it changes how it moves a lot else rt = 10; + // clear_xf, clear_yf is the last known position that the particle should almost certainly be able to move to nxf = clear_xf; nyf = clear_yf; - nx = (int)(parts[i].x+0.5f); - ny = (int)(parts[i].y+0.5f); + nx = clear_y; + ny = clear_x; + // Look for spaces to move horizontally (perpendicular to gravity direction), keep going until a space is found or the number of positions examined = rt for (j=0;jfabsf(pGravX)) mv = fabsf(pGravY); else @@ -4562,8 +4566,13 @@ void Simulation::update_particles_i(int start, int inc) if (mv<0.0001f) break; pGravX /= mv; pGravY /= mv; + // Move 1 pixel perpendicularly to gravity + // r is +1/-1, to try moving left or right at random if (j) { + // Not quite the gravity direction + // Gravity direction + last change in gravity direction + // This makes liquid movement a bit less frothy, particularly for balls of liquid in radial gravity. With radial gravity, instead of just moving along a tangent, the attempted movement will follow the curvature a bit better. nxf += r*(pGravY*2.0f-prev_pGravY); nyf += -r*(pGravX*2.0f-prev_pGravX); } @@ -4574,6 +4583,7 @@ void Simulation::update_particles_i(int start, int inc) } prev_pGravX = pGravX; prev_pGravY = pGravY; + // Check whether movement is allowed nx = (int)(nxf+0.5f); ny = (int)(nyf+0.5f); if (nx<0 || ny<0 || nx>=XRES || ny >=YRES) @@ -4583,20 +4593,25 @@ void Simulation::update_particles_i(int start, int inc) s = do_move(i, x, y, nxf, nyf); if (s) { + // Movement was successful nx = (int)(parts[i].x+0.5f); ny = (int)(parts[i].y+0.5f); break; } + // A particle of a different type, or a wall, was found. Stop trying to move any further horizontally unless the wall should be completely invisible to particles. if (bmap[ny/CELL][nx/CELL]!=WL_STREAM) break; } } if (s==1) { + // The particle managed to move horizontally, now try to move vertically (parallel to gravity direction) + // Keep going until the particle is blocked (by something that isn't the same element) or the number of positions examined = rt clear_x = nx; clear_y = ny; for (j=0;jfabsf(pGravX)) mv = fabsf(pGravY); else @@ -4622,22 +4638,24 @@ void Simulation::update_particles_i(int start, int inc) if (mv<0.0001f) break; pGravX /= mv; pGravY /= mv; + // Move 1 pixel in the direction of gravity nxf += pGravX; nyf += pGravY; nx = (int)(nxf+0.5f); ny = (int)(nyf+0.5f); if (nx<0 || ny<0 || nx>=XRES || ny>=YRES) break; + // If the space is anything except the same element (a wall, empty space, or occupied by a particle of a different element), try to move into it if ((pmap[ny][nx]&0xFF)!=t || bmap[ny/CELL][nx/CELL]) { s = do_move(i, clear_x, clear_y, nxf, nyf); if (s || bmap[ny/CELL][nx/CELL]!=WL_STREAM) - break; + break; // found the edge of the liquid and movement into it succeeded, so stop moving down } } } else if (s==-1) {} // particle is out of bounds - else if ((clear_x!=x||clear_y!=y) && do_move(i, x, y, clear_xf, clear_yf)) {} + else if ((clear_x!=x||clear_y!=y) && do_move(i, x, y, clear_xf, clear_yf)) {} // try moving to the last clear position else parts[i].flags |= FLAG_STAGNANT; parts[i].vx *= elements[t].Collision; parts[i].vy *= elements[t].Collision;