//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // //=============================================================================// #include "cbase.h" #include "tf_extra_map_entity.h" #include "KeyValues.h" #include "filesystem.h" struct EntityWhiteList_t { const char *pszKeyName; const char *pszEntName; }; // limit the entities that can be created using this method EntityWhiteList_t g_szEntityWhiteList[] = { // { "rocket", "entity_rocket" }, // { "carrier", "entity_carrier" }, { "sign", "entity_sign" }, // { "saucer", "entity_saucer" }, }; LINK_ENTITY_TO_CLASS( entity_rocket, CExtraMapEntity_Rocket ); LINK_ENTITY_TO_CLASS( entity_carrier, CExtraMapEntity_Carrier ); LINK_ENTITY_TO_CLASS( entity_sign, CExtraMapEntity_Sign ); LINK_ENTITY_TO_CLASS( entity_saucer, CExtraMapEntity_Saucer ); BEGIN_DATADESC( CExtraMapEntity ) DEFINE_THINKFUNC( AnimThink ), END_DATADESC(); IMPLEMENT_AUTO_LIST( IExtraMapEntityAutoList ); //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CExtraMapEntity::Spawn( void ) { Precache(); BaseClass::Spawn(); SetModel( STRING( GetModelName() ) ); SetMoveType( MOVETYPE_NONE ); SetSequence( 0 ); if ( ShouldAnimate() ) { ResetSequenceInfo(); SetThink( &CExtraMapEntity::AnimThink ); SetNextThink( gpGlobals->curtime + 0.1f ); } } void CExtraMapEntity::AnimThink( void ) { StudioFrameAdvance(); DispatchAnimEvents( this ); SetNextThink( gpGlobals->curtime + 0.1f ); } void CExtraMapEntity::Precache( void ) { BaseClass::Precache(); bool bAllowPrecache = CBaseEntity::IsPrecacheAllowed(); CBaseEntity::SetAllowPrecache( true ); Precache_Internal(); CBaseEntity::SetAllowPrecache( bAllowPrecache ); } void CExtraMapEntity::Precache_Internal( void ) { PrecacheModel( STRING( GetModelName() ) ); } const char *CExtraMapEntity::ValidateKeyName( const char *pszKey ) { if ( pszKey && pszKey[0] ) { for ( int i = 0; i < ARRAYSIZE( g_szEntityWhiteList ); i++ ) { if ( FStrEq( pszKey, g_szEntityWhiteList[i].pszKeyName ) ) { return g_szEntityWhiteList[i].pszEntName; } } } return NULL; } void CExtraMapEntity::PrepareModelName( const char *szModelName ) { const char *pszTemp = GetDefaultModel(); if ( szModelName && szModelName[0] ) { pszTemp = szModelName; } SetModelName( AllocPooledString( pszTemp ) ); } void CExtraMapEntity::SpawnExtraModel( void ) { /* const char *pszMapName = STRING( gpGlobals->mapname ); if ( !pszMapName || !pszMapName[0] ) return; KeyValues *pFileKV = new KeyValues( "models" ); if ( !pFileKV->LoadFromFile( g_pFullFileSystem, "scripts/extra_models.txt", "MOD" ) ) return; // See if we have an entry for this map. KeyValues *pMapKV = pFileKV->FindKey( pszMapName ); if ( pMapKV ) { FOR_EACH_SUBKEY( pMapKV, pSubKeyEnt ) { const char *pszEntName = ValidateKeyName( pSubKeyEnt->GetName() ); if ( !pszEntName ) continue; FOR_EACH_SUBKEY( pSubKeyEnt, pSubKeyCount ) { Vector loc = vec3_origin; QAngle rot( 0, 0, 0 ); char szModelName[MAX_PATH]; szModelName[0] = '\0'; float flChance = 1.0f; // assume we want to show everything unless specified in the .txt file FOR_EACH_SUBKEY( pSubKeyCount, pSubKey ) { if ( FStrEq( pSubKey->GetName(), "location" ) ) { const char *pszLoc = pSubKey->GetString(); UTIL_StringToVector( loc.Base(), pszLoc ); } else if ( FStrEq( pSubKey->GetName(), "rotation" ) ) { const char *pszRot = pSubKey->GetString(); UTIL_StringToVector( rot.Base(), pszRot ); } else if ( FStrEq( pSubKey->GetName(), "model" ) ) { V_strcpy_safe( szModelName, pSubKey->GetString() ); } else if ( FStrEq( pSubKey->GetName(), "chance" ) ) { flChance = pSubKey->GetFloat(); if ( flChance > 1.0f ) { flChance = 1.0f; } } } if ( ( flChance > 0.0f ) && ( RandomFloat( 0, 1 ) < flChance ) ) { CExtraMapEntity *pExtraMapEntity = static_cast< CExtraMapEntity* >( CBaseEntity::CreateNoSpawn( pszEntName, loc, rot ) ); if ( pExtraMapEntity ) { pExtraMapEntity->PrepareModelName( szModelName ); DispatchSpawn( pExtraMapEntity ); } } } } } pFileKV->deleteThis(); */ } //----------------------------------------------------------------------------- // Purpose: Grordbort rocket model in the skybox //----------------------------------------------------------------------------- void CExtraMapEntity_Rocket::Spawn( void ) { BaseClass::Spawn(); SetSolid( SOLID_BBOX ); SetSize( -Vector( 8, 8, 0 ), Vector( 8, 8, 16 ) ); } void CExtraMapEntity_Rocket::Precache_Internal( void ) { BaseClass::Precache_Internal(); PrecacheParticleSystem( "smoke_blackbillow_skybox" ); } //----------------------------------------------------------------------------- // Purpose: Mann vs. Machine carrier model in the skybox //----------------------------------------------------------------------------- void CExtraMapEntity_Carrier::Spawn( void ) { BaseClass::Spawn(); SetSolid( SOLID_BBOX ); SetSize( -Vector( 8, 8, 0 ), Vector( 8, 8, 16 ) ); } //----------------------------------------------------------------------------- // Purpose: Sign models to tease future updates //----------------------------------------------------------------------------- void CExtraMapEntity_Sign::Spawn( void ) { BaseClass::Spawn(); SetSolid( SOLID_NONE ); AddEffects( EF_NOSHADOW ); } //----------------------------------------------------------------------------- // Purpose: Saucer models to tease future updates //----------------------------------------------------------------------------- void CExtraMapEntity_Saucer::Spawn( void ) { BaseClass::Spawn(); SetSolid( SOLID_NONE ); AddEffects( EF_NOSHADOW ); }