Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/action.md
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,8 @@ For this, TNG has two new commands.
### Statistics
To see how well players are doing, we have implemented statistics into TNG. This feature will track various statistics of each player, for example accuracy or frags per minute. Tracked stats include shots fired and hits for all weapons, including punch attacks and grenade throws.

In matchmode, FPM is calculated using active match play time rather than total connected time. Only frames where the player is on a team and not a substitute count toward the FPM denominator. This means connecting early during warmup, spectating, or being a sub does not inflate your play time. In non-matchmode games, FPM uses total connected time as before.

**Commands:**
- `stats_endmap [0/1]` - when set to 1, this will display the stats scoreboard at the end of the map instead of the normal screen.
- `stats_afterround [0/1]` - when on (1), this will also record stats for events that happen when a round ends, for example when ff_afterround or FF is on.
Expand Down
1 change: 1 addition & 0 deletions src/action/a_cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -1314,6 +1314,7 @@ void Cmd_Ghost_f(edict_t * ent)
ent->client->resp.team_kills = ghost->team_kills;
ent->client->resp.streakKillsHighest = ghost->streakKillsHighest;
ent->client->resp.streakHSHighest = ghost->streakHSHighest;
ent->client->resp.active_frames = ghost->active_frames;

if (teamplay->value && ghost->team && ghost->team != ent->client->resp.team)
JoinTeam( ent, ghost->team, 1 );
Expand Down
2 changes: 2 additions & 0 deletions src/action/g_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -2035,6 +2035,7 @@ typedef struct
int ctf_lastfraggedcarrier;

int joined_team; // last frame # at which the player joined a team
int active_frames; // frames actively playing on a team during a match
int lastWave; //last time used wave

radio_t radio;
Expand Down Expand Up @@ -2888,6 +2889,7 @@ typedef struct
int team_kills;
int streakKillsHighest;
int streakHSHighest;
int active_frames;

}
gghost_t;
Expand Down
3 changes: 3 additions & 0 deletions src/action/g_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1403,6 +1403,9 @@ void G_RunFrame (void)

ClientBeginServerFrame (ent);

if (team_game_going && ent->client->resp.team != NOTEAM && !ent->client->resp.subteam)
ent->client->resp.active_frames++;

#ifndef NO_BOTS
// allow bots to think
if(!ent->is_bot)
Expand Down
1 change: 1 addition & 0 deletions src/action/p_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -4047,6 +4047,7 @@ void CreateGhost(edict_t * ent)
ghost->team_kills = ent->client->resp.team_kills;
ghost->streakKillsHighest = ent->client->resp.streakKillsHighest;
ghost->streakHSHighest = ent->client->resp.streakHSHighest;
ghost->active_frames = ent->client->resp.active_frames;

// Teamplay variables
if (teamplay->value) {
Expand Down
13 changes: 10 additions & 3 deletions src/action/tng_stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,9 @@ void A_ScoreboardEndLevel (edict_t * ent, edict_t * killer)
else
accuracy = 0;

secs = (level.framenum - cl->resp.enterframe) / HZ;
secs = cl->resp.active_frames > 0
? cl->resp.active_frames / HZ
: (level.framenum - cl->resp.enterframe) / HZ;
if (secs > 0)
fpm = (double)cl->resp.score * 60.0 / (double)secs;
else
Expand Down Expand Up @@ -738,7 +740,9 @@ void G_RegisterScore(void)
if (roundbased && game.roundNum > 0) {
fragsper = c->resp.score / game.roundNum;
} else {
sec = (level.framenum - c->resp.enterframe) / HZ;
sec = c->resp.active_frames > 0
? c->resp.active_frames / HZ
: (level.framenum - c->resp.enterframe) / HZ;
if (!sec)
sec = 1;
fragsper = c->resp.score * 3600 / sec;
Expand Down Expand Up @@ -1418,7 +1422,9 @@ void WriteLogEndMatchStats(gclient_t *cl)
char msg[1024];

shots = min( cl->resp.shotsTotal, 9999 );
secs = (level.framenum - cl->resp.enterframe) / HZ;
secs = cl->resp.active_frames > 0
? cl->resp.active_frames / HZ
: (level.framenum - cl->resp.enterframe) / HZ;

if (shots)
accuracy = (double)cl->resp.hitsTotal * 100.0 / (double)cl->resp.shotsTotal;
Expand Down Expand Up @@ -1597,6 +1603,7 @@ void LogEndMatchStats(void)
ghlient->resp.team_kills = ghost->team_kills;
ghlient->resp.streakKillsHighest = ghost->streakKillsHighest;
ghlient->resp.streakHSHighest = ghost->streakHSHighest;
ghlient->resp.active_frames = ghost->active_frames;
ghlient->resp.shotsTotal = ghost->shotsTotal;
ghlient->resp.hitsTotal = ghost->hitsTotal;

Expand Down
Loading