summaryrefslogtreecommitdiff
path: root/src/simulation/elements/TRON.cpp
diff options
context:
space:
mode:
authorSimon Robertshaw <simon@hardwired.org.uk>2012-11-17 19:44:09 (GMT)
committer Simon Robertshaw <simon@hardwired.org.uk>2012-11-17 19:44:09 (GMT)
commit058a2edd75debbd0297f92572316daa704bd379f (patch)
treead303f091f9a08b209b91eb34a9fcad996a3de69 /src/simulation/elements/TRON.cpp
parente3594aba9e05c6865d396418c028049cda92c2f3 (diff)
parent7a21ae192fe19868539956f3fe28e62b2c7c4429 (diff)
downloadpowder-058a2edd75debbd0297f92572316daa704bd379f.zip
powder-058a2edd75debbd0297f92572316daa704bd379f.tar.gz
Merge branch 'master' of github.com:FacialTurd/PowderToypp
Diffstat (limited to 'src/simulation/elements/TRON.cpp')
-rw-r--r--src/simulation/elements/TRON.cpp236
1 files changed, 236 insertions, 0 deletions
diff --git a/src/simulation/elements/TRON.cpp b/src/simulation/elements/TRON.cpp
new file mode 100644
index 0000000..36493a7
--- /dev/null
+++ b/src/simulation/elements/TRON.cpp
@@ -0,0 +1,236 @@
+#include "simulation/Elements.h"
+//#TPT-Directive ElementClass Element_TRON PT_TRON 143
+Element_TRON::Element_TRON()
+{
+ Identifier = "DEFAULT_PT_TRON";
+ Name = "TRON";
+ Colour = PIXPACK(0xA9FF00);
+ MenuVisible = 1;
+ MenuSection = SC_SPECIAL;
+ Enabled = 1;
+
+ Advection = 0.0f;
+ AirDrag = 0.00f * CFDS;
+ AirLoss = 0.90f;
+ Loss = 0.00f;
+ Collision = 0.0f;
+ Gravity = 0.0f;
+ Diffusion = 0.00f;
+ HotAir = 0.000f * CFDS;
+ Falldown = 0;
+
+ Flammable = 0;
+ Explosive = 0;
+ Meltable = 0;
+ Hardness = 0;
+
+ Weight = 100;
+
+ Temperature = 0.0f;
+ HeatConduct = 40;
+ Description = "Smart particles, Travels in straight lines and avoids obstacles. Grows with time.";
+
+ State = ST_NONE;
+ Properties = TYPE_SOLID|PROP_LIFE_DEC|PROP_LIFE_KILL;
+
+ LowPressure = IPL;
+ LowPressureTransition = NT;
+ HighPressure = IPH;
+ HighPressureTransition = NT;
+ LowTemperature = ITL;
+ LowTemperatureTransition = NT;
+ HighTemperature = ITH;
+ HighTemperatureTransition = NT;
+
+ Update = &Element_TRON::update;
+ Graphics = &Element_TRON::graphics;
+
+ Element_TRON::init_graphics();
+}
+
+#define TRON_HEAD 1
+#define TRON_NOGROW 2
+#define TRON_WAIT 4 //it was just created, so WAIT a frame
+#define TRON_NODIE 8
+#define TRON_DEATH 16 //Crashed, now dying
+int tron_rx[4] = {-1, 0, 1, 0};
+int tron_ry[4] = { 0,-1, 0, 1};
+unsigned int tron_colours[32];
+
+//#TPT-Directive ElementHeader Element_TRON static void init_graphics()
+void Element_TRON::init_graphics()
+{
+ int i;
+ int r, g, b;
+ for (i=0; i<32; i++)
+ {
+ HSV_to_RGB(i<<4,255,255,&r,&g,&b);
+ tron_colours[i] = r<<16 | g<<8 | b;
+ }
+}
+
+//#TPT-Directive ElementHeader Element_TRON static int update(UPDATE_FUNC_ARGS)
+int Element_TRON::update(UPDATE_FUNC_ARGS)
+ {
+ int r, rx, ry, np;
+ if (parts[i].tmp&TRON_WAIT)
+ {
+ parts[i].tmp &= ~TRON_WAIT;
+ return 0;
+ }
+ if (parts[i].tmp&TRON_HEAD)
+ {
+ int firstdircheck = 0,seconddir,seconddircheck = 0,lastdir,lastdircheck = 0;
+ int direction = (parts[i].tmp>>5 & 0x3);
+ int originaldir = direction;
+
+ //random turn
+ int random = rand()%340;
+ if (random==1 || random==3)
+ {
+ //randomly turn left(3) or right(1)
+ direction = (direction + random)%4;
+ }
+
+ //check infront
+ //do sight check
+ firstdircheck = Element_TRON::trymovetron(sim,x,y,direction,i,parts[i].tmp2);
+ if (firstdircheck < parts[i].tmp2)
+ {
+ if (originaldir != direction) //if we just tried a random turn, don't pick random again
+ {
+ seconddir = originaldir;
+ lastdir = (direction + 2)%4;
+ }
+ else
+ {
+ seconddir = (direction + ((rand()%2)*2)+1)% 4;
+ lastdir = (seconddir + 2)%4;
+ }
+ seconddircheck = trymovetron(sim,x,y,seconddir,i,parts[i].tmp2);
+ lastdircheck = trymovetron(sim,x,y,lastdir,i,parts[i].tmp2);
+ }
+ //find the best move
+ if (seconddircheck > firstdircheck)
+ direction = seconddir;
+ if (lastdircheck > seconddircheck && lastdircheck > firstdircheck)
+ direction = lastdir;
+ //now try making new head, even if it fails
+ if (Element_TRON::new_tronhead(sim,x + tron_rx[direction],y + tron_ry[direction],i,direction) == -1)
+ {
+ //ohgod crash
+ parts[i].tmp |= TRON_DEATH;
+ //trigger tail death for TRON_NODIE, or is that mode even needed? just set a high tail length(but it still won't start dying when it crashes)
+ }
+
+ //set own life and clear .tmp (it dies if it can't move anyway)
+ parts[i].life = parts[i].tmp2;
+ parts[i].tmp &= parts[i].tmp&0xF818;
+ }
+ else // fade tail deco, or prevent tail from dieing
+ {
+ if (parts[i].tmp&TRON_NODIE)
+ parts[i].life++;
+ //parts[i].dcolour = clamp_flt((float)parts[i].life/(float)parts[i].tmp2,0,1.0f) << 24 | parts[i].dcolour&0x00FFFFFF;
+ }
+ return 0;
+}
+
+
+
+//#TPT-Directive ElementHeader Element_TRON static int graphics(GRAPHICS_FUNC_ARGS)
+int Element_TRON::graphics(GRAPHICS_FUNC_ARGS)
+ {
+ unsigned int col = tron_colours[(cpart->tmp&0xF800)>>11];
+ if(cpart->tmp & TRON_HEAD)
+ *pixel_mode |= PMODE_GLOW;
+ *colr = (col & 0xFF0000)>>16;
+ *colg = (col & 0x00FF00)>>8;
+ *colb = (col & 0x0000FF);
+ if(cpart->tmp & TRON_DEATH)
+ {
+ *pixel_mode |= FIRE_ADD | PMODE_FLARE;
+ *firer = *colr;
+ *fireg = *colg;
+ *fireb = *colb;
+ *firea = 255;
+ }
+ if(cpart->life < cpart->tmp2 && !(cpart->tmp & TRON_HEAD))
+ {
+ *pixel_mode |= PMODE_BLEND;
+ *pixel_mode &= ~PMODE_FLAT;
+ *cola = (int)((((float)cpart->life)/((float)cpart->tmp2))*255.0f);
+ }
+ return 0;
+}
+
+//#TPT-Directive ElementHeader Element_TRON static int new_tronhead(Simulation * sim, int x, int y, int i, int direction)
+int Element_TRON::new_tronhead(Simulation * sim, int x, int y, int i, int direction)
+{
+ int np = sim->create_part(-1, x , y ,PT_TRON);
+ if (np==-1)
+ return -1;
+ if (sim->parts[i].life >= 100) // increase tail length
+ {
+ if (!(sim->parts[i].tmp&TRON_NOGROW))
+ sim->parts[i].tmp2++;
+ sim->parts[i].life = 5;
+ }
+ //give new head our properties
+ sim->parts[np].tmp = 1 | direction<<5 | sim->parts[i].tmp&(TRON_NOGROW|TRON_NODIE) | (sim->parts[i].tmp&0xF800);
+ if (np > i)
+ sim->parts[np].tmp |= TRON_WAIT;
+
+ sim->parts[np].ctype = sim->parts[i].ctype;
+ sim->parts[np].tmp2 = sim->parts[i].tmp2;
+ sim->parts[np].life = sim->parts[i].life + 2;
+ return 1;
+}
+
+//#TPT-Directive ElementHeader Element_TRON static int trymovetron(Simulation * sim, int x, int y, int dir, int i, int len)
+int Element_TRON::trymovetron(Simulation * sim, int x, int y, int dir, int i, int len)
+{
+ int k,j,r,rx,ry,tx,ty,count;
+ count = 0;
+ rx = x;
+ ry = y;
+ for (k = 1; k <= len; k ++)
+ {
+ rx += tron_rx[dir];
+ ry += tron_ry[dir];
+ r = sim->pmap[ry][rx];
+ if (!r && !sim->bmap[(ry)/CELL][(rx)/CELL] && ry > CELL && rx > CELL && ry < YRES-CELL && rx < XRES-CELL)
+ {
+ count++;
+ for (tx = rx - tron_ry[dir] , ty = ry - tron_rx[dir], j=1; abs(tx-rx) < (len-k) && abs(ty-ry) < (len-k); tx-=tron_ry[dir],ty-=tron_rx[dir],j++)
+ {
+ r = sim->pmap[ty][tx];
+ if (!r && !sim->bmap[(ty)/CELL][(tx)/CELL] && ty > CELL && tx > CELL && ty < YRES-CELL && tx < XRES-CELL)
+ {
+ if (j == (len-k))//there is a safe path, so we can break out
+ return len+1;
+ count++;
+ }
+ else //we hit a block so no need to check farther here
+ break;
+ }
+ for (tx = rx + tron_ry[dir] , ty = ry + tron_rx[dir], j=1; abs(tx-rx) < (len-k) && abs(ty-ry) < (len-k); tx+=tron_ry[dir],ty+=tron_rx[dir],j++)
+ {
+ r = sim->pmap[ty][tx];
+ if (!r && !sim->bmap[(ty)/CELL][(tx)/CELL] && ty > CELL && tx > CELL && ty < YRES-CELL && tx < XRES-CELL)
+ {
+ if (j == (len-k))
+ return len+1;
+ count++;
+ }
+ else
+ break;
+ }
+ }
+ else //a block infront, no need to continue
+ break;
+ }
+ return count;
+}
+
+Element_TRON::~Element_TRON() {}