bool CameraClass::CameraControl(InputClass* Input, float dtime)
{
	static float walkTime = 0;
	bool walking = false;
	if(Input->IsKeyPressed(DIK_W))
		{
			m_positionX += forward.x ;
			m_positionY += forward.y;
			m_positionZ += forward.z;
			walking = true;
		}
	if(Input->IsKeyPressed(DIK_S))
		{
			m_positionX -= forward.x ;
			m_positionY -= forward.y;
			m_positionZ -= forward.z;
			walking = true;
		}
	if(Input->IsKeyPressed(DIK_D))
		{
			m_positionX -= side.x ;
			m_positionY -= side.y;
			m_positionZ -= side.z;
			walking = true;
		}
	if(Input->IsKeyPressed(DIK_A))
		{
			m_positionX += side.x ;
			m_positionY += side.y;
			m_positionZ += side.z;
			walking = true;
		}

	//Input->XYDifference();
	float deltaX, deltaY;
	Input->GetMouseDelta(deltaX,deltaY);
	//Rotate(deltaX,deltaY,0);
	SetYPR(deltaX,deltaY,0);

	if (walking == true)
	{
		walkTime += dtime;
		if (walkTime>0.75f)
		{
			walkTime = 0;
			playSound = true;
		}
	}
	return true;

}
Beispiel #2
0
void MissileClass::Init1(void)
{
	float cl1, cl2;            /* used to calculate lift curve slope */
	float ubody, vbody, wbody; /* Initial velocities in Body Axes */
	//float cx, cz;
	float cx = 0, cz = 0; // JB 010318
	int i=0, j=0;
	mlTrig trigAlpha, trigBeta;
	float tmpAlpha;

	/*---------------------------------------*/
	/* location of missile in inertial space */
	/*---------------------------------------*/
	SetLaunchData();
	tmpAlpha = alpha;
	alt = -z; 

	/*-------------------------------------*/
	/* initial missile and propellant mass */
	/*-------------------------------------*/
	mass  = weight/GRAVITY;
	if (!F4IsBadReadPtr(inputData, sizeof(MissileInputData))){ // JB 010304 CTD
		m0    = inputData->wm0/GRAVITY;
		mp0   = inputData->wp0/GRAVITY;
	}
	else {
		m0 = 0; mp0 = 0; 
	} // JB 010304 CTD

	mprop = wprop/GRAVITY;

	/*------------------------------*/
	/* lift curve slope calculation */
	/*------------------------------*/
	Atmosphere();
	alpha = 0.0F;
	Trigenometry();

	if (aeroData && !F4IsBadReadPtr(aeroData, sizeof(MissileAeroData))){ // JB 010318 CTD
		cx = Math.TwodInterp (mach, alphat, aeroData->mach, 
											aeroData->alpha, aeroData->cx, 
											aeroData->numMach, aeroData->numAlpha, &i, &j);

		cz = Math.TwodInterp (mach, alphat, aeroData->mach, 
											aeroData->alpha, aeroData->cz, 
											aeroData->numMach, aeroData->numAlpha, &i, &j);
	}

	if (!ifd){
		return; // JB 010803
	}

	cl1 = -cz*ifd->geomData.cosalp + cx*ifd->geomData.sinalp;

	alpha = 1.0F;
	Trigenometry();

	if (aeroData && !F4IsBadReadPtr(aeroData, sizeof(MissileAeroData))) // JB 010318 CTD
	{
		cx = Math.TwodInterp (mach, alphat, aeroData->mach, 
											aeroData->alpha, aeroData->cx, 
											aeroData->numMach, aeroData->numAlpha, &i, &j);

		cz = Math.TwodInterp (mach, alphat, aeroData->mach, 
											aeroData->alpha, aeroData->cz, 
											aeroData->numMach, aeroData->numAlpha, &i, &j);
	}

	cl2 = -cz*ifd->geomData.cosalp + cx*ifd->geomData.sinalp;

	/*-------------*/
	/* derivatives */
	/*-------------*/
	ifd->clalph = cl2 - cl1;
	ifd->cybeta = -ifd->clalph;
	        
	/*----------------------------*/
	/* missile velocity at launch */
	/*----------------------------*/
	alpha = tmpAlpha;
	mlSinCos (&trigAlpha, alpha*DTR);
	mlSinCos (&trigBeta,  beta*DTR);
	ubody = vt*trigAlpha.cos* trigBeta.cos + q*initZLoc -
				r*initYLoc;

	vbody = vt*trigBeta.sin + r*initXLoc - p*initZLoc;

	wbody = vt*trigAlpha.sin*trigBeta.cos + p*initYLoc -
				q*initXLoc;

	vt    = (ubody*ubody  + wbody*wbody);
	alpha = (float)atan2(wbody, ubody)   * RTD;
	beta  = (float)atan2(vbody, sqrt(vt))* RTD;
	vt    = (float)sqrt(vbody*vbody + vt);

	Trigenometry();

	/*-----------------*/
	/* rotation matrix */
	/*-----------------*/
	dmx[0][0] =  ifd->geomData.cospsi*ifd->geomData.costhe;
	dmx[0][1] =  ifd->geomData.sinpsi*ifd->geomData.costhe;
	dmx[0][2] = -ifd->geomData.sinthe;

	dmx[1][0] = -ifd->geomData.sinpsi*ifd->geomData.cosphi + ifd->geomData.cospsi*ifd->geomData.sinthe*ifd->geomData.sinphi;
	dmx[1][1] =  ifd->geomData.cospsi*ifd->geomData.cosphi + ifd->geomData.sinpsi*ifd->geomData.sinthe*ifd->geomData.sinphi;
	dmx[1][2] =  ifd->geomData.costhe*ifd->geomData.sinphi;

	dmx[2][0] =  ifd->geomData.sinpsi*ifd->geomData.sinphi + ifd->geomData.cospsi*ifd->geomData.sinthe*ifd->geomData.cosphi;
	dmx[2][1] = -ifd->geomData.cospsi*ifd->geomData.sinphi + ifd->geomData.sinpsi*ifd->geomData.sinthe*ifd->geomData.cosphi;
	dmx[2][2] =  ifd->geomData.costhe*ifd->geomData.cosphi;

	/*-------------------------*/
	/* missile velocity vector */
	/*-------------------------*/
	xdot =  vt*ifd->geomData.cosgam*ifd->geomData.cossig;
	ydot =  vt*ifd->geomData.cosgam*ifd->geomData.sinsig;
	zdot = -vt*ifd->geomData.singam;

	ifd->oldx[0] = x;
	ifd->oldx[1] = x;
	ifd->oldx[2] = xdot; //0.0; // MLR 1/5/2005 - 
	ifd->oldx[3] = xdot; //0.0; // MLR 1/5/2005 - 

	ifd->oldy[0] = y;
	ifd->oldy[1] = y;
	ifd->oldy[2] = ydot; //0.0; // MLR 1/5/2005 - 
	ifd->oldy[3] = ydot; //0.0; // MLR 1/5/2005 - 

	ifd->oldz[0] = z;
	ifd->oldz[1] = z;
	ifd->oldz[2] = zdot; //0.0; // MLR 1/5/2005 - 
	ifd->oldz[3] = zdot; //0.0; // MLR 1/5/2005 - 

	ifd->burnIndex = 0;
	launchState = PreLaunch;
	runTime = 0.0F;
	guidencephase =0;
	GuidenceTime = 0.0f;
	ifd->oldalp = 0;
	ifd->oldalpdt = 0;
	ifd->oldbet = 0;
	ifd->oldbetdt = 0;
	ifd->lastmach = 0;
	ifd->lastalpha = 0;
	/*-------------------*/
	/* aero coefficients */
	/*-------------------*/
	Aerodynamics();

	/*---------------------------*/
	/* initialize engine impulse */
	/*---------------------------*/
	ifd->oldimp[0] = 0.0;
	ifd->oldimp[1] = 0.0;
	ifd->oldimp[2] = 0.0;
	ifd->oldimp[3] = 0.0;

	/*---------------------------------------------------*/
	/* delta velocity and displacement along launch rail */
	/*---------------------------------------------------*/
	ifd->olddx[0] = 0.0;
	ifd->olddx[1] = 0.0;
	ifd->olddx[2] = 0.0;
	ifd->olddx[3] = 0.0;

	ifd->olddu[0] = 0.0;
	ifd->olddu[1] = 0.0;
	ifd->olddu[2] = 0.0;
	ifd->olddu[3] = 0.0;

	SetDelta(xdot, ydot, zdot);
	SetYPR(psi, theta, phi);
}
void EjectedPilotClass::InitLocalData(AircraftClass *ac, int mode, int no){
	DrawableBSP		*acBSP;
	int				labelLen;

	_delayTime = SimLibElapsedTime + no * 2 * CampaignSeconds;
	// Initialize position, rotation, velocity, angular velocity.
	if (ac)
	{
		_pos = EP_VECTOR(ac->XPos(),ac->YPos(),ac->ZPos());

		_rot[I_ROLL] =	ac->Roll();
		_rot[I_PITCH] = ac->Pitch();
		_rot[I_YAW] = ac->Yaw();
		
		_vel = EP_VECTOR(ac->XDelta(),ac->YDelta(),ac->ZDelta());

		_aVel[I_ROLL] = ac->RollDelta();
		_aVel[I_PITCH] = ac->PitchDelta();
		_aVel[I_YAW] = ac->YawDelta();
	}
	else
	{

		_pos = EP_VECTOR(XPos(),YPos(),ZPos());

		_rot[I_ROLL] =	Roll();
		_rot[I_PITCH] = Pitch();
		_rot[I_YAW] = Yaw();
		
		_vel = EP_VECTOR(XDelta(),YDelta(),ZDelta());

		_aVel[I_ROLL] = RollDelta();
		_aVel[I_PITCH] = PitchDelta();
		_aVel[I_YAW] = YawDelta();
	}

	// Play with this value to change the signature of an
	// ejected pilot on the IR.
	SetPowerOutput(0);
	// sfr: not setters on this anymore
	//SetVt(0);
	//SetKias(0);

	// Initialize physical data.
	_pd = NULL;
	_stage = PD_START;

	// Initialize model data to NULL.
	_md = NULL;
	_model = MD_START;

	// Set the ejection mode.
	SetMode(mode);

	// Initialize run time and delta time.
	_runTime = 0.0;
	_deltaTime = 0.0;

	// We just set the type flag to "FalconSimEntity".
	SetTypeFlag(FalconEntity::FalconSimEntity);

	// Is it ourselves - Find out from the aircraft.
	if (ac && no == 0){
		_isPlayer = (SimDriver.GetPlayerEntity() == ac) ? TRUE : FALSE;
	}
	else {
		_isPlayer = FALSE;
	}

	// Is it a player - Find out from the aircraft.
	if (ac){
		_isDigital = ac->IsDigital() ? TRUE : FALSE;
	}
	else{
		_isDigital = TRUE;
	}

	// Set team/country
	if (ac){
      SetCountry (ac->GetCountry());
	}

	_endStageTimeAdjust = 
	(
		IsDigiPilot() ?
		0.0F :
		_pd->humanPilotEndStageTimeAdjust
	);
	
	// It hasn't hit the ground yet.
	_hitGround = FALSE;

	// The chute isn't collapsed yet.
	_collapseChute = FALSE;
	_chuteCollapsedTime = 1000000.0;

	// No death message yet.
	_deathMsg = NULL;

	// Update shared data.
	SetPosition(_pos[I_X], _pos[I_Y], _pos[I_Z]);
	SetDelta(_vel[I_X], _vel[I_Y], _vel[I_Z]);
	SetYPR(_rot[I_YAW], _rot[I_PITCH], _rot[I_ROLL]);
	SetYPRDelta(_aVel[I_YAW], _aVel[I_PITCH], _aVel[I_ROLL]);

	// Update matrices for geometry.
	CalcTransformMatrix((SimMoverClass *)this);

	// Set up our label.
	if (ac)
	{
		acBSP = (DrawableBSP *)ac->drawPointer;
		if(acBSP != NULL)
		{
			strncpy(_label, acBSP->Label(), 32);
			labelLen = strlen(acBSP->Label());
			if (no == 0){
			    strncat(_label, " Pilot", 32 - labelLen);
			}
			else {
			    char crewstr[20];
			    sprintf (crewstr, " Crew%d", no);
			    strncat(_label, crewstr, 32 - labelLen);
			}
			_label[31] = 0;
			_labelColor = acBSP->LabelColor();
		}
		else
		{
			_label[0] = 0;
			_labelColor = 0;
		}
	}
	else
	{
		strcpy(_label, "Pilot");
		labelLen = strlen(_label);
		_labelColor = 0;//acBSP->LabelColor();
	}
	
	_execCalledFromAircraft = FALSE;
	
	// Point to the aircraft that I ejected from.
	if (ac)
	{
		_aircraftId = ac->Id();
		_flightId = ac->GetCampaignObject()->Id();
	}

	// Update exec transfer synching data.
	_lastFrameCount = 0;
	//	_execCount = 0;

   // Act like a bomb, so nobody sees you
   // edg: yuck, we now have an eject pilot motion
   SetFlag(MOTION_BMB_AI);

   SetFlag(MOTION_EJECT_PILOT);

   if (IsLocal()) {
      SimVuDriver *drive = new SimVuDriver(this);
      drive->ExecDR(SimLibElapsedTime);
      SetDriver (drive);
   }
}
int EjectedPilotClass::Exec()
{
   	ACMIGenPositionRecord genPos;
	ACMISwitchRecord acmiSwitch;

	SoundPos.UpdatePos(this);

	if (IsDead())
		return TRUE;
	
		// Call superclass Exec.
		SimMoverClass::Exec();

      if (!SimDriver.MotionOn())
         return IsLocal();

      if (_delayTime > SimLibElapsedTime) { // not time yet
		RunJettisonCanopy(); // stay with it
		return IsLocal();
      }

		// Advance time
		AdvanceTime();

		// Simulate the ejected pilot here.
		switch(_stage)
		{
			case PD_JETTISON_CANOPY :
			{
				RunJettisonCanopy();
				
				break;
			}
			case PD_EJECT_SEAT :
			{
				RunEjectSeat();

				break;
			}
			case PD_FREE_FALL_WITH_SEAT :
			{
				RunFreeFall();

				break;
			}
			case PD_CHUTE_OPENING :
			{
				RunFreeFall();

				// Here we run our little switch based animation...
				static const int NUM_FRAMES = 31;

				float percent = (_runTime             - StageEndTime(_stage-1)) /
					            (StageEndTime(_stage) - StageEndTime(_stage-1));
				int	frame = FloatToInt32(percent * (NUM_FRAMES-0.5f));

				if ( frame < 0 )
					frame = 0;
				else if ( frame > NUM_FRAMES )
					frame = NUM_FRAMES;

				percent = ((_runTime  - _deltaTime )           - StageEndTime(_stage-1)) /
					       (StageEndTime(_stage) - StageEndTime(_stage-1));

				int	prevframe = FloatToInt32(percent * ((float)NUM_FRAMES-0.5f));
				if ( prevframe < 0 )
					prevframe = 0;
				else if ( prevframe > NUM_FRAMES )
					prevframe = NUM_FRAMES;

				if ( gACMIRec.IsRecording() && prevframe != frame)
				{
						acmiSwitch.hdr.time = SimLibElapsedTime * MSEC_TO_SEC + OTWDriver.todOffset;
						acmiSwitch.data.type = Type();
						acmiSwitch.data.uniqueID = ACMIIDTable->Add(Id(),NULL,0);//.num_;
						acmiSwitch.data.switchNum = 0;
						acmiSwitch.data.prevSwitchVal = 1<<prevframe;
						acmiSwitch.data.switchVal = 1<<frame;
						gACMIRec.SwitchRecord( &acmiSwitch );
				}
					
				if ( drawPointer )
					((DrawableBSP*)drawPointer)->SetSwitchMask( 0, 1<<frame );

				break;
			}
			case PD_FREE_FALL_WITH_OPEN_CHUTE :
			{
				RunFreeFallWithOpenChute();
	
				break;
			}
			case PD_FREE_FALL_WITH_COLLAPSED_CHUTE :
			{
				RunFreeFall();
	
				break;
			}
			case PD_SAFE_LANDING :
			{
				RunSafeLanding();

				_stageTimer += _deltaTime;

				static const int NUM_FRAMES = 13;
				float percent = _stageTimer/2.0f;
				int	frame = FloatToInt32(percent * ((float)NUM_FRAMES-0.5f));

				if ( frame < 0 )
					frame = 0;
				else if ( frame > NUM_FRAMES )
					frame = NUM_FRAMES;

				if ( drawPointer )
					((DrawableBSP*)drawPointer)->SetSwitchMask( 0, 1<<frame );
	
				break;
			}
			case PD_CRASH_LANDING :
			{
				RunCrashLanding();

				_stageTimer += _deltaTime;

				static const int NUM_FRAMES = 12;
				float percent = _stageTimer/2.0f;
				int	frame = FloatToInt32(percent * ((float)NUM_FRAMES-0.5f));

				if ( frame < 0 )
					frame = 0;
				else if ( frame > NUM_FRAMES )
					frame = NUM_FRAMES;

				if ( drawPointer )
					((DrawableBSP*)drawPointer)->SetSwitchMask( 0, 1<<frame );
	
				break;
			}
			default :
			{
				ShiWarning ("Bad Eject Mode");
			}
		}

		// Make sure all components of orientation are in range ( 0 <= n <= TWO_PI).
		FixOrientationRange();

		// Update shared data.
		SetPosition(_pos[I_X], _pos[I_Y], _pos[I_Z]);
		SetDelta(_vel[I_X], _vel[I_Y], _vel[I_Z]);
		SetYPR(_rot[I_YAW], _rot[I_PITCH], _rot[I_ROLL]);
		SetYPRDelta(_aVel[I_YAW], _aVel[I_PITCH], _aVel[I_ROLL]);
		if (gACMIRec.IsRecording() && (SimLibFrameCount & 3 ) == 0)
		{
			genPos.hdr.time = SimLibElapsedTime * MSEC_TO_SEC + OTWDriver.todOffset;
			genPos.data.type = Type();
			genPos.data.uniqueID = ACMIIDTable->Add(Id(),NULL,TeamInfo[GetTeam()]->GetColor());//.num_;
			genPos.data.x = XPos();
			genPos.data.y = YPos();
			genPos.data.z = ZPos();
			genPos.data.roll = Roll();
			genPos.data.pitch = Pitch();
			genPos.data.yaw = Yaw();
// remove			genPos.data.teamColor = TeamInfo[GetTeam()]->GetColor();
			gACMIRec.GenPositionRecord( &genPos );
		}

		// Update matrices for geometry.
		CalcTransformMatrix((SimMoverClass *)this);

		// See if it hit the ground.
		if ( _hitGround == FALSE )
			_hitGround = HasHitGround();

		/*
		** We now do completion in the safe or crash landing stages
		** (by calling HitGround() )
		if (HasHitGround())
		{
			HitGround();
		}
		*/

		// Display some debug data.
#if DEBUG_EJECTION_SEQUENCE
		SpewDebugData();
#endif // DEBUG_EJECTION_SEQUENCE

	return IsLocal();
}
void GroundClass::Init(SimInitDataClass* initData)
{
	SimVehicleClass::Init(initData);

	float nextX, nextY;
	float range, velocity;
	float wp1X, wp1Y, wp1Z;
	float wp2X, wp2Y, wp2Z;
	int i;
	WayPointClass* atWaypoint;
	mlTrig trig;
	VehicleClassDataType* vc;

	vc = GetVehicleClassData(Type() - VU_LAST_ENTITY_TYPE);

    // dustTrail = new DrawableTrail(TRAIL_DUST);
	isFootSquad		= FALSE;
	isEmitter		= FALSE;
	needKeepAlive	= FALSE;

	hasCrew			= (vc->Flags & VEH_HAS_CREW)		? TRUE : FALSE;
	isTowed			= (vc->Flags & VEH_IS_TOWED)		? TRUE : FALSE;
	isShip			= (GetDomain() == DOMAIN_SEA)		? TRUE : FALSE;

	// RV - Biker
	radarDown = false;

	// check for radar emitter
	if ( vc->RadarType != RDR_NO_RADAR ){
		isEmitter = TRUE;
	}

	// 2002-01-20 ADDED BY S.G. At time of creation, 
	// the radar will take the mode of the battalion instead of being 
	// off until it finds a target by itself (and can it find it if its radar is off!).
    // SimVehicleClass::Init created the radar so it's safe to do it here...
	if (isEmitter) {
		if (GetCampaignObject()->GetRadarMode() != FEC_RADAR_OFF) {
			RadarClass *radar = NULL;
			radar = (RadarClass*)FindSensor( this, SensorClass::Radar );
			ShiAssert( radar );
			radar->SetEmitting(TRUE);

			
			// 2002-04-22 MN last fix for FalconSP3 - 
			//this was a good intention to keep a 2D target targetted by a deaggregating unit,
			// however - it doesn't work this way. 
			//The campaign air target derived falconentity does not correlate with the deaggregated aircraft.
			// The SAM's radars would stay stuck at TRACK S1 or 
			//TRACK S3 and won't engage. Symptom was the not changing range to the target (.label 4)
			// Now with this code removed, SAMs should work correctly again. 
			//As we have large SAM bubble sizes - it doesn't really matter if we
			// need to go through all search states in the SIM again - 
			//because SAM's are faster in GUIDE mode than in maximum missile range.
			if (g_bSAM2D3DHandover)
			{
				// 2002-03-21 ADDED BY S.G. In addition, we need to set our radar's target RFN 
				//(right f*cking now) and run a sensor sweep on it so it's valid by the 
				//time TargetProcessing is called.
				FalconEntity	*campTargetEntity = ((UnitClass *)GetCampaignObject())->GetAirTarget();
				if (campTargetEntity)
				{
					SetTarget( new SimObjectType(campTargetEntity) );
					CalcRelAzElRangeAta(this, targetPtr);
					radar->SetDesiredTarget(targetPtr);
					radar->SetFlag(RadarClass::FirstSweep);
					radar->Exec(targetList);
				}				
			}
		}
	}

	SetFlag(ON_GROUND);
	SetPowerOutput(1.0F);	// Assume our motor is running all the time

	SetPosition (initData->x, initData->y, OTWDriver.GetGroundLevel(initData->x, initData->y));
	SetYPR(initData->heading, 0.0F, 0.0F);

	SetupGNDAI (initData);
    
	if (initData->ptIndex){
		// Don't move if we've got an assigned point
		gai->moveState = GNDAI_MOVE_HALTED;
		gai->moveFlags |= GNDAI_MOVE_FIXED_POSITIONS;
	}

	CalcTransformMatrix (this);

	strength        = 100.0F;

	// Check for Campaign mode
	// we don't follow waypoints here
	switch (gai->moveState)
	{
		case GNDAI_MOVE_GENERAL:
		{
			waypoint = curWaypoint = NULL;
			numWaypoints = 0;
			DeleteWPList(initData->waypointList);
			InitFromCampaignUnit();
		}
		break;
		case GNDAI_MOVE_WAYPOINT:
		{
			waypoint        = initData->waypointList;
			numWaypoints    = initData->numWaypoints;
			curWaypoint     = waypoint;
			if (curWaypoint)
			{
				// Corrent initial heading/velocity
				// Find the waypoint to go to.
				atWaypoint = curWaypoint;
				for (i=0; i<initData->currentWaypoint; i++)
				{
					atWaypoint = curWaypoint;
					curWaypoint = curWaypoint->GetNextWP();
				}

				// If current is the on we're at, set for the next one.
				if (curWaypoint == atWaypoint)
					curWaypoint = curWaypoint->GetNextWP();

				atWaypoint->GetLocation (&wp1X, &wp1Y, &wp1Z);

				if (curWaypoint == NULL)
				{
					wp1X = initData->x;
					wp1Y = initData->y;
					curWaypoint = atWaypoint;
					SetDelta (0.0F, 0.0F, 0.0F);
					SetYPRDelta (0.0F, 0.0F, 0.0F);
				}
				else {
					curWaypoint->GetLocation (&wp2X, &wp2Y, &wp2Z);

					SetYPR ((float)atan2 (wp2Y - wp1Y, wp2X - wp1X), 0.0F, 0.0F);

					nextX = wp2X;
					nextY = wp2Y;

					range = (float)sqrt((wp1X - nextX) * (wp1X - nextX) + (wp1Y - nextY) * (wp1Y - nextY));
					velocity = range / ((curWaypoint->GetWPArrivalTime() - SimLibElapsedTime) / SEC_TO_MSEC);

					if ((curWaypoint->GetWPArrivalTime() - SimLibElapsedTime) < 1 * SEC_TO_MSEC)
						velocity = 0.0F;

					// sfr: no need for this anymore
					//SetVt(velocity);
					//SetKias(velocity * FTPSEC_TO_KNOTS);
					mlSinCos (&trig, Yaw());
					SetDelta (velocity * trig.cos, velocity * trig.sin, 0.0F);
					SetYPRDelta (0.0F, 0.0F, 0.0F);
				}
			}
		}
		break;
		default:
		{
			SetDelta (0.0F, 0.0F, 0.0F);
			// sfr: no need for this anymore
			//SetVt(0.0F);
			//SetKias(0.0F);
			SetYPRDelta (0.0F, 0.0F, 0.0F);
			gai->moveState = GNDAI_MOVE_HALTED;
			waypoint = curWaypoint = NULL;
			numWaypoints = 0;
			DeleteWPList(initData->waypointList);
			InitFromCampaignUnit();
		}
		break;
	}

	theInputs   = new PilotInputs;

	// Create our SMS
	Sms = new SMSBaseClass (this, initData->weapon,initData->weapons);

	uchar dam[10] = {100};
	for (i = 0; i < 10; i++){
		dam[i] = 100;
	}
	Sms->SelectBestWeapon (dam, LowAir, -1);
	if (Sms->CurHardpoint() != -1){
		isAirCapable = TRUE;
	}
	else{
		isAirCapable = FALSE;
	}

	Sms->SelectBestWeapon (dam, NoMove, -1);
	if (Sms->CurHardpoint() != -1){
		isGroundCapable = TRUE;
	}
	else {
		isGroundCapable = FALSE;
	}
	Sms->SetCurHardpoint(-1);

	if ((GetType() == TYPE_WHEELED && GetSType() == STYPE_WHEELED_AIR_DEFENSE) ||
		(GetType() == TYPE_WHEELED && GetSType() == STYPE_WHEELED_AAA) ||
		(GetType() == TYPE_TRACKED && GetSType() == STYPE_TRACKED_AIR_DEFENSE) ||
		(GetType() == TYPE_TRACKED && GetSType() == STYPE_TRACKED_AAA) ||
		(GetType() == TYPE_TOWED && GetSType() == STYPE_TOWED_AAA))
	{
		isAirDefense = TRUE;
		// If we're an airdefense thingy, elevate our gun, and point in a random direction
		SetDOF(AIRDEF_ELEV, 60.0f * DTR);
		SetDOF(AIRDEF_ELEV2, 60.0f * DTR);
		SetDOF(AIRDEF_AZIMUTH, 180.0F*DTR - rand()/(float)RAND_MAX * 360.0F*DTR);
	}
	else{
		isAirDefense = FALSE;
	}
}