diff options
Diffstat (limited to 'src/simulation/elements/TRON.cpp')
| -rw-r--r-- | src/simulation/elements/TRON.cpp | 236 |
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() {} |
