//----------------------------------------------------------------------------- // Purpose: Looks up a template entity by name, returning the map data blob as // a null-terminated string containing key/value pairs. // NOTE: This can't handle multiple templates with the same targetname. //----------------------------------------------------------------------------- string_t Templates_FindByTargetName(const char *pszName) { int nCount = g_Templates.Count(); for (int i = 0; i < nCount; i++) { TemplateEntityData_t *pTemplate = g_Templates.Element(i); if ( !stricmp(pTemplate->pszName, pszName) ) return Templates_FindByIndex( i ); } return NULL_STRING; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CPointTemplate::PerformPrecache() { // Go through all our templated map data and precache all the entities in it int iTemplates = m_hTemplates.Count(); if ( !iTemplates ) { Msg("Precache called on a point_template that has no templates: %s\n", STRING(GetEntityName()) ); return; } // Tell the template system we're about to start a new template Templates_StartUniqueInstance(); //HierarchicalSpawn_t *pSpawnList = (HierarchicalSpawn_t*)stackalloc( iTemplates * sizeof(HierarchicalSpawn_t) ); int i; for ( i = 0; i < iTemplates; i++ ) { //CBaseEntity *pEntity = NULL; char *pMapData; int iTemplateIndex = m_hTemplates[i].iTemplateIndex; // Some templates have Entity I/O connecting the entities within the template. // Unique versions of these templates need to be created whenever they're instanced. int nStringSize; if ( AllowNameFixup() && Templates_IndexRequiresEntityIOFixup( iTemplateIndex ) ) { // This template requires instancing. // Create a new mapdata block and ask the template system to fill it in with // a unique version (with fixed Entity I/O connections). pMapData = Templates_GetEntityIOFixedMapData( iTemplateIndex ); } else { // Use the unmodified mapdata pMapData = (char*)STRING( Templates_FindByIndex( iTemplateIndex ) ); } nStringSize = Templates_GetStringSize( iTemplateIndex ); // Create the entity from the mapdata MapEntity_PrecacheEntity( pMapData, nStringSize ); } }
//----------------------------------------------------------------------------- // Purpose: Spawn the entities I contain // Input : &vecOrigin - // &vecAngles - // pEntities - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CPointTemplate::CreateInstance( const Vector &vecOrigin, const QAngle &vecAngles, CUtlVector<CBaseEntity*> *pEntities ) { // Go through all our templated map data and spawn all the entities in it int iTemplates = m_hTemplates.Count(); if ( !iTemplates ) { Msg("CreateInstance called on a point_template that has no templates: %s\n", STRING(GetEntityName()) ); return false; } // Tell the template system we're about to start a new template Templates_StartUniqueInstance(); int i; for ( i = 0; i < iTemplates; i++ ) { CBaseEntity *pEntity = NULL; char *pMapData; int iTemplateIndex = m_hTemplates[i].iTemplateIndex; // Some templates have Entity I/O connecting the entities within the template. // Unique versions of these templates need to be created whenever they're instanced. if ( Templates_IndexRequiresEntityIOFixup( iTemplateIndex ) ) { // This template requires instancing. // Create a new mapdata block and ask the template system to fill it in with // a unique version (with fixed Entity I/O connections). pMapData = Templates_GetEntityIOFixedMapData( iTemplateIndex ); } else { // Use the unmodified mapdata pMapData = (char*)STRING( Templates_FindByIndex( iTemplateIndex ) ); } // Create the entity from the mapdata MapEntity_ParseEntity( pEntity, pMapData, NULL ); if ( pEntity == NULL ) { Msg("Failed to initialize templated entity with mapdata: %s\n", pMapData ); return false; } // Get a matrix that'll convert from world to the new local space VMatrix matNewTemplateToWorld, matStoredLocalToWorld; matNewTemplateToWorld.SetupMatrixOrgAngles( vecOrigin, vecAngles ); MatrixMultiply( matNewTemplateToWorld, m_hTemplates[i].matEntityToTemplate, matStoredLocalToWorld ); // Get the world origin & angles from the stored local coordinates Vector vecNewOrigin; QAngle vecNewAngles; vecNewOrigin = matStoredLocalToWorld.GetTranslation(); MatrixToAngles( matStoredLocalToWorld, vecNewAngles ); // Set its origin & angles pEntity->SetAbsOrigin( vecNewOrigin ); pEntity->SetAbsAngles( vecNewAngles ); if ( DispatchSpawn( pEntity ) >= 0 ) { pEntities->AddToTail( pEntity ); } } // Now hookup entity heirarchy within the template int iCount = pEntities->Count(); for ( i = 0; i < iCount; i++ ) { CBaseEntity *pEntity = (*pEntities)[i]; if ( pEntity && pEntity->m_iParent != NULL_STRING ) { CBaseEntity *pParent = gEntList.FindEntityByName(NULL, pEntity->m_iParent, NULL); if ( pParent && (pParent->edict() != NULL) ) { pEntity->SetParent( pParent ); } } } return true; }
//----------------------------------------------------------------------------- // Purpose: Spawn the entities I contain // Input : &vecOrigin - // &vecAngles - // pEntities - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CPointTemplate::CreateInstance( const Vector &vecOrigin, const QAngle &vecAngles, CUtlVector<CBaseEntity*> *pEntities ) { // Go through all our templated map data and spawn all the entities in it int iTemplates = m_hTemplates.Count(); if ( !iTemplates ) { Msg("CreateInstance called on a point_template that has no templates: %s\n", STRING(GetEntityName()) ); return false; } // Tell the template system we're about to start a new template Templates_StartUniqueInstance(); HierarchicalSpawn_t *pSpawnList = (HierarchicalSpawn_t*)stackalloc( iTemplates * sizeof(HierarchicalSpawn_t) ); int i; for ( i = 0; i < iTemplates; i++ ) { CBaseEntity *pEntity = NULL; char *pMapData; int iTemplateIndex = m_hTemplates[i].iTemplateIndex; // Some templates have Entity I/O connecting the entities within the template. // Unique versions of these templates need to be created whenever they're instanced. if ( AllowNameFixup() && Templates_IndexRequiresEntityIOFixup( iTemplateIndex ) ) { // This template requires instancing. // Create a new mapdata block and ask the template system to fill it in with // a unique version (with fixed Entity I/O connections). pMapData = Templates_GetEntityIOFixedMapData( iTemplateIndex ); } else { // Use the unmodified mapdata pMapData = (char*)STRING( Templates_FindByIndex( iTemplateIndex ) ); } // Create the entity from the mapdata MapEntity_ParseEntity( pEntity, pMapData, NULL ); if ( pEntity == NULL ) { Msg("Failed to initialize templated entity with mapdata: %s\n", pMapData ); return false; } // Get a matrix that'll convert from world to the new local space VMatrix matNewTemplateToWorld, matStoredLocalToWorld; matNewTemplateToWorld.SetupMatrixOrgAngles( vecOrigin, vecAngles ); MatrixMultiply( matNewTemplateToWorld, m_hTemplates[i].matEntityToTemplate, matStoredLocalToWorld ); // Get the world origin & angles from the stored local coordinates Vector vecNewOrigin; QAngle vecNewAngles; vecNewOrigin = matStoredLocalToWorld.GetTranslation(); MatrixToAngles( matStoredLocalToWorld, vecNewAngles ); // Set its origin & angles pEntity->SetAbsOrigin( vecNewOrigin ); pEntity->SetAbsAngles( vecNewAngles ); pSpawnList[i].m_pEntity = pEntity; pSpawnList[i].m_nDepth = 0; } SpawnHierarchicalList( iTemplates, pSpawnList, true ); for ( i = 0; i < iTemplates; ++i ) { if ( pSpawnList[i].m_pEntity ) { pEntities->AddToTail( pSpawnList[i].m_pEntity ); } } return true; }