예제 #1
0
/*
* 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;
}
예제 #2
0
/*
* 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;
}
예제 #3
0
/*
* 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();
	}
}
예제 #4
0
//==========================================
// 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;
	}
}
예제 #5
0
/*
* 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" );
	}
}
예제 #6
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
	}
}