本文整理汇总了C++中CAI_Node::GetPosition方法的典型用法代码示例。如果您正苦于以下问题:C++ CAI_Node::GetPosition方法的具体用法?C++ CAI_Node::GetPosition怎么用?C++ CAI_Node::GetPosition使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类CAI_Node
的用法示例。
在下文中一共展示了CAI_Node::GetPosition方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: AddChild
//=========================================================
// Crea un hijo en un nodo candidato.
//=========================================================
void CDirector_Manager::AddChild()
{
// Actualizamos los nodos candidatos para la creación.
UpdateNodes();
// ¡No hay nodos!
if ( SpawnNodes.Count() <= 0 )
return;
// Intentamos crear al hijo.
for ( int i = 0; i < MAX_TRIES; ++i )
{
// Seleccionamos un nodo candidato al azar.
CAI_Node *pNode = GetRandomNode();
// El nodo no existe.
if ( !pNode )
continue;
// Obtenemos la ubicación del nodo e intentamos crear al hijo.
Vector vecOrigin = pNode->GetPosition(HULL_HUMAN);
bool bSpawn = AddChild(vecOrigin);
// El hijo no se ha podido crear.
if ( !bSpawn )
continue;
// Un hijo menos en la cola.
Director()->SpawnQueue = Director()->SpawnQueue - 1;
break;
}
}
示例2: SpawnBoss
//=========================================================
// Crea un jefe.
//=========================================================
void CDirector_Manager::SpawnBoss()
{
// Actualizamos los nodos candidatos para la creación.
UpdateNodes();
// ¡No hay nodos!
if ( SpawnNodes.Count() <= 0 )
return;
for ( int i = 0; i < MAX_TRIES; ++i )
{
// Seleccionamos un nodo candidato al azar.
CAI_Node *pNode = GetRandomNode();
// El nodo no existe.
if ( !pNode )
continue;
// Obtenemos la ubicación del nodo.
Vector vecOrigin = pNode->GetPosition(HULL_MEDIUM_TALL);
bool bSpawn = AddBoss(vecOrigin);
// El hijo no se ha podido crear.
if ( !bSpawn )
continue;
return;
}
// No se pudo crear al Jefe, intentarlo en otro momento.
Director()->BossPendient = true;
}
示例3: PrespawnAlienAtRandomNode
void CASW_Spawn_Manager::PrespawnAlienAtRandomNode(const char *szAlienClass, const int iNumAliens, const int iHull, const Vector &playerStartPos, const int iNumNodes)
{
for (int i = 0; i < iNumAliens; ++i)
{
CAI_Node *pNode = NULL;
for (int k = 0; k < 30; ++k)
{
int node_id = RandomInt(0, iNumNodes - 1);
pNode = g_pBigAINet->GetNode(node_id);
if (!pNode || pNode->GetType() != NODE_GROUND)
continue;
else if (pNode->GetOrigin().DistToSqr(playerStartPos) < 1000 * 1000)
{
continue;
}
if (ValidSpawnPoint(pNode->GetPosition(iHull), NAI_Hull::Mins(iHull), NAI_Hull::Maxs(iHull), true, false))
{
// Raise the end position a little up off the floor, place the npc and drop him down
CBaseEntity *pAlien = SpawnAlienAt(szAlienClass, pNode->GetPosition(iHull) + Vector(0.f, 0.f, 12.f), RandomAngle(0, 360));
IASW_Spawnable_NPC *pSpawnable = dynamic_cast<IASW_Spawnable_NPC*>(pAlien);
if (pSpawnable)
{
pSpawnable->SetAlienOrders(AOT_SpreadThenHibernate, vec3_origin, NULL);
}
if (asw_director_debug.GetBool() && pAlien)
{
Msg("Spawned alien at %f %f %f\n", pAlien->GetAbsOrigin());
NDebugOverlay::Cross3D(pAlien->GetAbsOrigin(), 8.0f, 255, 0, 0, true, 20.0f);
}
if (pAlien)
break;
}
}
}
}
示例4: PostSpawn
//=========================================================
// Verificaciones después de crear al NPC.
//=========================================================
bool CDirector_Manager::PostSpawn(CAI_BaseNPC *pNPC)
{
bool bStuck = true;
while ( bStuck )
{
trace_t tr;
UTIL_TraceHull(pNPC->GetAbsOrigin(), pNPC->GetAbsOrigin(), pNPC->WorldAlignMins(), pNPC->WorldAlignMaxs(), MASK_NPCSOLID, pNPC, COLLISION_GROUP_NONE, &tr);
if ( tr.fraction != 1.0 && tr.m_pEnt )
{
// Nos hemos atorado en un objeto con fisicas.
if ( FClassnameIs(tr.m_pEnt, "prop_physics") )
{
// Lo ajustamos como "No solido" para que el bucle lo ignore.
tr.m_pEnt->AddSolidFlags(FSOLID_NOT_SOLID);
// Removemos el objeto.
UTIL_RemoveImmediate(tr.m_pEnt);
continue;
}
// Nos hemos atorado con una pared o algo del mundo.
if ( tr.m_pEnt->IsWorld() )
{
// No... no podemos eliminar una pared...
// Removemos el NPC para evitar eventos sobrenaturales.
UTIL_RemoveImmediate(pNPC);
return false;
}
// No es un objeto con físicas ni del mundo.
// Intentamos encontrar una nueva ubicación para el hijo.
//DevMsg("[MANAGER] <%s> STUCK!!!! \r\n", tr.m_pEnt->GetClassname());
CAI_Node *pNode = GetRandomNode();
// Nada
if ( !pNode )
UTIL_RemoveImmediate(pNPC);
pNPC->SetAbsOrigin(pNode->GetPosition(HULL_HUMAN));
}
bStuck = false;
}
return true;
}
示例5: AddHorde
//=========================================================
// Crea un bonche de hijos en un nodo candidato.
//=========================================================
void CDirector_Manager::AddHorde(int pMount)
{
// Actualizamos los nodos candidatos para la creación.
UpdateNodes();
// ¡No hay nodos!
if ( SpawnNodes.Count() <= 0 )
return;
for ( int i = 0; i < MAX_TRIES; ++i )
{
// Seleccionamos un nodo candidato al azar.
CAI_Node *pNode = GetRandomNode();
// El nodo no existe.
if ( !pNode )
continue;
// Obtenemos la ubicación del nodo.
Vector vecOrigin = pNode->GetPosition(HULL_HUMAN);
ConVarRef director_debug("director_debug");
if ( director_debug.GetBool() )
NDebugOverlay::Cross3D(vecOrigin, 50.0f, 255, 128, 0, true, 20.0f);
// Creamos varios hijos en este nodo.
// Con las colisiones especiales (No colisionan con los otros hijos)
for ( int h = 0; h < pMount; ++h )
{
for ( int s = 0; s < MAX_TRIES; ++s )
{
bool pSpawn = AddChild(vecOrigin, SPAWN_NO_COLLISION_AND_POWERFUL);
if ( pSpawn )
break;
}
}
break;
}
}
示例6: GetPrepareToAttackPath
bool CAI_ASW_PrepareToEngageBehavior::GetPrepareToAttackPath(const Vector &vecThreat )
{
if ( !CAI_NetworkManager::NetworksLoaded() )
{
DevWarning( 2, "Graph not ready for GetPrepareToAttackPath!\n" );
return false;
}
Vector vecToThreat = vecThreat - GetAbsOrigin();
float flDistToThreat = vecToThreat.NormalizeInPlace();
/*
int iMyNode = GetOuter()->GetPathfinder()->NearestNodeToNPC();
int iThreatNode = GetOuter()->GetPathfinder()->NearestNodeToPoint( vecThreat );
if ( iMyNode == NO_NODE )
{
DevWarning( 2, "FindPrepareToAttackNode() - %s has no nearest node!\n", GetEntClassname());
return false;
}
if ( iThreatNode == NO_NODE )
{
// DevWarning( 2, "FindBackAwayNode() - Threat has no nearest node!\n" );
iThreatNode = iMyNode;
// return false;
}
// A vector pointing to the threat.
Vector vecToThreat;
vecToThreat = vecThreat - GetLocalOrigin();
// Get my current distance from the threat
float flCurDist = VectorNormalize( vecToThreat );
// find all nodes within the radius of our target
m_flPrepareRadius;
*/
int iNumNodes = g_pBigAINet->NumNodes();
CUtlVector<int> candidateNodes;
for ( int i = 0; i < iNumNodes; i++ )
{
CAI_Node *pNode = g_pBigAINet->GetNode( i );
if ( !pNode || pNode->GetType() != NODE_GROUND )
continue;
Vector vecPos = pNode->GetPosition( GetOuter()->GetHullType() );
Vector vecDir = vecPos - vecThreat;
float flDist = vecDir.NormalizeInPlace();
if ( flDist > m_flPrepareRadiusMax || flDist < m_flPrepareRadiusMin )
continue;
// Make sure this node doesn't take me past the enemy's position.
Vector vecToNode = vecPos - GetAbsOrigin();
float flDistToNode = vecToNode.NormalizeInPlace();
if( DotProduct( vecToNode, vecToThreat ) > 0.0 && flDistToNode > flDistToThreat )
continue;
candidateNodes.AddToTail( i );
}
if ( candidateNodes.Count() <= 0 )
return false;
int iOffset = RandomInt( 0, candidateNodes.Count() - 1 );
int iNumCandidateNodes = candidateNodes.Count();
int iMaxTries = 4;
for ( int i = 0; i < iNumCandidateNodes && iMaxTries > 0; i++ )
{
CAI_Node *pNode = g_pBigAINet->GetNode( candidateNodes[ i + iOffset ] );
if ( !pNode || pNode->GetType() != NODE_GROUND )
continue;
// see if we can reach it
Vector vecPos = pNode->GetPosition( GetOuter()->GetHullType() );
AI_NavGoal_t goal( vecPos );
if ( GetNavigator()->SetGoal( goal, AIN_CLEAR_TARGET ) )
{
return true;
}
iMaxTries--;
}
return false;
}
示例7: GetNetwork
AI_Waypoint_t *CAI_Pathfinder::FindBestPath(int startID, int endID)
{
if ( !GetNetwork()->NumNodes() )
return NULL;
int nNodes = GetNetwork()->NumNodes();
CAI_Node **pAInode = GetNetwork()->AccessNodes();
CVarBitVec openBS(nNodes);
CVarBitVec closeBS(nNodes);
// ------------- INITIALIZE ------------------------
float* nodeG = (float *)stackalloc( nNodes * sizeof(float) );
float* nodeH = (float *)stackalloc( nNodes * sizeof(float) );
float* nodeF = (float *)stackalloc( nNodes * sizeof(float) );
int* nodeP = (int *)stackalloc( nNodes * sizeof(int) ); // Node parent
for (int node=0;node<nNodes;node++)
{
nodeG[node] = FLT_MAX;
nodeP[node] = -1;
}
nodeG[startID] = 0;
nodeH[startID] = 0.1*(pAInode[startID]->GetPosition(GetHullType())-pAInode[endID]->GetPosition(GetHullType())).Length(); // Don't want to over estimate
nodeF[startID] = nodeG[startID] + nodeH[startID];
openBS.Set(startID);
closeBS.Set( startID );
// --------------- FIND BEST PATH ------------------
while (!openBS.IsAllClear())
{
int smallestID = CAI_Network::FindBSSmallest(&openBS,nodeF,nNodes);
openBS.Clear(smallestID);
CAI_Node *pSmallestNode = pAInode[smallestID];
if (GetOuter()->IsUnusableNode(smallestID, pSmallestNode->m_pHint))
continue;
if (smallestID == endID)
{
AI_Waypoint_t* route = MakeRouteFromParents(&nodeP[0], endID);
return route;
}
// Check this if the node is immediately in the path after the startNode
// that it isn't blocked
for (int link=0; link < pSmallestNode->NumLinks();link++)
{
CAI_Link *nodeLink = pSmallestNode->GetLinkByIndex(link);
if (!IsLinkUsable(nodeLink,smallestID))
continue;
// FIXME: the cost function should take into account Node costs (danger, flanking, etc).
int moveType = nodeLink->m_iAcceptedMoveTypes[GetHullType()] & CapabilitiesGet();
int testID = nodeLink->DestNodeID(smallestID);
Vector r1 = pSmallestNode->GetPosition(GetHullType());
Vector r2 = pAInode[testID]->GetPosition(GetHullType());
float dist = GetOuter()->GetNavigator()->MovementCost( moveType, r1, r2 ); // MovementCost takes ref parameters!!
if ( dist == FLT_MAX )
continue;
float new_g = nodeG[smallestID] + dist;
if ( !closeBS.IsBitSet(testID) || (new_g < nodeG[testID]) )
{
nodeP[testID] = smallestID;
nodeG[testID] = new_g;
nodeH[testID] = (pAInode[testID]->GetPosition(GetHullType())-pAInode[endID]->GetPosition(GetHullType())).Length();
nodeF[testID] = nodeG[testID] + nodeH[testID];
closeBS.Set( testID );
openBS.Set( testID );
}
}
}
return NULL;
}
示例8: FindCoverNode
int CAI_TacticalServices::FindCoverNode(const Vector &vNearPos, const Vector &vThreatPos, const Vector &vThreatEyePos, float flMinDist, float flMaxDist )
{
if ( !CAI_NetworkManager::NetworksLoaded() )
return NO_NODE;
AI_PROFILE_SCOPE( CAI_TacticalServices_FindCoverNode );
MARK_TASK_EXPENSIVE();
DebugFindCover( NO_NODE, GetOuter()->EyePosition(), vThreatEyePos, 0, 255, 255 );
int iMyNode = GetPathfinder()->NearestNodeToPoint( vNearPos );
if ( iMyNode == NO_NODE )
{
Vector pos = GetOuter()->GetAbsOrigin();
DevWarning( 2, "FindCover() - %s has no nearest node! (Check near %f %f %f)\n", GetEntClassname(), pos.x, pos.y, pos.z);
return NO_NODE;
}
if ( !flMaxDist )
{
// user didn't supply a MaxDist, so work up a crazy one.
flMaxDist = 784;
}
if ( flMinDist > 0.5 * flMaxDist)
{
flMinDist = 0.5 * flMaxDist;
}
// ------------------------------------------------------------------------------------
// We're going to search for a cover node by expanding to our current node's neighbors
// and then their neighbors, until cover is found, or all nodes are beyond MaxDist
// ------------------------------------------------------------------------------------
AI_NearNode_t *pBuffer = (AI_NearNode_t *)stackalloc( sizeof(AI_NearNode_t) * GetNetwork()->NumNodes() );
CNodeList list( pBuffer, GetNetwork()->NumNodes() );
CVarBitVec wasVisited(GetNetwork()->NumNodes()); // Nodes visited
// mark start as visited
list.Insert( AI_NearNode_t(iMyNode, 0) );
wasVisited.Set( iMyNode );
float flMinDistSqr = flMinDist*flMinDist;
float flMaxDistSqr = flMaxDist*flMaxDist;
static int nSearchRandomizer = 0; // tries to ensure the links are searched in a different order each time;
// Search until the list is empty
while( list.Count() )
{
// Get the node that is closest in the number of steps and remove from the list
int nodeIndex = list.ElementAtHead().nodeIndex;
list.RemoveAtHead();
CAI_Node *pNode = GetNetwork()->GetNode(nodeIndex);
Vector nodeOrigin = pNode->GetPosition(GetHullType());
float dist = (vNearPos - nodeOrigin).LengthSqr();
if (dist >= flMinDistSqr && dist < flMaxDistSqr)
{
Activity nCoverActivity = GetOuter()->GetCoverActivity( pNode->GetHint() );
Vector vEyePos = nodeOrigin + GetOuter()->EyeOffset(nCoverActivity);
if ( GetOuter()->IsValidCover( nodeOrigin, pNode->GetHint() ) )
{
// Check if this location will block the threat's line of sight to me
if (GetOuter()->IsCoverPosition(vThreatEyePos, vEyePos))
{
// --------------------------------------------------------
// Don't let anyone else use this node for a while
// --------------------------------------------------------
pNode->Lock( 1.0 );
if ( pNode->GetHint() && ( pNode->GetHint()->HintType() == HINT_TACTICAL_COVER_MED || pNode->GetHint()->HintType() == HINT_TACTICAL_COVER_LOW ) )
{
if ( GetOuter()->GetHintNode() )
{
GetOuter()->GetHintNode()->Unlock(GetOuter()->GetHintDelay(GetOuter()->GetHintNode()->HintType()));
GetOuter()->SetHintNode( NULL );
}
GetOuter()->SetHintNode( pNode->GetHint() );
}
// The next NPC who searches should use a slight different pattern
nSearchRandomizer = nodeIndex;
DebugFindCover( pNode->GetId(), vEyePos, vThreatEyePos, 0, 255, 0 );
return nodeIndex;
}
else
{
DebugFindCover( pNode->GetId(), vEyePos, vThreatEyePos, 255, 0, 0 );
}
}
else
{
DebugFindCover( pNode->GetId(), vEyePos, vThreatEyePos, 0, 0, 255 );
}
}
//.........这里部分代码省略.........
示例9: FindHordePosition
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;
}
示例10: UpdateCandidateNodes
void CASW_Spawn_Manager::UpdateCandidateNodes()
{
// don't update too frequently
if ( m_CandidateUpdateTimer.HasStarted() && !m_CandidateUpdateTimer.IsElapsed() )
return;
m_CandidateUpdateTimer.Start( asw_candidate_interval.GetFloat() );
if ( !GetNetwork() || !GetNetwork()->NumNodes() )
{
m_vecHordePosition = vec3_origin;
if ( asw_director_debug.GetBool() )
Msg("Error: Can't spawn hordes as this map has no node network\n");
return;
}
CASW_Game_Resource *pGameResource = ASWGameResource();
if ( !pGameResource )
return;
Vector vecSouthMarine = vec3_origin;
Vector vecNorthMarine = vec3_origin;
for ( int i=0; i<pGameResource->GetMaxMarineResources(); i++ )
{
CASW_Marine_Resource *pMR = pGameResource->GetMarineResource(i);
if ( !pMR )
continue;
CASW_Marine *pMarine = pMR->GetMarineEntity();
if ( !pMarine || pMarine->GetHealth() <= 0 )
continue;
if ( vecSouthMarine == vec3_origin || vecSouthMarine.y > pMarine->GetAbsOrigin().y )
{
vecSouthMarine = pMarine->GetAbsOrigin();
}
if ( vecNorthMarine == vec3_origin || vecNorthMarine.y < pMarine->GetAbsOrigin().y )
{
vecNorthMarine = pMarine->GetAbsOrigin();
}
}
if ( vecSouthMarine == vec3_origin || vecNorthMarine == vec3_origin ) // no live marines
return;
int iNumNodes = GetNetwork()->NumNodes();
m_northCandidateNodes.Purge();
m_southCandidateNodes.Purge();
for ( int i=0 ; i<iNumNodes; i++ )
{
CAI_Node *pNode = GetNetwork()->GetNode( i );
if ( !pNode || pNode->GetType() != NODE_GROUND )
continue;
Vector vecPos = pNode->GetPosition( CANDIDATE_ALIEN_HULL );
// find the nearest marine to this node
float flDistance = 0;
CASW_Marine *pMarine = dynamic_cast<CASW_Marine*>(UTIL_ASW_NearestMarine( vecPos, flDistance ));
if ( !pMarine )
return;
if ( flDistance > asw_horde_max_distance.GetFloat() || flDistance < asw_horde_min_distance.GetFloat() )
continue;
// check node isn't in an exit trigger
bool bInsideEscapeArea = false;
for ( int d=0; d<m_EscapeTriggers.Count(); d++ )
{
if ( m_EscapeTriggers[d]->CollisionProp()->IsPointInBounds( vecPos ) )
{
bInsideEscapeArea = true;
break;
}
}
if ( bInsideEscapeArea )
continue;
if ( vecPos.y >= vecSouthMarine.y )
{
if ( asw_director_debug.GetInt() == 3 )
{
NDebugOverlay::Box( vecPos, -Vector( 5, 5, 5 ), Vector( 5, 5, 5 ), 32, 32, 128, 10, 60.0f );
}
m_northCandidateNodes.AddToTail( i );
}
if ( vecPos.y <= vecNorthMarine.y )
{
m_southCandidateNodes.AddToTail( i );
if ( asw_director_debug.GetInt() == 3 )
{
NDebugOverlay::Box( vecPos, -Vector( 5, 5, 5 ), Vector( 5, 5, 5 ), 128, 32, 32, 10, 60.0f );
}
}
}
}
示例11: SpawnAlientAtRandomNode
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;
//.........这里部分代码省略.........
示例12: UpdateNodes
//=========================================================
// Actualiza los mejores nodos para la creación de hijos.
//=========================================================
void CDirector_Manager::UpdateNodes()
{
// Aún no toca actualizar.
if ( CandidateUpdateTimer.HasStarted() && !CandidateUpdateTimer.IsElapsed() )
return;
// Empezar el cronometro.
CandidateUpdateTimer.Start(director_update_nodes.GetFloat());
// ¡Este mapa no tiene nodos!
if ( !GetNetwork() || !GetNetwork()->NumNodes() )
{
ClientPrint(UTIL_InPlayerByIndex(1), HUD_PRINTCENTER, "#NoNODES");
Warning("[NODOS] Este mapa no tiene nodos de movimiento.\r\n");
return;
}
int iNumNodes = GetNetwork()->NumNodes();
SpawnNodes.Purge(); // Limpiamos la lista de nodos.
// Revisamos cada nodo.
for ( int i = 0; i < iNumNodes; ++i )
{
CAI_Node *pNode = GetNetwork()->GetNode(i);
// El nodo ya no existe o no es de suelo.
if ( !pNode || pNode->GetType() != NODE_GROUND )
continue;
// Buscar al jugador más cercano.
float flDistance = 0;
Vector vecPos = pNode->GetPosition(HULL_HUMAN);
CIN_Player *pPlayer = UTIL_GetNearestInPlayer(vecPos, flDistance);
// ¡Ninguno!
if ( !pPlayer )
return;
ConVarRef director_debug("director_debug");
ConVarRef director_min_distance("director_min_distance");
ConVarRef director_max_distance("director_max_distance");
ConVarRef director_spawn_outview("director_spawn_outview");
CBaseEntity *pChild = gEntList.FindEntityByNameNearest(CHILD_NAME, vecPos, 20);
CBaseEntity *pSpawn = gEntList.FindEntityByClassname(NULL, "info_player_start");
if ( pSpawn )
{
float spawnDistance = vecPos.DistTo(pSpawn->GetAbsOrigin());
// Este nodo esta muy cerca del Spawn.
if ( spawnDistance < SPAWN_OUT_DISTANCE )
continue;
}
// Hay un hijo aquí.
if ( pChild )
continue;
// Este nodo esta muy lejos o muy cerca.
if ( flDistance > director_max_distance.GetFloat() || flDistance < director_min_distance.GetFloat() )
continue;
// No usar nodos que esten a la vista de los jugadores.
if ( director_spawn_outview.GetBool() )
{
if ( UTIL_IsPlayersVisible(vecPos) )
continue;
}
// Marcamos al nodo afortunado.
if ( director_debug.GetBool() )
NDebugOverlay::Box(vecPos, -Vector(5, 5, 5), Vector(5, 5, 5), 32, 32, 128, 10, 6.0f);
// Lo agregamos a la lista.
SpawnNodes.AddToTail(i);
}
}
示例13: SpawnAlientAtRandomNode
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;
}