Exemple #1
0
/*
* G_Teams_ExecuteChallengersQueue
*/
void G_Teams_ExecuteChallengersQueue( void )
{
	edict_t *ent;
	edict_t **challengers;
	bool restartmatch = false;

	// Medar fixme: this is only really makes sense, if playerlimit per team is one
	if( GS_MatchState() == MATCH_STATE_PLAYTIME )
		return;

	if( !GS_HasChallengers() )
		return;

	if( game.realtime < level.spawnedTimeStamp + G_CHALLENGERS_MIN_JOINTEAM_MAPTIME )
	{
		static int time, lasttime;
		time = (int)( ( G_CHALLENGERS_MIN_JOINTEAM_MAPTIME - ( game.realtime - level.spawnedTimeStamp ) )*0.001 );
		if( lasttime && time == lasttime )
			return;
		lasttime = time;
		if( lasttime )
			G_CenterPrintFormatMsg( NULL, "Waiting... %s", va( "%i", lasttime ), NULL );
		else
			G_CenterPrintMsg( NULL, "" );
		return;
	}

	// pick players in join order and try to put them in the
	// game until we get the first refused one.
	challengers = G_Teams_ChallengersQueue();
	if( challengers )
	{
		int i;

		for( i = 0; challengers[i]; i++ )
		{
			ent = challengers[i];
			if( !G_Teams_JoinAnyTeam( ent, true ) )
				break;

			// if we successfully execute the challengers queue during the countdown, revert to warmup
			if( GS_MatchState() == MATCH_STATE_COUNTDOWN )
			{
				restartmatch = true;
			}
		}
	}

	if( restartmatch == true )
	{
		G_Match_Autorecord_Cancel();
		G_Match_LaunchState( MATCH_STATE_WARMUP );
	}
}
Exemple #2
0
static void G_Gametype_GENERIC_ThinkRules( void )
{
	if( G_Match_ScorelimitHit() || G_Match_TimelimitHit() || G_Match_SuddenDeathFinished() )
{
	G_CenterPrintMsg( NULL, "ENDOOOOOOOOOOOOOOOOO saaaaan!!!!!!!!!!\n" );
		G_Match_LaunchState( GS_MatchState() + 1 );
}

	if( GS_MatchState() >= MATCH_STATE_POSTMATCH )
		return;
}
Exemple #3
0
/*QUAKED target_changelevel (1 0 0) (-8 -8 -8) (8 8 8)
Changes level to "map" when fired
*/
void use_target_changelevel( edict_t *self, edict_t *other, edict_t *activator )
{
	//	if( GS_MatchState() >= MATCH_STATE_POSTMATCH )
	return;		// allready activated
	/*
	if( 0 )
	{
	// if noexit, do a ton of damage to other
	if( noexit->value && other != world )
	{
	T_Damage( other, self, self, vec3_origin, other->s.origin, vec3_origin, 10 * other->max_health, 1000, 0 );
	return;
	}

	// let everyone know who hit the exit
	if( other && other->client )
	G_Printf( "%s exited the level.\n", other->client->pers.netname);
	}
	*/
	trap_Cvar_SetValue( "g_maprotation", -1 );
	G_Match_LaunchState( MATCH_STATE_POSTMATCH );
}
/*
* 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();
	}
}
/*
* G_Match_CheckReadys
*/
void G_Match_CheckReadys( void )
{
	edict_t *e;
	bool allready;
	int readys, notreadys, teamsready;
	int team, i;

	if( GS_MatchState() != MATCH_STATE_WARMUP && GS_MatchState() != MATCH_STATE_COUNTDOWN )
		return;

	if( GS_MatchState() == MATCH_STATE_COUNTDOWN && level.forceStart )
		return; // never stop countdown if we have run out of warmup_timelimit

	teamsready = 0;
	for( team = TEAM_PLAYERS; team < GS_MAX_TEAMS; team++ )
	{
		readys = notreadys = 0;
		for( i = 0; i < teamlist[team].numplayers; i++ )
		{
			e = game.edicts + teamlist[team].playerIndices[i];

			if( !e->r.inuse )
				continue;
			if( e->s.team == TEAM_SPECTATOR )  //ignore spectators
				continue;

			if( level.ready[PLAYERNUM( e )] )
				readys++;
			else
				notreadys++;
		}
		if( !notreadys && readys )
			teamsready++;
	}

	// everyone has commited
	if( GS_TeamBasedGametype() )
	{
		if( teamsready == GS_MAX_TEAMS - TEAM_ALPHA )
			allready = true;
		else
			allready = false;
	}
	else
	{       //ffa
		if( teamsready && teamlist[TEAM_PLAYERS].numplayers > 1 )
			allready = true;
		else
			allready = false;
	}

	if( allready == true && GS_MatchState() != MATCH_STATE_COUNTDOWN )
	{
		G_PrintMsg( NULL, "All players are ready.  Match starting!\n" );
		G_Match_LaunchState( MATCH_STATE_COUNTDOWN );
	}
	else if( allready == false && GS_MatchState() == MATCH_STATE_COUNTDOWN )
	{
		G_PrintMsg( NULL, "Countdown aborted.\n" );
		G_CenterPrintMsg( NULL, "COUNTDOWN ABORTED" );
		G_Match_Autorecord_Cancel();
		G_Match_LaunchState( MATCH_STATE_WARMUP );
	}
}
/*
* G_EndMatch
*/
void G_EndMatch( void )
{
	level.forceExit = true;
	G_Match_LaunchState( MATCH_STATE_POSTMATCH );
}
Exemple #7
0
/*
* SpawnEntities
* 
* Creates a server's entity / program execution context by
* parsing textual entity definitions out of an ent file.
*/
void G_InitLevel( char *mapname, char *entities, int entstrlen, unsigned int levelTime, unsigned int serverTime, unsigned int realTime )
{
	char *mapString = NULL;
	char name[MAX_CONFIGSTRING_CHARS];
	int i;
	edict_t *ent;
	char *token;
	const gsitem_t *item;

	G_asGarbageCollect( true );

	GT_asCallShutdown();
	G_asCallMapExit();

	G_asShutdownMapScript();
	GT_asShutdownScript();

	G_FreeCallvotes();

	game.serverTime = serverTime;
	game.realtime = realTime;
	game.levelSpawnCount++;

	GClip_ClearWorld(); // clear areas links

	if( !entities )
		G_Error( "G_SpawnLevel: NULL entities string\n" );

	// make a copy of the raw entities string so it's not freed with the pool
	mapString = ( char * )G_Malloc( entstrlen + 1 );
	memcpy( mapString, entities, entstrlen );
	Q_strncpyz( name, mapname, sizeof( name ) );

	// clear old data

	G_LevelInitPool( strlen( mapname ) + 1 + ( entstrlen + 1 ) * 2 + G_LEVELPOOL_BASE_SIZE );

	G_StringPoolInit();

	memset( &level, 0, sizeof( level_locals_t ) );
	memset( &gs.gameState, 0, sizeof( gs.gameState ) );

	level.spawnedTimeStamp = game.realtime;
	level.time = levelTime;
	level.gravity = g_gravity->value;

	// get the strings back
	Q_strncpyz( level.mapname, name, sizeof( level.mapname ) );
	level.mapString = ( char * )G_LevelMalloc( entstrlen + 1 );
	level.mapStrlen = entstrlen;
	memcpy( level.mapString, mapString, entstrlen );
	G_Free( mapString );
	mapString = NULL;

	// make a copy of the raw entities string for parsing
	level.map_parsed_ents = ( char * )G_LevelMalloc( entstrlen + 1 );
	level.map_parsed_ents[0] = 0;

	if( !level.time )
		memset( game.edicts, 0, game.maxentities * sizeof( game.edicts[0] ) );
	else
	{
		G_FreeEdict( world );
		for( i = gs.maxclients + 1; i < game.maxentities; i++ )
		{
			if( game.edicts[i].r.inuse )
				G_FreeEdict( game.edicts + i );
		}
	}

	game.numentities = gs.maxclients + 1;

	// link client fields on player ents
	for( i = 0; i < gs.maxclients; i++ )
	{
		game.edicts[i+1].s.number = i+1;
		game.edicts[i+1].r.client = &game.clients[i];
		game.edicts[i+1].r.inuse = ( trap_GetClientState( i ) >= CS_CONNECTED ) ? true : false;
		memset( &game.clients[i].level, 0, sizeof( game.clients[0].level ) );
		game.clients[i].level.timeStamp = level.time;
	}

	// initialize game subsystems
	trap_ConfigString( CS_MAPNAME, level.mapname );
	trap_ConfigString( CS_SKYBOX, "" );
	trap_ConfigString( CS_AUDIOTRACK, "" );
	trap_ConfigString( CS_STATNUMS, va( "%i %i %i", STAT_SCORE, STAT_HEALTH, STAT_LAST_KILLER ) );
	trap_ConfigString( CS_POWERUPEFFECTS, va( "%i %i %i %i", EF_QUAD, EF_SHELL, EF_CARRIER, EF_REGEN ) );
	trap_ConfigString( CS_SCB_PLAYERTAB_LAYOUT, "" );
	trap_ConfigString( CS_SCB_PLAYERTAB_TITLES, "" );
	trap_ConfigString( CS_MATCHNAME, "" );
	trap_ConfigString( CS_MATCHSCORE, "" );

	// reset map messages
	for( i = 0; i < MAX_HELPMESSAGES; i++ ) {
		trap_ConfigString( CS_HELPMESSAGES + i, "" );
	}

	G_InitGameCommands();
	G_MapLocations_Init();
	G_CallVotes_Init();
	G_SpawnQueue_Init();
	G_Teams_Init();
	// load map script
	G_asLoadMapScript( level.mapname );
	G_Gametype_Init();
	// ch : this would be the location to "transfer ratings"
	G_PrecacheItems(); // set configstrings for items (gametype must be initialized)
	G_PrecacheMedia();
	G_PrecacheGameCommands(); // adding commands after this point won't update them to the client
	AI_InitLevel(); // load navigation file of the current map

	// start spawning entities

	level.canSpawnEntities = true;
	G_InitBodyQueue(); // reserve some spots for dead player bodies

	entities = level.mapString;

	i = 0;
	ent = NULL;
	while( 1 )
	{
		level.spawning_entity = NULL;

		// parse the opening brace
		token = COM_Parse( &entities );
		if( !entities )
			break;
		if( token[0] != '{' )
			G_Error( "G_SpawnMapEntities: found %s when expecting {", token );

		if( !ent )
		{
			ent = world;
			G_InitEdict( world );
		}
		else
			ent = G_Spawn();

		ent->spawnString = entities; // keep track of string definition of this entity

		entities = ED_ParseEdict( entities, ent );
		if( !ent->classname )
		{
			i++;
			// racesow - introducing the freestyle map bug again in
			// order to make some freestyle maps work
			if( !level.gametype.freestyleMapFix )
				G_FreeEdict( ent );
			// !racesow
			G_FreeEdict( ent );
			continue;
		}

		if( !G_CanSpawnEntity( ent ) )
		{
			i++;
			G_FreeEdict( ent );
			continue;
		}

		if( !G_CallSpawn( ent ) )
		{
			i++;
			G_FreeEdict( ent );
			continue;
		}

		// check whether an item is allowed to spawn
		if( ( item = ent->item ) )
		{
			// not pickable items aren't spawnable
			if( item->flags & ITFLAG_PICKABLE )
			{
				if( G_Gametype_CanSpawnItem( item ) )
				{
					// override entity's classname with whatever item specifies
					ent->classname = item->classname;
					PrecacheItem( item );
					continue;
				}
			}

			i++;
			G_FreeEdict( ent );
			continue;
		}
	}

	G_FindTeams();

	// is the parsing string sane?
	assert( (int)level.map_parsed_len < entstrlen );
	level.map_parsed_ents[level.map_parsed_len] = 0;

	// make sure server got the edicts data
	trap_LocateEntities( game.edicts, sizeof( game.edicts[0] ), game.numentities, game.maxentities );

	// items need brush model entities spawned before they are linked
	G_Items_FinishSpawningItems();

	//
	// initialize game subsystems which require entities initialized
	//

	// call gametype specific
	GT_asCallSpawn();

	// call map specific
	G_asCallMapInit();

	AI_InitEntitiesData();

	// always start in warmup match state and let the thinking code
	// revert it to wait state if empty ( so gametype based item masks are setup )
	G_Match_LaunchState( MATCH_STATE_WARMUP );

	G_asGarbageCollect( true );

	// racesow
	RS_Init();
}