codemp/game/g_arenas.c

Go to the documentation of this file.
00001 // Copyright (C) 1999-2000 Id Software, Inc.
00002 //
00003 //
00004 // g_arenas.c
00005 //
00006 
00007 #include "g_local.h"
00008 
00009 
00010 gentity_t       *podium1;
00011 gentity_t       *podium2;
00012 gentity_t       *podium3;
00013 
00014 
00015 /*
00016 ==================
00017 UpdateTournamentInfo
00018 ==================
00019 */
00020 void UpdateTournamentInfo( void ) {
00021         int                     i;
00022         gentity_t       *player;
00023         int                     playerClientNum;
00024         int                     n, accuracy, perfect,   msglen;
00025         int                     buflen;
00026         int                     score1, score2;
00027         qboolean        won;
00028         char            buf[32];
00029         char            msg[MAX_STRING_CHARS];
00030 
00031         // find the real player
00032         player = NULL;
00033         for (i = 0; i < level.maxclients; i++ ) {
00034                 player = &g_entities[i];
00035                 if ( !player->inuse ) {
00036                         continue;
00037                 }
00038                 if ( !( player->r.svFlags & SVF_BOT ) ) {
00039                         break;
00040                 }
00041         }
00042         // this should never happen!
00043         if ( !player || i == level.maxclients ) {
00044                 return;
00045         }
00046         playerClientNum = i;
00047 
00048         CalculateRanks();
00049 
00050         if ( level.clients[playerClientNum].sess.sessionTeam == TEAM_SPECTATOR ) {
00051                 Com_sprintf( msg, sizeof(msg), "postgame %i %i 0 0 0 0 0 0 0 0 0 0 0", level.numNonSpectatorClients, playerClientNum );
00052         }
00053         else {
00054                 if( player->client->accuracy_shots ) {
00055                         accuracy = player->client->accuracy_hits * 100 / player->client->accuracy_shots;
00056                 }
00057                 else {
00058                         accuracy = 0;
00059                 }
00060                 won = qfalse;
00061                 if (g_gametype.integer >= GT_CTF) {
00062                         score1 = level.teamScores[TEAM_RED];
00063                         score2 = level.teamScores[TEAM_BLUE];
00064                         if (level.clients[playerClientNum].sess.sessionTeam     == TEAM_RED) {
00065                                 won = (level.teamScores[TEAM_RED] > level.teamScores[TEAM_BLUE]);
00066                         } else {
00067                                 won = (level.teamScores[TEAM_BLUE] > level.teamScores[TEAM_RED]);
00068                         }
00069                 } else {
00070                         if (&level.clients[playerClientNum] == &level.clients[ level.sortedClients[0] ]) {
00071                                 won = qtrue;
00072                                 score1 = level.clients[ level.sortedClients[0] ].ps.persistant[PERS_SCORE];
00073                                 score2 = level.clients[ level.sortedClients[1] ].ps.persistant[PERS_SCORE];
00074                         } else {
00075                                 score2 = level.clients[ level.sortedClients[0] ].ps.persistant[PERS_SCORE];
00076                                 score1 = level.clients[ level.sortedClients[1] ].ps.persistant[PERS_SCORE];
00077                         }
00078                 }
00079                 if (won && player->client->ps.persistant[PERS_KILLED] == 0) {
00080                         perfect = 1;
00081                 } else {
00082                         perfect = 0;
00083                 }
00084                 Com_sprintf( msg, sizeof(msg), "postgame %i %i %i %i %i %i %i %i %i %i %i %i %i %i", level.numNonSpectatorClients, playerClientNum, accuracy,
00085                         player->client->ps.persistant[PERS_IMPRESSIVE_COUNT], player->client->ps.persistant[PERS_EXCELLENT_COUNT],player->client->ps.persistant[PERS_DEFEND_COUNT],
00086                         player->client->ps.persistant[PERS_ASSIST_COUNT], player->client->ps.persistant[PERS_GAUNTLET_FRAG_COUNT], player->client->ps.persistant[PERS_SCORE],
00087                         perfect, score1, score2, level.time, player->client->ps.persistant[PERS_CAPTURES] );
00088         }
00089 
00090         msglen = strlen( msg );
00091         for( i = 0; i < level.numNonSpectatorClients; i++ ) {
00092                 n = level.sortedClients[i];
00093                 Com_sprintf( buf, sizeof(buf), " %i %i %i", n, level.clients[n].ps.persistant[PERS_RANK], level.clients[n].ps.persistant[PERS_SCORE] );
00094                 buflen = strlen( buf );
00095                 if( msglen + buflen + 1 >= sizeof(msg) ) {
00096                         break;
00097                 }
00098                 strcat( msg, buf );
00099         }
00100         trap_SendConsoleCommand( EXEC_APPEND, msg );
00101 }
00102 
00103 
00104 /*
00105 static gentity_t *SpawnModelOnVictoryPad( gentity_t *pad, vec3_t offset, gentity_t *ent, int place ) {
00106         gentity_t       *body;
00107         vec3_t          vec;
00108         vec3_t          f, r, u;
00109 
00110         body = G_Spawn();
00111         if ( !body ) {
00112                 G_Printf( S_COLOR_RED "ERROR: out of gentities\n" );
00113                 return NULL;
00114         }
00115 
00116         body->classname = ent->client->pers.netname;
00117         body->client = ent->client;
00118         body->s = ent->s;
00119         body->s.eType = ET_PLAYER;              // could be ET_INVISIBLE
00120         body->s.eFlags = 0;                             // clear EF_TALK, etc
00121         body->s.powerups = 0;                   // clear powerups
00122         body->s.loopSound = 0;                  // clear lava burning
00123         body->s.number = body - g_entities;
00124         body->timestamp = level.time;
00125         body->physicsObject = qtrue;
00126         body->physicsBounce = 0;                // don't bounce
00127         body->s.event = 0;
00128         body->s.pos.trType = TR_STATIONARY;
00129         body->s.groundEntityNum = ENTITYNUM_WORLD;
00130         body->s.legsAnim = WeaponReadyAnim[ent->s.weapon];
00131         body->s.torsoAnim = WeaponReadyAnim[ent->s.weapon];
00132         if( body->s.weapon == WP_NONE ) {
00133                 body->s.weapon = WP_BRYAR_PISTOL;
00134         }
00135         if( body->s.weapon == WP_SABER) {
00136                 body->s.torsoAnim = BOTH_STAND2;
00137         }
00138         body->s.event = 0;
00139         body->r.svFlags = ent->r.svFlags;
00140         VectorCopy (ent->r.mins, body->r.mins);
00141         VectorCopy (ent->r.maxs, body->r.maxs);
00142         VectorCopy (ent->r.absmin, body->r.absmin);
00143         VectorCopy (ent->r.absmax, body->r.absmax);
00144         body->clipmask = CONTENTS_SOLID | CONTENTS_PLAYERCLIP;
00145         body->r.contents = CONTENTS_BODY;
00146         body->r.ownerNum = ent->r.ownerNum;
00147         body->takedamage = qfalse;
00148 
00149         VectorSubtract( level.intermission_origin, pad->r.currentOrigin, vec );
00150         vectoangles( vec, body->s.apos.trBase );
00151         body->s.apos.trBase[PITCH] = 0;
00152         body->s.apos.trBase[ROLL] = 0;
00153 
00154         AngleVectors( body->s.apos.trBase, f, r, u );
00155         VectorMA( pad->r.currentOrigin, offset[0], f, vec );
00156         VectorMA( vec, offset[1], r, vec );
00157         VectorMA( vec, offset[2], u, vec );
00158 
00159         G_SetOrigin( body, vec );
00160 
00161         trap_LinkEntity (body);
00162 
00163         body->count = place;
00164 
00165         return body;
00166 }
00167 
00168 
00169 static void CelebrateStop( gentity_t *player ) {
00170         int             anim;
00171 
00172         if( player->s.weapon == WP_SABER) {
00173                 anim = BOTH_STAND2;
00174         }
00175         else {
00176                 anim = WeaponReadyAnim[player->s.weapon];
00177         }
00178         player->s.torsoAnim = ( ( player->s.torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim;
00179 }
00180 
00181 
00182 #define TIMER_GESTURE   (34*66+50)
00183 static void CelebrateStart( gentity_t *player ) {
00184         player->s.torsoAnim = ( ( player->s.torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | BOTH_TALKGESTURE1;
00185         player->nextthink = level.time + TIMER_GESTURE;
00186         player->think = CelebrateStop;
00187 
00188         
00189 //      player->client->ps.events[player->client->ps.eventSequence & (MAX_PS_EVENTS-1)] = EV_TAUNT;
00190 //      player->client->ps.eventParms[player->client->ps.eventSequence & (MAX_PS_EVENTS-1)] = 0;
00191 //      player->client->ps.eventSequence++;
00192         
00193         G_AddEvent(player, EV_TAUNT, 0);
00194 }
00195 
00196 
00197 static vec3_t   offsetFirst  = {0, 0, 74};
00198 static vec3_t   offsetSecond = {-10, 60, 54};
00199 static vec3_t   offsetThird  = {-19, -60, 45};
00200 
00201 static void PodiumPlacementThink( gentity_t *podium ) {
00202         vec3_t          vec;
00203         vec3_t          origin;
00204         vec3_t          f, r, u;
00205 
00206         podium->nextthink = level.time + 100;
00207 
00208         AngleVectors( level.intermission_angle, vec, NULL, NULL );
00209         VectorMA( level.intermission_origin, trap_Cvar_VariableIntegerValue( "g_podiumDist" ), vec, origin );
00210         origin[2] -= trap_Cvar_VariableIntegerValue( "g_podiumDrop" );
00211         G_SetOrigin( podium, origin );
00212 
00213         if( podium1 ) {
00214                 VectorSubtract( level.intermission_origin, podium->r.currentOrigin, vec );
00215                 vectoangles( vec, podium1->s.apos.trBase );
00216                 podium1->s.apos.trBase[PITCH] = 0;
00217                 podium1->s.apos.trBase[ROLL] = 0;
00218 
00219                 AngleVectors( podium1->s.apos.trBase, f, r, u );
00220                 VectorMA( podium->r.currentOrigin, offsetFirst[0], f, vec );
00221                 VectorMA( vec, offsetFirst[1], r, vec );
00222                 VectorMA( vec, offsetFirst[2], u, vec );
00223 
00224                 G_SetOrigin( podium1, vec );
00225         }
00226 
00227         if( podium2 ) {
00228                 VectorSubtract( level.intermission_origin, podium->r.currentOrigin, vec );
00229                 vectoangles( vec, podium2->s.apos.trBase );
00230                 podium2->s.apos.trBase[PITCH] = 0;
00231                 podium2->s.apos.trBase[ROLL] = 0;
00232 
00233                 AngleVectors( podium2->s.apos.trBase, f, r, u );
00234                 VectorMA( podium->r.currentOrigin, offsetSecond[0], f, vec );
00235                 VectorMA( vec, offsetSecond[1], r, vec );
00236                 VectorMA( vec, offsetSecond[2], u, vec );
00237 
00238                 G_SetOrigin( podium2, vec );
00239         }
00240 
00241         if( podium3 ) {
00242                 VectorSubtract( level.intermission_origin, podium->r.currentOrigin, vec );
00243                 vectoangles( vec, podium3->s.apos.trBase );
00244                 podium3->s.apos.trBase[PITCH] = 0;
00245                 podium3->s.apos.trBase[ROLL] = 0;
00246 
00247                 AngleVectors( podium3->s.apos.trBase, f, r, u );
00248                 VectorMA( podium->r.currentOrigin, offsetThird[0], f, vec );
00249                 VectorMA( vec, offsetThird[1], r, vec );
00250                 VectorMA( vec, offsetThird[2], u, vec );
00251 
00252                 G_SetOrigin( podium3, vec );
00253         }
00254 }
00255 
00256 
00257 static gentity_t *SpawnPodium( void ) {
00258         gentity_t       *podium;
00259         vec3_t          vec;
00260         vec3_t          origin;
00261 
00262         podium = G_Spawn();
00263         if ( !podium ) {
00264                 return NULL;
00265         }
00266 
00267         podium->classname = "podium";
00268         podium->s.eType = ET_GENERAL;
00269         podium->s.number = podium - g_entities;
00270         podium->clipmask = CONTENTS_SOLID;
00271         podium->r.contents = CONTENTS_SOLID;
00272         podium->s.modelindex = G_ModelIndex( SP_PODIUM_MODEL );
00273 
00274         AngleVectors( level.intermission_angle, vec, NULL, NULL );
00275         VectorMA( level.intermission_origin, trap_Cvar_VariableIntegerValue( "g_podiumDist" ), vec, origin );
00276         origin[2] -= trap_Cvar_VariableIntegerValue( "g_podiumDrop" );
00277         G_SetOrigin( podium, origin );
00278 
00279         VectorSubtract( level.intermission_origin, podium->r.currentOrigin, vec );
00280         podium->s.apos.trBase[YAW] = vectoyaw( vec );
00281         trap_LinkEntity (podium);
00282 
00283         podium->think = PodiumPlacementThink;
00284         podium->nextthink = level.time + 100;
00285         return podium;
00286 }
00287 
00288 
00289 
00290 //==================
00291 //SpawnModelsOnVictoryPads
00292 //==================
00293 
00294 void SpawnModelsOnVictoryPads( void ) {
00295         gentity_t       *player;
00296         gentity_t       *podium;
00297 
00298         podium1 = NULL;
00299         podium2 = NULL;
00300         podium3 = NULL;
00301 
00302         podium = SpawnPodium();
00303 
00304         player = SpawnModelOnVictoryPad( podium, offsetFirst, &g_entities[level.sortedClients[0]],
00305                                 level.clients[ level.sortedClients[0] ].ps.persistant[PERS_RANK] &~ RANK_TIED_FLAG );
00306         if ( player ) {
00307                 player->nextthink = level.time + 2000;
00308                 player->think = CelebrateStart;
00309                 podium1 = player;
00310         }
00311 
00312         player = SpawnModelOnVictoryPad( podium, offsetSecond, &g_entities[level.sortedClients[1]],
00313                                 level.clients[ level.sortedClients[1] ].ps.persistant[PERS_RANK] &~ RANK_TIED_FLAG );
00314         if ( player ) {
00315                 podium2 = player;
00316         }
00317 
00318         if ( level.numNonSpectatorClients > 2 ) {
00319                 player = SpawnModelOnVictoryPad( podium, offsetThird, &g_entities[level.sortedClients[2]],
00320                                 level.clients[ level.sortedClients[2] ].ps.persistant[PERS_RANK] &~ RANK_TIED_FLAG );
00321                 if ( player ) {
00322                         podium3 = player;
00323                 }
00324         }
00325 }
00326 
00327 
00328 
00329 //===============
00330 //Svcmd_AbortPodium_f
00331 //===============
00332 
00333 void Svcmd_AbortPodium_f( void ) {
00334         if( g_gametype.integer != GT_SINGLE_PLAYER ) {
00335                 return;
00336         }
00337 
00338         if( podium1 ) {
00339                 podium1->nextthink = level.time;
00340                 podium1->think = CelebrateStop;
00341         }
00342 }
00343 */