void cRocketTurret::think() { int iMyIndex = -1; for (int i = 0; i < MAX_STRUCTURES; i++) { if (structure[i] == this) { iMyIndex = i; break; } } // this should not happen, but just in case if (iMyIndex < 0) { return; } if (player[getOwner()].bEnoughPower() == false) { return; // do not fire a thing now } // turning & shooting if (iTargetID > -1) { if (unit[iTargetID].isValid()) { // first make sure we face okay! int iCellX = iCellGiveX(getCell()); int iCellY = iCellGiveY(getCell()); int iTargetX = iCellGiveX(unit[iTargetID].iCell); int iTargetY = iCellGiveY(unit[iTargetID].iCell); int d = fDegrees(iCellX, iCellY, iTargetX, iTargetY); int f = face_angle(d); // get the angle // set facing iShouldHeadFacing = f; if (iShouldHeadFacing == iHeadFacing || (unit[iTargetID].iType == ORNITHOPTER)) { TIMER_fire++; int iDistance = 9999; int iSlowDown = 250; if (getType() == RTURRET) iSlowDown = 450; if (unit[iTargetID].isValid()) { // calculate distance iDistance = ABS_length(iCellX, iCellY, iTargetX, iTargetY); if (iDistance > structures[getType()].sight) iTargetID = -1; } else iTargetID = -1; if (iTargetID < 0) return; if (TIMER_fire > iSlowDown) { int iTargetCell = unit[iTargetID].iCell; int iBullet = BULLET_TURRET; if (getType() == RTURRET && iDistance > 3) iBullet = ROCKET_RTURRET; else { int iShootX = (iDrawX() + 16) + (mapCamera->getX() * 32); int iShootY = (iDrawY() + 16) + (mapCamera->getY() * 32); int bmp_head = convert_angle(iHeadFacing); PARTICLE_CREATE(iShootX, iShootY, OBJECT_TANKSHOOT, -1, bmp_head); } int iBull = create_bullet(iBullet, getCell(), iTargetCell, -1, iMyIndex); if (unit[iTargetID].iType == ORNITHOPTER) { // it is a homing missile! bullet[iBull].iHoming = iTargetID; bullet[iBull].TIMER_homing = 200; } TIMER_fire = 0; } } else { TIMER_turn++; int iSlowDown = 200; if (TIMER_turn > iSlowDown) { TIMER_turn = 0; int d = 1; int toleft = (iHeadFacing + 8) - iShouldHeadFacing; if (toleft > 7) toleft -= 8; int toright = abs(toleft - 8); if (toright == toleft) d = -1 + (rnd(2)); if (toleft > toright) d = 1; if (toright > toleft) d = -1; iHeadFacing += d; if (iHeadFacing < 0) iHeadFacing = 7; if (iHeadFacing > 7) iHeadFacing = 0; } // turning } } else iTargetID = -1; } // think like base class cAbstractStructure::think(); }
//---------------------------------------------------------------------------// //check to see if any of A's edges match any of B's edges static void edge_check ( LTNeighbor tn[],//neighbors const uint16 ta, //index of triangle A const uint16 tb, //index of triangle B const LTTriangle t[],//triangles const LTVector3f V[] //vertices ) { //NOTE: To handle non-manifold geometry, the angle //between faces with shared edges is minimized. So //if you have two faces 'b1' and 'b2' that look like: // // b1\ /b2 // \/______ A // //(both share an edge with A), then A considers b2 its //neighbor, and vice-versa. This makes more sense for //contact detection algorithms. const LTTriangle& A = t[ta];//triangle A const LTTriangle& B = t[tb];//triangle B LTNeighbor& Na = tn[ta];//A's neighbors LTNeighbor& Nb = tn[tb];//B's neighbors uint16 a0 = A.v[2];//first vertex along A's edge //check each of A's edges... for( int32 j=0 ; j<3 ; j++ ) { //A's edge is the directed line segment V[a0]->V[a1], //or more precisely V[A.v[j-1]]->V[A.v[j]] const uint16 a1 = A.v[j];//second vertex along A's edge uint16 b0 = B.v[2];//first vertex along B's edge //...against each of B's edges for( int32 k=0 ; k<3 ; k++ ) { const uint16 b1 = B.v[k];//second vertex along A's edge //do the vertices match? //(the edges go in //opposite directions) if( a0==b1 && a1==b0 ) { //to which index (0,1 or 2) does //the neighbor "link" correspond? const uint16 ja = ((j>0) ? ((uint16)(j-1)) : (uint16)2); const uint16 kb = ((k>0) ? ((uint16)(k-1)) : (uint16)2); //find the angle between A and B const float angle_ab = face_angle( B, A, ja, V ); //if A already has a neighbor along //this edge, find the angle between //A and its neighbor float angle_a = 2*PI + 0.1f;//handle the case of no neighbor const uint16 an = Na.t[ja];//A's current neighbor if( an != 0xFFFF )//then A has a neighbor { angle_a = face_angle( t[an], A, ja, V ); } //if B already has a neighbor along //this edge, find the angle between //B and its neighbor float angle_b = 2*PI + 0.1f;//handle the case of no neighbor const uint16 bn = Nb.t[kb];//B's current neighbor if( bn != 0xFFFF )//then B has a neighbor { angle_b = face_angle( t[bn], B, kb, V ); } //if the angle between A and B is less than //either of the angles A or B makes with its //current neighbor, then make A<->B and make //their neighbors ->0xFFFF if( angle_ab < angle_a && angle_ab < angle_b ) { LT_MEM_TRACK_ALLOC(Na.t[ja] = tb,LT_MEM_TYPE_PHYSICS); //A's new neighbor LT_MEM_TRACK_ALLOC(Nb.t[kb] = ta,LT_MEM_TYPE_PHYSICS); //B's new neighbor if( an != 0xFFFF ) { break_neighbor_link( tn[an], b0, t[an] ); } if( bn != 0xFFFF ) { break_neighbor_link( tn[bn], a0, t[bn] ); } } } //on the next iteration, b0 = b1; } //on the next iteration, a0 = a1; } }