mirror of
https://github.com/The-Powder-Toy/The-Powder-Toy.git
synced 2025-08-31 11:41:51 +02:00
Sort out scopes in Simulation::UpdateParticles
This commit is contained in:
@@ -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)
|
||||
|
Reference in New Issue
Block a user