void Routeman::DeleteAllRoutes( void ) { ::wxBeginBusyCursor(); // Iterate on the RouteList wxRouteListNode *node = pRouteList->GetFirst(); while( node ) { Route *proute = node->GetData(); if( proute->m_bIsInLayer ) { node = node->GetNext(); continue; } if( !proute->m_bIsTrack ) { pConfig->m_bIsImporting = true; pConfig->DeleteConfigRoute( proute ); DeleteRoute( proute ); node = pRouteList->GetFirst(); // Route pConfig->m_bIsImporting = false; } else node = node->GetNext(); } ::wxEndBusyCursor(); }
void Routeman::AssembleAllRoutes( void ) { // Iterate on the RouteList wxRouteListNode *node = pRouteList->GetFirst(); while( node ) { Route *proute = node->GetData(); proute->AssembleRoute(); if( proute->GetnPoints() ) { pSelect->AddAllSelectableRouteSegments( proute ); } else // this route has no points { pConfig->DeleteConfigRoute( proute ); DeleteRoute( proute ); } node = node->GetNext(); // Route } }
bool CASW_Spawn_Manager::FindHordePosition() { // need to find a suitable place from which to spawn a horde // this place should: // - be far enough away from the marines so the whole horde can spawn before the marines get there // - should have a clear path to the marines UpdateCandidateNodes(); // decide if the horde is going to come from behind or in front bool bNorth = RandomFloat() < 0.7f; if ( m_northCandidateNodes.Count() <= 0 ) { bNorth = false; } else if ( m_southCandidateNodes.Count() <= 0 ) { bNorth = true; } CUtlVector<int> &candidateNodes = bNorth ? m_northCandidateNodes : m_southCandidateNodes; if ( candidateNodes.Count() <= 0 ) { if ( asw_director_debug.GetBool() ) { Msg( " Failed to find horde pos as there are no candidate nodes\n" ); } return false; } int iMaxTries = 3; // количество попыток найти место для спавна волны for ( int i=0 ; i<iMaxTries ; i++ ) { int iChosen = RandomInt( 0, candidateNodes.Count() - 1); CAI_Node *pNode = GetNetwork()->GetNode( candidateNodes[iChosen] ); if ( !pNode ) continue; float flDistance = 0; CASW_Marine *pMarine = dynamic_cast<CASW_Marine*>(UTIL_ASW_NearestMarine( pNode->GetPosition( CANDIDATE_ALIEN_HULL ), flDistance )); if ( !pMarine ) { if ( asw_director_debug.GetBool() ) { Msg( " Failed to find horde pos as there is no nearest marine\n" ); } return false; } // check if there's a route from this node to the marine(s) AI_Waypoint_t *pRoute = ASWPathUtils()->BuildRoute( pNode->GetPosition( CANDIDATE_ALIEN_HULL ), pMarine->GetAbsOrigin(), NULL, 100 ); if ( !pRoute ) { if ( asw_director_debug.GetInt() >= 2 ) { Msg( " Discarding horde node %d as there's no route.\n", iChosen ); } continue; } if ( bNorth && UTIL_ASW_DoorBlockingRoute( pRoute, true ) ) { if ( asw_director_debug.GetInt() >= 2 ) { Msg( " Discarding horde node %d as there's a door in the way.\n", iChosen ); } DeleteRoute( pRoute ); continue; } m_vecHordePosition = pNode->GetPosition( CANDIDATE_ALIEN_HULL ) + Vector( 0, 0, 32 ); // spawn facing the nearest marine Vector vecDir = pMarine->GetAbsOrigin() - m_vecHordePosition; vecDir.z = 0; vecDir.NormalizeInPlace(); VectorAngles( vecDir, m_angHordeAngle ); if ( asw_director_debug.GetInt() >= 2 ) { Msg( " Accepting horde node %d.\n", iChosen ); } DeleteRoute( pRoute ); return true; } if ( asw_director_debug.GetBool() ) { Msg( " Failed to find horde pos as we tried 3 times to build routes to possible locations, but failed\n" ); } return false; }
bool CASW_Spawn_Manager::SpawnAlientAtRandomNode() { if ( spawnRandomAlienTimer.HasStarted() && !spawnRandomAlienTimer.IsElapsed() ) return false; spawnRandomAlienTimer.Start( MINIMUM_SPAWN_DELAY ); UpdateCandidateNodes(); // decide if the alien is going to come from behind or in front bool bNorth = RandomFloat() < 0.7f; if ( m_northCandidateNodes.Count() <= 0 ) { bNorth = false; } else if ( m_southCandidateNodes.Count() <= 0 ) { bNorth = true; } CUtlVector<int> &candidateNodes = bNorth ? m_northCandidateNodes : m_southCandidateNodes; if ( candidateNodes.Count() <= 0 ) return false; const char *szAlienClass = wandererQueue[wandererQueueStart]; Vector vecMins, vecMaxs; GetAlienBounds( szAlienClass, vecMins, vecMaxs ); int alienHull = getAlienHull(szAlienClass); int iMaxTries = 3; for ( int i=0 ; i<iMaxTries ; i++ ) { int iChosen = RandomInt( 0, candidateNodes.Count() - 1); CAI_Node *pNode = GetNetwork()->GetNode( candidateNodes[iChosen] ); if ( !pNode ) continue; float flDistance = 0; CASW_Marine *pMarine = dynamic_cast<CASW_Marine*>(UTIL_ASW_NearestMarine( pNode->GetPosition( alienHull ), flDistance )); if ( !pMarine ) return false; // check if there's a route from this node to the marine(s) AI_Waypoint_t *pRoute = ASWPathUtils()->BuildRoute( pNode->GetPosition( alienHull ), pMarine->GetAbsOrigin(), NULL, 100 ); if ( !pRoute ) { if ( asw_director_debug.GetBool() ) { NDebugOverlay::Cross3D( pNode->GetOrigin(), 10.0f, 255, 128, 0, true, 20.0f ); } continue; } if ( bNorth && UTIL_ASW_DoorBlockingRoute( pRoute, true ) ) { DeleteRoute( pRoute ); continue; } Vector vecSpawnPos = pNode->GetPosition( alienHull ) + Vector( 0, 0, 32 ); bool needsGround = Q_stricmp(szAlienClass, "asw_buzzer") != 0; if ( ValidSpawnPoint( vecSpawnPos, vecMins, vecMaxs, needsGround, MARINE_NEAR_DISTANCE ) ) { float extraClearanceFactor = 1; //the boomer's hull seems to be too small for some reason if (Q_stricmp(szAlienClass, "asw_boomer") == 0) { extraClearanceFactor = 2; } Vector shiftSpawnBy = shiftSpawnPosition(vecSpawnPos, vecMins, vecMaxs, extraClearanceFactor); if (shiftSpawnBy.z == -1 ) { DeleteRoute( pRoute ); continue; } Vector shiftedSpawnPos = vecSpawnPos+shiftSpawnBy; Vector testShift = shiftSpawnPosition(shiftedSpawnPos, vecMins, vecMaxs, extraClearanceFactor); if (testShift.x != 0 || testShift.y != 0 || testShift.z != 0) { DeleteRoute( pRoute ); continue; } if ( SpawnAlienAt( szAlienClass, shiftedSpawnPos, vec3_angle ) ) { wandererQueueStart++; wandererQueueStart %= WANDERER_QUEUE_SIZE; if ( asw_director_debug.GetBool() ) { NDebugOverlay::Cross3D( vecSpawnPos, 25.0f, 255, 255, 255, true, 20.0f ); float flDist; CASW_Marine *pMarine = UTIL_ASW_NearestMarine( vecSpawnPos, flDist ); if ( pMarine ) { NDebugOverlay::Line( pMarine->GetAbsOrigin(), vecSpawnPos, 64, 64, 64, true, 60.0f ); } } DeleteRoute( pRoute ); return true; } } else { if ( asw_director_debug.GetBool() ) { NDebugOverlay::Cross3D( vecSpawnPos, 25.0f, 255, 0, 0, true, 20.0f ); } } DeleteRoute( pRoute ); } return false; }
bool Routeman::UpdateProgress() { bool bret_val = false; if( pActiveRoute ) { // Update bearing, range, and crosstrack error // Bearing is calculated as Mercator Sailing, i.e. a cartographic "bearing" double north, east; toSM( pActivePoint->m_lat, pActivePoint->m_lon, gLat, gLon, &east, &north ); double a = atan( north / east ); if( fabs( pActivePoint->m_lon - gLon ) < 180. ) { if( pActivePoint->m_lon > gLon ) CurrentBrgToActivePoint = 90. - ( a * 180 / PI ); else CurrentBrgToActivePoint = 270. - ( a * 180 / PI ); } else { if( pActivePoint->m_lon > gLon ) CurrentBrgToActivePoint = 270. - ( a * 180 / PI ); else CurrentBrgToActivePoint = 90. - ( a * 180 / PI ); } // Calculate range using Great Circle Formula double d5 = DistGreatCircle( gLat, gLon, pActivePoint->m_lat, pActivePoint->m_lon ); CurrentRngToActivePoint = d5; // Get the XTE vector, normal to current segment vector2D va, vb, vn; double brg1, dist1, brg2, dist2; DistanceBearingMercator( pActivePoint->m_lat, pActivePoint->m_lon, pActiveRouteSegmentBeginPoint->m_lat, pActiveRouteSegmentBeginPoint->m_lon, &brg1, &dist1 ); vb.x = dist1 * sin( brg1 * PI / 180. ); vb.y = dist1 * cos( brg1 * PI / 180. ); DistanceBearingMercator( pActivePoint->m_lat, pActivePoint->m_lon, gLat, gLon, &brg2, &dist2 ); va.x = dist2 * sin( brg2 * PI / 180. ); va.y = dist2 * cos( brg2 * PI / 180. ); double sdelta = vGetLengthOfNormal( &va, &vb, &vn ); // NM CurrentXTEToActivePoint = sdelta; // Calculate the distance to the arrival line, which is perpendicular to the current route segment // Taking advantage of the calculated normal from current position to route segment vn vector2D vToArriveNormal; vSubtractVectors( &va, &vn, &vToArriveNormal ); CurrentRangeToActiveNormalCrossing = vVectorMagnitude( &vToArriveNormal ); // Compute current segment course // Using simple Mercater projection double x1, y1, x2, y2; toSM( pActiveRouteSegmentBeginPoint->m_lat, pActiveRouteSegmentBeginPoint->m_lon, pActiveRouteSegmentBeginPoint->m_lat, pActiveRouteSegmentBeginPoint->m_lon, &x1, &y1 ); toSM( pActivePoint->m_lat, pActivePoint->m_lon, pActiveRouteSegmentBeginPoint->m_lat, pActiveRouteSegmentBeginPoint->m_lon, &x2, &y2 ); double e1 = atan2( ( x2 - x1 ), ( y2 - y1 ) ); CurrentSegmentCourse = e1 * 180 / PI; if( CurrentSegmentCourse < 0 ) CurrentSegmentCourse += 360; // Compute XTE direction double h = atan( vn.y / vn.x ); if( vn.x > 0 ) CourseToRouteSegment = 90. - ( h * 180 / PI ); else CourseToRouteSegment = 270. - ( h * 180 / PI ); h = CurrentBrgToActivePoint - CourseToRouteSegment; if( h < 0 ) h = h + 360; if( h > 180 ) XTEDir = 1; else XTEDir = -1; // Determine Arrival bool bDidArrival = false; if( CurrentRangeToActiveNormalCrossing <= pActiveRoute->GetRouteArrivalRadius() ) { m_bArrival = true; UpdateAutopilot(); bDidArrival = true; if( !ActivateNextPoint( pActiveRoute, false ) ) // at the end? { Route *pthis_route = pActiveRoute; DeactivateRoute( true ); // this is an arrival if( pthis_route->m_bDeleteOnArrival ) { pConfig->DeleteConfigRoute( pthis_route ); DeleteRoute( pthis_route ); if( pRoutePropDialog ) { pRoutePropDialog->SetRouteAndUpdate( NULL ); pRoutePropDialog->UpdateProperties(); } if( pRouteManagerDialog ) pRouteManagerDialog->UpdateRouteListCtrl(); } } } if( !bDidArrival ) // Only once on arrival UpdateAutopilot(); bret_val = true; // a route is active } m_bDataValid = true; return bret_val; }
static DWORD HandleRouteMessage (route_message_t *msg, undo_lists_t *lists) { DWORD err; PMIB_IPFORWARD_ROW2 fwd_row; BOOL add = msg->header.type == msg_add_route; typedef NETIOAPI_API (*CreateIpForwardEntry2Fn) (PMIB_IPFORWARD_ROW2); static CreateIpForwardEntry2Fn CreateIpForwardEntry2 = NULL; if (!CreateIpForwardEntry2) { HMODULE iphlpapi = GetModuleHandle (TEXT("iphlpapi.dll")); if (iphlpapi == NULL) return GetLastError (); CreateIpForwardEntry2 = (CreateIpForwardEntry2Fn) GetProcAddress (iphlpapi, "CreateIpForwardEntry2"); if (!CreateIpForwardEntry2) return GetLastError (); } fwd_row = malloc (sizeof (*fwd_row)); if (fwd_row == NULL) return ERROR_OUTOFMEMORY; ZeroMemory (fwd_row, sizeof (*fwd_row)); fwd_row->ValidLifetime = 0xffffffff; fwd_row->PreferredLifetime = 0xffffffff; fwd_row->Protocol = MIB_IPPROTO_NETMGMT; fwd_row->Metric = msg->metric; fwd_row->DestinationPrefix.Prefix = sockaddr_inet (msg->family, &msg->prefix); fwd_row->DestinationPrefix.PrefixLength = (UINT8) msg->prefix_len; fwd_row->NextHop = sockaddr_inet (msg->family, &msg->gateway); if (msg->iface.index != -1) { fwd_row->InterfaceIndex = msg->iface.index; } else if (strlen (msg->iface.name)) { NET_LUID luid; err = InterfaceLuid (msg->iface.name, &luid); if (err) goto out; fwd_row->InterfaceLuid = luid; } if (add) { err = CreateIpForwardEntry2 (fwd_row); if (err) goto out; err = AddListItem (&(*lists)[route], fwd_row); if (err) DeleteRoute (fwd_row); } else { err = DeleteRoute (fwd_row); if (err) goto out; free (RemoveListItem (&(*lists)[route], CmpRoute, fwd_row)); } out: if (!add || err) free (fwd_row); return err; }
bool CASW_Spawn_Manager::SpawnAlientAtRandomNode() { UpdateCandidateNodes(); // decide if the alien is going to come from behind or in front bool bNorth = RandomFloat() < 0.7f; if ( m_northCandidateNodes.Count() <= 0 ) { bNorth = false; } else if ( m_southCandidateNodes.Count() <= 0 ) { bNorth = true; } CUtlVector<int> &candidateNodes = bNorth ? m_northCandidateNodes : m_southCandidateNodes; if ( candidateNodes.Count() <= 0 ) return false; const char *szAlienClass = "asw_drone"; Vector vecMins, vecMaxs; GetAlienBounds( szAlienClass, vecMins, vecMaxs ); int iMaxTries = 1; for ( int i=0 ; i<iMaxTries ; i++ ) { int iChosen = RandomInt( 0, candidateNodes.Count() - 1); CAI_Node *pNode = GetNetwork()->GetNode( candidateNodes[iChosen] ); if ( !pNode ) continue; float flDistance = 0; CASW_Marine *pMarine = dynamic_cast<CASW_Marine*>(UTIL_ASW_NearestMarine( pNode->GetPosition( CANDIDATE_ALIEN_HULL ), flDistance )); if ( !pMarine ) return false; // check if there's a route from this node to the marine(s) AI_Waypoint_t *pRoute = ASWPathUtils()->BuildRoute( pNode->GetPosition( CANDIDATE_ALIEN_HULL ), pMarine->GetAbsOrigin(), NULL, 100 ); if ( !pRoute ) { if ( asw_director_debug.GetBool() ) { NDebugOverlay::Cross3D( pNode->GetOrigin(), 10.0f, 255, 128, 0, true, 20.0f ); } continue; } if ( bNorth && UTIL_ASW_DoorBlockingRoute( pRoute, true ) ) { DeleteRoute( pRoute ); continue; } // riflemod: preventing wanderers from spawning behind closed airlocks if (UTIL_ASW_BrushBlockingRoute(pRoute, MASK_PLAYERSOLID_BRUSHONLY, COLLISION_GROUP_PLAYER_MOVEMENT)) { DeleteRoute(pRoute); continue; } Vector vecSpawnPos = pNode->GetPosition( CANDIDATE_ALIEN_HULL ) + Vector( 0, 0, 32 ); if ( ValidSpawnPoint( vecSpawnPos, vecMins, vecMaxs, true, MARINE_NEAR_DISTANCE ) ) { if ( SpawnAlienAt( szAlienClass, vecSpawnPos, vec3_angle ) ) { if ( asw_director_debug.GetBool() ) { NDebugOverlay::Cross3D( vecSpawnPos, 25.0f, 255, 255, 255, true, 20.0f ); float flDist; CASW_Marine *pMarine = UTIL_ASW_NearestMarine( vecSpawnPos, flDist ); if ( pMarine ) { NDebugOverlay::Line( pMarine->GetAbsOrigin(), vecSpawnPos, 64, 64, 64, true, 60.0f ); } } DeleteRoute( pRoute ); return true; } } else { if ( asw_director_debug.GetBool() ) { NDebugOverlay::Cross3D( vecSpawnPos, 25.0f, 255, 0, 0, true, 20.0f ); } } DeleteRoute( pRoute ); } return false; }