summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/game/g_admin.c44
-rw-r--r--src/game/g_combat.c93
-rw-r--r--src/game/g_local.h8
3 files changed, 61 insertions, 84 deletions
diff --git a/src/game/g_admin.c b/src/game/g_admin.c
index 80dcc49..0677e6f 100644
--- a/src/game/g_admin.c
+++ b/src/game/g_admin.c
@@ -4376,7 +4376,7 @@ G_admin_stats
qboolean G_admin_stats( gentity_t *ent )
{
gentity_t *targ;
- int i, j;
+ int i;
qboolean header = qfalse;
char err[ MAX_STRING_CHARS ];
const static char *cswNames[ ] =
@@ -4421,41 +4421,29 @@ qboolean G_admin_stats( gentity_t *ent )
{
combatRanks_t *ranks = targ->client->pers.combatRanks + i;
- for( j = CSD_FIRST; j < CSD_MAX; j++ )
- if( ranks->inuse[ j ] )
- goto no_skip;
- continue;
- no_skip:
+ if( !ranks->inuse )
+ continue;
if( !header )
{
header = qtrue;
ADMBP( va( "^3stats: ^7combat statistics of %s^7:\n"
- "^3%*s ^7 E ^1pct ^7 EB ^1pct ^7 FF ^1pct ^7FBF ^1pct ^7Slf ^1pct^7\n",
+ "^3%*s %*s %*s^7\n",
targ->client->pers.netname,
- CSW_MAX_NAME_LEN, "Weapon" ) );
+ CSW_MAX_NAME_LEN, "Weapon",
+ 8, "Skill",
+ 4, "Rank" ) );
}
- ADMBP( va( "^3%*s", CSW_MAX_NAME_LEN, cswNames[ i ] ) );
-
- for( j = CSD_FIRST; j < CSD_MAX; j++ )
- {
- if( ranks->inuse[ j ] )
- {
- ADMBP( va( " ^7%3d",
- MIN( (int)round( ranks->effs[ j ] * 100.0f ), 999 ) ) );
-
- if( ranks->ranked[ j ] )
- ADMBP( va( " ^1%3d",
- (int)round( ranks->effs_pc[ j ] * 100.0f ) ) );
- else
- ADMBP( " ^0n/a" );
- }
- else
- ADMBP( " ^0--- ---" );
- }
-
- ADMBP( "\n" );
+ if( ranks->ranked )
+ ADMBP( va( "^3%*s ^7%*d %*d%%\n",
+ CSW_MAX_NAME_LEN, cswNames[ i ],
+ 8, (int)round( ranks->skill * 1000 ),
+ 3, (int)round( ranks->skill_pc * 100 ) ) );
+ else
+ ADMBP( va( "^3%*s ^7%*d ^0----^7\n",
+ CSW_MAX_NAME_LEN, cswNames[ i ],
+ 8, (int)round( ranks->skill * 1000 ) ) );
}
if( !header )
diff --git a/src/game/g_combat.c b/src/game/g_combat.c
index c79f97d..4ed8e8b 100644
--- a/src/game/g_combat.c
+++ b/src/game/g_combat.c
@@ -1901,7 +1901,11 @@ void G_CalculateCombatRanks( void )
{
gentity_t *ent;
combatStatsWeapon_t weapon;
- combatStatsDmgType_t dmgtype;
+ combatStats_t *stats;
+ combatRanks_t *ranks;
+ int i, sample_count = 0, rank;
+ csrSample_t samples[ MAX_CLIENTS ];
+ float last;
// reset all ranks
for( ent = g_entities; ent < g_entities + MAX_CLIENTS; ent++ )
@@ -1909,69 +1913,54 @@ void G_CalculateCombatRanks( void )
memset( &ent->client->pers.combatRanks, 0, sizeof( combatRanks_t ) );
for( weapon = CSW_UNKNOWN + 1; weapon < CSW_MAX; weapon++ )
- for( dmgtype = CSD_FIRST; dmgtype < CSD_MAX; dmgtype++ )
+ {
+ for( ent = g_entities; ent < g_entities + MAX_CLIENTS; ent++ )
{
- int i, sample_count = 0, rank;
- csrSample_t samples[ MAX_CLIENTS ];
- float last;
-
- for( ent = g_entities; ent < g_entities + MAX_CLIENTS; ent++ )
- {
- combatStats_t *stats;
- combatRanks_t *ranks;
- int potential;
-
- if( !ent->inuse ||
- !ent->client ||
- ent->client->pers.connected == CON_CONNECTING )
- continue;
-
- stats = ent->client->pers.combatStats + weapon;
- ranks = ent->client->pers.combatRanks + weapon;
-
- if( !stats->fired )
- continue;
-
- potential = stats->fired;
+ if( !ent->inuse ||
+ !ent->client ||
+ ent->client->pers.connected == CON_CONNECTING )
+ continue;
- for( i = 0; i < CSD_MAX; i++ )
- if( i != dmgtype )
- potential -= stats->dealt[ i ];
+ stats = ent->client->pers.combatStats + weapon;
+ ranks = ent->client->pers.combatRanks + weapon;
- if( !potential )
- continue;
+ if( !stats->fired )
+ continue;
- ranks->inuse[ dmgtype ] = qtrue;
- ranks->effs[ dmgtype ] = (float)stats->dealt[ dmgtype ] / potential;
+ ranks->inuse = qtrue;
+ ranks->skill =
+ ( stats->dealt[ CSD_ENEMY ] + stats->dealt[ CSD_ENEMY_BUILDABLE ] -
+ stats->dealt[ CSD_FRIENDLY ] - stats->dealt[ CSD_FRIENDLY_BUILDABLE ] -
+ stats->dealt[ CSD_SELF ] ) / (float)stats->fired;
- samples[ sample_count ].ent = ent;
- samples[ sample_count++ ].value = ranks->effs[ dmgtype ];
- }
+ samples[ sample_count ].ent = ent;
+ samples[ sample_count++ ].value = ranks->skill;
+ }
- if( sample_count < 2 )
- continue;
+ if( sample_count < 2 )
+ continue;
- qsort( samples, sample_count, sizeof( csrSample_t ), (int(*)(const void*,const void*))csrSampleCmp );
+ qsort( samples, sample_count, sizeof( csrSample_t ), (int(*)(const void*,const void*))csrSampleCmp );
- for( i = 0, rank = 0; i < sample_count; i++ )
- {
- combatRanks_t *ranks = samples[ i ].ent->client->pers.combatRanks + weapon;
+ for( i = 0, rank = 0; i < sample_count; i++ )
+ {
+ combatRanks_t *ranks = samples[ i ].ent->client->pers.combatRanks + weapon;
- if( i > 0 && fabs( last - samples[ i ].value ) > 1.0e-5 )
- rank++;
+ if( i > 0 && fabs( last - samples[ i ].value ) > 1.0e-5 )
+ rank++;
- ranks->ranked[ dmgtype ] = qtrue;
- ranks->effs_pc[ dmgtype ] = rank;
+ ranks->ranked = qtrue;
+ ranks->skill_pc = rank;
- last = samples[ i ].value;
- }
+ last = samples[ i ].value;
+ }
- for( i = 0; i < sample_count; i++ )
- {
- float *eff = samples[ i ].ent->client->pers.combatRanks[ weapon ].effs_pc + dmgtype;
- (*eff) = 1.0f - (*eff) / ( (float)rank + 1 );
- }
+ for( i = 0; i < sample_count; i++ )
+ {
+ float *skill = &samples[ i ].ent->client->pers.combatRanks[ weapon ].skill;
+ (*skill) = 1.0f - (*skill) / ( (float)rank + 1 );
}
+ }
level.combatRanksTime = level.time;
}
@@ -1994,7 +1983,7 @@ void G_LogCombatSettings( void )
#undef CSW
};
- for( i = 0; i < CSW_MAX; i++ )
+ for( i = CSW_UNKNOWN + 1; i < CSW_MAX; i++ )
{
Com_sprintf( p, 4096 - ( p - buffer ), " %s %i", modNames[ cswToMod[ i ] ], cswDamages[ i ] );
while( *p ) p++;
diff --git a/src/game/g_local.h b/src/game/g_local.h
index db363f8..d2b5288 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -335,10 +335,10 @@ typedef struct
typedef struct
{
- qboolean inuse[ CSD_MAX ];
- qboolean ranked[ CSD_MAX ];
- float effs[ CSD_MAX ];
- float effs_pc[ CSD_MAX ];
+ qboolean inuse;
+ qboolean ranked;
+ float skill;
+ float skill_pc;
} combatRanks_t;
// client data that stays across multiple respawns, but is cleared