Beispiel #1
0
void CHLTVDirector::CreateShotFromEvent( CHLTVGameEvent *event )
{
	// show event at least for 2 more seconds after it occured
	const char *name = event->m_Event->GetName();
	
	bool bPlayerHurt = Q_strcmp( "player_hurt", name ) == 0;
	bool bPlayerKilled = Q_strcmp( "player_death", name ) == 0;
	bool bRoundStart = Q_strcmp( "round_start", name ) == 0;
	bool bRoundEnd = Q_strcmp( "round_end", name ) == 0;

	if ( bPlayerHurt || bPlayerKilled )
	{
		CBaseEntity *victim = UTIL_PlayerByUserId( event->m_Event->GetInt("userid") );
		CBaseEntity *attacker = UTIL_PlayerByUserId( event->m_Event->GetInt("attacker") );

		if ( !victim )
			return;

		if ( attacker == victim || attacker == NULL )
		{
			// player killed self or by WORLD
			StartChaseCameraShot( victim->entindex(), 0, 96, 20, 0, false );
		}
		else // attacker != NULL
		{
			// check if we would show it from ineye view
			bool bInEye = (bPlayerKilled && RandomFloat(0,1) > 0.33) || (bPlayerHurt && RandomFloat(0,1) > 0.66); 

			// if we show ineye view, show it more likely from killer
			if ( RandomFloat(0,1) > (bInEye?0.3f:0.7f)  )
			{
				V_swap( attacker, victim );
			}
						
			// hurting a victim is shown as chase more often
			// view from behind over head
			// lower view point, dramatic
			// view over shoulder, randomly left or right
			StartChaseCameraShot( victim->entindex(), attacker->entindex(), 96, -20, (RandomFloat()>0.5)?30:-30, bInEye );
		}
				
		// shot 2 seconds after death/hurt
		m_nNextShotTick = MIN( m_nNextShotTick, (event->m_Tick+TIME_TO_TICKS(2.0)) );
	}
	else if ( bRoundStart || bRoundEnd )
	{
		StartBestFixedCameraShot( false );
	}
	else
	{
		DevMsg( "No known TV shot for event %s\n", name );
	}
}
Beispiel #2
0
	bool PrintSDKEvent( IGameEvent * event )	// print Mod specific logs
	{
		const char *eventName = event->GetName();
	
		if ( !Q_strncmp( eventName, "server_", strlen("server_")) )
		{
			return false; // ignore server_ messages, always.
		}

#if defined ( SDK_USE_PLAYERCLASSES )
		if ( FStrEq( eventName, "player_changeclass" ) )
		{
			const int userid = event->GetInt( "userid" );
			CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid );

			if ( !pPlayer )
			{
				return false;
			}

			int iClass = event->GetInt("class");
			int iTeam = pPlayer->GetTeamNumber();
//Tony; when using teams, the player can only select classes on blue or red.
#if defined ( SDK_USE_TEAMS )
			if ( iTeam != SDK_TEAM_BLUE && iTeam != SDK_TEAM_RED )
#else
			if ( iTeam != TEAM_UNASSIGNED )
#endif
				return true;

			CSDKTeam *pTeam = GetGlobalSDKTeam( iTeam );

			if ( iClass == PLAYERCLASS_RANDOM )
			{
				UTIL_LogPrintf( "\"%s<%i><%s><%s>\" changed role to \"Random\"\n",  
					pPlayer->GetPlayerName(),
					userid,
					pPlayer->GetNetworkIDString(),
					pTeam->GetName()
					);
			}
			else if ( iClass < GetGlobalSDKTeam(iTeam)->GetNumPlayerClasses() )
			{
				const CSDKPlayerClassInfo &pInfo = GetGlobalSDKTeam(iTeam)->GetPlayerClassInfo( iClass );

				UTIL_LogPrintf( "\"%s<%i><%s><%s>\" changed role to \"%s\"\n",  
					pPlayer->GetPlayerName(),
					userid,
					pPlayer->GetNetworkIDString(),
					pTeam->GetName(),
					pInfo.m_szPrintName
					);
			}
			return true;
		}
#endif // SDK_USE_PLAYERCLASSES
		return false;
	}
Beispiel #3
0
/**
 * Game event processing
 */
