diff --git a/code/cgame/cg_consolecmds.c b/code/cgame/cg_consolecmds.c index 4c8b075e97..781f8cf40d 100644 --- a/code/cgame/cg_consolecmds.c +++ b/code/cgame/cg_consolecmds.c @@ -115,6 +115,27 @@ static void CG_ScoresUp_f( void ) { } } +static void CG_AccDown_f(void) { + + if (cg.accRequestTime + 2000 < cg.time) { + + cg.accRequestTime = cg.time; + trap_SendClientCommand("acc"); + + if (!cg.showAcc) { + cg.showAcc = qtrue; + } + + } else { + cg.showAcc = qtrue; + } +} + +static void CG_AccUp_f(void) { + if (cg.showAcc) { + cg.showAcc = qfalse; + } +} #ifdef MISSIONPACK extern menuDef_t *menuScoreboard; void Menu_Reset( void ); // FIXME: add to right include file @@ -499,6 +520,8 @@ static consoleCommand_t commands[] = { { "scoresUp", CG_scrollScoresUp_f }, #endif { "startOrbit", CG_StartOrbit_f }, + { "+acc", CG_AccDown_f}, + { "-acc", CG_AccUp_f}, //{ "camera", CG_Camera_f }, { "loaddeferred", CG_LoadDeferredPlayers } }; diff --git a/code/cgame/cg_draw.c b/code/cgame/cg_draw.c index c688875282..9e624a221a 100644 --- a/code/cgame/cg_draw.c +++ b/code/cgame/cg_draw.c @@ -2333,6 +2333,42 @@ static qboolean CG_DrawScoreboard( void ) { #endif } +#define ACCBOARD_XPOS cgs.screenXmax - 80 +#define ACCBOARD_YPOS cgs.screenYmax / 3 +#define ACCBOARD_HEIGHT 20 +#define ACCBOARD_WIDTH 75 +#define ACCITEM_SIZE 16 + +qboolean CG_DrawAccboard(void) { + int counter, i; + char *len; + i = 0; + + if (!cg.showAcc) { + return qfalse; + } + + for (counter = 0; counter < WP_NUM_WEAPONS; counter++) { + if (cg_weapons[counter + 2].weaponIcon /*&& counter != WP_PROX_LAUNCHER */&& counter != WP_GRAPPLING_HOOK) { + trap_R_SetColor(colorDkGrey); + + CG_DrawPic(ACCBOARD_XPOS, ACCBOARD_YPOS + i*ACCBOARD_HEIGHT, ACCBOARD_WIDTH, ACCBOARD_HEIGHT , cgs.media.teamStatusBar); + CG_DrawPic(ACCBOARD_XPOS + 5, ACCBOARD_YPOS + i*ACCBOARD_HEIGHT, ACCITEM_SIZE, ACCITEM_SIZE, cg_weapons[counter + 2].weaponIcon); + + if (cg.accuracys[counter][0] > 0) + len = va("%i%%", (cg.accuracys[counter][1]*100) / cg.accuracys[counter][0]); + else + len = "-%"; + + CG_DrawString(ACCBOARD_XPOS + ACCBOARD_WIDTH - 5, ACCBOARD_YPOS + i * ACCBOARD_HEIGHT + ACCITEM_SIZE / 2 - SMALLCHAR_HEIGHT / 2, + len, UI_SMALLFONT | UI_RIGHT ,NULL); + + trap_R_SetColor(NULL); + i++; + } + } + return qtrue; +} /* ================= CG_DrawIntermission @@ -2658,6 +2694,8 @@ static void CG_Draw2D(stereoFrame_t stereoFrame) if ( !cg.scoreBoardShowing) { CG_DrawCenterString(); } + + CG_DrawAccboard(); } // will be called on warmup end and when client changed void CG_WarmupEvent( void ) { diff --git a/code/cgame/cg_local.h b/code/cgame/cg_local.h index d47f289535..c868b18f00 100644 --- a/code/cgame/cg_local.h +++ b/code/cgame/cg_local.h @@ -655,6 +655,10 @@ typedef struct { int damageDoneTime; int damageDone; int hitSound; + + int accuracys[WP_NUM_WEAPONS][2]; + int accRequestTime; + qboolean showAcc; } cg_t; diff --git a/code/cgame/cg_main.c b/code/cgame/cg_main.c index 702f2fb087..f91b67c41d 100644 --- a/code/cgame/cg_main.c +++ b/code/cgame/cg_main.c @@ -1136,14 +1136,13 @@ static void CG_RegisterGraphics( void ) { cgs.media.dustPuffShader = trap_R_RegisterShader("hasteSmokePuff" ); #endif - if ( cgs.gametype >= GT_TEAM || cg_buildScript.integer ) { - cgs.media.friendShader = trap_R_RegisterShader( "sprites/friend" ); - cgs.media.redQuadShader = trap_R_RegisterShader("powerups/blueflag" ); - cgs.media.teamStatusBar = trap_R_RegisterShader( "gfx/2d/colorbar.tga" ); + cgs.media.friendShader = trap_R_RegisterShader( "sprites/friend" ); + cgs.media.redQuadShader = trap_R_RegisterShader("powerups/blueflag" ); + cgs.media.teamStatusBar = trap_R_RegisterShader( "gfx/2d/colorbar.tga" ); #ifdef MISSIONPACK - cgs.media.blueKamikazeShader = trap_R_RegisterShader( "models/weaphits/kamikblu" ); + cgs.media.blueKamikazeShader = trap_R_RegisterShader( "models/weaphits/kamikblu" ); #endif - } + cgs.media.armorModel = trap_R_RegisterModel( "models/powerups/armor/armor_yel.md3" ); cgs.media.armorIcon = trap_R_RegisterShaderNoMip( "icons/iconr_yellow" ); diff --git a/code/cgame/cg_servercmds.c b/code/cgame/cg_servercmds.c index 9be6c36108..71d18b5478 100644 --- a/code/cgame/cg_servercmds.c +++ b/code/cgame/cg_servercmds.c @@ -110,7 +110,18 @@ static void CG_ParseScores( void ) { #endif } +static void CG_ParseAccuracy( void ) { + int i; + + for ( i = WP_MACHINEGUN ; i < WP_NUM_WEAPONS ; i++ ) { + cg.accuracys[i-WP_MACHINEGUN][0] = atoi( CG_Argv( (i-WP_MACHINEGUN)*2 + 1 ) ); + cg.accuracys[i-WP_MACHINEGUN][1] = atoi( CG_Argv( (i-WP_MACHINEGUN)*2 + 2 ) ); +#if DEBUG + CG_Printf("W: %i shots: %i Hits: %i\n", i,cg.accuracys[i][0], cg.accuracys[i][1]); +#endif + } +} /* ================= CG_ParseTeamInfo @@ -1062,6 +1073,11 @@ static void CG_ServerCommand( void ) { return; } + if ( !strcmp( cmd, "accs" ) ) { + CG_ParseAccuracy(); + return; + } + if ( !strcmp( cmd, "tinfo" ) ) { CG_ParseTeamInfo(); return; diff --git a/code/game/g_client.c b/code/game/g_client.c index 96260360c8..b307d9687a 100644 --- a/code/game/g_client.c +++ b/code/game/g_client.c @@ -1063,6 +1063,7 @@ void ClientSpawn(gentity_t *ent) { int savedPing; // char *savedAreaBits; int accuracy_hits, accuracy_shots; + int accuracy[WP_NUM_WEAPONS][2]; int eventSequence; char userinfo[MAX_INFO_STRING]; @@ -1120,6 +1121,8 @@ void ClientSpawn(gentity_t *ent) { // savedAreaBits = client->areabits; accuracy_hits = client->accuracy_hits; accuracy_shots = client->accuracy_shots; + memcpy(accuracy,client->accuracy,sizeof(accuracy)); + for ( i = 0 ; i < MAX_PERSISTANT ; i++ ) { persistant[i] = client->ps.persistant[i]; } @@ -1133,6 +1136,10 @@ void ClientSpawn(gentity_t *ent) { // client->areabits = savedAreaBits; client->accuracy_hits = accuracy_hits; client->accuracy_shots = accuracy_shots; + for( i = 0 ; i < WP_NUM_WEAPONS ; i++ ){ + client->accuracy[i][0] = accuracy[i][0]; + client->accuracy[i][1] = accuracy[i][1]; + } client->lastkilled_client = -1; for ( i = 0 ; i < MAX_PERSISTANT ; i++ ) { diff --git a/code/game/g_cmds.c b/code/game/g_cmds.c index b04c583378..03382eabb6 100644 --- a/code/game/g_cmds.c +++ b/code/game/g_cmds.c @@ -97,6 +97,36 @@ void DeathmatchScoreboardMessage( gentity_t *ent ) { string ) ); } +/* +================== +AccMessage + +================== +*/ +void AccMessage( gentity_t *ent ) { + char entry[1024]; + + Com_sprintf (entry, sizeof(entry), + " %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i ", // %i %i %i %i %i %i + ent->client->accuracy[WP_MACHINEGUN][0], ent->client->accuracy[WP_MACHINEGUN][1], + ent->client->accuracy[WP_SHOTGUN][0], ent->client->accuracy[WP_SHOTGUN][1], + ent->client->accuracy[WP_GRENADE_LAUNCHER][0], ent->client->accuracy[WP_GRENADE_LAUNCHER][1], + ent->client->accuracy[WP_ROCKET_LAUNCHER][0], ent->client->accuracy[WP_ROCKET_LAUNCHER][1], + ent->client->accuracy[WP_LIGHTNING][0], ent->client->accuracy[WP_LIGHTNING][1], + ent->client->accuracy[WP_RAILGUN][0], ent->client->accuracy[WP_RAILGUN][1], + ent->client->accuracy[WP_PLASMAGUN][0], ent->client->accuracy[WP_PLASMAGUN][1], + ent->client->accuracy[WP_BFG][0], ent->client->accuracy[WP_BFG][1], + 0,0, //Hook +#ifdef MISSIONPACK + ent->client->accuracy[WP_NAILGUN][0], ent->client->accuracy[WP_NAILGUN][1], + 0,0, + ent->client->accuracy[WP_CHAINGUN][0], ent->client->accuracy[WP_CHAINGUN][1] +#endif + ent->client->accuracy[WP_HMG][0], ent->client->accuracy[WP_HMG][1] + ); + + trap_SendServerCommand( ent-g_entities, va("accs%s", entry )); +} /* ================== @@ -109,6 +139,16 @@ void Cmd_Score_f( gentity_t *ent ) { DeathmatchScoreboardMessage( ent ); } +/* +================== + Cmd_Acc_f + Request current scoreboard information +================== +*/ +void Cmd_Acc_f( gentity_t *ent ) { + AccMessage( ent ); +} + /* @@ -1775,6 +1815,10 @@ void ClientCommand( int clientNum ) { Cmd_Score_f (ent); return; } + if (Q_stricmp (cmd, "acc") == 0) { + Cmd_Acc_f (ent); + return; + } // ignore all other commands when at intermission if (level.intermissiontime) { diff --git a/code/game/g_local.h b/code/game/g_local.h index 51b9629e98..a63d48ef0d 100644 --- a/code/game/g_local.h +++ b/code/game/g_local.h @@ -320,6 +320,8 @@ struct gclient_s { char *areabits; int shotgunDamagePlumDmg; //rat damage plums + + int accuracy[WP_NUM_WEAPONS][2]; }; diff --git a/code/game/g_missile.c b/code/game/g_missile.c index 656b695a5c..2a49a12dad 100644 --- a/code/game/g_missile.c +++ b/code/game/g_missile.c @@ -83,9 +83,9 @@ void G_ExplodeMissile( gentity_t *ent ) { // splash damage if ( ent->splashDamage ) { - if( G_RadiusDamage( ent->r.currentOrigin, ent->parent, ent->splashDamage, ent->splashRadius, ent - , ent->splashMethodOfDeath ) ) { + if( G_RadiusDamage( ent->r.currentOrigin, ent->parent, ent->splashDamage, ent->splashRadius, ent, ent->splashMethodOfDeath ) ) { g_entities[ent->r.ownerNum].client->accuracy_hits++; + g_entities[ent->r.ownerNum].client->accuracy[ent->s.weapon][1]++; } } @@ -313,6 +313,7 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) { if( LogAccuracyHit( other, &g_entities[ent->r.ownerNum] ) ) { g_entities[ent->r.ownerNum].client->accuracy_hits++; hitClient = qtrue; + g_entities[ent->r.ownerNum].client->accuracy[ent->s.weapon][1]++; } BG_EvaluateTrajectoryDelta( &ent->s.pos, level.time, velocity ); if ( VectorLength( velocity ) == 0 ) { @@ -433,6 +434,7 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) { other, ent->splashMethodOfDeath ) ) { if( !hitClient ) { g_entities[ent->r.ownerNum].client->accuracy_hits++; + g_entities[ent->r.ownerNum].client->accuracy[ent->s.weapon][1]++; } } } diff --git a/code/game/g_weapon.c b/code/game/g_weapon.c index 2122584547..71ccb4c02f 100644 --- a/code/game/g_weapon.c +++ b/code/game/g_weapon.c @@ -118,7 +118,10 @@ qboolean CheckGauntletAttack( gentity_t *ent ) { damage = 50 * s_quadFactor; G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, 0, MOD_GAUNTLET ); - + if (LogAccuracyHit(traceEnt, ent)) { + ent->client->accuracy[WP_GAUNTLET][0]++; + ent->client->accuracy[WP_GAUNTLET][1]++; + } return qtrue; } @@ -204,6 +207,7 @@ void Bullet_Fire (gentity_t *ent, float spread, int damage, int mod ) { tent->s.eventParm = traceEnt->s.number; if( LogAccuracyHit( traceEnt, ent ) ) { ent->client->accuracy_hits++; + ent->client->accuracy[ent->s.weapon][1]++; } } else { tent = G_TempEntity( tr.endpos, EV_BULLET_HIT_WALL ); @@ -388,8 +392,10 @@ void ShotgunPattern( vec3_t origin, vec3_t origin2, int seed, gentity_t *ent ) { if( ShotgunPellet( origin, end, ent, &hitTargets) && !hitClient ) { hitClient = qtrue; ent->client->accuracy_hits++; + ent->client->accuracy[WP_SHOTGUN][1]++; } } + ShotgunDamagePlums(&hitTargets, ent); } @@ -600,6 +606,7 @@ void weapon_railgun_fire (gentity_t *ent) { ent->client->rewardTime = level.time + REWARD_SPRITE_TIME; } ent->client->accuracy_hits++; + ent->client->accuracy[WP_RAILGUN][1]++; } } @@ -708,6 +715,7 @@ void Weapon_LightningFire( gentity_t *ent ) { #endif if( LogAccuracyHit( traceEnt, ent ) ) { ent->client->accuracy_hits++; + ent->client->accuracy[WP_LIGHTNING][1]++; } G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, 0, MOD_LIGHTNING); } @@ -869,6 +877,7 @@ void FireWeapon( gentity_t *ent ) { } #else ent->client->accuracy_shots++; + ent->client->accuracy[ent->s.weapon][0]++; #endif }