summaryrefslogtreecommitdiff
path: root/src/simulation/Simulation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/simulation/Simulation.cpp')
-rw-r--r--src/simulation/Simulation.cpp348
1 files changed, 241 insertions, 107 deletions
diff --git a/src/simulation/Simulation.cpp b/src/simulation/Simulation.cpp
index 89295f4..354c759 100644
--- a/src/simulation/Simulation.cpp
+++ b/src/simulation/Simulation.cpp
@@ -46,7 +46,7 @@ void Simulation::clear_area(int area_x, int area_y, int area_w, int area_h)
}
}
-void Simulation::create_box(int x1, int y1, int x2, int y2, int c, int flags)
+void Simulation::CreateBox(int x1, int y1, int x2, int y2, int c, int flags)
{
int i, j;
if (c==SPC_PROP)
@@ -65,7 +65,27 @@ void Simulation::create_box(int x1, int y1, int x2, int y2, int c, int flags)
}
for (j=y1; j<=y2; j++)
for (i=x1; i<=x2; i++)
- create_parts(i, j, 0, 0, c, flags);
+ CreateParts(i, j, 0, 0, c, flags);
+}
+
+void Simulation::CreateWallBox(int x1, int y1, int x2, int y2, int c, int flags)
+{
+ int i, j;
+ if (x1>x2)
+ {
+ i = x2;
+ x2 = x1;
+ x1 = i;
+ }
+ if (y1>y2)
+ {
+ j = y2;
+ y2 = y1;
+ y1 = j;
+ }
+ for (j=y1; j<=y2; j++)
+ for (i=x1; i<=x2; i++)
+ CreateWalls(i, j, 0, 0, c, flags);
}
int Simulation::flood_prop_2(int x, int y, size_t propoffset, void * propvalue, int proptype, int parttype, char * bitmap)
@@ -133,10 +153,10 @@ Particle Simulation::Get(int x, int y)
return Particle();
}
-int Simulation::flood_parts(int x, int y, int fullc, int cm, int bm, int flags)
+int Simulation::FloodParts(int x, int y, int fullc, int cm, int bm, int flags)
{
int c = fullc&0xFF;
- int x1, x2, dy = (c<PT_NUM)?1:CELL;
+ int x1, x2, dy = 1;
int co = c;
if (c==SPC_PROP)
return 0;
@@ -169,10 +189,10 @@ int Simulation::flood_parts(int x, int y, int fullc, int cm, int bm, int flags)
else
bm = 0;
}
-
+
if (((pmap[y][x]&0xFF)!=cm || bmap[y/CELL][x/CELL]!=bm )/*||( (flags&BRUSH_SPECIFIC_DELETE) && cm!=SLALT)*/)
return 1;
-
+
// go left as far as possible
x1 = x2 = x;
while (x1>=CELL)
@@ -191,7 +211,7 @@ int Simulation::flood_parts(int x, int y, int fullc, int cm, int bm, int flags)
}
x2++;
}
-
+
// fill span
for (x=x1; x<=x2; x++)
{
@@ -200,40 +220,40 @@ int Simulation::flood_parts(int x, int y, int fullc, int cm, int bm, int flags)
if (create_part(-1,x, y, fullc)==-1)
return 0;
}
- else if (!create_parts(x, y, 0, 0, fullc, flags))
+ else if (!CreateParts(x, y, 0, 0, fullc, flags))
return 0;
}
// fill children
if (cm==PT_INST&&co==PT_SPRK)//wire crossing for INST
{
if (y>=CELL+dy && x1==x2 &&
- ((pmap[y-1][x1-1]&0xFF)==PT_INST||(pmap[y-1][x1-1]&0xFF)==PT_SPRK) && ((pmap[y-1][x1]&0xFF)==PT_INST||(pmap[y-1][x1]&0xFF)==PT_SPRK) && ((pmap[y-1][x1+1]&0xFF)==PT_INST || (pmap[y-1][x1+1]&0xFF)==PT_SPRK) &&
- (pmap[y-2][x1-1]&0xFF)!=PT_INST && ((pmap[y-2][x1]&0xFF)==PT_INST ||(pmap[y-2][x1]&0xFF)==PT_SPRK) && (pmap[y-2][x1+1]&0xFF)!=PT_INST)
- flood_parts(x1, y-2, fullc, cm, bm, flags);
+ ((pmap[y-1][x1-1]&0xFF)==PT_INST||(pmap[y-1][x1-1]&0xFF)==PT_SPRK) && ((pmap[y-1][x1]&0xFF)==PT_INST||(pmap[y-1][x1]&0xFF)==PT_SPRK) && ((pmap[y-1][x1+1]&0xFF)==PT_INST || (pmap[y-1][x1+1]&0xFF)==PT_SPRK) &&
+ (pmap[y-2][x1-1]&0xFF)!=PT_INST && ((pmap[y-2][x1]&0xFF)==PT_INST ||(pmap[y-2][x1]&0xFF)==PT_SPRK) && (pmap[y-2][x1+1]&0xFF)!=PT_INST)
+ FloodParts(x1, y-2, fullc, cm, bm, flags);
else if (y>=CELL+dy)
for (x=x1; x<=x2; x++)
if ((pmap[y-1][x]&0xFF)!=PT_SPRK)
{
if (x==x1 || x==x2 || y>=YRES-CELL-1 ||
- (pmap[y-1][x-1]&0xFF)==PT_INST || (pmap[y-1][x+1]&0xFF)==PT_INST ||
- (pmap[y+1][x-1]&0xFF)==PT_INST || ((pmap[y+1][x]&0xFF)!=PT_INST&&(pmap[y+1][x]&0xFF)!=PT_SPRK) || (pmap[y+1][x+1]&0xFF)==PT_INST)
- flood_parts(x, y-dy, fullc, cm, bm, flags);
-
+ (pmap[y-1][x-1]&0xFF)==PT_INST || (pmap[y-1][x+1]&0xFF)==PT_INST ||
+ (pmap[y+1][x-1]&0xFF)==PT_INST || ((pmap[y+1][x]&0xFF)!=PT_INST&&(pmap[y+1][x]&0xFF)!=PT_SPRK) || (pmap[y+1][x+1]&0xFF)==PT_INST)
+ FloodParts(x, y-dy, fullc, cm, bm, flags);
+
}
-
+
if (y<YRES-CELL-dy && x1==x2 &&
- ((pmap[y+1][x1-1]&0xFF)==PT_INST||(pmap[y+1][x1-1]&0xFF)==PT_SPRK) && ((pmap[y+1][x1]&0xFF)==PT_INST||(pmap[y+1][x1]&0xFF)==PT_SPRK) && ((pmap[y+1][x1+1]&0xFF)==PT_INST || (pmap[y+1][x1+1]&0xFF)==PT_SPRK) &&
- (pmap[y+2][x1-1]&0xFF)!=PT_INST && ((pmap[y+2][x1]&0xFF)==PT_INST ||(pmap[y+2][x1]&0xFF)==PT_SPRK) && (pmap[y+2][x1+1]&0xFF)!=PT_INST)
- flood_parts(x1, y+2, fullc, cm, bm, flags);
+ ((pmap[y+1][x1-1]&0xFF)==PT_INST||(pmap[y+1][x1-1]&0xFF)==PT_SPRK) && ((pmap[y+1][x1]&0xFF)==PT_INST||(pmap[y+1][x1]&0xFF)==PT_SPRK) && ((pmap[y+1][x1+1]&0xFF)==PT_INST || (pmap[y+1][x1+1]&0xFF)==PT_SPRK) &&
+ (pmap[y+2][x1-1]&0xFF)!=PT_INST && ((pmap[y+2][x1]&0xFF)==PT_INST ||(pmap[y+2][x1]&0xFF)==PT_SPRK) && (pmap[y+2][x1+1]&0xFF)!=PT_INST)
+ FloodParts(x1, y+2, fullc, cm, bm, flags);
else if (y<YRES-CELL-dy)
for (x=x1; x<=x2; x++)
if ((pmap[y+1][x]&0xFF)!=PT_SPRK)
{
if (x==x1 || x==x2 || y<0 ||
- (pmap[y+1][x-1]&0xFF)==PT_INST || (pmap[y+1][x+1]&0xFF)==PT_INST ||
- (pmap[y-1][x-1]&0xFF)==PT_INST || ((pmap[y-1][x]&0xFF)!=PT_INST&&(pmap[y-1][x]&0xFF)!=PT_SPRK) || (pmap[y-1][x+1]&0xFF)==PT_INST)
- flood_parts(x, y+dy, fullc, cm, bm, flags);
-
+ (pmap[y+1][x-1]&0xFF)==PT_INST || (pmap[y+1][x+1]&0xFF)==PT_INST ||
+ (pmap[y-1][x-1]&0xFF)==PT_INST || ((pmap[y-1][x]&0xFF)!=PT_INST&&(pmap[y-1][x]&0xFF)!=PT_SPRK) || (pmap[y-1][x+1]&0xFF)==PT_INST)
+ FloodParts(x, y+dy, fullc, cm, bm, flags);
+
}
}
else
@@ -241,12 +261,12 @@ int Simulation::flood_parts(int x, int y, int fullc, int cm, int bm, int flags)
if (y>=CELL+dy)
for (x=x1; x<=x2; x++)
if ((pmap[y-dy][x]&0xFF)==cm && bmap[(y-dy)/CELL][x/CELL]==bm)
- if (!flood_parts(x, y-dy, fullc, cm, bm, flags))
+ if (!FloodParts(x, y-dy, fullc, cm, bm, flags))
return 0;
if (y<YRES-CELL-dy)
for (x=x1; x<=x2; x++)
if ((pmap[y+dy][x]&0xFF)==cm && bmap[(y+dy)/CELL][x/CELL]==bm)
- if (!flood_parts(x, y+dy, fullc, cm, bm, flags))
+ if (!FloodParts(x, y+dy, fullc, cm, bm, flags))
return 0;
}
if (!(cm==PT_INST&&co==PT_SPRK))
@@ -254,6 +274,78 @@ int Simulation::flood_parts(int x, int y, int fullc, int cm, int bm, int flags)
return 0;
}
+int Simulation::FloodWalls(int x, int y, int c, int cm, int bm, int flags)
+{
+ int x1, x2, dy = CELL;
+ int co = c;
+ if (cm==-1)
+ {
+ if (c==0)
+ {
+ cm = pmap[y][x]&0xFF;
+ if (!cm)
+ return 0;
+ //if ((flags&BRUSH_REPLACEMODE) && cm!=SLALT)
+ // return 0;
+ }
+ else
+ cm = 0;
+ }
+ if (bm==-1)
+ {
+ if (c==WL_ERASE)
+ {
+ bm = bmap[y/CELL][x/CELL];
+ if (!bm)
+ return 0;
+ if (bm==WL_WALL)
+ cm = 0xFF;
+ }
+ else
+ bm = 0;
+ }
+
+ if (((pmap[y][x]&0xFF)!=cm || bmap[y/CELL][x/CELL]!=bm )/*||( (flags&BRUSH_SPECIFIC_DELETE) && cm!=SLALT)*/)
+ return 1;
+
+ // go left as far as possible
+ x1 = x2 = x;
+ while (x1>=CELL)
+ {
+ if ((pmap[y][x1-1]&0xFF)!=cm || bmap[y/CELL][(x1-1)/CELL]!=bm)
+ {
+ break;
+ }
+ x1--;
+ }
+ while (x2<XRES-CELL)
+ {
+ if ((pmap[y][x2+1]&0xFF)!=cm || bmap[y/CELL][(x2+1)/CELL]!=bm)
+ {
+ break;
+ }
+ x2++;
+ }
+
+ // fill span
+ for (x=x1; x<=x2; x++)
+ {
+ if (!CreateWalls(x, y, 0, 0, c, flags))
+ return 0;
+ }
+ // fill children
+ if (y>=CELL+dy)
+ for (x=x1; x<=x2; x++)
+ if ((pmap[y-dy][x]&0xFF)==cm && bmap[(y-dy)/CELL][x/CELL]==bm)
+ if (!FloodWalls(x, y-dy, c, cm, bm, flags))
+ return 0;
+ if (y<YRES-CELL-dy)
+ for (x=x1; x<=x2; x++)
+ if ((pmap[y+dy][x]&0xFF)==cm && bmap[(y+dy)/CELL][x/CELL]==bm)
+ if (!FloodWalls(x, y+dy, c, cm, bm, flags))
+ return 0;
+ return 0;
+}
int Simulation::flood_water(int x, int y, int i, int originaly, int check)
{
int x1 = 0,x2 = 0;
@@ -517,46 +609,20 @@ void Simulation::ApplyDecorationLine(int x1, int y1, int x2, int y2, int rx, int
}
//this creates particles from a brush, don't use if you want to create one particle
-int Simulation::create_parts(int x, int y, int rx, int ry, int c, int flags, Brush * cBrush)
+int Simulation::CreateParts(int x, int y, int rx, int ry, int c, int flags, Brush * cBrush)
{
int i, j, r, f = 0, u, v, oy, ox, b = 0, dw = 0, stemp = 0, p;//n;
-
+
if(cBrush)
{
rx = cBrush->GetRadius().X;
ry = cBrush->GetRadius().Y;
}
-
+
int wall = c - 100;
if (c==SPC_WIND || c==PT_FIGH)
return 0;
-
- //if(c==SPC_PROP){
- // prop_edit_ui(vid_buf, x, y);
- // return 0;
- //}
- for (r=UI_ACTUALSTART; r<=UI_ACTUALSTART+UI_WALLCOUNT; r++)
- {
- if (wall==r)
- {
- if (c == SPC_AIR || c == SPC_HEAT || c == SPC_COOL || c == SPC_VACUUM || c == SPC_PGRV || c == SPC_NGRV || wall == WL_SIGN)
- break;
- if (wall == WL_ERASE)
- b = 0;
- else
- b = wall;
- dw = 1;
- }
- }
- if (c == WL_FANHELPER)
- {
- b = WL_FANHELPER;
- dw = 1;
- }
- if (wall == WL_GRAV)
- {
- gravwl_timeout = 60;
- }
+
if (c==PT_LIGH)
{
if (lighting_recreate>0 && rx+ry>0)
@@ -573,49 +639,7 @@ int Simulation::create_parts(int x, int y, int rx, int ry, int c, int flags, Bru
}
else return 0;
}
-
- if (dw==1)
- {
- ry = ry/CELL;
- rx = rx/CELL;
- x = x/CELL;
- y = y/CELL;
- x -= rx/2;
- y -= ry/2;
- for (ox=x; ox<=x+rx; ox++)
- {
- for (oy=y; oy<=y+rx; oy++)
- {
- if (ox>=0&&ox<XRES/CELL&&oy>=0&&oy<YRES/CELL)
- {
- i = ox;
- j = oy;
- if (b==WL_FAN)
- {
- fvx[j][i] = 0.0f;
- fvy[j][i] = 0.0f;
- }
- if (b==WL_STREAM)
- {
- i = x + rx/2;
- j = y + ry/2;
- for (v=-1; v<2; v++)
- for (u=-1; u<2; u++)
- if (i+u>=0 && i+u<XRES/CELL &&
- j+v>=0 && j+v<YRES/CELL &&
- bmap[j+v][i+u] == WL_STREAM)
- return 1;
- bmap[j][i] = WL_STREAM;
- continue;
- }
- if (b==0 && bmap[j][i]==WL_GRAV) gravwl_timeout = 60;
- bmap[j][i] = b;
- }
- }
- }
- return 1;
- }
-
+
//eraser
if (c == 0)
{
@@ -639,7 +663,7 @@ int Simulation::create_parts(int x, int y, int rx, int ry, int c, int flags, Bru
}
return 1;
}
-
+
if (c == SPC_AIR || c == SPC_HEAT || c == SPC_COOL || c == SPC_VACUUM || c == SPC_PGRV || c == SPC_NGRV)
{
if (rx==0&&ry==0)
@@ -670,7 +694,7 @@ int Simulation::create_parts(int x, int y, int rx, int ry, int c, int flags, Bru
}
return 1;
}
-
+
//else, no special modes, draw element like normal.
if (rx==0&&ry==0)//workaround for 1pixel brush/floodfill crashing. todo: find a better fix later.
{
@@ -696,7 +720,64 @@ int Simulation::create_parts(int x, int y, int rx, int ry, int c, int flags, Bru
return !f;
}
-void Simulation::create_line(int x1, int y1, int x2, int y2, int rx, int ry, int c, int flags, Brush * cBrush)
+int Simulation::CreateWalls(int x, int y, int rx, int ry, int c, int flags, Brush * cBrush)
+{
+ int i, j, r, f = 0, u, v, oy, ox, b = 0, dw = 0, stemp = 0, p;//n;
+
+ if(cBrush)
+ {
+ rx = cBrush->GetRadius().X;
+ ry = cBrush->GetRadius().Y;
+ }
+
+ int wall = c;
+
+ if (wall == WL_ERASE)
+ b = 0;
+ else
+ b = wall;
+
+ ry = ry/CELL;
+ rx = rx/CELL;
+ x = x/CELL;
+ y = y/CELL;
+ x -= rx/2;
+ y -= ry/2;
+ for (ox=x; ox<=x+rx; ox++)
+ {
+ for (oy=y; oy<=y+rx; oy++)
+ {
+ if (ox>=0&&ox<XRES/CELL&&oy>=0&&oy<YRES/CELL)
+ {
+ i = ox;
+ j = oy;
+ if (b==WL_FAN)
+ {
+ fvx[j][i] = 0.0f;
+ fvy[j][i] = 0.0f;
+ }
+ if (b==WL_STREAM)
+ {
+ i = x + rx/2;
+ j = y + ry/2;
+ for (v=-1; v<2; v++)
+ for (u=-1; u<2; u++)
+ if (i+u>=0 && i+u<XRES/CELL &&
+ j+v>=0 && j+v<YRES/CELL &&
+ bmap[j+v][i+u] == WL_STREAM)
+ return 1;
+ bmap[j][i] = WL_STREAM;
+ continue;
+ }
+ if (b==0 && bmap[j][i]==WL_GRAV) gravwl_timeout = 60;
+ bmap[j][i] = b;
+ }
+ }
+ }
+ return 1;
+}
+
+void Simulation::CreateLine(int x1, int y1, int x2, int y2, int rx, int ry, int c, int flags, Brush * cBrush)
{
int cp=abs(y2-y1)>abs(x2-x1), x, y, dx, dy, sy;
float e, de;
@@ -732,20 +813,73 @@ void Simulation::create_line(int x1, int y1, int x2, int y2, int rx, int ry, int
for (x=x1; x<=x2; x++)
{
if (cp)
- create_parts(y, x, rx, ry, c, flags, cBrush);
+ CreateParts(y, x, rx, ry, c, flags, cBrush);
else
- create_parts(x, y, rx, ry, c, flags, cBrush);
+ CreateParts(x, y, rx, ry, c, flags, cBrush);
e += de;
if (e >= 0.5f)
{
y += sy;
if ((c==WL_EHOLE+100 || c==WL_ALLOWGAS+100 || c==WL_ALLOWENERGY+100 || c==WL_ALLOWALLELEC+100 || c==WL_ALLOWSOLID+100 || c==WL_ALLOWAIR+100 || c==WL_WALL+100 || c==WL_DESTROYALL+100 || c==WL_ALLOWLIQUID+100 || c==WL_FAN+100 || c==WL_STREAM+100 || c==WL_DETECT+100 || c==WL_EWALL+100 || c==WL_WALLELEC+100 || !(rx+ry))
- && ((y1<y2) ? (y<=y2) : (y>=y2)))
+ && ((y1<y2) ? (y<=y2) : (y>=y2)))
+ {
+ if (cp)
+ CreateParts(y, x, rx, ry, c, flags, cBrush);
+ else
+ CreateParts(x, y, rx, ry, c, flags, cBrush);
+ }
+ e -= 1.0f;
+ }
+ }
+}
+
+void Simulation::CreateWallLine(int x1, int y1, int x2, int y2, int rx, int ry, int c, int flags, Brush * cBrush)
+{
+ int cp=abs(y2-y1)>abs(x2-x1), x, y, dx, dy, sy;
+ float e, de;
+ if (cp)
+ {
+ y = x1;
+ x1 = y1;
+ y1 = y;
+ y = x2;
+ x2 = y2;
+ y2 = y;
+ }
+ if (x1 > x2)
+ {
+ y = x1;
+ x1 = x2;
+ x2 = y;
+ y = y1;
+ y1 = y2;
+ y2 = y;
+ }
+ dx = x2 - x1;
+ dy = abs(y2 - y1);
+ e = 0.0f;
+ if (dx)
+ de = dy/(float)dx;
+ else
+ de = 0.0f;
+ y = y1;
+ sy = (y1<y2) ? 1 : -1;
+ for (x=x1; x<=x2; x++)
+ {
+ if (cp)
+ CreateWalls(y, x, rx, ry, c, flags, cBrush);
+ else
+ CreateWalls(x, y, rx, ry, c, flags, cBrush);
+ e += de;
+ if (e >= 0.5f)
+ {
+ y += sy;
+ if (!(rx+ry) && ((y1<y2) ? (y<=y2) : (y>=y2)))
{
if (cp)
- create_parts(y, x, rx, ry, c, flags, cBrush);
+ CreateWalls(y, x, rx, ry, c, flags, cBrush);
else
- create_parts(x, y, rx, ry, c, flags, cBrush);
+ CreateWalls(x, y, rx, ry, c, flags, cBrush);
}
e -= 1.0f;
}
@@ -1097,7 +1231,7 @@ void Simulation::create_arc(int sx, int sy, int dx, int dy, int midpoints, int v
xmid[i+1] += (rand()%variance)-voffset;
ymid[i+1] += (rand()%variance)-voffset;
}
- create_line(xmid[i], ymid[i], xmid[i+1], ymid[i+1], 0, 0, type, flags);
+ CreateLine(xmid[i], ymid[i], xmid[i+1], ymid[i+1], 0, 0, type, flags);
}
free(xmid);
free(ymid);