[Gcblue-commits] gcb_wx/src/sim tcLauncherState.cpp,1.4,1.5 tcMapView.cpp,1.17,1.18 tcObjectControl.
Status: Alpha
Brought to you by:
ddcforge
Update of /cvsroot/gcblue/gcb_wx/src/sim In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11210/src/sim Modified Files: tcLauncherState.cpp tcMapView.cpp tcObjectControl.cpp tcPlatformObject.cpp tcRadarSensorState.cpp tcSensorState.cpp tcSimState.cpp tcTerrainView.cpp Log Message: Index: tcLauncherState.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/sim/tcLauncherState.cpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** tcLauncherState.cpp 30 Jan 2004 01:02:35 -0000 1.4 --- tcLauncherState.cpp 1 Feb 2004 22:19:09 -0000 1.5 *************** *** 29,41 **** tcDatabase* tcLauncherState::mpDatabase = NULL; tcSimState* tcLauncherState::simState = NULL; /** ! * */ ! void tcLauncherState::AddFullLauncher(tcDatabase *pDatabase, tnPoolIndex anKey, float azimuth_rad) { tcLauncherDBObject *ldata; unsigned long nChildKey; ! ldata = dynamic_cast<tcLauncherDBObject*>(pDatabase->GetObject(anKey)); if (ldata == NULL) { --- 29,45 ---- tcDatabase* tcLauncherState::mpDatabase = NULL; tcSimState* tcLauncherState::simState = NULL; + /** ! * @param anKey, key of launcher database object in database ! * @param azimuth_rad mount angle of (fixed) launcher in radians relative to bow/nose */ ! void tcLauncherState::AddFullLauncher(tnPoolIndex anKey, float azimuth_rad) { tcLauncherDBObject *ldata; unsigned long nChildKey; ! wxASSERT(mpDatabase); ! ! ldata = dynamic_cast<tcLauncherDBObject*>(mpDatabase->GetObject(anKey)); if (ldata == NULL) { *************** *** 51,56 **** // add new launcher ! nChildKey = pDatabase->GetKey(ldata->mzChildClass); ! tcDatabaseObject *pChildDBObj = pDatabase->GetObject(nChildKey); --- 55,60 ---- // add new launcher ! nChildKey = mpDatabase->GetKey(ldata->mzChildClass); ! tcDatabaseObject *pChildDBObj = mpDatabase->GetObject(nChildKey); *************** *** 82,86 **** new_launcher.fireControlSensor = NULL; // set detailed launch mode if missile ! tcMissileDBObject* pMissileDBObj = dynamic_cast<tcMissileDBObject*>(pDatabase->GetObject(nChildKey)); if (pMissileDBObj != NULL) { --- 86,91 ---- new_launcher.fireControlSensor = NULL; // set detailed launch mode if missile ! tcMissileDBObject* pMissileDBObj = ! dynamic_cast<tcMissileDBObject*>(mpDatabase->GetObject(nChildKey)); if (pMissileDBObj != NULL) { *************** *** 103,106 **** --- 108,218 ---- } + + /** + * @return LAUNCHER_READY if launcher is ready to launch. Launch readiness + * @return conditions depend on meLaunchMode for the launcher. + * @return Otherwise return error code + * @see teWeaponLaunchMode + * @see tcLauncherState::teLauncherStatus + * This method needs to be separated into smaller pieces. + */ + int tcLauncherState::GetLauncherStatus(unsigned nLauncher) + { + using namespace Database; + + if (nLauncher > launchers.size()) + { + std::cerr << "Bad launcher index" << std::endl; + return BAD_LAUNCHER; + } + tsLData& ldata = launchers[nLauncher]; + + if (ldata.mnCurrent <= 0) {return LAUNCHER_EMPTY;} // launcher empty + if (ldata.mfTimeToReady > 0) {return LAUNCHER_BUSY;} // launcher not ready + if (!ldata.mbActive) {return LAUNCHER_INACTIVE;} // launcher inactive or damaged + + if (ldata.meLaunchMode == DATUM_ONLY) // needs a datum programmed to launch + { + if ((ldata.msDatum.mfLat_rad != 0) || (ldata.msDatum.mfLon_rad != 0)) + { + return LAUNCHER_READY; + } + else + { + return NO_DATUM; + } + } + + wxASSERT(simState); + wxASSERT(parent); + + tcGameObject *targetObj = simState->GetObject(ldata.mnTargetID); + + // needs a fire control track (launching platform) to launch + if ((ldata.meLaunchMode == FC_TRACK)||(ldata.meLaunchMode == SEEKER_TRACK)) + { + if (ldata.mnTargetID == NULL_INDEX) return NO_TARGET; // needs a target + if (!ldata.fireControlSensor) return NO_FIRECONTROL; // database error + + if (!ldata.fireControlSensor->IsTrackAvailable()) return FC_BUSY; // no FC tracks available + if (targetObj == NULL) return NOT_DETECTED_FC; // target doesn't exist + + float range; + if (!ldata.fireControlSensor->CanDetectTarget(targetObj, range)) + { + return NOT_DETECTED_FC; + } + + if (ldata.meLaunchMode == FC_TRACK) return LAUNCHER_READY; + } + + // needs a seeker track to launch + if (ldata.meLaunchMode == SEEKER_TRACK) + { + tcMissileDBObject *pMissileDBObj = dynamic_cast<tcMissileDBObject*>(ldata.mpChildDBObj); + if (pMissileDBObj==NULL) + { + std::cerr << "GetLauncherStatus -- Error: SEEKER_TRACK guidance with non-missile" << std::endl; + return LAUNCHER_ERROR; + } + tnPoolIndex nSensorKey = pMissileDBObj->GetPrimarySeekerKey(); + + float seekerAz = parent->mcKin.mfHeading_rad + ldata.pointingAngle; + tsGeoPoint seekerLoc; + seekerLoc.Set((float)parent->mcKin.mfLon_rad,(float)parent->mcKin.mfLat_rad); + + long fcID = parent->mnID; + unsigned fcIdx = ldata.fireControlSensorIdx; + + bool canDetect = + simState->RadarCanDetect(nSensorKey,targetObj,seekerLoc,seekerAz, fcID, fcIdx); + if (canDetect) + { + return LAUNCHER_READY; + } + else + { + return NOT_DETECTED_SEEKER; + } + } + + // will launch and either proceed unguided or autonomously search out target + if (ldata.meLaunchMode == AUTO) + { + bool hasDatum = (ldata.msDatum.mfLat_rad != 0) || (ldata.msDatum.mfLon_rad != 0); + bool hasTarget = (ldata.mnTargetID == NULL_INDEX); + if ((!hasDatum) && (!hasTarget)) + { + return NO_TARGET; + } + else + { + return LAUNCHER_READY; + } + } + + return LAUNCHER_ERROR; // bad meLaunchMode + } + bool tcLauncherState::IsDatumLaunch(unsigned anLauncher) { *************** *** 108,111 **** --- 220,224 ---- return launchers[anLauncher].meLaunchMode == DATUM_ONLY; } + bool tcLauncherState::IsSeekerLaunch(unsigned anLauncher) { *************** *** 114,121 **** } ! void tcLauncherState::SetFireControlSensor(unsigned nLauncher, tcRadar* radar) { if (nLauncher > launchers.size()) {return;} launchers[nLauncher].fireControlSensor = radar; } --- 227,248 ---- } ! /** ! * @param nLauncher launcher index ! * @param radar pointer to tcRadar object that acts as fire control sensor ! * @param sensorIdx index of tcRadar object on parent platform ! */ ! void tcLauncherState::SetFireControlSensor(unsigned nLauncher, tcRadar* radar, unsigned sensorIdx) { + wxASSERT(radar); + if (nLauncher > launchers.size()) {return;} launchers[nLauncher].fireControlSensor = radar; + launchers[nLauncher].fireControlSensorIdx = sensorIdx; + // Launchers with fireControlSensor must have a FC track to launch + // SEEKER_TRACK already requires a fire control track (and a seeker track) so do not change + if (launchers[nLauncher].meLaunchMode != SEEKER_TRACK) + { + launchers[nLauncher].meLaunchMode = FC_TRACK; + } } *************** *** 150,212 **** /** ! * @return true if launcher is ready to launch. Launch readiness ! * conditions depend on meLaunchMode for the launcher ! * @see teWeaponLaunchMode ! */ ! bool tcLauncherState::ReadyToLaunch(unsigned nLauncher) { ! using namespace Database; ! if (nLauncher > launchers.size()) { ! std::cerr << "Bad launcher index" << std::endl; ! return false; } ! tsLData& ldata = launchers[nLauncher]; ! ! if (ldata.mnCurrent <= 0) {return false;} // launcher empty ! if (ldata.mfTimeToReady > 0) {return false;} // launcher not ready ! ! switch (ldata.meLaunchMode) { ! case DATUM_ONLY: // needs a datum programmed to launch ! { ! return (ldata.msDatum.mfLat_rad != 0) || (ldata.msDatum.mfLon_rad != 0); ! } ! case SA_TRACK: // needs a track (launching platform) to launch, semi-active or command guidance ! case SEEKER_TRACK: // needs a track to launch, seeker sensor checked before associating ! { ! wxASSERT(simState); ! ! if (ldata.mnTargetID == NULL_INDEX) return false; // needs a target ! tcMissileDBObject *pMissileDBObj = dynamic_cast<tcMissileDBObject*>(ldata.mpChildDBObj); ! if (pMissileDBObj==NULL) ! { ! std::cerr << "ReadyToLaunch -- Error: SA_TRACK guidance with non-missile" << std::endl; ! return false; ! } ! ! tnPoolIndex nSensorKey = pMissileDBObj->GetPrimarySeekerKey(); ! tcGameObject *targetObj = simState->GetObject(ldata.mnTargetID); ! ! float seekerAz = parent->mcKin.mfHeading_rad + ldata.pointingAngle; ! tsGeoPoint seekerLoc; ! seekerLoc.Set((float)parent->mcKin.mfLon_rad,(float)parent->mcKin.mfLat_rad); ! bool canDetect = simState->RadarCanDetect(nSensorKey,targetObj,seekerLoc,seekerAz); ! return canDetect; ! } ! ! case AUTO: // will launch and either proceed unguided or autonomously search out target ! { ! bool hasDatum = (ldata.msDatum.mfLat_rad != 0) || (ldata.msDatum.mfLon_rad != 0); ! bool hasTarget = (ldata.mnTargetID == NULL_INDEX); ! return hasDatum || hasTarget; ! } ! default: ! std::cerr << "Bad meLaunchMode" << std::endl; ! return false; } ! return false; } /** * --- 277,339 ---- /** ! * Converts launcher status code into string. ! */ ! std::string tcLauncherState::TranslateLauncherStatus(int status) { ! ! if (status == LAUNCHER_READY) { ! return "Launcher ready"; } ! if (status == BAD_LAUNCHER) { ! return "Launcher ready"; } ! if (status == LAUNCHER_EMPTY) ! { ! return "Launcher empty"; ! } ! if (status == LAUNCHER_BUSY) ! { ! return "Launcher busy"; ! } ! if (status == NO_DATUM) ! { ! return "No datum"; ! } ! if (status == NO_TARGET) ! { ! return "No target"; ! } ! if (status == NOT_DETECTED_FC) ! { ! return "Not detected by fire control"; ! } ! if (status == NOT_DETECTED_SEEKER) ! { ! return "Not detected by seeker"; ! } ! if (status == FC_BUSY) ! { ! return "Fire control busy"; ! } ! if (status == LAUNCHER_ERROR) ! { ! return "Corrupt launcher error"; ! } ! if (status == LAUNCHER_INACTIVE) ! { ! return "Launcher inactive or damaged"; ! } ! if (status == NO_FIRECONTROL) ! { ! return "No fire control sensor (database error)"; ! } ! ! std::cerr << "Bad launcher status code"; ! return "Bad launcher status code"; } + /** * Index: tcMapView.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/sim/tcMapView.cpp,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** tcMapView.cpp 29 Jan 2004 00:05:40 -0000 1.17 --- tcMapView.cpp 1 Feb 2004 22:19:09 -0000 1.18 *************** *** 96,103 **** mfGridBaseLon_rad = mfGridSize_rad*floorf(mrectCurrentView.left/mfGridSize_rad); mfGridBaseLat_rad = mfGridSize_rad*floorf(mrectCurrentView.bottom/mfGridSize_rad); ! mfScale_pelprad = mnWidth/mfLonWidth; ! mfScale_radppel = 1/mfScale_pelprad; ! // TODO: update ! // if(mpDDS_Terrain!=NULL) mpMapData->UpdateSurface(mpDDS_Terrain,mrectCurrentView); } /** --- 96,116 ---- mfGridBaseLon_rad = mfGridSize_rad*floorf(mrectCurrentView.left/mfGridSize_rad); mfGridBaseLat_rad = mfGridSize_rad*floorf(mrectCurrentView.bottom/mfGridSize_rad); ! mfScaleX_pelprad = mnWidth/mfLonWidth; ! mfScaleX_radppel = 1/mfScaleX_pelprad; ! mfScaleY_pelprad = mnHeight/mfLatWidth; ! mfScaleY_radppel = 1/mfScaleY_pelprad; ! ! /* ! fprintf(stdout, "*** setting map view to L:%f R:%f T:%f B:%f\n", ! mrectCurrentView.left, mrectCurrentView.right, ! mrectCurrentView.top, mrectCurrentView.bottom); ! fprintf(stdout, " map window L:%d R:%d T:%d B:%d\n", ! mrectWindow.left, mrectWindow.right, mrectWindow.top, mrectWindow.bottom); ! tcPoint testPoint = GeoToScreen(mfGridBaseLon_rad, mfGridBaseLat_rad); ! fprintf(stdout, " base geo (%f,%f) screen(%f, %f)\n", ! mfGridBaseLon_rad,mfGridBaseLat_rad, ! testPoint.x, testPoint.y); ! */ ! } /** *************** *** 115,120 **** tcPoint tcMapView::GeoToScreen(tcPoint pgeo) { tcPoint pscreen; ! pscreen.x = (pgeo.x - mfLonCenter)*mfScale_pelprad + mnXCenter; ! pscreen.y = (-pgeo.y + mfLatCenter)*mfScale_pelprad + mnYCenter; return pscreen; } --- 128,133 ---- tcPoint tcMapView::GeoToScreen(tcPoint pgeo) { tcPoint pscreen; ! pscreen.x = (pgeo.x - mfLonCenter)*mfScaleX_pelprad + mnXCenter; ! pscreen.y = (-pgeo.y + mfLatCenter)*mfScaleY_pelprad + mnYCenter; return pscreen; } *************** *** 122,138 **** tcPoint tcMapView::GeoToScreen(float afLon, float afLat) { tcPoint pscreen; ! pscreen.x = (afLon - mfLonCenter)*mfScale_pelprad + mnXCenter; ! pscreen.y = (-afLat + mfLatCenter)*mfScale_pelprad + mnYCenter; return pscreen; } /***********************************************************************************/ float tcMapView::GeoExtentToScreen(float afExtent_rad) { ! return afExtent_rad*mfScale_pelprad; } /***********************************************************************************/ tcPoint tcMapView::ScreenToGeo(wxPoint pscreen) { tcPoint pgeo; ! pgeo.x = ((float)pscreen.x - mnXCenter)*mfScale_radppel + mfLonCenter; ! pgeo.y = ((float)-pscreen.y + mnYCenter)*mfScale_radppel + mfLatCenter; return pgeo; } --- 135,151 ---- tcPoint tcMapView::GeoToScreen(float afLon, float afLat) { tcPoint pscreen; ! pscreen.x = (afLon - mfLonCenter)*mfScaleX_pelprad + mnXCenter; ! pscreen.y = (-afLat + mfLatCenter)*mfScaleY_pelprad + mnYCenter; return pscreen; } /***********************************************************************************/ float tcMapView::GeoExtentToScreen(float afExtent_rad) { ! return afExtent_rad*mfScaleX_pelprad; } /***********************************************************************************/ tcPoint tcMapView::ScreenToGeo(wxPoint pscreen) { tcPoint pgeo; ! pgeo.x = ((float)pscreen.x - mnXCenter)*mfScaleX_radppel + mfLonCenter; ! pgeo.y = ((float)-pscreen.y + mnYCenter)*mfScaleY_radppel + mfLatCenter; return pgeo; } *************** *** 140,145 **** tcPoint tcMapView::ScreenToGeo(float x, float y) { tcPoint pgeo; ! pgeo.x = (x - mnXCenter)*mfScale_radppel + mfLonCenter; ! pgeo.y = (-y + mnYCenter)*mfScale_radppel + mfLatCenter; return pgeo; } --- 153,158 ---- tcPoint tcMapView::ScreenToGeo(float x, float y) { tcPoint pgeo; ! pgeo.x = (x - mnXCenter)*mfScaleX_radppel + mfLonCenter; ! pgeo.y = (-y + mnYCenter)*mfScaleY_radppel + mfLatCenter; return pgeo; } *************** *** 162,166 **** wxPoint pos = wxWindow::GetPosition(); // mnWidth and mnHeight updated by tcWindow::OnSize - terrainView->SetSize(wxRect(pos.x,pos.y,mnWidth,mnHeight)); CalcViewParameters(); } --- 175,178 ---- *************** *** 173,176 **** --- 185,197 ---- (p.y >= mrectCurrentView.bottom)&&(p.y <= mrectCurrentView.top); } + /** + * override of wxWindow::SetSize so that terrainView->SetSize is called as well + */ + void tcMapView::SetSize(const wxRect& rect) + { + terrainView->SetSize(rect); + wxWindow::SetSize(rect); + } + /***********************************************************************************/ void tcMapView::SetViewCenterZoom(wxPoint pscreen, float afZoom) *************** *** 337,344 **** ! fKmPerPel = mfScale_radppel*C_RADTOKM; // calculate closest power of 10 km dist that corresponds to (about) 100 pixels fKmScale = expf(logf(10.0f)*floorf(log10f(fKmPerPel*120.0f))); ! nScaleBarWidth = (int)(fKmScale*C_KMTORAD*mfScale_pelprad); tcString sText; --- 358,365 ---- ! fKmPerPel = mfScaleX_radppel*C_RADTOKM; // calculate closest power of 10 km dist that corresponds to (about) 100 pixels fKmScale = expf(logf(10.0f)*floorf(log10f(fKmPerPel*120.0f))); ! nScaleBarWidth = (int)(fKmScale*C_KMTORAD*mfScaleX_pelprad); tcString sText; *************** *** 1323,1327 **** // search for hook ! fHookDistance = mfScale_radppel*16.0f; // 16 pixels fMinDistance = 1e15f; nMinID = NULL_INDEX; --- 1344,1348 ---- // search for hook ! fHookDistance = mfScaleX_radppel*16.0f; // 16 pixels fMinDistance = 1e15f; nMinID = NULL_INDEX; *************** *** 1350,1354 **** float dx,dy; float fDirection_rad = (float)C_PIOVER180*afDirection_deg; ! float dr = mfScale_radppel*16.0f; // 32 pixels dx = sinf(fDirection_rad)*dr; --- 1371,1375 ---- float dx,dy; float fDirection_rad = (float)C_PIOVER180*afDirection_deg; ! float dr = mfScaleX_radppel*16.0f; // 32 pixels dx = sinf(fDirection_rad)*dr; Index: tcObjectControl.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/sim/tcObjectControl.cpp,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** tcObjectControl.cpp 29 Jan 2004 00:05:45 -0000 1.10 --- tcObjectControl.cpp 1 Feb 2004 22:19:09 -0000 1.11 *************** *** 672,676 **** mcWeaponPanel.mastrCaption[i][4].Format("L-%s","DAT"); break; ! case SA_TRACK: mcWeaponPanel.mastrCaption[i][4].Format("L-%s","SA"); break; --- 672,676 ---- mcWeaponPanel.mastrCaption[i][4].Format("L-%s","DAT"); break; ! case FC_TRACK: mcWeaponPanel.mastrCaption[i][4].Format("L-%s","SA"); break; Index: tcPlatformObject.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/sim/tcPlatformObject.cpp,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** tcPlatformObject.cpp 30 Jan 2004 01:02:35 -0000 1.12 --- tcPlatformObject.cpp 1 Feb 2004 22:19:09 -0000 1.13 *************** *** 254,257 **** --- 254,264 ---- lastHeadingDelta = 0; } + + tcSensorState* tcPlatformObject::GetSensor(unsigned idx) + { + if (idx >= mapSensorState.size()) return NULL; + else return mapSensorState[idx]; + } + /******************************************************************************/ // return key of object to launch, otherwise NULL_INDEX *************** *** 296,310 **** /** ! * increment pending of anLauncher by anQuantity. ! * this doesn't support targeting multiple targets */ ! void tcPlatformObject::SetLaunch(int anLauncher, int anQuantity) { ! tsLData *pLauncher; - if ((anLauncher<0)||(anLauncher>=mcLauncherState.mnCount)) {return;} - pLauncher = &mcLauncherState.launchers[anLauncher]; - if (!pLauncher->mbActive) {return;} pLauncher->mnPending += anQuantity; if (pLauncher->mnPending > pLauncher->mnCurrent) {pLauncher->mnPending=pLauncher->mnCurrent;} } --- 303,322 ---- /** ! * If launcher is ready, increment pending of anLauncher by anQuantity. ! * This method does not support targeting multiple targets. ! * @return tcLauncherState::teLauncherStatus error code, LAUNCHER_READY = 0 for success */ ! int tcPlatformObject::SetLaunch(int anLauncher, int anQuantity) ! { ! int statusCode; ! ! statusCode = mcLauncherState.GetLauncherStatus(anLauncher); ! if (statusCode != tcLauncherState::LAUNCHER_READY) return statusCode; ! ! tsLData *pLauncher = &mcLauncherState.launchers[anLauncher]; pLauncher->mnPending += anQuantity; if (pLauncher->mnPending > pLauncher->mnCurrent) {pLauncher->mnPending=pLauncher->mnCurrent;} + return tcLauncherState::LAUNCHER_READY; } *************** *** 445,449 **** if (fcSensor == radar->mpDBObj->mzClass.mz) { ! mcLauncherState.SetFireControlSensor(nLauncher, radar); bSearching = false; } --- 457,461 ---- if (fcSensor == radar->mpDBObj->mzClass.mz) { ! mcLauncherState.SetFireControlSensor(nLauncher, radar, n); bSearching = false; } *************** *** 518,522 **** tnPoolIndex nLauncherKey = database->GetKey(mpDBObject->maLauncherClass[nLauncher]); float launcherAz_deg = mpDBObject->launcherAz[nLauncher]; ! mcLauncherState.AddFullLauncher(database, nLauncherKey, C_PIOVER180*launcherAz_deg); } --- 530,534 ---- tnPoolIndex nLauncherKey = database->GetKey(mpDBObject->maLauncherClass[nLauncher]); float launcherAz_deg = mpDBObject->launcherAz[nLauncher]; ! mcLauncherState.AddFullLauncher(nLauncherKey, C_PIOVER180*launcherAz_deg); } Index: tcRadarSensorState.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/sim/tcRadarSensorState.cpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** tcRadarSensorState.cpp 30 Jan 2004 01:02:50 -0000 1.4 --- tcRadarSensorState.cpp 1 Feb 2004 22:19:09 -0000 1.5 *************** *** 27,30 **** --- 27,31 ---- #include "tcGenericDBObject.h" #include "tcMissileDBObject.h" + #include "tcSimState.h" // break up this file later *************** *** 45,49 **** --- 46,54 ---- mnMode = mpDBObj->mbDetectsAir ? SSMODE_FCSURVEILLANCE : SSMODE_SURVEILLANCE; mfSensorHeight_m = 10.0f; + isSemiactive = mpDBObj->isSemiactive; + illuminatorID = -1; + illuminatorSensorIdx = 0; + return true; } *************** *** 59,66 **** bool bInSearchVolume = false; ! if (mpDBObj==NULL) { ! return false; } bool isSurface = false; bool isAir = false; --- 64,79 ---- bool bInSearchVolume = false; ! wxASSERT(mpDBObj); ! ! if (!mbActive) return false; ! ! float illuminatorTargetRange_km = 1e8; ! if (isSemiactive) { ! tcRadar* illum = GetSemiactiveIlluminator(); ! if (illum == NULL) return false; ! if (!illum->CanDetectTarget(target, illuminatorTargetRange_km)) return false; } + bool isSurface = false; bool isAir = false; *************** *** 113,126 **** } ! if (40.0f*(log10f(mpDBObj->mfRefRange_km) - log10f(fTargetRange_km)) ! >= rcs_dBsm) ! { ! bool bTargetTypeMatch = (mpDBObj->mbDetectsAir && isAir) || (mpDBObj->mbDetectsSurface && isSurface); ! return bTargetTypeMatch; // detected } ! return false; } --- 126,163 ---- } ! bool bTargetTypeMatch = (mpDBObj->mbDetectsAir && isAir) || (mpDBObj->mbDetectsSurface && isSurface); ! bool bDetectable; ! if (isSemiactive) ! { ! bDetectable = ! 20.0f*(2.0f*log10f(mpDBObj->mfRefRange_km) ! - log10f(fTargetRange_km) ! - log10f(illuminatorTargetRange_km) ! ) >= rcs_dBsm; } + else + { + bDetectable = + (40.0f*(log10f(mpDBObj->mfRefRange_km) - log10f(fTargetRange_km)) >= rcs_dBsm); + } + return bDetectable && bTargetTypeMatch; + + } ! /** ! * @return semi-active illuminator object ! */ ! tcRadar* tcRadar::GetSemiactiveIlluminator() ! { ! wxASSERT(isSemiactive); ! wxASSERT(simState); ! ! tcPlatformObject *platObj = ! dynamic_cast<tcPlatformObject*>(simState->GetObject(illuminatorID)); ! if (platObj == NULL) return NULL; ! tcRadar* illum = dynamic_cast<tcRadar*>(platObj->GetSensor(illuminatorSensorIdx)); ! return illum; } *************** *** 166,190 **** /** ! * @return true if track is available and radar can detect target. */ ! bool tcRadar::IsTrackAvailable(const tcGameObject* target) { ! return false; } /** ! * if track is available and detectable, reserve a track. * The current approach to semi-active guidance is to require each * missile to request one track per target, even if it is the same * target as a pre-existing track. */ ! bool tcRadar::RequestTrack(const tcGameObject* target) { ! return false; } bool tcRadar::ReleaseTrack() { ! return false; } --- 203,247 ---- /** ! * Does not test if radar can detect target. ! * @return true if track is available. */ ! bool tcRadar::IsTrackAvailable() { ! return (fireControlTrackCount < mpDBObj->maxFireControlTracks); } /** ! * if track is available, reserve a track. * The current approach to semi-active guidance is to require each * missile to request one track per target, even if it is the same * target as a pre-existing track. + * Calling method must check if target is detectable for this to + * work properly. */ ! bool tcRadar::RequestTrack() { ! if (IsTrackAvailable()) ! { ! fireControlTrackCount++; ! return true; ! } ! else ! { ! return false; ! } } bool tcRadar::ReleaseTrack() { ! if (fireControlTrackCount > 0) ! { ! fireControlTrackCount--; ! return true; ! } ! else ! { ! std::cerr << "tcRadar::ReleaseTrack called with no tracks." << std::endl; ! return false; ! } } *************** *** 207,209 **** * */ ! tcRadar::~tcRadar() {} \ No newline at end of file --- 264,276 ---- * */ ! tcRadar::~tcRadar() ! { ! // release fire control track ! if (isSemiactive) ! { ! if (tcRadar *illuminator = GetSemiactiveIlluminator()) ! { ! illuminator->ReleaseTrack(); ! } ! } ! } \ No newline at end of file Index: tcSensorState.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/sim/tcSensorState.cpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** tcSensorState.cpp 4 Jan 2004 22:24:53 -0000 1.2 --- tcSensorState.cpp 1 Feb 2004 22:19:09 -0000 1.3 *************** *** 20,23 **** --- 20,26 ---- #include "tcSensorState.h" #include "aerror.h" + #include "tcSimState.h" + + tcSimState* tcSensorState::simState = NULL; /** Index: tcSimState.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/sim/tcSimState.cpp,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** tcSimState.cpp 30 Jan 2004 01:02:50 -0000 1.26 --- tcSimState.cpp 1 Feb 2004 22:19:09 -0000 1.27 *************** *** 1,20 **** /* ! * Copyright (C) 2003 Dewitt "Cole" Colclough (de...@tw...) ! * All rights reserved. ! * ! * This file is part of the Global Conflict Blue (GCB) program. ! * GCB is free software; you can redistribute it and/or modify ! * it under the terms of version 2 of the GNU General Public License as ! * published by the Free Software Foundation. ! * ! * GCB is distributed in the hope that it will be useful, ! * but WITHOUT ANY WARRANTY; without even the implied warranty of ! * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! * GNU General Public License for more details. ! * ! * You should have received a copy of the GNU General Public License ! * along with GCB; if not, write to the Free Software ! * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! */ #include "stdwx.h" --- 1,20 ---- /* ! * Copyright (C) 2003 Dewitt "Cole" Colclough (de...@tw...) ! * All rights reserved. ! * ! * This file is part of the Global Conflict Blue (GCB) program. ! * GCB is free software; you can redistribute it and/or modify ! * it under the terms of version 2 of the GNU General Public License as ! * published by the Free Software Foundation. ! * ! * GCB is distributed in the hope that it will be useful, ! * but WITHOUT ANY WARRANTY; without even the implied warranty of ! * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! * GNU General Public License for more details. ! * ! * You should have received a copy of the GNU General Public License ! * along with GCB; if not, write to the Free Software ! * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! */ #include "stdwx.h" *************** *** 125,134 **** * If this is used with a non forward looking radar, it will not work * correctly. */ bool tcSimState::RadarCanDetect(tnPoolIndex anSensorKey, const tcGameObject* target, ! tsGeoPoint asSensorLocation, float afSensorAz) { float fRange_km; ! if (mcDefaultRadar.InitFromDB(mpDatabase,anSensorKey,0)==false) {return false;} mcDefaultRadar.UpdateCoverage(asSensorLocation,afSensorAz); return mcDefaultRadar.CanDetectTarget(target,fRange_km); --- 125,147 ---- * If this is used with a non forward looking radar, it will not work * correctly. + * @param fcID id of platform that has fire control sensor (for semi-active) + * @param fcIdx index of fire control sensor on fc platform (for semi-active) */ bool tcSimState::RadarCanDetect(tnPoolIndex anSensorKey, const tcGameObject* target, ! tsGeoPoint asSensorLocation, float afSensorAz, ! long fcID, unsigned fcIdx) { float fRange_km; ! ! if (mcDefaultRadar.InitFromDB(mpDatabase,anSensorKey,0)==false) ! { ! return false; ! } ! mcDefaultRadar.mbActive = true; ! ! if (mcDefaultRadar.IsSemiactive()) ! { ! mcDefaultRadar.SetIlluminator(fcID, fcIdx); ! } mcDefaultRadar.UpdateCoverage(asSensorLocation,afSensorAz); return mcDefaultRadar.CanDetectTarget(target,fRange_km); *************** *** 173,187 **** bFound = maPlatformState.Lookup(anKey,po); if (!bFound) {WTL("Err - tcSimState::DesignateLauncherTarget - source not found");return false;} tcPlatformObject* pPlatformObj = dynamic_cast<tcPlatformObject*>(po); if (pPlatformObj==NULL) {return false;} ! tcGameObject *pTargetObj; ! if (maPlatformState.Lookup(anTargetKey,pTargetObj) == false) {return false;} ! if (pTargetObj==NULL) {return false;} tcLauncherState *pLauncherState; po->GetLauncherState(pLauncherState); ! if (pLauncherState->ReadyToLaunch(anLauncher)) { - pPlatformObj->DesignateLauncherTarget(anTargetKey, anLauncher); if (mpUserInfo->IsOwnAlliance(pPlatformObj->mnAlliance)) { mpSound->PlayEffect(SEFFECT_NOISYBEEP); --- 186,199 ---- bFound = maPlatformState.Lookup(anKey,po); if (!bFound) {WTL("Err - tcSimState::DesignateLauncherTarget - source not found");return false;} + tcPlatformObject* pPlatformObj = dynamic_cast<tcPlatformObject*>(po); if (pPlatformObj==NULL) {return false;} ! ! pPlatformObj->DesignateLauncherTarget(anTargetKey, anLauncher); tcLauncherState *pLauncherState; po->GetLauncherState(pLauncherState); ! if (pLauncherState->GetLauncherStatus(anLauncher) == tcLauncherState::LAUNCHER_READY) { if (mpUserInfo->IsOwnAlliance(pPlatformObj->mnAlliance)) { mpSound->PlayEffect(SEFFECT_NOISYBEEP); *************** *** 191,195 **** else { ! return false; } /* --- 203,207 ---- else { ! return true; } /* *************** *** 204,232 **** if (pLauncher->meLaunchMode == SEEKER_TRACK) { // TODO: move this out of here to a modular function call ! tcMissileDBObject *pMissileDBObj = ! dynamic_cast<tcMissileDBObject*>(mpDatabase->GetObject(pLauncher->mnChildDBKey)); ! if (pMissileDBObj==NULL) {return false;} ! tnPoolIndex nSensorKey = mpDatabase->GetKey(pMissileDBObj->maSensorClass[0]); ! float fSeekerAz = po->mcKin.mfHeading_rad; // TODO: add launcher angle effect ! tsGeoPoint sSeekerLoc; ! sSeekerLoc.Set((float)po->mcKin.mfLon_rad,(float)po->mcKin.mfLat_rad); ! bool bCanDetect = RadarCanDetect(nSensorKey,pTargetObj,sSeekerLoc,fSeekerAz); ! if (bCanDetect) ! { ! pPlatformObj->DesignateLauncherTarget(anTargetKey, anLauncher); ! if (mpUserInfo->IsOwnAlliance(pPlatformObj->mnAlliance)) { ! mpSound->PlayEffect(SEFFECT_NOISYBEEP); ! } ! return true; ! } ! else { ! //pPlatformObj->DesignateLauncherTarget(anTargetKey, anLauncher); ! //mpSound->PlayEffect(SEFFECT_LOWBEEP); ! return false; ! } } else { ! return false; // don't designate for other launch modes for now } */ --- 216,244 ---- if (pLauncher->meLaunchMode == SEEKER_TRACK) { // TODO: move this out of here to a modular function call ! tcMissileDBObject *pMissileDBObj = ! dynamic_cast<tcMissileDBObject*>(mpDatabase->GetObject(pLauncher->mnChildDBKey)); ! if (pMissileDBObj==NULL) {return false;} ! tnPoolIndex nSensorKey = mpDatabase->GetKey(pMissileDBObj->maSensorClass[0]); ! float fSeekerAz = po->mcKin.mfHeading_rad; // TODO: add launcher angle effect ! tsGeoPoint sSeekerLoc; ! sSeekerLoc.Set((float)po->mcKin.mfLon_rad,(float)po->mcKin.mfLat_rad); ! bool bCanDetect = RadarCanDetect(nSensorKey,pTargetObj,sSeekerLoc,fSeekerAz); ! if (bCanDetect) ! { ! pPlatformObj->DesignateLauncherTarget(anTargetKey, anLauncher); ! if (mpUserInfo->IsOwnAlliance(pPlatformObj->mnAlliance)) { ! mpSound->PlayEffect(SEFFECT_NOISYBEEP); ! } ! return true; } else { ! //pPlatformObj->DesignateLauncherTarget(anTargetKey, anLauncher); ! //mpSound->PlayEffect(SEFFECT_LOWBEEP); ! return false; ! } ! } ! else { ! return false; // don't designate for other launch modes for now } */ *************** *** 244,247 **** --- 256,260 ---- UpdateObjTerrainInfo(); + // needs to be re-written to use the toLaunch queue for (int i=0;i<nSize;i++) { maPlatformState.GetNextAssoc(cmappos,nKey,pplat); *************** *** 332,336 **** } } ! --- 345,349 ---- } } ! *************** *** 1073,1078 **** } } ! else if (apRadarSS->mnMode == SSMODE_SEEKERTRACK) { ! applat->mfDamageLevel = 1.0f; // self destruct if track lost pTrack->mnID = NULL_INDEX; if(mpUserInfo->IsOwnAlliance(applat->mnAlliance)) { --- 1086,1094 ---- } } ! // shut down missile if track lost for > 7 seconds ! if ((apRadarSS->mnMode == SSMODE_SEEKERTRACK)&& ! (mfSimTime - pTrack->mfTimestamp) > 7.0) ! { ! applat->mfDamageLevel = 1.0f; pTrack->mnID = NULL_INDEX; if(mpUserInfo->IsOwnAlliance(applat->mnAlliance)) { *************** *** 1083,1088 **** return; } ! pTrack->mnID = NULL_INDEX; ! apRadarSS->mnMode = SSMODE_SEEKERSEARCH; break; case SSMODE_SEEKERSEARCH: --- 1099,1105 ---- return; } ! // this code to enter search mode after track lost ! //pTrack->mnID = NULL_INDEX; ! //apRadarSS->mnMode = SSMODE_SEEKERSEARCH; break; case SSMODE_SEEKERSEARCH: *************** *** 1159,1172 **** tcLauncherState* pLauncherState; plaunchingplatform->GetLauncherState(pLauncherState); ! if (pLauncherState != NULL) { tsLData *pLauncher = &pLauncherState->launchers[anLauncher]; ! if (pLauncher->meLaunchMode == DATUM_ONLY) { pMissileObj->msWaypoint = pLauncher->msDatum; } ! else if (pLauncher->meLaunchMode == SEEKER_TRACK) { pMissileObj->msWaypoint = pLauncher->msDatum; pMissileObj->mcSensorState.mbActive = true; pMissileObj->mcSensorState.mnMode = SSMODE_SEEKERACQUIRE; pMissileObj->mcSensorState.mcTrack.mnID = pLauncher->mnTargetID; } } --- 1176,1199 ---- tcLauncherState* pLauncherState; plaunchingplatform->GetLauncherState(pLauncherState); ! if (pLauncherState != NULL) ! { tsLData *pLauncher = &pLauncherState->launchers[anLauncher]; ! if (pLauncher->meLaunchMode == DATUM_ONLY) ! { pMissileObj->msWaypoint = pLauncher->msDatum; } ! else if ((pLauncher->meLaunchMode == SEEKER_TRACK) ! || (pLauncher->meLaunchMode == FC_TRACK)) ! { pMissileObj->msWaypoint = pLauncher->msDatum; pMissileObj->mcSensorState.mbActive = true; pMissileObj->mcSensorState.mnMode = SSMODE_SEEKERACQUIRE; pMissileObj->mcSensorState.mcTrack.mnID = pLauncher->mnTargetID; + if (pMissileObj->mcSensorState.IsSemiactive()) + { + pMissileObj->mcSensorState.SetIlluminator( + plaunchingplatform->mnID, pLauncher->fireControlSensorIdx); + pLauncher->fireControlSensor->RequestTrack(); + } } } *************** *** 1184,1188 **** pnew->mnAlliance = plaunchingplatform->mnAlliance; AddPlatform(pnew); ! if (mpUserInfo->IsOwnAlliance(plaunchingplatform->mnAlliance)) { mpSound->PlayEffect(SEFFECT_MISSILELAUNCH); } --- 1211,1216 ---- pnew->mnAlliance = plaunchingplatform->mnAlliance; AddPlatform(pnew); ! if (mpUserInfo->IsOwnAlliance(plaunchingplatform->mnAlliance)) ! { mpSound->PlayEffect(SEFFECT_MISSILELAUNCH); } *************** *** 1738,1743 **** --- 1766,1773 ---- msScenarioInfo.mbLoaded = false; goalTracker = new tcGoalTracker(); + tcGoal::AttachSimState(this); tcLauncherState::AttachSimState(this); + tcSensorState::AttachSimState(this); mcSensorMap.CreateMapForAlliance(1); Index: tcTerrainView.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/sim/tcTerrainView.cpp,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** tcTerrainView.cpp 22 Dec 2003 02:32:37 -0000 1.7 --- tcTerrainView.cpp 1 Feb 2004 22:19:09 -0000 1.8 *************** *** 55,58 **** --- 55,59 ---- float fSurfaceWidth, fSurfaceHeight; // surface coordinate dimensions + if (mrectCurrentView == r) return; mrectCurrentView = r; if (mp2DSurface == NULL) {return;} *************** *** 65,69 **** rdisp.Height = (fSurfaceHeight)*(r.top - mrectMap.bottom)/mrectMap.Height() - rdisp.Y; SetDisplayRegion(rdisp); ! //mp2DSurface->SetDisplayRegion(rdisp.x1,rdisp.y1,rdisp.x2,rdisp.y2); } --- 66,74 ---- rdisp.Height = (fSurfaceHeight)*(r.top - mrectMap.bottom)/mrectMap.Height() - rdisp.Y; SetDisplayRegion(rdisp); ! /* ! fprintf(stdout, "setting terrain to view L:%f R:%f T:%f B:%f\n", r.left, r.right, r.top, r.bottom); ! fprintf(stdout, " terrain window L:%d R:%d T:%d B:%d\n", ! mrectWindow.left, mrectWindow.right, mrectWindow.top, mrectWindow.bottom); ! */ //mp2DSurface->SetDisplayRegion(rdisp.x1,rdisp.y1,rdisp.x2,rdisp.y2); } |