/* * drone.c */ #include #include "pad.h" #include "defs.h" #include "sincos.h" #include "tank.h" #include "missile.h" #include "floor.h" #define MISSILE_TIME_2 50 // 2secs @ 25fps #include "player.h" void homeMissile(player_str *tank, int me, int op) { long dx, dz, tx, tz, mx, mz; short angle; tx = BTanks[op].coord2->coord.t[0]; tz = BTanks[op].coord2->coord.t[2]; mx = Bullets[me].coord2->coord.t[0]; mz = Bullets[me].coord2->coord.t[2]; dx = tx - mx; dz = tz - mz; angle = rinvtan(dz, dx); if(((tank->angle - angle + 4096) & 4095) > 32) { if(angle < tank->angle) { tank->angle -= 32; tank->mtilt = -64; } else { tank->angle += 32; tank->mtilt = 64; } } else tank->mtilt = 0; } void droneMove(player_str *tank, u_long pad, int me, int op) { long dx, dz, tx, tz, mx, mz, td, td2, td3, vt1, vt2; short angle; MATRIX ltw; GsCOORDINATE2 dir; SVECTOR rot, hpl; VECTOR hpw; //#define __STOP_THE_PIDGEON #ifdef __STOP_THE_PIDGEON return; #endif // the sneaky drone code... tx = BTanks[op].coord2->coord.t[0]; tz = BTanks[op].coord2->coord.t[2]; if(tank->mode & MODE_HIT) { if((tank->vp & 0x07) > 3) tank->vp -= 4; tank->xpos = tank->xold; tank->zpos = tank->zold; tank->xmot = 0; tank->zmot = 0; tank->hittime = 50; tank->mode = MODE_MOVE | MODE_DRONE | MODE_SPIN; } if(tank->mode & MODE_SCORE) { if((tank->vp & 0x07) > 3) tank->vp -= 4; tank->xpos = tank->xold; tank->zpos = tank->zold; tank->mode = MODE_DRONE; tank->xmot = 0; tank->zmot = 0; tank->hittime = 50; // dissable firing... } if(tank->mode == (MODE_TANK | MODE_DRONE)) { mx = BTanks[me].coord2->coord.t[0]; mz = BTanks[me].coord2->coord.t[2]; dx = tx - mx; // reverse these, and the order they're used dz = tz - mz; // in the invtan for 'dancing drone's' angle = rinvtan(dz, dx); if(((tank->angle - angle + 4096) & 4095) < 64) // almost straight ahead { td = abs(dx) + abs(dz); if(td < 4096 && !tank->hittime) // fire! { tank->keyhold |= PADR2; tank->mode |= MODE_MISSILE; tank->missiletime = MISSILE_TIME_2; tank->xold = tank->xpos; tank->zold = tank->zpos; tank->xpos += rsin(tank->angle) >> 8; tank->zpos += rcos(tank->angle) >> 8; } } else { if(angle < tank->angle) tank->angle -= 32; else tank->angle += 32; } if(!(tank->mode & MODE_MISSILE)) { if(tank->xmot || tank->zmot) // last move was valid { tank->xmot = rsin(tank->angle) >> 8; tank->zmot = rcos(tank->angle) >> 8; } else // invalid move - reverse? { tank->xmot = -rsin(tank->angle) >> 8; tank->zmot = -rcos(tank->angle) >> 8; } tank->mode |= MODE_MOVE; } } if(tank->mode & MODE_MISSILE) { if(tank->keyhold & PADR2) { if((tank->vp & 0x07) < 2) tank->vp += 4; } else { if((tank->vp & 0x07) > 3) tank->vp -= 4; } tank->missiletime--; if(!tank->missiletime) { tank->keyhold &= ~PADR2; tank->xpos = tank->xold; tank->zpos = tank->zold; tank->xmot = 0; tank->zmot = 0; tank->mode &= ~MODE_MISSILE; } else { homeMissile(tank, me, op); tank->xmot = rsin(tank->angle) >> 6; tank->zmot = rcos(tank->angle) >> 6; } } if(tank->hittime) tank->hittime--; if(tank->mode & MODE_SPIN) { tank->angle += 408; if(!tank->hittime) tank->mode &= ~MODE_SPIN; } if(tank->mode & MODE_MISS) { if((tank->vp & 0x07) > 3) tank->vp -= 4; tank->xpos = tank->xold; tank->zpos = tank->zold; tank->mode = MODE_DRONE; tank->hittime = 25; // don't try again for 25 frames } } /* * below is where the old drone code is kept... */ //#define NOT_SO_OLD_DRONE_CODE #ifdef NOT_SO_OLD_DRONE_CODE dir = *(BTanks[me].coord2); // setVector(&rot, 0, tank->angle, 0); // RotMatrix(&rot, &(dir.coord)); RotMatrixY(tank->angle, &(dir.coord)); GsGetLw(&dir, <w); setVector(&hpl, 0, 0, TANK_BOUNDC << 1); ApplyMatrix(<w, &hpl, &hpw); // consider a point at the // front of the tank mx = dir.coord.t[0] + hpw.vx; mz = dir.coord.t[2] + hpw.vz; printf("At angle %d point is at %d, %d\n", tank->angle, hpw.vx, hpw.vz); dx = tx - mx; dz = tz - mz; td = abs(dx) + abs(dz); // find the right angled distance setVector(&hpl, TANK_BOUNDC, 0, 0); ApplyMatrix(<w, &hpl, &hpw); mx = dir.coord.t[0] + hpw.vx; mz = dir.coord.t[2] + hpw.vz; dx = tx - mx; dz = tz - mz; vt1 = abs(dx) + abs(dz); // find the right angled distance setVector(&hpl, -TANK_BOUNDC, 0, 0); ApplyMatrix(<w, &hpl, &hpw); mx = dir.coord.t[0] + hpw.vx; mz = dir.coord.t[2] + hpw.vz; dx = tx - mx; dz = tz - mz; vt2 = abs(dx) + abs(dz); // find the right angled distance if(td < vt1 && td < vt2 && td < 2048) // were close fire anyway { tank->mode |= MODE_MISSILE; tank->missiletime = 50; // 2 secs @ 25fps tank->xold = tank->xpos; tank->zold = tank->zpos; } else { angle = 0; if(vt1 < td) angle = -32; if(vt2 < td) angle = 32; tank->angle += angle; tank->angle &= 4095; #endif #ifdef OLD_DRONE_CODE angle = (tx < mx) ? -32 : 32; // which way to turn (if facing northish) printf("Suggested move: rotate %d\n", angle); printf("Target @ (%d, %d) distance = %d (%d, %d)\n", tx, tz, td, dx, dz); if(tank->angle > 1024 && tank->angle < 3072) angle = tank->angle - angle;// facing south, turn the other way else angle += tank->angle; // turn angle &= 4095; printf("Current angle = %d, trying %d\n", tank->angle, angle); // setVector(&rot, 0, angle, 0); // RotMatrix(&rot, &(dir.coord)); RotMatrixY(angle, &(dir.coord)); GsGetLw(&dir, <w); ApplyMatrix(<w, &hpl, &hpw); mx = dir.coord.t[0] + hpw.vx; mz = dir.coord.t[2] + hpw.vz; // same point in // front of the tank dx = tx - mx; dz = tz - mz; td2 = abs(dx) + abs(dz); // find the distance printf("At angle %d point is at %d, %d\n", angle, hpw.vx, hpw.vz); printf("New target distance = %d (%d, %d)\n", td2, dx, dz); /* printf("Trying %d (%d)\n", -angle, 2 * (-angle)); setVector(&rot, 0, 2 * (-angle), 0); // try the other way RotMatrix(&rot, &(dir.coord)); GsGetLw(&dir, <w); ApplyMatrix(<w, &hpl, &hpw); mx = hpw.vx; mz = hpw.vz; // same point in // front of the tank dx = tx - mx; dz = tz - mz; td3 = abs(dx) + abs(dz); // find the distance printf("New target distance = %d (%d, %d)\n", td3, dx, dz); */ if(td2 <= td) // aha this makes things better { FntPrint("New Heading %d (%d < %d)\n", angle, td2, td); tank->angle = angle & 4095; tank->xmot = rsin(tank->angle) >> 8; tank->zmot = rcos(tank->angle) >> 8; tank->mode |= MODE_MOVE; } /* else if(td3 < td) // this way { FntPrint("New Heading %d (%d < %d)\n", angle, td2, td); tank->angle = (-angle) & 4095; tank->xmot = rsin(tank->angle) >> 8; tank->zmot = rcos(tank->angle) >> 8; tank->mode |= MODE_MOVE; } */ else // move forward { #endif