//========================================================= // 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; } }
//========================================================= // 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; }
void CRoutingZone::GetBootstrapNodes(const CUInt128& uTargetID, NodeMap& results, uint32 uDesiredCount, CSafeAddress::EProtocol eProtocol, int iMaxState) { while(uDesiredCount-->0) { if(CKadNode* pNode = GetRandomNode(eProtocol)) results[uTargetID ^ pNode->GetID()] = pNode; } }
//========================================================= // 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; }
//========================================================= // 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; } }