void CFishPool::FireGameEvent( IGameEvent *event )
{
	CBasePlayer *player = UTIL_PlayerByUserId( event->GetInt( "userid" ) );
	
	// the fish panic
	const float loudRange = 500.0f;
	const float quietRange = 75.0f;

	float range = (Q_strcmp( "player_footstep", event->GetName() )) ? loudRange : quietRange;

	for( int i=0; i<m_fishes.Count(); ++i )
	{
		// if player is NULL, assume a game-wide event
		if (player && (player->GetAbsOrigin() - m_fishes[i]->GetAbsOrigin()).IsLengthGreaterThan( range ))
		{
			// event too far away to care
			continue;
		}

		m_fishes[i]->Panic();
	}
}
Beispiel #4
0
void CTFHLTVDirector::CreateShotFromEvent( CHLTVGameEvent *event )
{
    // show event at least for 2 more seconds after it occured
    const char *name = event->m_Event->GetName();

    int thera = RandomFloat()>0.5?20:-20;

    if ( !Q_strcmp( "teamplay_point_startcapture", name ) ||
            !Q_strcmp( "teamplay_point_captured", name ) ||
            !Q_strcmp( "teamplay_capture_blocked", name ) )
    {
        CBaseEntity *pCapturePoint = GetCapturePointByIndex( event->m_Event->GetInt( "cp" ) );

        int iCameraIndex = -1;
        float flClosest = 99999.9f;

        if ( pCapturePoint )
        {
            // Does it have an associated viewpoint?
            for ( int i = 0; i<m_nNumFixedCameras; i++ )
            {
                CBaseEntity *pCamera = m_pFixedCameras[ i ];

                if ( pCamera )
                {
                    byte pvs[MAX_MAP_CLUSTERS/8];
                    int clusterIndex = engine->GetClusterForOrigin( pCamera->GetAbsOrigin() );
                    engine->GetPVSForCluster( clusterIndex, sizeof(pvs), pvs );
                    bool bCameraInPVS = engine->CheckOriginInPVS( pCapturePoint->GetAbsOrigin(), pvs, sizeof( pvs ) );

                    if ( bCameraInPVS == true )
                    {
                        float flDistance = (pCapturePoint->GetAbsOrigin() - pCamera->GetAbsOrigin()).Length();
                        if ( flDistance <= flClosest )
                        {
                            iCameraIndex = i;
                            flClosest = flDistance;
                        }
                    }
                }
            }
        }

        CBasePlayer *pPlayer = NULL;

        if ( !Q_strcmp( "teamplay_point_captured", name ) )
        {
            const char *pszCappers = event->m_Event->GetString("cappers");
            int nLength = Q_strlen(pszCappers);

            if ( nLength > 0 )
            {
                int iRandomCapper = pszCappers[ RandomInt(0,nLength-1) ];
                pPlayer = UTIL_PlayerByIndex( iRandomCapper );
            }
        }
        else if ( !Q_strcmp( "teamplay_capture_blocked", name ) )
        {
            int iBlocker = event->m_Event->GetInt("blocker");
            pPlayer = UTIL_PlayerByIndex( iBlocker );
        }

        if ( pPlayer )
        {
            if ( iCameraIndex >= 0 && RandomFloat() > 0.66f )
            {
                StartFixedCameraShot( iCameraIndex, pPlayer->entindex() );
            }
            else if ( pCapturePoint )
            {
                StartChaseCameraShot( pPlayer->entindex(), pCapturePoint->entindex(), 96, 20, thera, false );
            }
            else
            {
                StartChaseCameraShot( pPlayer->entindex(), 0, 96, 20, 0, false );
            }
        }
        else if ( iCameraIndex >= 0 && pCapturePoint )
        {
            // no player known for this event
            StartFixedCameraShot( iCameraIndex, pCapturePoint->entindex() );
        }

        // shot 2 seconds after event
        m_nNextShotTick = min( m_nNextShotTick, (event->m_Tick+TIME_TO_TICKS(1.0)) );
    }
    else if ( !Q_strcmp( "object_destroyed", name ) )
    {
        CBasePlayer *attacker = UTIL_PlayerByUserId( event->m_Event->GetInt("attacker") );
        if ( attacker )
        {
            int iObjectIndex = event->m_Event->GetInt("index");
            StartChaseCameraShot( attacker->entindex(), iObjectIndex, 96, 20, thera, false );
        }
    }
    else if ( !Q_strcmp( "ctf_flag_captured", name ) )
    {
        CBasePlayer *capper = UTIL_PlayerByUserId( event->m_Event->GetInt("capper") );
        if ( capper )
        {
            StartChaseCameraShot( capper->entindex(), 0, 96, 20, 0, false );
        }
    }
    else if ( !Q_strcmp( "teamplay_flag_event", name ) )
    {
        StartChaseCameraShot( event->m_Event->GetInt("player"), 0, 96, 20, 0, false );
    }
    else
    {

        // let baseclass create a shot
        BaseClass::CreateShotFromEvent( event );
    }
}
static void RecvProxy_ExplosionUserID( const CRecvProxyData *pData, void *pStruct, void *pOut )
{
	int iUserID = pData->m_Value.m_Int;
	( (C_TETFExplosion*)pStruct )->m_pPlayer = ( iUserID > 0 ) ? ToTFPlayer( UTIL_PlayerByUserId( iUserID ) ) : NULL;
}
Beispiel #6
0
bool CEventLog::PrintPlayerEvent( IGameEvent *event )
{
	const char * eventName = event->GetName();
	const int userid = event->GetInt( "userid" );

	if ( !Q_strncmp( eventName, "player_connect", Q_strlen("player_connect") ) ) // player connect is before the CBasePlayer pointer is setup
	{
		const char *name = event->GetString( "name" );
		const char *address = event->GetString( "address" );
		const char *networkid = event->GetString("networkid" );
		UTIL_LogPrintf( "\"%s<%i><%s><>\" connected, address \"%s\"\n", name, userid, networkid, address);
		return true;
	}
	else if ( !Q_strncmp( eventName, "player_disconnect", Q_strlen("player_disconnect")  ) )
	{
		const char *reason = event->GetString("reason" );
		const char *name = event->GetString("name" );
		const char *networkid = event->GetString("networkid" );
		CTeam *team = NULL;
		CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid );

		if ( pPlayer )
		{
			team = pPlayer->GetTeam();
		}

		UTIL_LogPrintf( "\"%s<%i><%s><%s>\" disconnected (reason \"%s\")\n", name, userid, networkid, team ? team->GetName() : "", reason );
		return true;
	}

	CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid );
	if ( !pPlayer)
	{
		DevMsg( "CEventLog::PrintPlayerEvent: Failed to find player (userid: %i, event: %s)\n", userid, eventName );
		return false;
	}

	if ( !Q_strncmp( eventName, "player_team", Q_strlen("player_team") ) )
	{
		const bool bDisconnecting = event->GetBool( "disconnect" );

		if ( !bDisconnecting )
		{
			const int newTeam = event->GetInt( "team" );
			const int oldTeam = event->GetInt( "oldteam" );
			CTeam *team = GetGlobalTeam( newTeam );
			CTeam *oldteam = GetGlobalTeam( oldTeam );
			
			UTIL_LogPrintf( "\"%s<%i><%s><%s>\" joined team \"%s\"\n", 
			pPlayer->GetPlayerName(),
			pPlayer->GetUserID(),
			pPlayer->GetNetworkIDString(),
			oldteam->GetName(),
			team->GetName() );
		}

		return true;
	}
	else if ( !Q_strncmp( eventName, "player_death", Q_strlen("player_death") ) )
	{
		const int attackerid = event->GetInt("attacker" );

#ifdef MSS
		const char *weapon = event->GetString( "weapon" );
#endif
		
		CBasePlayer *pAttacker = UTIL_PlayerByUserId( attackerid );
		CTeam *team = pPlayer->GetTeam();
		CTeam *attackerTeam = NULL;
		
		if ( pAttacker )
		{
			attackerTeam = pAttacker->GetTeam();
		}
		if ( pPlayer == pAttacker && pPlayer )  
		{  

#ifdef MSS
			UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"%s\"\n",  
							pPlayer->GetPlayerName(),
							userid,
							pPlayer->GetNetworkIDString(),
							team ? team->GetName() : "",
							weapon
							);
#else
			UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"%s\"\n",  
							pPlayer->GetPlayerName(),
							userid,
							pPlayer->GetNetworkIDString(),
							team ? team->GetName() : "",
							pAttacker->GetClassname()
							);
