You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
268 lines
8.1 KiB
268 lines
8.1 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: A camera entity that's used by the -makedevshots system to take |
|
// dev screenshots everytime the map is checked into source control. |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#include "cbase.h" |
|
#include "tier0/icommandline.h" |
|
#include "igamesystem.h" |
|
#include "filesystem.h" |
|
#include <KeyValues.h> |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
int g_iDevShotCameraCount = 0; |
|
#define DEVSHOT_INITIAL_WAIT 5 // Time after the level spawn before the first devshot camera takes it's shot |
|
#define DEVSHOT_INTERVAL 5 // Time between each devshot camera taking it's shot |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: A camera entity that's used by the -makedevshots system to take |
|
// dev screenshots everytime the map is checked into source control. |
|
//----------------------------------------------------------------------------- |
|
class CPointDevShotCamera : public CBaseEntity |
|
{ |
|
DECLARE_CLASS( CPointDevShotCamera, CBaseEntity ); |
|
public: |
|
DECLARE_DATADESC(); |
|
|
|
void Spawn( void ); |
|
void DevShotThink_Setup( void ); |
|
void DevShotThink_TakeShot( void ); |
|
void DevShotThink_PostShot( void ); |
|
|
|
// Always transmit to clients so they know where to move the view to |
|
virtual int UpdateTransmitState(); |
|
|
|
private: |
|
string_t m_iszCameraName; |
|
int m_iFOV; |
|
}; |
|
|
|
BEGIN_DATADESC( CPointDevShotCamera ) |
|
DEFINE_FUNCTION( DevShotThink_Setup ), |
|
DEFINE_FUNCTION( DevShotThink_TakeShot ), |
|
DEFINE_FUNCTION( DevShotThink_PostShot ), |
|
|
|
DEFINE_KEYFIELD( m_iszCameraName, FIELD_STRING, "cameraname" ), |
|
DEFINE_KEYFIELD( m_iFOV, FIELD_INTEGER, "FOV" ), |
|
END_DATADESC() |
|
|
|
LINK_ENTITY_TO_CLASS( point_devshot_camera, CPointDevShotCamera ); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Convenience function so we don't have to make this check all over |
|
//----------------------------------------------------------------------------- |
|
static CBasePlayer * UTIL_GetLocalPlayerOrListenServerHost( void ) |
|
{ |
|
if ( gpGlobals->maxClients > 1 ) |
|
{ |
|
if ( engine->IsDedicatedServer() ) |
|
{ |
|
return NULL; |
|
} |
|
|
|
return UTIL_GetListenServerHost(); |
|
} |
|
|
|
return UTIL_GetLocalPlayer(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CPointDevShotCamera::Spawn( void ) |
|
{ |
|
BaseClass::Spawn(); |
|
|
|
// Remove this entity immediately if we're not making devshots |
|
if ( !CommandLine()->FindParm("-makedevshots") ) |
|
{ |
|
UTIL_Remove( this ); |
|
return; |
|
} |
|
|
|
// Take a screenshot when it's my turn |
|
SetThink( &CPointDevShotCamera::DevShotThink_Setup ); |
|
SetNextThink( gpGlobals->curtime + DEVSHOT_INITIAL_WAIT + (g_iDevShotCameraCount * DEVSHOT_INTERVAL) ); |
|
|
|
g_iDevShotCameraCount++; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
int CPointDevShotCamera::UpdateTransmitState() |
|
{ |
|
// always transmit if currently used by a monitor |
|
return SetTransmitState( FL_EDICT_ALWAYS ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CPointDevShotCamera::DevShotThink_Setup( void ) |
|
{ |
|
// Move the player to the devshot camera |
|
CBasePlayer *pPlayer = UTIL_GetLocalPlayerOrListenServerHost(); |
|
if ( !pPlayer ) |
|
return; |
|
|
|
// Hide stuff |
|
engine->ClientCommand( pPlayer->edict(), "developer 0" ); |
|
engine->ClientCommand( pPlayer->edict(), "cl_drawhud 0" ); |
|
engine->ClientCommand( pPlayer->edict(), "sv_cheats 1" ); |
|
engine->ClientCommand( pPlayer->edict(), "god" ); |
|
engine->ClientCommand( pPlayer->edict(), "notarget" ); |
|
|
|
pPlayer->AddSolidFlags( FSOLID_NOT_SOLID ); |
|
pPlayer->EnableControl(FALSE); |
|
pPlayer->SetViewEntity( this ); |
|
pPlayer->SetFOV( this, m_iFOV ); |
|
|
|
// Hide the player's viewmodel |
|
if ( pPlayer->GetActiveWeapon() ) |
|
{ |
|
pPlayer->GetActiveWeapon()->AddEffects( EF_NODRAW ); |
|
} |
|
|
|
DispatchUpdateTransmitState(); |
|
|
|
// Now take the shot next frame |
|
SetThink( &CPointDevShotCamera::DevShotThink_TakeShot ); |
|
SetNextThink( gpGlobals->curtime ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CPointDevShotCamera::DevShotThink_TakeShot( void ) |
|
{ |
|
// Take the screenshot |
|
CBasePlayer *pPlayer = UTIL_GetLocalPlayerOrListenServerHost(); |
|
if ( !pPlayer ) |
|
return; |
|
|
|
engine->ClientCommand( pPlayer->edict(), "devshots_screenshot \"%s\"", STRING(m_iszCameraName) ); |
|
|
|
// Now take the shot next frame |
|
SetThink( &CPointDevShotCamera::DevShotThink_PostShot ); |
|
SetNextThink( gpGlobals->curtime + (DEVSHOT_INTERVAL - 1) ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CPointDevShotCamera::DevShotThink_PostShot( void ) |
|
{ |
|
// Take the screenshot |
|
CBasePlayer *pPlayer = UTIL_GetLocalPlayerOrListenServerHost(); |
|
if ( !pPlayer ) |
|
return; |
|
|
|
pPlayer->SetFOV( this, 0 ); |
|
|
|
// If all cameras have taken their shots, move to the next map |
|
g_iDevShotCameraCount--; |
|
if ( !g_iDevShotCameraCount ) |
|
{ |
|
engine->ClientCommand( pPlayer->edict(), "devshots_nextmap" ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Game system to detect maps without cameras in them, and move on |
|
//----------------------------------------------------------------------------- |
|
class CDevShotSystem : public CAutoGameSystemPerFrame |
|
{ |
|
public: |
|
|
|
CDevShotSystem( char const *name ) : CAutoGameSystemPerFrame( name ) |
|
{ |
|
} |
|
|
|
virtual void LevelInitPreEntity() |
|
{ |
|
m_bIssuedNextMapCommand = false; |
|
g_iDevShotCameraCount = 0; |
|
m_bParsedMapFile = false; |
|
} |
|
|
|
virtual void SafeRemoveIfDesired( void ) |
|
{ |
|
// If we're not making devshots, remove this system immediately |
|
if ( !CommandLine()->FindParm("-makedevshots") ) |
|
{ |
|
Remove( this ); |
|
return; |
|
} |
|
} |
|
|
|
virtual void FrameUpdatePostEntityThink( void ) |
|
{ |
|
// Wait until we're all spawned in |
|
if ( gpGlobals->curtime < 5 ) |
|
return; |
|
|
|
if ( m_bIssuedNextMapCommand ) |
|
return; |
|
|
|
if ( !m_bParsedMapFile ) |
|
{ |
|
m_bParsedMapFile = true; |
|
|
|
// See if we've got a camera file to import cameras from |
|
char szFullName[512]; |
|
Q_snprintf(szFullName,sizeof(szFullName), "maps/%s.txt", STRING( gpGlobals->mapname )); |
|
KeyValues *pkvMapCameras = new KeyValues( "MapCameras" ); |
|
if ( pkvMapCameras->LoadFromFile( filesystem, szFullName, "MOD" ) ) |
|
{ |
|
Warning( "Devshots: Loading point_devshot_camera positions from %s. \n", szFullName ); |
|
|
|
// Get each camera, and add it to our list |
|
KeyValues *pkvCamera = pkvMapCameras->GetFirstSubKey(); |
|
while ( pkvCamera ) |
|
{ |
|
// Get camera name |
|
const char *pCameraName = pkvCamera->GetName(); |
|
|
|
// Make a camera, and move it to the position specified |
|
CPointDevShotCamera *pCamera = (CPointDevShotCamera*)CreateEntityByName( "point_devshot_camera" ); |
|
Assert( pCamera ); |
|
pCamera->KeyValue( "cameraname", pCameraName ); |
|
pCamera->KeyValue( "origin", pkvCamera->GetString( "origin", "0 0 0" ) ); |
|
pCamera->KeyValue( "angles", pkvCamera->GetString( "angles", "0 0 0" ) ); |
|
pCamera->KeyValue( "FOV", pkvCamera->GetString( "FOV", "75" ) ); |
|
DispatchSpawn( pCamera ); |
|
pCamera->Activate(); |
|
|
|
// Move to next camera |
|
pkvCamera = pkvCamera->GetNextKey(); |
|
} |
|
} |
|
|
|
if ( !g_iDevShotCameraCount ) |
|
{ |
|
Warning( "Devshots: No point_devshot_camera in %s. Moving to next map.\n", STRING( gpGlobals->mapname ) ); |
|
|
|
CBasePlayer *pPlayer = UTIL_GetLocalPlayerOrListenServerHost(); |
|
if ( pPlayer ) |
|
{ |
|
engine->ClientCommand( pPlayer->edict(), "devshots_nextmap" ); |
|
m_bIssuedNextMapCommand = true; |
|
return; |
|
} |
|
} |
|
} |
|
} |
|
|
|
private: |
|
bool m_bIssuedNextMapCommand; |
|
bool m_bParsedMapFile; |
|
}; |
|
|
|
CDevShotSystem DevShotSystem( "CDevShotSystem" );
|
|
|