//=========================================================
// Verifica las condiciones y devuelve si es
// conveniente/posible crear un NPC en las coordenadas.
//=========================================================
bool CSurvivalZombieSpawn::CanMakeNPC(CAI_BaseNPC *pNPC, Vector *pResult)
{
	// Desactivado
	if ( Disabled || !sv_spawn_zombies.GetBool() )
	{
		UTIL_RemoveImmediate(pNPC);
		return false;
	}

	Vector origin;
	
	// Verificamos si es posible crear el NPC en el radio especificado.
	if ( !CAI_BaseNPC::FindSpotForNPCInRadius(&origin, GetAbsOrigin(), pNPC, SpawnRadius, true) )
	{
		if ( !CAI_BaseNPC::FindSpotForNPCInRadius(&origin, GetAbsOrigin(), pNPC, SpawnRadius, false) )
		{
			DevWarning("[SURVIVAL ZOMBIE MAKER] No se encontro un lugar valido para crear un zombie. \r\n");

			UTIL_RemoveImmediate(pNPC);
			return false;
		}
	}

	// Crear en la misma altura que el spawn (Y así evitamos que se cree por debajo del suelo)
	origin.z = GetAbsOrigin().z;

	*pResult = origin;
	return true;
}
//=========================================================
// Guardar los objetos necesarios en caché.
//=========================================================
void CDirectorSpawn::Precache()
{
	BaseClass::Precache();

	// NPC's
	int pNpcs = ARRAYSIZE(iNpcs) - 1;
	for ( int i = 0; i < pNpcs; ++i )
	{
		if ( iNpcs[i] == NULL_STRING )
			continue;

		// Buscamos si hay una plantilla con este nombre.
		string_t NpcData = Templates_FindByTargetName(STRING(iNpcs[i]));
			
		// No, se trata de una clase.
		if ( NpcData == NULL_STRING )
			UTIL_PrecacheOther(STRING(iNpcs[i]));
		else
		{
			// Guardamos en caché la plantilla.
			CBaseEntity *pEntity = NULL;
			MapEntity_ParseEntity(pEntity, STRING(NpcData), NULL);

			if ( pEntity != NULL )
			{
				pEntity->Precache();
				UTIL_RemoveImmediate(pEntity);
			}
		}
	}

	// JEFES
	int pBoss = ARRAYSIZE(iBoss) - 1;
	for ( int i = 0; i < pBoss; ++i )
	{
		if ( iBoss[i] == NULL_STRING )
			continue;

		// Buscamos si hay una plantilla con este nombre.
		string_t NpcData = Templates_FindByTargetName(STRING(iBoss[i]));
			
		// No, se trata de una clase.
		if ( NpcData == NULL_STRING )
			UTIL_PrecacheOther(STRING(iBoss[i]));
		else
		{
			// Guardamos en caché la plantilla.
			CBaseEntity *pEntity = NULL;
			MapEntity_ParseEntity(pEntity, STRING(NpcData), NULL);

			if ( pEntity != NULL )
			{
				pEntity->Precache();
				UTIL_RemoveImmediate(pEntity);
			}
		}
	}
}
//=========================================================
// 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;
}
示例#4
0
文件: util.cpp 项目: kila58/sourceop
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *szClassname - 
//			*modelName - 
//-----------------------------------------------------------------------------
void UTIL_PrecacheOther( const char *szClassname, const char *modelName )
{
#if defined( PRECACHE_OTHER_ONCE )
    // already done this one?, if not, mark as done
    if ( !g_PrecacheOtherList.AddOrMarkPrecached( szClassname ) )
        return;
#endif

    CBaseEntity	*pEntity = CreateEntityByName( szClassname );
    if ( !pEntity )
    {
        Warning( "NULL Ent in UTIL_PrecacheOther for %s\n", szClassname );
        return;
    }

    // If we have a specified model, set it before calling precache
    if ( modelName && modelName[0] )
    {
        VFuncs::SetModelName(pEntity, AllocPooledString( modelName ) );
    }
    
    if (pEntity)
        VFuncs::Precache( pEntity );

    UTIL_RemoveImmediate( pEntity );
}
void CHL2MP_Player::CreateRagdollEntity( void )
{
	if ( m_hRagdoll )
	{
		UTIL_RemoveImmediate( m_hRagdoll );
		m_hRagdoll = NULL;
	}

	// If we already have a ragdoll, don't make another one.
	CHL2MPRagdoll *pRagdoll = dynamic_cast< CHL2MPRagdoll* >( m_hRagdoll.Get() );
	
	if ( !pRagdoll )
	{
		// create a new one
		pRagdoll = dynamic_cast< CHL2MPRagdoll* >( CreateEntityByName( "hl2mp_ragdoll" ) );
	}

	if ( pRagdoll )
	{
		pRagdoll->m_hPlayer = this;
		pRagdoll->m_vecRagdollOrigin = GetAbsOrigin();
		pRagdoll->m_vecRagdollVelocity = GetAbsVelocity();
		pRagdoll->m_nModelIndex = m_nModelIndex;
		pRagdoll->m_nForceBone = m_nForceBone;
		pRagdoll->m_vecForce = m_vecTotalBulletForce;
		pRagdoll->SetAbsOrigin( GetAbsOrigin() );
	}

	// ragdolls will be removed on round restart automatically
	m_hRagdoll = pRagdoll;
}
示例#6
0
void Test_SpawnRandomEntities( const CCommand &args )
{
	if ( args.ArgC() < 3 )
	{
		Error( "Test_SpawnRandomEntities <min # entities> <max # entities> missing arguments." );
	}

	if ( g_StressEntities.Count() == 0 )
	{
		Error( "Test_SpawnRandomEntities: not initialized (call Test_InitRandomEntitySpawner frst)." );
	} 

	int nMin = atoi( args[ 1 ] );
	int nMax = atoi( args[ 2 ] );
	int count = RandomInt( nMin, nMax );

	for ( int i=0; i < count; i++ )
	{
		int iSlot = RandomInt( 0, g_StressEntities.Count() - 1 );

		// Remove any old entity in this slot.
		if ( g_StressEntities[iSlot].Get() )
			UTIL_RemoveImmediate( g_StressEntities[iSlot] );

		// Create a new one in this slot.
		int iType = RandomInt( 0, g_StressEntityRegs.Count() - 1 );
		g_StressEntities[iSlot] = g_StressEntityRegs[iType]->GetFn()();
	}
}
示例#7
0
void CWorldItem::Spawn( void )
{
	CBaseEntity *pEntity = NULL;

	switch (m_iType) 
	{
	case 44: // ITEM_BATTERY:
		pEntity = CBaseEntity::Create( "item_battery", GetLocalOrigin(), GetLocalAngles() );
		break;
	case 45: // ITEM_SUIT:
		pEntity = CBaseEntity::Create( "item_suit", GetLocalOrigin(), GetLocalAngles() );
		break;
	}

	if (!pEntity)
	{
		Warning("unable to create world_item %d\n", m_iType );
	}
	else
	{
		pEntity->m_target = m_target;
		pEntity->SetName( GetEntityName() );
		pEntity->ClearSpawnFlags();
		pEntity->AddSpawnFlags( m_spawnflags );
	}

	UTIL_RemoveImmediate( this );
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *pChild - 
//-----------------------------------------------------------------------------
void CBaseNPCMaker::ChildPostSpawn( CAI_BaseNPC *pChild )
{
	// If I'm stuck inside any props, remove them
	bool bFound = true;
	while ( bFound )
	{
		trace_t tr;
		UTIL_TraceHull( pChild->GetAbsOrigin(), pChild->GetAbsOrigin(), pChild->WorldAlignMins(), pChild->WorldAlignMaxs(), MASK_NPCSOLID, pChild, COLLISION_GROUP_NONE, &tr );
		//NDebugOverlay::Box( pChild->GetAbsOrigin(), pChild->WorldAlignMins(), pChild->WorldAlignMaxs(), 0, 255, 0, 32, 5.0 );
		if ( tr.fraction != 1.0 && tr.m_pEnt )
		{
			if ( FClassnameIs( tr.m_pEnt, "prop_physics" ) )
			{
				// Set to non-solid so this loop doesn't keep finding it
				tr.m_pEnt->AddSolidFlags( FSOLID_NOT_SOLID );
				UTIL_RemoveImmediate( tr.m_pEnt );
				continue;
			}
		}

		bFound = false;
	}
	if ( m_hIgnoreEntity != NULL )
	{
		pChild->SetOwnerEntity( m_hIgnoreEntity );
	}
}
示例#9
0
void CASW_Base_Spawner::RemoveObstructingProps( CBaseEntity *pChild )
{
	// If I'm stuck inside any props, remove them
	bool bFound = true;
	while ( bFound )
	{
		trace_t tr;
		UTIL_TraceHull( pChild->GetAbsOrigin(), pChild->GetAbsOrigin(), pChild->WorldAlignMins(), pChild->WorldAlignMaxs(), MASK_NPCSOLID, pChild, COLLISION_GROUP_NONE, &tr );
		if (asw_debug_spawners.GetBool())
		{
			NDebugOverlay::Box( pChild->GetAbsOrigin(), pChild->WorldAlignMins(), pChild->WorldAlignMaxs(), 0, 255, 0, 32, 5.0 );
		}
		if ( tr.fraction != 1.0 && tr.m_pEnt )
		{
			if ( dynamic_cast<CBaseProp*>(tr.m_pEnt) )
			{
				// Set to non-solid so this loop doesn't keep finding it
				tr.m_pEnt->AddSolidFlags( FSOLID_NOT_SOLID );
				UTIL_RemoveImmediate( tr.m_pEnt );
				continue;
			}
		}

		bFound = false;
	}
}
//-----------------------------------------------------------------------------
// Purpose: Get the test hull (create if none)
// Input  :
// Output :
//-----------------------------------------------------------------------------
void CAI_TestHull::ReturnTestHull(void)
{
	CAI_TestHull::pTestHull->bInUse = false;
	CAI_TestHull::pTestHull->AddSolidFlags( FSOLID_NOT_SOLID );
	UTIL_SetSize(CAI_TestHull::pTestHull, vec3_origin, vec3_origin);

	UTIL_RemoveImmediate( pTestHull );
	pTestHull = NULL;
}
示例#11
0
void CASW_Marine_Hint_Ent::Spawn()
{
	Assert( MarineHintManager() );
	MarineHintManager()->AddHint( this );

	BaseClass::Spawn();

	UTIL_RemoveImmediate( this );
}
示例#12
0
//-----------------------------------------------------------------------------
// Purpose: Place NPC somewhere on the perimeter of my radius.
//-----------------------------------------------------------------------------
void CTemplateNPCMaker::MakeNPCInRadius( void )
{
	if ( !CanMakeNPC(true))
		return;

	CAI_BaseNPC	*pent = NULL;
	CBaseEntity *pEntity = NULL;
	MapEntity_ParseEntity( pEntity, STRING(m_iszTemplateData), NULL );
	if ( pEntity != NULL )
	{
		pent = (CAI_BaseNPC *)pEntity;
	}

	if ( !pent )
	{
		Warning("NULL Ent in NPCMaker!\n" );
		return;
	}
	
	if ( !PlaceNPCInRadius( pent ) )
	{
		// Failed to place the NPC. Abort
		UTIL_RemoveImmediate( pent );
		return;
	}

	m_OnSpawnNPC.Set( pEntity, pEntity, this );

	pent->AddSpawnFlags( SF_NPC_FALL_TO_GROUND );

	pent->RemoveSpawnFlags( SF_NPC_TEMPLATE );
	ChildPreSpawn( pent );

	DispatchSpawn( pent );

	pent->SetOwnerEntity( this );
	DispatchActivate( pent );

	ChildPostSpawn( pent );

	m_nLiveChildren++;// count this NPC

	if (!(m_spawnflags & SF_NPCMAKER_INF_CHILD))
	{
		m_nMaxNumNPCs--;

		if ( IsDepleted() )
		{
			m_OnAllSpawned.FireOutput( this, this );

			// Disable this forever.  Don't kill it because it still gets death notices
			SetThink( NULL );
			SetUse( NULL );
		}
	}
}
示例#13
0
void CHL2MP_Player::UpdateOnRemove( void )
{
	if ( m_hRagdoll )
	{
		UTIL_RemoveImmediate( m_hRagdoll );
		m_hRagdoll = NULL;
	}

	BaseClass::UpdateOnRemove();
}
示例#14
0
void FreeContainingEntity( edict_t *ed )
{
	if ( ed )
	{
		CBaseEntity *ent = GetContainingEntity( ed );
		if ( ent )
		{
			ed->SetEdict( NULL, false );
			CBaseEntity::PhysicsRemoveTouchedList( ent );
			CBaseEntity::PhysicsRemoveGroundList( ent );
			UTIL_RemoveImmediate( ent );
		}
	}
}
//=========================================================
// Verificaciones después de crear al NPC.
//=========================================================
bool CDirectorSpawn::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;
			}
		}

		bStuck = false;
	}

	return true;
}
void QUA_helicopter::CreateCorpse( )
{
	m_lifeState = LIFE_DEAD;

	for ( int i = 0; i < HELICOPTER_MAX_GIBS; ++i )
	{
		CPhysicsProp *pGib = assert_cast<CPhysicsProp*>(CreateEntityByName( "prop_physics_multiplayer" ));
		pGib->SetAbsOrigin( GetAbsOrigin() );
		pGib->SetAbsAngles( GetAbsAngles() );
		pGib->SetAbsVelocity( GetAbsVelocity() );
		pGib->SetModel( s_pGibModelName[i] );
		pGib->Spawn();
		pGib->SetMoveType( MOVETYPE_VPHYSICS );

		float flMass = pGib->GetMass();
		/*if ( flMass < 200 )
		{*/
			Vector vecVelocity;
			pGib->GetMassCenter( &vecVelocity );
			vecVelocity -= WorldSpaceCenter();
			vecVelocity.z = fabs(vecVelocity.z);
			VectorNormalize( vecVelocity );

			// Apply a force that would make a 100kg mass travel 150 - 300 m/s
			float flRandomVel = random->RandomFloat( 150, 300 );
			vecVelocity *= (100 * flRandomVel) / flMass;
			vecVelocity.z += 100.0f;
			AngularImpulse angImpulse = RandomAngularImpulse( -500, 500 );
			
			IPhysicsObject *pObj = pGib->VPhysicsGetObject();
			if ( pObj != NULL )
			{
				pObj->AddVelocity( &vecVelocity, &angImpulse );
			}
			pGib->SetCollisionGroup( COLLISION_GROUP_DEBRIS );
		/*}*/
		pGib->Ignite( 60, false );
		pGib->Dissolve( NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL );
	}

	AddSolidFlags( FSOLID_NOT_SOLID );
	AddEffects( EF_NODRAW );
	UTIL_RemoveImmediate( this );
}
示例#17
0
void CTemplateNPCMaker::Precache()
{
	BaseClass::Precache();

	if ( !m_iszTemplateData )
	{
		//
		// This must be the first time we're activated, not a load from save game.
		// Look up the template in the template database.
		//
		if (!m_iszTemplateName)
		{
			Warning( "npc_template_maker %s has no template NPC!\n", STRING(GetEntityName()) );
			UTIL_Remove( this );
			return;
		}
		else
		{
			m_iszTemplateData = Templates_FindByTargetName(STRING(m_iszTemplateName));
			if ( m_iszTemplateData == NULL_STRING )
			{
				DevWarning( "npc_template_maker %s: template NPC %s not found!\n", STRING(GetEntityName()), STRING(m_iszTemplateName) );
				UTIL_Remove( this );
				return;
			}
		}
	}

	Assert( m_iszTemplateData != NULL_STRING );

	// If the mapper marked this as "preload", then instance the entity preache stuff and delete the entity
	//if ( !HasSpawnFlags(SF_NPCMAKER_NOPRELOADMODELS) )
	if ( m_iszTemplateData != NULL_STRING )
	{
		CBaseEntity *pEntity = NULL;
		MapEntity_ParseEntity( pEntity, STRING(m_iszTemplateData), NULL );
		if ( pEntity != NULL )
		{
			PrecacheTemplateEntity( pEntity );
			UTIL_RemoveImmediate( pEntity );
		}
	}
}
示例#18
0
//-----------------------------------------------------------------------------
// Purpose: Spawn a player
//-----------------------------------------------------------------------------
bp::object PyRespawnPlayer( CBasePlayer *pPlayer, const char *classname )
{
	if( !pPlayer || !pPlayer->edict() )
	{
		PyErr_SetString(PyExc_ValueError, "Invalid player");
		throw boost::python::error_already_set(); 
		return bp::object();
	}

	if( !classname )
	{
		PyErr_SetString(PyExc_ValueError, "Invalid player class");
		throw boost::python::error_already_set(); 
		return bp::object();
	}

	// Save edict + player name
	edict_t *pEdict = pPlayer->edict();
	const char *playername = pPlayer->GetPlayerName();

	// Destroy the old player entity
	UTIL_RemoveImmediate( pPlayer );

	// Create a new player using the provided player class
	CBasePlayer *pPlayerNew = dynamic_cast<CBasePlayer *>(CBasePlayer::CreatePlayer( classname, pEdict ));
	if( !pPlayerNew )
	{
		PyErr_SetString(PyExc_ValueError, "Invalid player entity class");
		throw boost::python::error_already_set(); 
		return bp::object();
	}
	pPlayerNew->SetPlayerName( playername );

	pPlayerNew->InitialSpawn();
	pPlayerNew->Spawn();
	
	return pPlayerNew->GetPyHandle();
}
示例#19
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *pEntData - 
//-----------------------------------------------------------------------------
void MapEntity_PrecacheEntity( const char *pEntData, int &nStringSize )
{
	CEntityMapData entData( (char*)pEntData, nStringSize );
	char className[MAPKEY_MAXLENGTH];
	
	if (!entData.ExtractValue("classname", className))
	{
		Error( "classname missing from entity!\n" );
	}

	// Construct via the LINK_ENTITY_TO_CLASS factory.
	CBaseEntity *pEntity = CreateEntityByName(className);

	//
	// Set up keyvalues, which can set the model name, which is why we don't just do UTIL_PrecacheOther here...
	//
	if ( pEntity != NULL )
	{
		pEntity->ParseMapData(&entData);
		pEntity->Precache();
		UTIL_RemoveImmediate( pEntity );
	}
}
void CBaseNetworkedPlayer::RemoveRagdollEntity()
{
	if ( m_hRagdoll.Get() )
		UTIL_RemoveImmediate( m_hRagdoll.Get() );	
}
//=========================================================
// Verifica las condiciones y devuelve si es
// conveniente/posible crear un NPC en las coordenadas.
//=========================================================
bool CDirectorSpawn::CanMakeNPC(CAI_BaseNPC *pNPC, Vector *pResult)
{
	// Desactivado
	// Esta entidad no funciona en Multiplayer.
	if ( Disabled )
	{
		UTIL_RemoveImmediate(pNPC);
		return false;
	}

	Vector origin;
	ConVarRef director_force_spawn_outview("director_force_spawn_outview");
	
	// Verificamos si es posible crear el NPC en el radio especificado.
	if ( !CAI_BaseNPC::FindSpotForNPCInRadius(&origin, GetAbsOrigin(), pNPC, SpawnRadius, director_force_spawn_outview.GetBool()) )
	{
		if ( !CAI_BaseNPC::FindSpotForNPCInRadius(&origin, GetAbsOrigin(), pNPC, SpawnRadius, false) )
		{
			DevWarning("[DIRECTOR SPAWN] No se encontro un lugar valido para crear un NPC. \r\n");

			UTIL_RemoveImmediate(pNPC);
			return false;
		}
	}

	// Crear en la misma altura que el spawn (Y así evitamos que se cree por debajo del suelo)
	origin.z = GetAbsOrigin().z;

	// Si esta activado la opción de forzar la creación fuera de la visibilidad del usuario.
	// Hay que asegurarnos de que el usuario no esta viendo el lugar de creación...
	if ( director_force_spawn_outview.GetBool() )
	{
		CDirector *pDirector = GetDirector();

		if ( !pDirector )
			return false;

		// En Climax con que no lo vea directamente es suficiente...
		//if ( pDirector->GetStatus() == CLIMAX )
		//{
			if ( UTIL_IsPlayersVisible(origin) )
			{
				DevWarning("[DIRECTOR SPAWN] El lugar de creacion estaba en el campo de vision. \r\n");
				UTIL_RemoveImmediate(pNPC);

				return false;
			}
		//}

		// En cualquier otro modo no debe ser visible ni estar en el cono de visibilidad del jugador.
		/*else
		{
			if ( UTIL_IsPlayersVisibleCone(origin) )
			{
				Warning("[DIRECTOR SPAWN] El lugar de creacion estaba en el campo de vision. \r\n");
				UTIL_RemoveImmediate(pNPC);

				return false;
			}
		}*/
	}

	*pResult = origin;
	return true;
}
void CServerTools::RemoveEntityImmediate( CBaseEntity *pEntity )
{
	UTIL_RemoveImmediate( pEntity );
}
//=========================================================
//=========================================================
void CNodeEnt::Spawn( void )
{
	// ---------------------------------------------------------------------------------
	//  If just a hint node (not used for navigation) just create a hint and bail
	// ---------------------------------------------------------------------------------
	if (FClassnameIs( this, "info_hint" ))
	{
		if (m_eHintType)
		{
			CAI_Hint::CreateHint(GetEntityName(),GetAbsOrigin(),(Hint_e)m_eHintType,NO_NODE,m_strGroup);
		}
		else
		{
			Msg("WARNING: Hint node with no hint type!\n");
		}
		UTIL_RemoveImmediate( this );
		return;
	}
	
	// ---------------------------------------------------------------------------------
	//  First check if this node has a hint.  If so create a hint entity
	// ---------------------------------------------------------------------------------
	CAI_Hint *pHint = NULL;
	if (m_eHintType || m_strGroup != NULL_STRING)
	{
		pHint = CAI_Hint::CreateHint(GetEntityName(),GetAbsOrigin(),(Hint_e)m_eHintType,m_nNodeCount,m_strGroup);
	}


	// ---------------------------------------------------------------------------------
	//  If we loaded from disk, we can discard all these node ents as soon as they spawn
	//  unless we are in WC edited mode
	// ---------------------------------------------------------------------------------
	if ( g_pAINetworkManager->NetworksLoaded() && !engine->IsInEditMode())
	{
		// If hint exists for this node, set it
		if (pHint)
		{
			CAI_Node *pNode = g_pBigAINet->GetNode(m_nNodeCount);
			if (pNode)
				pNode->SetHint( pHint );
			else
			{
				Msg("AI node graph corrupt\n");
			}
		}
		m_nNodeCount++;
		UTIL_RemoveImmediate( this );
		return;
	}	
	else
	{
		m_nNodeCount++;
	}

	// ---------------------------------------------------------------------------------
	//	Add a new node to the network
	// ---------------------------------------------------------------------------------
	// For now just using one big AI network
	CAI_Node *new_node = g_pBigAINet->AddNode( GetAbsOrigin(), GetAbsAngles().y );
	new_node->SetHint( pHint );

	// -------------------------------------------------------------------------
	//  Update table of how each WC id relates to each engine ID	
	// -------------------------------------------------------------------------
	if (g_pAINetworkManager->GetEditOps()->m_pNodeIndexTable)
	{
		g_pAINetworkManager->GetEditOps()->m_pNodeIndexTable[new_node->GetId()]	= m_nWCNodeID;
	}
	// Keep track of largest index used by WC
	if (g_pAINetworkManager->GetEditOps()->m_nNextWCIndex <= m_nWCNodeID)
	{
		g_pAINetworkManager->GetEditOps()->m_nNextWCIndex = m_nWCNodeID+1;
	}

	// -------------------------------------------------------------------------
	// If in WC edit mode:
	// 	Remember the original positions of the nodes before
	//	they drop so we can send the undropped positions to wc.
	// -------------------------------------------------------------------------
	if (engine->IsInEditMode())
	{
		if (g_pAINetworkManager->GetEditOps()->m_pWCPosition)
		{
			g_pAINetworkManager->GetEditOps()->m_pWCPosition[new_node->GetId()]		= new_node->GetOrigin();
		}
	}
	
	if (FClassnameIs( this, "info_node_air" ) || FClassnameIs( this, "info_node_air_hint" ))
	{
		new_node->SetType( NODE_AIR );
	}
	else if (FClassnameIs( this, "info_node_climb" ))
	{
		new_node->SetType( NODE_CLIMB );
	}
	else
	{
		new_node->SetType( NODE_GROUND );
	}

	// If changed as part of WC editing process note that network must be rebuilt
	if (m_debugOverlays & OVERLAY_WC_CHANGE_ENTITY)
	{
		g_pAINetworkManager->GetEditOps()->SetRebuildFlags();
		new_node->m_eNodeInfo			|= bits_NODE_WC_CHANGED;

		// Initialize the new nodes position.  The graph may not be rebuild
		// right away but the node should at least be positioned correctly
		g_AINetworkBuilder.InitNodePosition( g_pBigAINet, new_node );
	}

	UTIL_RemoveImmediate( this );
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *pMapData - 
//-----------------------------------------------------------------------------
int CNodeEnt::Spawn( const char *pMapData )
{
	m_NodeData.strEntityName = GetEntityName();
	m_NodeData.vecPosition = GetAbsOrigin();
	m_NodeData.nNodeID = NO_NODE;
	if ( m_NodeData.minState == NPC_STATE_NONE )
		m_NodeData.minState = NPC_STATE_IDLE;
	if ( m_NodeData.maxState == NPC_STATE_NONE )
		m_NodeData.maxState = NPC_STATE_COMBAT;
	// ---------------------------------------------------------------------------------
	//  If just a hint node (not used for navigation) just create a hint and bail
	// ---------------------------------------------------------------------------------
	if (FClassnameIs( this, "info_hint" ))
	{
		if (m_NodeData.nHintType)
		{
			CAI_HintManager::CreateHint( &m_NodeData, pMapData );
		}
		else
		{
			Warning("info_hint (HammerID: %d, position (%.2f, %.2f, %.2f)) with no hint type.\n", m_NodeData.nWCNodeID, m_NodeData.vecPosition.x, m_NodeData.vecPosition.y, m_NodeData.vecPosition.z );
		}
		UTIL_RemoveImmediate( this );
		return -1;
	}
	
	// ---------------------------------------------------------------------------------
	//  First check if this node has a hint.  If so create a hint entity
	// ---------------------------------------------------------------------------------
	CAI_Hint *pHint = NULL;

	if ( ClassMatches( "info_node_hint" ) || ClassMatches( "info_node_air_hint" ) )
	{
		if ( m_NodeData.nHintType || m_NodeData.strGroup != NULL_STRING || m_NodeData.strEntityName != NULL_STRING )
		{
			m_NodeData.nNodeID = m_nNodeCount;
			pHint = CAI_HintManager::CreateHint( &m_NodeData, pMapData );
			pHint->AddSpawnFlags( GetSpawnFlags() );
		}
	}


	// ---------------------------------------------------------------------------------
	//  If we loaded from disk, we can discard all these node ents as soon as they spawn
	//  unless we are in WC edited mode
	// ---------------------------------------------------------------------------------
	if ( g_pAINetworkManager->NetworksLoaded() && !engine->IsInEditMode())
	{
		// If hint exists for this node, set it
		if (pHint)
		{
			CAI_Node *pNode = g_pBigAINet->GetNode(m_nNodeCount);
			if (pNode)
				pNode->SetHint( pHint );
			else
			{
				DevMsg("AI node graph corrupt\n");
			}
		}
		m_nNodeCount++;
		UTIL_RemoveImmediate( this );
		return -1;
	}	
	else
	{
		m_nNodeCount++;
	}

	// ---------------------------------------------------------------------------------
	//	Add a new node to the network
	// ---------------------------------------------------------------------------------
	// For now just using one big AI network
	CAI_Node *new_node = g_pBigAINet->AddNode( GetAbsOrigin(), GetAbsAngles().y );
	new_node->SetHint( pHint );

	// -------------------------------------------------------------------------
	//  Update table of how each WC id relates to each engine ID	
	// -------------------------------------------------------------------------
	if (g_pAINetworkManager->GetEditOps()->m_pNodeIndexTable)
	{
		g_pAINetworkManager->GetEditOps()->m_pNodeIndexTable[new_node->GetId()]	= m_NodeData.nWCNodeID;
	}
	// Keep track of largest index used by WC
	if (g_pAINetworkManager->GetEditOps()->m_nNextWCIndex <= m_NodeData.nWCNodeID)
	{
		g_pAINetworkManager->GetEditOps()->m_nNextWCIndex = m_NodeData.nWCNodeID+1;
	}

	// -------------------------------------------------------------------------
	// If in WC edit mode:
	// 	Remember the original positions of the nodes before
	//	they drop so we can send the undropped positions to wc.
	// -------------------------------------------------------------------------
	if (engine->IsInEditMode())
	{
		if (g_pAINetworkManager->GetEditOps()->m_pWCPosition)
		{
			g_pAINetworkManager->GetEditOps()->m_pWCPosition[new_node->GetId()]		= new_node->GetOrigin();
		}
	}
	
	if (FClassnameIs( this, "info_node_air" ) || FClassnameIs( this, "info_node_air_hint" ))
	{
		new_node->SetType( NODE_AIR );
	}
	else if (FClassnameIs( this, "info_node_climb" ))
	{
		new_node->SetType( NODE_CLIMB );
	}
	else
	{
		new_node->SetType( NODE_GROUND );
	}

	new_node->m_eNodeInfo = ( m_spawnflags << NODE_ENT_FLAGS_SHIFT );

	// If changed as part of WC editing process note that network must be rebuilt
	if (m_debugOverlays & OVERLAY_WC_CHANGE_ENTITY)
	{
		g_pAINetworkManager->GetEditOps()->SetRebuildFlags();
		new_node->m_eNodeInfo			|= bits_NODE_WC_CHANGED;

		// Initialize the new nodes position.  The graph may not be rebuild
		// right away but the node should at least be positioned correctly
		g_AINetworkBuilder.InitNodePosition( g_pBigAINet, new_node );
	}

	UTIL_RemoveImmediate( this );

	return -1;
}
示例#25
0
//------------------------------------------------------------------------------
// Purpose : Initializes src and dest IDs for all dynamic links
//			 	
// Input   :
// Output  :
//------------------------------------------------------------------------------
void CAI_DynamicLink::InitDynamicLinks(void)
{
	if (!g_pAINetworkManager->GetEditOps()->m_pNodeIndexTable)
	{
		Warning("ERROR: Trying initialize links with no WC ID table!\n");
		return;
	}

	if ( gm_bInitialized )
		return;

	gm_bInitialized = true;

	bool bUpdateZones = false;

	GenerateControllerLinks();

	CAI_DynamicLink* pDynamicLink = CAI_DynamicLink::m_pAllDynamicLinks;

	while (pDynamicLink)
	{
		// -------------------------------------------------------------
		//  First convert this links WC IDs to engine IDs
		// -------------------------------------------------------------
		if ( !pDynamicLink->m_bFixedUpIds )
		{
			int	nSrcID = g_pAINetworkManager->GetEditOps()->GetNodeIdFromWCId( pDynamicLink->m_nSrcEditID );
			if (nSrcID == -1)
			{
				DevMsg( "ERROR: Dynamic link source WC node %d not found\n", pDynamicLink->m_nSrcEditID );
				nSrcID = NO_NODE;
			}

			int	nDestID = g_pAINetworkManager->GetEditOps()->GetNodeIdFromWCId( pDynamicLink->m_nDestEditID );
			if (nDestID == -1)
			{
				DevMsg( "ERROR: Dynamic link dest WC node %d not found\n", pDynamicLink->m_nDestEditID );
				nDestID = NO_NODE;
			}

			pDynamicLink->m_nSrcID  = nSrcID;
			pDynamicLink->m_nDestID  = nDestID;
			pDynamicLink->m_bFixedUpIds = true;
		}

		if ( pDynamicLink->m_nSrcID != NO_NODE && pDynamicLink->m_nDestID != NO_NODE )
		{
			if (  ( pDynamicLink->GetSpawnFlags() & bits_HULL_BITS_MASK ) != 0 )
			{
				CAI_Link *pLink = pDynamicLink->FindLink();
				if ( !pLink )
				{
					CAI_Node *pNode1, *pNode2;

					pNode1 = g_pBigAINet->GetNode( pDynamicLink->m_nSrcID );
					pNode2 = g_pBigAINet->GetNode( pDynamicLink->m_nDestID );

					if ( pNode1 && pNode2 )
					{
						pLink = g_pBigAINet->CreateLink( pDynamicLink->m_nSrcID, pDynamicLink->m_nDestID );
						if ( !pLink )
						{
							DevMsg( "Failed to create dynamic link (%d <--> %d)\n", pDynamicLink->m_nSrcEditID, pDynamicLink->m_nDestEditID );
						}
					}

				}

				if ( pLink )
				{
					bUpdateZones = true;

					int hullBits = ( pDynamicLink->GetSpawnFlags() & bits_HULL_BITS_MASK );
					for ( int i = 0; i < NUM_HULLS; i++ )
					{
						if ( hullBits & HullToBit( Hull_t(i) ) )
						{
							pLink->m_iAcceptedMoveTypes[i] = pDynamicLink->m_nLinkType;
						}
					}
				}
			}

			// Now set the link's state
			pDynamicLink->SetLinkState();

			// Go on to the next dynamic link
			pDynamicLink = pDynamicLink->m_pNextDynamicLink;
		}
		else
		{
			CAI_DynamicLink *pBadDynamicLink = pDynamicLink;

			// Go on to the next dynamic link
			pDynamicLink = pDynamicLink->m_pNextDynamicLink;

			UTIL_RemoveImmediate( pBadDynamicLink );
		}

	}

	if ( bUpdateZones )
	{
		g_AINetworkBuilder.InitZones( g_pBigAINet );
	}
}