int FlareClass::Exec(){ if (trail){ // I-Hawk - Removed, flare's trail isn't managed here anymore but from PS //UpdateTrail(); if (SimLibElapsedTime - timeOfDeath > 10 * SEC_TO_MSEC){ SetDead (TRUE); } } BombClass::Exec(); if(IsExploding()) { SetFlag( SHOW_EXPLOSION ); SetDead(TRUE); return TRUE; } // MLR 2003-11-15 flares were going thru the ground { float z; z = OTWDriver.GetGroundLevel(XPos(), YPos()); if(ZPos() > z) { int gtype = OTWDriver.GetGroundType(XPos(),YPos()); switch(gtype) { case COVERAGE_WATER: case COVERAGE_RIVER: case COVERAGE_SWAMP: // flare went into water. SetDead(TRUE); break; default: // give em a slight bounce. SetDelta((SM_SCALAR)(XDelta() * .25), (SM_SCALAR)(YDelta() * .25), (SM_SCALAR)(-ZDelta() * .25)); SetPosition(XPos(),YPos(),z); break; } } } SetDelta (XDelta() * 0.99F, YDelta() * 0.99F, ZDelta() * 0.99F); return TRUE; }
void EjectedPilotClass::ApplyDamage(FalconDamageMessage *damageMsg) { if(_stage >= PD_CHUTE_OPENING) { SimMoverClass::ApplyDamage(damageMsg); if(_collapseChute == FALSE) { // PlayRadioMessage (rcAIRMANDOWNB) // _flightId is the VU_ID of the flight the pilot ejected from Flight flight; flight = (Flight) vuDatabase->Find(_flightId); if(flight) { FalconRadioChatterMessage *radioMessage = new FalconRadioChatterMessage( flight->Id(), FalconLocalSession ); radioMessage->dataBlock.from = flight->Id(); radioMessage->dataBlock.to = MESSAGE_FOR_TEAM; radioMessage->dataBlock.voice_id = flight->GetFlightLeadVoiceID(); radioMessage->dataBlock.message = rcAIRMANDOWNB; //M.N. changed to 32767 -> flexibly use randomized values of max available eval indexes radioMessage->dataBlock.edata[0] = 32767; FalconSendMessage(radioMessage, FALSE); } F4Assert(_deathMsg == NULL); // Create death message. _deathMsg = new FalconDeathMessage (Id(), FalconLocalGame); // ahhhhhhhhhhhhhhhhh #ifdef MLR_NEWSNDCODE SoundPos.Sfx( SFX_SCREAM, 0, 1, 0); #else F4SoundFXSetPos( SFX_SCREAM, TRUE, XPos(), YPos(), ZPos(), 1.0f , 0 , XDelta(),YDelta(),ZDelta()); #endif _deathMsg->dataBlock.damageType = damageMsg->dataBlock.damageType; _deathMsg->dataBlock.dEntityID = Id(); _deathMsg->dataBlock.dCampID = 0; _deathMsg->dataBlock.dSide = GetCountry(); _deathMsg->dataBlock.dPilotID = pilotSlot; _deathMsg->dataBlock.dIndex = Type(); _deathMsg->dataBlock.fEntityID = damageMsg->dataBlock.fEntityID; _deathMsg->dataBlock.fCampID = damageMsg->dataBlock.fCampID; _deathMsg->dataBlock.fSide = damageMsg->dataBlock.fSide; _deathMsg->dataBlock.fPilotID = damageMsg->dataBlock.fPilotID; _deathMsg->dataBlock.fIndex = damageMsg->dataBlock.fIndex; _deathMsg->dataBlock.fWeaponID = damageMsg->dataBlock.fWeaponID; _deathMsg->dataBlock.fWeaponUID = damageMsg->dataBlock.fWeaponUID; } _collapseChute = TRUE; } }
void FlareClass::ExtraGraphics() { #if 0 Falcon4EntityClassType* classPtr; OTWDriver.RemoveObject(drawPointer, TRUE); drawPointer = NULL; classPtr = &Falcon4ClassTable[displayIndex]; OTWDriver.CreateVisualObject (this, classPtr->visType[0], OTWDriver.Scale()); BombClass::ExtraGraphics(); OTWDriver.RemoveObject(drawPointer, TRUE); drawPointer = NULL; classPtr = &Falcon4ClassTable[displayIndex]; OTWDriver.CreateVisualObject(this, classPtr->visType[0], OTWDriver.Scale()); #else BombClass::ExtraGraphics(); if (drawPointer){ OTWDriver.RemoveObject(drawPointer, TRUE); drawPointer = NULL; } Falcon4EntityClassType* classPtr = &Falcon4ClassTable[displayIndex]; OTWDriver.CreateVisualObject(this, classPtr->visType[0], OTWDriver.Scale()); #endif Tpoint newPoint = { XPos(), YPos(), ZPos() }; Tpoint vec = { XDelta(), YDelta(), ZDelta() }; //I-Hawk - Added vector to support new PS flare movement //RV - I-Hawk - PS flare effect call, to replace the old Flare effect /* OTWDriver.AddSfxRequest(new SfxClass( SFX_LIGHT_DEBRIS, // type SFX_MOVES, &newPoint, // world pos &vec, 1.0f, // time to live 1.0f) ); // scale */ DrawableParticleSys::PS_AddParticleEx( (SFX_FLARE_GFX + 1), &newPoint, &vec ); // I-Hawk - Removed, Not used anymore /* if(!g_bDisableMissleEngGlow) // MLR 2003-11-15 disable that shit-o star effect { OTWDriver.InsertObject(trailGlow); OTWDriver.InsertObject(trailSphere); }*/ // I-Hawk - Removed, old flare graphics stuff //OTWDriver.RemoveObject(drawPointer, TRUE); //drawPointer = new Drawable2D( DRAW2D_FLARE, 2.0f, &newPoint ); //OTWDriver.InsertObject(drawPointer); timeOfDeath = SimLibElapsedTime; }
/*---------------------------------------------------------------------------*/ void ConvertSegmentToPicoFeat(FPOINT *Start, FPOINT *End, FEATURE_SET FeatureSet) { /* ** Parameters: ** Start starting point of pico-feature ** End ending point of pico-feature ** FeatureSet set to add pico-feature to ** Globals: ** classify_pico_feature_length length of a single pico-feature ** Operation: This routine converts an entire segment of an outline ** into a set of pico features which are added to ** FeatureSet. The length of the segment is rounded to the ** nearest whole number of pico-features. The pico-features ** are spaced evenly over the entire segment. ** Return: none (results are placed in FeatureSet) ** Exceptions: none ** History: Tue Apr 30 15:44:34 1991, DSJ, Created. */ FEATURE Feature; FLOAT32 Angle; FLOAT32 Length; int NumFeatures; FPOINT Center; FPOINT Delta; int i; Angle = NormalizedAngleFrom (Start, End, 1.0); Length = DistanceBetween (*Start, *End); NumFeatures = (int) floor (Length / classify_pico_feature_length + 0.5); if (NumFeatures < 1) NumFeatures = 1; /* compute vector for one pico feature */ Delta.x = XDelta (*Start, *End) / NumFeatures; Delta.y = YDelta (*Start, *End) / NumFeatures; /* compute position of first pico feature */ Center.x = Start->x + Delta.x / 2.0; Center.y = Start->y + Delta.y / 2.0; /* compute each pico feature in segment and add to feature set */ for (i = 0; i < NumFeatures; i++) { Feature = NewFeature (&PicoFeatDesc); Feature->Params[PicoFeatDir] = Angle; Feature->Params[PicoFeatX] = Center.x; Feature->Params[PicoFeatY] = Center.y; AddFeature(FeatureSet, Feature); Center.x += Delta.x; Center.y += Delta.y; } } /* ConvertSegmentToPicoFeat */
int DebrisClass::Exec (void) { BombClass::Exec(); if(IsExploding()) { SetFlag( SHOW_EXPLOSION ); SetDead(TRUE); return TRUE; } SetDelta (XDelta() * 0.99F, YDelta() * 0.99F, ZDelta() * 0.99F); return TRUE; }
void EjectedPilotClass::InitChuteOpening() { // Set the new BSP. SetModel(MD_PILOT_AND_OPEN_CHUTE); // Set the orientation to upright _rot[I_ROLL] = 0.0; _rot[I_PITCH] = 0.0; _rot[I_YAW] = _vel.Heading(); // Set angular velocity to 0. _aVel[I_ROLL] = 0.0; _aVel[I_PITCH] = 0.0; _aVel[I_YAW] = 0.0; // play the sound #ifdef MLR_NEWSNDCODE SoundPos.Sfx( SFX_CHUTE, 0, 1.0f , 0 ); #else F4SoundFXSetPos( SFX_CHUTE, TRUE, XPos(), YPos(), ZPos(), 1.0f , 0 , XDelta(),YDelta(),ZDelta()); #endif _stageTimer = 0.0f; }
void AircraftClass::DropFlare (void) { vector pos, posDelta; int type; BombClass *weapon; if (counterMeasureStation[FLARE_STATION].weaponCount > 0) { if (this == FalconLocalSession->GetPlayerEntity()) g_intellivibeData.FlareDropped++; { static int chaffsid=0; // just need a fake id so multiple chaffs can play at once. chaffsid = (chaffsid + 1) & 0xf; SoundPos.Sfx( af->auxaeroData->sndBBFlare, chaffsid); } /* pos.x = XPos(); pos.y = YPos(); pos.z = ZPos(); posDelta.x = XDelta() * 0.75F; posDelta.y = YDelta() * 0.75F; posDelta.z = ZDelta() * 0.75F; */ // MLR 2003-11-16 New positional dispensers int NumToLaunch = 1; if(af->auxaeroData->Flare.Sequence==2) { NumToLaunch=af->auxaeroData->Flare.Count; } int i; for(i=0;i<NumToLaunch && counterMeasureStation[FLARE_STATION].weaponCount > 0;i++) { counterMeasureStation[FLARE_STATION].weaponCount--; Tpoint work; MatrixMult( &((DrawableBSP*)af->platform->drawPointer)->orientation, &af->auxaeroData->Flare.Pos[flareDispenser], &work ); pos.x=work.x + XPos(); pos.y=work.y + YPos(); pos.z=work.z + ZPos(); MatrixMult( &((DrawableBSP*)af->platform->drawPointer)->orientation, &af->auxaeroData->Flare.Vec[flareDispenser], &work ); posDelta.x=work.x + XDelta(); posDelta.y=work.y + YDelta(); posDelta.z=work.z + ZDelta(); switch(af->auxaeroData->Flare.Sequence) { case 0: // alternate dispensers; case 2: flareDispenser++; if(flareDispenser>=af->auxaeroData->Flare.Count) flareDispenser=0; break; case 1: // use 1 dispenser, then move to the next default: flareUsed++; if(flareUsed>=af->auxaeroData->Flare.Decoys[flareDispenser]) { flareUsed=0; flareDispenser++; if(flareDispenser>=af->auxaeroData->Flare.Count) flareDispenser=0; } break; } //type = GetClassID (DOMAIN_AIR, CLASS_VEHICLE, TYPE_BOMB, STYPE_BOMB_IRON, SPTYPE_MK82, VU_ANY, VU_ANY, VU_ANY) + VU_LAST_ENTITY_TYPE; // JB 010220 type = GetClassID (DOMAIN_AIR, CLASS_VEHICLE, TYPE_BOMB, STYPE_FLARE1, SPTYPE_CHAFF1 + 1, VU_ANY, VU_ANY, VU_ANY) + VU_LAST_ENTITY_TYPE; // JB 010220 weapon = new FlareClass (type); weapon->Init(); weapon->SetParent(this); weapon->Start(&pos, &posDelta, 0.2f); vuDatabase->/*Quick*/Insert(weapon); weapon->Wake(); } SetFlareExpireTime( SimLibElapsedTime + FlareTime ); SetNewestFlareID( weapon->Id() ); } //MI for EWS stuff if(g_bRealisticAvionics && this == FalconLocalSession->GetPlayerEntity()) { if(counterMeasureStation[FLARE_STATION].weaponCount == 0) { //F4SoundFXSetDist(af->auxaeroData->sndBBChaffFlareOut, TRUE, 0.0f, 1.0f); SoundPos.Sfx(af->auxaeroData->sndBBChaffFlareOut); //make sure we don't get here again, no sounds from now on counterMeasureStation[FLARE_STATION].weaponCount--; } else if(OTWDriver.pCockpitManager->mpIcp->FlareBingo == counterMeasureStation[FLARE_STATION].weaponCount) { if(OTWDriver.pCockpitManager->mpIcp->EWS_BINGO_ON) SoundPos.Sfx(af->auxaeroData->sndBBChaffFlareLow); //F4SoundFXSetDist( af->auxaeroData->sndBBChaffFlareLow, TRUE, 0.0f, 1.0f ); } //MI moved further down /*else if(counterMeasureStation[FLARE_STATION].weaponCount > 0) F4SoundFXSetDist(SFX_BB_CHAFLARE, FALSE, 0.0f, 1.0f);*/ } // If this is the player and they want unlimited chaff, let 'em have it if (IsSetFlag(MOTION_OWNSHIP) && PlayerOptions.UnlimitedChaff()) counterMeasureStation[FLARE_STATION].weaponCount++; }
void AircraftClass::DropChaff (void) { vector pos, posDelta; int type; BombClass *weapon; if (counterMeasureStation[CHAFF_STATION].weaponCount > 0) { if (this == FalconLocalSession->GetPlayerEntity()) g_intellivibeData.ChaffDropped++; /* pos.x = XPos(); pos.y = YPos(); pos.z = ZPos(); posDelta.x = XDelta() * 0.75F; posDelta.y = YDelta() * 0.75F; posDelta.z = ZDelta() * 0.75F; */ // new positional Dispensers int NumToLaunch = 1; if(af->auxaeroData->Chaff.Sequence==2) { NumToLaunch=af->auxaeroData->Chaff.Count; } int i; for(i=0;i<NumToLaunch && counterMeasureStation[CHAFF_STATION].weaponCount > 0;i++) { counterMeasureStation[CHAFF_STATION].weaponCount--; Tpoint work; MatrixMult( &((DrawableBSP*)af->platform->drawPointer)->orientation, &af->auxaeroData->Chaff.Pos[chaffDispenser], &work ); pos.x=work.x + XPos(); pos.y=work.y + YPos(); pos.z=work.z + ZPos(); MatrixMult( &((DrawableBSP*)af->platform->drawPointer)->orientation, &af->auxaeroData->Chaff.Vec[chaffDispenser], &work ); posDelta.x=work.x + XDelta(); posDelta.y=work.y + YDelta(); posDelta.z=work.z + ZDelta(); switch(af->auxaeroData->Chaff.Sequence) { case 0: // alternate dispensers; case 2: chaffDispenser++; if(chaffDispenser>=af->auxaeroData->Chaff.Count) chaffDispenser=0; break; case 1: // use 1 dispenser, then move to the next default: chaffUsed++; if(chaffUsed>=af->auxaeroData->Chaff.Decoys[chaffDispenser]) { chaffUsed=0; chaffDispenser++; if(chaffDispenser>=af->auxaeroData->Chaff.Count) chaffDispenser=0; } break; } // TODO: Use a different (much higher drag) type for the chaff //type = GetClassID (DOMAIN_AIR, CLASS_SFX, TYPE_CHAFF, STYPE_CHAFF, SPTYPE_CHAFF1, VU_ANY, VU_ANY, VU_ANY) + VU_LAST_ENTITY_TYPE; // JB 010220 type = GetClassID (DOMAIN_AIR, CLASS_VEHICLE, TYPE_BOMB, STYPE_CHAFF, SPTYPE_CHAFF1, VU_ANY, VU_ANY, VU_ANY) + VU_LAST_ENTITY_TYPE; // JB 010220 weapon = new ChaffClass(type); weapon->Init(); weapon->SetParent(this); weapon->Start(&pos, &posDelta, 0.2f); vuDatabase->/*Quick*/Insert(weapon); weapon->Wake(); } SetChaffExpireTime( SimLibElapsedTime + ChaffTime ); SetNewestChaffID( weapon->Id() ); } //MI for EWS stuff if(g_bRealisticAvionics && this == FalconLocalSession->GetPlayerEntity()) { if(counterMeasureStation[CHAFF_STATION].weaponCount == 0) { SoundPos.Sfx(af->auxaeroData->sndBBChaffFlareOut); //make sure we don't get here again, no sounds from now on counterMeasureStation[CHAFF_STATION].weaponCount--; } else if(OTWDriver.pCockpitManager->mpIcp->ChaffBingo == counterMeasureStation[CHAFF_STATION].weaponCount) { if(OTWDriver.pCockpitManager->mpIcp->EWS_BINGO_ON) SoundPos.Sfx(af->auxaeroData->sndBBChaffFlareLow); } //MI Moved further down /*if(counterMeasureStation[CHAFF_STATION].weaponCount > 0) F4SoundFXSetDist(SFX_BB_CHAFLARE, FALSE, 0.0f, 1.0f);*/ } // If this is the player and they want unlimited chaff, let 'em have it if (IsSetFlag(MOTION_OWNSHIP) && PlayerOptions.UnlimitedChaff()) counterMeasureStation[CHAFF_STATION].weaponCount++; }
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); } }
void HelicopterClass::RunExplosion (void) { int i; Tpoint pos; Falcon4EntityClassType *classPtr; SimBaseClass *tmpSimBase; Tpoint tp = Origin; Trotation tr = IMatrix; // F4PlaySound (SFX_DEF[SFX_OWNSHIP_BOOM].handle); //F4SoundFXSetPos( SFX_BOOMA1 + PRANDInt5(), TRUE, XPos(), YPos(), ZPos(), 1.0f ); SoundPos.Sfx( SFX_BOOMA1 + PRANDInt5() ); // MLR 5/16/2004 - // 1st do primary explosion pos.x = XPos(); pos.y = YPos(); pos.z = ZPos(); if ( OnGround( ) ) { pos.z = OTWDriver.GetGroundLevel( pos.x, pos.y ) - 4.0f; SetDelta( XDelta() * 0.1f, YDelta() * 0.1f, -50.0f ); OTWDriver.AddSfxRequest( new SfxClass (SFX_GROUND_EXPLOSION, // type &pos, // world pos 1.2f, // time to live 100.0f ) ); // scale } else { OTWDriver.AddSfxRequest( new SfxClass (SFX_AIR_HANGING_EXPLOSION, // type &pos, // world pos 2.0f, // time to live 200.0f + 200 * PRANDFloatPos() ) ); // scale } classPtr = (Falcon4EntityClassType*)EntityType(); // Add the parts (appairently hardcoded at 4) // Recoded by KCK on 6/23 to remove damage station BS for (i=0; i<4; i++) { tmpSimBase = new SimBaseClass(Type()); CalcTransformMatrix (tmpSimBase); OTWDriver.CreateVisualObject(tmpSimBase, classPtr->visType[i+2], &tp, &tr, OTWDriver.Scale()); tmpSimBase->SetPosition (pos.x, pos.y, pos.z); if (!i) { tmpSimBase->SetDelta (XDelta(), YDelta(), ZDelta()); } if (!OnGround()) { tmpSimBase->SetDelta ( XDelta() + 50.0f * PRANDFloat(), YDelta() + 50.0f * PRANDFloat(), ZDelta() + 50.0f * PRANDFloat() ); } else { tmpSimBase->SetDelta ( XDelta() + 50.0f * PRANDFloat(), YDelta() + 50.0f * PRANDFloat(), ZDelta() - 50.0f * PRANDFloatPos() ); } tmpSimBase->SetYPR (Yaw(), Pitch(), Roll()); if (!i) { // First peice is more steady and is flaming tmpSimBase->SetYPRDelta ( 0.0F, 0.0F, 10.0F + PRANDFloat() * 30.0F * DTR); OTWDriver.AddSfxRequest( new SfxClass (SFX_FLAMING_PART, // type SFX_MOVES | SFX_USES_GRAVITY | SFX_EXPLODE_WHEN_DONE, tmpSimBase, // sim base * 3.0f + PRANDFloatPos() * 4.0F, // time to live 1.0F ) ); // scale } else { // spin piece a random amount tmpSimBase->SetYPRDelta ( PRANDFloat() * 30.0F * DTR, PRANDFloat() * 30.0F * DTR, PRANDFloat() * 30.0F * DTR); OTWDriver.AddSfxRequest( new SfxClass (SFX_SMOKING_PART, // type SFX_MOVES | SFX_USES_GRAVITY | SFX_BOUNCES | SFX_EXPLODE_WHEN_DONE, tmpSimBase, // sim base * 4.0f * PRANDFloatPos() + (float)((i+1)*(i+1)), // time to live 1.0 ) ); // scale } } }
/* ** GroundClass Exec() function. ** NOTE: returns TRUE if we've processed this frame. FALSE if we're to do ** dead reckoning (in VU) */ int GroundClass::Exec (void) { //RV - I-Hawk - Added a 0 vector for RV new PS calls Tpoint PSvec; PSvec.x = 0; PSvec.y = 0; PSvec.z = 0; Tpoint pos; Tpoint vec; float speedScale; float groundZ; float labelLOD; float drawLOD; RadarClass *radar = NULL; SoundPos.UpdatePos((SimBaseClass *)this); //Cobra pos.x = 0.0f; pos.y = 0.0f; pos.z = 0.0f; // MLR 5/23/2004 - pos.x = XPos(); pos.y = YPos(); pos.z = OTWDriver.GetApproxGroundLevel( pos.x, pos.y ); // pos.z = -10.0f;//Cobra trying to fix the stupid uninit CTD SetPosition(pos.x, pos.y, pos.z); // dead? -- we do nothing if ( IsDead() ){ return FALSE; } // if damaged if ( pctStrength < 0.5f ){ if (sfxTimer > 1.5f - gai->distLOD * 1.3){ // reset the timer sfxTimer = 0.0f; pos.z -= 10.0f; // VP_changes this shoud be checked why have GetGroundLevel been subtracted by 10.0F // Sometimes the trails seem strange vec.x = PRANDFloat() * 20.0f; vec.y = PRANDFloat() * 20.0f; vec.z = PRANDFloat() * 20.0f; /* OTWDriver.AddSfxRequest( new SfxClass( SFX_TRAILSMOKE, // type SFX_MOVES | SFX_NO_GROUND_CHECK, // flags &pos, // world pos &vec, // vector 3.5f, // time to live 4.5f // scale ) ); */ DrawableParticleSys::PS_AddParticleEx((SFX_TRAILSMOKE + 1), &pos, &vec); } } if (IsExploding()){ // KCK: I've never seen this section of code executed. Maybe it gets hit, but I doubt // it. if (!IsSetFlag( SHOW_EXPLOSION )){ // Show the explosion Tpoint pos, vec; Falcon4EntityClassType *classPtr = (Falcon4EntityClassType *)EntityType(); //DrawableGroundVehicle *destroyedPtr; // FRB //Cobra TJL 11/07/04 CTD point initialize here pos.x = 0.0f; pos.y = 0.0f; pos.z = 0.0f; // MLR 5/23/2004 - uncommented out the x, y pos.x = XPos(); pos.y = YPos(); pos.z = OTWDriver.GetApproxGroundLevel( pos.x, pos.y ) - 10.0f; vec.x = 0.0f; vec.y = 0.0f; vec.z = 0.0f; // create a new drawable for destroyed vehicle // sometimes..... //RV - I-Hawk - Commenting all this if statement... not necessary /* if ( rand() & 1 ){ destroyedPtr = new DrawableGroundVehicle( classPtr->visType[3], &pos, Yaw(), 1.0f ); groundZ = PRANDFloatPos() * 60.0f + 15.0f; /* OTWDriver.AddSfxRequest( new SfxClass ( SFX_BURNING_PART, // type &pos, // world pos &vec, // (DrawableBSP *)destroyedPtr, groundZ, // time to live 1.0f // scale ) ); */ /* DrawableParticleSys::PS_AddParticleEx((SFX_BURNING_PART + 1), &pos, &vec); pos.z += 10.0f; /* OTWDriver.AddSfxRequest( new SfxClass( SFX_FEATURE_EXPLOSION, // type &pos, // world pos groundZ, // time to live 100.0f // scale ) ); */ /* DrawableParticleSys::PS_AddParticleEx((SFX_FEATURE_EXPLOSION + 1), &pos, &PSvec); } */ //RV - I-Hawk - seperating explosion type for ground/sea domains. also //adding a check so soldiers will not explode like ground vehicles... if (GetDomain() == DOMAIN_LAND && GetType() != TYPE_FOOT) { //pos.z -= 20.0f; /* OTWDriver.AddSfxRequest( new SfxClass( SFX_VEHICLE_EXPLOSION, // type &pos, // world pos 1.5f, // time to live 100.0f // scale ) ); */ DrawableParticleSys::PS_AddParticleEx((SFX_VEHICLE_EXPLOSION + 1), &pos, &PSvec); } else if ( GetDomain() == DOMAIN_SEA ) { DrawableParticleSys::PS_AddParticleEx((SFX_WATER_FIREBALL + 1), &pos, &PSvec); } // make sure we don't do it again... SetFlag( SHOW_EXPLOSION ); // we can now kill it immediately SetDead(TRUE); } return FALSE; } // exec any base functionality SimVehicleClass::Exec(); // Sept 30, 2002 // VP_changes: Frequently Z value is not in the correct place. It should follow the terrain. if ( drawPointer ){ drawPointer->GetPosition( &pos ); } else { return FALSE; } //JAM 27Sep03 - Let's try this groundZ = pos.z; // - 0.7f; KCK: WTF is this? //VP_changes Sept 25 groundZ = OTWDriver.GetGroundLevel( pos.x, pos.y ); // Movement/Targeting for local entities if (IsLocal() && SimDriver.MotionOn()) { //I commented this out, because it is done in gai->ProcessTargeting down below DSP 4/30/99 // Refresh our target pointer (if any) //SetTarget( SimCampHandoff( targetPtr, targetList, HANDOFF_RANDOM ) ); // Look for someone to do radar fire control for us FindBattalionFireControl(); // RV - Biker - Switch on lights for ground/naval vehicles int isNight = TimeOfDayGeneral(TheCampaign.CurrentTime) < TOD_DAWNDUSK ? true : false; if (drawPointer && ((DrawableBSP *)drawPointer)->GetNumSwitches() >= AIRDEF_LIGHT_SWITCH) { if (isShip) { isNight = (TimeOfDayGeneral(TheCampaign.CurrentTime) <= TOD_DAWNDUSK || realWeather->weatherCondition == INCLEMENT) ? true : false; if (pctStrength > 0.50f) { ((DrawableBSP *)drawPointer)->SetSwitchMask(0, isNight); ((DrawableBSP *)drawPointer)->SetSwitchMask(AIRDEF_LIGHT_SWITCH, isNight); } } else if (GetVt() > 1.0f) { VuListIterator vehicleWalker(SimDriver.combinedList); FalconEntity* object = (FalconEntity*)vehicleWalker.GetFirst(); bool hasThreat = false; float range = 999.9f * NM_TO_FT; // Consider each potential target in our environment while (object && !hasThreat) { // Skip sleeping sim objects if (object->IsSim()) { if (!((SimBaseClass*)object)->IsAwake()) { object = (FalconEntity*)vehicleWalker.GetNext(); continue; } } // Fow now we skip missles -- might want to display them eventually... if (object->IsMissile() || object->IsBomb()) { object = (FalconEntity*)vehicleWalker.GetNext(); continue; } if (object->GetTeam() == GetTeam()) { object = (FalconEntity*)vehicleWalker.GetNext(); continue; } float dx = object->XPos() - XPos(); float dy = object->YPos() - YPos(); float dz = object->ZPos() - ZPos(); range = (float)sqrt(dx*dx + dy*dy + dz*dz); if (range < 5.0f * NM_TO_FT) hasThreat = true; object = (FalconEntity*)vehicleWalker.GetNext(); } // If no enemy nearby and not heavy damaged switch on lights if (!hasThreat && pctStrength > 0.75f) { ((DrawableBSP *)drawPointer)->SetSwitchMask(AIRDEF_LIGHT_SWITCH, isNight); } else { ((DrawableBSP *)drawPointer)->SetSwitchMask(AIRDEF_LIGHT_SWITCH, 0); } } else { ((DrawableBSP *)drawPointer)->SetSwitchMask(AIRDEF_LIGHT_SWITCH, 0); } } // RV - Biker - Do also switch on lights for tractor vehicles if (truckDrawable && truckDrawable->GetNumSwitches() >= AIRDEF_LIGHT_SWITCH) { if (GetVt() > 1.0f) { VuListIterator vehicleWalker(SimDriver.combinedList); FalconEntity* object = (FalconEntity*)vehicleWalker.GetFirst(); bool hasThreat = false; float range = 999.9f * NM_TO_FT; // Consider each potential target in our environment while (object && !hasThreat) { // Skip sleeping sim objects if (object->IsSim()) { if (!((SimBaseClass*)object)->IsAwake()) { object = (FalconEntity*)vehicleWalker.GetNext(); continue; } } // Fow now we skip missles -- might want to display them eventually... if (object->IsMissile() || object->IsBomb()) { object = (FalconEntity*)vehicleWalker.GetNext(); continue; } if (object->GetTeam() == GetTeam()) { object = (FalconEntity*)vehicleWalker.GetNext(); continue; } float dx = object->XPos() - XPos(); float dy = object->YPos() - YPos(); float dz = object->ZPos() - ZPos(); range = (float)sqrt(dx*dx + dy*dy + dz*dz); if (range < 5.0f * NM_TO_FT) hasThreat = true; object = (FalconEntity*)vehicleWalker.GetNext(); } // If no enemy nearby and not heavy damaged switch on lights if (!hasThreat && pctStrength > 0.75f) { truckDrawable->SetSwitchMask(AIRDEF_LIGHT_SWITCH, isNight); } else { truckDrawable->SetSwitchMask(AIRDEF_LIGHT_SWITCH, 0); } } else { truckDrawable->SetSwitchMask(AIRDEF_LIGHT_SWITCH, 0); } } // RV - Biker - Shut down ship radar if damaged if (isShip && radarDown == false && pctStrength < 0.9f && rand()%50 > (pctStrength - 0.50f)*100) { isEmitter = false; RadarClass *radar = (RadarClass*)FindSensor(this, SensorClass::Radar); if (radar) { radarDown = true; radar->SetDesiredTarget(NULL); radar->SetEmitting(FALSE); } if (targetPtr) { SelectWeapon(true); } } // 2001-03-26 ADDED BY S.G. NEED TO KNOW IF THE RADAR CALLED SetSpotted // RV - Biker - Rotate radars float deltaDOF; float curDOF = GetDOFValue(5); deltaDOF = 180.0f * DTR * SimLibMajorFrameTime; curDOF += deltaDOF; if ( curDOF > 360.0f * DTR ) curDOF -= 360.0f * DTR; SetDOF(5, curDOF); int spottedSet = FALSE; // END OF ADDED SECTION // 2002-03-21 ADDED BY S.G. // If localData only has zeros, // there is a good chance they are not valid (should not happen here though)... if (targetPtr) { SimObjectLocalData* localData= targetPtr->localData; if ( localData->ataFrom == 0.0f && localData->az == 0.0f && localData->el == 0.0f && localData->range == 0.0f ) { CalcRelAzElRangeAta(this, targetPtr); } } // END OF ADDED SECTION 2002-03-21 // check for sending radar emmisions // 2002-02-26 MODIFIED BY S.G. // Added the nextTargetUpdate check to prevent the radar code to run on every frame! if ( isEmitter && nextTargetUpdate < SimLibElapsedTime){ // 2002-02-26 ADDED BY S.G. Next radar scan is 1 sec for aces, 2 for vets, etc ... nextTargetUpdate = SimLibElapsedTime + (5 - gai->skillLevel) * SEC_TO_MSEC; radar = (RadarClass*)FindSensor( this, SensorClass::Radar ); ShiAssert( radar ); if (radar){ radar->Exec( targetList ); } // 2001-03-26 ADDED BY S.G. // IF WE CAN SEE THE RADAR'S TARGET AND WE ARE A AIR DEFENSE THINGY // NOT IN A BKOGEN MORAL STATE, MARK IT AS SPOTTED IF WE'RE BRIGHT ENOUGH if ( radar && radar->CurrentTarget() && gai->skillLevel >= 3 && ((UnitClass *)GetCampaignObject())->GetSType() == STYPE_UNIT_AIR_DEFENSE && !((UnitClass *)GetCampaignObject())->Broken() ){ CampBaseClass *campBaseObj; if (radar->CurrentTarget()->BaseData()->IsSim()){ campBaseObj = ((SimBaseClass *)radar->CurrentTarget()->BaseData())->GetCampaignObject(); } else{ campBaseObj = (CampBaseClass *)radar->CurrentTarget()->BaseData(); } // JB 011002 If campBaseObj is NULL the target may be chaff if (campBaseObj && !(campBaseObj->GetSpotted(GetTeam())) && campBaseObj->IsFlight()){ RequestIntercept((FlightClass *)campBaseObj, GetTeam()); } spottedSet = TRUE; if (campBaseObj && radar->GetRadarDatFile()){ campBaseObj->SetSpotted( GetTeam(), TheCampaign.CurrentTime, (radar->radarData->flag & RAD_NCTR) != 0 && radar->CurrentTarget()->localData && radar->CurrentTarget()->localData->ataFrom < 45.0f * DTR && radar->CurrentTarget()->localData->range < radar->GetRadarDatFile()->MaxNctrRange / (2.0f * (16.0f - (float)gai->skillLevel) / 16.0f) ); } // 2002-03-05 MODIFIED BY S.G. target's aspect and skill used in the equation } // END OF ADDED SECTION } // 2001-03-26 ADDED BY S.G. // IF THE BATTALION LEAD HAS LOS // ON IT AND WE ARE A AIR DEFENSE THINGY NOT IN A BKOGEN MORAL STATE, // MARK IT AS SPOTTED IF WE'RE BRIGHT ENOUGH // 2002-02-11 MODIFED BY S.G. // Since I only identify visually, need to perform this even if spotted by radar in case I can ID it. if ( /*!spottedSet && gai->skillLevel >= 3 && */ ((UnitClass *)GetCampaignObject())->GetSType() == STYPE_UNIT_AIR_DEFENSE && gai == gai->battalionCommand && !((UnitClass *)GetCampaignObject())->Broken() && gai->GetAirTargetPtr() && CheckLOS(gai->GetAirTargetPtr()) ){ CampBaseClass *campBaseObj; if (gai->GetAirTargetPtr()->BaseData()->IsSim()) campBaseObj = ((SimBaseClass *)gai->GetAirTargetPtr()->BaseData())->GetCampaignObject(); else campBaseObj = (CampBaseClass *)gai->GetAirTargetPtr()->BaseData(); // JB 011002 If campBaseObj is NULL the target may be chaff if (!spottedSet && campBaseObj && !(campBaseObj->GetSpotted(GetTeam())) && campBaseObj->IsFlight()) RequestIntercept((FlightClass *)campBaseObj, GetTeam()); if (campBaseObj) campBaseObj->SetSpotted(GetTeam(),TheCampaign.CurrentTime, 1); // 2002-02-11 MODIFIED BY S.G. Visual detection means identified as well } // END OF ADDED SECTION // KCK: When should we run a target update cycle? if (SimLibElapsedTime > lastProcess){ gai->ProcessTargeting(); lastProcess = SimLibElapsedTime + processRate; } // KCK: Check if it's ok to think if (SimLibElapsedTime > lastThought ){ // do movement and (possibly) firing.... gai->Process (); lastThought = SimLibElapsedTime + thoughtRate; } // RV - Biker - Only allow SAM fire if radar still does work SimWeaponClass *theWeapon = Sms->GetCurrentWeapon(); // FRB - This version seems to give SAMs a little more activity if(SimLibElapsedTime > nextSamFireTime && !allowSamFire){ allowSamFire = TRUE; } // Biker's version //if(SimLibElapsedTime > nextSamFireTime && !allowSamFire) //{ // if (radarDown == false || (theWeapon && theWeapon->IsMissile() && theWeapon->sensorArray[0]->Type() == SensorClass::IRST)) // allowSamFire = TRUE; //} // Move and update delta; gai->Move_Towards_Dest(); // edg: always insure that our Z position is valid for the entity. // the draw pointer should have this value // KCK NOTE: The Z we have is actually LAST FRAME's Z. Probably not a big deal. SetPosition( XPos() + XDelta() * SimLibMajorFrameTime, YPos() + YDelta() * SimLibMajorFrameTime, groundZ ); // do firing // this also does weapon keep alive if ( Sms ){ gai->Fire(); } } // KCK: I simplified this some. This is now speed squared. speedScale = XDelta()*XDelta() + YDelta()*YDelta(); // set our level of detail if ( gai == gai->battalionCommand ){ gai->SetDistLOD(); } else{ gai->distLOD = gai->battalionCommand->distLOD; } // do some extra LOD stuff: if the unit is not a lead veh amd the // distLOD is less than a certain value, remove it from the draw // list. if (drawPointer && gai->rank != GNDAI_BATTALION_COMMANDER){ // distLOD cutoff by ranking (KCK: This is explicit for testing, could be a formula/table) if (gai->rank & GNDAI_COMPANY_LEADER){ labelLOD = .5F; drawLOD = .25F; } else if (gai->rank & GNDAI_PLATOON_LEADER){ labelLOD = .925F; drawLOD = .5F; } else { labelLOD = 1.1F; drawLOD = .75F; } // RV - Biker - Why do this maybe helpful knowing which vehicle has problems // Determine wether to draw label or not if (gai->distLOD < labelLOD){ if (!IsSetLocalFlag(NOT_LABELED)){ drawPointer->SetLabel ("", 0xff00ff00); // Don't label SetLocalFlag(NOT_LABELED); } } else if (IsSetLocalFlag(NOT_LABELED)){ SetLabel(this); UnSetLocalFlag(NOT_LABELED); } //if (IsSetLocalFlag(NOT_LABELED)) { // SetLabel(this); // UnSetLocalFlag(NOT_LABELED); //} } if (!targetPtr){ //rotate turret to be pointing forward again float maxAz = TURRET_ROTATE_RATE * SimLibMajorFrameTime; float maxEl = TURRET_ELEVATE_RATE * SimLibMajorFrameTime; float newEl; if (isAirDefense){ newEl = 60.0F*DTR; } else { newEl = 0.0F; } float delta = newEl - GetDOFValue(AIRDEF_ELEV); if(delta > 180.0F*DTR){ delta -= 180.0F*DTR; } else if(delta < -180.0F*DTR){ delta += 180.0F*DTR; } // Do elevation adjustments if (delta > maxEl){ SetDOFInc(AIRDEF_ELEV, maxEl); } else if (delta < -maxEl){ SetDOFInc(AIRDEF_ELEV, -maxEl); } else { SetDOF(AIRDEF_ELEV, newEl); } SetDOF(AIRDEF_ELEV, min(85.0F*DTR, max(GetDOFValue(AIRDEF_ELEV), 0.0F))); SetDOF(AIRDEF_ELEV2, GetDOFValue(AIRDEF_ELEV)); delta = 0.0F - GetDOFValue(AIRDEF_AZIMUTH); if(delta > 180.0F*DTR){ delta -= 180.0F*DTR; } else if(delta < -180.0F*DTR){ delta += 180.0F*DTR; } // Now do the azmuth adjustments if (delta > maxAz){ SetDOFInc(AIRDEF_AZIMUTH, maxAz); } else if (delta < -maxAz){ SetDOFInc(AIRDEF_AZIMUTH, -maxAz); } // RV - Biker - Don't do this //else // SetDOF(AIRDEF_AZIMUTH, 0.0F); } // Special shit by ground type if ( isFootSquad ){ if ( speedScale > 0.0f ){ // Couldn't this be done in the drawable class's update function??? ((DrawableGuys*)drawPointer)->SetSquadMoving( TRUE ); } else { // Couldn't this be done in the drawable class's update function??? ((DrawableGuys*)drawPointer)->SetSquadMoving( FALSE ); } // If we're less than 80% of the way from "FAR" toward the viewer, just draw one guy // otherwise, put 5 guys in a squad. if (gai->distLOD < 0.8f) { ((DrawableGuys*)drawPointer)->SetNumInSquad( 1 ); } else { ((DrawableGuys*)drawPointer)->SetNumInSquad( 5 ); } } // We're not a foot squad, so do the vehicle stuff else if ( !IsSetLocalFlag( IS_HIDDEN ) && speedScale > 300.0f ) { // speedScale /= ( 900.0f * KPH_TO_FPS * KPH_TO_FPS); // essentially 1.0F at 30 mph // JPO - for engine noise VehicleClassDataType *vc = GetVehicleClassData(Type() - VU_LAST_ENTITY_TYPE); ShiAssert(FALSE == F4IsBadReadPtr(vc, sizeof *vc)); // (a) Make sound: // everything sounds like a tank right now if ( GetCampaignObject()->IsBattalion() ){ //if (vc) if (vc && vc->EngineSound!=34){ // kludge prevent 34 from playing SoundPos.Sfx( vc->EngineSound, 0, 1.0, 0); // MLR 5/16/2004 - } else{ SoundPos.Sfx( SFX_TANK, 0, 1.0, 0); // MLR 5/16/2004 - } // (b) Make dust // dustTimer += SimLibMajorFrameTime; // if ( dustTimer > max( 0.2f, 4.5f - speedScale - gai->distLOD * 3.3f ) ) if ( ((rand() & 7) == 7) && gSfxCount[ SFX_GROUND_DUSTCLOUD ] < gSfxLODCutoff && gTotSfx < gSfxLODTotCutoff ){ // reset the timer // dustTimer = 0.0f; pos.x += PRANDFloat() * 5.0f; pos.y += PRANDFloat() * 5.0f; pos.z = groundZ; // RV - Biker - Move that smoke more behind the vehicle mlTrig trig; mlSinCos (&trig, Yaw()); pos.x -= 15.0f*trig.cos; pos.y -= 15.0f*trig.sin; vec.x = PRANDFloat() * 5.0f; vec.y = PRANDFloat() * 5.0f; vec.z = -20.0f; //JAM 24Oct03 - No dust trails when it's raining. if(realWeather->weatherCondition < INCLEMENT){ /* OTWDriver.AddSfxRequest( new SfxClass (SFX_VEHICLE_DUST, // type //JAM 03Oct03 // new SfxClass (SFX_GROUND_DUSTCLOUD, // type SFX_USES_GRAVITY | SFX_NO_DOWN_VECTOR | SFX_MOVES | SFX_NO_GROUND_CHECK, &pos, // world pos &vec, 1.0f, // time to live 1.f)); //JAM 03Oct03 8.5f )); // scale */ DrawableParticleSys::PS_AddParticleEx((SFX_VEHICLE_DUST + 1), &pos, &vec); } } // (c) Make sure we're using our 'Moving' model (i.e. Trucked artillery, APC, etc) if (truckDrawable){ // Keep truck 20 feet behind us (HACK HACK) Tpoint truckPos; mlTrig trig; mlSinCos (&trig, Yaw()); truckPos.x = XPos()-20.0F*trig.cos; truckPos.y = YPos()-20.0F*trig.sin; truckPos.z = ZPos(); truckDrawable->Update(&truckPos, Yaw()+PI); } if (isTowed || hasCrew){ SetSwitch(0,0x2); } } else // itsa task force { if (vc){ SoundPos.Sfx( vc->EngineSound, 0, 1.0, 0); } else { SoundPos.Sfx( SFX_SHIP, 0, 1.0, 0); } //RV - I-Hawk - Do wakes only at some cases if ( (rand() & 7) == 7 ) { //I-Hawk - not using all this anymore // // reset the timer // dustTimer = 0.0f; //float ttl; //static float trailspd = 5.0f; //static float bowfx = 0.92f; //static float sternfx = 0.75f; //float spdratio = GetVt() / ((UnitClass*)GetCampaignObject())->GetMaxSpeed(); float radius; if ( drawPointer ){ radius = drawPointer->Radius(); // JPO from 0.15 - now done inline } else{ radius = 90.0f; } //I-Hawk - Fixed position for ships wakes, effect "delay" in position is //handled by PS now. No more the "V shape" of water wakes. pos.x = XPos() + XDelta() * SimLibMajorFrameTime; pos.y = YPos() + YDelta() * SimLibMajorFrameTime; pos.z = groundZ; //// JPO - think this is sideways on. ///* //vec.x = dmx[1][0] * spdratio * PRANDFloat() * trailspd; //vec.y = dmx[1][1] * spdratio * PRANDFloat() * trailspd; //vec.z = 0.5f; // from -20 JPO //*/ //I-Hawk - More correct vector for wakes vec.x = XDelta(); vec.y = YDelta(); vec.z = 0.0f; //I-Hawk - Separate wake effect for different ships size int theSFX; if ( radius < 200.0f ) { theSFX = SFX_WATER_WAKE_SMALL; } else if ( radius >= 200.0f && radius < 400.0f ) { theSFX = SFX_WATER_WAKE_MEDIUM; } else if ( radius >= 400.0f ) { theSFX = SFX_WATER_WAKE_LARGE; } //I-Hawk - The PS DrawableParticleSys::PS_AddParticleEx((theSFX + 1), &pos, &vec); } } } // Otherwise, we're not moving or are hidden. Do some stuff else { // (b) Make sure we're using our 'Holding' model (i.e. Unlimbered artillery, troops prone, etc) if (truckDrawable){ // Once we stop, our truck doesn't move at all - but sits further away than when moving Tpoint truckPos; truckPos.x = XPos() + 40.0F; truckPos.y = YPos(); truckPos.z = 0.0F; truckDrawable->Update(&truckPos, Yaw()); } if (isTowed || hasCrew){ SetSwitch(0,0x1); } } // ACMI Output if (gACMIRec.IsRecording() && (SimLibFrameCount & 0x0f ) == 0){ ACMIGenPositionRecord genPos; 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 ); } return IsLocal(); }
void HelicopterClass::DoWeapons (void) { int fireFlag; // MissileClass* theMissile; Tpoint pos, vec; // Guns fireFlag = fireGun; if (Guns) { Guns->Exec(&fireFlag, gunDmx, &platformAngles, targetPtr, FALSE); if (fireFlag) { #ifdef MLR_NEWSNDCODE SoundPos.Sfx( SFX_MCGUN ); #else F4SoundFXSetPos( SFX_MCGUN, 0, XPos(), YPos(), ZPos(), 1.0f , 0 , XDelta(),YDelta(),ZDelta()); #endif pos.x = XPos(); pos.y = YPos(); // RV - Biker - Adjust gun smoke position //pos.z = ZPos() - 5.0f; pos.z = ZPos() + 1.0f + offsetZ; vec.x = PRANDFloat() * 30.0f; vec.y = PRANDFloat() * 30.0f; vec.z = -PRANDFloatPos() * 30.0f; //RV - I-Hawk - changing all LIGHT_CLOUD weapons effects calls // to more appropriate GUN_SMOKE effect here /* OTWDriver.AddSfxRequest( new SfxClass ( SFX_GUN_SMOKE, // type SFX_MOVES, &pos, // world pos &vec, // vel vector 2.3f, // time to live 2.0f ) ); // scale */ DrawableParticleSys::PS_AddParticleEx((SFX_GUN_SMOKE + 1), &pos, &vec); if (!IsFiring()) { // KCK: This has been moved to GunClass::Exec, since that's where we generate // new bullets // SendFireMessage ((SimWeaponClass*)Guns, FalconWeaponsFire::GUN, TRUE, targetPtr); #ifdef _DEBUG SimVehicleClass *theObject; if ( targetPtr ) { theObject = (SimVehicleClass *)targetPtr->BaseData(); /* if ( theObject->IsAirplane() ) MonoPrint( "HELO BRAIN Firing Guns at Air Unit\n" ); else if ( theObject->IsHelicopter() ) MonoPrint( "HELO BRAIN Firing Guns at Helo Unit\n" ); else if ( theObject->IsGroundVehicle() ) MonoPrint( "HELO BRAIN Firing Guns at Ground Unit\n" ); */ } #endif } SetFiring(TRUE); } else { if (IsFiring()) { SendFireMessage ((SimWeaponClass*)Guns, FalconWeaponsFire::GUN, FALSE, targetPtr); } SetFiring(FALSE); } } /* ** edg: no more FCC stuff here. All done in hdigi now if ( FCC->releaseConsent && Sms->curWeapon ) { if (FCC->GetMasterMode() == FireControlComputer::Missile || FCC->GetMasterMode() == FireControlComputer::Dogfight || FCC->GetMasterMode() == FireControlComputer::MissileOverride) { theMissile = (MissileClass *)Sms->curWeapon; if (Sms->LaunchMissile()) { SendFireMessage ((SimWeaponClass*)theMissile, FalconWeaponsFire::SRM, TRUE, targetPtr); fireMissile = FALSE; F4SoundFXSetPos( SFX_MISSILE1, 0, XPos(), YPos(), ZPos(), 1.0f ); } } else if (FCC->GetMasterMode() == FireControlComputer::AirGroundMissile) { theMissile = (MissileClass *)Sms->curWeapon; if (Sms->LaunchMissile()) { SendFireMessage ((SimWeaponClass*)theMissile, FalconWeaponsFire::AGM, TRUE, targetPtr); fireMissile = FALSE; F4SoundFXSetPos( SFX_MISSILE2, 0, XPos(), YPos(), ZPos(), 1.0f ); } } else if (FCC->GetMasterMode() == FireControlComputer::AirGroundBomb && FCC->GetSubMode() == FireControlComputer::RCKT) { if (FCC->bombPickle && Sms->curWeapon && !OnGround()) { // Play the sound F4SoundFXSetPos( SFX_RCKTLOOP, TRUE, XPos(), YPos(), ZPos(), 1.0f ); theMissile = (MissileClass *)Sms->curWeapon; if (Sms->LaunchRocket()) { // Stop firing FCC->bombPickle = FALSE; FCC->postDrop = TRUE; // Play the sound F4SoundFXSetPos( SFX_MISSILE3, TRUE, XPos(), YPos(), ZPos(), 1.0f ); // Drop a message SendFireMessage (theMissile, FalconWeaponsFire::Rocket, TRUE, targetPtr); } } } } */ /* else if (FCC->GetMasterMode() == FireControlComputer::AirGroundBomb) { curWeapon = Sms->curWeapon; if (FCC->bombPickle) { SendFireMessage ((SimWeaponClass*)curWeapon, FalconWeaponsFire::BMB, TRUE, targetPtr); if (Sms->DropBomb()) { FCC->bombPickle = FALSE; FCC->postDrop = TRUE; } } } */ // Handle missiles launched but still on the rail Sms->Exec(); }