Exemple #1
0
/*
* G_Timeout_Reset
*/
void G_Timeout_Reset( void )
{
	int i;

	GS_GamestatSetFlag( GAMESTAT_FLAG_PAUSED, false );
	level.timeout.time = 0;
	level.timeout.endtime = 0;
	level.timeout.caller = 0;
	for( i = 0; i < MAX_CLIENTS; i++ )
		level.timeout.used[i] = 0;
}
/*
* G_Match_CheckExtendPlayTime
*/
bool G_Match_CheckExtendPlayTime( void )
{
	// check for extended time/sudden death
	if( GS_MatchState() != MATCH_STATE_PLAYTIME )
		return false;

	if( GS_TeamBasedGametype() && !level.forceExit )
	{
		if( G_Match_Tied() )
		{
			GS_GamestatSetFlag( GAMESTAT_FLAG_MATCHEXTENDED, true );
			gs.gameState.stats[GAMESTAT_MATCHSTATE] = MATCH_STATE_PLAYTIME;
			gs.gameState.longstats[GAMELONG_MATCHSTART] = game.serverTime;

			if( g_match_extendedtime->value )
			{
				if( !GS_MatchExtended() )  // first one
					G_AnnouncerSound( NULL, trap_SoundIndex( S_ANNOUNCER_OVERTIME_GOING_TO_OVERTIME ), GS_MAX_TEAMS, true, NULL );
				else
					G_AnnouncerSound( NULL, trap_SoundIndex( S_ANNOUNCER_OVERTIME_OVERTIME ), GS_MAX_TEAMS, true, NULL );

				G_PrintMsg( NULL, "Match tied. Timelimit extended by %i minutes!\n", g_match_extendedtime->integer );
				G_CenterPrintFormatMsg( NULL, "%s MINUTE OVERTIME\n", va( "%i", g_match_extendedtime->integer ), NULL );
				gs.gameState.longstats[GAMELONG_MATCHDURATION] = (unsigned int)( ( fabs( g_match_extendedtime->value ) * 60 ) * 1000 );
			}
			else
			{
				G_AnnouncerSound( NULL, trap_SoundIndex( va( S_ANNOUNCER_OVERTIME_SUDDENDEATH_1_to_2, ( rand()&1 )+1 ) ), GS_MAX_TEAMS, true, NULL );
				G_PrintMsg( NULL, "Match tied. Sudden death!\n" );
				G_CenterPrintMsg( NULL, "SUDDEN DEATH" );
				gs.gameState.longstats[GAMELONG_MATCHDURATION] = 0;
			}

			return true;
		}
	}

	return false;
}
Exemple #3
0
/*
* Cmd_Timeout_f
*/
static void Cmd_Timeout_f( edict_t *ent )
{
	int num;

	if( ent->s.team == TEAM_SPECTATOR || GS_MatchState() != MATCH_STATE_PLAYTIME )
		return;

	if( GS_TeamBasedGametype() )
		num = ent->s.team;
	else
		num = ENTNUM( ent )-1;

	if( GS_MatchPaused() && ( level.timeout.endtime - level.timeout.time ) >= 2*TIMEIN_TIME )
	{
		G_PrintMsg( ent, "Timeout already in progress\n" );
		return;
	}

	if( g_maxtimeouts->integer != -1 && level.timeout.used[num] >= g_maxtimeouts->integer )
	{
		if( g_maxtimeouts->integer == 0 )
			G_PrintMsg( ent, "Timeouts are not allowed on this server\n" );
		else if( GS_TeamBasedGametype() )
			G_PrintMsg( ent, "Your team doesn't have any timeouts left\n" );
		else
			G_PrintMsg( ent, "You don't have any timeouts left\n" );
		return;
	}

	G_PrintMsg( NULL, "%s%s called a timeout\n", ent->r.client->netname, S_COLOR_WHITE );

	if( !GS_MatchPaused() )
		G_AnnouncerSound( NULL, trap_SoundIndex( va( S_ANNOUNCER_TIMEOUT_TIMEOUT_1_to_2, ( rand()&1 )+1 ) ), GS_MAX_TEAMS, true, NULL );

	level.timeout.used[num]++;
	GS_GamestatSetFlag( GAMESTAT_FLAG_PAUSED, true );
	level.timeout.caller = num;
	level.timeout.endtime = level.timeout.time + TIMEOUT_TIME + FRAMETIME;
}
/*
* 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();
}
/*
* 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();
	}
}
Exemple #6
0
/*
* G_Timeout_Update
* 
* Updates the timeout struct and informs clients about the status of the pause
*/
static void G_Timeout_Update( unsigned int msec )
{
	static int timeout_printtime = 0;
	static int timeout_last_endtime = 0;
	static int countdown_set = 1;

	if( !GS_MatchPaused() )
		return;

	game.frametime = 0;

	if( timeout_last_endtime != level.timeout.endtime ) // force print when endtime is changed
	{
		timeout_printtime = 0;
		timeout_last_endtime = level.timeout.endtime;
	}

	level.timeout.time += msec;
	if( level.timeout.endtime && level.timeout.time >= level.timeout.endtime )
	{
		level.timeout.time = 0;
		level.timeout.caller = -1;
		GS_GamestatSetFlag( GAMESTAT_FLAG_PAUSED, false );

		timeout_printtime = 0;
		timeout_last_endtime = -1;

		G_AnnouncerSound( NULL, trap_SoundIndex( va( S_ANNOUNCER_TIMEOUT_MATCH_RESUMED_1_to_2, ( rand()&1 )+1 ) ),
			GS_MAX_TEAMS, true, NULL );
		G_CenterPrintMsg( NULL, "Match resumed" );
		G_PrintMsg( NULL, "Match resumed\n" );
	}
	else if( timeout_printtime == 0 || level.timeout.time - timeout_printtime >= 1000 )
	{
		if( level.timeout.endtime )
		{
			int seconds_left = (int)( ( level.timeout.endtime - level.timeout.time ) / 1000.0 + 0.5 );

			if( seconds_left == ( TIMEIN_TIME * 2 ) / 1000 )
			{
				G_AnnouncerSound( NULL, trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_READY_1_to_2, ( rand()&1 )+1 ) ),
					GS_MAX_TEAMS, false, NULL );
				countdown_set = ( rand()&1 )+1;
			}
			else if( seconds_left >= 1 && seconds_left <= 3 )
			{
				G_AnnouncerSound( NULL, trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_COUNT_1_to_3_SET_1_to_2, seconds_left,
					countdown_set ) ), GS_MAX_TEAMS, false, NULL );
			}

			if( seconds_left > 1 )
				G_CenterPrintFormatMsg( NULL, "Match will resume in %s seconds", va( "%i", seconds_left ), NULL );
			else
				G_CenterPrintMsg( NULL, "Match will resume in 1 second" );
		}
		else
		{
			G_CenterPrintMsg( NULL, "Match paused" );
		}

		timeout_printtime = level.timeout.time;
	}
}
Exemple #7
0
/*
* G_CheckCvars
* Check for cvars that have been modified and need the game to be updated
*/
void G_CheckCvars( void )
{
	if( g_antilag_maxtimedelta->modified )
	{
		if( g_antilag_maxtimedelta->integer < 0 )
			trap_Cvar_SetValue( "g_antilag_maxtimedelta", abs( g_antilag_maxtimedelta->integer ) );
		g_antilag_maxtimedelta->modified = false;
		g_antilag_timenudge->modified = true;
	}

	if( g_antilag_timenudge->modified )
	{
		if( g_antilag_timenudge->integer > g_antilag_maxtimedelta->integer )
			trap_Cvar_SetValue( "g_antilag_timenudge", g_antilag_maxtimedelta->integer );
		else if( g_antilag_timenudge->integer < -g_antilag_maxtimedelta->integer )
			trap_Cvar_SetValue( "g_antilag_timenudge", -g_antilag_maxtimedelta->integer );
		g_antilag_timenudge->modified = false;
	}

	if( g_warmup_timelimit->modified )
	{
		// if we are inside timelimit period, update the endtime
		if( GS_MatchState() == MATCH_STATE_WARMUP )
		{
			gs.gameState.longstats[GAMELONG_MATCHDURATION] = (unsigned int)fabs( 60.0f * 1000 * g_warmup_timelimit->integer );
		}
		g_warmup_timelimit->modified = false;
	}

	if( g_timelimit->modified )
	{
		// if we are inside timelimit period, update the endtime
		if( GS_MatchState() == MATCH_STATE_PLAYTIME &&
			!GS_MatchExtended() )
		{
			if( g_timelimit->value )
				gs.gameState.longstats[GAMELONG_MATCHDURATION] = (unsigned int)fabs( 60.0f * 1000 * g_timelimit->value );
			else
				gs.gameState.longstats[GAMELONG_MATCHDURATION] = 0;
		}
		g_timelimit->modified = false;
	}

	if( g_match_extendedtime->modified )
	{
		// if we are inside extended_time period, update the endtime
		if( GS_MatchExtended() )
		{
			if( g_match_extendedtime->integer )
				gs.gameState.longstats[GAMELONG_MATCHDURATION] = (unsigned int)fabs( 60 * 1000 * g_match_extendedtime->value );
		}
		g_match_extendedtime->modified = false;
	}

	if( g_allow_falldamage->modified )
	{
		g_allow_falldamage->modified = false;
	}

	// update gameshared server settings

	// FIXME: This should be restructured so gameshared settings are the master settings
	GS_GamestatSetFlag( GAMESTAT_FLAG_INSTAGIB, ( g_instagib->integer != 0 ) );
	GS_GamestatSetFlag( GAMESTAT_FLAG_FALLDAMAGE, ( g_allow_falldamage->integer != 0 ) );
	GS_GamestatSetFlag( GAMESTAT_FLAG_SELFDAMAGE, ( g_allow_selfdamage->integer != 0 ) );
	GS_GamestatSetFlag( GAMESTAT_FLAG_HASCHALLENGERS, ( level.gametype.hasChallengersQueue != 0 ) );

	GS_GamestatSetFlag( GAMESTAT_FLAG_ISTEAMBASED, ( level.gametype.isTeamBased != 0 ) );
	GS_GamestatSetFlag( GAMESTAT_FLAG_ISRACE, ( level.gametype.isRace != 0 ) );

	GS_GamestatSetFlag( GAMESTAT_FLAG_COUNTDOWN, level.gametype.countdownEnabled );
	GS_GamestatSetFlag( GAMESTAT_FLAG_INHIBITSHOOTING, level.gametype.shootingDisabled );
	GS_GamestatSetFlag( GAMESTAT_FLAG_INFINITEAMMO, ( level.gametype.infiniteAmmo || GS_Instagib() ) != 0 );
	GS_GamestatSetFlag( GAMESTAT_FLAG_CANFORCEMODELS, level.gametype.canForceModels );
	GS_GamestatSetFlag( GAMESTAT_FLAG_CANSHOWMINIMAP, level.gametype.canShowMinimap );
	GS_GamestatSetFlag( GAMESTAT_FLAG_TEAMONLYMINIMAP, level.gametype.teamOnlyMinimap );

	GS_GamestatSetFlag( GAMESTAT_FLAG_MMCOMPATIBLE, level.gametype.mmCompatible );

	GS_GamestatSetLongFlag( GAMELONG_FLAG_ISTUTORIAL, ( level.gametype.isTutorial != 0 ) );

	gs.gameState.stats[GAMESTAT_MAXPLAYERSINTEAM] = level.gametype.maxPlayersPerTeam;
	clamp( gs.gameState.stats[GAMESTAT_MAXPLAYERSINTEAM], 0, 255 );

}