Пример #1
0
static int16 InterpolateAngle(int16 Angle, GLfloat MixFrac, int16 AddlAngle)
{
  if (MixFrac != 0 && AddlAngle != Angle) {
    int16 AngleDiff = NORMALIZE_ANGLE(AddlAngle - Angle);
    if (AngleDiff >= HALF_CIRCLE) {
      AngleDiff -= FULL_CIRCLE;
    }
    Angle += int16(MixFrac*AngleDiff);
  }
  return NORMALIZE_ANGLE(Angle);
}
Пример #2
0
//============================================================================
//カメラリセット
//============================================================================
//[input]
//	pCam:カメラデータ
//	pPlayer:プレイヤーオブジェクト
//===========================================================================
void CCamButton::Reset( CCamera *pCam[], CPlayer *pPlayer )
{
	/*カメラリセット*/
	if( ::Collision::Point_Rect( vMousePos, m_pResetBtnSpr->GetHitRect() ) )
	{
		Math::Point3DI Rot;
		
		Rot.x = pPlayer->GetRotate().y;
		Rot.y = NORMALIZE_ANGLE( pPlayer->GetRotate().x );
		Rot.z = pPlayer->GetRotate().z;
		
		if( CCommonObject::GetMouse()->GetMouse()->GetStateL() == MOUSE_PUSH )
		{
			m_IsCamReset = true;
		
			for( int i = 0;i < SCREEN_MAX;++i )
			{	
				pCam[i]->SetRotate( Rot );
			}
			
			
		}
		
		else
		{
			GetResetButton()->SetAnimXID( 2 );
		}
	}
	
	else if( CCommonObject::GetMouse()->GetMouse()->GetStateW() == MOUSE_PUSH )
	{
		Math::Point3DI Rot;
		
		Rot.x = pPlayer->GetRotate().y;
		Rot.y = NORMALIZE_ANGLE( pPlayer->GetRotate().x );
		Rot.z = pPlayer->GetRotate().z;
		
		m_IsCamReset = true;
	
		for( int i = 0;i < SCREEN_MAX;++i )
		{	
			pCam[i]->SetRotate( Rot );
		}
	}
	
	else
	{
		m_IsCamReset = false;
		GetResetButton()->SetAnimXID( 1 );
		
		
	}

}
Пример #3
0
bool pointInTriangle(QPointF point, const Triangle &triangle) {
	QPointF a = triangle[0], b = triangle[1], c = triangle[2];
	if (point == a || point == b || point == c)
		return true;
	QLineF line0(point, a), line1(point, b), line2(point, c);
	qreal angle0 = line0.angleTo(line1);
	angle0 = NORMALIZE_ANGLE(angle0);
	qreal angle1 = line1.angleTo(line2);
	angle1 = NORMALIZE_ANGLE(angle1);
	qreal angle2 = line2.angleTo(line0);
	angle2 = NORMALIZE_ANGLE(angle2);
	return qAbs(angle0 + angle1 + angle2 - 360) < EPS;
}
Пример #4
0
static bool
GenerateSpathi_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet)
{
	COUNT angle;

	GenerateDefault_generateMoons (solarSys, planet);

	if (matchWorld (solarSys, planet, 0, MATCH_PLANET))
	{
#ifdef NOTYET
		utf8StringCopy (GLOBAL_SIS (PlanetName),
				sizeof (GLOBAL_SIS (PlanetName)),
				"Spathiwa");
#endif /* NOTYET */

		solarSys->MoonDesc[0].data_index = PELLUCID_WORLD;
		solarSys->MoonDesc[0].alternate_colormap = NULL;
		solarSys->MoonDesc[0].radius = MIN_MOON_RADIUS + MOON_DELTA;
		angle = NORMALIZE_ANGLE (LOWORD (RandomContext_Random (SysGenRNG)));
		solarSys->MoonDesc[0].location.x =
				COSINE (angle, solarSys->MoonDesc[0].radius);
		solarSys->MoonDesc[0].location.y =
				SINE (angle, solarSys->MoonDesc[0].radius);
		ComputeSpeed(&solarSys->MoonDesc[0], TRUE, 1);
	}

	return true;
}
Пример #5
0
hpix_pixel_num_t
hpix_angles_to_ring_pixel(const hpix_resolution_t * resolution,
			  double theta,
			  double phi)
{
    assert(resolution != NULL);

    int jp, jm, ipix1;
    int ir, ip;

    hpix_nside_t nside = resolution->nside;
    hpix_nside_t nl2 = resolution->nside_times_two;
    hpix_nside_t nl4 = resolution->nside_times_four;
    unsigned int ncap  = resolution->ncap;

    double z = cos(theta);
    double z_abs = fabs(z);
    NORMALIZE_ANGLE(phi);
    double tt = phi / (0.5 * M_PI);

    if(z_abs <= 2./3.)
    {
	jp = (int) floor(nside * (0.5 + tt - z*0.75));
	jm = (int) floor(nside * (0.5 + tt + z*0.75));

	ir = nside + 1 + jp - jm;
	int kshift = 0;
	if(fmod(ir, 2) == 0.)
	    kshift = 1;

	ip = (int) floor((jp + jm - nside + kshift + 1) / 2) + 1;
	if(ip > nl4)
	    ip = ip - nl4;

	ipix1 = ncap + nl4 * (ir - 1) + ip;
    } else {
	double tp = tt - floor(tt);
	double tmp = sqrt(3. * (1. - z_abs));

	jp = (int) floor(nside * tp * tmp );
	jm = (int) floor(nside * (1. - tp) * tmp);

	ir = jp + jm + 1;
	ip = (int) floor(tt * ir) + 1;
	if(ip > 4 * ir)
	    ip -= 4 * ir;

	ipix1 = 2 * ir * (ir - 1) + ip;
	if (z <= 0.)
	{
	    ipix1 = resolution->num_of_pixels - 2 * ir * (ir + 1) + ip;
	}
    }
    return ipix1 - 1;
}
long ang2pix_ring(unsigned int nside,
		  double theta,
		  double phi)
{
    int nl2, nl4, ncap, npix;

    nl2 = 2*nside;
    nl4 = 4*nside;
    ncap  = nl2*(nside-1);
    npix  = 12*nside*nside;

    int jp, jm, ipix1;
    double z, z_abs, tt, tp, tmp;
    int ir, ip, kshift;

    z = cos(theta);
    z_abs = fabs(z);
    NORMALIZE_ANGLE(phi);
    tt = phi / (0.5 * M_PI);

    if(z_abs <= 2./3.)
    {
	jp = (int)floor(nside * (0.5 + tt - z*0.75));
	jm = (int)floor(nside * (0.5 + tt + z*0.75));

	ir = nside + 1 + jp - jm;
	kshift = 0;
	if(fmod(ir, 2) == 0.)
	    kshift = 1;

	ip = (int) floor((jp + jm - nside + kshift + 1) / 2) + 1;
	if(ip > nl4)
	    ip = ip - nl4;

	ipix1 = ncap + nl4 * (ir - 1) + ip;
    } else {
	tp = tt - floor(tt);
	tmp = sqrt(3. * (1. - z_abs));

	jp = (int) floor(nside * tp * tmp );
	jm = (int) floor(nside * (1. - tp) * tmp);

	ir = jp + jm + 1;
	ip = (int) floor(tt * ir) + 1;
	if(ip > 4 * ir)
	    ip = ip - 4 * ir;

	ipix1 = 2 * ir * (ir - 1) + ip;
	if (z <= 0.)
	{
	    ipix1 = npix - 2*ir*(ir+1) + ip;
	}
    }
    return ipix1 - 1;
}
Пример #7
0
void
hpix_vector_to_angles(const hpix_vector_t * vector,
		     double * theta, double * phi)
{
    assert(vector);
    assert(theta && phi);

    double vector_len = hpix_vector_length(vector);
    *theta = acos(vector->z / vector_len);
    *phi = atan2(vector->y, vector->x);
    NORMALIZE_ANGLE(*phi);
}
Пример #8
0
static bool
GenerateSaMatra_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet)
{
	GenerateDefault_generateMoons (solarSys, planet);

	if (matchWorld (solarSys, planet, 4, MATCH_PLANET))
	{
		COUNT angle;
		DWORD rand_val;

		solarSys->MoonDesc[0].data_index = SA_MATRA;
		solarSys->MoonDesc[0].radius = MIN_MOON_RADIUS + (2 * MOON_DELTA);
		rand_val = TFB_Random ();
		angle = NORMALIZE_ANGLE (LOWORD (rand_val));
		solarSys->MoonDesc[0].location.x =
				COSINE (angle, solarSys->MoonDesc[0].radius);
		solarSys->MoonDesc[0].location.y =
				SINE (angle, solarSys->MoonDesc[0].radius);
	}

	return true;
}
Пример #9
0
static bool
GenerateBurvixese_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet)
{
	GenerateDefault_generateMoons (solarSys, planet);

	if (matchWorld (solarSys, planet, 0, MATCH_PLANET))
	{
		COUNT angle;
		DWORD rand_val;

		solarSys->MoonDesc[0].data_index = SELENIC_WORLD;
		solarSys->MoonDesc[0].radius = MIN_MOON_RADIUS
				+ (MAX_MOONS - 1) * MOON_DELTA;
		rand_val = TFB_Random ();
		angle = NORMALIZE_ANGLE (LOWORD (rand_val));
		solarSys->MoonDesc[0].location.x =
				COSINE (angle, solarSys->MoonDesc[0].radius);
		solarSys->MoonDesc[0].location.y =
				SINE (angle, solarSys->MoonDesc[0].radius);
		ComputeSpeed(&solarSys->MoonDesc[0], TRUE, 1);
	}
	return true;
}
Пример #10
0
static bool
GenerateChmmr_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet)
{
	GenerateDefault_generateMoons (solarSys, planet);

	if (matchWorld (solarSys, planet, 1, MATCH_PLANET))
	{
		COUNT angle;
		DWORD rand_val;

		solarSys->MoonDesc[0].data_index = HIERARCHY_STARBASE;
		solarSys->MoonDesc[0].radius = MIN_MOON_RADIUS;
		rand_val = TFB_Random ();
		angle = NORMALIZE_ANGLE (LOWORD (rand_val));
		solarSys->MoonDesc[0].location.x =
				COSINE (angle, solarSys->MoonDesc[0].radius);
		solarSys->MoonDesc[0].location.y =
				SINE (angle, solarSys->MoonDesc[0].radius);
		ComputeSpeed(&solarSys->MoonDesc[0], TRUE, 1);
	}

	return true;
}
Пример #11
0
static void
androsynth_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern,
		COUNT ConcernCounter)
{
	EVALUATE_DESC *lpEvalDesc;
	STARSHIP *StarShipPtr;

	GetElementStarShip (ShipPtr, &StarShipPtr);

	lpEvalDesc = &ObjectsOfConcern[ENEMY_WEAPON_INDEX];
				/* in blazer form */
	if (ShipPtr->next.image.farray == StarShipPtr->RaceDescPtr->ship_data.special)
	{
		ObjectsOfConcern[CREW_OBJECT_INDEX].ObjectPtr = 0;
		if (lpEvalDesc->ObjectPtr && lpEvalDesc->MoveState == ENTICE)
		{
			if ((lpEvalDesc->ObjectPtr->state_flags & FINITE_LIFE)
					&& !(lpEvalDesc->ObjectPtr->state_flags & CREW_OBJECT))
				lpEvalDesc->MoveState = AVOID;
			else
				lpEvalDesc->ObjectPtr = 0;
		}

		ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter);
	}
	else
	{
		STARSHIP *pEnemyStarShip = NULL;

		lpEvalDesc = &ObjectsOfConcern[ENEMY_SHIP_INDEX];
		if (lpEvalDesc->ObjectPtr)
		{
			GetElementStarShip (lpEvalDesc->ObjectPtr, &pEnemyStarShip);
			// JMS_GFX
			if (lpEvalDesc->which_turn <= 16
					&& (StarShipPtr->special_counter > 0
					|| StarShipPtr->RaceDescPtr->ship_info.energy_level < MAX_ENERGY / 3
					|| ((WEAPON_RANGE (&pEnemyStarShip->RaceDescPtr->cyborg_control) <= (CLOSE_RANGE_WEAPON << RESOLUTION_FACTOR)
					&& lpEvalDesc->ObjectPtr->crew_level > BLAZER_DAMAGE)
					|| (lpEvalDesc->ObjectPtr->crew_level > (BLAZER_DAMAGE * 3)
					&& MANEUVERABILITY (&pEnemyStarShip->RaceDescPtr->cyborg_control) > SLOW_SHIP))))
				lpEvalDesc->MoveState = ENTICE;
		}

		ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter);

		if (StarShipPtr->special_counter == 0)
		{
			StarShipPtr->ship_input_state &= ~SPECIAL;
			// JMS_GFX
			if ((ObjectsOfConcern[ENEMY_WEAPON_INDEX].ObjectPtr
					&& ObjectsOfConcern[ENEMY_WEAPON_INDEX].which_turn <= 4)
					|| (lpEvalDesc->ObjectPtr
					&& StarShipPtr->RaceDescPtr->ship_info.energy_level >= MAX_ENERGY / 3
					&& (WEAPON_RANGE (&pEnemyStarShip->RaceDescPtr->cyborg_control) >=
					WEAPON_RANGE (&StarShipPtr->RaceDescPtr->cyborg_control) << 1
					|| (lpEvalDesc->which_turn < 16
					&& (WEAPON_RANGE (&pEnemyStarShip->RaceDescPtr->cyborg_control) > (CLOSE_RANGE_WEAPON << RESOLUTION_FACTOR)
					|| lpEvalDesc->ObjectPtr->crew_level <= BLAZER_DAMAGE)
					&& (lpEvalDesc->ObjectPtr->crew_level <= (BLAZER_DAMAGE * 3)
					|| MANEUVERABILITY (&pEnemyStarShip->RaceDescPtr->cyborg_control) <=
					SLOW_SHIP)))))
				StarShipPtr->ship_input_state |= SPECIAL;
		}

		if (!(StarShipPtr->ship_input_state & SPECIAL)
				&& StarShipPtr->weapon_counter == 0
				&& lpEvalDesc->ObjectPtr)
		{
			if (lpEvalDesc->which_turn <= 4)
				StarShipPtr->ship_input_state |= WEAPON;
			else if (lpEvalDesc->MoveState != PURSUE
					&& lpEvalDesc->which_turn <= 12)
			{
				COUNT travel_facing, direction_facing;
				SIZE delta_x, delta_y,
							ship_delta_x, ship_delta_y,
							other_delta_x, other_delta_y;

				GetCurrentVelocityComponents (&ShipPtr->velocity,
						&ship_delta_x, &ship_delta_y);
				GetCurrentVelocityComponents (&lpEvalDesc->ObjectPtr->velocity,
						&other_delta_x, &other_delta_y);
				delta_x = ship_delta_x - other_delta_x;
				delta_y = ship_delta_y - other_delta_y;
				travel_facing = ARCTAN (delta_x, delta_y);

				delta_x =
						lpEvalDesc->ObjectPtr->next.location.x -
						ShipPtr->next.location.x;
				delta_y =
						lpEvalDesc->ObjectPtr->next.location.y -
						ShipPtr->next.location.y;
				direction_facing = ARCTAN (delta_x, delta_y);

				if (NORMALIZE_ANGLE (travel_facing
						- direction_facing + OCTANT) <= QUADRANT)
					StarShipPtr->ship_input_state |= WEAPON;
			}
		}
	}
}
Пример #12
0
void
GenerateBurvixes (BYTE control)
{
	COUNT i;
	DWORD rand_val;

	switch (control)
	{
		case GENERATE_ENERGY:
		{
			DWORD rand_val, old_rand;

			if (pSolarSysState->pOrbitalDesc == &pSolarSysState->PlanetDesc[0])
			{
				COUNT which_node;

				old_rand = TFB_SeedRandom (
						pSolarSysState->SysInfo.PlanetInfo.ScanSeed[ENERGY_SCAN]
						);

				which_node = i = 0;
				do
				{
					rand_val = TFB_Random ();
					pSolarSysState->SysInfo.PlanetInfo.CurPt.x =
							(LOBYTE (LOWORD (rand_val)) % (MAP_WIDTH - (8 << 1))) + 8;
					pSolarSysState->SysInfo.PlanetInfo.CurPt.y =
							(HIBYTE (LOWORD (rand_val)) % (MAP_HEIGHT - (8 << 1))) + 8;
					pSolarSysState->SysInfo.PlanetInfo.CurType = 1;
					pSolarSysState->SysInfo.PlanetInfo.CurDensity = 0;
					if (which_node >= pSolarSysState->CurNode
							&& !(pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask[ENERGY_SCAN]
							& (1L << i)))
						break;
					++which_node;
				} while (++i < 16);
				pSolarSysState->CurNode = which_node;

				TFB_SeedRandom (old_rand);
				break;
			}
			else if (pSolarSysState->pOrbitalDesc->pPrevDesc == &pSolarSysState->PlanetDesc[0]
					&& pSolarSysState->pOrbitalDesc == &pSolarSysState->MoonDesc[0]
					&& !GET_GAME_STATE (BURVIXESE_BROADCASTERS))
			{
				old_rand = TFB_SeedRandom (
						pSolarSysState->SysInfo.PlanetInfo.ScanSeed[ENERGY_SCAN]
						);

				rand_val = TFB_Random ();
				pSolarSysState->SysInfo.PlanetInfo.CurPt.x =
						(LOBYTE (LOWORD (rand_val)) % (MAP_WIDTH - (8 << 1))) + 8;
				pSolarSysState->SysInfo.PlanetInfo.CurPt.y =
						(HIBYTE (LOWORD (rand_val)) % (MAP_HEIGHT - (8 << 1))) + 8;
				pSolarSysState->SysInfo.PlanetInfo.CurDensity = 0;
				pSolarSysState->SysInfo.PlanetInfo.CurType = 0;
				if (!(pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask[ENERGY_SCAN]
						& (1L << 0))
						&& pSolarSysState->CurNode == (COUNT)~0)
					pSolarSysState->CurNode = 1;
				else
				{
					pSolarSysState->CurNode = 0;
					if (pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask[ENERGY_SCAN]
							& (1L << 0))
					{
						SET_GAME_STATE (BURVIXESE_BROADCASTERS, 1);
						SET_GAME_STATE (BURV_BROADCASTERS_ON_SHIP, 1);
					}
				}

				TFB_SeedRandom (old_rand);
				break;
			}
			pSolarSysState->CurNode = 0;
			break;
		}
		case GENERATE_MOONS:
			GenerateRandomIP (GENERATE_MOONS);
			if (pSolarSysState->pBaseDesc == &pSolarSysState->PlanetDesc[0])
			{
				COUNT angle;

				pSolarSysState->MoonDesc[0].data_index = SELENIC_WORLD;
				pSolarSysState->MoonDesc[0].radius = MIN_MOON_RADIUS
						+ (MAX_MOONS - 1) * MOON_DELTA;
				rand_val = TFB_Random ();
				angle = NORMALIZE_ANGLE (LOWORD (rand_val));
				pSolarSysState->MoonDesc[0].location.x =
						COSINE (angle, pSolarSysState->MoonDesc[0].radius);
				pSolarSysState->MoonDesc[0].location.y =
						SINE (angle, pSolarSysState->MoonDesc[0].radius);
			}
			break;
		case GENERATE_PLANETS:
		{
			COUNT angle;

			GenerateRandomIP (GENERATE_PLANETS);

			pSolarSysState->PlanetDesc[0].data_index = REDUX_WORLD;
			pSolarSysState->PlanetDesc[0].NumPlanets = 1;
			pSolarSysState->PlanetDesc[0].radius = EARTH_RADIUS * 39L / 100;
			angle = ARCTAN (
					pSolarSysState->PlanetDesc[0].location.x,
					pSolarSysState->PlanetDesc[0].location.y
					);
			pSolarSysState->PlanetDesc[0].location.x =
					COSINE (angle, pSolarSysState->PlanetDesc[0].radius);
			pSolarSysState->PlanetDesc[0].location.y =
					SINE (angle, pSolarSysState->PlanetDesc[0].radius);
			break;
		}
		case GENERATE_ORBITAL:
		{
			rand_val = DoPlanetaryAnalysis (
					&pSolarSysState->SysInfo, pSolarSysState->pOrbitalDesc
					);

			pSolarSysState->SysInfo.PlanetInfo.ScanSeed[BIOLOGICAL_SCAN] = rand_val;
			i = (COUNT)~0;
			rand_val = GenerateLifeForms (&pSolarSysState->SysInfo, &i);

			pSolarSysState->SysInfo.PlanetInfo.ScanSeed[MINERAL_SCAN] = rand_val;
			i = (COUNT)~0;
			GenerateMineralDeposits (&pSolarSysState->SysInfo, &i);

			pSolarSysState->SysInfo.PlanetInfo.ScanSeed[ENERGY_SCAN] = rand_val;
			if (pSolarSysState->pOrbitalDesc == &pSolarSysState->PlanetDesc[0])
			{
				LoadStdLanderFont (&pSolarSysState->SysInfo.PlanetInfo);
				pSolarSysState->PlanetSideFrame[1] =
						CaptureDrawable (
						LoadGraphic (RUINS_MASK_PMAP_ANIM));
				pSolarSysState->SysInfo.PlanetInfo.DiscoveryString =
						CaptureStringTable (
								LoadStringTable (BURV_RUINS_STRTAB));
				pSolarSysState->SysInfo.PlanetInfo.Weather = 0;
				pSolarSysState->SysInfo.PlanetInfo.Tectonics = 0;
			}
			else if (pSolarSysState->pOrbitalDesc->pPrevDesc == &pSolarSysState->PlanetDesc[0]
					&& pSolarSysState->pOrbitalDesc == &pSolarSysState->MoonDesc[0]
					&& !GET_GAME_STATE (BURVIXESE_BROADCASTERS))
			{
				LoadStdLanderFont (&pSolarSysState->SysInfo.PlanetInfo);
				pSolarSysState->PlanetSideFrame[1] =
						CaptureDrawable (
						LoadGraphic (BURV_BCS_MASK_PMAP_ANIM));
				pSolarSysState->SysInfo.PlanetInfo.DiscoveryString =
						CaptureStringTable (
								LoadStringTable (BURV_BCS_STRTAB));
			}
			LoadPlanet (NULL);
			break;
		}
		default:
			GenerateRandomIP (control);
			break;
	}
}
Пример #13
0
static LibEDA_BaseStruct *GetDrawEntry(WinEDA_DrawFrame * frame, FILE *f, char *Line, int *LineNum)
{
int i = 0, jj, ll, Unit, Convert, size1, size2;
char *p, Buffer[256], BufName[256],
		 PinNum[256],
		 chartmp[256], chartmp1[256],
		ctmp;
wxString MsgLine;
bool Error = FALSE;
LibEDA_BaseStruct *Tail = NULL,
					*New = NULL,
					*Head = NULL;

	while (TRUE)
		{
		if (GetLine(f, Line, LineNum, 1024 ) == NULL)
			{
			DisplayError(frame, wxT("File ended prematurely"));
			return Head;
			}

		if (strncmp(Line, "ENDDRAW", 7) == 0)
			{
			break;
			}

		New = NULL;

		switch (Line[0])
			{
			case 'A': /* Arc */
				{
				int startx, starty, endx, endy;
				LibDrawArc * Arc = new LibDrawArc();
				New = Arc;
				ll = 0;
				int nbarg = sscanf(&Line[2], "%d %d %d %d %d %d %d %d %c %d %d %d %d",
						&Arc->m_Pos.x, &Arc->m_Pos.y, &Arc->m_Rayon,
						&Arc->t1, &Arc->t2, &Unit, &Convert,
						&Arc->m_Width, &ctmp, &startx, &starty, &endx, &endy);
				if ( nbarg < 8 ) Error = TRUE;
				Arc->m_Unit = Unit; Arc->m_Convert = Convert;
				if ( ctmp == 'F') Arc->m_Fill = FILLED_SHAPE;
				if ( ctmp == 'f') Arc->m_Fill = FILLED_WITH_BG_BODYCOLOR;

				NORMALIZE_ANGLE(Arc->t1);
				NORMALIZE_ANGLE(Arc->t2);
				
				if ( nbarg >= 13 ) // Coord reelles des extremites de l'arc lues
				{
					Arc->m_Start.x = startx; Arc->m_Start.y = starty;
					Arc->m_End.x = endx; Arc->m_End.y = endy;
				}
				else
				{
					Arc->m_Start.x = Arc->m_Rayon; Arc->m_Start.y = 0;
					Arc->m_End.x = Arc->m_Rayon; Arc->m_End.y = 0;
					RotatePoint( &Arc->m_Start.x, &Arc->m_Start.y, -Arc->t1);
					Arc->m_Start.x += Arc->m_Pos.x; Arc->m_Start.y +=Arc->m_Pos.y;
					RotatePoint( &Arc->m_End.x, &Arc->m_End.y, -Arc->t2);
					Arc->m_End.x += Arc->m_Pos.x; Arc->m_End.y +=Arc->m_Pos.y;
				}
				}
				break;

			case 'C': /* Circle */
				{
				LibDrawCircle * Circle = new LibDrawCircle();
				New = Circle; ll = 0;
				Error = sscanf(&Line[2], "%d %d %d %d %d %d %c",
						  &Circle->m_Pos.x, &Circle->m_Pos.y, &Circle->m_Rayon,
							&Unit, &Convert,&Circle->m_Width, &ctmp) < 6;
				Circle->m_Unit = Unit;
				Circle->m_Convert = Convert;
				if ( ctmp == 'F') Circle->m_Fill = FILLED_SHAPE;
				if ( ctmp == 'f') Circle->m_Fill = FILLED_WITH_BG_BODYCOLOR;
				}
				break;

			case 'T': /* Text */
				{
				LibDrawText * Text = new LibDrawText();
				New = Text;
				Buffer[0] = 0;
				Error = sscanf(&Line[2], "%d %d %d %d %d %d %d %s",
								  &Text->m_Horiz,
								  &Text->m_Pos.x, &Text->m_Pos.y,
								  &Text->m_Size.x, &Text->m_Type,
							&Unit, &Convert, Buffer) != 8;

				Text->m_Unit = Unit; Text->m_Convert = Convert;
                Text->m_Size.y = Text->m_Size.x;
				if (!Error)
					{	/* Convert '~' to spaces. */
					Text->m_Text = CONV_FROM_UTF8(Buffer);
					Text->m_Text.Replace(wxT("~"), wxT(" "));	// Les espaces sont restitués
					}
				}
				break;

			case 'S': /* Square */
				{
				LibDrawSquare * Square = new LibDrawSquare();
				New = Square; ll = 0;
				Error = sscanf(&Line[2], "%d %d %d %d %d %d %d %s",
							  &Square->m_Start.x, &Square->m_Start.y,
							  &Square->m_End.x, &Square->m_End.y,
							&Unit, &Convert,&Square->m_Width, &ctmp) < 7;
				Square->m_Unit = Unit; Square->m_Convert = Convert;
				if ( ctmp == 'F') Square->m_Fill = FILLED_SHAPE;
				if ( ctmp == 'f') Square->m_Fill = FILLED_WITH_BG_BODYCOLOR;
				}
				break;

			case 'X': /* Pin Description */
				{
				*Buffer = 0;
				LibDrawPin * Pin = new LibDrawPin();
				New = Pin;
				i = sscanf(Line+2, "%s %s %d %d %d %s %d %d %d %d %s %s",
								BufName, PinNum,
								&Pin->m_Pos.x, &Pin->m_Pos.y,
								&ll, chartmp1,
								&size1, &size2,
								&Unit, &Convert, chartmp, Buffer);

				Pin->m_SizeNum = size1;		/* Parametres type short */
				Pin->m_SizeName = size2;
				Pin->m_PinLen = ll;
				Pin->m_Orient = chartmp1[0] & 255;

				Pin->m_Unit = Unit; Pin->m_Convert = Convert;
				strncpy((char*)&Pin->m_PinNum, PinNum, 4);
				Error = (i != 11 && i != 12);

				Pin->m_PinName = CONV_FROM_UTF8(BufName);

				jj = *chartmp & 255;
				switch(jj)
					{
					case 'I':
						Pin->m_PinType = PIN_INPUT; break;
					case 'O':
						Pin->m_PinType = PIN_OUTPUT; break;
					case 'B':
						Pin->m_PinType = PIN_BIDI; break;
					case 'T':
						Pin->m_PinType = PIN_TRISTATE; break;
					case 'P':
						Pin->m_PinType = PIN_PASSIVE; break;
					case 'U':
						Pin->m_PinType = PIN_UNSPECIFIED; break;
					case 'W':
						Pin->m_PinType = PIN_POWER_IN; break;
					case 'w':
						Pin->m_PinType = PIN_POWER_OUT; break;
					case 'C':
						Pin->m_PinType = PIN_OPENCOLLECTOR; break;
					case 'E':
						Pin->m_PinType = PIN_OPENEMITTER; break;
					default:
						MsgLine.Printf( wxT("Unknown Pin Type [%c] line %d"),
										jj, *LineNum);
						 DisplayError(frame, MsgLine);
					}
				if( i == 12 )	/* Special Symbole defined */
				for( jj = strlen(Buffer); jj > 0 ; )
					{
					switch(Buffer[--jj])
						{
						case '~': break;
						case 'N': Pin->m_Attributs |= PINNOTDRAW; break;
						case 'I': Pin->m_PinShape |= INVERT; break;
						case 'C': Pin->m_PinShape |= CLOCK; break;
						case 'L': Pin->m_PinShape |= LOWLEVEL_IN; break;
						case 'V': Pin->m_PinShape |= LOWLEVEL_OUT; break;
						default:
							MsgLine.Printf( wxT("Unknown Pin Shape [%c] line %d"),
												Buffer[jj], *LineNum);
							DisplayError(frame, MsgLine); break;
						}
					}
				}
				break;

			case 'P': /* Polyline */
				{
				LibDrawPolyline * Polyl = new LibDrawPolyline();
				New = Polyl;

				if (sscanf(&Line[2], "%d %d %d %d",
						&Polyl->n, &Unit, &Convert,
						&Polyl->m_Width) == 4 &&
						Polyl->n > 0)
					{
					Polyl->m_Unit = Unit; Polyl->m_Convert = Convert;

					Polyl->PolyList = (int *)
							MyZMalloc(sizeof(int) * Polyl->n * 2);

					p = strtok(&Line[2], " \t\n");
					p = strtok(NULL, " \t\n");
					p = strtok(NULL, " \t\n");
					p = strtok(NULL, " \t\n");

					for (i = 0; i < Polyl->n * 2 && !Error; i++)
						{
						p = strtok(NULL, " \t\n");
						Error = sscanf(p, "%d", &Polyl->PolyList[i]) != 1;
						}
					Polyl->m_Fill = NO_FILL;
					if ( (p = strtok(NULL, " \t\n")) != NULL )
						{
						if ( p[0] == 'F') Polyl->m_Fill = FILLED_SHAPE;
						if ( p[0] == 'f')
							Polyl->m_Fill = FILLED_WITH_BG_BODYCOLOR;
						}
					}

				else  Error = TRUE;
				}
				break;

			default:
				MsgLine.Printf( wxT("Undefined DRAW command in line %d, aborted."),
								*LineNum);
				DisplayError(frame, MsgLine);
				return Head;
			}

		if (Error)
			{
			MsgLine.Printf( wxT("Error in %c DRAW command in line %d, aborted."),
							Line[0], *LineNum);
			DisplayError(frame, MsgLine);
			delete New;
			/* FLush till end of draw: */
			do  {
				if (GetLine(f, Line, LineNum, 1024  ) == NULL)
					{
					DisplayError(frame, wxT("File ended prematurely") );
					return Head;
					}
				}  while (strncmp(Line, "ENDDRAW", 7) != 0);
			return (Head);
			}

		else
			{
			if (Head == NULL) Head = Tail = New;
			else
				{
				Tail->Pnext = New; Tail = New;
				}
			}
		}

	return Head;
}
Пример #14
0
static void
supox_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern,
		COUNT ConcernCounter)
{
	STARSHIP *StarShipPtr;
	EVALUATE_DESC *lpEvalDesc;

	GetElementStarShip (ShipPtr, &StarShipPtr);

	lpEvalDesc = &ObjectsOfConcern[ENEMY_SHIP_INDEX];
	if (StarShipPtr->special_counter || lpEvalDesc->ObjectPtr == 0)
		StarShipPtr->ship_input_state &= ~SPECIAL;
	else
	{
		BOOLEAN LinedUp;
		COUNT direction_angle;
		SIZE delta_x, delta_y;

		delta_x = lpEvalDesc->ObjectPtr->next.location.x
				- ShipPtr->next.location.x;
		delta_y = lpEvalDesc->ObjectPtr->next.location.y
				- ShipPtr->next.location.y;
		direction_angle = ARCTAN (delta_x, delta_y);

		LinedUp = (BOOLEAN)(NORMALIZE_ANGLE (NORMALIZE_ANGLE (direction_angle
				- FACING_TO_ANGLE (StarShipPtr->ShipFacing))
				+ QUADRANT) <= HALF_CIRCLE);

		if (!LinedUp
				|| lpEvalDesc->which_turn > 20
				|| NORMALIZE_ANGLE (
				lpEvalDesc->facing
				- (FACING_TO_ANGLE (StarShipPtr->ShipFacing)
				+ HALF_CIRCLE) + OCTANT
				) > QUADRANT)
			StarShipPtr->ship_input_state &= ~SPECIAL;
		else if (LinedUp && lpEvalDesc->which_turn <= 12)
			StarShipPtr->ship_input_state |= SPECIAL;

		if (StarShipPtr->ship_input_state & SPECIAL)
			lpEvalDesc->MoveState = PURSUE;
	}

	ship_intelligence (ShipPtr,
			ObjectsOfConcern, ConcernCounter);

	if (StarShipPtr->ship_input_state & SPECIAL)
		StarShipPtr->ship_input_state |= THRUST | WEAPON;

	lpEvalDesc = &ObjectsOfConcern[ENEMY_WEAPON_INDEX];
	if (StarShipPtr->special_counter == 0
			&& lpEvalDesc->ObjectPtr
			&& lpEvalDesc->MoveState == AVOID
			&& ShipPtr->turn_wait == 0)
	{
		StarShipPtr->ship_input_state &= ~THRUST;
		StarShipPtr->ship_input_state |= SPECIAL;
		if (!(StarShipPtr->cur_status_flags & (LEFT | RIGHT)))
			StarShipPtr->ship_input_state |= 1 << ((BYTE)TFB_Random () & 1);
		else
			StarShipPtr->ship_input_state |=
					StarShipPtr->cur_status_flags & (LEFT | RIGHT);
	}
}
Пример #15
0
hpix_pixel_num_t
hpix_angles_to_nest_pixel(const hpix_resolution_t * resolution,
			  double theta,
			  double phi)
{
    assert(resolution != NULL);

    hpix_nside_t nside = resolution->nside;
    double z, z_abs, tt, tp, tmp;
    int    face_num,jp,jm;
    long   ifp, ifm;
    int    ix, iy, ix_low, ix_hi, iy_low, iy_hi, ipf, ntt;
    int    ns_max = 8192;

    z  = cos(theta);
    z_abs = fabs(z);
    NORMALIZE_ANGLE(phi);
    tt = phi / (0.5 * M_PI); /* in [0,4[ */

    if(z_abs <= 2./3.)
    {
	jp = (int) floor(ns_max*(0.5 + tt - z*0.75));
	jm = (int) floor(ns_max*(0.5 + tt + z*0.75));

	ifp = jp / ns_max; /* in {0,4} */
	ifm = jm / ns_max;

	if(ifp == ifm) face_num = (int) fmod(ifp, 4) + 4;
	else if(ifp < ifm) face_num = (int) fmod(ifp, 4);
	else face_num = (int) fmod(ifm, 4) + 8;

	ix = (int) fmod(jm, ns_max);
	iy = ns_max - (int) fmod(jp, ns_max) - 1;
    }
    else { /* polar region, z_abs > 2/3 */

	ntt = (int)floor(tt);
	if( ntt>=4 ) ntt = 3;
	tp = tt - ntt;
	tmp = sqrt( 3.*(1. - z_abs) ); /* in ]0,1] */

	jp = (int)floor( ns_max * tp * tmp );

	jm = (int)floor( ns_max * (1. - tp) * tmp );
	jp = (int)(jp < ns_max-1 ? jp : ns_max-1);
	jm = (int)(jm < ns_max-1 ? jm : ns_max-1);

	if( z>=0 ) {
	    face_num = ntt; /* in {0,3} */
	    ix = ns_max - jm - 1;
	    iy = ns_max - jp - 1;
	}
	else {
	    face_num = ntt + 8; /* in {8,11} */
	    ix =  jp;
	    iy =  jm;
	}
    }

    ix_low = (int)fmod(ix, 128);
    ix_hi  = ix / 128;
    iy_low = (int)fmod(iy, 128);
    iy_hi  = iy / 128;

    ipf = (x2pix[ix_hi]  + y2pix[iy_hi]) * (128 * 128)
	+ (x2pix[ix_low] + y2pix[iy_low]);
    ipf = (long) (ipf / pow(ns_max / nside, 2));
    return (hpix_pixel_num_t) (ipf + face_num * nside * nside);
}
Пример #16
0
static void
thraddash_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern, COUNT ConcernCounter)
{

	STARSHIP *StarShipPtr;
	EVALUATE_DESC *lpEvalDesc;
	
	lpEvalDesc = &ObjectsOfConcern[ENEMY_SHIP_INDEX];
	if (lpEvalDesc->ObjectPtr)
	{
#define STATIONARY_SPEED WORLD_TO_VELOCITY (DISPLAY_TO_WORLD (4))
		SIZE dx, dy;

		GetCurrentVelocityComponents (
				&lpEvalDesc->ObjectPtr->velocity, &dx, &dy
				);
		if (lpEvalDesc->which_turn > 8
				|| (long)dx * dx + (long)dy * dy <=
				(long)STATIONARY_SPEED * STATIONARY_SPEED)
			lpEvalDesc->MoveState = PURSUE;
		else
			lpEvalDesc->MoveState = ENTICE;
	}
	ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter);

	GetElementStarShip (ShipPtr, &StarShipPtr);
	if (StarShipPtr->special_counter == 0)
	{
		StarShipPtr->ship_input_state &= ~SPECIAL;
		if (ObjectsOfConcern[ENEMY_WEAPON_INDEX].ObjectPtr
				&& ObjectsOfConcern[ENEMY_WEAPON_INDEX].MoveState == ENTICE)
		{
			if ((StarShipPtr->ship_input_state & THRUST)
					|| (ShipPtr->turn_wait == 0
					&& !(StarShipPtr->ship_input_state & (LEFT | RIGHT)))
					|| NORMALIZE_FACING (ANGLE_TO_FACING (
					GetVelocityTravelAngle (
					&ObjectsOfConcern[ENEMY_WEAPON_INDEX].ObjectPtr->velocity
					) + HALF_CIRCLE + OCTANT)
					- StarShipPtr->ShipFacing) > ANGLE_TO_FACING (QUADRANT))
				StarShipPtr->ship_input_state |= SPECIAL;
		}
		else if (lpEvalDesc->ObjectPtr)
		{
			if (lpEvalDesc->MoveState == PURSUE)
			{
				if (StarShipPtr->RaceDescPtr->ship_info.energy_level >= WEAPON_ENERGY_COST
						+ SPECIAL_ENERGY_COST
						&& ShipPtr->turn_wait == 0
						&& !(StarShipPtr->ship_input_state & (LEFT | RIGHT))
						&& (!(StarShipPtr->cur_status_flags & SPECIAL)
						|| !(StarShipPtr->cur_status_flags
						& (SHIP_AT_MAX_SPEED | SHIP_BEYOND_MAX_SPEED))))
					StarShipPtr->ship_input_state |= SPECIAL;
			}
			else if (lpEvalDesc->MoveState == ENTICE)
			{
				COUNT direction_angle;
				SIZE delta_x, delta_y;

				delta_x = lpEvalDesc->ObjectPtr->next.location.x
						- ShipPtr->next.location.x;
				delta_y = lpEvalDesc->ObjectPtr->next.location.y
						- ShipPtr->next.location.y;
				direction_angle = ARCTAN (delta_x, delta_y);

				if ((lpEvalDesc->which_turn > 24
						&& !(StarShipPtr->ship_input_state & (LEFT | RIGHT)))
						|| (lpEvalDesc->which_turn <= 16
						&& NORMALIZE_ANGLE (direction_angle
						- (FACING_TO_ANGLE (StarShipPtr->ShipFacing) + HALF_CIRCLE)
						+ QUADRANT) <= HALF_CIRCLE
						&& (lpEvalDesc->which_turn < 12
						|| NORMALIZE_ANGLE (direction_angle
						- (GetVelocityTravelAngle (
								&lpEvalDesc->ObjectPtr->velocity
								) + HALF_CIRCLE)
						+ (OCTANT + 2)) <= ((OCTANT + 2) << 1))))
					StarShipPtr->ship_input_state |= SPECIAL;
			}
		}

		if ((StarShipPtr->ship_input_state & SPECIAL)
				&& StarShipPtr->RaceDescPtr->ship_info.energy_level >=
				SPECIAL_ENERGY_COST)
			StarShipPtr->ship_input_state &= ~THRUST;
	}
}
Пример #17
0
void
GenerateSOL (BYTE control)
{
	COUNT i;
	DWORD rand_val;
	PPLANET_DESC pCurDesc;

	switch (control)
	{
		case INIT_NPCS:
			init_probe ();
			break;
		case REINIT_NPCS:
			if (GET_GAME_STATE (CHMMR_BOMB_STATE) != 3)
				GenerateRandomIP (REINIT_NPCS);
			else
			{
				GLOBAL (BattleGroupRef) = 0;
				ReinitQueue (&GLOBAL (npc_built_ship_q));
			}
			break;
		case GENERATE_ENERGY:
			generate_energy_nodes ();
			break;
		case GENERATE_LIFE:
			generate_tractors ();
			break;
		case GENERATE_ORBITAL:
			generate_orbital ();
			break;
		case GENERATE_NAME:
			i = pSolarSysState->pBaseDesc - pSolarSysState->PlanetDesc;
			wstrcpy (GLOBAL_SIS (PlanetName), GAME_STRING (PLANET_NUMBER_BASE + i));
			SET_GAME_STATE (BATTLE_PLANET,
					pSolarSysState->PlanetDesc[i].data_index);
			break;
		case GENERATE_MOONS:
		{
			GenerateRandomIP (GENERATE_MOONS);

			i = pSolarSysState->pBaseDesc - pSolarSysState->PlanetDesc;
			switch (i)
			{
				case 2: /* moons of EARTH */
				{
					COUNT angle;

					pSolarSysState->MoonDesc[0].data_index = (BYTE)~0;
					pSolarSysState->MoonDesc[0].radius = MIN_MOON_RADIUS;
					angle = HALF_CIRCLE + QUADRANT;
					pSolarSysState->MoonDesc[0].location.x =
							COSINE (angle, pSolarSysState->MoonDesc[0].radius);
					pSolarSysState->MoonDesc[0].location.y =
							SINE (angle, pSolarSysState->MoonDesc[0].radius);

					pSolarSysState->MoonDesc[1].data_index = SELENIC_WORLD;
					pSolarSysState->MoonDesc[1].radius = MIN_MOON_RADIUS
							+ (MAX_MOONS - 1) * MOON_DELTA;
					rand_val = Random ();
					angle = NORMALIZE_ANGLE (LOWORD (rand_val));
					pSolarSysState->MoonDesc[1].location.x =
							COSINE (angle, pSolarSysState->MoonDesc[1].radius);
					pSolarSysState->MoonDesc[1].location.y =
							SINE (angle, pSolarSysState->MoonDesc[1].radius);
					break;
				}
				case 4: /* moons of JUPITER */
					pSolarSysState->MoonDesc[0].data_index = RADIOACTIVE_WORLD;
					pSolarSysState->MoonDesc[1].data_index = HALIDE_WORLD;
					pSolarSysState->MoonDesc[2].data_index = CYANIC_WORLD;
					pSolarSysState->MoonDesc[3].data_index = PELLUCID_WORLD;
					break;
				case 5: /* moons of SATURN */
					pSolarSysState->MoonDesc[0].data_index = ALKALI_WORLD;
					break;
				case 7: /* moons of NEPTUNE */
					pSolarSysState->MoonDesc[0].data_index = VINYLOGOUS_WORLD;
					break;
			}
			break;
		}
		case GENERATE_PLANETS:
		{
#define SOL_SEED 334241042L
			SeedRandom (SOL_SEED);

			pSolarSysState->SunDesc[0].NumPlanets = 9;
			for (i = 0, pCurDesc = pSolarSysState->PlanetDesc; i < 9; ++i, ++pCurDesc)
			{
				COUNT angle;
				UWORD word_val;

				pCurDesc->rand_seed = rand_val = Random ();
				word_val = LOWORD (rand_val);
				angle = NORMALIZE_ANGLE ((COUNT)HIBYTE (word_val));

				switch (i)
				{
					case 0: /* MERCURY */
						pCurDesc->data_index = METAL_WORLD;
						pCurDesc->radius = EARTH_RADIUS * 39L / 100;
						pCurDesc->NumPlanets = 0;
						break;
					case 1: /* VENUS */
						pCurDesc->data_index = PRIMORDIAL_WORLD;
						pCurDesc->radius = EARTH_RADIUS * 72L / 100;
						pCurDesc->NumPlanets = 0;
						angle = NORMALIZE_ANGLE (FULL_CIRCLE - angle);
						break;
					case 2: /* EARTH */
						pCurDesc->data_index = WATER_WORLD | PLANET_SHIELDED;
						pCurDesc->radius = EARTH_RADIUS;
						pCurDesc->NumPlanets = 2;
						break;
					case 3: /* MARS */
						pCurDesc->data_index = DUST_WORLD;
						pCurDesc->radius = EARTH_RADIUS * 152L / 100;
						pCurDesc->NumPlanets = 0;
						break;
					case 4: /* JUPITER */
						pCurDesc->data_index = RED_GAS_GIANT;
						pCurDesc->radius = EARTH_RADIUS * 500L /* 520L */ / 100;
						pCurDesc->NumPlanets = 4;
						break;
					case 5: /* SATURN */
						pCurDesc->data_index = ORA_GAS_GIANT;
						pCurDesc->radius = EARTH_RADIUS * 750L /* 952L */ / 100;
						pCurDesc->NumPlanets = 1;
						break;
					case 6: /* URANUS */
						pCurDesc->data_index = GRN_GAS_GIANT;
						pCurDesc->radius = EARTH_RADIUS * 1000L /* 1916L */ / 100;
						pCurDesc->NumPlanets = 0;
						break;
					case 7: /* NEPTUNE */
						pCurDesc->data_index = BLU_GAS_GIANT;
						pCurDesc->radius = EARTH_RADIUS * 1250L /* 2999L */ / 100;
						pCurDesc->NumPlanets = 1;
						break;
					case 8: /* PLUTO */
						pCurDesc->data_index = PELLUCID_WORLD;
						pCurDesc->radius = EARTH_RADIUS * 1550L /* 3937L */ / 100;
						pCurDesc->NumPlanets = 0;
						angle = FULL_CIRCLE - OCTANT;
						break;
				}

				pCurDesc->location.x =
						COSINE (angle, pCurDesc->radius);
				pCurDesc->location.y =
						SINE (angle, pCurDesc->radius);
			}
			break;
		}
		default:
			GenerateRandomIP (control);
			break;
	}
}
Пример #18
0
static void update_view_data(
	struct view_data *view)
{
	angle theta;