#endif
		}
		else if ( pAttacker )
		{
			CTeam *attackerTeam = pAttacker->GetTeam();

#ifdef MSS
			UTIL_LogPrintf( "\"%s<%i><%s><%s>\" killed \"%s<%i><%s><%s>\" with \"%s\"\n",  
							pAttacker->GetPlayerName(),
							attackerid,
							pAttacker->GetNetworkIDString(),
							attackerTeam ? attackerTeam->GetName() : "",
							pPlayer->GetPlayerName(),
							userid,
							pPlayer->GetNetworkIDString(),
							team ? team->GetName() : "",
							weapon
							);
#else
			UTIL_LogPrintf( "\"%s<%i><%s><%s>\" killed \"%s<%i><%s><%s>\"\n",  
							pAttacker->GetPlayerName(),
							attackerid,
							pAttacker->GetNetworkIDString(),
							attackerTeam ? attackerTeam->GetName() : "",
							pPlayer->GetPlayerName(),
							userid,
							pPlayer->GetNetworkIDString(),
							team ? team->GetName() : ""
							);								
#endif
		}
		else
		{  
			// killed by the world
			UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"world\"\n",
							pPlayer->GetPlayerName(),
							userid,
							pPlayer->GetNetworkIDString(),
							team ? team->GetName() : ""
							);
		}
		return true;
	}
	else if ( !Q_strncmp( eventName, "player_activate", Q_strlen("player_activate") ) )
	{
		UTIL_LogPrintf( "\"%s<%i><%s><>\" entered the game\n",  
							pPlayer->GetPlayerName(),
							userid,
							pPlayer->GetNetworkIDString()
							);

		return true;
	}
	else if ( !Q_strncmp( eventName, "player_changename", Q_strlen("player_changename") ) )
	{
		const char *newName = event->GetString( "newname" );
		const char *oldName = event->GetString( "oldname" );
		CTeam *team = pPlayer->GetTeam();
		UTIL_LogPrintf( "\"%s<%i><%s><%s>\" changed name to \"%s\"\n", 
					oldName,
					userid,
					pPlayer->GetNetworkIDString(),
					team ? team->GetName() : "",
					newName
					);
		return true;
	}
				   
