summaryrefslogtreecommitdiff
path: root/src/simulation/elements
diff options
context:
space:
mode:
Diffstat (limited to 'src/simulation/elements')
-rw-r--r--src/simulation/elements/ACID.cpp10
-rw-r--r--src/simulation/elements/ARAY.cpp2
-rw-r--r--src/simulation/elements/BCOL.cpp2
-rw-r--r--src/simulation/elements/CRAY.cpp5
-rw-r--r--src/simulation/elements/DTEC.cpp26
-rw-r--r--src/simulation/elements/ELEC.cpp3
-rw-r--r--src/simulation/elements/EXOT.cpp58
-rw-r--r--src/simulation/elements/FILT.cpp75
-rw-r--r--src/simulation/elements/PHOT.cpp5
-rw-r--r--src/simulation/elements/PIPE.cpp4
-rw-r--r--src/simulation/elements/PROT.cpp153
-rw-r--r--src/simulation/elements/PRTO.cpp4
-rw-r--r--src/simulation/elements/PSTN.cpp7
-rw-r--r--src/simulation/elements/QRTZ.cpp36
-rw-r--r--src/simulation/elements/SOAP.cpp2
-rw-r--r--src/simulation/elements/VIRS.cpp145
-rw-r--r--src/simulation/elements/VRSG.cpp49
-rw-r--r--src/simulation/elements/VRSS.cpp49
18 files changed, 571 insertions, 64 deletions
diff --git a/src/simulation/elements/ACID.cpp b/src/simulation/elements/ACID.cpp
index e078551..4ea94ff 100644
--- a/src/simulation/elements/ACID.cpp
+++ b/src/simulation/elements/ACID.cpp
@@ -48,7 +48,7 @@ Element_ACID::Element_ACID()
//#TPT-Directive ElementHeader Element_ACID static int update(UPDATE_FUNC_ARGS)
int Element_ACID::update(UPDATE_FUNC_ARGS)
- {
+{
int r, rx, ry, trade, np;
for (rx=-2; rx<3; rx++)
for (ry=-2; ry<3; ry++)
@@ -95,7 +95,7 @@ int Element_ACID::update(UPDATE_FUNC_ARGS)
}
}
}
- for ( trade = 0; trade<2; trade ++)
+ for (trade = 0; trade<2; trade++)
{
rx = rand()%5-2;
ry = rand()%5-2;
@@ -109,8 +109,8 @@ int Element_ACID::update(UPDATE_FUNC_ARGS)
int temp = parts[i].life - parts[r>>8].life;
if (temp==1)
{
- parts[r>>8].life ++;
- parts[i].life --;
+ parts[r>>8].life++;
+ parts[i].life--;
}
else if (temp>0)
{
@@ -126,7 +126,6 @@ int Element_ACID::update(UPDATE_FUNC_ARGS)
//#TPT-Directive ElementHeader Element_ACID static int graphics(GRAPHICS_FUNC_ARGS)
int Element_ACID::graphics(GRAPHICS_FUNC_ARGS)
-
{
int s = cpart->life;
if (s>75) s = 75; //These two should not be here.
@@ -140,5 +139,4 @@ int Element_ACID::graphics(GRAPHICS_FUNC_ARGS)
return 0;
}
-
Element_ACID::~Element_ACID() {}
diff --git a/src/simulation/elements/ARAY.cpp b/src/simulation/elements/ARAY.cpp
index ac28834..16bff2d 100644
--- a/src/simulation/elements/ARAY.cpp
+++ b/src/simulation/elements/ARAY.cpp
@@ -98,7 +98,7 @@ int Element_ARAY::update(UPDATE_FUNC_ARGS)
break;
}
} else if ((r&0xFF)==PT_FILT) {//get color if passed through FILT
- colored = parts[r>>8].ctype;
+ colored = Element_FILT::interactWavelengths(&parts[r>>8], colored);
//this if prevents BRAY from stopping on certain materials
} else if ((r&0xFF)!=PT_STOR && (r&0xFF)!=PT_INWR && ((r&0xFF)!=PT_SPRK || parts[r>>8].ctype!=PT_INWR) && (r&0xFF)!=PT_ARAY && (r&0xFF)!=PT_WIFI && !((r&0xFF)==PT_SWCH && parts[r>>8].life>=10)) {
if (nyy!=0 || nxx!=0) {
diff --git a/src/simulation/elements/BCOL.cpp b/src/simulation/elements/BCOL.cpp
index 3fb85af..cb53f6c 100644
--- a/src/simulation/elements/BCOL.cpp
+++ b/src/simulation/elements/BCOL.cpp
@@ -21,7 +21,7 @@ Element_BCOL::Element_BCOL()
Flammable = 0;
Explosive = 0;
- Meltable = 5;
+ Meltable = 0;
Hardness = 2;
Weight = 90;
diff --git a/src/simulation/elements/CRAY.cpp b/src/simulation/elements/CRAY.cpp
index 2933dcf..002ed28 100644
--- a/src/simulation/elements/CRAY.cpp
+++ b/src/simulation/elements/CRAY.cpp
@@ -96,13 +96,14 @@ int Element_CRAY::update(UPDATE_FUNC_ARGS)
else
nr = sim->create_part(-1, x+nxi+nxx, y+nyi+nyy, parts[i].ctype);
if (nr!=-1) {
- parts[nr].dcolour = colored;
+ if (colored)
+ parts[nr].dcolour = colored;
parts[nr].temp = parts[i].temp;
if(!--partsRemaining)
docontinue = 0;
}
} else if ((r&0xFF)==PT_FILT) { // get color if passed through FILT
- colored = wavelengthToDecoColour(parts[r>>8].ctype);
+ colored = wavelengthToDecoColour(Element_FILT::getWavelengths(&parts[r>>8]));
} else if ((r&0xFF) == PT_CRAY || nostop) {
docontinue = 1;
} else if(destroy && r && ((r&0xFF) != PT_DMND)) {
diff --git a/src/simulation/elements/DTEC.cpp b/src/simulation/elements/DTEC.cpp
index 8ecaf2e..ed894a2 100644
--- a/src/simulation/elements/DTEC.cpp
+++ b/src/simulation/elements/DTEC.cpp
@@ -73,6 +73,7 @@ int Element_DTEC::update(UPDATE_FUNC_ARGS)
}
}
}
+ int photonWl = 0;
for (rx=-rd; rx<rd+1; rx++)
for (ry=-rd; ry<rd+1; ry++)
if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES && (rx || ry))
@@ -84,7 +85,32 @@ int Element_DTEC::update(UPDATE_FUNC_ARGS)
continue;
if (parts[r>>8].type == parts[i].ctype && (parts[i].ctype != PT_LIFE || parts[i].tmp == parts[r>>8].ctype || !parts[i].tmp))
parts[i].life = 1;
+ if (parts[r>>8].type == PT_PHOT)
+ photonWl = parts[r>>8].ctype;
}
+ if (photonWl)
+ {
+ int nx, ny;
+ for (rx=-1; rx<2; rx++)
+ for (ry=-1; ry<2; ry++)
+ if (BOUNDS_CHECK && (rx || ry))
+ {
+ r = pmap[y+ry][x+rx];
+ if (!r)
+ continue;
+ nx = x+rx;
+ ny = y+ry;
+ while ((r&0xFF)==PT_FILT)
+ {
+ parts[r>>8].ctype = photonWl;
+ nx += rx;
+ ny += ry;
+ if (nx<0 || ny<0 || nx>=XRES || ny>=YRES)
+ break;
+ r = pmap[ny][nx];
+ }
+ }
+ }
return 0;
}
diff --git a/src/simulation/elements/ELEC.cpp b/src/simulation/elements/ELEC.cpp
index 8ab4af1..56e90b3 100644
--- a/src/simulation/elements/ELEC.cpp
+++ b/src/simulation/elements/ELEC.cpp
@@ -91,6 +91,7 @@ int Element_ELEC::update(UPDATE_FUNC_ARGS)
sim->create_part(r>>8, x+rx, y+ry, PT_H2);
return 1;
case PT_NEUT:
+ case PT_PROT: // this is the correct reaction, not NEUT, but leaving NEUT in anyway
sim->part_change_type(r>>8, x+rx, y+ry, PT_H2);
parts[r>>8].life = 0;
parts[r>>8].ctype = 0;
@@ -124,8 +125,6 @@ int Element_ELEC::update(UPDATE_FUNC_ARGS)
return 0;
}
-
-
//#TPT-Directive ElementHeader Element_ELEC static int graphics(GRAPHICS_FUNC_ARGS)
int Element_ELEC::graphics(GRAPHICS_FUNC_ARGS)
diff --git a/src/simulation/elements/EXOT.cpp b/src/simulation/elements/EXOT.cpp
index df075e0..e2f6e41 100644
--- a/src/simulation/elements/EXOT.cpp
+++ b/src/simulation/elements/EXOT.cpp
@@ -47,11 +47,13 @@ Element_EXOT::Element_EXOT()
}
//#TPT-Directive ElementHeader Element_EXOT static int update(UPDATE_FUNC_ARGS)
-int Element_EXOT::update(UPDATE_FUNC_ARGS) {
+int Element_EXOT::update(UPDATE_FUNC_ARGS)
+{
int r, rt, rx, ry, nb, rrx, rry, trade, tym;
for (rx=-2; rx<=2; rx++)
for (ry=-2; ry<=2; ry++)
- if (BOUNDS_CHECK && (rx || ry)) {
+ if (BOUNDS_CHECK && (rx || ry))
+ {
r = pmap[y+ry][x+rx];
if (!r)
continue;
@@ -65,11 +67,14 @@ int Element_EXOT::update(UPDATE_FUNC_ARGS) {
}
else if (rt == PT_EXOT)
{
+ if (parts[r>>8].ctype == PT_PROT)
+ parts[i].ctype = PT_PROT;
if (parts[r>>8].life == 1500 && !(rand()%1000))
parts[i].life = 1500;
}
else if (rt == PT_LAVA)
{
+ //turn molten TTAN or molten GOLD to molten VIBR
if (parts[r>>8].ctype == PT_TTAN || parts[r>>8].ctype == PT_GOLD)
{
if (!(rand()%10))
@@ -79,66 +84,71 @@ int Element_EXOT::update(UPDATE_FUNC_ARGS) {
return 1;
}
}
+ //molten VIBR will kill the leftover EXOT though, so the VIBR isn't killed later
else if (parts[r>>8].ctype == PT_VIBR)
{
- if (1>rand()%1000)
+ if (!(rand()%1000))
{
sim->kill_part(i);
return 1;
}
}
}
- if ((parts[i].tmp>245) && (parts[i].life>1000))
+ if (parts[i].tmp > 245 && parts[i].life > 1000)
if (rt!=PT_EXOT && rt!=PT_BREC && rt!=PT_DMND && rt!=PT_CLNE && rt!=PT_PRTI && rt!=PT_PRTO && rt!=PT_PCLN && rt!=PT_VOID && rt!=PT_NBHL && rt!=PT_WARP)
{
sim->create_part(i, x, y, rt);
- return 0;
+ return 1;
}
}
+
parts[i].tmp--;
parts[i].tmp2--;
- if (parts[i].tmp<1 || parts[i].tmp>250)
+ //reset tmp every 250 frames, gives EXOT it's slow flashing effect
+ if (parts[i].tmp < 1 || parts[i].tmp > 250)
parts[i].tmp = 250;
- if (parts[i].tmp2<1)
+
+ if (parts[i].tmp2 < 1)
parts[i].tmp2 = 1;
- else if (parts[i].tmp2>6000)
+ else if (parts[i].tmp2 > 6000)
{
parts[i].tmp2 = 10000;
- if (parts[i].life<1001)
+ if (parts[i].life < 1001)
{
sim->part_change_type(i, x, y, PT_WARP);
return 0;
}
}
- else if(parts[i].life<1001)
+ else if(parts[i].life < 1001)
sim->pv[y/CELL][x/CELL] += (parts[i].tmp2*CFDS)/160000;
+
if (sim->pv[y/CELL][x/CELL]>200 && parts[i].temp>9000 && parts[i].tmp2>200)
{
parts[i].tmp2 = 6000;
sim->part_change_type(i, x, y, PT_WARP);
return 0;
}
- if (parts[i].tmp2>100)
+ if (parts[i].tmp2 > 100)
{
- for ( trade = 0; trade<9; trade ++)
+ for (trade = 0; trade < 9; trade++)
{
rx = rand()%5-2;
ry = rand()%5-2;
- if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry))
+ if (BOUNDS_CHECK && (rx || ry))
{
r = pmap[y+ry][x+rx];
if (!r)
continue;
- if ((r&0xFF)==PT_EXOT && (parts[i].tmp2>parts[r>>8].tmp2) && parts[r>>8].tmp2>=0 )//diffusion
+ if ((r&0xFF)==PT_EXOT && (parts[i].tmp2 > parts[r>>8].tmp2) && parts[r>>8].tmp2 >= 0) //diffusion
{
tym = parts[i].tmp2 - parts[r>>8].tmp2;
- if (tym ==1)
+ if (tym == 1)
{
- parts[r>>8].tmp2 ++;
- parts[i].tmp2 --;
+ parts[r>>8].tmp2++;
+ parts[i].tmp2--;
break;
}
- if (tym>0)
+ if (tym > 0)
{
parts[r>>8].tmp2 += tym/2;
parts[i].tmp2 -= tym/2;
@@ -148,7 +158,17 @@ int Element_EXOT::update(UPDATE_FUNC_ARGS) {
}
}
}
- if (parts[i].temp<273.15f)
+ if (parts[i].ctype == PT_PROT)
+ {
+ if (parts[i].temp < 50.0f)
+ {
+ sim->create_part(i, x, y, PT_CFLM);
+ return 1;
+ }
+ else
+ parts[i].temp -= 1.0f;
+ }
+ else if (parts[i].temp < 273.15f)
{
parts[i].vx = 0;
parts[i].vy = 0;
diff --git a/src/simulation/elements/FILT.cpp b/src/simulation/elements/FILT.cpp
index d6b82f2..8ece142 100644
--- a/src/simulation/elements/FILT.cpp
+++ b/src/simulation/elements/FILT.cpp
@@ -48,21 +48,17 @@ Element_FILT::Element_FILT()
//#TPT-Directive ElementHeader Element_FILT static int graphics(GRAPHICS_FUNC_ARGS)
int Element_FILT::graphics(GRAPHICS_FUNC_ARGS)
-
{
- int x, temp_bin = (int)((cpart->temp-273.0f)*0.025f);
- if (temp_bin < 0) temp_bin = 0;
- if (temp_bin > 25) temp_bin = 25;
- cpart->ctype = 0x1F << temp_bin;
+ int x, wl = Element_FILT::getWavelengths(cpart);
*colg = 0;
*colb = 0;
*colr = 0;
for (x=0; x<12; x++) {
- *colr += (cpart->ctype >> (x+18)) & 1;
- *colb += (cpart->ctype >> x) & 1;
+ *colr += (wl >> (x+18)) & 1;
+ *colb += (wl >> x) & 1;
}
for (x=0; x<12; x++)
- *colg += (cpart->ctype >> (x+9)) & 1;
+ *colg += (wl >> (x+9)) & 1;
x = 624/(*colr+*colg+*colb+1);
*cola = 127;
*colr *= x;
@@ -73,5 +69,68 @@ int Element_FILT::graphics(GRAPHICS_FUNC_ARGS)
return 0;
}
+//#TPT-Directive ElementHeader Element_FILT static int interactWavelengths(Particle* cpart, int origWl)
+// Returns the wavelengths in a particle after FILT interacts with it (e.g. a photon)
+// cpart is the FILT particle, origWl the original wavelengths in the interacting particle
+int Element_FILT::interactWavelengths(Particle* cpart, int origWl)
+{
+ const int mask = 0x3FFFFFFF;
+ int filtWl = getWavelengths(cpart);
+ switch (cpart->tmp)
+ {
+ case 0:
+ return filtWl; //Assign Colour
+ case 1:
+ return origWl & filtWl; //Filter Colour
+ case 2:
+ return origWl | filtWl; //Add Colour
+ case 3:
+ return origWl & (~filtWl); //Subtract colour of filt from colour of photon
+ case 4:
+ {
+ int shift = int((cpart->temp-273.0f)*0.025f);
+ if (shift<=0) shift = 1;
+ return (origWl << shift) & mask; // red shift
+ }
+ case 5:
+ {
+ int shift = int((cpart->temp-273.0f)*0.025f);
+ if (shift<=0) shift = 1;
+ return (origWl >> shift) & mask; // blue shift
+ }
+ case 6:
+ return origWl; // No change
+ case 7:
+ return origWl ^ filtWl; // XOR colours
+ case 8:
+ return (~origWl) & mask; // Invert colours
+ case 9:
+ {
+ int t1, t2, t3, r;
+ t1 = (origWl & 0x0000FF)+(rand()%5)-2;
+ t1 = ((origWl & 0x00FF00)>>8)+(rand()%5)-2;
+ t3 = ((origWl & 0xFF0000)>>16)+(rand()%5)-2;
+ return (origWl & 0xFF000000) | (t3<<16) | (t2<<8) | t1;
+ }
+ default:
+ return filtWl;
+ }
+}
+
+//#TPT-Directive ElementHeader Element_FILT static int getWavelengths(Particle* cpart)
+int Element_FILT::getWavelengths(Particle* cpart)
+{
+ if (cpart->ctype)
+ {
+ return cpart->ctype;
+ }
+ else
+ {
+ int temp_bin = (int)((cpart->temp-273.0f)*0.025f);
+ if (temp_bin < 0) temp_bin = 0;
+ if (temp_bin > 25) temp_bin = 25;
+ return (0x1F << temp_bin);
+ }
+}
Element_FILT::~Element_FILT() {}
diff --git a/src/simulation/elements/PHOT.cpp b/src/simulation/elements/PHOT.cpp
index e132d3d..4fe5bbe 100644
--- a/src/simulation/elements/PHOT.cpp
+++ b/src/simulation/elements/PHOT.cpp
@@ -88,6 +88,11 @@ int Element_PHOT::update(UPDATE_FUNC_ARGS)
parts[i].ctype = 0x1F<<(rand()%26);
parts[i].life++; //Delay death
}
+ else if ((r&0xFF) == PT_FILT && parts[r>>8].tmp==9)
+ {
+ parts[i].vx += ((float)(rand()%1000-500))/1000.0f;
+ parts[i].vy += ((float)(rand()%1000-500))/1000.0f;
+ }
}
return 0;
}
diff --git a/src/simulation/elements/PIPE.cpp b/src/simulation/elements/PIPE.cpp
index 14dbee0..ee1a21a 100644
--- a/src/simulation/elements/PIPE.cpp
+++ b/src/simulation/elements/PIPE.cpp
@@ -71,6 +71,8 @@ int Element_PIPE::update(UPDATE_FUNC_ARGS)
{
int r, rx, ry, np;
int rnd, rndstore;
+ if ((parts[i].tmp&0xFF)>=PT_NUM || !sim->elements[parts[i].tmp&0xFF].Enabled)
+ parts[i].tmp &= ~0xFF;
if (parts[i].tmp & PPIP_TMPFLAG_TRIGGERS)
{
int pause_changed = 0;
@@ -285,7 +287,7 @@ int Element_PIPE::update(UPDATE_FUNC_ARGS)
//#TPT-Directive ElementHeader Element_PIPE static int graphics(GRAPHICS_FUNC_ARGS)
int Element_PIPE::graphics(GRAPHICS_FUNC_ARGS)
{
- if ((cpart->tmp&0xFF)>0 && (cpart->tmp&0xFF)<PT_NUM)
+ if ((cpart->tmp&0xFF)>0 && (cpart->tmp&0xFF)<PT_NUM && ren->sim->elements[(cpart->tmp&0xFF)].Enabled)
{
//Create a temp. particle and do a subcall.
Particle tpart;
diff --git a/src/simulation/elements/PROT.cpp b/src/simulation/elements/PROT.cpp
new file mode 100644
index 0000000..4302244
--- /dev/null
+++ b/src/simulation/elements/PROT.cpp
@@ -0,0 +1,153 @@
+#include "simulation/Elements.h"
+//#TPT-Directive ElementClass Element_PROT PT_PROT 173
+Element_PROT::Element_PROT()
+{
+ Identifier = "DEFAULT_PT_PROT";
+ Name = "PROT";
+ Colour = PIXPACK(0x990000);
+ MenuVisible = 1;
+ MenuSection = SC_NUCLEAR;
+ Enabled = 1;
+
+ Advection = 0.0f;
+ AirDrag = 0.00f * CFDS;
+ AirLoss = 1.00f;
+ Loss = 1.00f;
+ Collision = -.99f;
+ Gravity = 0.0f;
+ Diffusion = 0.00f;
+ HotAir = 0.000f * CFDS;
+ Falldown = 0;
+
+ Flammable = 0;
+ Explosive = 0;
+ Meltable = 0;
+ Hardness = 0;
+
+ Weight = -1;
+
+ Temperature = R_TEMP+273.15f;
+ HeatConduct = 61;
+ Description = "Protons. Transfer heat to materials, and removes sparks.";
+
+ State = ST_GAS;
+ Properties = TYPE_ENERGY|PROP_LIFE_KILL;
+
+ LowPressure = IPL;
+ LowPressureTransition = NT;
+ HighPressure = IPH;
+ HighPressureTransition = NT;
+ LowTemperature = ITL;
+ LowTemperatureTransition = NT;
+ HighTemperature = ITH;
+ HighTemperatureTransition = NT;
+
+ Update = &Element_PROT::update;
+ Graphics = &Element_PROT::graphics;
+}
+
+//#TPT-Directive ElementHeader Element_PROT static int update(UPDATE_FUNC_ARGS)
+int Element_PROT::update(UPDATE_FUNC_ARGS)
+{
+ sim->pv[y/CELL][x/CELL] -= .003f;
+ int under = pmap[y][x];
+ //set off explosives (only when hot because it wasn't as fun when it made an entire save explode)
+ if (parts[i].temp > 273.15f+500.0f && (sim->elements[under&0xFF].Flammable || sim->elements[under&0xFF].Explosive || (under&0xFF) == PT_BANG))
+ {
+ sim->create_part(under>>8, x, y, PT_FIRE);
+ parts[under>>8].temp += restrict_flt(sim->elements[under&0xFF].Flammable*5, MIN_TEMP, MAX_TEMP);
+ sim->pv[y/CELL][x/CELL] += 1.00f;
+ }
+ //remove active sparks
+ else if ((under&0xFF) == PT_SPRK)
+ {
+ sim->part_change_type(under>>8, x, y, parts[under>>8].ctype);
+ parts[under>>8].life = 44+parts[under>>8].life;
+ parts[under>>8].ctype = 0;
+ }
+ //prevent inactive sparkable elements from being sparked
+ else if ((sim->elements[under&0xFF].Properties&PROP_CONDUCTS) && parts[under>>8].life <= 4)
+ {
+ parts[under>>8].life = 40+parts[under>>8].life;
+ }
+ else if ((under&0xFF) == PT_EXOT)
+ parts[under>>8].ctype = PT_PROT;
+
+ //make temp of other things closer to it's own temperature. This will change temp of things that don't conduct, and won't change the PROT's temperature
+ if (under)
+ {
+ if ((under&0xFF) == PT_WIFI || (under&0xFF) == PT_PRTI || (under&0xFF) == PT_PRTO)
+ {
+ float change;
+ if (parts[i].temp<173.15f) change = -1000.0f;
+ else if (parts[i].temp<273.15f) change = -100.0f;
+ else if (parts[i].temp>473.15f) change = 1000.0f;
+ else if (parts[i].temp>373.15f) change = 100.0f;
+ else change = 0.0f;
+ parts[under>>8].temp = restrict_flt(parts[under>>8].temp+change, MIN_TEMP, MAX_TEMP);
+ }
+ else
+ {
+ parts[under>>8].temp = restrict_flt(parts[under>>8].temp-(parts[under>>8].temp-parts[i].temp)/4.0f, MIN_TEMP, MAX_TEMP);
+ }
+ }
+ //else, slowly kill it if it's not inside an element
+ else
+ parts[i].life--;
+
+ //if this proton has collided with another last frame, change it into a heavier element
+ if (parts[i].tmp)
+ {
+ int newID, element;
+ if (parts[i].tmp > 4250)
+ element = PT_SING; //particle accelerators are known to create earth-destroying black holes
+ else if (parts[i].tmp > 275)
+ element = PT_PLUT;
+ else if (parts[i].tmp > 170)
+ element = PT_URAN;
+ else if (parts[i].tmp > 100)
+ element = PT_PLSM;
+ else if (parts[i].tmp > 40)
+ element = PT_O2;
+ else if (parts[i].tmp > 20)
+ element = PT_CO2;
+ else
+ element = PT_NBLE;
+ newID = sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, element);
+ parts[newID].temp = restrict_flt(100.0f*parts[i].tmp, MIN_TEMP, MAX_TEMP);
+ sim->kill_part(i);
+ return 1;
+ }
+ //collide with other protons to make heavier materials
+ int ahead = sim->photons[y][x];
+ if ((ahead>>8) != i && (ahead&0xFF) == PT_PROT)
+ {
+ float velocity1 = powf(parts[i].vx, 2.0f)+powf(parts[i].vy, 2.0f);
+ float velocity2 = powf(parts[ahead>>8].vx, 2.0f)+powf(parts[ahead>>8].vy, 2.0f);
+ float direction1 = atan2f(-parts[i].vy, parts[i].vx);
+ float direction2 = atan2f(-parts[ahead>>8].vy, parts[ahead>>8].vx);
+ float difference = direction1 - direction2; if (difference < 0) difference += 6.28319f;
+
+ if (difference > 3.12659f && difference < 3.15659f && velocity1 + velocity2 > 10.0f)
+ {
+ parts[ahead>>8].tmp += (int)(velocity1 + velocity2);
+ sim->kill_part(i);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+//#TPT-Directive ElementHeader Element_PROT static int graphics(GRAPHICS_FUNC_ARGS)
+int Element_PROT::graphics(GRAPHICS_FUNC_ARGS)
+{
+ *firea = 20;
+ *firer = 250;
+ *fireg = 128;
+ *fireb = 128;
+
+ *pixel_mode |= FIRE_ADD;
+ return 1;
+}
+
+Element_PROT::~Element_PROT() {}
diff --git a/src/simulation/elements/PRTO.cpp b/src/simulation/elements/PRTO.cpp
index 6ec11b4..1eae7ce 100644
--- a/src/simulation/elements/PRTO.cpp
+++ b/src/simulation/elements/PRTO.cpp
@@ -85,7 +85,7 @@ int Element_PRTO::update(UPDATE_FUNC_ARGS)
sim->create_part(-1,x-1,y+1,PT_SPRK);
sim->create_part(-1,x-1,y,PT_SPRK);
sim->create_part(-1,x-1,y-1,PT_SPRK);
- sim->portalp[parts[i].tmp][randomness][nnx] = sim->emptyparticle;
+ memset(&sim->portalp[parts[i].tmp][randomness][nnx], 0, sizeof(Particle));
break;
}
else if (sim->portalp[parts[i].tmp][randomness][nnx].type)
@@ -132,7 +132,7 @@ int Element_PRTO::update(UPDATE_FUNC_ARGS)
parts[np] = sim->portalp[parts[i].tmp][randomness][nnx];
parts[np].x = x+rx;
parts[np].y = y+ry;
- sim->portalp[parts[i].tmp][randomness][nnx] = sim->emptyparticle;
+ memset(&sim->portalp[parts[i].tmp][randomness][nnx], 0, sizeof(Particle));
break;
}
}
diff --git a/src/simulation/elements/PSTN.cpp b/src/simulation/elements/PSTN.cpp
index 6dda77f..998f7a2 100644
--- a/src/simulation/elements/PSTN.cpp
+++ b/src/simulation/elements/PSTN.cpp
@@ -167,7 +167,7 @@ int Element_PSTN::update(UPDATE_FUNC_ARGS)
//#TPT-Directive ElementHeader Element_PSTN static int CanMoveStack(Simulation * sim, int stackX, int stackY, int directionX, int directionY, int maxSize, int amount, bool retract, int block)
int Element_PSTN::CanMoveStack(Simulation * sim, int stackX, int stackY, int directionX, int directionY, int maxSize, int amount, bool retract, int block)
{
- int posX, posY, r, spaces = 0, currentPos = 0;
+ int posX, posY, r, spaces = 0, currentPos = 0, num = 0;
if (amount <= 0)
return 0;
for(posX = stackX, posY = stackY; currentPos < maxSize + amount && currentPos < XRES-1; posX += directionX, posY += directionY) {
@@ -176,7 +176,7 @@ int Element_PSTN::CanMoveStack(Simulation * sim, int stackX, int stackY, int dir
}
r = sim->pmap[posY][posX];
if (sim->IsWallBlocking(posX, posY, 0) || (block && (r&0xFF) == block))
- return spaces;
+ return num;
if(!r) {
spaces++;
tempParts[currentPos++] = -1;
@@ -186,8 +186,9 @@ int Element_PSTN::CanMoveStack(Simulation * sim, int stackX, int stackY, int dir
if(spaces < maxSize && currentPos < maxSize && (!retract || ((r&0xFF) == PT_FRME) && posX == stackX && posY == stackY))
tempParts[currentPos++] = r>>8;
else
- return spaces;
+ return num;
}
+ num++;
}
if (spaces)
return currentPos;
diff --git a/src/simulation/elements/QRTZ.cpp b/src/simulation/elements/QRTZ.cpp
index 5eec6d6..b399662 100644
--- a/src/simulation/elements/QRTZ.cpp
+++ b/src/simulation/elements/QRTZ.cpp
@@ -60,7 +60,7 @@ int Element_QRTZ::update(UPDATE_FUNC_ARGS)
}
}
// absorb SLTW
- if (parts[i].ctype!=-1)
+ if (parts[i].tmp != -1)
for (rx=-1; rx<2; rx++)
for (ry=-1; ry<2; ry++)
if (BOUNDS_CHECK && (rx || ry))
@@ -71,15 +71,15 @@ int Element_QRTZ::update(UPDATE_FUNC_ARGS)
else if ((r&0xFF)==PT_SLTW && !(rand()%500))
{
sim->kill_part(r>>8);
- parts[i].ctype ++;
+ parts[i].tmp++;
}
}
// grow and diffuse
- if (parts[i].ctype>0)
+ if (parts[i].tmp > 0)
{
- bool stopgrow=false;
+ bool stopgrow = false;
int rnd, sry, srx;
- for ( trade = 0; trade<9; trade ++)
+ for (trade = 0; trade < 9; trade++)
{
rnd = rand()%0x3FF;
rx = (rnd%5)-2;
@@ -91,20 +91,20 @@ int Element_QRTZ::update(UPDATE_FUNC_ARGS)
{
if (!stopgrow)//try to grow
{
- if (!pmap[y+sry][x+srx] && parts[i].ctype!=0)
+ if (!pmap[y+sry][x+srx] && parts[i].tmp!=0)
{
np = sim->create_part(-1,x+srx,y+sry,PT_QRTZ);
if (np>-1)
{
- parts[np].tmp = parts[i].tmp;
- parts[i].ctype--;
+ parts[np].tmp2 = parts[i].tmp2;
+ parts[i].tmp--;
if (rand()%2)
{
- parts[np].ctype=-1;//dead qrtz
+ parts[np].tmp=-1;//dead qrtz
}
- else if (!parts[i].ctype && !(rand()%15))
+ else if (!parts[i].tmp && !(rand()%15))
{
- parts[i].ctype=-1;
+ parts[i].tmp=-1;
}
stopgrow=true;
}
@@ -114,19 +114,19 @@ int Element_QRTZ::update(UPDATE_FUNC_ARGS)
r = pmap[y+ry][x+rx];
if (!r)
continue;
- else if ((r&0xFF)==PT_QRTZ && (parts[i].ctype>parts[r>>8].ctype) && parts[r>>8].ctype>=0)
+ else if ((r&0xFF)==PT_QRTZ && (parts[i].tmp>parts[r>>8].tmp) && parts[r>>8].tmp>=0)
{
- tmp = parts[i].ctype - parts[r>>8].ctype;
+ tmp = parts[i].tmp - parts[r>>8].tmp;
if (tmp ==1)
{
- parts[r>>8].ctype ++;
- parts[i].ctype --;
+ parts[r>>8].tmp++;
+ parts[i].tmp--;
break;
}
if (tmp>0)
{
- parts[r>>8].ctype += tmp/2;
- parts[i].ctype -= tmp/2;
+ parts[r>>8].tmp += tmp/2;
+ parts[i].tmp -= tmp/2;
break;
}
}
@@ -141,7 +141,7 @@ int Element_QRTZ::update(UPDATE_FUNC_ARGS)
int Element_QRTZ::graphics(GRAPHICS_FUNC_ARGS)
//QRTZ and PQRT
{
- int t = cpart->type, z = cpart->tmp - 5;//speckles!
+ int t = cpart->type, z = cpart->tmp2 - 5;//speckles!
/*if (cpart->temp>(ptransitions[t].thv-800.0f))//hotglow for quartz
{
float frequency = 3.1415/(2*ptransitions[t].thv-(ptransitions[t].thv-800.0f));
diff --git a/src/simulation/elements/SOAP.cpp b/src/simulation/elements/SOAP.cpp
index de7055d..fb88287 100644
--- a/src/simulation/elements/SOAP.cpp
+++ b/src/simulation/elements/SOAP.cpp
@@ -28,7 +28,7 @@ Element_SOAP::Element_SOAP()
Temperature = R_TEMP-2.0f +273.15f;
HeatConduct = 29;
- Description = "Soap. Creates bubbles. Washes off deco color.";
+ Description = "Soap. Creates bubbles, washes off deco color, and cures virus.";
State = ST_LIQUID;
Properties = TYPE_LIQUID|PROP_NEUTPENETRATE|PROP_LIFE_DEC;
diff --git a/src/simulation/elements/VIRS.cpp b/src/simulation/elements/VIRS.cpp
new file mode 100644
index 0000000..a4a8800
--- /dev/null
+++ b/src/simulation/elements/VIRS.cpp
@@ -0,0 +1,145 @@
+#include "simulation/Elements.h"
+//#TPT-Directive ElementClass Element_VIRS PT_VIRS 174
+Element_VIRS::Element_VIRS()
+{
+ Identifier = "DEFAULT_PT_VIRS";
+ Name = "VIRS";
+ Colour = PIXPACK(0xFE11F6);
+ MenuVisible = 1;
+ MenuSection = SC_LIQUID;
+ Enabled = 1;
+
+ Advection = 0.6f;
+ AirDrag = 0.01f * CFDS;
+ AirLoss = 0.98f;
+ Loss = 0.95f;
+ Collision = 0.0f;
+ Gravity = 0.1f;
+ Diffusion = 0.00f;
+ HotAir = 0.000f * CFDS;
+ Falldown = 2;
+
+ Flammable = 100;
+ Explosive = 0;
+ Meltable = 0;
+ Hardness = 20;
+
+ Weight = 31;
+
+ Temperature = 72.0f + 273.15f;
+ HeatConduct = 251;
+ Description = "Virus. Turns everything it touches into virus.";
+
+ State = ST_LIQUID;
+ Properties = TYPE_LIQUID|PROP_DEADLY;
+
+ LowPressure = IPL;
+ LowPressureTransition = NT;
+ HighPressure = IPH;
+ HighPressureTransition = NT;
+ LowTemperature = 305.0f;
+ LowTemperatureTransition = PT_VRSS;
+ HighTemperature = 673.0f;
+ HighTemperatureTransition = PT_VRSG;
+
+ Update = &Element_VIRS::update;
+
+}
+
+//#TPT-Directive ElementHeader Element_VIRS static int update(UPDATE_FUNC_ARGS)
+int Element_VIRS::update(UPDATE_FUNC_ARGS)
+{
+ //pavg[0] measures how many frames until it is cured (0 if still actively spreading and not being cured)
+ //pavg[1] measures how many frames until it dies
+ int r, rx, ry, rndstore = rand();
+ if (parts[i].pavg[0])
+ {
+ parts[i].pavg[0] -= (rndstore&0x1) ? 0:1;
+ //has been cured, so change back into the original element
+ if (!parts[i].pavg[0])
+ {
+ sim->part_change_type(i,x,y,parts[i].tmp2);
+ parts[i].tmp2 = 0;
+ parts[i].pavg[0] = 0;
+ parts[i].pavg[1] = 0;
+ return 0;
+ }
+ }
+ //decrease pavg[1] so it slowly dies
+ if (parts[i].pavg[1] > 0)
+ {
+ if (((rndstore>>1)&0xD) < 1)
+ {
+ parts[i].pavg[1]--;
+ //if pavg[1] is now 0 and it's not in the process of being cured, kill it
+ if (!parts[i].pavg[1] && !parts[i].pavg[0])
+ {
+ sim->kill_part(i);
+ return 1;
+ }
+ }
+ }
+
+ //none of the things in the below loop happen while virus is being cured
+ if (parts[i].pavg[0])
+ return 0;
+
+ for (rx=-1; rx<2; rx++)
+ {
+ //reset rndstore, one random can last through 3 locations and reduce rand() calling by up to 6x as much
+ rndstore = rand();
+ for (ry=-1; ry<2; ry++)
+ {
+ if (BOUNDS_CHECK && (rx || ry))
+ {
+ r = pmap[y+ry][x+rx];
+ if (!r)
+ continue;
+
+ //spread "being cured" state
+ if (((r&0xFF) == PT_VIRS || (r&0xFF) == PT_VRSS || (r&0xFF) == PT_VRSG) && parts[r>>8].pavg[0])
+ {
+ parts[i].pavg[0] = parts[r>>8].pavg[0] + (((rndstore&0x7)>>1) ? 2:1);
+ rndstore = rndstore >> 3;
+ return 0;
+ }
+ //soap cures virus
+ else if ((r&0xFF) == PT_SOAP)
+ {
+ parts[i].pavg[0] += 10;
+ if (!((rndstore&0x7)>>1))
+ sim->kill_part(r>>8);
+ return 0;
+ }
+ //transforms things into virus here
+ else if ((r&0xFF) != PT_VIRS && (r&0xFF) != PT_VRSS && (r&0xFF) != PT_VRSG && (r&0xFF) != PT_DMND)
+ {
+ if (!((rndstore&0xF)>>1))
+ {
+ parts[r>>8].tmp2 = (r&0xFF);
+ parts[r>>8].pavg[0] = 0;
+ if (parts[i].pavg[1])
+ parts[r>>8].pavg[1] = parts[i].pavg[1] + ((rndstore>>4) ? 1:0);
+ else
+ parts[r>>8].pavg[1] = 0;
+ if (parts[r>>8].temp < 305.0f)
+ sim->part_change_type(r>>8,x,y,PT_VRSS);
+ else if (parts[r>>8].temp > 673.0f)
+ sim->part_change_type(r>>8,x,y,PT_VRSG);
+ else
+ sim->part_change_type(r>>8,x,y,PT_VIRS);
+ }
+ rndstore = rndstore >> 5;
+ }
+ //protons make VIRS last forever
+ else if ((sim->photons[y+ry][x+rx]&0xFF) == PT_PROT)
+ {
+ parts[i].pavg[1] = 0;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+Element_VIRS::~Element_VIRS() {}
diff --git a/src/simulation/elements/VRSG.cpp b/src/simulation/elements/VRSG.cpp
new file mode 100644
index 0000000..8c699d7
--- /dev/null
+++ b/src/simulation/elements/VRSG.cpp
@@ -0,0 +1,49 @@
+#include "simulation/Elements.h"
+//#TPT-Directive ElementClass Element_VRSG PT_VRSG 176
+Element_VRSG::Element_VRSG()
+{
+ Identifier = "DEFAULT_PT_VRSG";
+ Name = "VRSG";
+ Colour = PIXPACK(0xFE68FE);
+ MenuVisible = 0;
+ MenuSection = SC_GAS;
+ Enabled = 1;
+
+ Advection = 1.0f;
+ AirDrag = 0.01f * CFDS;
+ AirLoss = 0.99f;
+ Loss = 0.30f;
+ Collision = -0.1f;
+ Gravity = 0.0f;
+ Diffusion = 0.75f;
+ HotAir = 0.000f * CFDS;
+ Falldown = 0;
+
+ Flammable = 500;
+ Explosive = 0;
+ Meltable = 0;
+ Hardness = 0;
+
+ Weight = 1;
+
+ Temperature = 522.0f + 273.15f;
+ HeatConduct = 251;
+ Description = "Gas Virus. Turns everything it touches into virus.";
+
+ State = ST_GAS;
+ Properties = TYPE_GAS|PROP_DEADLY;
+
+ LowPressure = IPL;
+ LowPressureTransition = NT;
+ HighPressure = IPH;
+ HighPressureTransition = NT;
+ LowTemperature = 673.0f;
+ LowTemperatureTransition = PT_VIRS;
+ HighTemperature = ITH;
+ HighTemperatureTransition = NT;
+
+ Update = &Element_VIRS::update;
+
+}
+
+Element_VRSG::~Element_VRSG() {}
diff --git a/src/simulation/elements/VRSS.cpp b/src/simulation/elements/VRSS.cpp
new file mode 100644
index 0000000..903a5f7
--- /dev/null
+++ b/src/simulation/elements/VRSS.cpp
@@ -0,0 +1,49 @@
+#include "simulation/Elements.h"
+//#TPT-Directive ElementClass Element_VRSS PT_VRSS 175
+Element_VRSS::Element_VRSS()
+{
+ Identifier = "DEFAULT_PT_VRSS";
+ Name = "VRSS";
+ Colour = PIXPACK(0xD408CD);
+ MenuVisible = 0;
+ MenuSection = SC_SOLIDS;
+ Enabled = 1;
+
+ Advection = 0.0f;
+ AirDrag = 0.00f * CFDS;
+ AirLoss = 0.90f;
+ Loss = 0.00f;
+ Collision = 0.0f;
+ Gravity = 0.0f;
+ Diffusion = 0.00f;
+ HotAir = 0.000f * CFDS;
+ Falldown = 0;
+
+ Flammable = 5;
+ Explosive = 0;
+ Meltable = 0;
+ Hardness = 1;
+
+ Weight = 100;
+
+ Temperature = R_TEMP+ 273.15f;
+ HeatConduct = 251;
+ Description = "Solid Virus. Turns everything it touches into virus.";
+
+ State = ST_SOLID;
+ Properties = TYPE_SOLID|PROP_DEADLY;
+
+ LowPressure = IPL;
+ LowPressureTransition = NT;
+ HighPressure = IPH;
+ HighPressureTransition = NT;
+ LowTemperature = ITL;
+ LowTemperatureTransition = NT;
+ HighTemperature = 305.0f;
+ HighTemperatureTransition = PT_VIRS;
+
+ Update = &Element_VIRS::update;
+
+}
+
+Element_VRSS::~Element_VRSS() {}