	// LP change: doing all the FOV changes here:
	View_AdjustFOV(view->field_of_view,view->target_field_of_view);
	
	if (view->effect==NONE)
	{
		view->world_to_screen_x= view->real_world_to_screen_x;
		view->world_to_screen_y= view->real_world_to_screen_y;
	}
	else
	{
		update_render_effect(view);
	}
	
	view->untransformed_left_edge.i= view->world_to_screen_x;
	view->untransformed_right_edge.i= - view->world_to_screen_x;
	
	/* calculate world_to_screen_y*tan(pitch) */
	view->dtanpitch= (view->world_to_screen_y*sine_table[view->pitch])/cosine_table[view->pitch];

	/* calculate left cone vector */
	theta= NORMALIZE_ANGLE(view->yaw-view->half_cone);
	view->left_edge.i= cosine_table[theta], view->left_edge.j= sine_table[theta];
	
	/* calculate right cone vector */
	theta= NORMALIZE_ANGLE(view->yaw+view->half_cone);
	view->right_edge.i= cosine_table[theta], view->right_edge.j= sine_table[theta];
	
	/* calculate top cone vector (negative to clip the right direction) */
	view->top_edge.i= - view->world_to_screen_y;
	view->top_edge.j= - (view->half_screen_height + view->dtanpitch); /* ==k */

