diff options
| author | Simon Robertshaw <simon@hardwired.org.uk> | 2012-01-17 20:46:06 (GMT) |
|---|---|---|
| committer | Simon Robertshaw <simon@hardwired.org.uk> | 2012-01-17 20:46:06 (GMT) |
| commit | 4a60b97c700c2f1843b7e99313554cb89fb5da4e (patch) | |
| tree | 3b33ef6f74a4e8a4ff5968a81b9c4c429ccaa7c6 /src/elements | |
| parent | 6273089bf486bf46ad325d72c7290ebb272bd3d8 (diff) | |
| download | powder-4a60b97c700c2f1843b7e99313554cb89fb5da4e.zip powder-4a60b97c700c2f1843b7e99313554cb89fb5da4e.tar.gz | |
Some minor changes
Diffstat (limited to 'src/elements')
98 files changed, 6532 insertions, 0 deletions
diff --git a/src/elements/O2.cpp b/src/elements/O2.cpp new file mode 100644 index 0000000..78b4229 --- /dev/null +++ b/src/elements/O2.cpp @@ -0,0 +1,30 @@ +#include "element.h" + +int update_O2(UPDATE_FUNC_ARGS) +{ + int r,rx,ry; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + + if ((r&0xFF)==PT_FIRE) + { + parts[r>>8].temp+=(rand()/(RAND_MAX/100)); + if(parts[r>>8].tmp&0x01) + parts[r>>8].temp=3473; + parts[r>>8].tmp |= 2; + } + if ((r&0xFF)==PT_FIRE || (r&0xFF)==PT_PLSM) + { + sim->create_part(i,x,y,PT_FIRE); + parts[i].temp+=(rand()/(RAND_MAX/100)); + parts[i].tmp |= 2; + } + + } + return 0; +} diff --git a/src/elements/acel.cpp b/src/elements/acel.cpp new file mode 100644 index 0000000..7ab9684 --- /dev/null +++ b/src/elements/acel.cpp @@ -0,0 +1,58 @@ +#include "element.h" + +int update_ACEL(UPDATE_FUNC_ARGS) { + int r, rx, ry; + parts[i].tmp = 0; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry) && !(rx && ry)) + { + r = pmap[y+ry][x+rx]; + if(!r) + r = sim->photons[y+ry][x+rx]; + if ((r>>8)>=NPART || !r) + continue; + if(sim->ptypes[r&0xFF].properties & (TYPE_PART | TYPE_LIQUID | TYPE_GAS | TYPE_ENERGY)) + { + parts[r>>8].vx *= 1.1f; + parts[r>>8].vy *= 1.1f; + parts[i].tmp = 1; + } + } + return 0; +} + +int graphics_ACEL(GRAPHICS_FUNC_ARGS) +{ + if(cpart->tmp) + *pixel_mode |= PMODE_GLOW; + return 0; +} +int update_DCEL(UPDATE_FUNC_ARGS) { + int r, rx, ry; + parts[i].tmp = 0; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry) && !(rx && ry)) + { + r = pmap[y+ry][x+rx]; + if(!r) + r = sim->photons[y+ry][x+rx]; + if ((r>>8)>=NPART || !r) + continue; + if(sim->ptypes[r&0xFF].properties & (TYPE_PART | TYPE_LIQUID | TYPE_GAS | TYPE_ENERGY)) + { + parts[r>>8].vx *= 0.9f; + parts[r>>8].vy *= 0.9f; + parts[i].tmp = 1; + } + } + return 0; +} + +int graphics_DCEL(GRAPHICS_FUNC_ARGS) +{ + if(cpart->tmp) + *pixel_mode |= PMODE_GLOW; + return 0; +} diff --git a/src/elements/acid.cpp b/src/elements/acid.cpp new file mode 100644 index 0000000..3a72b9d --- /dev/null +++ b/src/elements/acid.cpp @@ -0,0 +1,76 @@ +#include "element.h" + +int update_ACID(UPDATE_FUNC_ARGS) { + int r, rx, ry, trade, np; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_ACID && (r&0xFF)!=PT_CAUS) + { + if ((r&0xFF)==PT_PLEX || (r&0xFF)==PT_NITR || (r&0xFF)==PT_GUNP || (r&0xFF)==PT_RBDM || (r&0xFF)==PT_LRBD) + { + sim->part_change_type(i,x,y,PT_FIRE); + sim->part_change_type(r>>8,x+rx,y+ry,PT_FIRE); + parts[i].life = 4; + parts[r>>8].life = 4; + } + else if ((r&0xFF)==PT_WTRV) + { + if(!(rand()%250)) + { + sim->part_change_type(i, x, y, PT_CAUS); + parts[i].life = (rand()%50)+25; + sim->kill_part(r>>8); + } + } + else if (((r&0xFF)!=PT_CLNE && (r&0xFF)!=PT_PCLN && sim->ptypes[r&0xFF].hardness>(rand()%1000))&&parts[i].life>=50) + { + if (sim->parts_avg(i, r>>8,PT_GLAS)!= PT_GLAS)//GLAS protects stuff from acid + { + float newtemp = ((60.0f-(float)sim->ptypes[r&0xFF].hardness))*7.0f; + if(newtemp < 0){ + newtemp = 0; + } + parts[i].temp += newtemp; + parts[i].life--; + sim->kill_part(r>>8); + } + } + else if (parts[i].life<=50) + { + sim->kill_part(i); + return 1; + } + } + } + for ( trade = 0; trade<2; trade ++) + { + rx = rand()%5-2; + ry = rand()%5-2; + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if ((r>>8)>=NPART || !r) + continue; + if ((r&0xFF)==PT_ACID&&(parts[i].life>parts[r>>8].life)&&parts[i].life>0)//diffusion + { + int temp = parts[i].life - parts[r>>8].life; + if (temp ==1) + { + parts[r>>8].life ++; + parts[i].life --; + } + else if (temp>0) + { + parts[r>>8].life += temp/2; + parts[i].life -= temp/2; + } + } + } + } + return 0; +} diff --git a/src/elements/amtr.cpp b/src/elements/amtr.cpp new file mode 100644 index 0000000..d119cc9 --- /dev/null +++ b/src/elements/amtr.cpp @@ -0,0 +1,28 @@ +#include "element.h" + +int update_AMTR(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_AMTR && (r&0xFF)!=PT_DMND && (r&0xFF)!=PT_CLNE && (r&0xFF)!=PT_PCLN && (r&0xFF)!=PT_NONE && (r&0xFF)!=PT_PHOT && (r&0xFF)!=PT_VOID && (r&0xFF)!=PT_BHOL && (r&0xFF)!=PT_NBHL && (r&0xFF)!=PT_PRTI && (r&0xFF)!=PT_PRTO) + { + parts[i].life++; + if (parts[i].life==4) + { + sim->kill_part(i); + return 1; + } + if (10>(rand()/(RAND_MAX/100))) + sim->create_part(r>>8, x+rx, y+ry, PT_PHOT); + else + sim->kill_part(r>>8); + sim->pv[y/CELL][x/CELL] -= 2.0f; + } + } + return 0; +} diff --git a/src/elements/anar.cpp b/src/elements/anar.cpp new file mode 100644 index 0000000..83eaf5a --- /dev/null +++ b/src/elements/anar.cpp @@ -0,0 +1,27 @@ +#include "element.h" + +int update_ANAR(UPDATE_FUNC_ARGS) { + int r, rx, ry; + + //if (parts[i].temp >= 0.23) + // parts[i].temp --; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_HFLM) + { + if (1>rand()%22) + { + sim->part_change_type(i,x,y,PT_HFLM); + parts[i].life = rand()%150+50; + parts[r>>8].temp = parts[i].temp = 0; + sim->pv[y/CELL][x/CELL] -= 0.5; + } + } + } + return 0; +} diff --git a/src/elements/aray.cpp b/src/elements/aray.cpp new file mode 100644 index 0000000..65b0d53 --- /dev/null +++ b/src/elements/aray.cpp @@ -0,0 +1,104 @@ +#include "element.h" + +int update_ARAY(UPDATE_FUNC_ARGS) { + int r, nxx, nyy, docontinue, nxi, nyi, rx, ry, nr, ry1, rx1; + if (parts[i].life==0) { + int colored =0; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_SPRK) { + int destroy = (parts[r>>8].ctype==PT_PSCN)?1:0; + int nostop = (parts[r>>8].ctype==PT_INST)?1:0; + for (docontinue = 1, nxx = 0, nyy = 0, nxi = rx*-1, nyi = ry*-1; docontinue; nyy+=nyi, nxx+=nxi) { + if (!(x+nxi+nxx<XRES && y+nyi+nyy<YRES && x+nxi+nxx >= 0 && y+nyi+nyy >= 0)) { + break; + } + r = pmap[y+nyi+nyy][x+nxi+nxx]; + if (!r) { + int nr = sim->create_part(-1, x+nxi+nxx, y+nyi+nyy, PT_BRAY); + if (nr!=-1) { + if (destroy) {//if it came from PSCN + parts[nr].tmp = 2; + parts[nr].life = 2; + } else + parts[nr].ctype = colored; + parts[nr].temp = parts[i].temp; + } + } else if (!destroy) { + if ((r&0xFF)==PT_BRAY&&parts[r>>8].tmp==0) {//if it hits another BRAY that isn't red + if (nyy!=0 || nxx!=0) { + parts[r>>8].life = 1020;//makes it last a while + parts[r>>8].tmp = 1; + if (!parts[r>>8].ctype)//and colors it if it isn't already + parts[r>>8].ctype = colored; + } + docontinue = 0;//then stop it + } else if ((r&0xFF)==PT_BRAY&&parts[r>>8].tmp==1) {//if it hits one that already was a long life, reset it + parts[r>>8].life = 1020; + //docontinue = 1; + } else if ((r&0xFF)==PT_FILT) {//get color if passed through FILT + colored = parts[r>>8].ctype; + //this if prevents BRAY from stopping on certain materials + } else if ((r&0xFF)!=PT_STOR && (r&0xFF)!=PT_INWR && (r&0xFF)!=PT_ARAY && (r&0xFF)!=PT_WIFI && !((r&0xFF)==PT_SWCH && parts[r>>8].life>=10)) { + if (nyy!=0 || nxx!=0) { + sim->create_part(-1, x+nxi+nxx, y+nyi+nyy, PT_SPRK); + } + //if (!(nostop && (ptypes[r&0xFF].properties&PROP_CONDUCTS))) { + if (!(nostop && parts[r>>8].ctype >= 0 && parts[r>>8].ctype < PT_NUM && (sim->ptypes[parts[r>>8].ctype].properties&PROP_CONDUCTS))) { + docontinue = 0; + } else { + docontinue = 1; + } + } else if((r&0xFF)==PT_STOR) { + if(parts[r>>8].tmp) + { + //Cause STOR to release + for(ry1 = 1; ry1 >= -1; ry1--){ + for(rx1 = 0; rx1 >= -1 && rx1 <= 1; rx1 = -rx1-rx1+1){ + int np = sim->create_part(-1, x+nxi+nxx+rx1, y+nyi+nyy+ry1, parts[r>>8].tmp); + if (np!=-1) + { + parts[np].temp = parts[r>>8].temp; + parts[np].life = parts[r>>8].flags; + parts[np].tmp = parts[r>>8].pavg[0]; + parts[np].ctype = parts[r>>8].pavg[1]; + parts[r>>8].tmp = 0; + parts[r>>8].life = 10; + break; + } + } + } + } + else + { + parts[r>>8].life = 10; + } + } + } else if (destroy) { + if ((r&0xFF)==PT_BRAY) { + parts[r>>8].life = 1; + docontinue = 1; + //this if prevents red BRAY from stopping on certain materials + } else if ((r&0xFF)==PT_STOR || (r&0xFF)==PT_INWR || (r&0xFF)==PT_ARAY || (r&0xFF)==PT_WIFI || (r&0xFF)==PT_FILT || ((r&0xFF)==PT_SWCH && parts[r>>8].life>=10)) { + if((r&0xFF)==PT_STOR) + { + parts[r>>8].tmp = 0; + parts[r>>8].life = 0; + } + docontinue = 1; + } else { + docontinue = 0; + } + } + } + } + //parts[i].life = 4; + } + } + return 0; +} diff --git a/src/elements/bang.cpp b/src/elements/bang.cpp new file mode 100644 index 0000000..658a567 --- /dev/null +++ b/src/elements/bang.cpp @@ -0,0 +1,75 @@ +#include "element.h" + +int update_BANG(UPDATE_FUNC_ARGS) { + int r, rx, ry, nb; + if(parts[i].tmp==0) + { + if(parts[i].temp>=673.0f) + parts[i].tmp = 1; + else + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_FIRE || (r&0xFF)==PT_PLSM) + { + parts[i].tmp = 1; + } + else if ((r&0xFF)==PT_SPRK || (r&0xFF)==PT_LIGH) + { + parts[i].tmp = 1; + } + } + + } + else if(parts[i].tmp==1) + { + int tempvalue = 2; + sim->flood_prop(x, y, offsetof(Particle, tmp), &tempvalue, 0); + } + else if(parts[i].tmp==2) + { + parts[i].tmp = 3; + } + else if(parts[i].tmp>=3) + { + float otemp = parts[i].temp-275.13f; + //Explode!! + sim->pv[y/CELL][x/CELL] += 0.5f; + parts[i].tmp = 0; + if(!(rand()%3)) + { + if(!(rand()%2)) + { + sim->create_part(i, x, y, PT_FIRE); + parts[i].temp = restrict_flt((MAX_TEMP/4)+otemp, MIN_TEMP, MAX_TEMP); + } + else + { + sim->create_part(i, x, y, PT_SMKE); + parts[i].temp = restrict_flt((MAX_TEMP/4)+otemp, MIN_TEMP, MAX_TEMP); + } + } + else + { + if(!(rand()%15)) + { + sim->create_part(i, x, y, PT_BOMB); + parts[i].tmp = 1; + parts[i].life = 50; + parts[i].temp = restrict_flt((MAX_TEMP/3)+otemp, MIN_TEMP, MAX_TEMP); + parts[i].vx = rand()%20-10; + parts[i].vy = rand()%20-10; + } + else + { + sim->kill_part(i); + } + } + return 1; + } + return 0; +} diff --git a/src/elements/bcln.cpp b/src/elements/bcln.cpp new file mode 100644 index 0000000..8c00f95 --- /dev/null +++ b/src/elements/bcln.cpp @@ -0,0 +1,40 @@ +#include "element.h" + +int update_BCLN(UPDATE_FUNC_ARGS) { + if (!parts[i].life && sim->pv[y/CELL][x/CELL]>4.0f) + parts[i].life = rand()%40+80; + if (parts[i].life) + { + float advection = 0.1f; + parts[i].vx += advection*sim->vx[y/CELL][x/CELL]; + parts[i].vy += advection*sim->vy[y/CELL][x/CELL]; + } + if (parts[i].ctype<=0 || parts[i].ctype>=PT_NUM || (parts[i].ctype==PT_LIFE && (parts[i].tmp<0 || parts[i].tmp>=NGOLALT))) + { + int r, rx, ry; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES) + { + r = sim->photons[y+ry][x+rx]; + if (!r) + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_CLNE && (r&0xFF)!=PT_PCLN && + (r&0xFF)!=PT_BCLN && (r&0xFF)!=PT_STKM && + (r&0xFF)!=PT_STKM2 && (r&0xFF)!=PT_PBCN && + (r&0xFF)<PT_NUM) + { + parts[i].ctype = r&0xFF; + if ((r&0xFF)==PT_LIFE) + parts[i].tmp = parts[r>>8].ctype; + } + } + } + else { + if (parts[i].ctype==PT_LIFE) sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, parts[i].ctype|(parts[i].tmp<<8)); + else sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, parts[i].ctype); + } + return 0; +} diff --git a/src/elements/bcol.cpp b/src/elements/bcol.cpp new file mode 100644 index 0000000..d941508 --- /dev/null +++ b/src/elements/bcol.cpp @@ -0,0 +1,68 @@ +#include "element.h" + +int update_BCOL(UPDATE_FUNC_ARGS) { + int r, rx, ry, trade, temp; + if (parts[i].life<=0) { + sim->create_part(i, x, y, PT_FIRE); + return 1; + } else if (parts[i].life < 100) { + parts[i].life--; + sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, PT_FIRE); + } + + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_FIRE || (r&0xFF)==PT_PLSM) && 1>(rand()%500)) + { + if (parts[i].life>100) { + parts[i].life = 99; + } + } + if ((r&0xFF)==PT_LAVA && 1>(rand()%500)) + { + if (parts[r>>8].ctype == PT_IRON) { + parts[r>>8].ctype = PT_METL; + sim->kill_part(i); + return 1; + } + } + } + /*if(100-parts[i].life > parts[i].tmp2) + parts[i].tmp2 = 100-parts[i].life; + if(parts[i].tmp2 < 0) parts[i].tmp2 = 0; + for ( trade = 0; trade<4; trade ++) + { + rx = rand()%5-2; + ry = rand()%5-2; + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_COAL || (r&0xFF)==PT_BCOL)&&(parts[i].tmp2>parts[r>>8].tmp2)&&parts[i].tmp2>0)//diffusion + { + int temp = parts[i].tmp2 - parts[r>>8].tmp2; + if(temp < 10) + continue; + if (temp ==1) + { + parts[r>>8].tmp2 ++; + parts[i].tmp2 --; + } + else if (temp>0) + { + parts[r>>8].tmp2 += temp/2; + parts[i].tmp2 -= temp/2; + } + } + } + }*/ + if(parts[i].temp > parts[i].tmp2) + parts[i].tmp2 = parts[i].temp; + return 0; +} diff --git a/src/elements/bizr.cpp b/src/elements/bizr.cpp new file mode 100644 index 0000000..538b87f --- /dev/null +++ b/src/elements/bizr.cpp @@ -0,0 +1,44 @@ +#include "element.h" + +//Used by ALL 3 BIZR states +int update_BIZR(UPDATE_FUNC_ARGS) { + int r, rx, ry, nr, ng, nb, na; + float tr, tg, tb, ta, mr, mg, mb, ma; + float blend; + if(parts[i].dcolour){ + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_BIZR && (r&0xFF)!=PT_BIZRG && (r&0xFF)!=PT_BIZRS) + { + blend = 0.95f; + tr = (parts[r>>8].dcolour>>16)&0xFF; + tg = (parts[r>>8].dcolour>>8)&0xFF; + tb = (parts[r>>8].dcolour)&0xFF; + ta = (parts[r>>8].dcolour>>24)&0xFF; + + mr = (parts[i].dcolour>>16)&0xFF; + mg = (parts[i].dcolour>>8)&0xFF; + mb = (parts[i].dcolour)&0xFF; + ma = (parts[i].dcolour>>24)&0xFF; + + nr = (tr*blend) + (mr*(1-blend)); + ng = (tg*blend) + (mg*(1-blend)); + nb = (tb*blend) + (mb*(1-blend)); + na = (ta*blend) + (ma*(1-blend)); + + parts[r>>8].dcolour = nr<<16 | ng<<8 | nb | na<<24; + } + } + } + if(((r = sim->photons[y][x])&0xFF)==PT_PHOT || ((r = pmap[y][x])&0xFF)==PT_PHOT) + { + sim->part_change_type(r>>8, x, y, PT_ELEC); + parts[r>>8].ctype = 0; + } + return 0; +} diff --git a/src/elements/bmtl.cpp b/src/elements/bmtl.cpp new file mode 100644 index 0000000..a3dc4b8 --- /dev/null +++ b/src/elements/bmtl.cpp @@ -0,0 +1,29 @@ +#include "element.h" + +int update_BMTL(UPDATE_FUNC_ARGS) { + int r, rx, ry, rt, tempFactor; + if (parts[i].tmp>1) + { + parts[i].tmp--; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + rt = parts[r>>8].type; + if ((rt==PT_METL || rt==PT_IRON) && 1>(rand()/(RAND_MAX/100))) + { + sim->part_change_type(r>>8,x+rx,y+ry,PT_BMTL); + parts[r>>8].tmp=(parts[i].tmp<=7)?parts[i].tmp=1:parts[i].tmp-(rand()%5);//rand()/(RAND_MAX/300)+100; + } + } + } + else if (parts[i].tmp==1 && 1>rand()%1000) + { + parts[i].tmp = 0; + sim->part_change_type(i,x,y,PT_BRMT); + } + return 0; +} diff --git a/src/elements/bomb.cpp b/src/elements/bomb.cpp new file mode 100644 index 0000000..b2e9e7d --- /dev/null +++ b/src/elements/bomb.cpp @@ -0,0 +1,85 @@ +#include "element.h" + +int update_BOMB(UPDATE_FUNC_ARGS) { + int r, rx, ry, nb; + //Spark is used so much now that it should be a seperate element. + if (parts[i].tmp==1) { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (sim->ptypes[r&0xFF].properties & (TYPE_SOLID | TYPE_PART | TYPE_LIQUID) && !(sim->ptypes[r&0xFF].properties & PROP_SPARKSETTLE)) { + sim->kill_part(i); + return 1; + } + } + } else if (parts[i].tmp==0) { + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_BOMB && (r&0xFF)!=PT_DMND && (r&0xFF)!=PT_CLNE && (r&0xFF)!=PT_PCLN && (r&0xFF)!=PT_BCLN) { + int rad = 8; + int nxi; + int nxj; + pmap[y][x] = 0; + for (nxj=-(rad+1); nxj<=(rad+1); nxj++) + for (nxi=-(rad+1); nxi<=(rad+1); nxi++) + if ((pow(nxi,2))/(pow((rad+1),2))+(pow(nxj,2))/(pow((rad+1),2))<=1) { + nb = sim->create_part(-1, x+nxi, y+nxj, PT_BOMB); + if (nb!=-1) { + parts[nb].tmp = 1; + parts[nb].life = 50; + parts[nb].temp = MAX_TEMP; + parts[nb].vx = rand()%20-10; + parts[nb].vy = rand()%20-10; + } + } + for (nxj=-rad; nxj<=rad; nxj++) + for (nxi=-rad; nxi<=rad; nxi++) + if ((pow(nxi,2))/(pow(rad,2))+(pow(nxj,2))/(pow(rad,2))<=1) + if ((pmap[y+nxj][x+nxi]&0xFF)!=PT_DMND && (pmap[y+nxj][x+nxi]&0xFF)!=PT_CLNE && (pmap[y+nxj][x+nxi]&0xFF)!=PT_PCLN && (pmap[y+nxj][x+nxi]&0xFF)!=PT_BCLN) { + sim->delete_part(x+nxi, y+nxj, 0);//it SHOULD kill anything but the exceptions above, doesn't seem to always work + sim->pv[(y+nxj)/CELL][(x+nxi)/CELL] += 0.1f; + nb = sim->create_part(-1, x+nxi, y+nxj, PT_BOMB); + if (nb!=-1) { + parts[nb].tmp = 2; + parts[nb].life = 2; + parts[nb].temp = MAX_TEMP; + } + } + //create_parts(x, y, 9, 9, PT_BOMB); + //create_parts(x, y, 8, 8, PT_NONE); + sim->kill_part(i); + return 1; + } + } + } + return 0; +} +int graphics_BOMB(GRAPHICS_FUNC_ARGS) +{ + if (cpart->tmp==0) { + //Normal bomb + *pixel_mode |= PMODE_FLARE; + } + else if(cpart->tmp==2) + { + //Flash + *pixel_mode = PMODE_FLAT | FIRE_ADD; + *colr = *colg = *colb = *firer = *fireg = *fireb = *firea = 255; + } + else + { + //Flying spark + *pixel_mode = PMODE_SPARK | PMODE_ADD; + *cola = 4*cpart->life; + } + return 0; +} diff --git a/src/elements/boyl.cpp b/src/elements/boyl.cpp new file mode 100644 index 0000000..e4ee6d2 --- /dev/null +++ b/src/elements/boyl.cpp @@ -0,0 +1,43 @@ +#include "element.h" + +int update_BOYL(UPDATE_FUNC_ARGS) { + int r, rx, ry; + if (sim->pv[y/CELL][x/CELL]<(parts[i].temp/100)) + sim->pv[y/CELL][x/CELL] += 0.001f*((parts[i].temp/100)-sim->pv[y/CELL][x/CELL]); + if (y+CELL<YRES && sim->pv[y/CELL+1][x/CELL]<(parts[i].temp/100)) + sim->pv[y/CELL+1][x/CELL] += 0.001f*((parts[i].temp/100)-sim->pv[y/CELL+1][x/CELL]); + if (x+CELL<XRES) + { + sim->pv[y/CELL][x/CELL+1] += 0.001f*((parts[i].temp/100)-sim->pv[y/CELL][x/CELL+1]); + if (y+CELL<YRES) + sim->pv[y/CELL+1][x/CELL+1] += 0.001f*((parts[i].temp/100)-sim->pv[y/CELL+1][x/CELL+1]); + } + if (y-CELL>=0 && sim->pv[y/CELL-1][x/CELL]<(parts[i].temp/100)) + sim->pv[y/CELL-1][x/CELL] += 0.001f*((parts[i].temp/100)-sim->pv[y/CELL-1][x/CELL]); + if (x-CELL>=0) + { + sim->pv[y/CELL][x/CELL-1] += 0.001f*((parts[i].temp/100)-sim->pv[y/CELL][x/CELL-1]); + if (y-CELL>=0) + sim->pv[y/CELL-1][x/CELL-1] += 0.001f*((parts[i].temp/100)-sim->pv[y/CELL-1][x/CELL-1]); + } + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && + x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_WATR && 1>rand()%30) + { + sim->part_change_type(r>>8,x+rx,y+ry,PT_FOG); + } + else if ((r&0xFF)==PT_O2 && 1>rand()%9) + { + sim->kill_part(r>>8); + sim->part_change_type(i,x,y,PT_WATR); + sim->pv[y/CELL][x/CELL] += 4.0; + } + } + return 0; +} diff --git a/src/elements/brmt.cpp b/src/elements/brmt.cpp new file mode 100644 index 0000000..c23bd99 --- /dev/null +++ b/src/elements/brmt.cpp @@ -0,0 +1,35 @@ +#include "element.h" + +int update_BRMT(UPDATE_FUNC_ARGS) { + int r, rx, ry, rt, tempFactor; + if (parts[i].temp > (250.0f+273.15f)) + { + printf("%f\n", (250.0f+273.15f)-parts[i].temp); + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + rt = parts[r>>8].type; + tempFactor = 1000 - (((250.0f+273.15f)-parts[i].temp)*2); + if(tempFactor < 2) + tempFactor = 2; + if ((rt==PT_BREC) && 1 > (rand()%tempFactor)) + { + if(rand()%2) + { + sim->create_part(r>>8, x+rx, y+ry, PT_THRM); + } + else + { sim->create_part(i, x, y, PT_THRM); + } + return 1; + //part_change_type(r>>8,x+rx,y+ry,PT_BMTL); + //parts[r>>8].tmp=(parts[i].tmp<=7)?parts[i].tmp=1:parts[i].tmp-(rand()%5);//rand()/(RAND_MAX/300)+100; + } + } + } + return 0; +} diff --git a/src/elements/btry.cpp b/src/elements/btry.cpp new file mode 100644 index 0000000..3f11003 --- /dev/null +++ b/src/elements/btry.cpp @@ -0,0 +1,24 @@ +#include "element.h" + +int update_BTRY(UPDATE_FUNC_ARGS) { + int r, rx, ry, rt; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + rt = parts[r>>8].type; + if (sim->parts_avg(i,r>>8,PT_INSL) != PT_INSL) + { + if ((sim->ptypes[rt].properties&PROP_CONDUCTS) && !(rt==PT_WATR||rt==PT_SLTW||rt==PT_NTCT||rt==PT_PTCT||rt==PT_INWR) && parts[r>>8].life==0 && abs(rx)+abs(ry) < 4) + { + parts[r>>8].life = 4; + parts[r>>8].ctype = rt; + sim->part_change_type(r>>8,x+rx,y+ry,PT_SPRK); + } + } + } + return 0; +} diff --git a/src/elements/c5.cpp b/src/elements/c5.cpp new file mode 100644 index 0000000..412245f --- /dev/null +++ b/src/elements/c5.cpp @@ -0,0 +1,24 @@ +#include "element.h" + +int update_C5(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)!=PT_C5 && parts[r>>8].temp<100)||(r&0xFF)==PT_HFLM) + { + if (1>rand()%6) + { + sim->part_change_type(i,x,y,PT_HFLM); + parts[r>>8].temp = parts[i].temp = 0; + parts[i].life = rand()%150+50; + sim->pv[y/CELL][x/CELL] += 1.5; + } + } + } + return 0; +} diff --git a/src/elements/caus.cpp b/src/elements/caus.cpp new file mode 100644 index 0000000..2ec268e --- /dev/null +++ b/src/elements/caus.cpp @@ -0,0 +1,35 @@ +#include "element.h" + +int update_CAUS(UPDATE_FUNC_ARGS) { + int r, rx, ry, trade, np; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_ACID && (r&0xFF)!=PT_CAUS) + { + if (((r&0xFF)!=PT_CLNE && (r&0xFF)!=PT_PCLN && sim->ptypes[r&0xFF].hardness>(rand()%1000))&&parts[i].life>=50) + { + if (sim->parts_avg(i, r>>8,PT_GLAS)!= PT_GLAS)//GLAS protects stuff from acid + { + float newtemp = ((60.0f-(float)sim->ptypes[r&0xFF].hardness))*7.0f; + if(newtemp < 0){ + newtemp = 0; + } + parts[i].temp += newtemp; + parts[i].life--; + sim->kill_part(r>>8); + } + } + else if (parts[i].life<=50) + { + sim->kill_part(i); + return 1; + } + } + } + return 0; +} diff --git a/src/elements/cbnw.cpp b/src/elements/cbnw.cpp new file mode 100644 index 0000000..cf0c13e --- /dev/null +++ b/src/elements/cbnw.cpp @@ -0,0 +1,89 @@ +#include "element.h" + +int update_CBNW(UPDATE_FUNC_ARGS) { + int r, rx, ry, oldt; + oldt = parts[i].tmp; + if (sim->pv[y/CELL][x/CELL]<=3) + { + if(20>(rand()%80000)) + { + sim->part_change_type(i,x,y,PT_CO2); + parts[i].ctype = 5; + sim->pv[y/CELL][x/CELL] += 0.5f; + } + else if(sim->pv[y/CELL][x/CELL]<=-0.5) + { + sim->part_change_type(i,x,y,PT_CO2); + parts[i].ctype = 5; + sim->pv[y/CELL][x/CELL] += 0.5f; + } + } + if (parts[i].tmp>0) + parts[i].tmp--; + if(!(rand()%200)) + { + parts[i].tmp2 = rand()%40; + } else if(parts[i].tmp2!=20) { + parts[i].tmp2 -= (parts[i].tmp2>20)?1:-1; + } + if(oldt==1) + { + //Explode + if(rand()%4) + { + sim->part_change_type(i,x,y,PT_CO2); + parts[i].ctype = 5; + sim->pv[y/CELL][x/CELL] += 0.2f; + } + } + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((sim->ptypes[r&0xFF].properties&TYPE_PART) && parts[i].tmp == 0 && 1>(rand()%250)) + { + //Start explode + parts[i].tmp = rand()%25;//(rand()%100)+50; + } + else if((sim->ptypes[r&0xFF].properties&TYPE_SOLID) && (r&0xFF)!=PT_DMND && (r&0xFF)!=PT_GLAS && parts[i].tmp == 0 && (2-sim->pv[y/CELL][x/CELL])>(rand()%20000)) + { + if(rand()%2) + { + sim->part_change_type(i,x,y,PT_CO2); + parts[i].ctype = 5; + sim->pv[y/CELL][x/CELL] += 0.2f; + } + } + if ((r&0xFF)==PT_CBNW) + { + if(!parts[i].tmp && parts[r>>8].tmp) + { + parts[i].tmp = parts[r>>8].tmp; + if((r>>8)>i) //If the other particle hasn't been life updated + parts[i].tmp--; + } + else if(parts[i].tmp && !parts[r>>8].tmp) + { + parts[r>>8].tmp = parts[i].tmp; + if((r>>8)>i) //If the other particle hasn't been life updated + parts[r>>8].tmp++; + } + } + if (((r&0xFF)==PT_RBDM||(r&0xFF)==PT_LRBD) && (sim->legacy_enable||parts[i].temp>(273.15f+12.0f)) && 1>(rand()%500)) + { + sim->part_change_type(i,x,y,PT_FIRE); + parts[i].life = 4; + } + if ((r&0xFF)==PT_FIRE){ + sim->kill_part(r>>8); + if(1>(rand()%150)){ + sim->kill_part(i); + return 1; + } + } + } + return 0; +} diff --git a/src/elements/clne.cpp b/src/elements/clne.cpp new file mode 100644 index 0000000..13b25b9 --- /dev/null +++ b/src/elements/clne.cpp @@ -0,0 +1,32 @@ +#include "element.h" + +int update_CLNE(UPDATE_FUNC_ARGS) { + if (parts[i].ctype<=0 || parts[i].ctype>=PT_NUM || (parts[i].ctype==PT_LIFE && (parts[i].tmp<0 || parts[i].tmp>=NGOLALT))) + { + int r, rx, ry; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES) + { + r = sim->photons[y+ry][x+rx]; + if (!r) + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_CLNE && (r&0xFF)!=PT_PCLN && + (r&0xFF)!=PT_BCLN && (r&0xFF)!=PT_STKM && + (r&0xFF)!=PT_PBCN && (r&0xFF)!=PT_STKM2 && + (r&0xFF)<PT_NUM) + { + parts[i].ctype = r&0xFF; + if ((r&0xFF)==PT_LIFE) + parts[i].tmp = parts[r>>8].ctype; + } + } + } + else { + if (parts[i].ctype==PT_LIFE) sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, parts[i].ctype|(parts[i].tmp<<8)); + else sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, parts[i].ctype); + } + return 0; +} diff --git a/src/elements/clst.cpp b/src/elements/clst.cpp new file mode 100644 index 0000000..2c31d87 --- /dev/null +++ b/src/elements/clst.cpp @@ -0,0 +1,38 @@ +#include "element.h" + +int update_CLST(UPDATE_FUNC_ARGS) { + int r, rx, ry; + float cxy; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_WATR && 1>(rand()%1500)) + { + sim->part_change_type(i,x,y,PT_PSTS); + sim->kill_part(r>>8); + } + if ((r&0xFF)==PT_NITR) + { + sim->create_part(i, x, y, PT_BANG); + sim->create_part(r>>8, x+rx, y+ry, PT_BANG); + } + if ((r&0xFF)==PT_CLST) + { + if(parts[i].temp <195) + cxy = 0.05; + if(parts[i].temp >= 195 && parts[i].temp <295) + cxy = 0.015; + if(parts[i].temp >= 295 && parts[i].temp <350) + cxy = 0.01; + if(parts[i].temp > 350) + cxy = 0.005; + parts[i].vx += cxy*rx; + parts[i].vy += cxy*ry;//These two can be set not to calculate over 350 later. They do virtually nothing over 0.005. + } + } + return 0; +} diff --git a/src/elements/co2.cpp b/src/elements/co2.cpp new file mode 100644 index 0000000..5a3bbf5 --- /dev/null +++ b/src/elements/co2.cpp @@ -0,0 +1,31 @@ +#include "element.h" + +int update_CO2(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (20>(rand()%40000)&&parts[i].ctype==5) + { + parts[i].ctype = 0; + sim->create_part(-3, x, y, PT_WATR); + } + if ((r>>8)>=NPART || !r) + continue; + if ((r&0xFF)==PT_FIRE){ + sim->kill_part(r>>8); + if(1>(rand()%150)){ + sim->kill_part(i); + return 1; + } + } + if (((r&0xFF)==PT_WATR || (r&0xFF)==PT_DSTW) && 1>(rand()%250)) + { + sim->part_change_type(i,x,y,PT_CBNW); + sim->kill_part(r>>8); + } + } + return 0; +} diff --git a/src/elements/coal.cpp b/src/elements/coal.cpp new file mode 100644 index 0000000..256aa69 --- /dev/null +++ b/src/elements/coal.cpp @@ -0,0 +1,75 @@ +#include "element.h" + +int update_COAL(UPDATE_FUNC_ARGS) { + int r, rx, ry, trade, temp; + if (parts[i].life<=0) { + sim->create_part(i, x, y, PT_FIRE); + return 1; + } else if (parts[i].life < 100) { + parts[i].life--; + sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, PT_FIRE); + } + if ((sim->pv[y/CELL][x/CELL] > 4.3f)&&parts[i].tmp>40) + parts[i].tmp=39; + else if (parts[i].tmp<40&&parts[i].tmp>0) + parts[i].tmp--; + else if (parts[i].tmp<=0) { + sim->create_part(i, x, y, PT_BCOL); + return 1; + } + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_FIRE || (r&0xFF)==PT_PLSM) && 1>(rand()%500)) + { + if (parts[i].life>100) { + parts[i].life = 99; + } + } + if ((r&0xFF)==PT_LAVA && 1>(rand()%500)) + { + if (parts[r>>8].ctype == PT_IRON) { + parts[r>>8].ctype = PT_METL; + sim->kill_part(i); + return 1; + } + } + } + /*if(100-parts[i].life > parts[i].tmp2) + parts[i].tmp2 = 100-parts[i].life; + if(parts[i].tmp2 < 0) parts[i].tmp2 = 0; + for ( trade = 0; trade<4; trade ++) + { + rx = rand()%5-2; + ry = rand()%5-2; + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_COAL || (r&0xFF)==PT_BCOL)&&(parts[i].tmp2>parts[r>>8].tmp2)&&parts[i].tmp2>0)//diffusion + { + int temp = parts[i].tmp2 - parts[r>>8].tmp2; + if(temp < 10) + continue; + if (temp ==1) + { + parts[r>>8].tmp2 ++; + parts[i].tmp2 --; + } + else if (temp>0) + { + parts[r>>8].tmp2 += temp/2; + parts[i].tmp2 -= temp/2; + } + } + } + }*/ + if(parts[i].temp > parts[i].tmp2) + parts[i].tmp2 = parts[i].temp; + return 0; +} diff --git a/src/elements/conv.cpp b/src/elements/conv.cpp new file mode 100644 index 0000000..ce4ee48 --- /dev/null +++ b/src/elements/conv.cpp @@ -0,0 +1,45 @@ +#include "element.h" + +int update_CONV(UPDATE_FUNC_ARGS) { + int r, rx, ry; + if (parts[i].ctype<=0 || parts[i].ctype>=PT_NUM || (parts[i].ctype==PT_LIFE && (parts[i].tmp<0 || parts[i].tmp>=NGOLALT))) + { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES) + { + r = sim->photons[y+ry][x+rx]; + if (!r) + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_CLNE && (r&0xFF)!=PT_PCLN && + (r&0xFF)!=PT_BCLN && (r&0xFF)!=PT_STKM && + (r&0xFF)!=PT_PBCN && (r&0xFF)!=PT_STKM2 && + (r&0xFF)!=PT_CONV && (r&0xFF)<PT_NUM) + { + parts[i].ctype = r&0xFF; + if ((r&0xFF)==PT_LIFE) + parts[i].tmp = parts[r>>8].ctype; + } + } + } + else if(parts[i].ctype>0 && parts[i].ctype<PT_NUM && parts[i].ctype!=PT_CONV) { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES) + { + r = sim->photons[y+ry][x+rx]; + if (!r) + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if((r&0xFF)!=PT_CONV && (r&0xFF)!=parts[i].ctype) + { + if (parts[i].ctype==PT_LIFE) sim->create_part(r>>8, x+rx, y+ry, parts[i].ctype|(parts[i].tmp<<8)); + else sim->create_part(r>>8, x+rx, y+ry, parts[i].ctype); + } + } + } + return 0; +} diff --git a/src/elements/dest.cpp b/src/elements/dest.cpp new file mode 100644 index 0000000..014fad4 --- /dev/null +++ b/src/elements/dest.cpp @@ -0,0 +1,66 @@ +#include "element.h" + +int update_DEST(UPDATE_FUNC_ARGS) { + int r,rx,ry,topv; + rx=rand()%5-2; + ry=rand()%5-2; + + r = pmap[y+ry][x+rx]; + if (!r || (r&0xFF)==PT_DEST || (r&0xFF)==PT_DMND) + return 0; + + if (parts[i].life<=0 || parts[i].life>37) + { + parts[i].life=30+rand()%20; + parts[i].temp+=20000; + sim->pv[y/CELL][x/CELL]+=60.0f; + } + parts[i].temp+=10000; + if ((r&0xFF)==PT_PLUT || (r&0xFF)==PT_DEUT) + { + sim->pv[y/CELL][x/CELL]+=20.0f; + parts[i].temp+=18000; + if (rand()%2==0) + { + float orig_temp = parts[r>>8].temp; + sim->create_part(r>>8, x+rx, y+ry, PT_NEUT); + parts[r>>8].temp = restrict_flt(orig_temp+40000.0f, MIN_TEMP, MAX_TEMP); + sim->pv[y/CELL][x/CELL] += 10.0f; + parts[i].life-=4; + } + } + else if ((r&0xFF)==PT_INSL) + { + sim->create_part(r>>8, x+rx, y+ry, PT_PLSM); + } + else if (rand()%3==0) + { + sim->kill_part(r>>8); + parts[i].life -= 4*((sim->ptypes[r&0xFF].properties&TYPE_SOLID)?3:1); + if (parts[i].life<=0) + parts[i].life=1; + parts[i].temp+=10000; + } + else + { + if (sim->ptypes[r&0xFF].hconduct) parts[r>>8].temp = restrict_flt(parts[r>>8].temp+10000.0f, MIN_TEMP, MAX_TEMP); + } + topv=sim->pv[y/CELL][x/CELL]/9+parts[r>>8].temp/900; + if (topv>40.0f) + topv=40.0f; + sim->pv[y/CELL][x/CELL]+=40.0f+topv; + parts[i].temp = restrict_flt(parts[i].temp, MIN_TEMP, MAX_TEMP); + return 0; +} +int graphics_DEST(GRAPHICS_FUNC_ARGS) +{ + if(cpart->life) + { + *pixel_mode |= PMODE_LFLARE; + } + else + { + *pixel_mode |= PMODE_SPARK; + } + return 0; +} diff --git a/src/elements/deut.cpp b/src/elements/deut.cpp new file mode 100644 index 0000000..03de364 --- /dev/null +++ b/src/elements/deut.cpp @@ -0,0 +1,89 @@ +#include "element.h" + +int update_DEUT(UPDATE_FUNC_ARGS) { + int r, rx, ry, trade, np; + int maxlife = ((10000/(parts[i].temp + 1))-1); + if ((10000%((int)parts[i].temp+1))>rand()%((int)parts[i].temp+1)) + maxlife ++; + if (parts[i].life < maxlife) + { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r || (parts[i].life >=maxlife)) + continue; + if ((r&0xFF)==PT_DEUT&&33>=rand()/(RAND_MAX/100)+1) + { + if ((parts[i].life + parts[r>>8].life + 1) <= maxlife) + { + parts[i].life += parts[r>>8].life + 1; + sim->kill_part(r>>8); + } + } + } + } + else + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (parts[i].life<=maxlife) + continue; + if ((!r)&&parts[i].life>=1)//if nothing then create deut + { + np = sim->create_part(-1,x+rx,y+ry,PT_DEUT); + if (np<0) continue; + parts[i].life--; + parts[np].temp = parts[i].temp; + parts[np].life = 0; + } + } + for ( trade = 0; trade<4; trade ++) + { + rx = rand()%5-2; + ry = rand()%5-2; + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_DEUT&&(parts[i].life>parts[r>>8].life)&&parts[i].life>0)//diffusion + { + int temp = parts[i].life - parts[r>>8].life; + if (temp ==1) + { + parts[r>>8].life ++; + parts[i].life --; + } + else if (temp>0) + { + parts[r>>8].life += temp/2; + parts[i].life -= temp/2; + } + } + } + } + return 0; +} + +int graphics_DEUT(GRAPHICS_FUNC_ARGS) +{ + if(cpart->life>=700) + { + *colr += cpart->life*1; + *colg += cpart->life*2; + *colb += cpart->life*3; + *pixel_mode |= PMODE_GLOW; + } + else + { + *colr += cpart->life*1; + *colg += cpart->life*2; + *colb += cpart->life*3; + *pixel_mode |= PMODE_BLUR; + } + return 0; +} diff --git a/src/elements/dlay.cpp b/src/elements/dlay.cpp new file mode 100644 index 0000000..4643b30 --- /dev/null +++ b/src/elements/dlay.cpp @@ -0,0 +1,48 @@ +#include "element.h" + +int update_DLAY(UPDATE_FUNC_ARGS) { + int r, rx, ry, oldl; + oldl = parts[i].life; + if (parts[i].life>0) + parts[i].life--; + //if (parts[i].life==1) + //{ + if (parts[i].temp>=256.0+273.15) + parts[i].temp=256.0+273.15; + if (parts[i].temp<= -256.0+273.15) + parts[i].temp = -256.0+273.15; + + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_SPRK && parts[i].life==0 && parts[r>>8].ctype==PT_PSCN) + { + parts[i].life = (int)(parts[i].temp-273.15); + } + else if ((r&0xFF)==PT_DLAY) + { + if(!parts[i].life && parts[r>>8].life) + { + parts[i].life = parts[r>>8].life; + if((r>>8)>i) //If the other particle hasn't been life updated + parts[i].life--; + } + else if(parts[i].life && !parts[r>>8].life) + { + parts[r>>8].life = parts[i].life; + if((r>>8)>i) //If the other particle hasn't been life updated + parts[r>>8].life++; + } + } + else if((r&0xFF)==PT_NSCN && oldl==1) + { + sim->create_part(-1, x+rx, y+ry, PT_SPRK); + } + } + //} + return 0; +} diff --git a/src/elements/dstw.cpp b/src/elements/dstw.cpp new file mode 100644 index 0000000..03ae7dd --- /dev/null +++ b/src/elements/dstw.cpp @@ -0,0 +1,39 @@ +#include "element.h" + +int update_DSTW(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_SALT && 1>(rand()%250)) + { + sim->part_change_type(i,x,y,PT_SLTW); + sim->part_change_type(r>>8,x+rx,y+ry,PT_SLTW); + } + if (((r&0xFF)==PT_WATR||(r&0xFF)==PT_SLTW) && 1>(rand()%500)) + { + sim->part_change_type(i,x,y,PT_WATR); + } + if ((r&0xFF)==PT_SLTW && 1>(rand()%500)) + { + sim->part_change_type(i,x,y,PT_SLTW); + } + if (((r&0xFF)==PT_RBDM||(r&0xFF)==PT_LRBD) && (sim->legacy_enable||parts[i].temp>12.0f) && 1>(rand()%500)) + { + sim->part_change_type(i,x,y,PT_FIRE); + parts[i].life = 4; + } + if ((r&0xFF)==PT_FIRE){ + sim->kill_part(r>>8); + if(1>(rand()%150)){ + sim->kill_part(i); + return 1; + } + } + } + return 0; +} diff --git a/src/elements/elec.cpp b/src/elements/elec.cpp new file mode 100644 index 0000000..6b06f8f --- /dev/null +++ b/src/elements/elec.cpp @@ -0,0 +1,101 @@ +#include "element.h" + +int update_ELEC(UPDATE_FUNC_ARGS) { + int r, rt, rx, ry, nb, rrx, rry; + float rr, rrr; + parts[i].pavg[0] = x; + parts[i].pavg[1] = y; + if(pmap[y][x]==PT_GLOW) + { + sim->part_change_type(i, x, y, PT_PHOT); + } + for (rx=-2; rx<=2; rx++) + for (ry=-2; ry<=2; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES) { + r = pmap[y+ry][x+rx]; + if (!r) + r = sim->photons[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_GLAS) + { + //fire_r[y/CELL][x/CELL] += rand()%200; //D: Doesn't work with OpenGL, also shouldn't be here TODO: FIX THIS SHIT + //fire_g[y/CELL][x/CELL] += rand()%200; + //fire_b[y/CELL][x/CELL] += rand()%200; + for (rrx=-1; rrx<=1; rrx++) + { + for (rry=-1; rry<=1; rry++) + { + if (x+rx+rrx>=0 && y+ry+rry>=0 && x+rx+rrx<XRES && y+ry+rry<YRES) { + nb = sim->create_part(-1, x+rx+rrx, y+ry+rry, PT_BOMB); + if (nb!=-1) { + parts[nb].tmp = 1; + parts[nb].life = 50; + parts[nb].temp = 400.0f; + parts[nb].vx = rand()%20-10; + parts[nb].vy = rand()%20-10; + } + } + } + } + sim->kill_part(i); + return 1; + } + if ((r&0xFF)==PT_LCRY) + { + parts[r>>8].tmp2 = 5+rand()%5; + } + if ((r&0xFF)==PT_WATR || (r&0xFF)==PT_DSTW || (r&0xFF)==PT_SLTW || (r&0xFF)==PT_CBNW) + { + if(rand()%2) + { + sim->create_part(r>>8, x+rx, y+ry, PT_H2); + sim->part_change_type(i, x, y, PT_O2); + parts[i].life = 0; + parts[i].ctype = 0; + return 1; + } + else + { + sim->create_part(r>>8, x+rx, y+ry, PT_O2); + sim->part_change_type(i, x, y, PT_H2); + parts[i].life = 0; + parts[i].ctype = 0; + return 1; + } + } + if ((r&0xFF)==PT_NEUT) + { + sim->part_change_type(r>>8, x+rx, y+ry, PT_H2); + parts[r>>8].life = 0; + parts[r>>8].ctype = 0; + } + if ((r&0xFF)==PT_DEUT) + { + if(parts[r>>8].life < 6000) + parts[r>>8].life += 1; + parts[r>>8].temp = 0; + parts[i].temp = 0; + sim->kill_part(i); + return 1; + } + if (sim->ptypes[r&0xFF].properties & PROP_CONDUCTS) + { + sim->create_part(-1, x+rx, y+ry, PT_SPRK); + sim->kill_part(i); + return 1; + } + } + return 0; +} + +int graphics_ELEC(GRAPHICS_FUNC_ARGS) +{ + *firea = 70; + *firer = *colr; + *fireg = *colg; + *fireb = *colb; + + *pixel_mode |= FIRE_ADD; + return 0; +} diff --git a/src/elements/elementmisc.cpp b/src/elements/elementmisc.cpp new file mode 100644 index 0000000..a169e80 --- /dev/null +++ b/src/elements/elementmisc.cpp @@ -0,0 +1,12 @@ +#include "element.h" + +int update_MISC(UPDATE_FUNC_ARGS) { + /*int t = parts[i].type; + if (t==PT_LOVE) + ISLOVE=1; + else if (t==PT_LOLZ) + ISLOLZ=1; + else if (t==PT_GRAV) + ISGRAV=1;*/ + return 0; +} diff --git a/src/elements/emp.cpp b/src/elements/emp.cpp new file mode 100644 index 0000000..a187196 --- /dev/null +++ b/src/elements/emp.cpp @@ -0,0 +1,128 @@ +#include "element.h" + +int update_EMP(UPDATE_FUNC_ARGS) { + int r,rx,ry,ok=0,t,n,nx,ny; + if (parts[i].life) + return 0; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_SPRK) + { + ok=1; + break; + } + } + if (!ok) + return 0; + parts[i].life=220; + //emp_decor+=3; TODO: Fix + //if (emp_decor>40) + // emp_decor=40; + for (r=0; r<=sim->parts_lastActiveIndex; r++) + { + t=parts[r].type; + rx=parts[r].x; + ry=parts[r].y; + if (t==PT_SPRK || (t==PT_SWCH && parts[r].life!=0 && parts[r].life!=10) || (t==PT_WIRE && parts[r].ctype>0)) + { + int is_elec=0; + if ((parts[r].ctype==PT_PSCN || parts[r].ctype==PT_NSCN || parts[r].ctype==PT_PTCT || + parts[r].ctype==PT_NTCT || parts[r].ctype==PT_INST || parts[r].ctype==PT_SWCH) || t==PT_WIRE || t==PT_SWCH) + { + is_elec=1; + if (sim->ptypes[parts[r].type].hconduct && rand()%100==0) + parts[r].temp = restrict_flt(parts[r].temp+3000.0f, MIN_TEMP, MAX_TEMP); + if (rand()%80==0) + sim->part_change_type(r, rx, ry, PT_BREC); + else if (rand()%120==0) + sim->part_change_type(r, rx, ry, PT_NTCT); + } + + for (nx=-2; nx<3; nx++) + for (ny=-2; ny<3; ny++) + if (rx+nx>=0 && ry+ny>=0 && rx+nx<XRES && ry+ny<YRES && (rx || ry)) + { + n = pmap[ry+ny][rx+nx]; + if (!n) + continue; + /*if ((n&0xFF)==PT_BTRY && rand()%60==0) + { + part_change_type(n>>8, rx+nx, ry+ny, PT_PLSM); + parts[n>>8].life=rand()%100+70; + parts[n>>8].temp+=3000; + }*/ + + //Some elements should only be affected by wire/swch, or by a spark on inst/semiconductor + //So not affected by spark on metl, watr etc + if (is_elec) + { + if (((n&0xFF)==PT_METL || (n&0xFF)==PT_BMTL) && rand()%280==0) + { + parts[n>>8].temp = restrict_flt(parts[n>>8].temp+3000.0f, MIN_TEMP, MAX_TEMP); + } + if ((n&0xFF)==PT_BMTL && rand()%160==0) + { + sim->part_change_type(n>>8, rx+nx, ry+ny, PT_BMTL);//TODO: Redundant, was this meant to be BRMT or something? + parts[n>>8].temp = restrict_flt(parts[n>>8].temp+1000.0f, MIN_TEMP, MAX_TEMP); + } + if ((n&0xFF)==PT_METL && rand()%300==0) + { + sim->part_change_type(n>>8, rx+nx, ry+ny, PT_BMTL); + } + if ((n&0xFF)==PT_WIFI && rand()%8==0) + { + //Randomise channel + parts[n>>8].temp = rand()%MAX_TEMP; + } + if ((n&0xFF)==PT_WIFI && rand()%16==0) + { + sim->create_part(n>>8, rx+nx, ry+ny, PT_BREC); + parts[n>>8].temp = restrict_flt(parts[n>>8].temp+1000.0f, MIN_TEMP, MAX_TEMP); + } + } + if ((n&0xFF)==PT_SWCH && rand()%100==0) + { + sim->part_change_type(n>>8, rx+nx, ry+ny, PT_BREC); + } + if ((n&0xFF)==PT_SWCH && rand()%100==0) + { + parts[n>>8].temp = restrict_flt(parts[n>>8].temp+2000.0f, MIN_TEMP, MAX_TEMP); + } + if ((n&0xFF)==PT_ARAY && rand()%60==0) + { + sim->create_part(n>>8, rx+nx, ry+ny, PT_BREC); + parts[n>>8].temp = restrict_flt(parts[n>>8].temp+1000.0f, MIN_TEMP, MAX_TEMP); + } + if (t==PT_DLAY && rand()%70==0) + { + //Randomise delay + parts[n>>8].temp = (rand()%256) + 273.15f; + } + } + } + } + return 0; +} +int graphics_EMP(GRAPHICS_FUNC_ARGS) +{ + if(cpart->life) + { + *colr = cpart->life*1.5; + *colg = cpart->life*1.5; + *colb = 200-(cpart->life); + if (*colr>255) + *colr = 255; + if (*colg>255) + *colg = 255; + if (*colb>255) + *colb = 255; + if (*colb<=0) + *colb = 0; + } + return 0; +} diff --git a/src/elements/figh.cpp b/src/elements/figh.cpp new file mode 100644 index 0000000..8b18871 --- /dev/null +++ b/src/elements/figh.cpp @@ -0,0 +1,105 @@ +#include "element.h" + +int update_FIGH(UPDATE_FUNC_ARGS) +{ + playerst* figh = &sim->fighters[(unsigned char)parts[i].tmp]; + + float tarx, tary; + + parts[i].tmp2 = 0; //0 - stay in place, 1 - seek a stick man + + //Set target cords + if (sim->player.spwn) + { + if (sim->player2.spwn) + if ((pow(sim->player.legs[2]-x, 2) + pow(sim->player.legs[3]-y, 2))<= + (pow(sim->player2.legs[2]-x, 2) + pow(sim->player2.legs[3]-y, 2))) + { + tarx = sim->player.legs[2]; + tary = sim->player.legs[3]; + } + else + { + tarx = sim->player2.legs[2]; + tary = sim->player2.legs[3]; + } + else + { + tarx = sim->player.legs[2]; + tary = sim->player.legs[3]; + } + + parts[i].tmp2 = 1; + } + else + if (sim->player2.spwn) + { + tarx = sim->player2.legs[2]; + tary = sim->player2.legs[3]; + + parts[i].tmp2 = 1; + } + + switch (parts[i].tmp2) + { + case 1: + if ((pow(tarx-x, 2) + pow(tary-y, 2))<600) + { + if (figh->elem == PT_LIGH || figh->elem == PT_NEUT + || (sim->ptypes[figh->elem].properties&(PROP_DEADLY|PROP_RADIOACTIVE)) + || sim->ptypes[figh->elem].heat>=323 || sim->ptypes[figh->elem].heat<=243) + figh->comm = (int)figh->comm | 0x08; + } + else + if (tarx<x ) + { + if(!sim->eval_move(PT_DUST, figh->legs[4]-10, figh->legs[5]+6, NULL)) + figh->comm = 0x01; + else + figh->comm = 0x02; + + if (!sim->eval_move(PT_DUST, figh->legs[4]-4, figh->legs[5]-1, NULL) + || !sim->eval_move(PT_DUST, figh->legs[12]-4, figh->legs[13]-1, NULL) + || sim->eval_move(PT_DUST, 2*figh->legs[4]-figh->legs[6], figh->legs[5]+5, NULL)) + figh->comm = (int)figh->comm | 0x04; + } + else + { + if (!sim->eval_move(PT_DUST, figh->legs[12]+10, figh->legs[13]+6, NULL)) + figh->comm = 0x02; + else + figh->comm = 0x01; + + if (!sim->eval_move(PT_DUST, figh->legs[4]+4, figh->legs[5]-1, NULL) + || !sim->eval_move(PT_DUST, figh->legs[4]+4, figh->legs[5]-1, NULL) + || sim->eval_move(PT_DUST, 2*figh->legs[12]-figh->legs[14], figh->legs[13]+5, NULL)) + figh->comm = (int)figh->comm | 0x04; + } + break; + default: + figh->comm = 0; + break; + } + + figh->pcomm = figh->comm; + + run_stickman(figh, UPDATE_FUNC_SUBCALL_ARGS); + return 0; +} + +int graphics_FIGH(GRAPHICS_FUNC_ARGS) +{ + playerst * cplayer;// = &sim->fighters[(unsigned char)cpart->tmp]; + *pixel_mode = PSPEC_STICKMAN; + /*if (cplayer->elem<PT_NUM) + { + *colr = PIXR(sim->ptypes[cplayer->elem].pcolors); + *colg = PIXG(sim->ptypes[cplayer->elem].pcolors); + *colb = PIXB(sim->ptypes[cplayer->elem].pcolors); + } + else*/ + { + *colr = *colg = *colb = 255; + } + return 1; +} diff --git a/src/elements/fire.cpp b/src/elements/fire.cpp new file mode 100644 index 0000000..1f9c0c2 --- /dev/null +++ b/src/elements/fire.cpp @@ -0,0 +1,19 @@ +#include "element.h" + +int graphics_FIRE(GRAPHICS_FUNC_ARGS) +{ + int caddress = restrict_flt(restrict_flt((float)cpart->life, 0.0f, 200.0f)*3, 0.0f, (200.0f*3)-3); + *colr = (unsigned char)ren->flm_data[caddress]; + *colg = (unsigned char)ren->flm_data[caddress+1]; + *colb = (unsigned char)ren->flm_data[caddress+2]; + + *firea = 255; + *firer = *colr; + *fireg = *colg; + *fireb = *colb; + + *pixel_mode = PMODE_NONE; //Clear default, don't draw pixel + *pixel_mode |= FIRE_ADD; + //Returning 0 means dynamic, do not cache + return 0; +} diff --git a/src/elements/firw.cpp b/src/elements/firw.cpp new file mode 100644 index 0000000..74605b0 --- /dev/null +++ b/src/elements/firw.cpp @@ -0,0 +1,65 @@ +#include "element.h" + +int update_FIRW(UPDATE_FUNC_ARGS) { + int r, rx, ry, rt, np; + if (parts[i].tmp==0) { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + rt = parts[r>>8].type; + if (rt==PT_FIRE||rt==PT_PLSM||rt==PT_THDR) + { + parts[i].tmp = 1; + parts[i].life = rand()%50+60; + } + } + } + else if (parts[i].tmp==1) { + if (parts[i].life==0) { + parts[i].tmp=2; + } else { + float newVel = parts[i].life/25; + parts[i].flags = parts[i].flags&0xFFFFFFFE; + /* TODO: + if ((pmap[(int)(ly-newVel)][(int)lx]&0xFF)==PT_NONE && ly-newVel>0) { + parts[i].vy = -newVel; + ly-=newVel; + iy-=newVel; + }*/ + parts[i].vy = -newVel; + } + } + else if (parts[i].tmp==2) { + int col = rand()%200+4; + int tmul; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + tmul = rand()%7; + np = sim->create_part(-1, x+rx, y+ry, PT_FIRW); + if (np>-1) + { + parts[np].vx = (rand()%3-1)*tmul; + parts[np].vy = (rand()%3-1)*tmul; + parts[np].tmp = col; + parts[np].life = rand()%100+100; + parts[np].temp = 6000.0f; + parts[np].dcolour = parts[i].dcolour; + } + } + sim->pv[y/CELL][x/CELL] += 20; + sim->kill_part(i); + return 1; + } else if (parts[i].tmp>=3) { + if (parts[i].life<=0) { + sim->kill_part(i); + return 1; + } + } + return 0; +} diff --git a/src/elements/fog.cpp b/src/elements/fog.cpp new file mode 100644 index 0000000..28952e9 --- /dev/null +++ b/src/elements/fog.cpp @@ -0,0 +1,22 @@ +#include "element.h" + +int update_FOG(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (sim->ptypes[r&0xFF].state==ST_SOLID&&5>=rand()%50&&parts[i].life==0&&!((r&0xFF)==PT_CLNE||(r&0xFF)==PT_PCLN)) // TODO: should this also exclude BCLN? + { + sim->part_change_type(i,x,y,PT_RIME); + } + if ((r&0xFF)==PT_SPRK) + { + parts[i].life += rand()%20; + } + } + return 0; +} diff --git a/src/elements/frzw.cpp b/src/elements/frzw.cpp new file mode 100644 index 0000000..932bccb --- /dev/null +++ b/src/elements/frzw.cpp @@ -0,0 +1,30 @@ +#include "element.h" + +int update_FRZW(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_WATR&&5>rand()%70) + { + sim->part_change_type(r>>8,x+rx,y+ry,PT_FRZW); + } + } + if (parts[i].life==0&&13>rand()%2500) + { + sim->part_change_type(i,x,y,PT_ICEI); + parts[i].ctype=PT_FRZW; + parts[i].temp = restrict_flt(parts[i].temp-200.0f, MIN_TEMP, MAX_TEMP); + } + else if ((100-(parts[i].life))>rand()%50000) + { + sim->part_change_type(i,x,y,PT_ICEI); + parts[i].ctype=PT_FRZW; + parts[i].temp = restrict_flt(parts[i].temp-200.0f, MIN_TEMP, MAX_TEMP); + } + return 0; +} diff --git a/src/elements/frzz.cpp b/src/elements/frzz.cpp new file mode 100644 index 0000000..8e09c1d --- /dev/null +++ b/src/elements/frzz.cpp @@ -0,0 +1,25 @@ +#include "element.h" + +int update_FRZZ(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_WATR&&5>rand()%100) + { + sim->part_change_type(r>>8,x+rx,y+ry,PT_FRZW); + parts[r>>8].life = 100; + parts[i].type = PT_NONE; + } + + } + if (parts[i].type==PT_NONE) { + sim->kill_part(i); + return 1; + } + return 0; +} diff --git a/src/elements/fsep.cpp b/src/elements/fsep.cpp new file mode 100644 index 0000000..3db5ba5 --- /dev/null +++ b/src/elements/fsep.cpp @@ -0,0 +1,35 @@ +#include "element.h" + +int update_FSEP(UPDATE_FUNC_ARGS) { + int r, rx, ry; + if (parts[i].life<=0) { + r = sim->create_part(i, x, y, PT_PLSM); + if (r!=-1) + parts[r].life = 50; + return 1; + } else if (parts[i].life < 40) { + parts[i].life--; + if ((rand()%10)==0) { + r = sim->create_part(-1, (rx=x+rand()%3-1), (ry=y+rand()%3-1), PT_PLSM); + if (r!=-1) + parts[r].life = 50; + } + } + else { + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_SPRK || (parts[i].temp>=(273.15+400.0f))) && 1>(rand()%15)) + { + if (parts[i].life>40) { + parts[i].life = 39; + } + } + } + } + return 0; +} diff --git a/src/elements/fuse.cpp b/src/elements/fuse.cpp new file mode 100644 index 0000000..e1db1ff --- /dev/null +++ b/src/elements/fuse.cpp @@ -0,0 +1,41 @@ +#include "element.h" + +int update_FUSE(UPDATE_FUNC_ARGS) { + int r, rx, ry; + if (parts[i].life<=0) { + r = sim->create_part(i, x, y, PT_PLSM); + if (r!=-1) + parts[r].life = 50; + return 1; + } else if (parts[i].life < 40) { + parts[i].life--; + if ((rand()%100)==0) { + r = sim->create_part(-1, (rx=x+rand()%3-1), (ry=y+rand()%3-1), PT_PLSM); + if (r!=-1) + parts[r].life = 50; + } + } + if ((sim->pv[y/CELL][x/CELL] > 2.7f)&&parts[i].tmp>40) + parts[i].tmp=39; + else if (parts[i].tmp<40&&parts[i].tmp>0) + parts[i].tmp--; + else if (parts[i].tmp<=0) { + sim->create_part(i, x, y, PT_FSEP); + return 1; + } + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_SPRK || ((parts[i].temp>=(273.15+700.0f)) && 1>(rand()%20))) + { + if (parts[i].life>40) { + parts[i].life = 39; + } + } + } + return 0; +} diff --git a/src/elements/fwrk.cpp b/src/elements/fwrk.cpp new file mode 100644 index 0000000..d217ad9 --- /dev/null +++ b/src/elements/fwrk.cpp @@ -0,0 +1,53 @@ +#include "element.h" + +int update_FWRK(UPDATE_FUNC_ARGS) { + int r, rx, ry, np; + if ((parts[i].temp>400&&(9+parts[i].temp/40)>rand()%100000&&parts[i].life==0&&!pmap[y-1][x])||parts[i].ctype==PT_DUST) + { + np = sim->create_part(-1, x , y-1 , PT_FWRK); + if (np!=-1) + { + parts[np].vy = rand()%8-22; + parts[np].vx = rand()%20-rand()%20; + parts[np].life=rand()%15+25; + parts[np].dcolour = parts[i].dcolour; + sim->kill_part(i); + return 1; + } + } + if (parts[i].life>=45) + parts[i].life=0; + if ((parts[i].life<3&&parts[i].life>0)||(parts[i].vy>6&&parts[i].life>0)) + { + int q = (rand()%255+1); + int w = (rand()%255+1); + int e = (rand()%255+1); + for (rx=-1; rx<2; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + if (5>=rand()%8) + { + if (!pmap[y+ry][x+rx]) + { + np = sim->create_part(-1, x+rx, y+ry , PT_DUST); + sim->pv[y/CELL][x/CELL] += 2.00f*CFDS; + if (np!=-1) + { + parts[np].vy = -(rand()%10-1); + parts[np].vx = ((rand()%2)*2-1)*rand()%(5+5)+(parts[i].vx)*2 ; + parts[np].life= rand()%37+18; + parts[np].tmp=q; + parts[np].flags=w; + parts[np].ctype=e; + parts[np].temp= rand()%20+6000; + parts[np].dcolour = parts[i].dcolour; + } + } + } + } + sim->kill_part(i); + return 1; + } + return 0; +} diff --git a/src/elements/gbmb.cpp b/src/elements/gbmb.cpp new file mode 100644 index 0000000..95afc4e --- /dev/null +++ b/src/elements/gbmb.cpp @@ -0,0 +1,26 @@ +#include "element.h" +int update_GBMB(UPDATE_FUNC_ARGS) { + int rx,ry,r; + if (parts[i].life<=0) + { + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + { + r = pmap[y+ry][x+rx]; + if(!r) + continue; + if((r&0xFF)!=PT_BOMB && (r&0xFF)!=PT_GBMB && + (r&0xFF)!=PT_CLNE && (r&0xFF)!=PT_PCLN && + (r&0xFF)!=PT_DMND) + { + parts[i].life=60; + break; + } + } + } + if(parts[i].life>20) + sim->gravmap[(y/CELL)*(XRES/CELL)+(x/CELL)] = 20; + if(parts[i].life<20 && parts[i].life>=1) + sim->gravmap[(y/CELL)*(XRES/CELL)+(x/CELL)] = -80; + return 0; +} diff --git a/src/elements/glas.cpp b/src/elements/glas.cpp new file mode 100644 index 0000000..e8c0a6c --- /dev/null +++ b/src/elements/glas.cpp @@ -0,0 +1,11 @@ +#include "element.h" + +int update_GLAS(UPDATE_FUNC_ARGS) { + parts[i].pavg[0] = parts[i].pavg[1]; + parts[i].pavg[1] = sim->pv[y/CELL][x/CELL]; + if (parts[i].pavg[1]-parts[i].pavg[0] > 0.25f || parts[i].pavg[1]-parts[i].pavg[0] < -0.25f) + { + sim->part_change_type(i,x,y,PT_BGLA); + } + return 0; +} diff --git a/src/elements/glow.cpp b/src/elements/glow.cpp new file mode 100644 index 0000000..e83e2f4 --- /dev/null +++ b/src/elements/glow.cpp @@ -0,0 +1,28 @@ +#include "element.h" + +int update_GLOW(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_WATR&&5>(rand()%2000)) + { + parts[i].type = PT_NONE; + sim->part_change_type(r>>8,x+rx,y+ry,PT_DEUT); + parts[r>>8].life = 10; + } + } + parts[i].ctype = sim->pv[y/CELL][x/CELL]*16; + + parts[i].tmp = abs((int)((sim->vx[y/CELL][x/CELL]+sim->vy[y/CELL][x/CELL])*16.0f)) + abs((int)((parts[i].vx+parts[i].vy)*64.0f)); + //printf("%f %f\n", parts[i].vx, parts[i].vy); + if (parts[i].type==PT_NONE) { + sim->kill_part(i); + return 1; + } + return 0; +} diff --git a/src/elements/goo.cpp b/src/elements/goo.cpp new file mode 100644 index 0000000..c305182 --- /dev/null +++ b/src/elements/goo.cpp @@ -0,0 +1,13 @@ +#include "element.h" + +int update_GOO(UPDATE_FUNC_ARGS) { + if (!parts[i].life && sim->pv[y/CELL][x/CELL]>1.0f) + parts[i].life = rand()%80+300; + if (parts[i].life) + { + float advection = 0.1f; + parts[i].vx += advection*sim->vx[y/CELL][x/CELL]; + parts[i].vy += advection*sim->vy[y/CELL][x/CELL]; + } + return 0; +} diff --git a/src/elements/gpmp.cpp b/src/elements/gpmp.cpp new file mode 100644 index 0000000..dcde7a9 --- /dev/null +++ b/src/elements/gpmp.cpp @@ -0,0 +1,34 @@ +#include "element.h" + +int update_GPMP(UPDATE_FUNC_ARGS) { + int r, rx, ry; + if (parts[i].life>0 && parts[i].life!=10) + parts[i].life--; + if (parts[i].life==10) + { + if (parts[i].temp>=256.0+273.15) + parts[i].temp=256.0+273.15; + if (parts[i].temp<= -256.0+273.15) + parts[i].temp = -256.0+273.15; + + sim->gravmap[(y/CELL)*(XRES/CELL)+(x/CELL)] = 0.2f*(parts[i].temp-273.15); + if (y+CELL<YRES && sim->pv[y/CELL+1][x/CELL]<(parts[i].temp-273.15)) + sim->gravmap[(y/CELL+1)*(XRES/CELL)+(x/CELL)] += 0.1f*((parts[i].temp-273.15)-sim->gravmap[(y/CELL+1)*(XRES/CELL)+(x/CELL)]); + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_GPMP) + { + if (parts[r>>8].life<10&&parts[r>>8].life>0) + parts[i].life = 9; + else if (parts[r>>8].life==0) + parts[r>>8].life = 10; + } + } + } + return 0; +} diff --git a/src/elements/graphics_default.cpp b/src/elements/graphics_default.cpp new file mode 100644 index 0000000..1270977 --- /dev/null +++ b/src/elements/graphics_default.cpp @@ -0,0 +1,23 @@ +#include "element.h" + +int graphics_DEFAULT(GRAPHICS_FUNC_ARGS) +{ + int t = cpart->type; + //Property based defaults + if(ren->sim->ptypes[t].properties & PROP_RADIOACTIVE) *pixel_mode |= PMODE_GLOW; + if(ren->sim->ptypes[t].properties & TYPE_LIQUID) + { + *pixel_mode |= PMODE_BLUR; + } + if(ren->sim->ptypes[t].properties & TYPE_GAS) + { + *pixel_mode &= ~PMODE; + *pixel_mode |= FIRE_BLEND; + *firer = *colr/2; + *fireg = *colg/2; + *fireb = *colb/2; + *firea = 125; + *pixel_mode |= DECO_FIRE; + } + return 1; +} diff --git a/src/elements/h2.cpp b/src/elements/h2.cpp new file mode 100644 index 0000000..da39ad0 --- /dev/null +++ b/src/elements/h2.cpp @@ -0,0 +1,34 @@ +#include "element.h" + +int update_H2(UPDATE_FUNC_ARGS) +{ + int r,rx,ry,rt; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + rt = (r&0xFF); + if (!r) + continue; + if (sim->pv[y/CELL][x/CELL] > 8.0f && rt == PT_DESL) // This will not work. DESL turns to fire above 5.0 pressure + { + sim->part_change_type(r>>8,x+rx,y+ry,PT_WATR); + sim->part_change_type(i,x,y,PT_OIL); + } + if ((r&0xFF)==PT_FIRE) + { + parts[r>>8].temp=2473.15; + if(parts[r>>8].tmp&0x02) + parts[r>>8].temp=3473; + parts[r>>8].tmp |= 1; + } + if ((r&0xFF)==PT_FIRE || (r&0xFF)==PT_PLSM || (r&0xFF)==PT_LAVA) + { + sim->create_part(i,x,y,PT_FIRE); + parts[i].temp+=(rand()/(RAND_MAX/100)); + parts[i].tmp |= 1; + } + } + return 0; +} diff --git a/src/elements/hswc.cpp b/src/elements/hswc.cpp new file mode 100644 index 0000000..c727395 --- /dev/null +++ b/src/elements/hswc.cpp @@ -0,0 +1,26 @@ +#include "element.h" + +int update_HSWC(UPDATE_FUNC_ARGS) { + int r, rx, ry; + if (parts[i].life>0 && parts[i].life!=10) + parts[i].life--; + if (parts[i].life==10) + { + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_HSWC) + { + if (parts[r>>8].life<10&&parts[r>>8].life>0) + parts[i].life = 9; + else if (parts[r>>8].life==0) + parts[r>>8].life = 10; + } + } + } + return 0; +} diff --git a/src/elements/ice.cpp b/src/elements/ice.cpp new file mode 100644 index 0000000..aece17b --- /dev/null +++ b/src/elements/ice.cpp @@ -0,0 +1,23 @@ +#include "element.h" + +int update_ICEI(UPDATE_FUNC_ARGS) { //currently used for snow as well + int r, rx, ry; + if (parts[i].ctype==PT_FRZW)//get colder if it is from FRZW + { + parts[i].temp = restrict_flt(parts[i].temp-1.0f, MIN_TEMP, MAX_TEMP); + } + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_SALT || (r&0xFF)==PT_SLTW) && 1>(rand()%1000)) + { + sim->part_change_type(i,x,y,PT_SLTW); + sim->part_change_type(r>>8,x+rx,y+ry,PT_SLTW); + } + } + return 0; +} diff --git a/src/elements/ignt.cpp b/src/elements/ignt.cpp new file mode 100644 index 0000000..1d7ea64 --- /dev/null +++ b/src/elements/ignt.cpp @@ -0,0 +1,44 @@ +#include "element.h" + +int update_IGNT(UPDATE_FUNC_ARGS) { + int r, rx, ry; + if(parts[i].tmp==0) + { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_FIRE || (r&0xFF)==PT_PLSM) + { + parts[i].tmp = 1; + } + else if ((r&0xFF)==PT_SPRK || (r&0xFF)==PT_LIGH || ((r&0xFF)==PT_IGNT && parts[r>>8].life==1)) + { + parts[i].tmp = 1; + } + } + } + else if(parts[i].life > 0) + { + if(rand()%3) + { + int nb = sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, PT_BOMB); + if (nb!=-1) { + parts[nb].tmp = 1; + parts[nb].life = 30; + parts[nb].vx = rand()%20-10; + parts[nb].vy = rand()%20-10; + parts[nb].temp = restrict_flt(400.0f+parts[i].temp-273.15, MIN_TEMP, MAX_TEMP); + } + } + else + { + sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, PT_FIRE); + } + parts[i].life--; + } + return 0; +} diff --git a/src/elements/iron.cpp b/src/elements/iron.cpp new file mode 100644 index 0000000..b887cf8 --- /dev/null +++ b/src/elements/iron.cpp @@ -0,0 +1,25 @@ +#include "element.h" + +int update_IRON(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((((r&0xFF) == PT_SALT && 15>(rand()/(RAND_MAX/700))) || + ((r&0xFF) == PT_SLTW && 30>(rand()/(RAND_MAX/2000))) || + ((r&0xFF) == PT_WATR && 5 >(rand()/(RAND_MAX/6000))) || + ((r&0xFF) == PT_O2 && 2 >(rand()/(RAND_MAX/500))) || + ((r&0xFF) == PT_LO2))&& + (!(parts[i].life)) + ) + { + sim->part_change_type(i,x,y,PT_BMTL); + parts[i].tmp=(rand()/(RAND_MAX/10))+20; + } + } + return 0; +} diff --git a/src/elements/isz.cpp b/src/elements/isz.cpp new file mode 100644 index 0000000..25446d2 --- /dev/null +++ b/src/elements/isz.cpp @@ -0,0 +1,14 @@ +#include "element.h" + +int update_ISZ(UPDATE_FUNC_ARGS) { // for both ISZS and ISOZ + float rr, rrr; + if (1>rand()%200 && ((int)(-4.0f*(sim->pv[y/CELL][x/CELL])))>(rand()%1000)) + { + sim->create_part(i, x, y, PT_PHOT); + rr = (rand()%228+128)/127.0f; + rrr = (rand()%360)*3.14159f/180.0f; + parts[i].vx = rr*cosf(rrr); + parts[i].vy = rr*sinf(rrr); + } + return 0; +} diff --git a/src/elements/lava.cpp b/src/elements/lava.cpp new file mode 100644 index 0000000..3d7827b --- /dev/null +++ b/src/elements/lava.cpp @@ -0,0 +1,19 @@ +#include "element.h" + +int graphics_LAVA(GRAPHICS_FUNC_ARGS) +{ + *colr = cpart->life * 2 + 0xE0; + *colg = cpart->life * 1 + 0x50; + *colb = cpart->life / 2 + 0x10; + if (*colr>255) *colr = 255; + if (*colg>192) *colg = 192; + if (*colb>128) *colb = 128; + *firea = 40; + *firer = *colr; + *fireg = *colg; + *fireb = *colb; + *pixel_mode |= FIRE_ADD; + *pixel_mode |= PMODE_BLUR; + //Returning 0 means dynamic, do not cache + return 0; +} diff --git a/src/elements/lcry.cpp b/src/elements/lcry.cpp new file mode 100644 index 0000000..546c2ca --- /dev/null +++ b/src/elements/lcry.cpp @@ -0,0 +1,61 @@ +#include "element.h" + +int update_LCRY(UPDATE_FUNC_ARGS) +{ + int r, rx, ry; + if(parts[i].tmp==1 || parts[i].tmp==0) + { + if(parts[i].tmp==1) + { + if(parts[i].life<=0) + parts[i].tmp = 0; + else + { + parts[i].life-=2; + if(parts[i].life < 0) + parts[i].life = 0; + parts[i].tmp2 = parts[i].life; + } + } + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_LCRY && parts[r>>8].tmp == 3) + { + parts[r>>8].tmp = 1; + } + } + } + else if(parts[i].tmp==2 || parts[i].tmp==3) + { + if(parts[i].tmp==2) + { + if(parts[i].life>=10) + parts[i].tmp = 3; + else + { + parts[i].life+=2; + if(parts[i].life > 10) + parts[i].life = 10; + parts[i].tmp2 = parts[i].life; + } + } + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_LCRY && parts[r>>8].tmp == 0) + { + parts[r>>8].tmp = 2; + } + } + } + return 0; +} diff --git a/src/elements/legacy.cpp b/src/elements/legacy.cpp new file mode 100644 index 0000000..dd58173 --- /dev/null +++ b/src/elements/legacy.cpp @@ -0,0 +1,120 @@ +#include "element.h" + +// Interactions which only occur when legacy_enable is on +int update_legacy_all(UPDATE_FUNC_ARGS) { + int r, rx, ry, rt; + int t = parts[i].type; + if (!sim->legacy_enable) return 0; + if (t==PT_WTRV) { + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && + x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_WATR||(r&0xFF)==PT_DSTW||(r&0xFF)==PT_SLTW) && 1>(rand()%1000)) + { + sim->part_change_type(i,x,y,PT_WATR); + sim->part_change_type(r>>8,x+rx,y+ry,PT_WATR); + } + if (((r&0xFF)==PT_ICEI || (r&0xFF)==PT_SNOW) && 1>(rand()%1000)) + { + sim->part_change_type(i,x,y,PT_WATR); + if (1>(rand()%1000)) + sim->part_change_type(r>>8,x+rx,y+ry,PT_WATR); + } + } + } + else if (t==PT_WATR) { + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && + x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_FIRE || (r&0xFF)==PT_LAVA) && 1>(rand()%10)) + { + sim->part_change_type(i,x,y,PT_WTRV); + } + } + } + else if (t==PT_SLTW) { + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && + x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_FIRE || (r&0xFF)==PT_LAVA) && 1>(rand()%10)) + { + sim->part_change_type(i,x,y,PT_SALT); + sim->part_change_type(r>>8,x+rx,y+ry,PT_WTRV); + } + } + } + else if (t==PT_DSTW) { + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && + x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_FIRE || (r&0xFF)==PT_LAVA) && 1>(rand()%10)) + { + sim->part_change_type(i,x,y,PT_WTRV); + } + } + } + else if (t==PT_ICEI) { + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_WATR || (r&0xFF)==PT_DSTW) && 1>(rand()%1000)) + { + sim->part_change_type(i,x,y,PT_ICEI); + sim->part_change_type(r>>8,x+rx,y+ry,PT_ICEI); + } + } + } + else if (t==PT_SNOW) { + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_WATR || (r&0xFF)==PT_DSTW) && 1>(rand()%1000)) + { + sim->part_change_type(i,x,y,PT_ICEI); + sim->part_change_type(r>>8,x+rx,y+ry,PT_ICEI); + } + if (((r&0xFF)==PT_WATR || (r&0xFF)==PT_DSTW) && 15>(rand()%1000)) + sim->part_change_type(i,x,y,PT_WATR); + } + } + if (t==PT_WTRV && sim->pv[y/CELL][x/CELL]>4.0f) + sim->part_change_type(i,x,y,PT_DSTW); + if (t==PT_OIL && sim->pv[y/CELL][x/CELL]<-6.0f) + sim->part_change_type(i,x,y,PT_GAS); + if (t==PT_GAS && sim->pv[y/CELL][x/CELL]>6.0f) + sim->part_change_type(i,x,y,PT_OIL); + if (t==PT_DESL && sim->pv[y/CELL][x/CELL]>12.0f) + { + sim->part_change_type(i,x,y,PT_FIRE); + parts[i].life = rand()%50+120; + } + return 0; +} diff --git a/src/elements/ligh.cpp b/src/elements/ligh.cpp new file mode 100644 index 0000000..8108c4b --- /dev/null +++ b/src/elements/ligh.cpp @@ -0,0 +1,295 @@ +#include "element.h" + +#define LIGHTING_POWER 0.65 + +int LIGH_nearest_part(Simulation * sim, int ci, int max_d) +{ + int distance = (max_d!=-1)?max_d:MAX_DISTANCE; + int ndistance = 0; + int id = -1; + int i = 0; + int cx = (int)sim->parts[ci].x; + int cy = (int)sim->parts[ci].y; + for (i=0; i<=sim->parts_lastActiveIndex; i++) + { + if (sim->parts[i].type && sim->parts[i].life && i!=ci && sim->parts[i].type!=PT_LIGH && sim->parts[i].type!=PT_THDR && sim->parts[i].type!=PT_NEUT && sim->parts[i].type!=PT_PHOT) + { + ndistance = abs(cx-sim->parts[i].x)+abs(cy-sim->parts[i].y);// Faster but less accurate Older: sqrt(pow(cx-parts[i].x, 2)+pow(cy-parts[i].y, 2)); + if (ndistance<distance) + { + distance = ndistance; + id = i; + } + } + } + return id; +} + +int contact_part(Simulation * sim, int i, int tp) +{ + int x=sim->parts[i].x, y=sim->parts[i].y; + int r,rx,ry; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = sim->pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==tp) + return r>>8; + } + return -1; +} + +void create_line_par(Simulation * sim, int x1, int y1, int x2, int y2, int c, int temp, int life, int tmp, int tmp2) +{ + int cp=abs(y2-y1)>abs(x2-x1), x, y, dx, dy, sy; + float e, de; + if (c==WL_EHOLE || c==WL_ALLOWGAS || c==WL_ALLOWALLELEC || c==WL_ALLOWSOLID || c==WL_ALLOWAIR || c==WL_WALL || c==WL_DESTROYALL || c==WL_ALLOWLIQUID || c==WL_FAN || c==WL_STREAM || c==WL_DETECT || c==WL_EWALL || c==WL_WALLELEC) + return; // this function only for particles, no walls + 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++) + { + int p; + if (cp) + p = sim->create_part(-1, y, x, c); + else + p = sim->create_part(-1, x, y,c); + if (p!=-1) + { + sim->parts[p].life = life; + sim->parts[p].temp = temp; + sim->parts[p].tmp = tmp; + sim->parts[p].tmp2 = tmp2; + } + e += de; + if (e >= 0.5f) + { + y += sy; + e -= 1.0f; + } + } +} + +int update_LIGH(UPDATE_FUNC_ARGS) +{ + /* + * + * tmp2: + * -1 - part will be removed + * 0 - "branches" of the lightning + * 1 - bending + * 2 - branching + * 3 - transfer spark or make destruction + * 4 - first pixel + * + * life - "thickness" of lighting (but anyway one pixel) + * + * tmp - angle of lighting + * + */ + int r,rx,ry, multipler, powderful; + float angle, angle2=-1; + int pNear = 0; + powderful = powderful = parts[i].temp*(1+parts[i].life/40)*LIGHTING_POWER; + update_PYRO(UPDATE_FUNC_SUBCALL_ARGS); + if (sim->aheat_enable) + { + sim->hv[y/CELL][x/CELL]+=powderful/50; + if (sim->hv[y/CELL][x/CELL]>MAX_TEMP) + sim->hv[y/CELL][x/CELL]=MAX_TEMP; + } + + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_LIGH && (r&0xFF)!=PT_TESC) + { + if ((r&0xFF)!=PT_CLNE&&(r&0xFF)!=PT_THDR&&(r&0xFF)!=PT_DMND&&(r&0xFF)!=PT_FIRE&&(r&0xFF)!=PT_NEUT&&(r&0xFF)!=PT_PHOT) + { + if ((sim->ptypes[r&0xFF].properties&PROP_CONDUCTS) && parts[r>>8].life==0) + { + sim->create_part(r>>8,x+rx,y+ry,PT_SPRK); + } + sim->pv[y/CELL][x/CELL] += powderful/400; + if (sim->ptypes[r&0xFF].hconduct) parts[r>>8].temp = restrict_flt(parts[r>>8].temp+powderful/1.5, MIN_TEMP, MAX_TEMP); + } + if ((r&0xFF)==PT_DEUT || (r&0xFF)==PT_PLUT) // start nuclear reactions + { + parts[r>>8].temp = restrict_flt(parts[r>>8].temp+powderful, MIN_TEMP, MAX_TEMP); + sim->pv[y/CELL][x/CELL] +=powderful/35; + if (rand()%3==0) + { + sim->part_change_type(r>>8,x+rx,y+ry,PT_NEUT); + parts[r>>8].life = rand()%480+480; + parts[r>>8].vx=rand()%10-5; + parts[r>>8].vy=rand()%10-5; + } + } + if ((r&0xFF)==PT_COAL || (r&0xFF)==PT_BCOL) // ignite coal + { + if (parts[r>>8].life>100) { + parts[r>>8].life = 99; + } + } + if (sim->ptypes[r&0xFF].hconduct) + parts[r>>8].temp = restrict_flt(parts[r>>8].temp+powderful/10, MIN_TEMP, MAX_TEMP); + if (((r&0xFF)==PT_STKM && sim->player.elem!=PT_LIGH) || ((r&0xFF)==PT_STKM2 && sim->player2.elem!=PT_LIGH)) + { + parts[r>>8].life-=powderful/100; + } + } + } + if (parts[i].tmp2==3) + { + parts[i].tmp2=0; + return 1; + } + + if (parts[i].tmp2==-1) + { + sim->kill_part(i); + return 1; + } + if (parts[i].tmp2<=0 || parts[i].life<=1) + { + if (parts[i].tmp2>0) + parts[i].tmp2=0; + parts[i].tmp2--; + return 1; + } + if (parts[i].tmp2<=-2) + { + sim->kill_part(i); + return 1; + } + + angle2=-1; + + pNear = LIGH_nearest_part(sim, i, parts[i].life*2.5); + if (pNear!=-1) + { + int t=parts[pNear].type; + float n_angle; // angle to nearest part + rx=parts[pNear].x-x; + ry=parts[pNear].y-y; + if (rx*rx+ry*ry!=0) + n_angle = asin(-ry/sqrt(rx*rx+ry*ry)); + else + n_angle = 0; + if (n_angle<0) + n_angle+=M_PI*2; + if (parts[i].life<5 || fabs(n_angle-parts[i].tmp*M_PI/180)<M_PI*0.8) // lightning strike + { + create_line_par(sim, x, y, x+rx, y+ry, PT_LIGH, parts[i].temp, parts[i].life, parts[i].tmp-90, 0); + + if (t!=PT_TESC) + { + pNear=contact_part(sim, pNear, PT_LIGH); + if (pNear!=-1) + { + parts[pNear].tmp2=3; + parts[pNear].life=(int)(1.0*parts[i].life/2-1); + parts[pNear].tmp=parts[i].tmp-180; + parts[pNear].temp=parts[i].temp; + } + } + } + else pNear=-1; + } + + //if (parts[i].tmp2==1/* || near!=-1*/) + //angle=0;//parts[i].tmp-30+rand()%60; + angle = parts[i].tmp-30+rand()%60; + if (angle<0) + angle+=360; + if (angle>=360) + angle-=360; + if (parts[i].tmp2==2 && pNear==-1) + { + angle2=angle+100-rand()%200; + if (angle2<0) + angle2+=360; + if (angle2>=360) + angle-=360; + } + + multipler=parts[i].life*1.5+rand()%((int)(parts[i].life+1)); + rx=cos(angle*M_PI/180)*multipler; + ry=-sin(angle*M_PI/180)*multipler; + create_line_par(sim, x, y, x+rx, y+ry, PT_LIGH, parts[i].temp, parts[i].life, angle, 0); + + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if ((r&0xFF)==PT_LIGH) + { + parts[r>>8].tmp2=1+(rand()%200>parts[i].tmp2*parts[i].tmp2/10+60); + parts[r>>8].life=(int)(1.0*parts[i].life/1.5-rand()%2); + parts[r>>8].tmp=angle; + parts[r>>8].temp=parts[i].temp; + } + } + + if (angle2!=-1) + { + multipler=parts[i].life*1.5+rand()%((int)(parts[i].life+1)); + rx=cos(angle2*M_PI/180)*multipler; + ry=-sin(angle2*M_PI/180)*multipler; + create_line_par(sim, x, y, x+rx, y+ry, PT_LIGH, parts[i].temp, parts[i].life, angle2, 0); + + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if ((r&0xFF)==PT_LIGH) + { + parts[r>>8].tmp2=1+(rand()%200>parts[i].tmp2*parts[i].tmp2/10+40); + parts[r>>8].life=(int)(1.0*parts[i].life/1.5-rand()%2); + parts[r>>8].tmp=angle; + parts[r>>8].temp=parts[i].temp; + } + } + } + + parts[i].tmp2=-1; + return 1; +} +int graphics_LIGH(GRAPHICS_FUNC_ARGS) +{ + *colr = 235; + *colg = 245; + *colb = 255; + *pixel_mode |= PMODE_GLOW; + return 1; +} diff --git a/src/elements/merc.cpp b/src/elements/merc.cpp new file mode 100644 index 0000000..2df113b --- /dev/null +++ b/src/elements/merc.cpp @@ -0,0 +1,70 @@ +#include "element.h" + +int update_MERC(UPDATE_FUNC_ARGS) { + int r, rx, ry, trade, np; + int maxtmp = ((10000/(parts[i].temp + 1))-1); + if ((10000%((int)parts[i].temp+1))>rand()%((int)parts[i].temp+1)) + maxtmp ++; + if (parts[i].tmp < maxtmp) + { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r || (parts[i].tmp >=maxtmp)) + continue; + if ((r&0xFF)==PT_MERC&&33>=rand()/(RAND_MAX/100)+1) + { + if ((parts[i].tmp + parts[r>>8].tmp + 1) <= maxtmp) + { + parts[i].tmp += parts[r>>8].tmp + 1; + sim->kill_part(r>>8); + } + } + } + } + else + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (parts[i].tmp<=maxtmp) + continue; + if ((!r)&&parts[i].tmp>=1)//if nothing then create deut + { + np = sim->create_part(-1,x+rx,y+ry,PT_MERC); + if (np<0) continue; + parts[i].tmp--; + parts[np].temp = parts[i].temp; + parts[np].tmp = 0; + } + } + for ( trade = 0; trade<4; trade ++) + { + rx = rand()%5-2; + ry = rand()%5-2; + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_MERC&&(parts[i].tmp>parts[r>>8].tmp)&&parts[i].tmp>0)//diffusion + { + int temp = parts[i].tmp - parts[r>>8].tmp; + if (temp ==1) + { + parts[r>>8].tmp ++; + parts[i].tmp --; + } + else if (temp>0) + { + parts[r>>8].tmp += temp/2; + parts[i].tmp -= temp/2; + } + } + } + } + return 0; +} diff --git a/src/elements/mort.cpp b/src/elements/mort.cpp new file mode 100644 index 0000000..bbb6264 --- /dev/null +++ b/src/elements/mort.cpp @@ -0,0 +1,6 @@ +#include "element.h" + +int update_MORT(UPDATE_FUNC_ARGS) { + sim->create_part(-1, x, y-1, PT_SMKE); + return 0; +} diff --git a/src/elements/nbhl.cpp b/src/elements/nbhl.cpp new file mode 100644 index 0000000..056313c --- /dev/null +++ b/src/elements/nbhl.cpp @@ -0,0 +1,6 @@ +#include "element.h" + +int update_NBHL(UPDATE_FUNC_ARGS) { + sim->gravmap[(y/CELL)*(XRES/CELL)+(x/CELL)] += 0.1f; + return 0; +} diff --git a/src/elements/neut.cpp b/src/elements/neut.cpp new file mode 100644 index 0000000..a48fc09 --- /dev/null +++ b/src/elements/neut.cpp @@ -0,0 +1,145 @@ +#include "element.h" + + +int create_n_parts(Simulation * sim, int n, int x, int y, float vx, float vy, float temp, int t)//testing a new deut create part +{ + int i, c; + n = (n/50); + if (n<1) { + n = 1; + } + if (n>340) { + n = 340; + } + if (x<0 || y<0 || x>=XRES || y>=YRES || t<0 || t>=PT_NUM) + return -1; + + for (c=0; c<n; c++) { + float r = (rand()%128+128)/127.0f; + float a = (rand()%360)*M_PI/180.0f; + if (sim->pfree == -1) + return -1; + i = sim->pfree; + sim->pfree = sim->parts[i].life; + if (i>sim->parts_lastActiveIndex) sim->parts_lastActiveIndex = i; + + sim->parts[i].x = (float)x; + sim->parts[i].y = (float)y; + sim->parts[i].type = t; + sim->parts[i].life = rand()%480+480; + sim->parts[i].vx = r*cosf(a); + sim->parts[i].vy = r*sinf(a); + sim->parts[i].ctype = 0; + sim->parts[i].temp = temp; + sim->parts[i].tmp = 0; + if (t!=PT_STKM&&t!=PT_STKM2 && t!=PT_PHOT && t!=PT_NEUT && !sim->pmap[y][x]) + sim->pmap[y][x] = t|(i<<8); + else if ((t==PT_PHOT||t==PT_NEUT) && !sim->photons[y][x]) + sim->photons[y][x] = t|(i<<8); + + sim->pv[y/CELL][x/CELL] += 6.0f * CFDS; + } + return 0; +} + +int update_NEUT(UPDATE_FUNC_ARGS) { + int r, rx, ry, rt; + int pressureFactor = 3 + (int)sim->pv[y/CELL][x/CELL]; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_WATR || (r&0xFF)==PT_ICEI || (r&0xFF)==PT_SNOW) + { + parts[i].vx *= 0.995; + parts[i].vy *= 0.995; + } + if ((r&0xFF)==PT_PLUT && pressureFactor>(rand()%1000)) + { + if (33>rand()%100) + { + sim->create_part(r>>8, x+rx, y+ry, rand()%3 ? PT_LAVA : PT_URAN); + parts[r>>8].temp = MAX_TEMP; + if (parts[r>>8].type==PT_LAVA) { + parts[r>>8].tmp = 100; + parts[r>>8].ctype = PT_PLUT; + } + } + else + { + sim->create_part(r>>8, x+rx, y+ry, PT_NEUT); + parts[r>>8].vx = 0.25f*parts[r>>8].vx + parts[i].vx; + parts[r>>8].vy = 0.25f*parts[r>>8].vy + parts[i].vy; + } + sim->pv[y/CELL][x/CELL] += 10.0f * CFDS; //Used to be 2, some people said nukes weren't powerful enough + update_PYRO(UPDATE_FUNC_SUBCALL_ARGS); + } +#ifdef SDEUT + else if ((r&0xFF)==PT_DEUT && (pressureFactor+1+(parts[r>>8].life/100))>(rand()%1000)) + { + create_n_parts(sim, parts[r>>8].life, x+rx, y+ry, parts[i].vx, parts[i].vy, restrict_flt(parts[r>>8].temp + parts[r>>8].life*500, MIN_TEMP, MAX_TEMP), PT_NEUT); + sim->kill_part(r>>8); + } +#else + else if ((r&0xFF)==PT_DEUT && (pressureFactor+1)>(rand()%1000)) + { + create_part(r>>8, x+rx, y+ry, PT_NEUT); + parts[r>>8].vx = 0.25f*parts[r>>8].vx + parts[i].vx; + parts[r>>8].vy = 0.25f*parts[r>>8].vy + parts[i].vy; + if (parts[r>>8].life>0) + { + parts[r>>8].life --; + parts[r>>8].temp = restrict_flt(parts[r>>8].temp + parts[r>>8].life*17, MIN_TEMP, MAX_TEMP); + pv[y/CELL][x/CELL] += 6.0f * CFDS; + } + else + sim.kill_part(r>>8); + } +#endif + else if ((r&0xFF)==PT_GUNP && 15>(rand()%1000)) + sim->part_change_type(r>>8,x+rx,y+ry,PT_DUST); + else if ((r&0xFF)==PT_DYST && 15>(rand()%1000)) + sim->part_change_type(r>>8,x+rx,y+ry,PT_YEST); + else if ((r&0xFF)==PT_YEST) + sim->part_change_type(r>>8,x+rx,y+ry,PT_DYST); + else if ((r&0xFF)==PT_WATR && 15>(rand()%100)) + sim->part_change_type(r>>8,x+rx,y+ry,PT_DSTW); + else if ((r&0xFF)==PT_PLEX && 15>(rand()%1000)) + sim->part_change_type(r>>8,x+rx,y+ry,PT_GOO); + else if ((r&0xFF)==PT_NITR && 15>(rand()%1000)) + sim->part_change_type(r>>8,x+rx,y+ry,PT_DESL); + else if ((r&0xFF)==PT_PLNT && 5>(rand()%100)) + sim->create_part(r>>8, x+rx, y+ry, PT_WOOD); + else if ((r&0xFF)==PT_DESL && 15>(rand()%1000)) + sim->part_change_type(r>>8,x+rx,y+ry,PT_GAS); + else if ((r&0xFF)==PT_COAL && 5>(rand()%100)) + sim->create_part(r>>8, x+rx, y+ry, PT_WOOD); + else if ((r&0xFF)==PT_DUST && 5>(rand()%100)) + sim->part_change_type(r>>8, x+rx, y+ry, PT_FWRK); + else if ((r&0xFF)==PT_FWRK && 5>(rand()%100)) + parts[r>>8].ctype = PT_DUST; + else if ((r&0xFF)==PT_ACID && 5>(rand()%100)) + sim->create_part(r>>8, x+rx, y+ry, PT_ISOZ); + /*if(parts[r>>8].type>1 && parts[r>>8].type!=PT_NEUT && parts[r>>8].type-1!=PT_NEUT && parts[r>>8].type-1!=PT_STKM && + (ptypes[parts[r>>8].type-1].menusection==SC_LIQUID|| + ptypes[parts[r>>8].type-1].menusection==SC_EXPLOSIVE|| + ptypes[parts[r>>8].type-1].menusection==SC_GAS|| + ptypes[parts[r>>8].type-1].menusection==SC_POWDERS) && 15>(rand()%1000)) + parts[r>>8].type--;*/ + } + return 0; +} + +int graphics_NEUT(GRAPHICS_FUNC_ARGS) +{ + *firea = 120; + *firer = 10; + *fireg = 80; + *fireb = 120; + + *pixel_mode |= FIRE_ADD; + return 1; +} diff --git a/src/elements/newgraphics.cpp b/src/elements/newgraphics.cpp new file mode 100644 index 0000000..83da27b --- /dev/null +++ b/src/elements/newgraphics.cpp @@ -0,0 +1,541 @@ +#include "element.h" +#include "hmap.h" + +int graphics_QRTZ(GRAPHICS_FUNC_ARGS) //QRTZ and PQRT +{ + int t = cpart->type, z = cpart->tmp - 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)); + int q = (cpart->temp>ptransitions[t].thv)?ptransitions[t].thv-(ptransitions[t].thv-800.0f):cpart->temp-(ptransitions[t].thv-800.0f); + *colr += sin(frequency*q) * 226 + (z * 16); + *colg += sin(frequency*q*4.55 +3.14) * 34 + (z * 16); + *colb += sin(frequency*q*2.22 +3.14) * 64 + (z * 16); + } + else*/ + { + *colr += z * 16; + *colg += z * 16; + *colb += z * 16; + } + return 0; +} +int graphics_CLST(GRAPHICS_FUNC_ARGS) +{ + int z = cpart->tmp - 5;//speckles! + *colr += z * 16; + *colg += z * 16; + *colb += z * 16; + return 0; +} +int graphics_CBNW(GRAPHICS_FUNC_ARGS) +{ + int z = cpart->tmp2 - 20;//speckles! + *colr += z * 1; + *colg += z * 2; + *colb += z * 8; + return 0; +} +int graphics_SPNG(GRAPHICS_FUNC_ARGS) +{ + *colr -= cpart->life*15; + *colg -= cpart->life*15; + *colb -= cpart->life*15; + if (*colr<=50) + *colr = 50; + if (*colg<=50) + *colg = 50; + if (*colb<=20) + *colb = 20; + return 0; +} +int graphics_LIFE(GRAPHICS_FUNC_ARGS) +{ + pixel pc; + if (cpart->ctype==NGT_LOTE)//colors for life states + { + if (cpart->tmp==2) + pc = PIXRGB(255, 128, 0); + else if (cpart->tmp==1) + pc = PIXRGB(255, 255, 0); + else + pc = PIXRGB(255, 0, 0); + } + else if (cpart->ctype==NGT_FRG2)//colors for life states + { + if (cpart->tmp==2) + pc = PIXRGB(0, 100, 50); + else + pc = PIXRGB(0, 255, 90); + } + else if (cpart->ctype==NGT_STAR)//colors for life states + { + if (cpart->tmp==4) + pc = PIXRGB(0, 0, 128); + else if (cpart->tmp==3) + pc = PIXRGB(0, 0, 150); + else if (cpart->tmp==2) + pc = PIXRGB(0, 0, 190); + else if (cpart->tmp==1) + pc = PIXRGB(0, 0, 230); + else + pc = PIXRGB(0, 0, 70); + } + else if (cpart->ctype==NGT_FROG)//colors for life states + { + if (cpart->tmp==2) + pc = PIXRGB(0, 100, 0); + else + pc = PIXRGB(0, 255, 0); + } + else if (cpart->ctype==NGT_BRAN)//colors for life states + { + if (cpart->tmp==1) + pc = PIXRGB(150, 150, 0); + else + pc = PIXRGB(255, 255, 0); + } else { + //pc = gmenu[cpart->ctype].colour; + } + *colr = PIXR(pc); + *colg = PIXG(pc); + *colb = PIXB(pc); + return 0; +} +int graphics_DUST(GRAPHICS_FUNC_ARGS) +{ + if(cpart->life >= 1) + { + *colr = cpart->flags; + *colg = cpart->tmp; + *colb = cpart->ctype; + if (ren->decorations_enable && cpart->dcolour) + { + int a = (cpart->dcolour>>24)&0xFF; + *colr = (a*((cpart->dcolour>>16)&0xFF) + (255-a)**colr) >> 8; + *colg = (a*((cpart->dcolour>>8)&0xFF) + (255-a)**colg) >> 8; + *colb = (a*((cpart->dcolour)&0xFF) + (255-a)**colb) >> 8; + } + *pixel_mode |= PMODE_GLOW; + /**firea = 255; + *firer = *colr; + *fireg = *colg; + *fireb = *colb;*/ + } + return 0; +} +int graphics_GRAV(GRAPHICS_FUNC_ARGS) +{ + int GRAV_R, GRAV_B, GRAV_G, GRAV_R2, GRAV_B2, GRAV_G2; + *colr = 20; + *colg = 20; + *colb = 20; + if (cpart->vx>0) + { + *colr += (cpart->vx)*GRAV_R; + *colg += (cpart->vx)*GRAV_G; + *colb += (cpart->vx)*GRAV_B; + } + if (cpart->vy>0) + { + *colr += (cpart->vy)*GRAV_G; + *colg += (cpart->vy)*GRAV_B; + *colb += (cpart->vy)*GRAV_R; + + } + if (cpart->vx<0) + { + *colr -= (cpart->vx)*GRAV_B; + *colg -= (cpart->vx)*GRAV_R; + *colb -= (cpart->vx)*GRAV_G; + + } + if (cpart->vy<0) + { + *colr -= (cpart->vy)*GRAV_R2; + *colg -= (cpart->vy)*GRAV_G2; + *colb -= (cpart->vy)*GRAV_B2; + } + return 0; +} +int graphics_WIFI(GRAPHICS_FUNC_ARGS) +{ + float frequency = 0.0628; + int q = cpart->tmp; + *colr = sin(frequency*q + 0) * 127 + 128; + *colg = sin(frequency*q + 2) * 127 + 128; + *colb = sin(frequency*q + 4) * 127 + 128; + return 0; +} +int graphics_PRTI(GRAPHICS_FUNC_ARGS) +{ + *firea = 8; + *firer = 255; + *fireg = 0; + *fireb = 0; + *pixel_mode |= EFFECT_GRAVIN; + *pixel_mode &= ~PMODE; + *pixel_mode |= PMODE_ADD; + return 1; +} +int graphics_PRTO(GRAPHICS_FUNC_ARGS) +{ + *firea = 8; + *firer = 0; + *fireg = 0; + *fireb = 255; + *pixel_mode |= EFFECT_GRAVOUT; + *pixel_mode &= ~PMODE; + *pixel_mode |= PMODE_ADD; + return 1; +} +int graphics_BIZR(GRAPHICS_FUNC_ARGS) //BIZR, BIZRG, BIZRS +{ + int x = 0; + *colg = 0; + *colb = 0; + *colr = 0; + for (x=0; x<12; x++) { + *colr += (cpart->ctype >> (x+18)) & 1; + *colb += (cpart->ctype >> x) & 1; + } + for (x=0; x<12; x++) + *colg += (cpart->ctype >> (x+9)) & 1; + x = 624/(*colr+*colg+*colb+1); + *colr *= x; + *colg *= x; + *colb *= x; + if(fabs(cpart->vx)+fabs(cpart->vy)>0) + { + *firea = 255; + *fireg = *colg/5 * fabs(cpart->vx)+fabs(cpart->vy); + *fireb = *colb/5 * fabs(cpart->vx)+fabs(cpart->vy); + *firer = *colr/5 * fabs(cpart->vx)+fabs(cpart->vy); + *pixel_mode |= FIRE_ADD; + } + return 0; +} +int graphics_INVS(GRAPHICS_FUNC_ARGS) +{ + //pv[ny/CELL][nx/CELL]>4.0f || pv[ny/CELL][nx/CELL]<-4.0f + if(cpart->tmp) + { + *cola = 100; + *colr = 15; + *colg = 0; + *colb = 150; + *pixel_mode &= PMODE; + *pixel_mode |= PMODE_BLEND; + } + return 0; +} +int graphics_ACID(GRAPHICS_FUNC_ARGS) +{ + int s = cpart->life; + if (s>75) s = 75; //These two should not be here. + if (s<49) s = 49; + s = (s-49)*3; + if (s==0) s = 1; + *colr += s*4; + *colg += s*1; + *colb += s*2; + *pixel_mode |= PMODE_BLUR; + return 0; +} +int graphics_FILT(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; + *colg = 0; + *colb = 0; + *colr = 0; + for (x=0; x<12; x++) { + *colr += (cpart->ctype >> (x+18)) & 1; + *colb += (cpart->ctype >> x) & 1; + } + for (x=0; x<12; x++) + *colg += (cpart->ctype >> (x+9)) & 1; + x = 624/(*colr+*colg+*colb+1); + *cola = 127; + *colr *= x; + *colg *= x; + *colb *= x; + *pixel_mode &= ~PMODE; + *pixel_mode |= PMODE_BLEND; + return 0; +} +int graphics_BRAY(GRAPHICS_FUNC_ARGS) +{ + int x, trans = 255; + if(cpart->tmp==0) + { + trans = cpart->life * 7; + if (trans>255) trans = 255; + if (cpart->ctype) { + *colg = 0; + *colb = 0; + *colr = 0; + for (x=0; x<12; x++) { + *colr += (cpart->ctype >> (x+18)) & 1; + *colb += (cpart->ctype >> x) & 1; + } + for (x=0; x<12; x++) + *colg += (cpart->ctype >> (x+9)) & 1; + x = 624/(*colr+*colg+*colb+1); + *colr *= x; + *colg *= x; + *colb *= x; + } + } + else if(cpart->tmp==1) + { + trans = cpart->life/4; + if (trans>255) trans = 255; + if (cpart->ctype) { + *colg = 0; + *colb = 0; + *colr = 0; + for (x=0; x<12; x++) { + *colr += (cpart->ctype >> (x+18)) & 1; + *colb += (cpart->ctype >> x) & 1; + } + for (x=0; x<12; x++) + *colg += (cpart->ctype >> (x+9)) & 1; + x = 624/(*colr+*colg+*colb+1); + *colr *= x; + *colg *= x; + *colb *= x; + } + } + else if(cpart->tmp==2) + { + trans = cpart->life*100; + if (trans>255) trans = 255; + *colr = 255; + *colg = 150; + *colb = 50; + } + *cola = trans; + *pixel_mode &= ~PMODE; + *pixel_mode |= PMODE_BLEND; + return 0; +} +int graphics_SWCH(GRAPHICS_FUNC_ARGS) +{ + if(cpart->life >= 10) + { + *colr = 17; + *colg = 217; + *colb = 24; + *pixel_mode |= PMODE_GLOW; + } + return 0; +} +int graphics_THDR(GRAPHICS_FUNC_ARGS) +{ + *firea = 160; + *fireg = 192; + *fireb = 255; + *firer = 144; + *pixel_mode |= FIRE_ADD; + return 1; +} +int graphics_GLOW(GRAPHICS_FUNC_ARGS) +{ + *firer = restrict_flt(cpart->temp-(275.13f+32.0f), 0, 128)/50.0f; + *fireg = restrict_flt(cpart->ctype, 0, 128)/50.0f; + *fireb = restrict_flt(cpart->tmp, 0, 128)/50.0f; + + *colr = restrict_flt(64.0f+cpart->temp-(275.13f+32.0f), 0, 255); + *colg = restrict_flt(64.0f+cpart->ctype, 0, 255); + *colb = restrict_flt(64.0f+cpart->tmp, 0, 255); + + *pixel_mode |= FIRE_ADD; + return 0; +} +int graphics_LCRY(GRAPHICS_FUNC_ARGS) +{ + if(ren->decorations_enable && cpart->dcolour && cpart->dcolour&0xFF000000) + { + *colr = (cpart->dcolour>>16)&0xFF; + *colg = (cpart->dcolour>>8)&0xFF; + *colb = (cpart->dcolour)&0xFF; + + if(cpart->tmp2<10){ + *colr /= 10-cpart->tmp2; + *colg /= 10-cpart->tmp2; + *colb /= 10-cpart->tmp2; + } + + } + else + { + *colr = *colg = *colb = 0x50+((cpart->tmp2>10?10:cpart->tmp2)*10); + } + *pixel_mode |= NO_DECO; + return 0; + + /*int lifemod = ((cpart->tmp2>10?10:cpart->tmp2)*10); + *colr += lifemod; + *colg += lifemod; + *colb += lifemod; + if(decorations_enable && cpart->dcolour && cpart->dcolour&0xFF000000) + { + lifemod *= 2.5f; + if(lifemod < 40) + lifemod = 40; + *colr = (lifemod*((cpart->dcolour>>16)&0xFF) + (255-lifemod)**colr) >> 8; + *colg = (lifemod*((cpart->dcolour>>8)&0xFF) + (255-lifemod)**colg) >> 8; + *colb = (lifemod*((cpart->dcolour)&0xFF) + (255-lifemod)**colb) >> 8; + } + *pixel_mode |= NO_DECO; + return 0;*/ +} +int graphics_PCLN(GRAPHICS_FUNC_ARGS) +{ + int lifemod = ((cpart->life>10?10:cpart->life)*10); + *colr += lifemod; + *colg += lifemod; + return 0; +} +int graphics_PBCN(GRAPHICS_FUNC_ARGS) +{ + int lifemod = ((cpart->life>10?10:cpart->life)*10); + *colr += lifemod; + *colg += lifemod/2; + return 0; +} +int graphics_DLAY(GRAPHICS_FUNC_ARGS) +{ + int stage = (int)(((float)cpart->life/(cpart->temp-273.15))*100.0f); + *colr += stage; + *colg += stage; + *colb += stage; + return 0; +} +int graphics_HSWC(GRAPHICS_FUNC_ARGS) +{ + int lifemod = ((cpart->life>10?10:cpart->life)*19); + *colr += lifemod; + return 0; +} +int graphics_PVOD(GRAPHICS_FUNC_ARGS) +{ + int lifemod = ((cpart->life>10?10:cpart->life)*16); + *colr += lifemod; + return 0; +} +int graphics_STOR(GRAPHICS_FUNC_ARGS) +{ + if(cpart->tmp){ + *pixel_mode |= PMODE_GLOW; + *colr = 0x50; + *colg = 0xDF; + *colb = 0xDF; + } else { + *colr = 0x20; + *colg = 0xAF; + *colb = 0xAF; + } + return 0; +} +int graphics_PUMP(GRAPHICS_FUNC_ARGS) +{ + int lifemod = ((cpart->life>10?10:cpart->life)*19); + *colb += lifemod; + return 0; +} +int graphics_GPMP(GRAPHICS_FUNC_ARGS) +{ + int lifemod = ((cpart->life>10?10:cpart->life)*19); + *colg += lifemod; + *colb += lifemod; + return 0; +} +int graphics_HFLM(GRAPHICS_FUNC_ARGS) +{ + int caddress = restrict_flt(restrict_flt((float)((int)(cpart->life/2)), 0.0f, 200.0f)*3, 0.0f, (200.0f*3)-3); + *colr = (unsigned char)hflm_data[caddress]; + *colg = (unsigned char)hflm_data[caddress+1]; + *colb = (unsigned char)hflm_data[caddress+2]; + + *firea = 255; + *firer = *colr; + *fireg = *colg; + *fireb = *colb; + + *pixel_mode = PMODE_NONE; //Clear default, don't draw pixel + *pixel_mode |= FIRE_ADD; + //Returning 0 means dynamic, do not cache + return 0; +} +int graphics_FIRW(GRAPHICS_FUNC_ARGS) +{ + if(cpart->tmp>=3) + { + int caddress = restrict_flt(restrict_flt((float)(cpart->tmp-4), 0.0f, 200.0f)*3, 0.0f, (200.0f*3)-3); + *colr = (unsigned char)firw_data[caddress]; + *colg = (unsigned char)firw_data[caddress+1]; + *colb = (unsigned char)firw_data[caddress+2]; + + if (ren->decorations_enable && cpart->dcolour) + { + int a = (cpart->dcolour>>24)&0xFF; + *colr = (a*((cpart->dcolour>>16)&0xFF) + (255-a)**colr) >> 8; + *colg = (a*((cpart->dcolour>>8)&0xFF) + (255-a)**colg) >> 8; + *colb = (a*((cpart->dcolour)&0xFF) + (255-a)**colb) >> 8; + } + + *firea = cpart->life*4; + if(*firea > 240) + *firea = 240; + *firer = *colr; + *fireg = *colg; + *fireb = *colb; + + *pixel_mode = PMODE_NONE; //Clear default, don't draw pixel + *pixel_mode |= FIRE_ADD; + //Returning 0 means dynamic, do not cache + } + else if(cpart->tmp > 0) + { + *pixel_mode |= PMODE_GLOW; + } + return 0; +} +int graphics_GBMB(GRAPHICS_FUNC_ARGS) +{ + if (cpart->life <= 0) { + *pixel_mode |= PMODE_FLARE; + } + else + { + *pixel_mode |= PMODE_SPARK; + } + return 0; +} +int graphics_COAL(GRAPHICS_FUNC_ARGS) //Both COAL and Broken Coal +{ + *colr += (cpart->tmp2-295.15f)/3; + + if (*colr > 170) + *colr = 170; + if (*colr < *colg) + *colr = *colg; + + *colg = *colb = *colr; + + if((cpart->temp-295.15f) > 300.0f-200.0f) + { + float frequency = 3.1415/(2*300.0f-(300.0f-200.0f)); + int q = ((cpart->temp-295.15f)>300.0f)?300.0f-(300.0f-200.0f):(cpart->temp-295.15f)-(300.0f-200.0f); + + *colr += sin(frequency*q) * 226; + *colg += sin(frequency*q*4.55 +3.14) * 34; + *colb += sin(frequency*q*2.22 +3.14) * 64; + } + return 0; +} + diff --git a/src/elements/none.cpp b/src/elements/none.cpp new file mode 100644 index 0000000..50f301f --- /dev/null +++ b/src/elements/none.cpp @@ -0,0 +1,6 @@ +#include "element.h" + +int update_(UPDATE_FUNC_ARGS) { + + return 0; +} diff --git a/src/elements/nptct.cpp b/src/elements/nptct.cpp new file mode 100644 index 0000000..2d68a9b --- /dev/null +++ b/src/elements/nptct.cpp @@ -0,0 +1,7 @@ +#include "element.h" + +int update_NPTCT(UPDATE_FUNC_ARGS) { + if (parts[i].temp>295.0f) + parts[i].temp -= 2.5f; + return 0; +} diff --git a/src/elements/nwhl.cpp b/src/elements/nwhl.cpp new file mode 100644 index 0000000..f53b657 --- /dev/null +++ b/src/elements/nwhl.cpp @@ -0,0 +1,6 @@ +#include "element.h" + +int update_NWHL(UPDATE_FUNC_ARGS) { + sim->gravmap[(y/CELL)*(XRES/CELL)+(x/CELL)] -= 0.1f; + return 0; +} diff --git a/src/elements/pbcn.cpp b/src/elements/pbcn.cpp new file mode 100644 index 0000000..7e99397 --- /dev/null +++ b/src/elements/pbcn.cpp @@ -0,0 +1,83 @@ +#include "element.h" + +int update_PBCN(UPDATE_FUNC_ARGS) { + int r, rx, ry; + if (parts[i].life>0 && parts[i].life!=10) + parts[i].life--; + if (!parts[i].tmp2 && sim->pv[y/CELL][x/CELL]>4.0f) + parts[i].tmp2 = rand()%40+80; + if (parts[i].tmp2) + { + float advection = 0.1f; + parts[i].vx += advection*sim->vx[y/CELL][x/CELL]; + parts[i].vy += advection*sim->vy[y/CELL][x/CELL]; + parts[i].tmp2--; + if(!parts[i].tmp2){ + sim->kill_part(i); + return 1; + } + } + if (parts[i].ctype<=0 || parts[i].ctype>=PT_NUM || (parts[i].ctype==PT_LIFE && (parts[i].tmp<0 || parts[i].tmp>=NGOLALT))) + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES) + { + r = sim->photons[y+ry][x+rx]; + if (!r) + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_CLNE && (r&0xFF)!=PT_PCLN && + (r&0xFF)!=PT_BCLN && (r&0xFF)!=PT_SPRK && + (r&0xFF)!=PT_NSCN && (r&0xFF)!=PT_PSCN && + (r&0xFF)!=PT_STKM && (r&0xFF)!=PT_STKM2 && + (r&0xFF)!=PT_PBCN && (r&0xFF)<PT_NUM) + { + parts[i].ctype = r&0xFF; + if ((r&0xFF)==PT_LIFE) + parts[i].tmp = parts[r>>8].ctype; + } + } + if (parts[i].life==10) + { + + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_PBCN) + { + if (parts[r>>8].life<10&&parts[r>>8].life>0) + parts[i].life = 9; + else if (parts[r>>8].life==0) + parts[r>>8].life = 10; + } + } + } + if (parts[i].ctype>0 && parts[i].ctype<PT_NUM && parts[i].life==10) { + if (parts[i].ctype==PT_PHOT) {//create photons a different way + for (rx=-1; rx<2; rx++) { + for (ry=-1; ry<2; ry++) { + int r = sim->create_part(-1, x+rx, y+ry, parts[i].ctype); + if (r!=-1) { + parts[r].vx = rx*3; + parts[r].vy = ry*3; + } + } + } + } + else if (parts[i].ctype==PT_LIFE) {//create life a different way + for (rx=-1; rx<2; rx++) { + for (ry=-1; ry<2; ry++) { + sim->create_part(-1, x+rx, y+ry, parts[i].ctype|(parts[i].tmp<<8)); + } + } + } else { + sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, parts[i].ctype); + } + } + return 0; +} diff --git a/src/elements/pcln.cpp b/src/elements/pcln.cpp new file mode 100644 index 0000000..cd1ed4f --- /dev/null +++ b/src/elements/pcln.cpp @@ -0,0 +1,73 @@ +#include "element.h" + +int update_PCLN(UPDATE_FUNC_ARGS) { + int r, rx, ry; + if (parts[i].life>0 && parts[i].life!=10) + parts[i].life--; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_SPRK) + { + if (parts[r>>8].ctype==PT_PSCN) + parts[i].life = 10; + else if (parts[r>>8].ctype==PT_NSCN) + parts[i].life = 9; + } + if ((r&0xFF)==PT_PCLN) + { + if (parts[i].life==10&&parts[r>>8].life<10&&parts[r>>8].life>0) + parts[i].life = 9; + else if (parts[i].life==0&&parts[r>>8].life==10) + parts[i].life = 10; + } + } + if (parts[i].ctype<=0 || parts[i].ctype>=PT_NUM || (parts[i].ctype==PT_LIFE && (parts[i].tmp<0 || parts[i].tmp>=NGOLALT))) + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES) + { + r = sim->photons[y+ry][x+rx]; + if (!r) + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_CLNE && (r&0xFF)!=PT_PCLN && + (r&0xFF)!=PT_BCLN && (r&0xFF)!=PT_SPRK && + (r&0xFF)!=PT_NSCN && (r&0xFF)!=PT_PSCN && + (r&0xFF)!=PT_STKM && (r&0xFF)!=PT_STKM2 && + (r&0xFF)!=PT_PBCN && (r&0xFF)<PT_NUM) + { + parts[i].ctype = r&0xFF; + if ((r&0xFF)==PT_LIFE) + parts[i].tmp = parts[r>>8].ctype; + } + } + if (parts[i].ctype>0 && parts[i].ctype<PT_NUM && parts[i].life==10) { + if (parts[i].ctype==PT_PHOT) {//create photons a different way + for (rx=-1; rx<2; rx++) { + for (ry=-1; ry<2; ry++) { + int r = sim->create_part(-1, x+rx, y+ry, parts[i].ctype); + if (r!=-1) { + parts[r].vx = rx*3; + parts[r].vy = ry*3; + } + } + } + } + else if (parts[i].ctype==PT_LIFE) {//create life a different way + for (rx=-1; rx<2; rx++) { + for (ry=-1; ry<2; ry++) { + sim->create_part(-1, x+rx, y+ry, parts[i].ctype|(parts[i].tmp<<8)); + } + } + } else { + sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, parts[i].ctype); + } + } + return 0; +} diff --git a/src/elements/phot.cpp b/src/elements/phot.cpp new file mode 100644 index 0000000..3ed6b5d --- /dev/null +++ b/src/elements/phot.cpp @@ -0,0 +1,84 @@ +#include "element.h" + +int update_PHOT(UPDATE_FUNC_ARGS) { + int r, rt, rx, ry; + float rr, rrr; + parts[i].pavg[0] = x; + parts[i].pavg[1] = y; + if (!parts[i].ctype) { + sim->kill_part(i); + return 1; + } + if (1>rand()%10) update_PYRO(UPDATE_FUNC_SUBCALL_ARGS); + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES && (rx || ry)) { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_ISOZ && 5>(rand()%2000)) + { + parts[i].vx *= 0.90; + parts[i].vy *= 0.90; + sim->create_part(r>>8, x+rx, y+ry, PT_PHOT); + rrr = (rand()%360)*3.14159f/180.0f; + rr = (rand()%128+128)/127.0f; + parts[r>>8].vx = rr*cosf(rrr); + parts[r>>8].vy = rr*sinf(rrr); + sim->pv[y/CELL][x/CELL] -= 15.0f * CFDS; + } + if ((r&0xFF)==PT_ISZS && 5>(rand()%2000)) + { + parts[i].vx *= 0.90; + parts[i].vy *= 0.90; + sim->create_part(r>>8, x+rx, y+ry, PT_PHOT); + rr = (rand()%228+128)/127.0f; + rrr = (rand()%360)*3.14159f/180.0f; + parts[r>>8].vx = rr*cosf(rrr); + parts[r>>8].vy = rr*sinf(rrr); + sim->pv[y/CELL][x/CELL] -= 15.0f * CFDS; + } + } + r = pmap[y][x]; + if((r&0xFF) == PT_QRTZ && r)// && parts[i].ctype==0x3FFFFFFF) + { + float a = (rand()%360)*3.14159f/180.0f; + parts[i].vx = 3.0f*cosf(a); + parts[i].vy = 3.0f*sinf(a); + if(parts[i].ctype == 0x3FFFFFFF) + parts[i].ctype = 0x1F<<(rand()%26); + parts[i].life++; //Delay death + } + //r = pmap[y][x]; + //rt = r&0xFF; + /*if (rt==PT_CLNE || rt==PT_PCLN || rt==PT_BCLN || rt==PT_PBCN) { + if (!parts[r>>8].ctype) + parts[r>>8].ctype = PT_PHOT; + }*/ + + return 0; +} + +int graphics_PHOT(GRAPHICS_FUNC_ARGS) +{ + int x = 0; + *colr = *colg = *colb = 0; + for (x=0; x<12; x++) { + *colr += (cpart->ctype >> (x+18)) & 1; + *colb += (cpart->ctype >> x) & 1; + } + for (x=0; x<12; x++) + *colg += (cpart->ctype >> (x+9)) & 1; + x = 624/(*colr+*colg+*colb+1); + *colr *= x; + *colg *= x; + *colb *= x; + + *firea = 100; + *firer = *colr; + *fireg = *colg; + *fireb = *colb; + + *pixel_mode |= FIRE_ADD; + return 0; +} diff --git a/src/elements/pipe.cpp b/src/elements/pipe.cpp new file mode 100644 index 0000000..08432f5 --- /dev/null +++ b/src/elements/pipe.cpp @@ -0,0 +1,332 @@ +#include "element.h" + +signed char pos_1_rx[] = {-1,-1,-1, 0, 0, 1, 1, 1}; +signed char pos_1_ry[] = {-1, 0, 1,-1, 1,-1, 0, 1}; + +void pushParticle(Simulation * sim, int i, int count, int original) +{ + int rndstore, rnd, rx, ry, r, x, y, np, q, notctype=(((sim->parts[i].ctype)%3)+2); + if ((sim->parts[i].tmp&0xFF) == 0 || count >= 2)//don't push if there is nothing there, max speed of 2 per frame + return; + x = (int)(sim->parts[i].x+0.5f); + y = (int)(sim->parts[i].y+0.5f); + if( !(sim->parts[i].tmp&0x200) ) + { + //normal random push + rndstore = rand(); + // RAND_MAX is at least 32767 on all platforms i.e. pow(8,5)-1 + // so can go 5 cycles without regenerating rndstore + for (q=0; q<3; q++)//try to push twice + { + rnd = rndstore&7; + rndstore = rndstore>>3; + rx = pos_1_rx[rnd]; + ry = pos_1_ry[rnd]; + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES) + { + r = sim->pmap[y+ry][x+rx]; + if (!r) + continue; + else if ((r&0xFF)==PT_PIPE && sim->parts[r>>8].ctype!=notctype && (sim->parts[r>>8].tmp&0xFF)==0) + { + sim->parts[r>>8].tmp = (sim->parts[r>>8].tmp&~0xFF) | (sim->parts[i].tmp&0xFF); + sim->parts[r>>8].temp = sim->parts[i].temp; + sim->parts[r>>8].flags = sim->parts[i].flags; + sim->parts[r>>8].pavg[0] = sim->parts[i].pavg[0]; + sim->parts[r>>8].pavg[1] = sim->parts[i].pavg[1]; + if (r>>8 > original) + sim->parts[r>>8].tmp2 = 1;//skip particle push, normalizes speed + sim->parts[i].tmp &= ~0xFF; + count++; + pushParticle(sim, r>>8,count,original); + } + } + } + } + else //predefined 1 pixel thick pipe movement + { + int coords = 7 - ((sim->parts[i].tmp>>10)&7); + r = sim->pmap[y+ pos_1_ry[coords]][x+ pos_1_rx[coords]]; + if (!r) + { + } + else if ((r&0xFF)==PT_PIPE && sim->parts[r>>8].ctype!=notctype && (sim->parts[r>>8].tmp&0xFF)==0) + { + sim->parts[r>>8].tmp = (sim->parts[r>>8].tmp&~0xFF) | (sim->parts[i].tmp&0xFF); + sim->parts[r>>8].temp = sim->parts[i].temp; + sim->parts[r>>8].flags = sim->parts[i].flags; + sim->parts[r>>8].pavg[0] = sim->parts[i].pavg[0]; + sim->parts[r>>8].pavg[1] = sim->parts[i].pavg[1]; + if (r>>8 > original) + sim->parts[r>>8].tmp2 = 1;//skip particle push, normalizes speed + sim->parts[i].tmp &= ~0xFF; + count++; + pushParticle(sim, r>>8,count,original); + } + + + } + return; +} + +int update_PIPE(UPDATE_FUNC_ARGS) { + int r, rx, ry, np; + int rnd, rndstore; + if (parts[i].ctype>=2 && parts[i].ctype<=4) + { + if (parts[i].life==3) + { + int lastneighbor = -1; + int neighborcount = 0; + int count = 0; + // make automatic pipe pattern + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_PIPE&&parts[r>>8].ctype==1) + { + parts[r>>8].ctype = (((parts[i].ctype)%3)+2);//reverse + parts[r>>8].life = 6; + if ( parts[i].tmp&0x100)//is a single pixel pipe + { + parts[r>>8].tmp |= 0x200;//will transfer to a single pixel pipe + parts[r>>8].tmp |= count<<10;//coords of where it came from + } + neighborcount ++; + lastneighbor = r>>8; + } + else if ((r&0xFF)==PT_PIPE&&parts[r>>8].ctype!=(((parts[i].ctype-1)%3)+2)) + { + neighborcount ++; + lastneighbor = r>>8; + } + count++; + } + if(neighborcount == 1) + parts[lastneighbor].tmp |= 0x100; + } + else + { + if (parts[i].tmp2 == 1)//skip particle push to prevent particle number being higher causeing speed up + { + parts[i].tmp2 = 0 ; + } + else + { + pushParticle(sim, i,0,i); + } + + if (nt)//there is something besides PIPE around current particle + { + rndstore = rand(); + rnd = rndstore&7; + rndstore = rndstore>>3; + rx = pos_1_rx[rnd]; + ry = pos_1_ry[rnd]; + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES) + { + r = pmap[y+ry][x+rx]; + if(!r) + r = sim->photons[y+ry][x+rx]; + if (surround_space && !r && (parts[i].tmp&0xFF)!=0) //creating at end + { + np = sim->create_part(-1,x+rx,y+ry,parts[i].tmp&0xFF); + if (np!=-1) + { + parts[np].temp = parts[i].temp;//pipe saves temp and life now + parts[np].life = parts[i].flags; + parts[np].tmp = parts[i].pavg[0]; + parts[np].ctype = parts[i].pavg[1]; + parts[i].tmp &= ~0xFF; + } + } + //try eating particle at entrance + else if ((parts[i].tmp&0xFF) == 0 && (sim->ptypes[r&0xFF].falldown!= 0 || sim->ptypes[r&0xFF].state == ST_GAS)) + { + if ((r&0xFF)==PT_SOAP) + sim->detach(r>>8); + parts[i].tmp = (parts[i].tmp&~0xFF) | parts[r>>8].type; + parts[i].temp = parts[r>>8].temp; + parts[i].flags = parts[r>>8].life; + parts[i].pavg[0] = parts[r>>8].tmp; + parts[i].pavg[1] = parts[r>>8].ctype; + sim->kill_part(r>>8); + } + else if ((parts[i].tmp&0xFF) == 0 && (r&0xFF)==PT_STOR && parts[r>>8].tmp && (sim->ptypes[parts[r>>8].tmp].falldown!= 0 || sim->ptypes[parts[r>>8].tmp].state == ST_GAS)) + { + parts[i].tmp = parts[r>>8].tmp; + parts[i].temp = parts[r>>8].temp; + parts[i].flags = parts[r>>8].flags; + parts[i].pavg[0] = parts[r>>8].pavg[0]; + parts[i].pavg[1] = parts[r>>8].pavg[1]; + parts[r>>8].tmp = 0; + parts[r>>8].life = 0; + } + } + } + } + } + else if (!parts[i].ctype && parts[i].life<=10) + { + if (parts[i].temp<272.15)//manual pipe colors + { + if (parts[i].temp>173.25&&parts[i].temp<273.15) + { + parts[i].ctype = 2; + parts[i].life = 0; + } + if (parts[i].temp>73.25&&parts[i].temp<=173.15) + { + parts[i].ctype = 3; + parts[i].life = 0; + } + if (parts[i].temp>=0&&parts[i].temp<=73.15) + { + parts[i].ctype = 4; + parts[i].life = 0; + } + } + else + { + // make a border + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + { + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + sim->create_part(-1,x+rx,y+ry,PT_BRCK);//BRCK border, people didn't like DMND + } + } + if (parts[i].life<=1) + parts[i].ctype = 1; + } + } + else if (parts[i].ctype==1)//wait for empty space before starting to generate automatic pipe pattern + { + if (!parts[i].life) + { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + if (!pmap[y+ry][x+rx]) + parts[i].life=50; + } + } + else if (parts[i].life==5)//check for beginning of pipe single pixel + { + int issingle = 1; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if ((r&0xFF)==PT_PIPE && parts[i].ctype==1 && parts[i].life ) + issingle = 0; + } + if (issingle) + parts[i].tmp |= 0x100; + } + else if (parts[i].life==2) + { + parts[i].ctype = 2; + parts[i].life = 6; + } + } + return 0; +} + +int graphics_PIPE(GRAPHICS_FUNC_ARGS) +{ + + if ((cpart->tmp&0xFF)>0 && (cpart->tmp&0xFF)<PT_NUM) + { + //Create a temp. particle and do a subcall. + Particle tpart; + int t; + memset(&tpart, 0, sizeof(Particle)); + tpart.type = cpart->tmp&0xFF; + tpart.temp = cpart->temp; + tpart.life = cpart->flags; + tpart.tmp = cpart->pavg[0]; + tpart.ctype = cpart->pavg[1]; + t = tpart.type; + if (ren->graphicscache[t].isready) + { + *pixel_mode = ren->graphicscache[t].pixel_mode; + *colr = ren->graphicscache[t].colr; + *colg = ren->graphicscache[t].colg; + *colb = ren->graphicscache[t].colb; + *firea = ren->graphicscache[t].firea; + *firer = ren->graphicscache[t].firer; + *fireg = ren->graphicscache[t].fireg; + *fireb = ren->graphicscache[t].fireb; + } + else + { + *colr = PIXR(ren->sim->ptypes[t].pcolors); + *colg = PIXR(ren->sim->ptypes[t].pcolors); + *colb = PIXR(ren->sim->ptypes[t].pcolors); + if (ren->sim->ptypes[t].graphics_func) + { + (*(ren->sim->ptypes[t].graphics_func))(ren, &tpart, nx, ny, pixel_mode, cola, colr, colg, colb, firea, firer, fireg, fireb); + } + else + { + graphics_DEFAULT(ren, &tpart, nx, ny, pixel_mode, cola, colr, colg, colb, firea, firer, fireg, fireb); + } + } + //*colr = PIXR(ptypes[cpart->tmp&0xFF].pcolors); + //*colg = PIXG(ptypes[cpart->tmp&0xFF].pcolors); + //*colb = PIXB(ptypes[cpart->tmp&0xFF].pcolors); + } + else + { + if (cpart->ctype==2) + { + *colr = 50; + *colg = 1; + *colb = 1; + } + else if (cpart->ctype==3) + { + *colr = 1; + *colg = 50; + *colb = 1; + } + else if (cpart->ctype==4) + { + *colr = 1; + *colg = 1; + *colb = 50; + } + else if (cpart->temp<272.15&&cpart->ctype!=1) + { + if (cpart->temp>173.25&&cpart->temp<273.15) + { + *colr = 50; + *colg = 1; + *colb = 1; + } + if (cpart->temp>73.25&&cpart->temp<=173.15) + { + *colr = 1; + *colg = 50; + *colb = 1; + } + if (cpart->temp>=0&&cpart->temp<=73.15) + { + *colr = 1; + *colg = 1; + *colb = 50; + } + } + } + return 0; +} diff --git a/src/elements/plnt.cpp b/src/elements/plnt.cpp new file mode 100644 index 0000000..a44c8c2 --- /dev/null +++ b/src/elements/plnt.cpp @@ -0,0 +1,55 @@ +#include "element.h" + +int update_PLNT(UPDATE_FUNC_ARGS) { + int r, rx, ry, np; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_WATR && 1>(rand()%250)) + { + np = sim->create_part(r>>8,x+rx,y+ry,PT_PLNT); + if (np<0) continue; + parts[np].life = 0; + } + else if ((r&0xFF)==PT_LAVA && 1>(rand()%250)) + { + sim->part_change_type(i,x,y,PT_FIRE); + parts[i].life = 4; + } + else if (((r&0xFF)==PT_SMKE || (r&0xFF)==PT_CO2) && (1>rand()%250)) + { + sim->kill_part(r>>8); + parts[i].life = rand()%60 + 60; + } + else if ((r&0xFF)==PT_WOOD && (1>rand()%20) && abs(rx+ry)<=2 && sim->VINE_MODE) + { + int nnx = rand()%3 -1; + int nny = rand()%3 -1; + if (x+rx+nnx>=0 && y+ry+nny>0 && x+rx+nnx<XRES && y+ry+nny<YRES && (nnx || nny)) + { + if (pmap[y+ry+nny][x+rx+nnx]) + continue; + np = sim->create_part(-1,x+rx+nnx,y+ry+nny,PT_VINE); + if (np<0) continue; + parts[np].temp = parts[i].temp; + } + } + } + if (parts[i].life==2) + { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + sim->create_part(-1,x+rx,y+ry,PT_O2); + } + parts[i].life = 0; + } + return 0; +} diff --git a/src/elements/plsm.cpp b/src/elements/plsm.cpp new file mode 100644 index 0000000..c6f7c20 --- /dev/null +++ b/src/elements/plsm.cpp @@ -0,0 +1,20 @@ +#include "element.h" +#include "hmap.h" + +int graphics_PLSM(GRAPHICS_FUNC_ARGS) +{ + int caddress = restrict_flt(restrict_flt((float)cpart->life, 0.0f, 200.0f)*3, 0.0f, (200.0f*3)-3); + *colr = (unsigned char)ren->plasma_data[caddress]; + *colg = (unsigned char)ren->plasma_data[caddress+1]; + *colb = (unsigned char)ren->plasma_data[caddress+2]; + + *firea = 255; + *firer = *colr; + *fireg = *colg; + *fireb = *colb; + + *pixel_mode = PMODE_GLOW | PMODE_ADD; //Clear default, don't draw pixel + *pixel_mode |= FIRE_ADD; + //Returning 0 means dynamic, do not cache + return 0; +} diff --git a/src/elements/plut.cpp b/src/elements/plut.cpp new file mode 100644 index 0000000..3e2820d --- /dev/null +++ b/src/elements/plut.cpp @@ -0,0 +1,9 @@ +#include "element.h" + +int update_PLUT(UPDATE_FUNC_ARGS) { + if (1>rand()%100 && ((int)(5.0f*sim->pv[y/CELL][x/CELL]))>(rand()%1000)) + { + sim->create_part(i, x, y, PT_NEUT); + } + return 0; +} diff --git a/src/elements/prti.cpp b/src/elements/prti.cpp new file mode 100644 index 0000000..df212d4 --- /dev/null +++ b/src/elements/prti.cpp @@ -0,0 +1,79 @@ +#include "element.h" +/*these are the count values of where the particle gets stored, depending on where it came from + 0 1 2 + 7 . 3 + 6 5 4 + PRTO does (count+4)%8, so that it will come out at the opposite place to where it came in + PRTO does +/-1 to the count, so it doesn't jam as easily +*/ +int portal_rx[8] = {-1, 0, 1, 1, 1, 0,-1,-1}; +int portal_ry[8] = {-1,-1,-1, 0, 1, 1, 1, 0}; + +int update_PRTI(UPDATE_FUNC_ARGS) { + int r, nnx, rx, ry, fe = 0; + int count =0; + parts[i].tmp = (int)((parts[i].temp-73.15f)/100+1); + if (parts[i].tmp>=CHANNELS) parts[i].tmp = CHANNELS-1; + else if (parts[i].tmp<0) parts[i].tmp = 0; + for (count=0; count<8; count++) + { + rx = portal_rx[count]; + ry = portal_ry[count]; + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + fe = 1; + if (!r || (r&0xFF)==PT_PRTI || (r&0xFF)==PT_PRTO || (sim->ptypes[r&0xFF].falldown== 0 && sim->ptypes[r&0xFF].state != ST_GAS && (r&0xFF)!=PT_SPRK)) + { + r = sim->photons[y+ry][x+rx]; + if (!r || (r&0xFF)==PT_PRTI || (r&0xFF)==PT_PRTO || (sim->ptypes[r&0xFF].falldown== 0 && sim->ptypes[r&0xFF].state != ST_GAS && (r&0xFF)!=PT_SPRK)) + continue; + } + + if ((r&0xFF) == PT_SOAP) + sim->detach(r>>8); + + for ( nnx=0; nnx<80; nnx++) + if (!sim->portalp[parts[i].tmp][count][nnx].type) + { + sim->portalp[parts[i].tmp][count][nnx] = parts[r>>8]; + if ((r&0xFF)==PT_SPRK) + sim->part_change_type(r>>8,x+rx,y+ry,parts[r>>8].ctype); + else + sim->kill_part(r>>8); + fe = 1; + break; + } + } + } + + + if (fe) { + int orbd[4] = {0, 0, 0, 0}; //Orbital distances + int orbl[4] = {0, 0, 0, 0}; //Orbital locations + if (!parts[i].life) parts[i].life = rand(); + if (!parts[i].ctype) parts[i].ctype = rand(); + sim->orbitalparts_get(parts[i].life, parts[i].ctype, orbd, orbl); + for (r = 0; r < 4; r++) { + if (orbd[r]>1) { + orbd[r] -= 12; + if (orbd[r]<1) { + orbd[r] = (rand()%128)+128; + orbl[r] = rand()%255; + } else { + orbl[r] += 2; + orbl[r] = orbl[r]%255; + } + } else { + orbd[r] = (rand()%128)+128; + orbl[r] = rand()%255; + } + } + sim->orbitalparts_set(&parts[i].life, &parts[i].ctype, orbd, orbl); + } else { + parts[i].life = 0; + parts[i].ctype = 0; + } + return 0; +} diff --git a/src/elements/prto.cpp b/src/elements/prto.cpp new file mode 100644 index 0000000..ee61abf --- /dev/null +++ b/src/elements/prto.cpp @@ -0,0 +1,88 @@ +#include "element.h" +/*these are the count values of where the particle gets stored, depending on where it came from + 0 1 2 + 7 . 3 + 6 5 4 + PRTO does (count+4)%8, so that it will come out at the opposite place to where it came in + PRTO does +/-1 to the count, so it doesn't jam as easily +*/ +int update_PRTO(UPDATE_FUNC_ARGS) { + int r, nnx, rx, ry, np, fe = 0; + int count = 0; + parts[i].tmp = (int)((parts[i].temp-73.15f)/100+1); + if (parts[i].tmp>=CHANNELS) parts[i].tmp = CHANNELS-1; + else if (parts[i].tmp<0) parts[i].tmp = 0; + for (count=0; count<8; count++) + { + rx = sim->portal_rx[count]; + ry = sim->portal_ry[count]; + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + fe = 1; + if (r) + continue; + if (!r) + { + for ( nnx =0 ; nnx<80; nnx++) + { + int randomness = (count + rand()%3-1 + 4)%8;//add -1,0,or 1 to count + if (sim->portalp[parts[i].tmp][randomness][nnx].type==PT_SPRK)// TODO: make it look better, spark creation + { + sim->create_part(-1,x+1,y,PT_SPRK); + sim->create_part(-1,x+1,y+1,PT_SPRK); + sim->create_part(-1,x+1,y-1,PT_SPRK); + sim->create_part(-1,x,y-1,PT_SPRK); + sim->create_part(-1,x,y+1,PT_SPRK); + 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; + break; + } + else if (sim->portalp[parts[i].tmp][randomness][nnx].type) + { + if (sim->portalp[parts[i].tmp][randomness][nnx].type==PT_STKM) + sim->player.spwn = 0; + if (sim->portalp[parts[i].tmp][randomness][nnx].type==PT_STKM2) + sim->player2.spwn = 0; + np = sim->create_part(-1, x+rx, y+ry, sim->portalp[parts[i].tmp][randomness][nnx].type); + if (np<0) continue; + 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; + break; + } + } + } + } + } + if (fe) { + int orbd[4] = {0, 0, 0, 0}; //Orbital distances + int orbl[4] = {0, 0, 0, 0}; //Orbital locations + if (!parts[i].life) parts[i].life = rand(); + if (!parts[i].ctype) parts[i].life = rand(); + sim->orbitalparts_get(parts[i].life, parts[i].ctype, orbd, orbl); + for (r = 0; r < 4; r++) { + if (orbd[r]<254) { + orbd[r] += 16; + if (orbd[r]>254) { + orbd[r] = 0; + orbl[r] = rand()%255; + } + //orbl[r] += 1; + //orbl[r] = orbl[r]%255; + } else { + orbd[r] = 0; + orbl[r] = rand()%255; + } + } + sim->orbitalparts_set(&parts[i].life, &parts[i].ctype, orbd, orbl); + } else { + parts[i].life = 0; + parts[i].ctype = 0; + } + return 0; +} diff --git a/src/elements/pump.cpp b/src/elements/pump.cpp new file mode 100644 index 0000000..8a7254e --- /dev/null +++ b/src/elements/pump.cpp @@ -0,0 +1,41 @@ +#include "element.h" + +int update_PUMP(UPDATE_FUNC_ARGS) { + int r, rx, ry; + if (parts[i].life>0 && parts[i].life!=10) + parts[i].life--; + if (parts[i].life==10) + { + if (parts[i].temp>=256.0+273.15) + parts[i].temp=256.0+273.15; + if (parts[i].temp<= -256.0+273.15) + parts[i].temp = -256.0+273.15; + + if (sim->pv[y/CELL][x/CELL]<(parts[i].temp-273.15)) + sim->pv[y/CELL][x/CELL] += 0.1f*((parts[i].temp-273.15)-sim->pv[y/CELL][x/CELL]); + if (y+CELL<YRES && sim->pv[y/CELL+1][x/CELL]<(parts[i].temp-273.15)) + sim->pv[y/CELL+1][x/CELL] += 0.1f*((parts[i].temp-273.15)-sim->pv[y/CELL+1][x/CELL]); + if (x+CELL<XRES) + { + sim->pv[y/CELL][x/CELL+1] += 0.1f*((parts[i].temp-273.15)-sim->pv[y/CELL][x/CELL+1]); + if (y+CELL<YRES) + sim->pv[y/CELL+1][x/CELL+1] += 0.1f*((parts[i].temp-273.15)-sim->pv[y/CELL+1][x/CELL+1]); + } + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_PUMP) + { + if (parts[r>>8].life<10&&parts[r>>8].life>0) + parts[i].life = 9; + else if (parts[r>>8].life==0) + parts[r>>8].life = 10; + } + } + } + return 0; +} diff --git a/src/elements/pvod.cpp b/src/elements/pvod.cpp new file mode 100644 index 0000000..e645d0a --- /dev/null +++ b/src/elements/pvod.cpp @@ -0,0 +1,30 @@ +#include "element.h" + +int update_PVOD(UPDATE_FUNC_ARGS) { + int r, rx, ry; + if (parts[i].life>0 && parts[i].life!=10) + parts[i].life--; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_SPRK) + { + if (parts[r>>8].ctype==PT_PSCN) + parts[i].life = 10; + else if (parts[r>>8].ctype==PT_NSCN) + parts[i].life = 9; + } + if ((r&0xFF)==PT_PVOD) + { + if (parts[i].life==10&&parts[r>>8].life<10&&parts[r>>8].life>0) + parts[i].life = 9; + else if (parts[i].life==0&&parts[r>>8].life==10) + parts[i].life = 10; + } + } + return 0; +} diff --git a/src/elements/pyro.cpp b/src/elements/pyro.cpp new file mode 100644 index 0000000..790e295 --- /dev/null +++ b/src/elements/pyro.cpp @@ -0,0 +1,129 @@ +#include "element.h" + +int update_PYRO(UPDATE_FUNC_ARGS) { + int r, rx, ry, rt, t = parts[i].type; + if (t==PT_PLSM&&parts[i].ctype == PT_NBLE&&parts[i].life <=1) + { + t = PT_NBLE; + sim->part_change_type(i,x,y,t); + parts[i].life = 0; + } + if(t==PT_FIRE && parts[i].life <=1) + { + if (parts[i].tmp==3){ + t = PT_DSTW; + sim->part_change_type(i,x,y,t); + parts[i].life = 0; + parts[i].ctype = PT_FIRE; + } + else if (parts[i].temp<625) + { + t = PT_SMKE; + sim->part_change_type(i,x,y,t); + parts[i].life = rand()%20+250; + } + } + if(t==PT_PLSM && parts[i].life <=1) + { + if (parts[i].tmp==3){ + t = PT_DSTW; + sim->part_change_type(i,x,y,t); + parts[i].life = 0; + parts[i].ctype = PT_FIRE; + } + } + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (sim->bmap[(y+ry)/CELL][(x+rx)/CELL] && sim->bmap[(y+ry)/CELL][(x+rx)/CELL]!=WL_STREAM) + continue; + rt = parts[r>>8].type; + if ((surround_space || sim->ptypes[rt].explosive) && + (t!=PT_SPRK || (rt!=PT_RBDM && rt!=PT_LRBD && rt!=PT_INSL)) && + (t!=PT_PHOT || rt!=PT_INSL) && + (rt!=PT_SPNG || parts[r>>8].life==0) && + sim->ptypes[rt].flammable && (sim->ptypes[rt].flammable + (int)(sim->pv[(y+ry)/CELL][(x+rx)/CELL]*10.0f))>(rand()%1000)) + { + sim->part_change_type(r>>8,x+rx,y+ry,PT_FIRE); + parts[r>>8].temp = restrict_flt(sim->ptypes[PT_FIRE].heat + (sim->ptypes[rt].flammable/2), MIN_TEMP, MAX_TEMP); + parts[r>>8].life = rand()%80+180; + parts[r>>8].tmp = parts[r>>8].ctype = 0; + if (sim->ptypes[rt].explosive) + sim->pv[y/CELL][x/CELL] += 0.25f * CFDS; + } + } + if (sim->legacy_enable) update_legacy_PYRO(UPDATE_FUNC_SUBCALL_ARGS); + return 0; +} + +int update_legacy_PYRO(UPDATE_FUNC_ARGS) { + int r, rx, ry, rt, lpv, t = parts[i].type; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (sim->bmap[(y+ry)/CELL][(x+rx)/CELL] && sim->bmap[(y+ry)/CELL][(x+rx)/CELL]!=WL_STREAM) + continue; + rt = r&0xFF; + lpv = (int)sim->pv[(y+ry)/CELL][(x+rx)/CELL]; + if (lpv < 1) lpv = 1; + if (t!=PT_SPRK && sim->ptypes[rt].meltable && ((rt!=PT_RBDM && rt!=PT_LRBD) || t!=PT_SPRK) && ((t!=PT_FIRE&&t!=PT_PLSM) || (rt!=PT_METL && rt!=PT_IRON && rt!=PT_ETRD && rt!=PT_PSCN && rt!=PT_NSCN && rt!=PT_NTCT && rt!=PT_PTCT && rt!=PT_BMTL && rt!=PT_BRMT && rt!=PT_SALT && rt!=PT_INWR)) && + sim->ptypes[rt].meltable*lpv>(rand()%1000)) + { + if (t!=PT_LAVA || parts[i].life>0) + { + parts[r>>8].ctype = (rt==PT_BRMT)?PT_BMTL:parts[r>>8].type; + parts[r>>8].ctype = (parts[r>>8].ctype==PT_SAND)?PT_GLAS:parts[r>>8].ctype; + sim->part_change_type(r>>8,x+rx,y+ry,PT_LAVA); + parts[r>>8].life = rand()%120+240; + } + else + { + parts[i].life = 0; + t = parts[i].type = (parts[i].ctype)?parts[i].ctype:PT_STNE; + parts[i].ctype = PT_NONE;//rt; + sim->part_change_type(i,x,y,t); + return 1; + } + } + if (t!=PT_SPRK && (rt==PT_ICEI || rt==PT_SNOW)) + { + parts[r>>8].type = PT_WATR; + if (t==PT_FIRE) + { + sim->kill_part(i); + return 1; + } + if (t==PT_LAVA) + { + parts[i].life = 0; + t = parts[i].type = PT_STNE; + sim->part_change_type(i,x,y,t); + } + } + if (t!=PT_SPRK && (rt==PT_WATR || rt==PT_DSTW || rt==PT_SLTW)) + { + sim->kill_part(r>>8); + if (t==PT_FIRE) + { + sim->kill_part(i); + return 1; + } + if (t==PT_LAVA) + { + parts[i].life = 0; + t = parts[i].type = (parts[i].ctype)?parts[i].ctype:PT_STNE; + parts[i].ctype = PT_NONE; + sim->part_change_type(i,x,y,t); + } + } + } + return 0; +} diff --git a/src/elements/qrtz.cpp b/src/elements/qrtz.cpp new file mode 100644 index 0000000..7768765 --- /dev/null +++ b/src/elements/qrtz.cpp @@ -0,0 +1,94 @@ +#include "element.h" + +int update_QRTZ(UPDATE_FUNC_ARGS) { + int r, tmp, trade, rx, ry, np, t; + t = parts[i].type; + if (t == PT_QRTZ) + { + parts[i].pavg[0] = parts[i].pavg[1]; + parts[i].pavg[1] = sim->pv[y/CELL][x/CELL]; + if (parts[i].pavg[1]-parts[i].pavg[0] > 0.05*(parts[i].temp/3) || parts[i].pavg[1]-parts[i].pavg[0] < -0.05*(parts[i].temp/3)) + { + sim->part_change_type(i,x,y,PT_PQRT); + } + } + // absorb SLTW + if (parts[i].ctype!=-1) + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + else if ((r&0xFF)==PT_SLTW && (1>rand()%2500)) + { + sim->kill_part(r>>8); + parts[i].ctype ++; + } + } + // grow if absorbed SLTW + if (parts[i].ctype>0) + { + for ( trade = 0; trade<5; trade ++) + { + rx = rand()%3-1; + ry = rand()%3-1; + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r && parts[i].ctype!=0) + { + np = sim->create_part(-1,x+rx,y+ry,PT_QRTZ); + if (np>-1) + { + parts[np].tmp = parts[i].tmp; + parts[i].ctype--; + if (5>rand()%10) + { + parts[np].ctype=-1;//dead qrtz + } + else if (!parts[i].ctype && 1>rand()%15) + { + parts[i].ctype=-1; + } + + break; + } + } + } + } + } + // diffuse absorbed SLTW + if (parts[i].ctype>0) + { + 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)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==t && (parts[i].ctype>parts[r>>8].ctype) && parts[r>>8].ctype>=0 )//diffusion + { + tmp = parts[i].ctype - parts[r>>8].ctype; + if (tmp ==1) + { + parts[r>>8].ctype ++; + parts[i].ctype --; + break; + } + if (tmp>0) + { + parts[r>>8].ctype += tmp/2; + parts[i].ctype -= tmp/2; + break; + } + } + } + } + } + return 0; +} diff --git a/src/elements/rime.cpp b/src/elements/rime.cpp new file mode 100644 index 0000000..617414b --- /dev/null +++ b/src/elements/rime.cpp @@ -0,0 +1,26 @@ +#include "element.h" + +int update_RIME(UPDATE_FUNC_ARGS) { + int r, rx, ry; + parts[i].vx = 0; + parts[i].vy = 0; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_SPRK) + { + sim->part_change_type(i,x,y,PT_FOG); + parts[i].life = rand()%50 + 60; + } + else if ((r&0xFF)==PT_FOG&&parts[r>>8].life>0) + { + sim->part_change_type(i,x,y,PT_FOG); + parts[i].life = parts[r>>8].life; + } + } + return 0; +} diff --git a/src/elements/shld.cpp b/src/elements/shld.cpp new file mode 100644 index 0000000..cbe8306 --- /dev/null +++ b/src/elements/shld.cpp @@ -0,0 +1,162 @@ +#include "element.h" + +int update_SHLD1(UPDATE_FUNC_ARGS) { + int r, nnx, nny, rx, ry; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + else if ((r&0xFF)==PT_SPRK&&parts[i].life==0) + { + if (55>rand()%200&&parts[i].life==0) + { + sim->part_change_type(i,x,y,PT_SHLD2); + parts[i].life = 7; + } + for ( nnx=-1; nnx<2; nnx++) + for ( nny=-1; nny<2; nny++) + { + if (!pmap[y+ry+nny][x+rx+nnx]) + { + sim->create_part(-1,x+rx+nnx,y+ry+nny,PT_SHLD1); + //parts[pmap[y+ny+nny][x+nx+nnx]>>8].life=7; + } + } + } + else if ((r&0xFF)==PT_SHLD3&&4>rand()%10) + { + sim->part_change_type(i,x,y,PT_SHLD2); + parts[i].life = 7; + } + } + return 0; +} + +int update_SHLD2(UPDATE_FUNC_ARGS) { + int r, nnx, nny, rx, ry, np; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r && parts[i].life>0) + sim->create_part(-1,x+rx,y+ry,PT_SHLD1); + if (!r) + continue; + else if ((r&0xFF)==PT_SPRK&&parts[i].life==0) + { + if (25>rand()%200&&parts[i].life==0) + { + sim->part_change_type(i,x,y,PT_SHLD3); + parts[i].life = 7; + } + for ( nnx=-1; nnx<2; nnx++) + for ( nny=-1; nny<2; nny++) + { + if (!pmap[y+ry+nny][x+rx+nnx]) + { + np = sim->create_part(-1,x+rx+nnx,y+ry+nny,PT_SHLD1); + if (np<0) continue; + parts[np].life=7; + } + } + } + else if ((r&0xFF)==PT_SHLD4&&4>rand()%10) + { + sim->part_change_type(i,x,y,PT_SHLD3); + parts[i].life = 7; + } + } + return 0; +} + +int update_SHLD3(UPDATE_FUNC_ARGS) { + int r, nnx, nny, rx, ry, np; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + { + if (1>rand()%2500) + { + np = sim->create_part(-1,x+rx,y+ry,PT_SHLD1); + if (np<0) continue; + parts[np].life=7; + sim->part_change_type(i,x,y,PT_SHLD2); + } + else + continue; + + } + if ((r&0xFF)==PT_SHLD1 && parts[i].life>3) + { + sim->part_change_type(r>>8,x+rx,y+ry,PT_SHLD2); + parts[r>>8].life=7; + } + else if ((r&0xFF)==PT_SPRK&&parts[i].life==0) + { + if (18>rand()%3000&&parts[i].life==0) + { + sim->part_change_type(i,x,y,PT_SHLD4); + parts[i].life = 7; + } + for ( nnx=-1; nnx<2; nnx++) + for ( nny=-1; nny<2; nny++) + { + + if (!pmap[y+ry+nny][x+rx+nnx]) + { + np = sim->create_part(-1,x+rx+nnx,y+ry+nny,PT_SHLD1); + if (np<0) continue; + parts[np].life=7; + } + } + } + } + return 0; +} + +int update_SHLD4(UPDATE_FUNC_ARGS) { + int r, nnx, nny, rx, ry, np; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + { + if (1>rand()%5500) + { + np = sim->create_part(-1,x+rx,y+ry,PT_SHLD1); + if (np<0) continue; + parts[np].life=7; + sim->part_change_type(i,x,y,PT_SHLD2); + } + else + continue; + + } + if ((r&0xFF)==PT_SHLD2 && parts[i].life>3) + { + sim->part_change_type(r>>8,x+rx,y+ry,PT_SHLD3); + parts[r>>8].life = 7; + } + else if ((r&0xFF)==PT_SPRK&&parts[i].life==0) + for ( nnx=-1; nnx<2; nnx++) + for ( nny=-1; nny<2; nny++) + { + if (!pmap[y+ry+nny][x+rx+nnx]) + { + np = sim->create_part(-1,x+rx+nnx,y+ry+nny,PT_SHLD1); + if (np<0) continue; + parts[np].life=7; + } + } + } + return 0; +} diff --git a/src/elements/sing.cpp b/src/elements/sing.cpp new file mode 100644 index 0000000..fa6121c --- /dev/null +++ b/src/elements/sing.cpp @@ -0,0 +1,104 @@ +#include "element.h" + +int update_SING(UPDATE_FUNC_ARGS) { + int r, rx, ry, cry, crx, rad, nxi, nxj, nb, j, spawncount; + int singularity = -parts[i].life; + float angle, v; + + if (sim->pv[y/CELL][x/CELL]<singularity) + sim->pv[y/CELL][x/CELL] += 0.1f*(singularity-sim->pv[y/CELL][x/CELL]); + if (y+CELL<YRES && sim->pv[y/CELL+1][x/CELL]<singularity) + sim->pv[y/CELL+1][x/CELL] += 0.1f*(singularity-sim->pv[y/CELL+1][x/CELL]); + if (x+CELL<XRES) + { + sim->pv[y/CELL][x/CELL+1] += 0.1f*(singularity-sim->pv[y/CELL][x/CELL+1]); + if (y+CELL<YRES) + sim->pv[y/CELL+1][x/CELL+1] += 0.1f*(singularity-sim->pv[y/CELL+1][x/CELL+1]); + } + if (y+CELL>0 && sim->pv[y/CELL-1][x/CELL]<singularity) + sim->pv[y/CELL-1][x/CELL] += 0.1f*(singularity-sim->pv[y/CELL-1][x/CELL]); + if (x+CELL>0) + { + sim->pv[y/CELL][x/CELL-1] += 0.1f*(singularity-sim->pv[y/CELL][x/CELL-1]); + if (y+CELL>0) + sim->pv[y/CELL-1][x/CELL-1] += 0.1f*(singularity-sim->pv[y/CELL-1][x/CELL-1]); + } + if (parts[i].life<1) { + //Pop! + for (rx=-2; rx<3; rx++) { + crx = (x/CELL)+rx; + for (ry=-2; ry<3; ry++) { + cry = (y/CELL)+ry; + if (cry > 0 && crx > 0 && crx < (XRES/CELL) && cry < (YRES/CELL)) { + sim->pv[cry][crx] += (float)parts[i].tmp; + } + } + } + spawncount = (parts[i].tmp>255)?255:parts[i].tmp; + if (spawncount>=1) + spawncount = spawncount/8; + spawncount = spawncount*spawncount*M_PI; + for (j=0;j<spawncount;j++) + { + switch(rand()%3) + { + case 0: + nb = sim->create_part(-3, x, y, PT_PHOT); + break; + case 1: + nb = sim->create_part(-3, x, y, PT_NEUT); + break; + case 2: + nb = sim->create_part(-3, x, y, PT_ELEC); + break; + } + if (nb!=-1) { + parts[nb].life = (rand()%300); + parts[nb].temp = MAX_TEMP/2; + angle = rand()*2.0f*M_PI/RAND_MAX; + v = (float)(rand())*5.0f/RAND_MAX; + parts[nb].vx = v*cosf(angle); + parts[nb].vy = v*sinf(angle); + } + else if (sim->pfree==-1) + break;//if we've run out of particles, stop trying to create them - saves a lot of lag on "sing bomb" saves + } + sim->kill_part(i); + return 1; + } + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_DMND&&33>=rand()/(RAND_MAX/100)+1) + { + if ((r&0xFF)==PT_SING && parts[r>>8].life >10) + { + if (parts[i].life+parts[r>>8].life > 255) + continue; + parts[i].life += parts[r>>8].life; + } + else + { + if (parts[i].life+3 > 255) + { + if (parts[r>>8].type!=PT_SING && 1>rand()%100) + { + int np; + np = sim->create_part(r>>8,x+rx,y+ry,PT_SING); + parts[np].life = rand()%50+60; + } + continue; + } + parts[i].life += 3; + parts[i].tmp++; + } + parts[i].temp = restrict_flt(parts[r>>8].temp+parts[i].temp, MIN_TEMP, MAX_TEMP); + sim->kill_part(r>>8); + } + } + return 0; +} diff --git a/src/elements/sltw.cpp b/src/elements/sltw.cpp new file mode 100644 index 0000000..c965fd4 --- /dev/null +++ b/src/elements/sltw.cpp @@ -0,0 +1,30 @@ +#include "element.h" + +int update_SLTW(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_SALT && 1>(rand()%10000)) + sim->kill_part(r>>8); + if ((r&0xFF)==PT_PLNT&&5>(rand()%1000)) + sim->kill_part(r>>8); + if (((r&0xFF)==PT_RBDM||(r&0xFF)==PT_LRBD) && !sim->legacy_enable && parts[i].temp>(273.15f+12.0f) && 1>(rand()%500)) + { + sim->part_change_type(i,x,y,PT_FIRE); + parts[i].life = 4; + } + if ((r&0xFF)==PT_FIRE){ + sim->kill_part(r>>8); + if(1>(rand()%150)){ + sim->kill_part(i); + return 1; + } + } + } + return 0; +} diff --git a/src/elements/smke.cpp b/src/elements/smke.cpp new file mode 100644 index 0000000..d19bd0a --- /dev/null +++ b/src/elements/smke.cpp @@ -0,0 +1,18 @@ +#include "element.h" + +int graphics_SMKE(GRAPHICS_FUNC_ARGS) +{ + *colr = 55; + *colg = 55; + *colb = 55; + + *firea = 75; + *firer = 55; + *fireg = 55; + *fireb = 55; + + *pixel_mode = PMODE_NONE; //Clear default, don't draw pixel + *pixel_mode |= FIRE_BLEND; + //Returning 1 means static, cache as we please + return 1; +}
\ No newline at end of file diff --git a/src/elements/soap.cpp b/src/elements/soap.cpp new file mode 100644 index 0000000..0d31292 --- /dev/null +++ b/src/elements/soap.cpp @@ -0,0 +1,234 @@ +#include "element.h" + +int update_SOAP(UPDATE_FUNC_ARGS) +{ + int r, rx, ry, nr, ng, nb, na; + float tr, tg, tb, ta; + float blend; + + //0x01 - bubble on/off + //0x02 - first mate yes/no + //0x04 - "back" mate yes/no + + if ((parts[i].ctype&1) == 1) + { + if (parts[i].temp>0) + { + if (parts[i].life<=0) + { + if ((parts[i].ctype&6) != 6 && parts[i].ctype>1) + { + int target; + + target = i; + + while((parts[target].ctype&6) != 6 && parts[target].ctype>1) + { + if ((parts[target].ctype&2) == 2) + { + target = parts[target].tmp; + sim->detach(target); + } + + if ((parts[target].ctype&4) == 4) + { + target = parts[target].tmp2; + sim->detach(target); + } + } + } + + if ((parts[i].ctype&6) != 6) + parts[i].ctype = 0; + + if ((parts[i].ctype&6) == 6 && (parts[parts[i].tmp].ctype&6) == 6 && parts[parts[i].tmp].tmp == i) + sim->detach(i); + } + + parts[i].vy -= 0.1f; + + parts[i].vy *= 0.5f; + parts[i].vx *= 0.5f; + } + + if((parts[i].ctype&2) != 2) + { + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + + if ((parts[r>>8].type == PT_SOAP) && ((parts[r>>8].ctype&1) == 1) + && ((parts[r>>8].ctype&4) != 4)) + { + if ((parts[r>>8].ctype&2) == 2) + { + parts[i].tmp = r>>8; + parts[r>>8].tmp2 = i; + + parts[i].ctype |= 2; + parts[r>>8].ctype |= 4; + } + else + { + if ((parts[i].ctype&2) != 2) + { + parts[i].tmp = r>>8; + parts[r>>8].tmp2 = i; + + parts[i].ctype |= 2; + parts[r>>8].ctype |= 4; + } + } + } + } + } + else + { + if (parts[i].life<=0) + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r && !sim->bmap[(y+ry)/CELL][(x+rx)/CELL]) + continue; + + if (parts[i].temp>0) + { + if (sim->bmap[(y+ry)/CELL][(x+rx)/CELL] + || (r && sim->ptypes[r&0xFF].state != ST_GAS + && (r&0xFF) != PT_SOAP && (r&0xFF) != PT_GLAS) + || (parts[r>>8].ctype == 0 && (r&0xFF) == PT_SOAP + && (abs(parts[r>>8].vx)<2 || abs(parts[r>>8].vy)<2))) + { + sim->detach(i); + continue; + } + } + + if ((r&0xFF) == PT_SOAP && parts[r>>8].ctype == 1) + { + int buf; + + buf = parts[i].tmp; + + parts[i].tmp = r>>8; + parts[buf].tmp2 = r>>8; + parts[r>>8].tmp2 = i; + parts[r>>8].tmp = buf; + parts[r>>8].ctype = 7; + } + + if ((r&0xFF) == PT_SOAP && parts[r>>8].ctype == 7 && parts[i].tmp != r>>8 && parts[i].tmp2 != r>>8) + { + int buf; + + parts[parts[i].tmp].tmp2 = parts[r>>8].tmp2; + parts[parts[r>>8].tmp2].tmp = parts[i].tmp; + parts[r>>8].tmp2 = i; + parts[i].tmp = r>>8; + } + } + } + + if((parts[i].ctype&2) == 2) + { + float d, dx, dy; + + dx = parts[i].x - parts[parts[i].tmp].x; + dy = parts[i].y - parts[parts[i].tmp].y; + + d = 9/(pow(dx, 2)+pow(dy, 2)+9)-0.5; + + parts[parts[i].tmp].vx -= dx*d; + parts[parts[i].tmp].vy -= dy*d; + + parts[i].vx += dx*d; + parts[i].vy += dy*d; + + if (((parts[parts[i].tmp].ctype&2) == 2) && ((parts[parts[i].tmp].ctype&1) == 1) + && ((parts[parts[parts[i].tmp].tmp].ctype&2) == 2) && ((parts[parts[parts[i].tmp].tmp].ctype&1) == 1)) + { + int ii; + + ii = parts[parts[parts[i].tmp].tmp].tmp; + + dx = parts[ii].x - parts[parts[i].tmp].x; + dy = parts[ii].y - parts[parts[i].tmp].y; + + d = 81/(pow(dx, 2)+pow(dy, 2)+81)-0.5; + + parts[parts[i].tmp].vx -= dx*d*0.5f; + parts[parts[i].tmp].vy -= dy*d*0.5f; + + parts[ii].vx += dx*d*0.5f; + parts[ii].vy += dy*d*0.5f; + } + } + } + else + { + if (sim->pv[y/CELL][x/CELL]>0.5f || sim->pv[y/CELL][x/CELL]<(-0.5f)) + { + parts[i].ctype = 1; + parts[i].life = 10; + } + + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + + if ((r&0xFF) == PT_OIL) + { + float ax, ay; + + parts[i].vy -= 0.1f; + + parts[i].vy *= 0.5f; + parts[i].vx *= 0.5f; + + ax = (parts[i].vx + parts[r>>8].vx)/2; + ay = (parts[i].vy + parts[r>>8].vy)/2; + + parts[i].vx = ax; + parts[i].vy = ay; + parts[r>>8].vx = ax; + parts[r>>8].vy = ay; + } + } + } + + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_SOAP) + { + blend = 0.85f; + tr = (parts[r>>8].dcolour>>16)&0xFF; + tg = (parts[r>>8].dcolour>>8)&0xFF; + tb = (parts[r>>8].dcolour)&0xFF; + ta = (parts[r>>8].dcolour>>24)&0xFF; + + nr = (tr*blend); + ng = (tg*blend); + nb = (tb*blend); + na = (ta*blend); + + parts[r>>8].dcolour = nr<<16 | ng<<8 | nb | na<<24; + } + } + + return 0; +} diff --git a/src/elements/spng.cpp b/src/elements/spng.cpp new file mode 100644 index 0000000..28b3e1b --- /dev/null +++ b/src/elements/spng.cpp @@ -0,0 +1,110 @@ +#include "element.h" + +int update_SPNG(UPDATE_FUNC_ARGS) { + int r, trade, rx, ry, tmp, np; + if (sim->pv[y/CELL][x/CELL]<=3 && sim->pv[y/CELL][x/CELL]>=-3&&parts[i].temp<=374.0f) + { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_WATR&&33>=rand()/(RAND_MAX/100)+1) + { + parts[i].life++; + sim->kill_part(r>>8); + } + } + } + else + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if ((!r)&&parts[i].life>=1)//if nothing then create water + { + np = sim->create_part(-1,x+rx,y+ry,PT_WATR); + if (np>-1) parts[i].life--; + } + } + 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)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_SPNG&&(parts[i].life>parts[r>>8].life)&&parts[i].life>0)//diffusion + { + tmp = parts[i].life - parts[r>>8].life; + if (tmp ==1) + { + parts[r>>8].life ++; + parts[i].life --; + trade = 9; + } + else if (tmp>0) + { + parts[r>>8].life += tmp/2; + parts[i].life -= tmp/2; + trade = 9; + } + } + } + } + tmp = 0; + if (parts[i].life>0) + { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_FIRE) + { + tmp++; + if (parts[r>>8].life>60) + parts[r>>8].life -= parts[r>>8].life/60; + else if (parts[r>>8].life>2) + parts[r>>8].life--; + } + } + } + if (tmp && parts[i].life>3) + parts[i].life -= parts[i].life/3; + if (tmp>1) + tmp = tmp/2; + if (tmp || parts[i].temp>=374) + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if ((!r)&&parts[i].life>=1)//if nothing then create steam + { + np = sim->create_part(-1,x+rx,y+ry,PT_WTRV); + if (np>-1) + { + parts[np].temp = parts[i].temp; + tmp--; + parts[i].life--; + parts[i].temp -= 20.0f; + } + } + } + if (tmp>0) + { + if (parts[i].life>tmp) + parts[i].life -= tmp; + else + parts[i].life = 0; + } + return 0; +} diff --git a/src/elements/sprk.cpp b/src/elements/sprk.cpp new file mode 100644 index 0000000..244e831 --- /dev/null +++ b/src/elements/sprk.cpp @@ -0,0 +1,230 @@ +#include "element.h" + +int update_SPRK(UPDATE_FUNC_ARGS) { + int r, rx, ry, rt, conduct_sprk, nearp, pavg, ct = parts[i].ctype; + update_PYRO(UPDATE_FUNC_SUBCALL_ARGS); + + if (parts[i].life<=0) + { + if (ct==PT_WATR||ct==PT_SLTW||ct==PT_PSCN||ct==PT_NSCN||ct==PT_ETRD||ct==PT_INWR) + parts[i].temp = R_TEMP + 273.15f; + if (ct<=0 || ct>=PT_NUM) + ct = PT_METL; + sim->part_change_type(i,x,y,ct); + parts[i].ctype = PT_NONE; + parts[i].life = 4; + if (ct == PT_WATR) + parts[i].life = 64; + if (ct == PT_SLTW) + parts[i].life = 54; + if (ct == PT_SWCH) + parts[i].life = 14; + return 0; + } + if (ct==PT_SPRK) + { + sim->kill_part(i); + return 1; + } + else if (ct==PT_NTCT || ct==PT_PTCT) + { + update_NPTCT(UPDATE_FUNC_SUBCALL_ARGS); + } + else if (ct==PT_ETRD&&parts[i].life==1) + { + nearp = sim->nearest_part(i, PT_ETRD, -1); + if (nearp!=-1 && sim->parts_avg(i, nearp, PT_INSL)!=PT_INSL) + { + sim->create_line(x, y, (int)(parts[nearp].x+0.5f), (int)(parts[nearp].y+0.5f), 0, 0, PT_PLSM, 0); + sim->part_change_type(i,x,y,ct); + ct = parts[i].ctype = PT_NONE; + parts[i].life = 20; + sim->part_change_type(nearp,(int)(parts[nearp].x+0.5f),(int)(parts[nearp].y+0.5f),PT_SPRK); + parts[nearp].life = 9; + parts[nearp].ctype = PT_ETRD; + } + } + else if (ct==PT_NBLE&&parts[i].life<=1) + { + parts[i].life = rand()%150+50; + sim->part_change_type(i,x,y,PT_PLSM); + parts[i].ctype = PT_NBLE; + parts[i].temp = 3500; + sim->pv[y/CELL][x/CELL] += 1; + } + else if (ct==PT_TESC) // tesla coil code + { + if (parts[i].tmp>300) + parts[i].tmp=300; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (r) + continue; + if (rand()%(parts[i].tmp*parts[i].tmp/20+6)==0) + { + int p = sim->create_part(-1, x+rx*2, y+ry*2, PT_LIGH); + if (p!=-1) + { + if(parts[i].tmp<=4) //Prevent Arithmetic errors with zero values + continue; + parts[p].life=rand()%(2+parts[i].tmp/15)+parts[i].tmp/7; + if (parts[i].life>60) + parts[i].life=60; + parts[p].temp=parts[p].life*parts[i].tmp/2.5; + parts[p].tmp2=1; + parts[p].tmp=acos(1.0*rx/sqrt(rx*rx+ry*ry))/M_PI*360; + parts[i].temp-=parts[i].tmp*2+parts[i].temp/5; // slight self-cooling + if (fabs(sim->pv[y/CELL][x/CELL])!=0.0f) + { + if (fabs(sim->pv[y/CELL][x/CELL])<=0.5f) + sim->pv[y/CELL][x/CELL]=0; + else + sim->pv[y/CELL][x/CELL]-=(sim->pv[y/CELL][x/CELL]>0)?0.5:-0.5; + } + } + } + } + } + else if (ct==PT_IRON) { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF) == PT_DSTW && 30>(rand()/(RAND_MAX/1000))) || + ((r&0xFF) == PT_SLTW && 30>(rand()/(RAND_MAX/1000))) || + ((r&0xFF) == PT_WATR && 30>(rand()/(RAND_MAX/1000)))) + { + if (rand()<RAND_MAX/3) + sim->part_change_type(r>>8,x+rx,y+ry,PT_O2); + else + sim->part_change_type(r>>8,x+rx,y+ry,PT_H2); + } + } + } + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + rt = parts[r>>8].type; + conduct_sprk = 1; + + + pavg = sim->parts_avg(r>>8, i,PT_INSL); + if ((rt==PT_SWCH||(rt==PT_SPRK&&parts[r>>8].ctype==PT_SWCH)) && pavg!=PT_INSL) // make sparked SWCH turn off correctly + { + if (rt==PT_SWCH&&ct==PT_PSCN&&parts[r>>8].life<10) { + parts[r>>8].life = 10; + } + if (ct==PT_NSCN) { + sim->part_change_type(r>>8,x+rx,y+ry,PT_SWCH); + parts[r>>8].ctype = PT_NONE; + parts[r>>8].life = 9; + } + } + else if ((ct==PT_PSCN||ct==PT_NSCN) && (rt==PT_PUMP||rt==PT_GPMP||rt==PT_HSWC||rt==PT_PBCN)) // PROP_PTOGGLE, Maybe? We seem to use 2 different methods for handling actived elements, this one seems better. Yes, use this one for new elements, PCLN is different for compatibility with existing saves + { + if (ct==PT_PSCN) parts[r>>8].life = 10; + else if (ct==PT_NSCN && parts[r>>8].life>=10) parts[r>>8].life = 9; + } + else if ((ct==PT_PSCN||ct==PT_NSCN) && (rt==PT_LCRY&&abs(rx)<2&&abs(ry)<2)) + { + if (ct==PT_PSCN && parts[r>>8].tmp == 0) parts[r>>8].tmp = 2; + else if (ct==PT_NSCN && parts[r>>8].tmp == 3) parts[r>>8].tmp = 1; + } + + + // ct = spark from material, rt = spark to material. Make conduct_sprk = 0 if conduction not allowed + + if (pavg == PT_INSL) conduct_sprk = 0; + if (!((sim->ptypes[rt].properties&PROP_CONDUCTS)||rt==PT_INST||rt==PT_QRTZ)) conduct_sprk = 0; + if (abs(rx)+abs(ry)>=4 &&ct!=PT_SWCH&&rt!=PT_SWCH) + conduct_sprk = 0; + + + if (ct==PT_METL && (rt==PT_NTCT||rt==PT_PTCT||rt==PT_INWR||(rt==PT_SPRK&&(parts[r>>8].ctype==PT_NTCT||parts[r>>8].ctype==PT_PTCT))) && pavg!=PT_INSL) + { + parts[r>>8].temp = 473.0f; + if (rt==PT_NTCT||rt==PT_PTCT) + conduct_sprk = 0; + } + if (ct==PT_NTCT && !(rt==PT_PSCN || rt==PT_NTCT || (rt==PT_NSCN&&parts[i].temp>373.0f))) + conduct_sprk = 0; + if (ct==PT_PTCT && !(rt==PT_PSCN || rt==PT_PTCT || (rt==PT_NSCN&&parts[i].temp<373.0f))) + conduct_sprk = 0; + if (ct==PT_INWR && !(rt==PT_NSCN || rt==PT_INWR || rt==PT_PSCN)) + conduct_sprk = 0; + if (ct==PT_NSCN && rt==PT_PSCN) + conduct_sprk = 0; + if (ct==PT_ETRD && !(rt==PT_METL||rt==PT_ETRD||rt==PT_BMTL||rt==PT_BRMT||rt==PT_LRBD||rt==PT_RBDM||rt==PT_PSCN||rt==PT_NSCN)) + conduct_sprk = 0; + if (ct==PT_INST&&rt!=PT_NSCN) conduct_sprk = 0; + if (ct==PT_SWCH && (rt==PT_PSCN||rt==PT_NSCN||rt==PT_WATR||rt==PT_SLTW||rt==PT_NTCT||rt==PT_PTCT||rt==PT_INWR)) + conduct_sprk = 0; + if (rt==PT_QRTZ && !((ct==PT_NSCN||ct==PT_METL||ct==PT_PSCN||ct==PT_QRTZ) && (parts[r>>8].temp<173.15||sim->pv[(y+ry)/CELL][(x+rx)/CELL]>8))) + conduct_sprk = 0; + if (rt==PT_NTCT && !(ct==PT_NSCN || ct==PT_NTCT || (ct==PT_PSCN&&parts[r>>8].temp>373.0f))) + conduct_sprk = 0; + if (rt==PT_PTCT && !(ct==PT_NSCN || ct==PT_PTCT || (ct==PT_PSCN&&parts[r>>8].temp<373.0f))) + conduct_sprk = 0; + if (rt==PT_INWR && !(ct==PT_NSCN || ct==PT_INWR || ct==PT_PSCN)) + conduct_sprk = 0; + if (rt==PT_INST&&ct!=PT_PSCN) + conduct_sprk = 0; + + if (conduct_sprk) { + if (rt==PT_WATR||rt==PT_SLTW) { + if (parts[r>>8].life==0 && (parts[i].life<2 || ((r>>8)<i && parts[i].life<3))) + { + sim->part_change_type(r>>8,x+rx,y+ry,PT_SPRK); + if (rt==PT_WATR) parts[r>>8].life = 6; + else parts[r>>8].life = 5; + parts[r>>8].ctype = rt; + } + } + else if (rt==PT_INST) { + if (parts[i].life>=3&&parts[r>>8].life==0) + { + sim->flood_parts(x+rx,y+ry,PT_SPRK,PT_INST,-1, 0);//spark the wire + } + } + else if (parts[r>>8].life==0 && (parts[i].life<3 || ((r>>8)<i && parts[i].life<4))) { + parts[r>>8].life = 4; + parts[r>>8].ctype = rt; + sim->part_change_type(r>>8,x+rx,y+ry,PT_SPRK); + if (parts[r>>8].temp+10.0f<673.0f&&!sim->legacy_enable&&(rt==PT_METL||rt==PT_BMTL||rt==PT_BRMT||rt==PT_PSCN||rt==PT_NSCN||rt==PT_ETRD||rt==PT_NBLE||rt==PT_IRON)) + parts[r>>8].temp = parts[r>>8].temp+10.0f; + } + else if (ct==PT_ETRD && parts[i].life==5) + { + sim->part_change_type(i,x,y,ct); + parts[i].ctype = PT_NONE; + parts[i].life = 20; + parts[r>>8].life = 4; + parts[r>>8].ctype = rt; + sim->part_change_type(r>>8,x+rx,y+ry,PT_SPRK); + } + } + } + return 0; +} + +int graphics_SPRK(GRAPHICS_FUNC_ARGS) +{ + *firea = 80; + + *firer = *colr = 170; + *fireg = *colg = 200; + *fireb = *colb = 220; + //*pixel_mode |= FIRE_ADD; + *pixel_mode |= FIRE_ADD; + return 1; +} diff --git a/src/elements/stkm.cpp b/src/elements/stkm.cpp new file mode 100644 index 0000000..322eba1 --- /dev/null +++ b/src/elements/stkm.cpp @@ -0,0 +1,488 @@ +#include "element.h" + +int update_SPAWN(UPDATE_FUNC_ARGS) { + if (!sim->player.spwn) + sim->create_part(-1, x, y, PT_STKM); + + return 0; +} + +int update_STKM(UPDATE_FUNC_ARGS) +{ + run_stickman(&sim->player, UPDATE_FUNC_SUBCALL_ARGS); + return 0; +} + +int graphics_STKM(GRAPHICS_FUNC_ARGS) +{ + /**pixel_mode = PSPEC_STICKMAN; + if ((int)sim->player.elem<PT_NUM) + { + *colr = PIXR(ptypes[sim->player.elem].pcolors); + *colg = PIXG(ptypes[sim->player.elem].pcolors); + *colb = PIXB(ptypes[sim->player.elem].pcolors); + } + else*/ + { + *colr = *colg = *colb = 255; + } + return 1; +} + +int run_stickman(playerst* playerp, UPDATE_FUNC_ARGS) { + int r, rx, ry; + float pp, d; + float dt = 0.9;///(FPSB*FPSB); //Delta time in square + float gvx, gvy; + float gx, gy, dl, dr; + + if ((parts[i].ctype>0 && parts[i].ctype<PT_NUM && sim->ptypes[parts[i].ctype].falldown>0) || parts[i].ctype==SPC_AIR || parts[i].ctype == PT_NEUT || parts[i].ctype == PT_PHOT || parts[i].ctype == PT_LIGH) + playerp->elem = parts[i].ctype; + playerp->frames++; + + //Tempirature handling + if (parts[i].temp<243) + parts[i].life -= 1; + if ((parts[i].temp<309.6f) && (parts[i].temp>=243)) + parts[i].temp += 1; + + //Death + if (parts[i].life<1 || (sim->pv[y/CELL][x/CELL]>=4.5f && playerp->elem != SPC_AIR) ) //If his HP is less that 0 or there is very big wind... + { + for (r=-2; r<=1; r++) + { + sim->create_part(-1, x+r, y-2, playerp->elem); + sim->create_part(-1, x+r+1, y+2, playerp->elem); + sim->create_part(-1, x-2, y+r+1, playerp->elem); + sim->create_part(-1, x+2, y+r, playerp->elem); + } + sim->kill_part(i); //Kill him + return 1; + } + + //Follow gravity + gvx = gvy = 0.0f; + switch (sim->gravityMode) + { + default: + case 0: + gvy = 1; + break; + case 1: + gvy = gvx = 0.0f; + break; + case 2: + { + float gravd; + gravd = 0.01f - hypotf((parts[i].x - XCNTR), (parts[i].y - YCNTR)); + gvx = ((float)(parts[i].x - XCNTR) / gravd); + gvy = ((float)(parts[i].y - YCNTR) / gravd); + } + } + + gvx += sim->gravx[((int)parts[i].y/CELL)*(XRES/CELL)+((int)parts[i].x/CELL)]; + gvy += sim->gravy[((int)parts[i].y/CELL)*(XRES/CELL)+((int)parts[i].x/CELL)]; + + parts[i].vx -= gvx*dt; //Head up! + parts[i].vy -= gvy*dt; + + //Verlet integration + pp = 2*playerp->legs[0]-playerp->legs[2]+playerp->accs[0]*dt*dt; + playerp->legs[2] = playerp->legs[0]; + playerp->legs[0] = pp; + pp = 2*playerp->legs[1]-playerp->legs[3]+playerp->accs[1]*dt*dt; + playerp->legs[3] = playerp->legs[1]; + playerp->legs[1] = pp; + + pp = 2*playerp->legs[4]-playerp->legs[6]+(playerp->accs[2]+gvx)*dt*dt; + playerp->legs[6] = playerp->legs[4]; + playerp->legs[4] = pp; + pp = 2*playerp->legs[5]-playerp->legs[7]+(playerp->accs[3]+gvy)*dt*dt; + playerp->legs[7] = playerp->legs[5]; + playerp->legs[5] = pp; + + pp = 2*playerp->legs[8]-playerp->legs[10]+playerp->accs[4]*dt*dt; + playerp->legs[10] = playerp->legs[8]; + playerp->legs[8] = pp; + pp = 2*playerp->legs[9]-playerp->legs[11]+playerp->accs[5]*dt*dt; + playerp->legs[11] = playerp->legs[9]; + playerp->legs[9] = pp; + + pp = 2*playerp->legs[12]-playerp->legs[14]+(playerp->accs[6]+gvx)*dt*dt; + playerp->legs[14] = playerp->legs[12]; + playerp->legs[12] = pp; + pp = 2*playerp->legs[13]-playerp->legs[15]+(playerp->accs[7]+gvy)*dt*dt; + playerp->legs[15] = playerp->legs[13]; + playerp->legs[13] = pp; + + //Setting accseleration to 0 + playerp->accs[0] = 0; + playerp->accs[1] = 0; + + playerp->accs[2] = 0; + playerp->accs[3] = 0; + + playerp->accs[4] = 0; + playerp->accs[5] = 0; + + playerp->accs[6] = 0; + playerp->accs[7] = 0; + + gx = (playerp->legs[4] + playerp->legs[12])/2 - gvy; + gy = (playerp->legs[5] + playerp->legs[13])/2 + gvx; + dl = pow(gx - playerp->legs[4], 2) + pow(gy - playerp->legs[5], 2); + dr = pow(gx - playerp->legs[12], 2) + pow(gy - playerp->legs[13], 2); + + //Go left + if (((int)(playerp->comm)&0x01) == 0x01) + { + if (dl>dr) + { + if (!sim->eval_move(PT_DUST, playerp->legs[4], playerp->legs[5], NULL)) + { + playerp->accs[2] = -3*gvy-3*gvx; + playerp->accs[3] = 3*gvx-3*gvy; + playerp->accs[0] = -gvy; + playerp->accs[1] = gvx; + } + } + else + { + if (!sim->eval_move(PT_DUST, playerp->legs[12], playerp->legs[13], NULL)) + { + playerp->accs[6] = -3*gvy-3*gvx; + playerp->accs[7] = 3*gvx-3*gvy; + playerp->accs[0] = -gvy; + playerp->accs[1] = gvx; + } + } + } + + //Go right + if (((int)(playerp->comm)&0x02) == 0x02) + { + if (dl<dr) + { + if (!sim->eval_move(PT_DUST, playerp->legs[4], playerp->legs[5], NULL)) + { + playerp->accs[2] = 3*gvy-3*gvx; + playerp->accs[3] = -3*gvx-3*gvy; + playerp->accs[0] = gvy; + playerp->accs[1] = -gvx; + } + } + else + { + if (!sim->eval_move(PT_DUST, playerp->legs[12], playerp->legs[13], NULL)) + { + playerp->accs[6] = 3*gvy-3*gvx; + playerp->accs[7] = -3*gvx-3*gvy; + playerp->accs[0] = gvy; + playerp->accs[1] = -gvx; + } + } + } + + //Jump + if (((int)(playerp->comm)&0x04) == 0x04 && + (!sim->eval_move(PT_DUST, playerp->legs[4], playerp->legs[5], NULL) || !sim->eval_move(PT_DUST, playerp->legs[12], playerp->legs[13], NULL))) + { + parts[i].vy -= 4*gvy; + playerp->accs[3] -= gvy; + playerp->accs[7] -= gvy; + } + + //Charge detector wall if foot inside + if (sim->bmap[(int)(playerp->legs[5]+0.5)/CELL][(int)(playerp->legs[4]+0.5)/CELL]==WL_DETECT) + sim->set_emap((int)playerp->legs[4]/CELL, (int)playerp->legs[5]/CELL); + if (sim->bmap[(int)(playerp->legs[13]+0.5)/CELL][(int)(playerp->legs[12]+0.5)/CELL]==WL_DETECT) + sim->set_emap((int)(playerp->legs[12]+0.5)/CELL, (int)(playerp->legs[13]+0.5)/CELL); + + //Searching for particles near head + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + r = sim->photons[y+ry][x+rx]; + + if (!r && !sim->bmap[(y+ry)/CELL][(x+rx)/CELL]) + continue; + + if (sim->ptypes[r&0xFF].falldown!=0 || sim->ptypes[r&0xFF].state == ST_GAS || (r&0xFF) == PT_NEUT || (r&0xFF) == PT_PHOT) + { + playerp->elem = r&0xFF; //Current element + } + if ((r&0xFF)==PT_TESC || (r&0xFF)==PT_LIGH) + playerp->elem = PT_LIGH; + if ((r&0xFF) == PT_PLNT && parts[i].life<100) //Plant gives him 5 HP + { + if (parts[i].life<=95) + parts[i].life += 5; + else + parts[i].life = 100; + sim->kill_part(r>>8); + } + + if ((r&0xFF) == PT_NEUT) + { + if (parts[i].life<=100) parts[i].life -= (102-parts[i].life)/2; + else parts[i].life *= 0.9f; + sim->kill_part(r>>8); + } + if (sim->bmap[(ry+y)/CELL][(rx+x)/CELL]==WL_FAN) + playerp->elem = SPC_AIR; + if ((r&0xFF)==PT_PRTI) + STKM_interact(sim, playerp, i, rx, ry); + if (!parts[i].type)//STKM_interact may kill STKM + return 1; + } + + //Head position + rx = x + 3*((((int)playerp->pcomm)&0x02) == 0x02) - 3*((((int)playerp->pcomm)&0x01) == 0x01); + ry = y - 3*(playerp->pcomm == 0); + + //Spawn + if (((int)(playerp->comm)&0x08) == 0x08) + { + ry -= 2*(rand()%2)+1; + r = pmap[ry][rx]; + if (sim->ptypes[r&0xFF].state == ST_SOLID) + { + sim->create_part(-1, rx, ry, PT_SPRK); + playerp->frames = 0; + } + else + { + int np = -1; + if (playerp->elem == SPC_AIR) + sim->create_parts(rx + 3*((((int)playerp->pcomm)&0x02) == 0x02) - 3*((((int)playerp->pcomm)&0x01) == 0x01), ry, 4, 4, SPC_AIR, 0); + else if (playerp->elem==PT_LIGH && playerp->frames<30)//limit lightning creation rate + np = -1; + else + np = sim->create_part(-1, rx, ry, playerp->elem); + if ( (np < NPART) && np>=0) + { + if (playerp->elem == PT_PHOT) + { + int random = abs(rand()%3-1)*3; + if (random==0) + { + sim->kill_part(np); + } + else + { + parts[np].vy = 0; + if (((int)playerp->pcomm)&(0x01|0x02)) + parts[np].vx = (((((int)playerp->pcomm)&0x02) == 0x02) - (((int)(playerp->pcomm)&0x01) == 0x01))*random; + else + parts[np].vx = random; + } + } + else if (playerp->elem == PT_LIGH) + { + float angle; + int power = 100; + if (gvx!=0 || gvy!=0) + angle = atan2(gvx, gvy)*180.0f/M_PI; + else + angle = rand()%360; + if (((int)playerp->comm)&0x01) + angle += 180; + if (angle>360) + angle-=360; + if (angle<0) + angle+=360; + parts[np].tmp = angle; + parts[np].life=rand()%(2+power/15)+power/7; + parts[np].temp=parts[np].life*power/2.5; + parts[np].tmp2=1; + } + else if (playerp->elem != SPC_AIR) + { + parts[np].vx -= -gvy*(5*((((int)playerp->pcomm)&0x02) == 0x02) - 5*(((int)(playerp->pcomm)&0x01) == 0x01)); + parts[np].vy -= gvx*(5*((((int)playerp->pcomm)&0x02) == 0x02) - 5*(((int)(playerp->pcomm)&0x01) == 0x01)); + parts[i].vx -= (sim->ptypes[(int)playerp->elem].weight*parts[np].vx)/1000; + } + playerp->frames = 0; + } + + } + } + + //Simulation of joints + d = 25/(pow((playerp->legs[0]-playerp->legs[4]), 2) + pow((playerp->legs[1]-playerp->legs[5]), 2)+25) - 0.5; //Fast distance + playerp->legs[4] -= (playerp->legs[0]-playerp->legs[4])*d; + playerp->legs[5] -= (playerp->legs[1]-playerp->legs[5])*d; + playerp->legs[0] += (playerp->legs[0]-playerp->legs[4])*d; + playerp->legs[1] += (playerp->legs[1]-playerp->legs[5])*d; + + d = 25/(pow((playerp->legs[8]-playerp->legs[12]), 2) + pow((playerp->legs[9]-playerp->legs[13]), 2)+25) - 0.5; + playerp->legs[12] -= (playerp->legs[8]-playerp->legs[12])*d; + playerp->legs[13] -= (playerp->legs[9]-playerp->legs[13])*d; + playerp->legs[8] += (playerp->legs[8]-playerp->legs[12])*d; + playerp->legs[9] += (playerp->legs[9]-playerp->legs[13])*d; + + d = 36/(pow((playerp->legs[0]-parts[i].x), 2) + pow((playerp->legs[1]-parts[i].y), 2)+36) - 0.5; + parts[i].vx -= (playerp->legs[0]-parts[i].x)*d; + parts[i].vy -= (playerp->legs[1]-parts[i].y)*d; + playerp->legs[0] += (playerp->legs[0]-parts[i].x)*d; + playerp->legs[1] += (playerp->legs[1]-parts[i].y)*d; + + d = 36/(pow((playerp->legs[8]-parts[i].x), 2) + pow((playerp->legs[9]-parts[i].y), 2)+36) - 0.5; + parts[i].vx -= (playerp->legs[8]-parts[i].x)*d; + parts[i].vy -= (playerp->legs[9]-parts[i].y)*d; + playerp->legs[8] += (playerp->legs[8]-parts[i].x)*d; + playerp->legs[9] += (playerp->legs[9]-parts[i].y)*d; + + if (!sim->eval_move(PT_DUST, playerp->legs[4], playerp->legs[5], NULL)) + { + playerp->legs[4] = playerp->legs[6]; + playerp->legs[5] = playerp->legs[7]; + } + + if (!sim->eval_move(PT_DUST, playerp->legs[12], playerp->legs[13], NULL)) + { + playerp->legs[12] = playerp->legs[14]; + playerp->legs[13] = playerp->legs[15]; + } + + //This makes stick man "pop" from obstacles + if (!sim->eval_move(PT_DUST, playerp->legs[4], playerp->legs[5], NULL)) + { + float t; + t = playerp->legs[4]; playerp->legs[4] = playerp->legs[6]; playerp->legs[6] = t; + t = playerp->legs[5]; playerp->legs[5] = playerp->legs[7]; playerp->legs[7] = t; + } + + if (!sim->eval_move(PT_DUST, playerp->legs[12], playerp->legs[13], NULL)) + { + float t; + t = playerp->legs[12]; playerp->legs[12] = playerp->legs[14]; playerp->legs[14] = t; + t = playerp->legs[13]; playerp->legs[13] = playerp->legs[15]; playerp->legs[15] = t; + } + + //Keeping legs distance + if ((pow((playerp->legs[4] - playerp->legs[12]), 2) + pow((playerp->legs[5]-playerp->legs[13]), 2))<16) + { + float tvx, tvy; + tvx = -gvy; + tvy = gvx; + + if (tvx || tvy) + { + playerp->accs[2] -= 0.2*tvx/hypot(tvx, tvy); + playerp->accs[3] -= 0.2*tvy/hypot(tvx, tvy); + + playerp->accs[6] += 0.2*tvx/hypot(tvx, tvy); + playerp->accs[7] += 0.2*tvy/hypot(tvx, tvy); + } + } + + if ((pow((playerp->legs[0] - playerp->legs[8]), 2) + pow((playerp->legs[1]-playerp->legs[9]), 2))<16) + { + float tvx, tvy; + tvx = -gvy; + tvy = gvx; + + if (tvx || tvy) + { + playerp->accs[0] -= 0.2*tvx/hypot(tvx, tvy); + playerp->accs[1] -= 0.2*tvy/hypot(tvx, tvy); + + playerp->accs[4] += 0.2*tvx/hypot(tvx, tvy); + playerp->accs[5] += 0.2*tvy/hypot(tvx, tvy); + } + } + + //If legs touch something + STKM_interact(sim, playerp, i, (int)(playerp->legs[4]+0.5), (int)(playerp->legs[5]+0.5)); + STKM_interact(sim, playerp, i, (int)(playerp->legs[12]+0.5), (int)(playerp->legs[13]+0.5)); + STKM_interact(sim, playerp, i, (int)(playerp->legs[4]+0.5), (int)playerp->legs[5]); + STKM_interact(sim, playerp, i, (int)(playerp->legs[12]+0.5), (int)playerp->legs[13]); + if (!parts[i].type) + return 1; + + parts[i].ctype = playerp->elem; + return 0; +} + +void STKM_interact(Simulation * sim, playerst* playerp, int i, int x, int y) +{ + int r; + if (x<0 || y<0 || x>=XRES || y>=YRES || !sim->parts[i].type) + return; + r = sim->pmap[y][x]; + if (r) + { + if ((r&0xFF)==PT_SPRK && playerp->elem!=PT_LIGH) //If on charge + { + sim->parts[i].life -= (int)(rand()*20/RAND_MAX)+32; + } + + if (sim->ptypes[r&0xFF].hconduct && ((playerp->elem!=PT_LIGH && sim->parts[r>>8].temp>=323) || sim->parts[r>>8].temp<=243)) + { + sim->parts[i].life -= 2; + playerp->accs[3] -= 1; + } + + if (sim->ptypes[r&0xFF].properties&PROP_DEADLY) + switch (r&0xFF) + { + case PT_ACID: + sim->parts[i].life -= 5; + break; + default: + sim->parts[i].life -= 1; + break; + } + + if (sim->ptypes[r&0xFF].properties&PROP_RADIOACTIVE) + sim->parts[i].life -= 1; + + if ((r&0xFF)==PT_PRTI && sim->parts[i].type) + { + int nnx, count=1;//gives rx=0, ry=1 in update_PRTO + sim->parts[r>>8].tmp = (int)((sim->parts[r>>8].temp-73.15f)/100+1); + if (sim->parts[r>>8].tmp>=CHANNELS) sim->parts[r>>8].tmp = CHANNELS-1; + else if (sim->parts[r>>8].tmp<0) sim->parts[r>>8].tmp = 0; + for (nnx=0; nnx<80; nnx++) + if (!sim->portalp[sim->parts[r>>8].tmp][count][nnx].type) + { + sim->portalp[sim->parts[r>>8].tmp][count][nnx] = sim->parts[i]; + sim->kill_part(i); + playerp->spwn = 1;//stop SPWN creating a new STKM while he is in portal + break; + } + } + } +} + +void STKM_init_legs(Simulation * sim, playerst* playerp, int i) +{ + int x, y; + + x = (int)(sim->parts[i].x+0.5f); + y = (int)(sim->parts[i].y+0.5f); + + playerp->legs[0] = x-1; + playerp->legs[1] = y+6; + playerp->legs[2] = x-1; + playerp->legs[3] = y+6; + + playerp->legs[4] = x-3; + playerp->legs[5] = y+12; + playerp->legs[6] = x-3; + playerp->legs[7] = y+12; + + playerp->legs[8] = x+1; + playerp->legs[9] = y+6; + playerp->legs[10] = x+1; + playerp->legs[11] = y+6; + + playerp->legs[12] = x+3; + playerp->legs[13] = y+12; + playerp->legs[14] = x+3; + playerp->legs[15] = y+12; +} diff --git a/src/elements/stkm2.cpp b/src/elements/stkm2.cpp new file mode 100644 index 0000000..967bea2 --- /dev/null +++ b/src/elements/stkm2.cpp @@ -0,0 +1,29 @@ +#include "element.h" + +int update_SPAWN2(UPDATE_FUNC_ARGS) { + if (!sim->player2.spwn) + sim->create_part(-1, x, y, PT_STKM2); + + return 0; +} + +int update_STKM2(UPDATE_FUNC_ARGS) { + run_stickman(&sim->player2, UPDATE_FUNC_SUBCALL_ARGS); + return 0; +} + +int graphics_STKM2(GRAPHICS_FUNC_ARGS) +{ + /**pixel_mode = PSPEC_STICKMAN; + if ((int)sim->player2.elem<PT_NUM) + { + *colr = PIXR(ptypes[sim->player2.elem].pcolors); + *colg = PIXG(ptypes[sim->player2.elem].pcolors); + *colb = PIXB(ptypes[sim->player2.elem].pcolors); + } + else*/ + { + *colr = *colg = *colb = 255; + } + return 1; +} diff --git a/src/elements/stor.cpp b/src/elements/stor.cpp new file mode 100644 index 0000000..66eb072 --- /dev/null +++ b/src/elements/stor.cpp @@ -0,0 +1,43 @@ +#include "element.h" + +int update_STOR(UPDATE_FUNC_ARGS) { + int r, rx, ry, np, rx1, ry1; + if(parts[i].life && !parts[i].tmp) + parts[i].life--; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if ((r>>8)>=NPART || !r) + continue; + if (!parts[i].tmp && !parts[i].life && (r&0xFF)!=PT_STOR && !(sim->ptypes[(r&0xFF)].properties&TYPE_SOLID) && (!parts[i].ctype || (r&0xFF)==parts[i].ctype)) + { + parts[i].tmp = parts[r>>8].type; + parts[i].temp = parts[r>>8].temp; + parts[i].flags = parts[r>>8].life; + parts[i].pavg[0] = parts[r>>8].tmp; + parts[i].pavg[1] = parts[r>>8].ctype; + sim->kill_part(r>>8); + } + if(parts[i].tmp && (r&0xFF)==PT_SPRK && parts[r>>8].ctype==PT_PSCN) + { + for(ry1 = 1; ry1 >= -1; ry1--){ + for(rx1 = 0; rx1 >= -1 && rx1 <= 1; rx1 = -rx1-rx1+1){ // Oscilate the X starting at 0, 1, -1, 3, -5, etc (Though stop at -1) + np = sim->create_part(-1,x+rx1,y+ry1,parts[i].tmp); + if (np!=-1) + { + parts[np].temp = parts[i].temp; + parts[np].life = parts[i].flags; + parts[np].tmp = parts[i].pavg[0]; + parts[np].ctype = parts[i].pavg[1]; + parts[i].tmp = 0; + parts[i].life = 10; + break; + } + } + } + } + } + return 0; +} diff --git a/src/elements/swch.cpp b/src/elements/swch.cpp new file mode 100644 index 0000000..ee2c467 --- /dev/null +++ b/src/elements/swch.cpp @@ -0,0 +1,41 @@ +#include "element.h" + +int update_SWCH(UPDATE_FUNC_ARGS) { + int r, rt, rx, ry; + if (parts[i].life>0 && parts[i].life!=10) + parts[i].life--; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (sim->parts_avg(i,r>>8,PT_INSL)!=PT_INSL) { + rt = r&0xFF; + if (rt==PT_SWCH) + { + if (parts[i].life>=10&&parts[r>>8].life<10&&parts[r>>8].life>0) + parts[i].life = 9; + else if (parts[i].life==0&&parts[r>>8].life==10) + parts[i].life = 10; + } + else if (rt==PT_SPRK&&parts[i].life==10&&parts[r>>8].ctype!=PT_PSCN&&parts[r>>8].ctype!=PT_NSCN) { + sim->part_change_type(i,x,y,PT_SPRK); + parts[i].ctype = PT_SWCH; + parts[i].life = 4; + } + } + } + //turn off SWCH from two red BRAYS + if (parts[i].life==10 && (!(pmap[y-1][x-1]&0xFF) && ((pmap[y-1][x]&0xFF)==PT_BRAY&&parts[pmap[y-1][x]>>8].tmp==2) && !(pmap[y-1][x+1]&0xFF) && ((pmap[y][x+1]&0xFF)==PT_BRAY&&parts[pmap[y][x+1]>>8].tmp==2))) + { + parts[i].life = 9; + } + //turn on SWCH from two red BRAYS + else if (parts[i].life<=5 && (!(pmap[y-1][x-1]&0xFF) && (((pmap[y-1][x]&0xFF)==PT_BRAY&&parts[pmap[y-1][x]>>8].tmp==2) || ((pmap[y+1][x]&0xFF)==PT_BRAY&&parts[pmap[y+1][x]>>8].tmp==2)) && !(pmap[y-1][x+1]&0xFF) && (((pmap[y][x+1]&0xFF)==PT_BRAY&&parts[pmap[y][x+1]>>8].tmp==2) || ((pmap[y][x-1]&0xFF)==PT_BRAY&&parts[pmap[y][x-1]>>8].tmp==2)))) + { + parts[i].life = 14; + } + return 0; +} diff --git a/src/elements/thdr.cpp b/src/elements/thdr.cpp new file mode 100644 index 0000000..f7f95b4 --- /dev/null +++ b/src/elements/thdr.cpp @@ -0,0 +1,38 @@ +#include "element.h" + +int update_THDR(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((sim->ptypes[r&0xFF].properties&PROP_CONDUCTS) && parts[r>>8].life==0 && !((r&0xFF)==PT_WATR||(r&0xFF)==PT_SLTW) && parts[r>>8].ctype!=PT_SPRK) + { + parts[i].type = PT_NONE; + parts[r>>8].ctype = parts[r>>8].type; + sim->part_change_type(r>>8,x+rx,y+ry,PT_SPRK); + parts[r>>8].life = 4; + } + else if ((r&0xFF)!=PT_CLNE&&(r&0xFF)!=PT_THDR&&(r&0xFF)!=PT_SPRK&&(r&0xFF)!=PT_DMND&&(r&0xFF)!=PT_FIRE&&(r&0xFF)!=PT_NEUT&&(r&0xFF)!=PT_PHOT&&(r&0xFF)) + { + sim->pv[y/CELL][x/CELL] += 100.0f; + if (sim->legacy_enable&&1>(rand()%200)) + { + parts[i].life = rand()%50+120; + sim->part_change_type(i,x,y,PT_FIRE); + } + else + { + parts[i].type = PT_NONE; + } + } + } + if (parts[i].type==PT_NONE) { + sim->kill_part(i); + return 1; + } + return 0; +} diff --git a/src/elements/thrm.cpp b/src/elements/thrm.cpp new file mode 100644 index 0000000..91939e6 --- /dev/null +++ b/src/elements/thrm.cpp @@ -0,0 +1,29 @@ +#include "element.h" + +int update_THRM(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_FIRE || (r&0xFF)==PT_PLSM || (r&0xFF)==PT_LAVA)) // TODO: could this go in update_PYRO? + { + if (1>(rand()%500)) { + sim->part_change_type(i,x,y,PT_LAVA); + parts[i].ctype = PT_BMTL; + parts[i].temp = 3500.0f; + sim->pv[y/CELL][x/CELL] += 50.0f; + } else { + sim->part_change_type(i,x,y,PT_LAVA); + parts[i].life = 400; + parts[i].ctype = PT_THRM; + parts[i].temp = 3500.0f; + parts[i].tmp = 20; + } + } + } + return 0; +} diff --git a/src/elements/uran.cpp b/src/elements/uran.cpp new file mode 100644 index 0000000..a8b2a06 --- /dev/null +++ b/src/elements/uran.cpp @@ -0,0 +1,10 @@ +#include "element.h" + +int update_URAN(UPDATE_FUNC_ARGS) { + if (!sim->legacy_enable && sim->pv[y/CELL][x/CELL]>0.0f) + { + float atemp = parts[i].temp + (-MIN_TEMP); + parts[i].temp = restrict_flt((atemp*(1+(sim->pv[y/CELL][x/CELL]/2000)))+MIN_TEMP, MIN_TEMP, MAX_TEMP); + } + return 0; +} diff --git a/src/elements/vine.cpp b/src/elements/vine.cpp new file mode 100644 index 0000000..165d391 --- /dev/null +++ b/src/elements/vine.cpp @@ -0,0 +1,19 @@ +#include "element.h" + +int update_VINE(UPDATE_FUNC_ARGS) { + int r, np, rx =(rand()%3)-1, ry=(rand()%3)-1; + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (1>rand()%15) + sim->part_change_type(i,x,y,PT_PLNT); + else if (!r) + { + np = sim->create_part(-1,x+rx,y+ry,PT_VINE); + if (np<0) return 0; + parts[np].temp = parts[i].temp; + sim->part_change_type(i,x,y,PT_PLNT); + } + } + return 0; +} diff --git a/src/elements/warp.cpp b/src/elements/warp.cpp new file mode 100644 index 0000000..ddc1b81 --- /dev/null +++ b/src/elements/warp.cpp @@ -0,0 +1,28 @@ +#include "element.h" + +int update_WARP(UPDATE_FUNC_ARGS) { + int trade, r, rx, ry; + for ( trade = 0; trade<5; trade ++) + { + rx = rand()%3-1; + ry = rand()%3-1; + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_WARP&&(r&0xFF)!=PT_STKM&&(r&0xFF)!=PT_STKM2&&(r&0xFF)!=PT_DMND&&(r&0xFF)!=PT_CLNE&&(r&0xFF)!=PT_BCLN&&(r&0xFF)!=PT_PCLN&&(10>=rand()%200)) + { + parts[i].x = parts[r>>8].x; + parts[i].y = parts[r>>8].y; + parts[r>>8].x = x; + parts[r>>8].y = y; + parts[i].life += 4; + pmap[y][x] = r; + pmap[y+ry][x+rx] = (i<<8)|parts[i].type; + trade = 5; + } + } + } + return 0; +} diff --git a/src/elements/watr.cpp b/src/elements/watr.cpp new file mode 100644 index 0000000..09b66a9 --- /dev/null +++ b/src/elements/watr.cpp @@ -0,0 +1,36 @@ +#include "element.h" + +int update_WATR(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_SALT && 1>(rand()%250)) + { + sim->part_change_type(i,x,y,PT_SLTW); + sim->part_change_type(r>>8,x+rx,y+ry,PT_SLTW); + } + if (((r&0xFF)==PT_RBDM||(r&0xFF)==PT_LRBD) && (sim->legacy_enable||parts[i].temp>(273.15f+12.0f)) && 1>(rand()%500)) + { + sim->part_change_type(i,x,y,PT_FIRE); + parts[i].life = 4; + } + if ((r&0xFF)==PT_FIRE){ + sim->kill_part(r>>8); + if(1>(rand()%150)){ + sim->kill_part(i); + return 1; + } + } + /*if ((r&0xFF)==PT_CNCT && 1>(rand()%500)) Concrete+Water to paste, not very popular + { + part_change_type(i,x,y,PT_PSTE); + sim.kill_part(r>>8); + }*/ + } + return 0; +} diff --git a/src/elements/wifi.cpp b/src/elements/wifi.cpp new file mode 100644 index 0000000..ee5e264 --- /dev/null +++ b/src/elements/wifi.cpp @@ -0,0 +1,35 @@ +#include "element.h" + +int update_WIFI(UPDATE_FUNC_ARGS) { + int r, rx, ry; + parts[i].tmp = (int)((parts[i].temp-73.15f)/100+1); + if (parts[i].tmp>=CHANNELS) parts[i].tmp = CHANNELS-1; + else if (parts[i].tmp<0) parts[i].tmp = 0; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (sim->wireless[parts[i].tmp][0]) + { + if (((r&0xFF)==PT_NSCN||(r&0xFF)==PT_PSCN||(r&0xFF)==PT_INWR)&&parts[r>>8].life==0 && sim->wireless[parts[i].tmp][0]) + { + parts[r>>8].ctype = r&0xFF; + sim->part_change_type(r>>8,x+rx,y+ry,PT_SPRK); + parts[r>>8].life = 4; + } + } + else + { + if ((r&0xFF)==PT_SPRK && parts[r>>8].ctype!=PT_NSCN && parts[r>>8].life>=3) + { + sim->wireless[parts[i].tmp][0] = 1; + sim->wireless[parts[i].tmp][1] = 1; + //ISWIRE = 1; + } + } + } + return 0; +} diff --git a/src/elements/wire.cpp b/src/elements/wire.cpp new file mode 100644 index 0000000..49d3720 --- /dev/null +++ b/src/elements/wire.cpp @@ -0,0 +1,67 @@ +#include "element.h" + +int update_WIRE(UPDATE_FUNC_ARGS) { + int s,r,rx,ry,count; + /* + 0: wire + 1: spark head + 2: spark tail + + tmp is previous state, ctype is current state + */ + //parts[i].tmp=parts[i].ctype; + parts[i].ctype=0; + if(parts[i].tmp==1) + { + parts[i].ctype=2; + } + if(parts[i].tmp==2) + { + parts[i].ctype=0; + } + + count=0; + for(rx=-1; rx<2; rx++) + for(ry=-1; ry<2; ry++) + { + if(x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if((r&0xFF)==PT_SPRK && parts[r>>8].ctype==PT_PSCN){parts[i].ctype=1; parts[r>>8].life=0; return 0;} + else if((r&0xFF)==PT_NSCN && parts[i].tmp==1){sim->create_part(-1, x+rx, y+ry, PT_SPRK);} + else if((r&0xFF)==PT_WIRE && parts[r>>8].tmp==1 && !parts[i].tmp){count++;} + } + } + if(count==1 || count==2) + parts[i].ctype=1; + return 0; +} + +int graphics_WIRE(GRAPHICS_FUNC_ARGS) +{ + if (cpart->ctype==0) + { + *colr = 255; + *colg = 204; + *colb = 0; + return 0; + } + if (cpart->ctype==1) + { + *colr = 50; + *colg = 100; + *colb = 255; + //*pixel_mode |= PMODE_GLOW; + return 0; + } + if (cpart->ctype==2) + { + *colr = 255; + *colg = 100; + *colb = 50; + //*pixel_mode |= PMODE_GLOW; + return 0; + } +} diff --git a/src/elements/wtrv.cpp b/src/elements/wtrv.cpp new file mode 100644 index 0000000..de0eae4 --- /dev/null +++ b/src/elements/wtrv.cpp @@ -0,0 +1,21 @@ +#include "element.h" + +int update_WTRV(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_RBDM||(r&0xFF)==PT_LRBD) && !sim->legacy_enable && parts[i].temp>(273.15f+12.0f) && 1>(rand()%500)) + { + sim->part_change_type(i,x,y,PT_FIRE); + parts[i].life = 4; + } + } + if(parts[i].temp>1273&&parts[i].ctype==PT_FIRE) + parts[i].temp-=parts[i].temp/1000; + return 0; +} diff --git a/src/elements/yest.cpp b/src/elements/yest.cpp new file mode 100644 index 0000000..c6c7db6 --- /dev/null +++ b/src/elements/yest.cpp @@ -0,0 +1,21 @@ +#include "element.h" + +int update_YEST(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_DYST && 1>(rand()%30) && !sim->legacy_enable) + { + sim->part_change_type(i,x,y,PT_DYST); + } + } + if (parts[i].temp>303&&parts[i].temp<317) { + sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, PT_YEST); + } + return 0; +} |
