From 39ed87570bdb2f86969d4be821c94b722dc71179 Mon Sep 17 00:00:00 2001 From: Joe Ludwig Date: Wed, 26 Jun 2013 15:22:04 -0700 Subject: First version of the SOurce SDK 2013 --- mp/src/game/server/point_devshot_camera.cpp | 268 ++++++++++++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 mp/src/game/server/point_devshot_camera.cpp (limited to 'mp/src/game/server/point_devshot_camera.cpp') diff --git a/mp/src/game/server/point_devshot_camera.cpp b/mp/src/game/server/point_devshot_camera.cpp new file mode 100644 index 00000000..c266c8a4 --- /dev/null +++ b/mp/src/game/server/point_devshot_camera.cpp @@ -0,0 +1,268 @@ +//========= 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 + +// 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" ); -- cgit v1.2.3