// ignored events
//player_hurt
	return false;
}
Beispiel #7
0
void CHLTVDirector::CreateShotFromEvent( CGameEvent *event )
{
	// show event at least for 2 more seconds after it occured
	const char *name = event->m_Event->GetName();
	IGameEvent *shot = NULL;

	bool bPlayerHurt = Q_strcmp( "player_hurt", name ) == 0;
	bool bPlayerKilled = Q_strcmp( "player_death", name ) == 0;
	bool bRoundStart = Q_strcmp( "round_start", name ) == 0;
	bool bRoundEnd = Q_strcmp( "round_end", name ) == 0;

	if ( bPlayerHurt || bPlayerKilled )
	{
		CBaseEntity *victim = UTIL_PlayerByUserId( event->m_Event->GetInt("userid") );
		CBaseEntity *attacker = UTIL_PlayerByUserId( event->m_Event->GetInt("attacker") );

		if ( !victim )
			return;

		if ( attacker == victim || attacker == NULL )
		{
			// player killed self or by WORLD
			shot = gameeventmanager->CreateEvent( "hltv_chase", true );
			shot->SetInt( "target1", victim->entindex() );
			shot->SetInt( "target2", 0 );
			shot->SetInt( "theta", 0 );	// view from behind over head
			shot->SetInt( "phi", 20 );	// from above
			shot->SetFloat( "distance", 96.0f );
		}
		else // attacker != NULL
		{
			// check if we would show it from ineye view
			bool bInEye = (bPlayerKilled && RandomFloat(0,1) > 0.33) || (bPlayerHurt && RandomFloat(0,1) > 0.66); 

			// if we show ineye view, show it more likely from killer
			if ( RandomFloat(0,1) > (bInEye?0.3f:0.7f)  )
			{
				swap( attacker, victim );
			}
						
			// hurting a victim is shown as chase more often
			shot = gameeventmanager->CreateEvent( "hltv_chase", true );
			shot->SetInt( "target1", victim->entindex() );
			shot->SetInt( "target2", attacker->entindex() );

			// view from behind over head
			shot->SetInt( "phi", -20 ); // lower view point, dramatic
			shot->SetFloat( "distance", 96.0f );
			shot->SetInt( "ineye", bInEye?1:0 );
							
			// view over shoulder, randomly left or right
			if ( RandomFloat(0,1) > 0.5  )
			{
				shot->SetInt( "theta", 30 ); // swing left
			}
			else
			{
				shot->SetInt( "theta", -30 ); // swing right
			}
			
		}
				
		// shot 2 seconds after death/hurt
		m_nNextShotTick = MIN( m_nNextShotTick, (event->m_Tick+TIME_TO_TICKS(2.0)) );
		m_iPVSEntity = victim->entindex();
	}
	else if ( bRoundStart || bRoundEnd )
	{
		StartBestFixedCameraShot( false );
	}
	else
	{
		DevMsg( "No known TV shot for event %s\n", name );
	}


	if ( shot )
	{
		m_pHLTVServer->BroadcastEvent( shot );
		gameeventmanager->FreeEvent( shot );
	}
}
//=========================================================
//=========================================================
void C_GameInstructor::FireGameEvent( IGameEvent *event )
{
	VPROF_BUDGET( "C_GameInstructor::FireGameEvent", "GameInstructor" );
	const char *name = event->GetName();
 
	if ( Q_strcmp( name, "gameinstructor_draw" ) == 0 )
	{
		if ( m_bNoDraw )
		{
			if ( gameinstructor_verbose.GetInt() > 0 )
			{
				ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " );
				ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Set to draw...\n" );
			}
 
			m_bNoDraw = false;
		}
	}
	else if ( Q_strcmp( name, "gameinstructor_nodraw" ) == 0 )
	{
		if ( !m_bNoDraw )
		{
			if ( gameinstructor_verbose.GetInt() > 0 )
			{
				ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " );
				ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Set to not draw...\n" );
			}
 
			m_bNoDraw = true;
			StopAllLessons();
		}
	}
	else if ( Q_strcmp( name, "round_end" ) == 0 )
	{
		if ( gameinstructor_verbose.GetInt() > 0 )
		{
			ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " );
			ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Round ended...\n" );
		}
 
		CloseAllOpenOpportunities();
 
		if ( IsPC() )
		{
			// Good place to backup our counts
			WriteSaveData();
		}
	}
	else if ( Q_strcmp( name, "round_start" ) == 0 )
	{
		if ( gameinstructor_verbose.GetInt() > 0 )
		{
			ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " );
			ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Round started...\n" );
		}
 
		CloseAllOpenOpportunities();
 
		EvaluateLessonsForGameRules();
	}
	else if ( Q_strcmp( name, "player_death" ) == 0 )
	{
		#if !defined(NO_STEAM) && defined(USE_CEG)
				Steamworks_TestSecret(); 
				Steamworks_SelfCheck(); 
		#endif
 
		C_BasePlayer *pLocalPlayer = GetLocalPlayer();
 
		if ( pLocalPlayer && pLocalPlayer == UTIL_PlayerByUserId( event->GetInt( "userid" ) ) )
		{
			if ( gameinstructor_verbose.GetInt() > 0 )
			{
				ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " );
				ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Local player died...\n" );
			}
 
			for ( int i = m_OpenOpportunities.Count() - 1; i >= 0; --i )
			{
				CBaseLesson *pLesson		= m_OpenOpportunities[ i ];
				CBaseLesson *pRootLesson	= pLesson->GetRoot();
 
				if ( !pRootLesson->CanOpenWhenDead() )
					CloseOpportunity( pLesson );
			}
		}
	}
	else if ( Q_strcmp( name, "player_team" ) == 0 )
	{
		C_BasePlayer *pLocalPlayer = GetLocalPlayer();
 
		if ( pLocalPlayer && pLocalPlayer == UTIL_PlayerByUserId( event->GetInt( "userid" ) ) && 
			 ( event->GetInt( "team" ) != event->GetInt( "oldteam" ) || event->GetBool( "disconnect" ) ) )
		{
			if ( gameinstructor_verbose.GetInt() > 0 )
			{
				ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " );
				ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Local player changed team (or disconnected)...\n" );
			}
 
			CloseAllOpenOpportunities();
		}
 
		EvaluateLessonsForGameRules();
	}
	else if ( Q_strcmp( name, "player_disconnect" ) == 0 )
	{
		C_BasePlayer *pLocalPlayer = GetLocalPlayer();
		if ( pLocalPlayer && pLocalPlayer == UTIL_PlayerByUserId( event->GetInt( "userid" ) ) )
		{
			if ( gameinstructor_verbose.GetInt() > 0 )
			{
				ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " );
				ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Local player disconnected...\n" );
			}
 
			CloseAllOpenOpportunities();
		}
	}
	else if ( Q_strcmp( name, "map_transition" ) == 0 )
	{
		if ( gameinstructor_verbose.GetInt() > 0 )
		{
			ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " );
			ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "Map transition...\n" );
		}
 
		CloseAllOpenOpportunities();
 
		if ( m_bNoDraw )
		{
			if ( gameinstructor_verbose.GetInt() > 0 )
			{
				ConColorMsg( Color( 255, 128, 64, 255 ), "[INSTRUCTOR]: " );
				ConColorMsg( Color( 64, 128, 255, 255 ), "Set to draw...\n" );
			}
 
			m_bNoDraw = false;
		}
 
		if ( IsPC() )
		{
			// Good place to backup our counts
			WriteSaveData();
		}
	}
	else if ( Q_strcmp( name, "game_newmap" ) == 0 )
	{
		if ( gameinstructor_verbose.GetInt() > 0 )
		{
			ConColorMsg( CBaseLesson::m_rgbaVerboseHeader, "[INSTRUCTOR]: " );
			ConColorMsg( CBaseLesson::m_rgbaVerbosePlain, "New map...\n" );
		}
 
		CloseAllOpenOpportunities();
 
		if ( m_bNoDraw )
		{
			if ( gameinstructor_verbose.GetInt() > 0 )
			{
				ConColorMsg( Color( 255, 128, 64, 255 ), "[INSTRUCTOR]: " );
				ConColorMsg( Color( 64, 128, 255, 255 ), "Set to draw...\n" );
			}
 
			m_bNoDraw = false;
		}
 
		if ( IsPC() )
		{
			// Good place to backup our counts
			WriteSaveData();
		}
	}
 
	else if ( Q_strcmp( name, "set_instructor_group_enabled" ) == 0 )
	{
		const char *pszGroup	= event->GetString( "group" );
		bool bEnabled			= event->GetInt( "enabled" ) != 0;
 
		if ( pszGroup && pszGroup[0] )
			SetLessonGroupEnabled(pszGroup, bEnabled);
	}
}
	bool PrintCStrikeEvent( IGameEvent *event )	// print Mod specific logs
	{
		const char *eventName = event->GetName();
	
		// messages that don't have a user associated to them
		if ( !Q_strncmp( eventName, "round_end", Q_strlen("round_end") ) )
		{
			const int winner = event->GetInt( "winner" );
			const int reason = event->GetInt( "reason" );
			const char *msg = event->GetString( "message" );
			msg++; // remove the '#' char

			switch( reason )
			{
			case Game_Commencing:
				UTIL_LogPrintf( "World triggered \"Game_Commencing\"\n" );
				return true;
				break;
			}

			CTeam *ct = GetGlobalTeam( TEAM_CT );
			CTeam *ter = GetGlobalTeam( TEAM_TERRORIST );
			Assert( ct && ter );

			switch ( winner )
			{
			case WINNER_CT:
				UTIL_LogPrintf( "Team \"%s\" triggered \"%s\" (CT \"%i\") (T \"%i\")\n", ct->GetName(), msg, ct->GetScore(), ter->GetScore() );
				break;
			case WINNER_TER:
				UTIL_LogPrintf( "Team \"%s\" triggered \"%s\" (CT \"%i\") (T \"%i\")\n", ter->GetName(), msg, ct->GetScore(), ter->GetScore() );
				break;
			case WINNER_DRAW:
			default:
				UTIL_LogPrintf( "World triggered \"%s\" (CT \"%i\") (T \"%i\")\n", msg, ct->GetScore(), ter->GetScore() );
				break;
			}	

			UTIL_LogPrintf( "Team \"CT\" scored \"%i\" with \"%i\" players\n", ct->GetScore(), ct->GetNumPlayers() );
			UTIL_LogPrintf( "Team \"TERRORIST\" scored \"%i\" with \"%i\" players\n", ter->GetScore(), ter->GetNumPlayers() );
			
			UTIL_LogPrintf("World triggered \"Round_End\"\n");
			return true;
		}
		else if ( !Q_strncmp( eventName, "server_", strlen("server_")) )
		{
			return false; // ignore server_ messages
		}
		
		const int userid = event->GetInt( "userid" );
		CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid );
		if ( !pPlayer )
		{
			return false;
		}

		if ( FStrEq( eventName, "player_hurt" ) )
		{
			const int attackerid = event->GetInt("attacker" );
			const char *weapon = event->GetString( "weapon" );
			CBasePlayer *pAttacker = UTIL_PlayerByUserId( attackerid );
			if ( !pAttacker )
			{
				return false;
			}

			bool isTeamAttack = ( (pPlayer->GetTeamNumber() == pAttacker->GetTeamNumber() ) && (pPlayer != pAttacker) );
			int detail = mp_logdetail.GetInt();
			if ( ( isTeamAttack && ( detail & LOG_DETAIL_TEAMMATE_ATTACKS ) ) ||
				( !isTeamAttack && ( detail & LOG_DETAIL_ENEMY_ATTACKS ) ) )
			{
				int hitgroup = event->GetInt( "hitgroup" );
				const char *hitgroupStr = "GENERIC";
				switch ( hitgroup )
				{
				case HITGROUP_GENERIC:
					hitgroupStr = "generic";
					break;
				case HITGROUP_HEAD:
					hitgroupStr = "head";
					break;
				case HITGROUP_CHEST:
					hitgroupStr = "chest";
					break;
				case HITGROUP_STOMACH:
					hitgroupStr = "stomach";
					break;
				case HITGROUP_LEFTARM:
					hitgroupStr = "left arm";
					break;
				case HITGROUP_RIGHTARM:
					hitgroupStr = "right arm";
					break;
				case HITGROUP_LEFTLEG:
					hitgroupStr = "left leg";
					break;
				case HITGROUP_RIGHTLEG:
					hitgroupStr = "right leg";
					break;
				}

				UTIL_LogPrintf( "\"%s<%i><%s><%s>\" attacked \"%s<%i><%s><%s>\" with \"%s\" (damage \"%d\") (damage_armor \"%d\") (health \"%d\") (armor \"%d\") (hitgroup \"%s\")\n",  
					pAttacker->GetPlayerName(),
					attackerid,
					pAttacker->GetNetworkIDString(),
					pAttacker->GetTeam()->GetName(),
					pPlayer->GetPlayerName(),
					userid,
					pPlayer->GetNetworkIDString(),
					pPlayer->GetTeam()->GetName(),
					weapon,
					event->GetInt( "dmg_health" ),
					event->GetInt( "dmg_armor" ),
					event->GetInt( "health" ),
					event->GetInt( "armor" ),
					hitgroupStr );
			}
			return true;
		}
		else if ( !Q_strncmp( eventName, "player_death", Q_strlen("player_death") ) )
		{
			const int attackerid = event->GetInt("attacker" );
			const char *weapon = event->GetString( "weapon" );
			const bool headShot = (event->GetInt( "headshot" ) == 1);
			CBasePlayer *pAttacker = UTIL_PlayerByUserId( attackerid );

			if ( pPlayer == pAttacker )  
			{  
				UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"%s\"\n",  
								pPlayer->GetPlayerName(),
								userid,
								pPlayer->GetNetworkIDString(),
								pPlayer->GetTeam()->GetName(),
								weapon
								);
			}
			else if ( pAttacker )
			{
				UTIL_LogPrintf( "\"%s<%i><%s><%s>\" killed \"%s<%i><%s><%s>\" with \"%s\"%s\n",  
								pAttacker->GetPlayerName(),
								attackerid,
								pAttacker->GetNetworkIDString(),
								pAttacker->GetTeam()->GetName(),
								pPlayer->GetPlayerName(),
								userid,
								pPlayer->GetNetworkIDString(),
								pPlayer->GetTeam()->GetName(),
								weapon,
								headShot ? " (headshot)":""
								);								
			}
			else
			{  
				// killed by the world
				UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"world\"\n",
								pPlayer->GetPlayerName(),
								userid,
								pPlayer->GetNetworkIDString(),
								pPlayer->GetTeam()->GetName()
								);
			}
			return true;
		}
		else if ( !Q_strncmp( eventName, "round_start", Q_strlen("round_start") ) )
		{
			UTIL_LogPrintf("World triggered \"Round_Start\"\n");
			return true;
		}
		else if ( !Q_strncmp( eventName, "hostage_follows", Q_strlen("hostage_follows") ) )
		{
			UTIL_LogPrintf( "\"%s<%i><%s><CT>\" triggered \"Touched_A_Hostage\"\n",
								pPlayer->GetPlayerName(),
								userid,
								pPlayer->GetNetworkIDString()
								);
			return true;
		}
		else if ( !Q_strncmp( eventName, "hostage_killed", Q_strlen("hostage_killed") ) )
		{
			UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Killed_A_Hostage\"\n", 
								pPlayer->GetPlayerName(),
								userid,
								pPlayer->GetNetworkIDString(),
								pPlayer->GetTeam()->GetName()
								);
			return true;
		}
		else if ( !Q_strncmp( eventName, "hostage_rescued", Q_strlen("hostage_rescued") ) )
		{
			UTIL_LogPrintf("\"%s<%i><%s><CT>\" triggered \"Rescued_A_Hostage\"\n",
								pPlayer->GetPlayerName(),
								userid,
								pPlayer->GetNetworkIDString()
								);
			return true;
		}
		else if ( !Q_strncmp( eventName, "bomb_planted", Q_strlen("bomb_planted") ) )
		{
			UTIL_LogPrintf("\"%s<%i><%s><TERRORIST>\" triggered \"Planted_The_Bomb\"\n", 
								pPlayer->GetPlayerName(),
								userid,
								pPlayer->GetNetworkIDString()
								);
			return true;
		}
		else if ( !Q_strncmp( eventName, "bomb_defused", Q_strlen("bomb_defused") ) )
		{
			UTIL_LogPrintf("\"%s<%i><%s><CT>\" triggered \"Defused_The_Bomb\"\n", 
								pPlayer->GetPlayerName(),
								userid,
								pPlayer->GetNetworkIDString()
								);
			return true;
		}
		else if ( !Q_strncmp( eventName, "bomb_dropped", Q_strlen("bomb_dropped") ) )
		{
			UTIL_LogPrintf("\"%s<%i><%s><TERRORIST>\" triggered \"Dropped_The_Bomb\"\n", 
								pPlayer->GetPlayerName(),
								userid,
								pPlayer->GetNetworkIDString()
								);
			return true;
		}
		else if ( !Q_strncmp( eventName, "bomb_begindefuse", Q_strlen("bomb_begindefuse") ) )
		{
			const bool haskit = (event->GetInt( "haskit" ) == 1);
			UTIL_LogPrintf("\"%s<%i><%s><CT>\" triggered \"%s\"\n", 
								pPlayer->GetPlayerName(),
								userid,
								pPlayer->GetNetworkIDString(),
								haskit ? "Begin_Bomb_Defuse_With_Kit" : "Begin_Bomb_Defuse_Without_Kit"
								);
			return true;
		}
		else if ( !Q_strncmp( eventName, "bomb_pickup", Q_strlen("bomb_pickup") ) )
		{
			UTIL_LogPrintf("\"%s<%i><%s><TERRORIST>\" triggered \"Got_The_Bomb\"\n", 
								pPlayer->GetPlayerName(),
								userid,
								pPlayer->GetNetworkIDString()
								);
			return true;
		}	
		