	/* calculate bottom cone vector */
	view->bottom_edge.i= view->world_to_screen_y;
	view->bottom_edge.j= - view->half_screen_height + view->dtanpitch; /* ==k */

	/* if weÕre sitting on one of the endpoints in our origin polygon, move us back slightly (±1) into
		that polygon.  when we split rays weÕre assuming that weÕll never pass through a given
		vertex in different directions (because if we do the tree becomes a graph) but when
		we start on a vertex this can happen.  this is a destructive modification of the origin. */
	{
		short i;
		struct polygon_data *polygon= get_polygon_data(view->origin_polygon_index);
		
		for (i= 0;i<polygon->vertex_count;++i)
		{
			struct world_point2d *vertex= &get_endpoint_data(polygon->endpoint_indexes[i])->vertex;
			
			if (vertex->x==view->origin.x && vertex->y==view->origin.y)
			{
				world_point2d *ccw_vertex= &get_endpoint_data(polygon->endpoint_indexes[WRAP_LOW(i, polygon->vertex_count-1)])->vertex;
				world_point2d *cw_vertex= &get_endpoint_data(polygon->endpoint_indexes[WRAP_HIGH(i, polygon->vertex_count-1)])->vertex;
				world_vector2d inset_vector;
				
				inset_vector.i= (ccw_vertex->x-vertex->x) + (cw_vertex->x-vertex->x);
				inset_vector.j= (ccw_vertex->y-vertex->y) + (cw_vertex->y-vertex->y);
				view->origin.x+= SGN(inset_vector.i);
				view->origin.y+= SGN(inset_vector.j);
				
				break;
			}
		}
		
		/* determine whether we are under or over the media boundary of our polygon; we will see all
			other media boundaries from this orientation (above or below) or fail to draw them. */
		if (polygon->media_index==NONE)
		{
			view->under_media_boundary= false;
		}
		else
		{
			struct media_data *media= get_media_data(polygon->media_index);
			
			// LP change: idiot-proofing
			if (media)
			{
				view->under_media_boundary= UNDER_MEDIA(media, view->origin.z);
				view->under_media_index= polygon->media_index;
			} else {
				view->under_media_boundary= false;
			}
		}
	}
}
Пример #19
0
/* assumes ¶t==1 tick */
void move_projectiles(
	void)
{
	struct projectile_data *projectile;
	short projectile_index;
	
	for (projectile_index=0,projectile=projectiles;projectile_index<MAXIMUM_PROJECTILES_PER_MAP;++projectile_index,++projectile)
	{
		if (SLOT_IS_USED(projectile))
		{
			struct object_data *object= get_object_data(projectile->object_index);
			
//			if (!OBJECT_IS_INVISIBLE(object))
			{
				struct projectile_definition *definition= get_projectile_definition(projectile->type);
				short old_polygon_index= object->polygon;
				world_point3d new_location, old_location;
				short obstruction_index, new_polygon_index;
				
				new_location= old_location= object->location;
	
				/* update our objectÕs animation */
				animate_object(projectile->object_index);
				
				/* if weÕre supposed to end when our animation loops, check this condition */
				if ((definition->flags&_stop_when_animation_loops) && (GET_OBJECT_ANIMATION_FLAGS(object)&_obj_last_frame_animated))
				{
					remove_projectile(projectile_index);
				}
				else
				{
					world_distance speed= definition->speed;
					uint32 adjusted_definition_flags = 0;
					uint16 flags;
					
					/* base alien projectile speed on difficulty level */
					if (definition->flags&_alien_projectile)
					{
						switch (dynamic_world->game_information.difficulty_level)
						{
							case _wuss_level: speed-= speed>>3; break;
							case _easy_level: speed-= speed>>4; break;
							case _major_damage_level: speed+= speed>>3; break;
							case _total_carnage_level: speed+= speed>>2; break;
						}
					}
	
					/* if this is a guided projectile with a valid target, update guidance system */				
					if ((definition->flags&_guided) && projectile->target_index!=NONE && (dynamic_world->tick_count&1)) update_guided_projectile(projectile_index);

					if (PROJECTILE_HAS_CROSSED_MEDIA_BOUNDARY(projectile)) adjusted_definition_flags= _penetrates_media;
					
					/* move the projectile and check for collisions; if we didnÕt detonate move the
						projectile and check to see if we need to leave a contrail */
					if ((definition->flags&_affected_by_half_gravity) && (dynamic_world->tick_count&1)) projectile->gravity-= GRAVITATIONAL_ACCELERATION;
					if (definition->flags&_affected_by_gravity) projectile->gravity-= GRAVITATIONAL_ACCELERATION;
					if (definition->flags&_doubly_affected_by_gravity) projectile->gravity-= 2*GRAVITATIONAL_ACCELERATION;
					if (film_profile.m1_low_gravity_projectiles && static_world->environment_flags&_environment_low_gravity && static_world->environment_flags&_environment_m1_weapons)
					{
						projectile->gravity /= 2;
					}
					new_location.z+= projectile->gravity;
					translate_point3d(&new_location, speed, object->facing, projectile->elevation);
					if (definition->flags&_vertical_wander) new_location.z+= (global_random()&1) ? WANDER_MAGNITUDE : -WANDER_MAGNITUDE;
					if (definition->flags&_horizontal_wander) translate_point3d(&new_location, (global_random()&1) ? WANDER_MAGNITUDE : -WANDER_MAGNITUDE, NORMALIZE_ANGLE(object->facing+QUARTER_CIRCLE), 0);
					if (film_profile.infinity_smg)
					{
						definition->flags ^= adjusted_definition_flags;
					}
					flags= translate_projectile(projectile->type, &old_location, object->polygon, &new_location, &new_polygon_index, projectile->owner_index, &obstruction_index, 0, false, projectile_index);
					if (film_profile.infinity_smg)
					{
						definition->flags ^= adjusted_definition_flags;
					}
					
					// LP change: set up for penetrating media boundary
					bool will_go_through = false;
					
					if (flags&_projectile_hit)
					{
						if ((flags&_projectile_hit_floor) && (definition->flags&_rebounds_from_floor) &&
							projectile->gravity<-MINIMUM_REBOUND_VELOCITY)
						{
							play_object_sound(projectile->object_index, definition->rebound_sound);
							projectile->gravity= - projectile->gravity + (projectile->gravity>>2); /* 0.75 */
						}
						else
						{
 							short monster_obstruction_index= (flags&_projectile_hit_monster) ? get_object_data(obstruction_index)->permutation : NONE;
							bool destroy_persistent_projectile= false;
							
							if (flags&_projectile_hit_scenery) damage_scenery(obstruction_index);
							
							/* cause damage, if we can */
							if (!PROJECTILE_HAS_CAUSED_DAMAGE(projectile))
							{
								struct damage_definition *damage= &definition->damage;
								
								damage->scale= projectile->damage_scale;
								if (definition->flags&_becomes_item_on_detonation)
								{
									if (monster_obstruction_index==NONE)
									{
										struct object_location location;
										
										location.p= object->location, location.p.z= 0;
										location.polygon_index= object->polygon;
										location.yaw= location.pitch= 0;
										location.flags= 0;
										// START Benad
										// Found it!
										// With new_item(), current_item_count[item] increases, but not
										// with try_and_add_player_item(). So reverse the effect of new_item in advance.
										dynamic_world->current_item_count[projectile->permutation]--;
										// END Benad
										new_item(&location, projectile->permutation);
										
										destroy_persistent_projectile= true;
									}
									else
									{
										if(MONSTER_IS_PLAYER(get_monster_data(monster_obstruction_index)))
										{
											short player_obstruction_index= monster_index_to_player_index(monster_obstruction_index);
											destroy_persistent_projectile= try_and_add_player_item(player_obstruction_index, projectile->permutation);
										}
									}
								}
								else
								{
									if (definition->area_of_effect)
									{
										damage_monsters_in_radius(monster_obstruction_index, projectile->owner_index, projectile->owner_type, &old_location, object->polygon, definition->area_of_effect, damage, projectile_index);
									}
									else
									{
										if (monster_obstruction_index!=NONE) damage_monster(monster_obstruction_index, projectile->owner_index, projectile->owner_type, &old_location, damage, projectile_index);
									}
								}
							}
              
							if ((definition->flags&_persistent) && !destroy_persistent_projectile)
							{
								SET_PROJECTILE_DAMAGE_STATUS(projectile, true);
							}
							else
							{
								short detonation_effect= definition->detonation_effect;
								
								if (monster_obstruction_index!=NONE)
								{
									if (definition->flags&_bleeding_projectile)
									{
										detonation_effect= get_monster_impact_effect(monster_obstruction_index);
									}
									if (definition->flags&_melee_projectile)
									{
										short new_detonation_effect= get_monster_melee_impact_effect(monster_obstruction_index);
										if (new_detonation_effect!=NONE) detonation_effect= new_detonation_effect;
									}
								}
								if (flags&_projectile_hit_media)
								{
									get_media_detonation_effect(get_polygon_data(obstruction_index)->media_index, definition->media_detonation_effect, &detonation_effect);
									// LP addition: check if projectile will hit media and continue (PMB flag)
									// set will_go_through for later processing
									if (film_profile.a1_smg)
									{
										// Be careful about parentheses here!
										will_go_through = (definition->flags&_penetrates_media_boundary) != 0;
										// Push the projectile upward or downward, if necessary
										if (will_go_through) {
											if (projectile->elevation == 0) {}
											else if (projectile->elevation < HALF_CIRCLE) new_location.z++;
											else if (projectile->elevation > HALF_CIRCLE) new_location.z--;
										}
									}
								}
								if (film_profile.a1_smg)
								{
									// LP addition: don't detonate if going through media
									// if PMB is set; otherwise, detonate if doing so.
									// Some of the later routines may set both "hit landscape" and "hit media",
									// so be careful.
									if (flags&_projectile_hit_landscape && !(flags&_projectile_hit_media)) detonation_effect= NONE;
								}
								else
								{
									if (flags&_projectile_hit_landscape) detonation_effect = NONE;
								}
								
								if (detonation_effect!=NONE) new_effect(&new_location, new_polygon_index, detonation_effect, object->facing);
								L_Call_Projectile_Detonated(projectile->type, projectile->owner_index, new_polygon_index, new_location);
								
								if (!film_profile.infinity_smg || (!(definition->flags&_penetrates_media_boundary) || !(flags&_projectile_hit_media)))
								{
									if ((definition->flags&_persistent_and_virulent) && !destroy_persistent_projectile && monster_obstruction_index!=NONE)
									{
										bool reassign_projectile = true;
										if (film_profile.prevent_dead_projectile_owners)
										{
											monster_data *monster = get_monster_data(monster_obstruction_index);
											reassign_projectile = MONSTER_IS_PLAYER(monster) || !MONSTER_IS_DYING(monster);
										}
										if (reassign_projectile)
											projectile->owner_index= monster_obstruction_index; /* keep going, but donÕt hit this target again */
									}
									// LP addition: don't remove a projectile that will hit media and continue (PMB flag)
									else if (!will_go_through)
									{
										remove_projectile(projectile_index);
									}
								}
								else if (film_profile.infinity_smg)
								{
									SET_PROJECTILE_CROSSED_MEDIA_BOUNDARY_STATUS(projectile, true);
								}
							}
						}
					}
					// Move the projectile if it hit nothing or it will go through media surface
					if (!(flags&_projectile_hit) || will_go_through)
					// else
					{
						/* move to the new_polygon_index */
						translate_map_object(projectile->object_index, &new_location, new_polygon_index);
						
						/* should we leave a contrail at our old location? */
						if ((projectile->ticks_since_last_contrail+=1)>=definition->ticks_between_contrails)
						{
							if (definition->maximum_contrails==NONE || projectile->contrail_count<definition->maximum_contrails)
							{
								projectile->contrail_count+= 1;
								projectile->ticks_since_last_contrail= 0;
								if (definition->contrail_effect!=NONE) new_effect(&old_location, old_polygon_index, definition->contrail_effect, object->facing);
							}
						}
		
						if ((flags&_flyby_of_current_player) && !PROJECTILE_HAS_MADE_A_FLYBY(projectile))
						{
							SET_PROJECTILE_FLYBY_STATUS(projectile, true);
							play_object_sound(projectile->object_index, definition->flyby_sound);
						}
		
						/* if we have a maximum range and we have exceeded it then remove the projectile */
						if (definition->maximum_range!=NONE)
						{
							if ((projectile->distance_travelled+= speed)>=definition->maximum_range)
							{
								remove_projectile(projectile_index);
							}
						}
					}
				}
			}
		}
Пример #20
0
void
FillOrbits (SOLARSYS_STATE *system, BYTE NumPlanets,
		PLANET_DESC *pBaseDesc, BOOLEAN TypesDefined)
{ /* Generate Planets in orbit around star */
	BYTE StarColor, PlanetCount, MaxPlanet;
	BOOLEAN GeneratingMoons;
	COUNT StarSize;
	PLANET_DESC *pPD;
	struct
	{
		COUNT MinRockyDist, MinGasGDist;
	} Suns[] =
	{
		{DWARF_ROCK_DIST, DWARF_GASG_DIST},
		{GIANT_ROCK_DIST, GIANT_GASG_DIST},
		{SUPERGIANT_ROCK_DIST, SUPERGIANT_GASG_DIST},
	};
#ifdef DEBUG_ORBITS
UNICODE buf[256];
char stype[] = {'D', 'G', 'S'};
char scolor[] = {'B', 'G', 'O', 'R', 'W', 'Y'};
#endif /* DEBUG_ORBITS */

	pPD = pBaseDesc;
	StarSize = system->SunDesc[0].data_index;
	StarColor = STAR_COLOR (CurStarDescPtr->Type);

	if (NumPlanets == (BYTE)~0)
	{
#define MAX_GENERATED_PLANETS 9
		// XXX: This is pretty funny. Instead of calling RNG once, like so:
		//     1 + Random % MAX_GENERATED_PLANETS
		//   we spin in a loop until the result > 0.
		//   Note that this behavior must be kept to preserve the universe.
		do
			NumPlanets = LOWORD (RandomContext_Random (SysGenRNG))
					% (MAX_GENERATED_PLANETS + 1);
		while (NumPlanets == 0);
		system->SunDesc[0].NumPlanets = NumPlanets;
	}

#ifdef DEBUG_ORBITS
	GetClusterName (CurStarDescPtr, buf);
	log_add (log_Debug, "cluster name = %s  color = %c type = %c", buf,
			scolor[STAR_COLOR (CurStarDescPtr->Type)],
			stype[STAR_TYPE (CurStarDescPtr->Type)]);
#endif /* DEBUG_ORBITS */
	GeneratingMoons = (BOOLEAN) (pBaseDesc == system->MoonDesc);
	if (GeneratingMoons)
		MaxPlanet = FIRST_LARGE_ROCKY_WORLD;
	else
		MaxPlanet = NUMBER_OF_PLANET_TYPES;
	PlanetCount = NumPlanets;
	while (NumPlanets--)
	{
		BYTE chance;
		DWORD rand_val;
		COUNT min_radius, angle;
		SIZE delta_r;
		PLANET_DESC *pLocPD;

		do
		{
			rand_val = RandomContext_Random (SysGenRNG);
			if (TypesDefined)
				rand_val = 0;
			else
				pPD->data_index =
						(BYTE)(HIBYTE (LOWORD (rand_val)) % MaxPlanet);

			chance = PLANET_NEVER;
			switch (StarColor)
			{
				case BLUE_BODY:
					chance = BlueDistribution (pPD->data_index);
					break;
				case GREEN_BODY:
					chance = GreenDistribution (pPD->data_index);
					break;
				case ORANGE_BODY:
					chance = OrangeDistribution (pPD->data_index);
					break;
				case RED_BODY:
					chance = RedDistribution (pPD->data_index);
					break;
				case WHITE_BODY:
					chance = WhiteDistribution (pPD->data_index);
					break;
				case YELLOW_BODY:
					chance = YellowDistribution (pPD->data_index);
					break;
			}
		} while (LOBYTE (LOWORD (rand_val)) >= chance);

		if (pPD->data_index < FIRST_GAS_GIANT)
			min_radius = Suns[StarSize].MinRockyDist;
		else
			min_radius = Suns[StarSize].MinGasGDist;
RelocatePlanet:
		rand_val = RandomContext_Random (SysGenRNG);
		if (GeneratingMoons)
		{
			pPD->radius = MIN_MOON_RADIUS
					+ ((LOWORD (rand_val) % MAX_MOONS) * MOON_DELTA);
			for (pLocPD = pPD - 1; pLocPD >= pBaseDesc; --pLocPD)
			{
				if (pPD->radius == pLocPD->radius)
					goto RelocatePlanet;
			}
			pPD->NumPlanets = 0;
		}
		else
		{
			pPD->radius =
					(LOWORD (rand_val) % (MAX_PLANET_RADIUS - min_radius))
					+ min_radius;
			for (pLocPD = pPD - 1; pLocPD >= pBaseDesc; --pLocPD)
			{
				delta_r = UNSCALE_RADIUS (pLocPD->radius) / 5
						- UNSCALE_RADIUS (pPD->radius) / 5;
				if (delta_r < 0)
					delta_r = -delta_r;
				if (delta_r <= 1)
					goto RelocatePlanet;
			}
		}

		rand_val = RandomContext_Random (SysGenRNG);
		angle = NORMALIZE_ANGLE (LOWORD (rand_val));
		pPD->location.x = COSINE (angle, pPD->radius);
		pPD->location.y = SINE (angle, pPD->radius);
		pPD->rand_seed = MAKE_DWORD (pPD->location.x, pPD->location.y);

		++pPD;
	}

	{
		BYTE i;

		for (i = 0; i < PlanetCount; ++i)
		{
			BYTE j;

			for (j = (BYTE)(PlanetCount - 1); j > i; --j)
			{
				if (pBaseDesc[i].radius > pBaseDesc[j].radius)
				{
					PLANET_DESC temp;

					temp = pBaseDesc[i];
					pBaseDesc[i] = pBaseDesc[j];
					pBaseDesc[j] = temp;
				}
			}
		}
	}
}
Пример #21
0
// Convert angle from degrees to the Marathon engine's internal units
static int16 GetAngle(float InAngle)
{
	float A = DegreesToInternal*InAngle;
	int16 IA = (A >= 0) ? int16(A + 0.5) : - int16(-A + 0.5);
	return NORMALIZE_ANGLE(IA);
}
Пример #22
0
static void ComputeArc(LibDrawArc * DrawItem, wxPoint ArcCentre)
/***************************************************************/
/* routine d'ajustage des parametres de l'arc en cours de trace
	calcule le centre, rayon, angles pour que l'arc en cours
	passe par les points ArcStartX,Y et ArcEndX,Y avec le centre le plus proche
	de la pos souris
	Remarque: le centre n'est evidemment pas sur la grille
*/
{
int dx, dy;
int cX, cY;			/* Coord centre de l'arc */
int angle;

	cX = ArcCentre.x; cY = ArcCentre.y;

	cY = -cY;	/* Attention a l'orientation de l'axe Y */

	/* calcul de cX et cY pour que l'arc passe par ArcStartX,Y et ArcEndX,Y */
	dx = ArcEndX - ArcStartX; dy = ArcEndY - ArcStartY;
	cX -= ArcStartX; cY -= ArcStartY;
	angle = (int)(atan2(dy, dx) *1800 /M_PI);
	RotatePoint( &dx, &dy, angle);	/* Le segment dx, dy est horizontal */
									/* -> dx = longueur, dy = 0 */
	RotatePoint( &cX, &cY, angle);
	cX = dx / 2;	/* cX, cY est sur la mediane du segment 0,0 a dx,0 */

	RotatePoint( &cX, &cY, -angle);
	cX += ArcStartX; cY += ArcStartY;

	DrawItem->m_Pos.x = cX; DrawItem->m_Pos.y = cY;

	dx = ArcStartX - DrawItem->m_Pos.x;
	dy = ArcStartY - DrawItem->m_Pos.y;

	DrawItem->m_Rayon = (int)sqrt( (dx*dx) + (dy*dy) );

	DrawItem->t1 = (int)(atan2(dy, dx) *1800 /M_PI);

	dx = ArcEndX - DrawItem->m_Pos.x;
	dy = ArcEndY - DrawItem->m_Pos.y;

	DrawItem->t2 = (int)(atan2(dy, dx) *1800 /M_PI);
	
	DrawItem->m_Start.x = ArcStartX;
	DrawItem->m_Start.y = ArcStartY;
	DrawItem->m_End.x = ArcEndX;
	DrawItem->m_End.y = ArcEndY;
	
	NORMALIZE_ANGLE(DrawItem->t1);
	NORMALIZE_ANGLE(DrawItem->t2);	// angles = 0 .. 3600
	
	// limitation val abs a < 1800 (1/2 cercle) pour eviter Pbs d'affichage en miroir
	// car en trace on suppose que l'arc fait moins de 180 deg pour trouver
	// son orientation apres rot, miroir...
	if ( (DrawItem->t2 - DrawItem->t1) > 1800 ) DrawItem->t2 -= 3600;
	else if ( (DrawItem->t2 - DrawItem->t1) <= -1800 ) DrawItem->t2 += 3600;
	
wxString msg;
	angle = DrawItem->t2 - DrawItem->t1;
	msg.Printf(_("Arc %.1f deg"), (float)angle/10 );
	EDA_Appl->LibeditFrame->PrintMsg(msg);
	
	while ( (DrawItem->t2 - DrawItem->t1) >= 1800 )
	{
			DrawItem->t2--;
			DrawItem->t1++;
	}
	while ( (DrawItem->t1 - DrawItem->t2) >= 1800 )
	{
			DrawItem->t2++;
			DrawItem->t1--;
	}

	NORMALIZE_ANGLE(DrawItem->t1);
	NORMALIZE_ANGLE(DrawItem->t2);

}
Пример #23
0
static void
mmrnmhrm_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern,
		COUNT ConcernCounter)
{
	BOOLEAN CanTransform;
	EVALUATE_DESC *lpEvalDesc;
	STARSHIP *StarShipPtr;
	STARSHIP *EnemyStarShipPtr;

	GetElementStarShip (ShipPtr, &StarShipPtr);
	CanTransform = (BOOLEAN)(StarShipPtr->special_counter == 0
			&& StarShipPtr->RaceDescPtr->ship_info.energy_level >=
			StarShipPtr->RaceDescPtr->characteristics.special_energy_cost);

	lpEvalDesc = &ObjectsOfConcern[ENEMY_SHIP_INDEX];
	if (lpEvalDesc->ObjectPtr)
	{
		GetElementStarShip (lpEvalDesc->ObjectPtr, &EnemyStarShipPtr);
	}

	ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter);

	StarShipPtr->ship_input_state &= ~SPECIAL;
	if (CanTransform
			&& lpEvalDesc->ObjectPtr
			&& !(StarShipPtr->ship_input_state & WEAPON))
	{
		SIZE delta_x, delta_y;
		COUNT travel_angle, direction_angle;

		GetCurrentVelocityComponents (&lpEvalDesc->ObjectPtr->velocity,
				&delta_x, &delta_y);
		if (delta_x == 0 && delta_y == 0)
			direction_angle = travel_angle = 0;
		else
		{
			delta_x = lpEvalDesc->ObjectPtr->current.location.x
					- ShipPtr->current.location.x;
			delta_y = lpEvalDesc->ObjectPtr->current.location.y
					- ShipPtr->current.location.y;
			direction_angle = ARCTAN (-delta_x, -delta_y);
			travel_angle = GetVelocityTravelAngle (
					&lpEvalDesc->ObjectPtr->velocity
					);
		}

		if (ShipPtr->next.image.farray == StarShipPtr->RaceDescPtr->ship_data.ship)
		{
			if (lpEvalDesc->which_turn > 8)
			{
				if (MANEUVERABILITY (&EnemyStarShipPtr->RaceDescPtr->cyborg_control) <= SLOW_SHIP
						|| NORMALIZE_ANGLE (
								direction_angle - travel_angle + QUADRANT
								) > HALF_CIRCLE)
					StarShipPtr->ship_input_state |= SPECIAL;
			}
		}
		else
		{
			SIZE ship_delta_x, ship_delta_y;

			GetCurrentVelocityComponents (&ShipPtr->velocity,
					&ship_delta_x, &ship_delta_y);
			delta_x -= ship_delta_x;
			delta_y -= ship_delta_y;
			travel_angle = ARCTAN (delta_x, delta_y);
			if (lpEvalDesc->which_turn < 16)
			{
				if (lpEvalDesc->which_turn <= 8
						|| NORMALIZE_ANGLE (
								direction_angle - travel_angle + OCTANT
								) <= QUADRANT)
					StarShipPtr->ship_input_state |= SPECIAL;
			}
			else if (lpEvalDesc->which_turn > 32
					&& NORMALIZE_ANGLE (
							direction_angle - travel_angle + QUADRANT
							) > HALF_CIRCLE)
				StarShipPtr->ship_input_state |= SPECIAL;
		}
	}

	if (ShipPtr->current.image.farray == StarShipPtr->RaceDescPtr->ship_data.special)
	{
		if (!(StarShipPtr->ship_input_state & SPECIAL)
				&& lpEvalDesc->ObjectPtr)
			StarShipPtr->ship_input_state |= WEAPON;
		else
			StarShipPtr->ship_input_state &= ~WEAPON;
	}
}