Sort out scopes in Simulation::UpdateParticles

This commit is contained in:
Tamás Bálint Misius
2023-10-22 10:27:50 +02:00
parent 1c1ef12761
commit edcbeaca56

View File

@@ -2229,27 +2229,16 @@ void Simulation::delete_part(int x, int y)//calls kill_part with the particle lo
void Simulation::UpdateParticles(int start, int end)
{
int i, j, x, y, t, r, surround_space, s, rt, nt;
float mv, dx, dy, nrx, nry, dp, ctemph, ctempl, gravtot;
int fin_x, fin_y, clear_x, clear_y, stagnant;
float fin_xf, fin_yf, clear_xf, clear_yf;
float nn, ct1, ct2, swappage;
float pt = R_TEMP;
float c_heat = 0.0f;
int h_count = 0;
int surround[8];
int surround_hconduct[8];
bool transitionOccurred;
//the main particle loop function, goes over all particles.
for (i = start; i < end && i <= parts_lastActiveIndex; i++)
for (auto i = start; i < end && i <= parts_lastActiveIndex; i++)
{
if (parts[i].type)
{
debug_mostRecentlyUpdated = i;
t = parts[i].type;
auto t = parts[i].type;
x = (int)(parts[i].x+0.5f);
y = (int)(parts[i].y+0.5f);
auto x = (int)(parts[i].x+0.5f);
auto y = (int)(parts[i].y+0.5f);
// Kill a particle off screen
if (x<CELL || y<CELL || x>=XRES-CELL || y>=YRES-CELL)
@@ -2345,18 +2334,28 @@ void Simulation::UpdateParticles(int start, int end)
#endif
}
transitionOccurred = false;
auto transitionOccurred = false;
j = surround_space = nt = 0;//if nt is greater than 1 after this, then there is a particle around the current particle, that is NOT the current particle's type, for water movement.
for (auto nx=-1; nx<2; nx++)
for (auto ny=-1; ny<2; ny++) {
if (nx||ny) {
surround[j] = r = pmap[y+ny][x+nx];
j++;
surround_space += (!TYP(r)); // count empty space
nt += (TYP(r)!=t); // count empty space and particles of different type
int surround[8];
auto surround_space = 0;
auto nt = 0; //if nt is greater than 1 after this, then there is a particle around the current particle, that is NOT the current particle's type, for water movement.
{
auto j = 0;
for (auto nx=-1; nx<2; nx++)
{
for (auto ny=-1; ny<2; ny++)
{
if (nx||ny)
{
auto r = pmap[y+ny][x+nx];
surround[j] = r;
j++;
surround_space += (!TYP(r)); // count empty space
nt += (TYP(r)!=t); // count empty space and particles of different type
}
}
}
}
float gel_scale = 1.0f;
if (t==PT_GEL)
@@ -2371,10 +2370,10 @@ void Simulation::UpdateParticles(int start, int end)
auto offsetX = int(std::round(convGravX + x));
auto offsetY = int(std::round(convGravY + y));
if ((offsetX != x || offsetY != y) && offsetX >= 0 && offsetX < XRES && offsetY >= 0 && offsetY < YRES) {//some heat convection for liquids
r = pmap[offsetY][offsetX];
auto r = pmap[offsetY][offsetX];
if (!(!r || parts[i].type != TYP(r))) {
if (parts[i].temp>parts[ID(r)].temp) {
swappage = parts[i].temp;
auto swappage = parts[i].temp;
parts[i].temp = parts[ID(r)].temp;
parts[ID(r)].temp = swappage;
}
@@ -2383,42 +2382,43 @@ void Simulation::UpdateParticles(int start, int end)
}
//heat transfer code
h_count = 0;
#ifdef REALISTIC
if (t&&(t!=PT_HSWC||parts[i].life==10)&&(elements[t].HeatConduct*gel_scale))
#else
auto h_count = 0;
if (t && (t!=PT_HSWC||parts[i].life==10) && rng.chance(int(elements[t].HeatConduct*gel_scale), 250))
#endif
{
if (aheat_enable && !(elements[t].Properties&PROP_NOAMBHEAT))
{
#ifdef REALISTIC
c_heat = parts[i].temp*96.645/elements[t].HeatConduct*gel_scale*fabs(elements[t].Weight) + hv[y/CELL][x/CELL]*100*(pv[y/CELL][x/CELL]-MIN_PRESSURE)/(MAX_PRESSURE-MIN_PRESSURE)*2;
auto c_heat = parts[i].temp*96.645/elements[t].HeatConduct*gel_scale*fabs(elements[t].Weight) + hv[y/CELL][x/CELL]*100*(pv[y/CELL][x/CELL]-MIN_PRESSURE)/(MAX_PRESSURE-MIN_PRESSURE)*2;
float c_Cm = 96.645/elements[t].HeatConduct*gel_scale*fabs(elements[t].Weight) + 100*(pv[y/CELL][x/CELL]-MIN_PRESSURE)/(MAX_PRESSURE-MIN_PRESSURE)*2;
pt = c_heat/c_Cm;
auto pt = c_heat/c_Cm;
pt = restrict_flt(pt, -MAX_TEMP+MIN_TEMP, MAX_TEMP-MIN_TEMP);
parts[i].temp = pt;
//Pressure increase from heat (temporary)
pv[y/CELL][x/CELL] += (pt-hv[y/CELL][x/CELL])*0.004;
hv[y/CELL][x/CELL] = pt;
#else
c_heat = (hv[y/CELL][x/CELL]-parts[i].temp)*0.04;
auto c_heat = (hv[y/CELL][x/CELL]-parts[i].temp)*0.04;
c_heat = restrict_flt(c_heat, -MAX_TEMP+MIN_TEMP, MAX_TEMP-MIN_TEMP);
parts[i].temp += c_heat;
hv[y/CELL][x/CELL] -= c_heat;
#endif
}
c_heat = 0.0f;
auto c_heat = 0.0f;
#ifdef REALISTIC
float c_Cm = 0.0f;
#endif
for (j=0; j<8; j++)
int surround_hconduct[8];
for (auto j=0; j<8; j++)
{
surround_hconduct[j] = i;
r = surround[j];
auto r = surround[j];
if (!r)
continue;
rt = TYP(r);
auto rt = TYP(r);
if (rt && elements[rt].HeatConduct && (rt!=PT_HSWC||parts[ID(r)].life==10)
&& (t!=PT_FILT||(rt!=PT_BRAY&&rt!=PT_BIZR&&rt!=PT_BIZRG))
&& (rt!=PT_FILT||(t!=PT_BRAY&&t!=PT_PHOT&&t!=PT_BIZR&&t!=PT_BIZRG))
@@ -2441,6 +2441,7 @@ void Simulation::UpdateParticles(int start, int end)
h_count++;
}
}
float pt = R_TEMP;
#ifdef REALISTIC
if (t==PT_GEL)
gel_scale = parts[i].tmp*2.55f;
@@ -2457,13 +2458,14 @@ void Simulation::UpdateParticles(int start, int end)
#else
pt = (c_heat+parts[i].temp)/(h_count+1);
pt = parts[i].temp = restrict_flt(pt, MIN_TEMP, MAX_TEMP);
for (j=0; j<8; j++)
for (auto j=0; j<8; j++)
{
parts[surround_hconduct[j]].temp = pt;
}
#endif
ctemph = ctempl = pt;
auto ctemph = pt;
auto ctempl = pt;
// change boiling point with pressure
if (((elements[t].Properties&TYPE_LIQUID) && IsElementOrNone(elements[t].HighTemperatureTransition) && (elements[elements[t].HighTemperatureTransition].Properties&TYPE_GAS))
|| t==PT_LNTG || t==PT_SLTW)
@@ -2471,7 +2473,7 @@ void Simulation::UpdateParticles(int start, int end)
else if (((elements[t].Properties&TYPE_GAS) && IsElementOrNone(elements[t].LowTemperatureTransition) && (elements[elements[t].LowTemperatureTransition].Properties&TYPE_LIQUID))
|| t==PT_WTRV)
ctempl -= 2.0f*pv[y/CELL][x/CELL];
s = 1;
auto s = 1;
//A fix for ice with ctype = 0
if ((t==PT_ICEI || t==PT_SNOW) && (!IsElement(parts[i].ctype) || parts[i].ctype==PT_ICEI || parts[i].ctype==PT_SNOW))
@@ -2665,7 +2667,7 @@ void Simulation::UpdateParticles(int start, int end)
s = 0;
#ifdef REALISTIC
pt = restrict_flt(pt, MIN_TEMP, MAX_TEMP);
for (j=0; j<8; j++)
for (auto j=0; j<8; j++)
{
parts[surround_hconduct[j]].temp = pt;
}
@@ -2787,57 +2789,58 @@ void Simulation::UpdateParticles(int start, int end)
pv[y/CELL][x/CELL] += 0.25f * CFDS;
}
s = 1;
gravtot = fabs(gravy[(y/CELL)*XCELLS+(x/CELL)])+fabs(gravx[(y/CELL)*XCELLS+(x/CELL)]);
if (elements[t].HighPressureTransition>-1 && pv[y/CELL][x/CELL]>elements[t].HighPressure) {
// particle type change due to high pressure
if (elements[t].HighPressureTransition!=PT_NUM)
t = elements[t].HighPressureTransition;
else if (t==PT_BMTL) {
if (pv[y/CELL][x/CELL]>2.5f)
t = PT_BRMT;
else if (pv[y/CELL][x/CELL]>1.0f && parts[i].tmp==1)
t = PT_BRMT;
else s = 0;
}
else s = 0;
} else if (elements[t].LowPressureTransition>-1 && pv[y/CELL][x/CELL]<elements[t].LowPressure && gravtot<=(elements[t].LowPressure/4.0f)) {
// particle type change due to low pressure
if (elements[t].LowPressureTransition!=PT_NUM)
t = elements[t].LowPressureTransition;
else s = 0;
} else if (elements[t].HighPressureTransition>-1 && gravtot>(elements[t].HighPressure/4.0f)) {
// particle type change due to high gravity
if (elements[t].HighPressureTransition!=PT_NUM)
t = elements[t].HighPressureTransition;
else if (t==PT_BMTL) {
if (gravtot>0.625f)
t = PT_BRMT;
else if (gravtot>0.25f && parts[i].tmp==1)
t = PT_BRMT;
else s = 0;
}
else s = 0;
} else s = 0;
// particle type change occurred
if (s)
{
if (t == PT_NONE)
auto s = 1;
auto gravtot = fabs(gravy[(y/CELL)*XCELLS+(x/CELL)])+fabs(gravx[(y/CELL)*XCELLS+(x/CELL)]);
if (elements[t].HighPressureTransition>-1 && pv[y/CELL][x/CELL]>elements[t].HighPressure) {
// particle type change due to high pressure
if (elements[t].HighPressureTransition!=PT_NUM)
t = elements[t].HighPressureTransition;
else if (t==PT_BMTL) {
if (pv[y/CELL][x/CELL]>2.5f)
t = PT_BRMT;
else if (pv[y/CELL][x/CELL]>1.0f && parts[i].tmp==1)
t = PT_BRMT;
else s = 0;
}
else s = 0;
} else if (elements[t].LowPressureTransition>-1 && pv[y/CELL][x/CELL]<elements[t].LowPressure && gravtot<=(elements[t].LowPressure/4.0f)) {
// particle type change due to low pressure
if (elements[t].LowPressureTransition!=PT_NUM)
t = elements[t].LowPressureTransition;
else s = 0;
} else if (elements[t].HighPressureTransition>-1 && gravtot>(elements[t].HighPressure/4.0f)) {
// particle type change due to high gravity
if (elements[t].HighPressureTransition!=PT_NUM)
t = elements[t].HighPressureTransition;
else if (t==PT_BMTL) {
if (gravtot>0.625f)
t = PT_BRMT;
else if (gravtot>0.25f && parts[i].tmp==1)
t = PT_BRMT;
else s = 0;
}
else s = 0;
} else s = 0;
// particle type change occurred
if (s)
{
kill_part(i);
goto killed;
if (t == PT_NONE)
{
kill_part(i);
goto killed;
}
parts[i].life = 0;
// part_change_type could refuse to change the type and kill the particle
// for example, changing type to STKM but one already exists
// we need to account for that to not cause simulation corruption issues
if (part_change_type(i,x,y,t))
goto killed;
if (t == PT_FIRE)
parts[i].life = rng.between(120, 169);
transitionOccurred = true;
}
parts[i].life = 0;
// part_change_type could refuse to change the type and kill the particle
// for example, changing type to STKM but one already exists
// we need to account for that to not cause simulation corruption issues
if (part_change_type(i,x,y,t))
goto killed;
if (t == PT_FIRE)
parts[i].life = rng.between(120, 169);
transitionOccurred = true;
}
//call the particle update function, if there is one
@@ -2862,57 +2865,44 @@ killed:
if (!parts[i].vx&&!parts[i].vy)//if its not moving, skip to next particle, movement code it next
continue;
mv = fmaxf(fabsf(parts[i].vx), fabsf(parts[i].vy));
if (mv < ISTP)
int fin_x, fin_y, clear_x, clear_y;
float fin_xf, fin_yf, clear_xf, clear_yf;
{
clear_x = x;
clear_y = y;
clear_xf = parts[i].x;
clear_yf = parts[i].y;
fin_xf = clear_xf + parts[i].vx;
fin_yf = clear_yf + parts[i].vy;
fin_x = (int)(fin_xf+0.5f);
fin_y = (int)(fin_yf+0.5f);
}
else
{
if (mv > MAX_VELOCITY)
auto mv = fmaxf(fabsf(parts[i].vx), fabsf(parts[i].vy));
if (mv < ISTP)
{
parts[i].vx *= MAX_VELOCITY/mv;
parts[i].vy *= MAX_VELOCITY/mv;
mv = MAX_VELOCITY;
}
// interpolate to see if there is anything in the way
dx = parts[i].vx*ISTP/mv;
dy = parts[i].vy*ISTP/mv;
fin_xf = parts[i].x;
fin_yf = parts[i].y;
fin_x = (int)(fin_xf+0.5f);
fin_y = (int)(fin_yf+0.5f);
bool closedEholeStart = InBounds(fin_x, fin_y) && (bmap[fin_y/CELL][fin_x/CELL] == WL_EHOLE && !emap[fin_y/CELL][fin_x/CELL]);
while (1)
{
mv -= ISTP;
fin_xf += dx;
fin_yf += dy;
clear_x = x;
clear_y = y;
clear_xf = parts[i].x;
clear_yf = parts[i].y;
fin_xf = clear_xf + parts[i].vx;
fin_yf = clear_yf + parts[i].vy;
fin_x = (int)(fin_xf+0.5f);
fin_y = (int)(fin_yf+0.5f);
if (edgeMode == EDGE_LOOP)
}
else
{
if (mv > MAX_VELOCITY)
{
bool x_ok = (fin_xf >= CELL-.5f && fin_xf < XRES-CELL-.5f);
bool y_ok = (fin_yf >= CELL-.5f && fin_yf < YRES-CELL-.5f);
if (!x_ok)
fin_xf = remainder_p(fin_xf-CELL+.5f, XRES-CELL*2.0f)+CELL-.5f;
if (!y_ok)
fin_yf = remainder_p(fin_yf-CELL+.5f, YRES-CELL*2.0f)+CELL-.5f;
parts[i].vx *= MAX_VELOCITY/mv;
parts[i].vy *= MAX_VELOCITY/mv;
mv = MAX_VELOCITY;
}
// interpolate to see if there is anything in the way
auto dx = parts[i].vx*ISTP/mv;
auto dy = parts[i].vy*ISTP/mv;
fin_xf = parts[i].x;
fin_yf = parts[i].y;
fin_x = (int)(fin_xf+0.5f);
fin_y = (int)(fin_yf+0.5f);
bool closedEholeStart = InBounds(fin_x, fin_y) && (bmap[fin_y/CELL][fin_x/CELL] == WL_EHOLE && !emap[fin_y/CELL][fin_x/CELL]);
while (1)
{
mv -= ISTP;
fin_xf += dx;
fin_yf += dy;
fin_x = (int)(fin_xf+0.5f);
fin_y = (int)(fin_yf+0.5f);
}
if (mv <= 0.0f)
{
// nothing found
fin_xf = parts[i].x + parts[i].vx;
fin_yf = parts[i].y + parts[i].vy;
if (edgeMode == EDGE_LOOP)
{
bool x_ok = (fin_xf >= CELL-.5f && fin_xf < XRES-CELL-.5f);
@@ -2921,33 +2911,50 @@ killed:
fin_xf = remainder_p(fin_xf-CELL+.5f, XRES-CELL*2.0f)+CELL-.5f;
if (!y_ok)
fin_yf = remainder_p(fin_yf-CELL+.5f, YRES-CELL*2.0f)+CELL-.5f;
fin_x = (int)(fin_xf+0.5f);
fin_y = (int)(fin_yf+0.5f);
}
fin_x = (int)(fin_xf+0.5f);
fin_y = (int)(fin_yf+0.5f);
clear_xf = fin_xf-dx;
clear_yf = fin_yf-dy;
clear_x = (int)(clear_xf+0.5f);
clear_y = (int)(clear_yf+0.5f);
break;
if (mv <= 0.0f)
{
// nothing found
fin_xf = parts[i].x + parts[i].vx;
fin_yf = parts[i].y + parts[i].vy;
if (edgeMode == EDGE_LOOP)
{
bool x_ok = (fin_xf >= CELL-.5f && fin_xf < XRES-CELL-.5f);
bool y_ok = (fin_yf >= CELL-.5f && fin_yf < YRES-CELL-.5f);
if (!x_ok)
fin_xf = remainder_p(fin_xf-CELL+.5f, XRES-CELL*2.0f)+CELL-.5f;
if (!y_ok)
fin_yf = remainder_p(fin_yf-CELL+.5f, YRES-CELL*2.0f)+CELL-.5f;
}
fin_x = (int)(fin_xf+0.5f);
fin_y = (int)(fin_yf+0.5f);
clear_xf = fin_xf-dx;
clear_yf = fin_yf-dy;
clear_x = (int)(clear_xf+0.5f);
clear_y = (int)(clear_yf+0.5f);
break;
}
//block if particle can't move (0), or some special cases where it returns 1 (can_move = 3 but returns 1 meaning particle will be eaten)
//also photons are still blocked (slowed down) by any particle (even ones it can move through), and absorb wall also blocks particles
int eval = eval_move(t, fin_x, fin_y, NULL);
if (!eval || (can_move[t][TYP(pmap[fin_y][fin_x])] == 3 && eval == 1) || (t == PT_PHOT && pmap[fin_y][fin_x]) || bmap[fin_y/CELL][fin_x/CELL]==WL_DESTROYALL || closedEholeStart!=(bmap[fin_y/CELL][fin_x/CELL] == WL_EHOLE && !emap[fin_y/CELL][fin_x/CELL]))
{
// found an obstacle
clear_xf = fin_xf-dx;
clear_yf = fin_yf-dy;
clear_x = (int)(clear_xf+0.5f);
clear_y = (int)(clear_yf+0.5f);
break;
}
if (bmap[fin_y/CELL][fin_x/CELL]==WL_DETECT && emap[fin_y/CELL][fin_x/CELL]<8)
set_emap(fin_x/CELL, fin_y/CELL);
}
//block if particle can't move (0), or some special cases where it returns 1 (can_move = 3 but returns 1 meaning particle will be eaten)
//also photons are still blocked (slowed down) by any particle (even ones it can move through), and absorb wall also blocks particles
int eval = eval_move(t, fin_x, fin_y, NULL);
if (!eval || (can_move[t][TYP(pmap[fin_y][fin_x])] == 3 && eval == 1) || (t == PT_PHOT && pmap[fin_y][fin_x]) || bmap[fin_y/CELL][fin_x/CELL]==WL_DESTROYALL || closedEholeStart!=(bmap[fin_y/CELL][fin_x/CELL] == WL_EHOLE && !emap[fin_y/CELL][fin_x/CELL]))
{
// found an obstacle
clear_xf = fin_xf-dx;
clear_yf = fin_yf-dy;
clear_x = (int)(clear_xf+0.5f);
clear_y = (int)(clear_yf+0.5f);
break;
}
if (bmap[fin_y/CELL][fin_x/CELL]==WL_DETECT && emap[fin_y/CELL][fin_x/CELL]<8)
set_emap(fin_x/CELL, fin_y/CELL);
}
}
stagnant = parts[i].flags & FLAG_STAGNANT;
auto stagnant = parts[i].flags & FLAG_STAGNANT;
parts[i].flags &= ~FLAG_STAGNANT;
if (t==PT_STKM || t==PT_STKM2 || t==PT_FIGH)
@@ -3031,25 +3038,26 @@ killed:
int lt_glas = (lt == PT_GLAS) || (lt == PT_BGLA);
if ((rt_glas && !lt_glas) || (lt_glas && !rt_glas))
{
float nrx, nry;
if (!get_normal_interp(REFRACT|t, parts[i].x, parts[i].y, parts[i].vx, parts[i].vy, &nrx, &nry)) {
kill_part(i);
continue;
}
r = get_wavelength_bin(&parts[i].ctype);
auto r = get_wavelength_bin(&parts[i].ctype);
if (r == -1 || !(parts[i].ctype&0x3FFFFFFF))
{
kill_part(i);
continue;
}
nn = GLASS_IOR - GLASS_DISP*(r-30)/30.0f;
auto nn = GLASS_IOR - GLASS_DISP*(r-30)/30.0f;
nn *= nn;
auto enter = rt_glas && !lt_glas;
nrx = enter ? -nrx : nrx;
nry = enter ? -nry : nry;
nn = enter ? 1.0f/nn : nn;
ct1 = parts[i].vx*nrx + parts[i].vy*nry;
ct2 = 1.0f - (nn*nn)*(1.0f-(ct1*ct1));
auto ct1 = parts[i].vx*nrx + parts[i].vy*nry;
auto ct2 = 1.0f - (nn*nn)*(1.0f-(ct1*ct1));
if (ct2 < 0.0f) {
// total internal reflection
parts[i].vx -= 2.0f*ct1*nrx;
@@ -3087,7 +3095,7 @@ killed:
kill_part(i);
continue;
}
r = pmap[fin_y][fin_x];
auto r = pmap[fin_y][fin_x];
if ((TYP(r)==PT_PIPE || TYP(r) == PT_PPIP) && !TYP(parts[ID(r)].ctype))
{
@@ -3113,6 +3121,7 @@ killed:
parts[i].ctype &= mask;
}
float nrx, nry;
if (get_normal_interp(t, parts[i].x, parts[i].y, parts[i].vx, parts[i].vy, &nrx, &nry))
{
if (TYP(r) == PT_CRMC)
@@ -3122,13 +3131,13 @@ killed:
rx = cosf(r); ry = sinf(r);
anrx = rx * nrx + ry * nry;
anry = rx * nry - ry * nrx;
dp = anrx*parts[i].vx + anry*parts[i].vy;
auto dp = anrx*parts[i].vx + anry*parts[i].vy;
parts[i].vx -= 2.0f*dp*anrx;
parts[i].vy -= 2.0f*dp*anry;
}
else
{
dp = nrx*parts[i].vx + nry*parts[i].vy;
auto dp = nrx*parts[i].vx + nry*parts[i].vy;
parts[i].vx -= 2.0f*dp*nrx;
parts[i].vy -= 2.0f*dp*nry;
}
@@ -3201,17 +3210,16 @@ killed:
}
else
{
s = 1;
r = rng.between(0, 1) * 2 - 1;// position search direction (left/right first)
auto r = rng.between(0, 1) * 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))
{
// allow diagonal movement if target position is blocked
// but no point trying this if particle is stuck in a block of identical particles
dx = parts[i].vx - parts[i].vy*r;
dy = parts[i].vy + parts[i].vx*r;
auto dx = parts[i].vx - parts[i].vy*r;
auto dy = parts[i].vy + parts[i].vx*r;
mv = std::max(fabsf(dx), fabsf(dy));
auto mv = std::max(fabsf(dx), fabsf(dy));
dx /= mv;
dy /= mv;
if (do_move(i, x, y, clear_xf+dx, clear_yf+dy))
@@ -3220,9 +3228,11 @@ killed:
parts[i].vy *= elements[t].Collision;
goto movedone;
}
swappage = dx;
dx = dy*r;
dy = -swappage*r;
{
auto swappage = dx;
dx = dy*r;
dy = -swappage*r;
}
if (do_move(i, x, y, clear_xf+dx, clear_yf+dy))
{
parts[i].vx *= elements[t].Collision;
@@ -3232,8 +3242,9 @@ killed:
}
if (elements[t].Falldown>1 && !grav->IsEnabled() && gravityMode==GRAV_VERTICAL && parts[i].vy>fabsf(parts[i].vx))
{
s = 0;
auto s = 0;
// stagnant is true if FLAG_STAGNANT was set for this particle in previous frame
int rt;
if (!stagnant || nt) //nt is if there is an something else besides the current particle type, around the particle
rt = 30;//slight less water lag, although it changes how it moves a lot
else
@@ -3243,7 +3254,7 @@ killed:
rt = int(parts[i].tmp*0.20f+5.0f);
auto nx = -1, ny = -1;
for (j=clear_x+r; j>=0 && j>=clear_x-rt && j<clear_x+rt && j<XRES; j+=r)
for (auto j=clear_x+r; j>=0 && j>=clear_x-rt && j<clear_x+rt && j<XRES; j+=r)
{
if ((TYP(pmap[fin_y][j])!=t || bmap[fin_y/CELL][j/CELL])
&& (s=do_move(i, x, y, (float)j, fin_yf)))
@@ -3266,7 +3277,7 @@ killed:
r = (parts[i].vy>0) ? 1 : -1;
if (s==1)
for (j=ny+r; j>=0 && j<YRES && j>=ny-rt && j<ny+rt; j+=r)
for (auto j=ny+r; j>=0 && j<YRES && j>=ny-rt && j<ny+rt; j+=r)
{
if ((TYP(pmap[j][nx])!=t || bmap[j/CELL][nx/CELL]) && do_move(i, nx, ny, (float)nx, (float)j))
break;
@@ -3282,11 +3293,11 @@ killed:
else if (elements[t].Falldown>1 && fabsf(pGravX*parts[i].vx+pGravY*parts[i].vy)>fabsf(pGravY*parts[i].vx-pGravX*parts[i].vy))
{
float nxf, nyf, prev_pGravX, prev_pGravY, ptGrav = elements[t].Gravity;
s = 0;
auto s = 0;
// stagnant is true if FLAG_STAGNANT was set for this particle in previous frame
// nt is if there is something else besides the current particle type around the particle
// 30 gives slightly less water lag, although it changes how it moves a lot
rt = (!stagnant || nt) ? 30 : 10;
auto rt = (!stagnant || nt) ? 30 : 10;
// clear_xf, clear_yf is the last known position that the particle should almost certainly be able to move to
nxf = clear_xf;
@@ -3294,12 +3305,12 @@ killed:
auto nx = clear_x;
auto ny = clear_y;
// 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;j<rt;j++)
for (auto j=0;j<rt;j++)
{
// Calculate overall gravity direction
GetGravityField(nx, ny, ptGrav, 1.0f, pGravX, pGravY);
// Scale gravity vector so that the largest component is 1 pixel
mv = std::max(fabsf(pGravX), fabsf(pGravY));
auto mv = std::max(fabsf(pGravX), fabsf(pGravY));
if (mv<0.0001f) break;
pGravX /= mv;
pGravY /= mv;
@@ -3346,12 +3357,12 @@ killed:
// 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;j<rt;j++)
for (auto j=0;j<rt;j++)
{
// Calculate overall gravity direction
GetGravityField(nx, ny, ptGrav, 1.0f, pGravX, pGravY);
// Scale gravity vector so that the largest component is 1 pixel
mv = std::max(fabsf(pGravX), fabsf(pGravY));
auto mv = std::max(fabsf(pGravX), fabsf(pGravY));
if (mv<0.0001f) break;
pGravX /= mv;
pGravY /= mv;
@@ -3391,10 +3402,13 @@ killed:
movedone:
continue;
}
}
//'f' was pressed (single frame)
if (framerender)
{
framerender--;
}
}
void Simulation::RecalcFreeParticles(bool do_life_dec)