//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ // //=============================================================================// #include "cbase.h" #include "../EventLog.h" #include "team.h" #include "teamplayroundbased_gamerules.h" #include "tf_gamerules.h" #include "team_control_point_master.h" #include "team_control_point_round.h" #include "tf_team.h" #include "KeyValues.h" extern ConVar tf_flag_caps_per_round; class CTFEventLog : public CEventLog { private: typedef CEventLog BaseClass; public: bool PrintEvent( IGameEvent *event ) // override virtual function { if ( !PrintTFEvent( event ) ) // allow TF to override logging { return BaseClass::PrintEvent( event ); } else { return true; } } bool Init() { BaseClass::Init(); ListenForGameEvent( "player_death" ); ListenForGameEvent( "player_hurt" ); ListenForGameEvent( "player_changeclass" ); ListenForGameEvent( "tf_game_over" ); ListenForGameEvent( "player_chargedeployed" ); ListenForGameEvent( "player_builtobject" ); ListenForGameEvent( "teamplay_flag_event" ); ListenForGameEvent( "object_destroyed" ); ListenForGameEvent( "teamplay_capture_blocked" ); ListenForGameEvent( "teamplay_point_captured" ); ListenForGameEvent( "teamplay_round_stalemate" ); ListenForGameEvent( "teamplay_round_win" ); ListenForGameEvent( "teamplay_game_over" ); return true; } protected: bool PrintTFEvent( IGameEvent *event ) // print Mod specific logs { const char *eventName = event->GetName(); if ( !Q_strncmp( eventName, "server_", strlen("server_")) ) { return false; // ignore server_ messages } if ( !Q_strncmp( eventName, "player_death", Q_strlen( "player_death" ) ) ) { const int userid = event->GetInt( "userid" ); CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid ); if ( !pPlayer ) { return false; } const int attackerid = event->GetInt( "attacker" ); const char *weapon = event->GetString( "weapon" ); int iCustomDamage = event->GetInt( "customkill" ); CBasePlayer *pAttacker = UTIL_PlayerByUserId( attackerid ); if ( pPlayer == pAttacker ) { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"%s\" (attacker_position \"%d %d %d\")\n", pPlayer->GetPlayerName(), userid, pPlayer->GetNetworkIDString(), pPlayer->GetTeam()->GetName(), weapon, (int)pPlayer->GetAbsOrigin().x, (int)pPlayer->GetAbsOrigin().y, (int)pPlayer->GetAbsOrigin().z ); } else if ( pAttacker ) { const char *pszCustom = NULL; switch( iCustomDamage ) { case TF_DMG_CUSTOM_HEADSHOT: pszCustom = "headshot"; break; case TF_DMG_CUSTOM_BACKSTAB: pszCustom = "backstab"; break; default: break; } if ( pszCustom ) { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" killed \"%s<%i><%s><%s>\" with \"%s\" (customkill \"%s\") (attacker_position \"%d %d %d\") (victim_position \"%d %d %d\")\n", pAttacker->GetPlayerName(), attackerid, pAttacker->GetNetworkIDString(), pAttacker->GetTeam()->GetName(), pPlayer->GetPlayerName(), userid, pPlayer->GetNetworkIDString(), pPlayer->GetTeam()->GetName(), weapon, pszCustom, (int)pAttacker->GetAbsOrigin().x, (int)pAttacker->GetAbsOrigin().y, (int)pAttacker->GetAbsOrigin().z, (int)pPlayer->GetAbsOrigin().x, (int)pPlayer->GetAbsOrigin().y, (int)pPlayer->GetAbsOrigin().z ); } else { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" killed \"%s<%i><%s><%s>\" with \"%s\" (attacker_position \"%d %d %d\") (victim_position \"%d %d %d\")\n", pAttacker->GetPlayerName(), attackerid, pAttacker->GetNetworkIDString(), pAttacker->GetTeam()->GetName(), pPlayer->GetPlayerName(), userid, pPlayer->GetNetworkIDString(), pPlayer->GetTeam()->GetName(), weapon, (int)pAttacker->GetAbsOrigin().x, (int)pAttacker->GetAbsOrigin().y, (int)pAttacker->GetAbsOrigin().z, (int)pPlayer->GetAbsOrigin().x, (int)pPlayer->GetAbsOrigin().y, (int)pPlayer->GetAbsOrigin().z ); } } else { // killed by the world UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"world\" (attacker_position \"%d %d %d\")\n", pPlayer->GetPlayerName(), userid, pPlayer->GetNetworkIDString(), pPlayer->GetTeam()->GetName(), (int)pPlayer->GetAbsOrigin().x, (int)pPlayer->GetAbsOrigin().y, (int)pPlayer->GetAbsOrigin().z ); } // Assist kill int assistid = event->GetInt( "assister" ); CBasePlayer *pAssister = UTIL_PlayerByUserId( assistid ); if ( pAssister ) { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"kill assist\" against \"%s<%i><%s><%s>\" (assister_position \"%d %d %d\") (attacker_position \"%d %d %d\") (victim_position \"%d %d %d\")\n", pAssister->GetPlayerName(), assistid, pAssister->GetNetworkIDString(), pAssister->GetTeam()->GetName(), pPlayer->GetPlayerName(), userid, pPlayer->GetNetworkIDString(), pPlayer->GetTeam()->GetName(), (int)pAssister->GetAbsOrigin().x, (int)pAssister->GetAbsOrigin().y, (int)pAssister->GetAbsOrigin().z, (int)pAttacker->GetAbsOrigin().x, (int)pAttacker->GetAbsOrigin().y, (int)pAttacker->GetAbsOrigin().z, (int)pPlayer->GetAbsOrigin().x, (int)pPlayer->GetAbsOrigin().y, (int)pPlayer->GetAbsOrigin().z ); } // Domination and Revenge // pAttacker //int attackerid = engine->GetPlayerForUserID( event->GetInt( "attacker" ) ); // pPlayer //int userid = engine->GetPlayerForUserID( event->GetInt( "userid" ) ); // pAssister // assistid if ( event->GetInt( "dominated" ) > 0 && pAttacker ) { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"domination\" against \"%s<%i><%s><%s>\"\n", pAttacker->GetPlayerName(), attackerid, pAttacker->GetNetworkIDString(), pAttacker->GetTeam()->GetName(), pPlayer->GetPlayerName(), userid, pPlayer->GetNetworkIDString(), pPlayer->GetTeam()->GetName() ); } if ( event->GetInt( "assister_dominated" ) > 0 && pAssister ) { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"domination\" against \"%s<%i><%s><%s>\" (assist \"1\")\n", pAssister->GetPlayerName(), assistid, pAssister->GetNetworkIDString(), pAssister->GetTeam()->GetName(), pPlayer->GetPlayerName(), userid, pPlayer->GetNetworkIDString(), pPlayer->GetTeam()->GetName() ); } if ( event->GetInt( "revenge" ) > 0 && pAttacker ) { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"revenge\" against \"%s<%i><%s><%s>\"\n", pAttacker->GetPlayerName(), attackerid, pAttacker->GetNetworkIDString(), pAttacker->GetTeam()->GetName(), pPlayer->GetPlayerName(), userid, pPlayer->GetNetworkIDString(), pPlayer->GetTeam()->GetName() ); } if ( event->GetInt( "assister_revenge" ) > 0 && pAssister ) { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"revenge\" against \"%s<%i><%s><%s>\" (assist \"1\")\n", pAssister->GetPlayerName(), assistid, pAssister->GetNetworkIDString(), pAssister->GetTeam()->GetName(), pPlayer->GetPlayerName(), userid, pPlayer->GetNetworkIDString(), pPlayer->GetTeam()->GetName() ); } return true; } else 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"); if ( pPlayer->GetTeamNumber() < FIRST_GAME_TEAM ) return true; if ( iClass >= TF_FIRST_NORMAL_CLASS && iClass <= TF_LAST_NORMAL_CLASS ) { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" changed role to \"%s\"\n", pPlayer->GetPlayerName(), userid, pPlayer->GetNetworkIDString(), pPlayer->GetTeam()->GetName(), GetPlayerClassData( iClass )->m_szClassName ); } return true; } else if ( FStrEq( eventName, "tf_game_over" ) || FStrEq( eventName, "teamplay_game_over" ) ) { UTIL_LogPrintf( "World triggered \"Game_Over\" reason \"%s\"\n", event->GetString( "reason" ) ); UTIL_LogPrintf( "Team \"Red\" final score \"%d\" with \"%d\" players\n", GetGlobalTeam( TF_TEAM_RED )->GetScore(), GetGlobalTeam( TF_TEAM_RED )->GetNumPlayers() ); UTIL_LogPrintf( "Team \"Blue\" final score \"%d\" with \"%d\" players\n", GetGlobalTeam( TF_TEAM_BLUE )->GetScore(), GetGlobalTeam( TF_TEAM_BLUE )->GetNumPlayers() ); return true; } else if ( FStrEq( eventName, "player_chargedeployed" ) ) { const int userid = event->GetInt( "userid" ); CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid ); if ( !pPlayer ) { return false; } UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"chargedeployed\"\n", pPlayer->GetPlayerName(), userid, pPlayer->GetNetworkIDString(), pPlayer->GetTeam()->GetName() ); return true; } else if ( FStrEq( eventName, "player_builtobject" ) ) { const int userid = event->GetInt( "userid" ); CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid ); if ( !pPlayer ) { return false; } // object name const int objectid = event->GetInt( "object" ); const CObjectInfo *pInfo = GetObjectInfo( objectid ); if ( pInfo ) { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"builtobject\" (object \"%s\") (position \"%d %d %d\")\n", pPlayer->GetPlayerName(), userid, pPlayer->GetNetworkIDString(), pPlayer->GetTeam()->GetName(), pInfo->m_pObjectName, (int)pPlayer->GetAbsOrigin().x, (int)pPlayer->GetAbsOrigin().y, (int)pPlayer->GetAbsOrigin().z ); } return true; } else if ( FStrEq( eventName, "teamplay_flag_event" ) ) { int playerindex = event->GetInt( "player" ); CBasePlayer *pPlayer = UTIL_PlayerByIndex( playerindex ); if ( !pPlayer ) { return false; } char *pszEvent = "unknown"; // picked up, dropped, defended, captured int iEventType = event->GetInt( "eventtype" ); bool bPlainLogEntry = true; switch ( iEventType ) { case TF_FLAGEVENT_PICKUP: pszEvent = "picked up"; break; case TF_FLAGEVENT_CAPTURE: pszEvent = "captured"; if ( tf_flag_caps_per_round.GetInt() > 0 ) { bPlainLogEntry = false; } break; case TF_FLAGEVENT_DEFEND: pszEvent = "defended"; break; case TF_FLAGEVENT_DROPPED: pszEvent = "dropped"; break; } if ( bPlainLogEntry ) { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"flagevent\" (event \"%s\") (position \"%d %d %d\")\n", pPlayer->GetPlayerName(), pPlayer->GetUserID(), pPlayer->GetNetworkIDString(), pPlayer->GetTeam()->GetName(), pszEvent, (int)pPlayer->GetAbsOrigin().x, (int)pPlayer->GetAbsOrigin().y, (int)pPlayer->GetAbsOrigin().z ); } else { CTFTeam *pTeam = GetGlobalTFTeam( pPlayer->GetTeamNumber() ); UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"flagevent\" (event \"%s\") (team_caps \"%d\") (caps_per_round \"%d\") (position \"%d %d %d\")\n", pPlayer->GetPlayerName(), pPlayer->GetUserID(), pPlayer->GetNetworkIDString(), pPlayer->GetTeam()->GetName(), pszEvent, pTeam->GetFlagCaptures(), tf_flag_caps_per_round.GetInt(), (int)pPlayer->GetAbsOrigin().x, (int)pPlayer->GetAbsOrigin().y, (int)pPlayer->GetAbsOrigin().z ); } return true; } else if ( FStrEq( eventName, "object_destroyed" ) ) { int objectid = event->GetInt( "objecttype" ); const CObjectInfo *pInfo = NULL; if ( objectid >= 0 && objectid < OBJ_LAST ) { pInfo = GetObjectInfo( objectid ); } if ( !pInfo ) return false; const int userid = event->GetInt( "userid" ); CBasePlayer *pObjectOwner = UTIL_PlayerByUserId( userid ); if ( !pObjectOwner ) { return false; } const int attackerid = event->GetInt( "attacker" ); CBasePlayer *pAttacker = UTIL_PlayerByUserId( attackerid ); if ( !pAttacker ) { return false; } const char *weapon = event->GetString( "weapon" ); // log that the person killed an object // attacker //with "weapon" UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"killedobject\" (object \"%s\") (weapon \"%s\") (objectowner \"%s<%i><%s><%s>\") (attacker_position \"%d %d %d\")\n", pAttacker->GetPlayerName(), attackerid, pAttacker->GetNetworkIDString(), pAttacker->GetTeam()->GetName(), pInfo->m_pObjectName, weapon, pObjectOwner->GetPlayerName(), userid, pObjectOwner->GetNetworkIDString(), pObjectOwner->GetTeam()->GetName(), (int)pAttacker->GetAbsOrigin().x, (int)pAttacker->GetAbsOrigin().y, (int)pAttacker->GetAbsOrigin().z ); const int assisterid = event->GetInt( "assister" ); CBasePlayer *pAssister = UTIL_PlayerByUserId( assisterid ); if ( pAssister ) { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"killedobject\" (object \"%s\") (objectowner \"%s<%i><%s><%s>\") (assist \"1\") (assister_position \"%d %d %d\") (attacker_position \"%d %d %d\")\n", pAssister->GetPlayerName(), assisterid, pAssister->GetNetworkIDString(), pAssister->GetTeam()->GetName(), pInfo->m_pObjectName, pObjectOwner->GetPlayerName(), userid, pObjectOwner->GetNetworkIDString(), pObjectOwner->GetTeam()->GetName(), (int)pAssister->GetAbsOrigin().x, (int)pAssister->GetAbsOrigin().y, (int)pAssister->GetAbsOrigin().z, (int)pAttacker->GetAbsOrigin().x, (int)pAttacker->GetAbsOrigin().y, (int)pAttacker->GetAbsOrigin().z ); } } else if ( FStrEq( eventName, "teamplay_capture_blocked" ) ) { int blockerindex = event->GetInt( "blocker" ); CBasePlayer *pBlocker = UTIL_PlayerByIndex( blockerindex ); if ( !pBlocker ) { return true; } UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"captureblocked\" (cp \"%d\") (cpname \"%s\") (position \"%d %d %d\")\n", pBlocker->GetPlayerName(), pBlocker->GetUserID(), pBlocker->GetNetworkIDString(), pBlocker->GetTeam()->GetName(), event->GetInt( "cp" ), event->GetString( "cpname" ), (int)pBlocker->GetAbsOrigin().x, (int)pBlocker->GetAbsOrigin().y, (int)pBlocker->GetAbsOrigin().z ); } else if ( FStrEq( eventName, "teamplay_point_captured" ) ) { CTeam *pTeam = GetGlobalTeam( event->GetInt( "team" ) ); if ( !pTeam ) return true; const char *szCappers = event->GetString( "cappers" ); int iNumCappers = Q_strlen( szCappers ); if ( iNumCappers <= 0 ) return true; char buf[1024]; Q_snprintf( buf, sizeof(buf), "Team \"%s\" triggered \"pointcaptured\" (cp \"%d\") (cpname \"%s\") (numcappers \"%d\") ", pTeam->GetName(), event->GetInt( "cp" ), event->GetString( "cpname" ), iNumCappers ); for ( int i=0;i 0 && iPlayerIndex <= MAX_PLAYERS ); CBasePlayer *pPlayer = UTIL_PlayerByIndex( iPlayerIndex ); if ( !pPlayer ) continue; char playerBuf[256]; Q_snprintf( playerBuf, sizeof(playerBuf), "(player%d \"%s<%i><%s><%s>\") (position%d \"%d %d %d\") ", i + 1, pPlayer->GetPlayerName(), pPlayer->GetUserID(), pPlayer->GetNetworkIDString(), pPlayer->GetTeam()->GetName(), i + 1, (int)pPlayer->GetAbsOrigin().x, (int)pPlayer->GetAbsOrigin().y, (int)pPlayer->GetAbsOrigin().z ); Q_strncat( buf, playerBuf, sizeof(buf), COPY_ALL_CHARACTERS ); } UTIL_LogPrintf( "%s\n", buf ); } else if ( FStrEq( eventName, "teamplay_round_stalemate" ) ) { int iReason = event->GetInt( "reason" ); if ( iReason == STALEMATE_TIMER ) { UTIL_LogPrintf( "World triggered \"Round_SuddenDeath\" reason \"round timelimit reached\"\n" ); } else if ( iReason == STALEMATE_SERVER_TIMELIMIT ) { UTIL_LogPrintf( "World triggered \"Round_SuddenDeath\" reason \"server timelimit reached\"\n" ); } else { UTIL_LogPrintf( "World triggered \"Round_SuddenDeath\"\n" ); } return true; } else if ( FStrEq( eventName, "teamplay_round_win" ) ) { bool bShowScores = true; int iTeam = event->GetInt( "team" ); bool bFullRound = event->GetBool( "full_round" ); if ( iTeam == TEAM_UNASSIGNED ) { UTIL_LogPrintf( "World triggered \"Round_Stalemate\"\n" ); } else { const char *pszWinner = "Red"; if ( iTeam == TF_TEAM_BLUE ) { pszWinner = "Blue"; } CTeamControlPointMaster *pMaster = g_hControlPointMasters.Count() ? g_hControlPointMasters[0] : NULL; if ( pMaster && pMaster->PlayingMiniRounds() ) { UTIL_LogPrintf( "World triggered \"Mini_Round_Win\" (winner \"%s\") (round \"%s\")\n", pszWinner, pMaster->GetCurrentRound()->GetEntityName().ToCStr() ); UTIL_LogPrintf( "World triggered \"Mini_Round_Length\" (seconds \"%0.2f\")\n", event->GetFloat( "round_time" ) ); bShowScores = false; } if ( bFullRound ) { UTIL_LogPrintf( "World triggered \"Round_Win\" (winner \"%s\")\n", pszWinner ); if ( !pMaster || !pMaster->PlayingMiniRounds() ) { UTIL_LogPrintf( "World triggered \"Round_Length\" (seconds \"%0.2f\")\n", event->GetFloat( "round_time" ) ); } bShowScores = true; } } if ( bShowScores ) { UTIL_LogPrintf( "Team \"Red\" current score \"%d\" with \"%d\" players\n", GetGlobalTeam( TF_TEAM_RED )->GetScore(), GetGlobalTeam( TF_TEAM_RED )->GetNumPlayers() ); UTIL_LogPrintf( "Team \"Blue\" current score \"%d\" with \"%d\" players\n", GetGlobalTeam( TF_TEAM_BLUE )->GetScore(), GetGlobalTeam( TF_TEAM_BLUE )->GetNumPlayers() ); } } return false; } }; CTFEventLog g_TFEventLog; //----------------------------------------------------------------------------- // Singleton access //----------------------------------------------------------------------------- IGameSystem* GameLogSystem() { return &g_TFEventLog; }