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();

}
Example #2
0
//---------------------------------------------------------------------------//
//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;
	}
}