/* * G_Match_SuddenDeathFinished */ bool G_Match_SuddenDeathFinished( void ) { if( GS_MatchState() != MATCH_STATE_PLAYTIME ) return false; if( !GS_MatchExtended() || GS_MatchDuration() ) return false; return G_Match_Tied() ? false : true; }
/* * G_Match_TimelimitHit */ bool G_Match_TimelimitHit( void ) { // check for timelimit hit if( !GS_MatchDuration() || game.serverTime < GS_MatchEndTime() ) return false; if( GS_MatchState() == MATCH_STATE_WARMUP ) level.forceStart = true; // force match starting when timelimit is up, even if someone goes unready if( GS_MatchState() == MATCH_STATE_WAITEXIT ) { level.exitNow = true; return false; // don't advance into next state. The match will be restarted } return true; }
/* * G_Match_CheckStateAbort */ static void G_Match_CheckStateAbort( void ) { bool any = false; bool enough; if( GS_MatchState() <= MATCH_STATE_NONE || GS_MatchState() >= MATCH_STATE_POSTMATCH || level.gametype.mathAbortDisabled ) { GS_GamestatSetFlag( GAMESTAT_FLAG_WAITING, false ); return; } if( GS_TeamBasedGametype() ) { int team, emptyteams = 0; for( team = TEAM_ALPHA; team < GS_MAX_TEAMS; team++ ) { if( !teamlist[team].numplayers ) emptyteams++; else any = true; } enough = ( emptyteams == 0 ); } else { enough = ( teamlist[TEAM_PLAYERS].numplayers > 1 ); any = ( teamlist[TEAM_PLAYERS].numplayers > 0 ); } // if waiting, turn on match states when enough players joined if( GS_MatchWaiting() && enough ) { GS_GamestatSetFlag( GAMESTAT_FLAG_WAITING, false ); G_UpdatePlayersMatchMsgs(); } // turn off active match states if not enough players left else if( GS_MatchState() == MATCH_STATE_WARMUP && !enough && GS_MatchDuration() ) { GS_GamestatSetFlag( GAMESTAT_FLAG_WAITING, true ); G_UpdatePlayersMatchMsgs(); } else if( GS_MatchState() == MATCH_STATE_COUNTDOWN && !enough ) { if( any ) { G_PrintMsg( NULL, "Not enough players left. Countdown aborted.\n" ); G_CenterPrintMsg( NULL, "COUNTDOWN ABORTED" ); } G_Match_Autorecord_Cancel(); G_Match_LaunchState( MATCH_STATE_WARMUP ); GS_GamestatSetFlag( GAMESTAT_FLAG_WAITING, true ); G_UpdatePlayersMatchMsgs(); } // match running, but not enough players left else if( GS_MatchState() == MATCH_STATE_PLAYTIME && !enough ) { if( any ) { G_PrintMsg( NULL, "Not enough players left. Match aborted.\n" ); G_CenterPrintMsg( NULL, "MATCH ABORTED" ); } G_EndMatch(); } }
//========================================== // BOT_DMclass_VSAYmessages //========================================== static void BOT_DMclass_VSAYmessages( edict_t *self ) { if( GS_MatchState() != MATCH_STATE_PLAYTIME ) return; if( level.gametype.dummyBots || bot_dummy->integer ) return; if( self->snap.damageteam_given > 25 ) { if( rand() & 1 ) { if( rand() & 1 ) { G_BOTvsay_f( self, "oops", true ); } else { G_BOTvsay_f( self, "sorry", true ); } } return; } if( self->ai->vsay_timeout > level.time ) return; if( GS_MatchDuration() && game.serverTime + 4000 > GS_MatchEndTime() ) { self->ai->vsay_timeout = game.serverTime + ( 1000 + (GS_MatchEndTime() - game.serverTime) ); if( rand() & 1 ) G_BOTvsay_f( self, "goodgame", false ); return; } self->ai->vsay_timeout = level.time + ( ( 8+random()*12 ) * 1000 ); // the more bots, the less vsays to play if( random() > 0.1 + 1.0f / game.numBots ) return; if( GS_TeamBasedGametype() && !GS_InvidualGameType() ) { if( self->health < 20 && random() > 0.3 ) { G_BOTvsay_f( self, "needhealth", true ); return; } if( ( self->s.weapon == 0 || self->s.weapon == 1 ) && random() > 0.7 ) { G_BOTvsay_f( self, "needweapon", true ); return; } if( self->r.client->resp.armor < 10 && random() > 0.8 ) { G_BOTvsay_f( self, "needarmor", true ); return; } } // NOT team based here if( random() > 0.2 ) return; switch( (int)brandom( 1, 8 ) ) { default: break; case 1: G_BOTvsay_f( self, "roger", false ); break; case 2: G_BOTvsay_f( self, "noproblem", false ); break; case 3: G_BOTvsay_f( self, "yeehaa", false ); break; case 4: G_BOTvsay_f( self, "yes", false ); break; case 5: G_BOTvsay_f( self, "no", false ); break; case 6: G_BOTvsay_f( self, "booo", false ); break; case 7: G_BOTvsay_f( self, "attack", false ); break; case 8: G_BOTvsay_f( self, "ok", false ); break; } }
/* * G_UpdateServerInfo * update the cvars which show the match state at server browsers */ static void G_UpdateServerInfo( void ) { // g_match_time if( GS_MatchState() <= MATCH_STATE_WARMUP ) { trap_Cvar_ForceSet( "g_match_time", "Warmup" ); } else if( GS_MatchState() == MATCH_STATE_COUNTDOWN ) { trap_Cvar_ForceSet( "g_match_time", "Countdown" ); } else if( GS_MatchState() == MATCH_STATE_PLAYTIME ) { // partly from G_GetMatchState char extra[MAX_INFO_VALUE]; int clocktime, timelimit, mins, secs; if( GS_MatchDuration() ) timelimit = ( ( GS_MatchDuration() ) * 0.001 ) / 60; else timelimit = 0; clocktime = (float)( game.serverTime - GS_MatchStartTime() ) * 0.001f; if( clocktime <= 0 ) { mins = 0; secs = 0; } else { mins = clocktime / 60; secs = clocktime - mins * 60; } extra[0] = 0; if( GS_MatchExtended() ) { if( timelimit ) Q_strncatz( extra, " overtime", sizeof( extra ) ); else Q_strncatz( extra, " suddendeath", sizeof( extra ) ); } if( GS_MatchPaused() ) Q_strncatz( extra, " (in timeout)", sizeof( extra ) ); if( timelimit ) trap_Cvar_ForceSet( "g_match_time", va( "%02i:%02i / %02i:00%s", mins, secs, timelimit, extra ) ); else trap_Cvar_ForceSet( "g_match_time", va( "%02i:%02i%s", mins, secs, extra ) ); } else { trap_Cvar_ForceSet( "g_match_time", "Finished" ); } // g_match_score if( GS_MatchState() >= MATCH_STATE_PLAYTIME && GS_TeamBasedGametype() ) { char score[MAX_INFO_STRING]; score[0] = 0; Q_strncatz( score, va( " %s: %i", GS_TeamName( TEAM_ALPHA ), teamlist[TEAM_ALPHA].stats.score ), sizeof( score ) ); Q_strncatz( score, va( " %s: %i", GS_TeamName( TEAM_BETA ), teamlist[TEAM_BETA].stats.score ), sizeof( score ) ); if( strlen( score ) >= MAX_INFO_VALUE ) { // prevent "invalid info cvar value" flooding score[0] = '\0'; } trap_Cvar_ForceSet( "g_match_score", score ); } else { trap_Cvar_ForceSet( "g_match_score", "" ); } // g_needpass if( password->modified ) { if( password->string && strlen( password->string ) ) { trap_Cvar_ForceSet( "g_needpass", "1" ); } else { trap_Cvar_ForceSet( "g_needpass", "0" ); } password->modified = false; } // g_gametypes_available if( g_votable_gametypes->modified || g_disable_vote_gametype->modified ) { if( g_disable_vote_gametype->integer || !g_votable_gametypes->string || !strlen( g_votable_gametypes->string ) ) { trap_Cvar_ForceSet( "g_gametypes_available", "" ); } else { char *votable; char *name; size_t len; int count; len = 0; for( count = 0; ( name = G_ListNameForPosition( g_gametypes_list->string, count, CHAR_GAMETYPE_SEPARATOR ) ) != NULL; count++ ) { if( G_Gametype_IsVotable( name ) ) len += strlen( name ) + 1; } len++; votable = ( char * )G_Malloc( len ); votable[0] = 0; for( count = 0; ( name = G_ListNameForPosition( g_gametypes_list->string, count, CHAR_GAMETYPE_SEPARATOR ) ) != NULL; count++ ) { if( G_Gametype_IsVotable( name ) ) { Q_strncatz( votable, name, len ); Q_strncatz( votable, " ", len ); } } //votable[ strlen( votable )-2 ] = 0; // remove the last space trap_Cvar_ForceSet( "g_gametypes_available", votable ); G_Free( votable ); } g_votable_gametypes->modified = false; g_disable_vote_gametype->modified = false; } if( GS_RaceGametype() ) { trap_Cvar_ForceSet( "g_race_gametype", "1" ); } else { trap_Cvar_ForceSet( "g_race_gametype", "0" ); } }
/* * CG_AddLocalSounds */ static void CG_AddLocalSounds( void ) { static bool postmatchsound_set = false, demostream = false, background = false; static unsigned int lastSecond = 0; // add local announces if( GS_Countdown() ) { if( GS_MatchDuration() ) { unsigned int duration, curtime, remainingSeconds; float seconds; curtime = GS_MatchPaused() ? cg.frame.serverTime : cg.time; duration = GS_MatchDuration(); if( duration + GS_MatchStartTime() < curtime ) duration = curtime - GS_MatchStartTime(); // avoid negative results seconds = (float)( GS_MatchStartTime() + duration - curtime ) * 0.001f; remainingSeconds = (unsigned int)seconds; if( remainingSeconds != lastSecond ) { if( 1 + remainingSeconds < 4 ) { struct sfx_s *sound = trap_S_RegisterSound( va( S_ANNOUNCER_COUNTDOWN_COUNT_1_to_3_SET_1_to_2, 1 + remainingSeconds, 1 ) ); CG_AddAnnouncerEvent( sound, false ); } lastSecond = remainingSeconds; } } } else lastSecond = 0; // add sounds from announcer CG_ReleaseAnnouncerEvents(); // if in postmatch, play postmatch song if( GS_MatchState() >= MATCH_STATE_POSTMATCH ) { if( !postmatchsound_set && !demostream ) { trap_S_StartBackgroundTrack( S_PLAYLIST_POSTMATCH, NULL, 3 ); // loop random track from the playlist postmatchsound_set = true; background = false; } } else { if( cgs.demoPlaying && cgs.demoAudioStream && !demostream ) { trap_S_StartBackgroundTrack( cgs.demoAudioStream, NULL, 0 ); demostream = true; } if( postmatchsound_set ) { trap_S_StopBackgroundTrack(); postmatchsound_set = false; background = false; } if( (!postmatchsound_set && !demostream) && !background ) { CG_StartBackgroundTrack(); background = true; } // notice: these 2 sound files aren't used anymore //cgs.media.sfxTimerBipBip //cgs.media.sfxTimerPloink } }