void asw_path_end_f() { CASW_Player *pPlayer = ToASW_Player(UTIL_GetCommandClient()); if ( !pPlayer || !ASWPathUtils() ) return; if ( !pPlayer->GetMarine() ) return; Vector vecPathEnd = pPlayer->GetMarine()->GetAbsOrigin(); debugoverlay->AddBoxOverlay( g_vecPathStart, Vector(-10, -10, -10 ), Vector(10, 10, 10) , vec3_angle, 255, 0, 0, 255, 30.0f ); debugoverlay->AddBoxOverlay( vecPathEnd, Vector(-10, -10, -10 ), Vector(10, 10, 10) , vec3_angle, 255, 255, 0, 255, 30.0f ); AI_Waypoint_t *pWaypoint = ASWPathUtils()->BuildRoute( g_vecPathStart, vecPathEnd, NULL, 100, NAV_NONE, bits_BUILD_GET_CLOSE ); if ( !pWaypoint ) { Msg( "Failed to find route\n" ); return; } if ( UTIL_ASW_DoorBlockingRoute( pWaypoint, true ) ) { Msg(" Route blocked by sealed/locked door\n" ); } ASWPathUtils()->DebugDrawRoute( g_vecPathStart, pWaypoint ); }
void asw_path_start_f() { CASW_Player *pPlayer = ToASW_Player(UTIL_GetCommandClient()); if ( !pPlayer || !ASWPathUtils() ) return; if ( !pPlayer->GetMarine() ) return; g_vecPathStart = pPlayer->GetMarine()->GetAbsOrigin(); }
bool CASW_Weapon_Blink::SetBlinkDestination() { CASW_Player *pPlayer = GetCommander(); if ( !pPlayer ) return false; CASW_Marine *pMarine = GetMarine(); if ( !pMarine ) return false; Vector vecStart = pPlayer->GetCrosshairTracePos() + Vector( 0, 0, 30 ); Vector vecEnd = pPlayer->GetCrosshairTracePos() - Vector( 0, 0, 30 ); trace_t tr; UTIL_TraceHull( vecStart, vecEnd, pMarine->WorldAlignMins(), pMarine->WorldAlignMaxs(), MASK_PLAYERSOLID_BRUSHONLY, pMarine, COLLISION_GROUP_PLAYER_MOVEMENT, &tr ); if ( tr.startsolid || tr.allsolid ) { m_vecInvalidDestination = vecStart; return false; } if ( pMarine->GetAbsOrigin().DistTo( tr.endpos ) > asw_blink_range.GetFloat() ) { m_vecInvalidDestination = tr.endpos; return false; } Vector vecDest = tr.endpos; // now see if we can build an AI path from the marine to this spot bool bValidRoute = false; if ( !pMarine->GetPathfinder() ) { m_vecInvalidDestination = vecDest; return false; } AI_Waypoint_t *pRoute = pMarine->GetPathfinder()->BuildRoute( pMarine->GetAbsOrigin(), vecDest, NULL, 30, NAV_GROUND, bits_BUILD_GROUND | bits_BUILD_IGNORE_NPCS ); if ( pRoute && !UTIL_ASW_DoorBlockingRoute( pRoute, true ) ) { if ( !UTIL_ASW_BrushBlockingRoute( pRoute, MASK_PLAYERSOLID_BRUSHONLY, COLLISION_GROUP_PLAYER_MOVEMENT ) ) { // if end node of the route is too Z different, then abort, to stop people jumping on top of walls AI_Waypoint_t *pLast = pRoute->GetLast(); if ( pLast ) { AI_Waypoint_t *pNode = pLast->GetPrev(); if ( !pNode || fabs( pNode->GetPos().z - pLast->GetPos().z ) < 80.0f ) { bValidRoute = true; } } } } if ( !bValidRoute ) { // find the closest node to the dest and try to path there instead CAI_Network *pNetwork = pMarine->GetNavigator() ? pMarine->GetNavigator()->GetNetwork() : NULL; if ( pNetwork ) { int nNode = pNetwork->NearestNodeToPoint( vecDest, false ); if ( nNode != NO_NODE ) { CAI_Node *pNode = pNetwork->GetNode( nNode ); if ( pNode && pNode->GetType() == NODE_GROUND ) { vecDest = pNode->GetOrigin(); if ( pRoute ) { ASWPathUtils()->DeleteRoute( pRoute ); pRoute = NULL; } pRoute = pMarine->GetPathfinder()->BuildRoute( pMarine->GetAbsOrigin(), vecDest, NULL, 30, NAV_GROUND, bits_BUILD_GROUND | bits_BUILD_IGNORE_NPCS ); if ( pRoute && !UTIL_ASW_DoorBlockingRoute( pRoute, true ) ) { if ( !UTIL_ASW_BrushBlockingRoute( pRoute, MASK_PLAYERSOLID_BRUSHONLY, COLLISION_GROUP_PLAYER_MOVEMENT ) ) { bValidRoute = true; } } if ( !bValidRoute ) { m_vecInvalidDestination = vecDest; } } } } } if ( !bValidRoute ) { if ( pRoute ) { ASWPathUtils()->DeleteRoute( pRoute ); pRoute = NULL; } return false; } if ( asw_blink_debug.GetBool() ) { ASWPathUtils()->DebugDrawRoute( pMarine->GetAbsOrigin(), pRoute ); } m_vecAbilityDestination = vecDest; if ( pRoute ) { ASWPathUtils()->DeleteRoute( pRoute ); pRoute = NULL; } return true; }
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 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; }