// unused events:
//hostage_hurt
//bomb_exploded

		return false;
	}
void CCSHLTVDirector::CreateShotFromEvent( CHLTVGameEvent *event )
{
	// show event at least for 2 more seconds after it occured
	const char *name = event->m_Event->GetName();
	IGameEvent *shot = NULL;

	if ( !Q_strcmp( "hostage_rescued", name ) ||
		 !Q_strcmp( "hostage_hurt", name ) ||
		 !Q_strcmp( "hostage_follows", name ) ||
		 !Q_strcmp( "hostage_killed", name ) )
	{
		CBaseEntity *player = UTIL_PlayerByUserId( event->m_Event->GetInt("userid") );
		
		if ( !player )
			return;

		// shot player as primary, hostage as secondary target
		shot = gameeventmanager->CreateEvent( "hltv_chase", true );
		shot->SetInt( "target1", player->entindex() );
		shot->SetInt( "target2", event->m_Event->GetInt("hostage") );
		shot->SetFloat( "distance", 96.0f );
		shot->SetInt( "theta", 40 );
		shot->SetInt( "phi", 20 );

		// shot 2 seconds after event
		m_nNextShotTick = min( m_nNextShotTick, (event->m_Tick+TIME_TO_TICKS(2.0)) );
		m_iPVSEntity = player->entindex();
	}

	else if ( !Q_strcmp( "bomb_pickup", name ) ||
		!Q_strcmp( "bomb_dropped", name ) ||
		!Q_strcmp( "bomb_planted", name ) ||
		!Q_strcmp( "bomb_defused", name ) )
	{
		CBaseEntity *player = UTIL_PlayerByUserId( event->m_Event->GetInt("userid") );

		if ( !player )
			return;

		shot = gameeventmanager->CreateEvent( "hltv_chase", true );
		shot->SetInt( "target1", player->entindex() );
		shot->SetInt( "target2", 0 );
		shot->SetFloat( "distance", 64.0f );
		shot->SetInt( "theta", 200 );
		shot->SetInt( "phi", 10 );

		// shot 2 seconds after pickup
		m_nNextShotTick = min( m_nNextShotTick, (event->m_Tick+TIME_TO_TICKS(2.0)) );
		m_iPVSEntity = player->entindex();
	}
	else
	{
		// let baseclass create a shot
		BaseClass::CreateShotFromEvent( event );

		return;
	}

	if ( shot )
	{
		m_pHLTVServer->BroadcastEvent( shot );
		gameeventmanager->FreeEvent( shot );
		DevMsg("DrcCmd: %s\n", name );
	}
}