summaryrefslogtreecommitdiff
path: root/src/simulation
diff options
context:
space:
mode:
Diffstat (limited to 'src/simulation')
-rw-r--r--src/simulation/Particle.cpp2
-rw-r--r--src/simulation/Particle.h1
-rw-r--r--src/simulation/Simulation.cpp283
-rw-r--r--src/simulation/Simulation.h8
-rw-r--r--src/simulation/Solid.h22
-rw-r--r--src/simulation/elements/QRTZ.cpp2
-rw-r--r--src/simulation/elements/RBDM.cpp4
-rw-r--r--src/simulation/elements/TTAN.cpp6
-rw-r--r--src/simulation/elements/TUNG.cpp4
-rw-r--r--src/simulation/tools/SimTool.h2
-rw-r--r--src/simulation/tools/SolidTool.cpp65
11 files changed, 383 insertions, 16 deletions
diff --git a/src/simulation/Particle.cpp b/src/simulation/Particle.cpp
index 19089a1..d3657e4 100644
--- a/src/simulation/Particle.cpp
+++ b/src/simulation/Particle.cpp
@@ -16,5 +16,7 @@ std::vector<StructProperty> Particle::GetProperties()
properties.push_back(StructProperty("tmp", StructProperty::Integer, offsetof(Particle, tmp)));
properties.push_back(StructProperty("tmp2", StructProperty::Integer, offsetof(Particle, tmp2)));
properties.push_back(StructProperty("dcolour", StructProperty::UInteger, offsetof(Particle, dcolour)));
+ properties.push_back(StructProperty("sld", StructProperty::UInteger, offsetof(Particle, sld)));
+ properties.push_back(StructProperty("snext", StructProperty::UInteger, offsetof(Particle, snext)));
return properties;
}
diff --git a/src/simulation/Particle.h b/src/simulation/Particle.h
index fbb5988..99fa96c 100644
--- a/src/simulation/Particle.h
+++ b/src/simulation/Particle.h
@@ -15,6 +15,7 @@ struct Particle
int tmp;
int tmp2;
unsigned int dcolour;
+ int sld, snext, sprev;
/** Returns a list of properties, their type and offset within the structure that can be changed
by higher-level processes referring to them by name such as Lua or the property tool **/
static std::vector<StructProperty> GetProperties();
diff --git a/src/simulation/Simulation.cpp b/src/simulation/Simulation.cpp
index 60ca1f7..cb59b15 100644
--- a/src/simulation/Simulation.cpp
+++ b/src/simulation/Simulation.cpp
@@ -933,6 +933,36 @@ void Simulation::ApplyDecorationBox(int x1, int y1, int x2, int y2, int colR, in
ApplyDecoration(i, j, colR, colG, colB, colA, mode);
}
+int Simulation::ToolClick(int x, int y, int tool)
+{
+ if(tools[tool])
+ {
+ Particle * cpart = NULL;
+ int r;
+ if(r = pmap[y][x])
+ cpart = &(parts[r>>8]);
+ else if(r = photons[y][x])
+ cpart = &(parts[r>>8]);
+ return tools[tool]->Click(this, cpart, x, y);
+ }
+ return 0;
+}
+
+int Simulation::ToolStart(int x, int y, int tool)
+{
+ if(tools[tool])
+ {
+ Particle * cpart = NULL;
+ int r;
+ if(r = pmap[y][x])
+ cpart = &(parts[r>>8]);
+ else if(r = photons[y][x])
+ cpart = &(parts[r>>8]);
+ return tools[tool]->Start(this, cpart, x, y);
+ }
+ return 0;
+}
+
int Simulation::Tool(int x, int y, int tool, float strength)
{
if(tools[tool])
@@ -1872,6 +1902,10 @@ void Simulation::clear_sim(void)
memset(bmap, 0, sizeof(bmap));
memset(emap, 0, sizeof(emap));
memset(parts, 0, sizeof(Particle)*NPART);
+ for (i=0; i<NSOLID; i++) {
+ solids[i].first = -1;
+ solids[i].last = -1;
+ }
for (i=0; i<NPART-1; i++)
parts[i].life = i+1;
parts[NPART-1].life = -1;
@@ -1947,6 +1981,16 @@ void Simulation::init_can_move()
for (destinationType = 0; destinationType < PT_NUM; destinationType++)
can_move[movingType][destinationType] = 1;
+ // solids don't pass through things and non-energy things don't pass through solids
+ for (movingType = 1; movingType < PT_NUM; movingType++)
+ for (destinationType = 1; destinationType < PT_NUM; destinationType++) {
+ if(elements[movingType].Properties & TYPE_SOLID)
+ can_move[movingType][destinationType] = 0;
+ if((elements[destinationType].Properties & TYPE_SOLID) &&
+ (elements[movingType].Properties & TYPE_ENERGY))
+ can_move[movingType][destinationType] = 0;
+ }
+
//photons go through everything by default
for (destinationType = 1; destinationType < PT_NUM; destinationType++)
can_move[PT_PHOT][destinationType] = 2;
@@ -2143,6 +2187,8 @@ int Simulation::try_move(int i, int x, int y, int nx, int ny)
return 1;
e = eval_move(parts[i].type, nx, ny, &r);
+ if(parts[i].sld && r && parts[i].sld == parts[r>>8].sld)
+ return 1;
/* half-silvered mirror */
if (!e && parts[i].type==PT_PHOT &&
@@ -2353,6 +2399,33 @@ int Simulation::do_move(int i, int x, int y, float nxf, float nyf)
if (parts[i].type == PT_NONE)
return 0;
result = try_move(i, x, y, nx, ny);
+
+ if(parts[i].sld) {
+ Solid *sld = solids + (parts[i].sld - 1);
+ float dx = nxf - parts[i].x;
+ float dy = nyf - parts[i].y;
+
+ if(nx<CELL || nx>=XRES-CELL || ny<CELL || ny>=YRES-CELL) {
+ kill_part(i);
+ return -1;
+ }
+
+ if(result == 0) {
+ float px = parts[i].x - sld->cx;
+ float py = parts[i].y - sld->cy;
+ int tx = (px >= 0.0f);
+ int ty = (py >= 0.0f);
+
+ sld->bf = 1;
+ if(px > sld->bpx[0]) { sld->bpx[0] = px; sld->bpy[0] = py; sld->bdx[0] = dx; sld->bdy[0] = dy; sld->bp[0] = pmap[ny][nx] ? pmap[ny][nx] >> 8 : -1; }
+ if(px < sld->bpx[1]) { sld->bpx[1] = px; sld->bpy[1] = py; sld->bdx[1] = dx; sld->bdy[1] = dy; sld->bp[1] = pmap[ny][nx] ? pmap[ny][nx] >> 8 : -1; }
+ if(py > sld->bpy[2]) { sld->bpx[2] = px; sld->bpy[2] = py; sld->bdx[2] = dx; sld->bdy[2] = dy; sld->bp[2] = pmap[ny][nx] ? pmap[ny][nx] >> 8 : -1; }
+ if(py < sld->bpy[3]) { sld->bpx[3] = px; sld->bpy[3] = py; sld->bdx[3] = dx; sld->bdy[3] = dy; sld->bp[3] = pmap[ny][nx] ? pmap[ny][nx] >> 8 : -1; }
+ }
+
+ return 1;
+ }
+
if (result)
{
int t = parts[i].type;
@@ -2371,7 +2444,7 @@ int Simulation::do_move(int i, int x, int y, float nxf, float nyf)
photons[ny][nx] = t|(i<<8);
else if (t)
pmap[ny][nx] = t|(i<<8);
- }
+ }
}
return result;
}
@@ -2574,6 +2647,23 @@ void Simulation::detach(int i)
parts[i].ctype = 0;
}
+void Simulation::unlink_solid(int i)
+{
+ Solid *sld = solids + (parts[i].sld - 1);
+
+ if(parts[i].sprev == -1)
+ sld->first = parts[i].snext;
+ else
+ parts[parts[i].sprev].snext = parts[i].snext;
+
+ if(parts[i].snext == -1)
+ sld->last = parts[i].sprev;
+ else
+ parts[parts[i].snext].sprev = parts[i].sprev;
+
+ parts[i].sld = 0;
+}
+
void Simulation::kill_part(int i)//kills particle number i
{
int x = (int)(parts[i].x+0.5f);
@@ -2588,6 +2678,9 @@ void Simulation::kill_part(int i)//kills particle number i
if (parts[i].type == PT_NONE)
return;
+ if(parts[i].sld)
+ unlink_solid(i);
+
if(parts[i].type > 0 && parts[i].type < PT_NUM && elementCount[parts[i].type])
elementCount[parts[i].type]--;
if (parts[i].type == PT_STKM)
@@ -2625,6 +2718,9 @@ void Simulation::part_change_type(int i, int x, int y, int t)//changes the type
return;
}
+ if(parts[i].sld && !(elements[t].Properties & TYPE_SOLID))
+ unlink_solid(i); // DEFECTOR!
+
if (parts[i].type == PT_STKM)
player.spwn = 0;
else if (parts[i].type == PT_STKM2)
@@ -2823,6 +2919,8 @@ int Simulation::create_part(int p, int x, int y, int tv)
parts[i].tmp = 0;
parts[i].tmp2 = 0;
parts[i].dcolour = 0;
+ parts[i].sld = 0;
+ parts[i].snext = 0;
parts[i].flags = 0;
if (t == PT_GLAS || t == PT_QRTZ || t == PT_TUNG)
{
@@ -3618,8 +3716,8 @@ void Simulation::update_particles_i(int start, int inc)
}
}
}
- if (elements[t].Gravity || !(elements[t].Properties & TYPE_SOLID))
- {
+ if ((elements[t].Gravity && (!(elements[t].Properties & TYPE_SOLID) || parts[i].sld)) ||
+ !(elements[t].Properties & TYPE_SOLID)) {
//Gravity mode by Moach
switch (gravityMode)
{
@@ -3658,9 +3756,14 @@ void Simulation::update_particles_i(int start, int inc)
parts[i].vx *= elements[t].Loss;
parts[i].vy *= elements[t].Loss;
}
- //particle gets velocity from the vx and vy maps
- parts[i].vx += elements[t].Advection*vx[y/CELL][x/CELL] + pGravX;
- parts[i].vy += elements[t].Advection*vy[y/CELL][x/CELL] + pGravY;
+ parts[i].vx += pGravX;
+ parts[i].vy += pGravY;
+
+ //particle gets velocity from the vx and vy maps (advection)
+ if (elements[t].Advection && (!(elements[t].Properties & TYPE_SOLID) || parts[i].sld)) {
+ parts[i].vx += elements[t].Advection*vx[y/CELL][x/CELL];
+ parts[i].vy += elements[t].Advection*vy[y/CELL][x/CELL];
+ }
if (elements[t].Diffusion)//the random diffusion that gasses have
@@ -4639,6 +4742,170 @@ int Simulation::GetParticleType(std::string type)
return -1;
}
+void Simulation::update_solids()
+{
+ int i, pp, nc, bb, bd, nx, ny;
+ float cdx, cdy, adx, ady, mmx, mmy, dd, ee, rmx, rmy, vx, vy;
+ float cvrot, svrot;
+ Solid *sld;
+
+ for(i=0; i<NSOLID; i++) {
+ sld = solids + i;
+ if(sld->first == -1)
+ continue;
+
+ for(pp=sld->first; pp!=-1; pp=parts[pp].snext) {
+ nx = (int)(parts[pp].x + 0.5f);
+ ny = (int)(parts[pp].y + 0.5f);
+ if(!pmap[ny-1][nx])
+ parts[pp].vy += pv[ny/CELL][nx/CELL-1];
+ if(!pmap[ny+1][nx])
+ parts[pp].vy -= pv[ny/CELL][nx/CELL+1];
+ if(!pmap[ny][nx-1])
+ parts[pp].vx += pv[ny/CELL][nx/CELL-1];
+ if(!pmap[ny][nx+1])
+ parts[pp].vx -= pv[ny/CELL][nx/CELL+1];
+ sld->ax += parts[pp].vx;
+ sld->ay += parts[pp].vy;
+ sld->an ++;
+ }
+ sld->ax /= sld->an;
+ sld->ay /= sld->an;
+
+ if(sld->bf) {
+ for(bd=0; bd<4; bd++) {
+ cdx = sld->bpx[bd];
+ cdy = sld->bpy[bd];
+ ee = cdy*sld->ax - cdx*sld->ay;
+ for(bb=0; bb<4; bb++)
+ if(bd != bb && (sld->bpx[bd] != sld->bpx[bb] || sld->bpy[bd] != sld->bpy[bb])) {
+ cdx = sld->bpx[bb] - sld->bpx[bd];
+ cdy = sld->bpy[bb] - sld->bpy[bd];
+ dd = cdy*sld->bdx[bb] - cdx*sld->bdy[bb];
+ if(dd * ee < 0.0f)
+ break;
+ }
+ if(bb >= 4)
+ break;
+ }
+ if(bd >= 4) {
+ nc = 0;
+ for(pp=sld->first; pp!=-1; pp=parts[pp].snext) {
+ sld->cx += parts[pp].x;
+ sld->cy += parts[pp].y;
+ parts[pp].vx = 0.0f;
+ parts[pp].vy = 0.0f;
+ nc ++;
+ }
+ sld->cx /= nc;
+ sld->cy /= nc;
+ sld->vx = sld->vy = sld->vrot = 0.0f;
+ sld->ax = sld->ay = sld->arot = 0.0f;
+ sld->an = 0;
+ sld->bf = 0;
+ sld->bpx[0] = -10000;
+ sld->bpx[1] = 10000;
+ sld->bpy[2] = -10000;
+ sld->bpy[3] = 10000;
+ continue;
+ }
+
+ cdx = sld->cx + sld->bpx[bd];
+ cdy = sld->cy + sld->bpy[bd];
+ mmx = -sld->bdx[bd];
+ mmy = -sld->bdy[bd];
+ } else
+ mmx = mmy = 0.0f;
+
+ sld->cx = sld->cy = 0.0f;
+ nc = 0;
+ for(pp=sld->first; pp!=-1; pp=parts[pp].snext) {
+ sld->cx += parts[pp].x;
+ sld->cy += parts[pp].y;
+ nc ++;
+ }
+ sld->cx /= nc;
+ sld->cy /= nc;
+
+ if(!sld->bf) {
+ cdx = sld->cx;
+ cdy = sld->cy;
+ }
+
+ if(sld->an) {
+ if(sld->bf) {
+ sld->vx = 0.0f;
+ sld->vy = 0.0f;
+ } else {
+ sld->vx = sld->ax;
+ sld->vy = sld->ay;
+ }
+ }
+
+ for(pp=sld->first; pp!=-1; pp=parts[pp].snext) {
+ dd = (parts[pp].x - cdx)*(parts[pp].x - cdx) + (parts[pp].y - cdy)*(parts[pp].y - cdy);
+ if(dd > 0.5f)
+ sld->arot += ((parts[pp].vx - sld->vx)*(parts[pp].y - cdy) - (parts[pp].vy - sld->vy)*(parts[pp].x - cdx)) / dd;
+ }
+
+ if(sld->an) {
+ sld->vrot = atanf(sld->arot / sld->an);
+ printf("Solid %d: count %d, vx %f, vy %f, vrot %f, b %d/%d, cdx %f, cdy %f\n", i, sld->an, sld->vx, sld->vy, sld->vrot, sld->bf, bd, cdx, cdy);
+ if(sld->bf) {
+ printf(" ");
+ for(bb=0; bb<4; bb++)
+ printf(" [ %f %f ]", sld->bpx[bb], sld->bpy[bb]);
+ printf("\n");
+ }
+ }
+
+ cvrot = cosf(sld->vrot) - 1.0f;
+ svrot = sinf(sld->vrot);
+ rmx = rmy = 0.0f;
+ for(pp=sld->first; pp!=-1; pp=parts[pp].snext) {
+ adx = parts[pp].x - cdx;
+ ady = parts[pp].y - cdy;
+ vx = sld->vx + adx*cvrot + ady*svrot;
+ vy = sld->vy + ady*cvrot - adx*svrot;
+ rmx += parts[pp].vx - vx;
+ rmy += parts[pp].vy - vy;
+ parts[pp].vx = vx;
+ parts[pp].vy = vy;
+ parts[pp].x += parts[pp].vx + mmx;
+ parts[pp].y += parts[pp].vy + mmy;
+ }
+
+ if(sld->bf && sld->bp[bd] != -1) {
+ pp = sld->bp[bd];
+ if(parts[pp].sld && parts[pp].type) {
+ if(parts[pp].sld-1 != i) {
+ printf(" reaction momentum: %f %f (solid-solid %d)\n", rmx, rmy, parts[pp].sld-1);
+ parts[pp].vx += rmx;
+ parts[pp].vy += rmy;
+ }
+ } else if(!(elements[parts[pp].type].Properties & TYPE_SOLID) && parts[pp].type) {
+ ee = hypotf(rmx, rmy) * 0.01f;
+ if(ee > 1.0f) {
+ ee = 1.0f / ee;
+ rmx *= ee;
+ rmy *= ee;
+ }
+ printf(" reaction momentum: %f %f (solid-particle %s)\n", rmx, rmy, elements[parts[pp].type].Name);
+ parts[pp].vx += rmx;
+ parts[pp].vy += rmy;
+ }
+ }
+
+ sld->ax = sld->ay = sld->arot = 0.0f;
+ sld->an = 0;
+ sld->bf = 0;
+ sld->bpx[0] = -10000;
+ sld->bpx[1] = 10000;
+ sld->bpy[2] = -10000;
+ sld->bpy[3] = 10000;
+ }
+}
+
void Simulation::update_particles()//doesn't update the particles themselves, but some other things
{
int i, x, y, t;
@@ -4740,8 +5007,10 @@ void Simulation::update_particles()//doesn't update the particles themselves, bu
}
}
- if(!sys_pause||framerender)
+ if(!sys_pause||framerender) {
update_particles_i(0, 1);
+ update_solids();
+ }
if(framerender)
framerender--;
diff --git a/src/simulation/Simulation.h b/src/simulation/Simulation.h
index 31185f6..7b0ee91 100644
--- a/src/simulation/Simulation.h
+++ b/src/simulation/Simulation.h
@@ -9,6 +9,7 @@
#include "SimulationData.h"
#include "Sign.h"
#include "Particle.h"
+#include "Solid.h"
#include "Stickman.h"
#include "WallType.h"
#include "GOLMenu.h"
@@ -101,6 +102,8 @@ public:
int pmap[YRES][XRES];
int photons[YRES][XRES];
int pmap_count[YRES][XRES];
+ //Solids
+ Solid solids[NSOLID];
//Simulation Settings
int edgeMode;
int gravityMode;
@@ -148,6 +151,7 @@ public:
//int get_brush_flags();
TPT_NO_INLINE int create_part(int p, int x, int y, int t);
TPT_NO_INLINE void delete_part(int x, int y);
+ void unlink_solid(int part);
void get_sign_pos(int i, int *x0, int *y0, int *w, int *h);
TPT_NO_INLINE int is_wire(int x, int y);
TPT_NO_INLINE int is_wire_off(int x, int y);
@@ -157,6 +161,7 @@ public:
int nearest_part(int ci, int t, int max_d);
void update_particles_i(int start, int inc);
void update_particles();
+ void update_solids();
void rotate_area(int area_x, int area_y, int area_w, int area_h, int invert);
void clear_area(int area_x, int area_y, int area_w, int area_h);
@@ -169,6 +174,8 @@ public:
void ApplyDecorationBox(int x1, int y1, int x2, int y2, int colR, int colG, int colB, int colA, int mode);
//Drawing Tools like HEAT, AIR, and GRAV
+ int ToolStart(int x, int y, int tool);
+ int ToolClick(int x, int y, int tool);
int Tool(int x, int y, int tool, float strength = 1.0f);
int ToolBrush(int x, int y, int tool, Brush * cBrush, float strength = 1.0f);
void ToolLine(int x1, int y1, int x2, int y2, int tool, Brush * cBrush, float strength = 1.0f);
@@ -188,7 +195,6 @@ public:
void CreateLine(int x1, int y1, int x2, int y2, int c);
void CreateBox(int x1, int y1, int x2, int y2, int c, int flags = -1);
int FloodParts(int x, int y, int c, int cm, int flags = -1);
-
void GetGravityField(int x, int y, float particleGrav, float newtonGrav, float & pGravX, float & pGravY);
diff --git a/src/simulation/Solid.h b/src/simulation/Solid.h
new file mode 100644
index 0000000..f4b932c
--- /dev/null
+++ b/src/simulation/Solid.h
@@ -0,0 +1,22 @@
+#ifndef SOLID_H_
+#define SOLID_H_
+
+#include <vector>
+#include "StructProperty.h"
+
+#define NSOLID 16
+
+struct Solid
+{
+ int first, last;
+ float vx, vy, vrot;
+ float cx, cy; // centroid position
+ float ax, ay, arot, arad; // accumulators
+ int an;
+ unsigned char bf; // blocking flags
+ float bpx[4], bpy[4]; // blocking position extents
+ float bdx[4], bdy[4]; // blocking position orientation
+ int bp[4]; // blocking counterparticle ID
+};
+
+#endif
diff --git a/src/simulation/elements/QRTZ.cpp b/src/simulation/elements/QRTZ.cpp
index b399662..b76d817 100644
--- a/src/simulation/elements/QRTZ.cpp
+++ b/src/simulation/elements/QRTZ.cpp
@@ -12,7 +12,7 @@ Element_QRTZ::Element_QRTZ()
Advection = 0.0f;
AirDrag = 0.00f * CFDS;
AirLoss = 0.90f;
- Loss = 0.00f;
+ Loss = 0.99f;
Collision = 0.0f;
Gravity = 0.0f;
Diffusion = 0.00f;
diff --git a/src/simulation/elements/RBDM.cpp b/src/simulation/elements/RBDM.cpp
index b1aed85..24ada3f 100644
--- a/src/simulation/elements/RBDM.cpp
+++ b/src/simulation/elements/RBDM.cpp
@@ -12,9 +12,9 @@ Element_RBDM::Element_RBDM()
Advection = 0.0f;
AirDrag = 0.00f * CFDS;
AirLoss = 0.90f;
- Loss = 0.00f;
+ Loss = 0.99f;
Collision = 0.0f;
- Gravity = 0.0f;
+ Gravity = 0.1f;
Diffusion = 0.00f;
HotAir = 0.000f * CFDS;
Falldown = 0;
diff --git a/src/simulation/elements/TTAN.cpp b/src/simulation/elements/TTAN.cpp
index 3f997f7..ef16532 100644
--- a/src/simulation/elements/TTAN.cpp
+++ b/src/simulation/elements/TTAN.cpp
@@ -11,11 +11,11 @@ Element_TTAN::Element_TTAN()
Enabled = 1;
Advection = 0.0f;
- AirDrag = 0.00f * CFDS;
+ AirDrag = 0.02f * CFDS;
AirLoss = 0.90f;
- Loss = 0.00f;
+ Loss = 0.999f;
Collision = 0.0f;
- Gravity = 0.0f;
+ Gravity = 0.2f;
Diffusion = 0.00f;
HotAir = 0.000f * CFDS;
Falldown = 0;
diff --git a/src/simulation/elements/TUNG.cpp b/src/simulation/elements/TUNG.cpp
index 9b5f61d..c07aa01 100644
--- a/src/simulation/elements/TUNG.cpp
+++ b/src/simulation/elements/TUNG.cpp
@@ -13,9 +13,9 @@ Element_TUNG::Element_TUNG()
Advection = 0.0f;
AirDrag = 0.00f * CFDS;
AirLoss = 0.90f;
- Loss = 0.00f;
+ Loss = 0.9999f;
Collision = 0.0f;
- Gravity = 0.0f;
+ Gravity = 0.5f;
Diffusion = 0.00f;
HotAir = 0.000f * CFDS;
Falldown = 0;
diff --git a/src/simulation/tools/SimTool.h b/src/simulation/tools/SimTool.h
index c5a5cb1..17db8f0 100644
--- a/src/simulation/tools/SimTool.h
+++ b/src/simulation/tools/SimTool.h
@@ -18,6 +18,8 @@ public:
SimTool();
virtual ~SimTool() {}
virtual int Perform(Simulation * sim, Particle * cpart, int x, int y, float strength) { return 0; }
+ virtual int Start(Simulation * sim, Particle * cpart, int x, int y) { return 0; }
+ virtual int Click(Simulation * sim, Particle * cpart, int x, int y) { return 0; }
};
#endif
diff --git a/src/simulation/tools/SolidTool.cpp b/src/simulation/tools/SolidTool.cpp
new file mode 100644
index 0000000..b147820
--- /dev/null
+++ b/src/simulation/tools/SolidTool.cpp
@@ -0,0 +1,65 @@
+#include "ToolClasses.h"
+//#TPT-Directive ToolClass Tool_Solid TOOL_SOLID 6
+//#TPT-Directive ToolHeader Tool_Solid int LastSolid
+//#TPT-Directive ToolHeader Tool_Solid virtual int Start(Simulation * sim, Particle * cpart, int x, int y)
+Tool_Solid::Tool_Solid()
+{
+ Identifier = "DEFAULT_TOOL_SOLID";
+ Name = "SLD";
+ Colour = PIXPACK(0xA0A080);
+ Description = "Makes affected particles into a solid.";
+ LastSolid = -1;
+}
+
+int Tool_Solid::Start(Simulation * sim, Particle * cpart, int x, int y) {
+ if(cpart && cpart->sld)
+ LastSolid = cpart->sld - 1;
+ else
+ LastSolid = -1;
+ return 1;
+}
+
+int Tool_Solid::Perform(Simulation * sim, Particle * cpart, int x, int y, float strength)
+{
+ int solid_index = LastSolid, i;
+
+ if(!cpart || cpart->sld ||
+ !(sim->elements[cpart->type].Properties & TYPE_SOLID))
+ return 0;
+
+ if(solid_index == -1)
+ for(i=0; i<NSOLID; i++)
+ if(sim->solids[i].first == -1) {
+ solid_index = i;
+ break;
+ }
+ if(solid_index == -1)
+ return 0;
+ LastSolid = solid_index;
+
+ Solid *sld = sim->solids + solid_index;
+
+ cpart->sld = solid_index + 1;
+ if(sld->first == -1) {
+ sld->vx = sld->vy = sld->vrot = 0.0f;
+ sld->cx = x;
+ sld->cy = y;
+ sld->ax = sld->ay = sld->arot = 0.0f;
+ sld->an = 0;
+ sld->bf = 0;
+ sld->bpx[0] = -10000;
+ sld->bpx[1] = 10000;
+ sld->bpy[2] = -10000;
+ sld->bpy[3] = 10000;
+ sld->first = cpart - sim->parts;
+ }
+
+ cpart->snext = -1;
+ cpart->sprev = sld->last;
+ if(sld->last != -1)
+ sim->parts[sld->last].snext = cpart - sim->parts;
+ sld->last = cpart - sim->parts;
+ return 1;
+}
+
+Tool_Solid::~Tool_Solid() {}