// from AS void G_SetRaceTime( edict_t *ent, int sector, unsigned int time ) { gclient_t *cl; raceRun_t *rr; cl = ent->r.client; if( ! ent->r.inuse || cl == NULL ) return; rr = &cl->level.stats.currentRun; if( sector < -1 || sector >= rr->numSectors ) return; // normal sector if( sector >= 0 ) rr->times[sector] = time; else if (rr->numSectors > 0) { raceRun_t *nrr; // new global racerun rr->times[rr->numSectors] = time; rr->timestamp = trap_Milliseconds(); // validate the client // no bots for race, at all if( ent->r.svflags & SVF_FAKECLIENT /* && mm_debug_reportbots->value == 0 */ ) { G_Printf("G_SetRaceTime: not reporting fakeclients\n"); return; } if( cl->mm_session <= 0 ) { G_Printf("G_SetRaceTime: not reporting non-registered clients\n"); return; } if( !game.raceruns ) game.raceruns = LinearAllocator( sizeof( raceRun_t ), 0, _G_LevelMalloc, _G_LevelFree ); // push new run nrr = ( raceRun_t * )LA_Alloc( game.raceruns ); memcpy( nrr, rr, sizeof( raceRun_t ) ); // reuse this one in nrr rr->times = 0; // see if we have to push intermediate result if( LA_Size( game.raceruns ) >= RACERUN_BATCH_SIZE ) { G_Match_SendReport(); // double-check this for memory-leaks if( game.raceruns != 0 ) LinearAllocator_Free( game.raceruns ); game.raceruns = 0; } } }
/* * G_Match_LaunchState */ void G_Match_LaunchState( int matchState ) { static bool advance_queue = false; if( game.asEngine != NULL ) { // give the gametype a chance to refuse the state change, or to set up things for it if( !GT_asCallMatchStateFinished( matchState ) ) return; } else { // There isn't any script, run generic fuction if( !G_Gametype_GENERIC_MatchStateFinished( matchState ) ) return; } GS_GamestatSetFlag( GAMESTAT_FLAG_MATCHEXTENDED, false ); GS_GamestatSetFlag( GAMESTAT_FLAG_WAITING, false ); if( matchState == MATCH_STATE_POSTMATCH ) { level.finalMatchDuration = game.serverTime - GS_MatchStartTime(); } if( ( matchState == MATCH_STATE_POSTMATCH && GS_RaceGametype() ) || ( matchState != MATCH_STATE_POSTMATCH && gs.gameState.stats[GAMESTAT_MATCHSTATE] == MATCH_STATE_POSTMATCH ) ) { // entering postmatch in race or leaving postmatch in normal gt G_Match_SendReport(); trap_MM_GameState( false ); } switch( matchState ) { default: case MATCH_STATE_WARMUP: { advance_queue = false; level.forceStart = false; gs.gameState.stats[GAMESTAT_MATCHSTATE] = MATCH_STATE_WARMUP; gs.gameState.longstats[GAMELONG_MATCHDURATION] = (unsigned int)( fabs( g_warmup_timelimit->value * 60 ) * 1000 ); gs.gameState.longstats[GAMELONG_MATCHSTART] = game.serverTime; // race has playtime in warmup too, so flag the matchmaker about this if( GS_RaceGametype() ) trap_MM_GameState( true ); break; } case MATCH_STATE_COUNTDOWN: { advance_queue = true; gs.gameState.stats[GAMESTAT_MATCHSTATE] = MATCH_STATE_COUNTDOWN; gs.gameState.longstats[GAMELONG_MATCHDURATION] = (unsigned int)( fabs( g_countdown_time->value ) * 1000 ); gs.gameState.longstats[GAMELONG_MATCHSTART] = game.serverTime; break; } case MATCH_STATE_PLAYTIME: { // ch : should clear some statcollection memory from warmup? advance_queue = true; // shouldn't be needed here level.forceStart = false; gs.gameState.stats[GAMESTAT_MATCHSTATE] = MATCH_STATE_PLAYTIME; gs.gameState.longstats[GAMELONG_MATCHDURATION] = (unsigned int)( fabs( 60 * g_timelimit->value )*1000 ); gs.gameState.longstats[GAMELONG_MATCHSTART] = game.serverTime; // request a new match UUID trap_ConfigString( CS_MATCHUUID, "" ); // tell matchmaker that the game is on, so if // client disconnects before SendReport, it is flagged // as 'purgable' on MM side trap_MM_GameState( true ); } break; case MATCH_STATE_POSTMATCH: { gs.gameState.stats[GAMESTAT_MATCHSTATE] = MATCH_STATE_POSTMATCH; gs.gameState.longstats[GAMELONG_MATCHDURATION] = (unsigned int)fabs( g_postmatch_timelimit->value * 1000 ); // postmatch time in seconds gs.gameState.longstats[GAMELONG_MATCHSTART] = game.serverTime; G_Timeout_Reset(); level.teamlock = false; level.forceExit = false; G_Match_Autorecord_Stats(); } break; case MATCH_STATE_WAITEXIT: { if( advance_queue ) { G_Teams_AdvanceChallengersQueue(); advance_queue = true; } gs.gameState.stats[GAMESTAT_MATCHSTATE] = MATCH_STATE_WAITEXIT; gs.gameState.longstats[GAMELONG_MATCHDURATION] = 25000; gs.gameState.longstats[GAMELONG_MATCHSTART] = game.serverTime; level.exitNow = false; } break; } // give the gametype the chance to setup for the new state if( game.asEngine != NULL ) GT_asCallMatchStateStarted(); else G_Gametype_GENERIC_MatchStateStarted(); G_UpdatePlayersMatchMsgs(); }