summaryrefslogtreecommitdiff
path: root/game/server/tf/tf_eventlog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/server/tf/tf_eventlog.cpp')
-rw-r--r--game/server/tf/tf_eventlog.cpp677
1 files changed, 677 insertions, 0 deletions
diff --git a/game/server/tf/tf_eventlog.cpp b/game/server/tf/tf_eventlog.cpp
new file mode 100644
index 0000000..04e7a85
--- /dev/null
+++ b/game/server/tf/tf_eventlog.cpp
@@ -0,0 +1,677 @@
+//========= Copyright 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( "medic_death" );
+ ListenForGameEvent( "player_hurt" );
+ ListenForGameEvent( "player_changeclass" );
+ ListenForGameEvent( "tf_game_over" );
+ ListenForGameEvent( "player_chargedeployed" );
+
+ ListenForGameEvent( "teamplay_flag_event" );
+ ListenForGameEvent( "teamplay_capture_blocked" );
+ ListenForGameEvent( "teamplay_point_captured" );
+ ListenForGameEvent( "teamplay_round_stalemate" );
+ ListenForGameEvent( "teamplay_round_win" );
+ ListenForGameEvent( "teamplay_game_over" );
+
+ ListenForGameEvent( "player_builtobject" );
+ ListenForGameEvent( "player_carryobject" );
+ ListenForGameEvent( "player_dropobject" );
+ ListenForGameEvent( "object_removed" );
+ ListenForGameEvent( "object_detonated" );
+ ListenForGameEvent( "object_destroyed" );
+ 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_logclassname" );
+ 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_DECAPITATION:
+ case TF_DMG_CUSTOM_HEADSHOT:
+ pszCustom = "headshot";
+ break;
+ case TF_DMG_CUSTOM_BACKSTAB:
+ pszCustom = "backstab";
+ break;
+
+ default:
+ break;
+ }
+
+ // is the spy feigning death?
+ if ( event->GetInt( "death_flags" ) & TF_DEATH_FEIGN_DEATH )
+ {
+ pszCustom = "feign_death";
+ }
+
+ 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
+ {
+ int iDamageBits = event->GetInt( "damagebits" );
+ if ( ( iDamageBits & DMG_VEHICLE ) || ( iDamageBits & DMG_NERVEGAS ) )
+ {
+ const char *pszCustomKill = "train";
+ if ( iDamageBits & DMG_NERVEGAS )
+ {
+ pszCustomKill = "saw";
+ }
+
+ // killed by the world
+ UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"world\" (customkill \"%s\") (attacker_position \"%d %d %d\")\n",
+ pPlayer->GetPlayerName(),
+ userid,
+ pPlayer->GetNetworkIDString(),
+ pPlayer->GetTeam()->GetName(),
+ pszCustomKill,
+ (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,
+ pAttacker ? (int)pAttacker->GetAbsOrigin().x : 0,
+ pAttacker ? (int)pAttacker->GetAbsOrigin().y : 0,
+ pAttacker ? (int)pAttacker->GetAbsOrigin().z : 0,
+ (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( "death_flags" ) & TF_DEATH_DOMINATION && 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( "death_flags" ) & TF_DEATH_ASSISTER_DOMINATION && 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( "death_flags" ) & TF_DEATH_REVENGE && 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( "death_flags" ) & TF_DEATH_ASSISTER_REVENGE && 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" ) ||
+ FStrEq( eventName, "player_carryobject" ) ||
+ FStrEq( eventName, "player_dropobject" ) ||
+ FStrEq( eventName, "player_removed" ) ||
+ FStrEq( eventName, "object_detonated" ) )
+ {
+ const int userid = event->GetInt( "userid" );
+ CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid );
+ if ( pPlayer )
+ {
+ // Some events have "object" and some have "objecttype". We can't change them as there are third-party
+ // scripts that listen for these events.
+ const int objectid = !event->IsEmpty( "objecttype" ) ? event->GetInt( "objecttype" ) : event->GetInt( "object" );
+ const CObjectInfo *pInfo = ( objectid >= 0 && objectid < OBJ_LAST ) ? GetObjectInfo( objectid ) : NULL;
+ if ( pInfo )
+ {
+ UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"%s\" (object \"%s\") (position \"%d %d %d\")\n",
+ pPlayer->GetPlayerName(),
+ userid,
+ pPlayer->GetNetworkIDString(),
+ pPlayer->GetTeam()->GetName(),
+ eventName,
+ pInfo->m_pObjectName,
+ (int)pPlayer->GetAbsOrigin().x,
+ (int)pPlayer->GetAbsOrigin().y,
+ (int)pPlayer->GetAbsOrigin().z );
+ }
+ return true;
+ }
+ return false;
+ }
+ else if ( FStrEq( eventName, "object_destroyed" ) )
+ {
+ int objectid = event->GetInt( "objecttype" );
+ const CObjectInfo *pInfo = ( objectid >= 0 && objectid < OBJ_LAST ) ? GetObjectInfo( objectid ) : NULL;
+ 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
+ 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_flag_event" ) )
+ {
+ int playerindex = event->GetInt( "player" );
+
+ CBasePlayer *pPlayer = UTIL_PlayerByIndex( playerindex );
+ if ( !pPlayer )
+ {
+ return false;
+ }
+
+ const 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, "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<iNumCappers;i++ )
+ {
+ int iPlayerIndex = szCappers[i];
+
+ Assert( iPlayerIndex != '\0' && iPlayerIndex > 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() );
+ }
+ }
+ else if ( FStrEq( eventName, "medic_death" ) )
+ {
+ const int userid = event->GetInt( "userid" );
+ CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid );
+ if ( !pPlayer )
+ {
+ return false;
+ }
+
+ const int attackerid = event->GetInt( "attacker" );
+ CBasePlayer *pAttacker = UTIL_PlayerByUserId( attackerid );
+
+ bool bCharged = event->GetBool( "charged" );
+ int iHealing = event->GetInt( "healing" );
+
+ if ( !pAttacker )
+ {
+ pAttacker = pPlayer;
+ }
+
+ UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"medic_death\" against \"%s<%i><%s><%s>\" (healing \"%d\") (ubercharge \"%s\")\n",
+ pAttacker->GetPlayerName(),
+ attackerid,
+ pAttacker->GetNetworkIDString(),
+ pAttacker->GetTeam()->GetName(),
+ pPlayer->GetPlayerName(),
+ userid,
+ pPlayer->GetNetworkIDString(),
+ pPlayer->GetTeam()->GetName(),
+ iHealing,
+ bCharged ? "1" : "0" );
+
+ return true;
+ }
+
+ return false;
+ }
+};
+
+CTFEventLog g_TFEventLog;
+
+//-----------------------------------------------------------------------------
+// Singleton access
+//-----------------------------------------------------------------------------
+IGameSystem* GameLogSystem()
+{
+ return &g_TFEventLog;
+}
+