示例#1
0
/*
* G_Teams_InitLevel
*/
void G_Teams_Init( void )
{
	edict_t	*ent;

	// set the team names with default ones
	trap_ConfigString( CS_TEAM_SPECTATOR_NAME, GS_DefaultTeamName( TEAM_SPECTATOR ) );
	trap_ConfigString( CS_TEAM_PLAYERS_NAME, GS_DefaultTeamName( TEAM_PLAYERS ) );
	trap_ConfigString( CS_TEAM_ALPHA_NAME, GS_DefaultTeamName( TEAM_ALPHA ) );
	trap_ConfigString( CS_TEAM_BETA_NAME, GS_DefaultTeamName( TEAM_BETA ) );

	g_teams_maxplayers = trap_Cvar_Get( "g_teams_maxplayers", "0", CVAR_ARCHIVE );
	g_teams_allow_uneven = trap_Cvar_Get( "g_teams_allow_uneven", "1", CVAR_ARCHIVE );

	//unlock all teams and clear up team lists
	memset( teamlist, 0, sizeof( teamlist ) );

	for( ent = game.edicts + 1; PLAYERNUM( ent ) < gs.maxclients; ent++ )
	{
		if( ent->r.inuse )
		{
			memset( &ent->r.client->teamstate, 0, sizeof( ent->r.client->teamstate ) );
			memset( &ent->r.client->resp, 0, sizeof( ent->r.client->resp ) );
			ent->s.team = ent->r.client->team = TEAM_SPECTATOR;
			G_GhostClient( ent );
			ent->movetype = MOVETYPE_NOCLIP; // allow freefly
			ent->r.client->teamstate.timeStamp = level.time;
			ent->r.client->resp.timeStamp = level.time;
		}
	}

}
示例#2
0
static void light_use( edict_t *self, edict_t *other, edict_t *activator )
{
	if( self->spawnflags & START_OFF )
	{
		trap_ConfigString( CS_LIGHTS+self->style, "m" );
		self->spawnflags &= ~START_OFF;
	}
	else
	{
		trap_ConfigString( CS_LIGHTS+self->style, "a" );
		self->spawnflags |= START_OFF;
	}
}
示例#3
0
文件: tvm_cmds.c 项目: Picmip/qfusion
/*
* TVM_AddGameCommand
*/
static void TVM_AddGameCommand( tvm_relay_t *relay, const char *name, void *callback ) {
	int i;

#ifndef NDEBUG
	// check for double add
	for( i = 0; i < MAX_GAMECOMMANDS; i++ ) {
		if( g_Commands[i].name[0] == '\0' ) {
			continue;
		}
		if( !Q_stricmp( g_Commands[i].name, name ) ) {
			assert( false );
		}
	}
#endif

	// find a free one and add it
	for( i = 0; i < MAX_GAMECOMMANDS; i++ ) {
		if( g_Commands[i].name[0] == '\0' ) {
			g_Commands[i].func = callback;
			Q_strncpyz( g_Commands[i].name, name, sizeof( g_Commands[i].name ) );
			trap_ConfigString( relay, CS_GAMECOMMANDS + i, name );
			return;
		}
	}

	TVM_RelayError( relay, "G_AddCommand: Couldn't find a free g_Commands spot for the new command\n" );
}
示例#4
0
/*
* TVM_SpawnEntities
*
* Creates a server's entity / program execution context by
* parsing textual entity definitions out of an ent file.
*/
void TVM_SpawnEntities( tvm_relay_t *relay, const char *mapname, const char *entities, int entstrlen ) {
	edict_t *ent;
	int i;

	assert( mapname );

	Q_strncpyz( relay->mapname, mapname, sizeof( relay->mapname ) );

	GClip_ClearWorld( relay ); // clear areas links

	memset( relay->edicts, 0, relay->maxentities * sizeof( relay->edicts[0] ) );
	for( i = 0, ent = &relay->edicts[0]; i < relay->maxentities; i++, ent++ ) {
		ent->relay = relay;
		ent->s.number = i;
	}
	relay->numentities = 0;

	// overwrite gamecommands from the relay
	for( i = 0; i < MAX_GAMECOMMANDS; i++ ) {
		assert( CS_GAMECOMMANDS + i < MAX_CONFIGSTRINGS );
		relay->configStringsOverwritten[CS_GAMECOMMANDS + i] = true;
		trap_ConfigString( relay, CS_GAMECOMMANDS + i, "" );
	}

	TVM_RemoveGameCommands( relay );
	TVM_AddGameCommands( relay );
}
示例#5
0
/*
* G_PrecacheGameCommands
*/
void G_PrecacheGameCommands( void )
{
	int i;

	for( i = 0; i < MAX_GAMECOMMANDS; i++ )
		trap_ConfigString( CS_GAMECOMMANDS + i, g_Commands[i].name );
}
示例#6
0
static void G_Gametype_GENERIC_Init( void )
{
	trap_ConfigString( CS_GAMETYPETITLE, "Generic Deathmatch" );
	trap_ConfigString( CS_GAMETYPEVERSION, "1.0" );
	trap_ConfigString( CS_GAMETYPEAUTHOR, "Warsow Development Team" );
	trap_Cvar_ForceSet( "g_gametype", "generic" );

	level.gametype.spawnableItemsMask = ( IT_WEAPON|IT_AMMO|IT_ARMOR|IT_POWERUP|IT_HEALTH );
	level.gametype.respawnableItemsMask = ( IT_WEAPON|IT_AMMO|IT_ARMOR|IT_POWERUP|IT_HEALTH );
	level.gametype.dropableItemsMask = ( IT_WEAPON|IT_AMMO|IT_ARMOR|IT_POWERUP|IT_HEALTH );
	level.gametype.pickableItemsMask = ( level.gametype.spawnableItemsMask|level.gametype.dropableItemsMask );
	if( GS_Instagib() )
		level.gametype.pickableItemsMask &= ~G_INSTAGIB_NEGATE_ITEMMASK;

	level.gametype.isTeamBased = false;
	level.gametype.isRace = false;
	level.gametype.isTutorial = false;
	level.gametype.inverseScore = false;
	level.gametype.hasChallengersQueue = false;
	level.gametype.maxPlayersPerTeam = 0;

	level.gametype.ammo_respawn = 20;
	level.gametype.armor_respawn = 25;
	level.gametype.weapon_respawn = 5;
	level.gametype.health_respawn = 25;
	level.gametype.powerup_respawn = 90;
	level.gametype.megahealth_respawn = 20;
	level.gametype.ultrahealth_respawn = 60;

	level.gametype.countdownEnabled = false;
	level.gametype.mathAbortDisabled = false;
	level.gametype.canForceModels = true;
	level.gametype.canShowMinimap = false;
	level.gametype.teamOnlyMinimap = true;
	level.gametype.spawnpointRadius = 256;

	level.gametype.canShowMinimap = false;
	level.gametype.teamOnlyMinimap = true;

	level.gametype.mmCompatible = false;

	if( GS_Instagib() )
		level.gametype.spawnpointRadius *= 2;

	trap_ConfigString( CS_SCB_PLAYERTAB_LAYOUT, "%n 164 %i 64 %l 48 %p 18 %p 18" );
	trap_ConfigString( CS_SCB_PLAYERTAB_TITLES, "Name Score Ping C R" );
}
示例#7
0
//QUAKED worldspawn (0 0 0) ?
//
//Only used for the world.
//"sky"	environment map name
//"skyaxis"	vector axis for rotating sky
//"skyrotate"	speed of rotation in degrees/second
//"sounds"	music cd track number
//"gravity"	800 is default gravity
//"message"	text to print at user logon
//========================
static void SP_worldspawn( edict_t *ent )
{
	ent->movetype = MOVETYPE_PUSH;
	ent->r.solid = SOLID_YES;
	ent->r.inuse = true;       // since the world doesn't use G_Spawn()
	VectorClear( ent->s.origin );
	VectorClear( ent->s.angles );
	GClip_SetBrushModel( ent, "*0" ); // sets mins / maxs and modelindex 1
	G_PureModel( "*0" );

	if( st.nextmap )
		Q_strncpyz( level.nextmap, st.nextmap, sizeof( level.nextmap ) );

	// make some data visible to the server
	/*
	message = trap_GetFullnameFromMapList( level.mapname );
	if( message && message[0] )
		ent->message = G_LevelCopyString( message );
	*/

	if( ent->message && ent->message[0] )
	{
		trap_ConfigString( CS_MESSAGE, ent->message );
		Q_strncpyz( level.level_name, ent->message, sizeof( level.level_name ) );
	}
	else
	{
		trap_ConfigString( CS_MESSAGE, level.mapname );
		Q_strncpyz( level.level_name, level.mapname, sizeof( level.level_name ) );
	}

	// send music
	if( st.music )
	{
		trap_ConfigString( CS_AUDIOTRACK, st.music );
		trap_PureSound( st.music );
	}

	if( st.gravity )
		level.gravity = atof( st.gravity );

	if( st.colorCorrection )
	{
		level.colorCorrection = trap_ImageIndex( st.colorCorrection );
		gs.gameState.stats[GAMESTAT_COLORCORRECTION] = level.colorCorrection;
	}
}
示例#8
0
void SP_light( edict_t *self )
{
	if( !self->targetname )
	{
		G_FreeEdict( self );
		return;
	}

	if( self->style >= 32 )
	{
		self->use = light_use;
		if( self->spawnflags & START_OFF )
			trap_ConfigString( CS_LIGHTS+self->style, "a" );
		else
			trap_ConfigString( CS_LIGHTS+self->style, "m" );
	}
}
示例#9
0
/*QUAKED props_skyportal (.6 .7 .7) (-8 -8 0) (8 8 16)
"fov" for the skybox default is whatever client's fov is set to
"scale" is world/skyarea ratio if you want to keep a certain perspective when player moves around the world
"noents" makes the skyportal ignore entities within the sky area, making them invisible for the player
*/
void SP_skyportal( edict_t *ent )
{
	// default to client's FOV
	//	if (!st.fov)
	//		st.fov = 90;
	ent->r.svflags = SVF_NOCLIENT;

	trap_ConfigString( CS_SKYBOX, va( "%.3f %.3f %.3f %.1f %.1f %d %.1f %.1f %.1f", ent->s.origin[0], ent->s.origin[1], ent->s.origin[2],
		st.fov, st.scale, st.noents, ent->s.angles[0], ent->s.angles[1], ent->s.angles[2] ) );
}
示例#10
0
文件: tvm_cmds.c 项目: Picmip/qfusion
/*
* TVM_RemoveGameCommands
*/
void TVM_RemoveGameCommands( tvm_relay_t *relay ) {
	int i;

	for( i = 0; i < MAX_GAMECOMMANDS; i++ ) {
		if( g_Commands[i].name[0] != '\0' ) {
			g_Commands[i].func = NULL;
			g_Commands[i].name[0] = 0;
			trap_ConfigString( relay, CS_GAMECOMMANDS + i, "" );
		}
	}
}
示例#11
0
/*
* ClientDisconnect
* Called when a player drops from the server.
* Will not be called between levels.
*/
void ClientDisconnect( edict_t *ent, const char *reason )
{
	int team;

	if( !ent->r.client || !ent->r.inuse )
		return;

	// always report in RACE mode
	if( GS_RaceGametype() 
		|| ( ent->r.client->team != TEAM_SPECTATOR && ( GS_MatchState() == MATCH_STATE_PLAYTIME || GS_MatchState() == MATCH_STATE_POSTMATCH ) ) )
		G_AddPlayerReport( ent, GS_MatchState() == MATCH_STATE_POSTMATCH );

	for( team = TEAM_PLAYERS; team < GS_MAX_TEAMS; team++ )
		G_Teams_UnInvitePlayer( team, ent );

	if( !level.gametype.disableObituaries || !(ent->r.svflags & SVF_FAKECLIENT ) )
	{
		if( !reason )
			G_PrintMsg( NULL, "%s" S_COLOR_WHITE " disconnected\n", ent->r.client->netname );
		else
			G_PrintMsg( NULL, "%s" S_COLOR_WHITE " disconnected (%s" S_COLOR_WHITE ")\n", ent->r.client->netname, reason );
	}

	// send effect
	if( ent->s.team > TEAM_SPECTATOR )
		G_TeleportEffect( ent, false );

	ent->r.client->team = TEAM_SPECTATOR;
	G_ClientRespawn( ent, true ); // respawn as ghost
	ent->movetype = MOVETYPE_NOCLIP; // allow freefly

	// let the gametype scripts know this client just disconnected
	G_Gametype_ScoreEvent( ent->r.client, "disconnect", NULL );

	G_FreeAI( ent );
	AI_EnemyRemoved( ent );

	ent->r.inuse = false;
	ent->r.svflags = SVF_NOCLIENT;

	memset( ent->r.client, 0, sizeof( *ent->r.client ) );
	ent->r.client->ps.playerNum = PLAYERNUM( ent );

	trap_ConfigString( CS_PLAYERINFOS+PLAYERNUM( ent ), "" );
	GClip_UnlinkEntity( ent );

	G_Match_CheckReadys();
}
示例#12
0
/*
* G_AddCommand
*/
void G_AddCommand( const char *name, gamecommandfunc_t callback )
{
	int i;
	char temp[MAX_QPATH];
	static const char *blacklist[] = { "callvotevalidate", "callvotepassed", NULL };

	Q_strncpyz( temp, name, sizeof( temp ) );

	for( i = 0; blacklist[i] != NULL; i++ )
	{
		if( !Q_stricmp( blacklist[i], temp ) )
		{
			G_Printf( "WARNING: G_AddCommand: command name '%s' is write protected\n", temp );
			return;
		}
	}

	// see if we already had it in game side
	for( i = 0; i < MAX_GAMECOMMANDS; i++ )
	{
		if( !g_Commands[i].name[0] )
			break;
		if( !Q_stricmp( g_Commands[i].name, temp ) )
		{
			// update func if different
			if( g_Commands[i].func != callback )
				g_Commands[i].func = ( gamecommandfunc_t )callback;
			return;
		}
	}

	if( i == MAX_GAMECOMMANDS )
	{
		G_Error( "G_AddCommand: Couldn't find a free g_Commands spot for the new command. (increase MAX_GAMECOMMANDS)\n" );
		return;
	}

	// we don't have it, add it
	g_Commands[i].func = ( gamecommandfunc_t )callback;
	Q_strncpyz( g_Commands[i].name, temp, sizeof( g_Commands[i].name ) );

	// add the configstring if the precache process was already done
	if( level.canSpawnEntities )
		trap_ConfigString( CS_GAMECOMMANDS + i, g_Commands[i].name );
}
示例#13
0
/*
* G_UpdatePlayerInfoString
*/
static void G_UpdatePlayerInfoString( int playerNum )
{
	char playerString[MAX_INFO_STRING];
	gclient_t *client;

	assert( playerNum >= 0 && playerNum < gs.maxclients );
	client = &game.clients[playerNum];

	// update client information in cgame
	playerString[0] = 0;

	Info_SetValueForKey( playerString, "name", client->netname );
	Info_SetValueForKey( playerString, "hand", va( "%i", client->hand ) );
	Info_SetValueForKey( playerString, "color",
		va( "%i %i %i", client->color[0], client->color[1], client->color[2] ) );

	playerString[MAX_CONFIGSTRING_CHARS-1] = 0;
	trap_ConfigString( CS_PLAYERINFOS + playerNum, playerString );
}
示例#14
0
static void target_lightramp_think( edict_t *self )
{
	char style[2];

	style[0] = 'a' + self->moveinfo.movedir[0] + ( level.time - self->timeStamp ) / game.snapFrameTime * self->moveinfo.movedir[2];
	style[1] = 0;
	trap_ConfigString( CS_LIGHTS+self->enemy->style, style );

	if( level.time - self->timeStamp < self->speed * 1000 )
	{
		self->nextThink = level.time + 1;
	}
	else if( self->spawnflags & 1 )
	{
		char temp;

		temp = self->moveinfo.movedir[0];
		self->moveinfo.movedir[0] = self->moveinfo.movedir[1];
		self->moveinfo.movedir[1] = temp;
		self->moveinfo.movedir[2] *= -1;
	}
}
示例#15
0
/*
* G_UpdateMMPlayerInfoString
*/
static void G_UpdateMMPlayerInfoString( int playerNum )
{
	char playerString[MAX_INFO_STRING];
	gclient_t *client;

	assert( playerNum >= 0 && playerNum < gs.maxclients );
	client = &game.clients[playerNum];

	if( playerNum >= MAX_MMPLAYERINFOS ) {
		return; // oops
	}

	// update client information in cgame
	playerString[0] = 0;

	if( client->mmflags != 0 ) {
		Info_SetValueForKey( playerString, "f", va( "%x", client->mmflags ) ); // use hex for shorter representation
	}

	playerString[MAX_CONFIGSTRING_CHARS-1] = 0;
	trap_ConfigString( CS_MMPLAYERINFOS + playerNum, playerString );
}
示例#16
0
文件: g_items.c 项目: hettoo/racesow
/*
* SetItemNames
* 
* Called by worldspawn
*/
void G_PrecacheItems( void )
{
	int i;
	gsitem_t *item;

	// precache item names and weapondefs
	for( i = 1; ( item = GS_FindItemByTag( i ) ) != NULL; i++ )
	{
		trap_ConfigString( CS_ITEMS + i, item->name );

		if( item->type & IT_WEAPON && GS_GetWeaponDef( item->tag ) )
		{
			G_PrecacheWeapondef( i, &GS_GetWeaponDef( item->tag )->firedef );
			G_PrecacheWeapondef( i, &GS_GetWeaponDef( item->tag )->firedef_weak );
		}
	}

	// precache items
	if( GS_Instagib() )
	{
		item = GS_FindItemByTag( WEAP_INSTAGUN );
		PrecacheItem( item );
	}
	else
	{
		for( i = WEAP_GUNBLADE; i < WEAP_TOTAL; i++ )
		{
			item = GS_FindItemByTag( i );
			PrecacheItem( item );
		}
	}

	// Vic: precache ammo pack if it's droppable
	item = GS_FindItemByClassname( "item_ammopack" );
	if( item && G_Gametype_CanDropItem( item, qtrue ) )
	{
		PrecacheItem( item );
	}
}
示例#17
0
/*
* G_Gametype_Init
*/
void G_Gametype_Init( void )
{
	bool changed = false;
	const char *mapGametype;

	g_gametypes_list = trap_Cvar_Get( "g_gametypes_list", "", CVAR_NOSET|CVAR_ARCHIVE );
	G_Gametype_GenerateGametypesList(); // fill the g_gametypes_list cvar

	// empty string to allow all
	g_votable_gametypes = trap_Cvar_Get( "g_votable_gametypes", "", CVAR_ARCHIVE );

	if( !g_gametype ) // first time initialized
		changed = true;

	g_gametype = trap_Cvar_Get( "g_gametype", "dm", CVAR_SERVERINFO|CVAR_ARCHIVE|CVAR_LATCH );

	//get the match cvars too
	g_warmup_timelimit = trap_Cvar_Get( "g_warmup_timelimit", "5", CVAR_ARCHIVE );
	g_postmatch_timelimit = trap_Cvar_Get( "g_postmatch_timelimit", "4", CVAR_ARCHIVE );
	g_countdown_time = trap_Cvar_Get( "g_countdown_time", "5", CVAR_ARCHIVE );
	g_match_extendedtime = trap_Cvar_Get( "g_match_extendedtime", "2", CVAR_ARCHIVE );

	// game settings
	g_timelimit = trap_Cvar_Get( "g_timelimit", "10", CVAR_ARCHIVE );
	g_scorelimit = trap_Cvar_Get( "g_scorelimit", "0", CVAR_ARCHIVE );
	g_allow_falldamage = trap_Cvar_Get( "g_allow_falldamage", "1", CVAR_ARCHIVE );
	g_allow_selfdamage = trap_Cvar_Get( "g_allow_selfdamage", "1", CVAR_ARCHIVE );
	g_allow_teamdamage = trap_Cvar_Get( "g_allow_teamdamage", "1", CVAR_ARCHIVE );
	g_allow_bunny = trap_Cvar_Get( "g_allow_bunny", "1", CVAR_ARCHIVE|CVAR_READONLY );

	// map-specific gametype
	mapGametype = G_asCallMapGametype();
	if( mapGametype[0] && G_Gametype_Exists( mapGametype ) )
		trap_Cvar_Set( g_gametype->name, mapGametype );

	// update latched gametype change
	if( g_gametype->latched_string )
	{
		if( G_Gametype_Exists( g_gametype->latched_string ) )
		{
			trap_Cvar_ForceSet( "g_gametype", va( "%s", g_gametype->latched_string ) );
			changed = true;
		}
		else
		{
			G_Printf( "G_Gametype: Invalid new gametype, change ignored\n" );
			trap_Cvar_ForceSet( "g_gametype", va( "%s", g_gametype->string ) );
		}
	}

	if( !G_Gametype_Exists( g_gametype->string ) )
	{
		G_Printf( "G_Gametype: Wrong value: '%s'. Setting up with default (dm)\n", g_gametype->string );
		trap_Cvar_ForceSet( "g_gametype", "dm" );
		changed = true;
	}

	G_Printf( "-------------------------------------\n" );
	G_Printf( "Initalizing '%s' gametype\n", g_gametype->string );

	if( changed )
	{
		const char *configs_path = "configs/server/gametypes/";

		G_InitChallengersQueue();

		// print a hint for admins so they know there's a chance to execute a
		// config here, but don't show it as an error, because it isn't
		G_Printf( "loading %s%s.cfg\n", configs_path, g_gametype->string );
		trap_Cmd_ExecuteText( EXEC_NOW, va( "exec %s%s.cfg silent\n", configs_path, g_gametype->string ) );
		trap_Cbuf_Execute();

		// on a listen server, override gametype-specific settings in config
		trap_Cmd_ExecuteText( EXEC_NOW, "vstr ui_startservercmd\n" );
		trap_Cbuf_Execute();
	}

	// fixme: we are doing this twice because the gametype may check for GS_Instagib
	G_CheckCvars(); // update GS_Instagib, GS_FallDamage, etc

	G_Gametype_SetDefaults();

	// Init the current gametype
	if( !GT_asLoadScript( g_gametype->string ) )
		G_Gametype_GENERIC_Init();

	GS_SetGametypeName( g_gametype->string );

	trap_ConfigString( CS_GAMETYPENAME, g_gametype->string );

	G_CheckCvars(); // update GS_Instagib, GS_FallDamage, etc

	// ch : if new gametype has been initialized, transfer the
	// client-specific ratings to gametype-specific list
	if( changed )
		G_TransferRatings();
}
示例#18
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();
}
示例#19
0
/*
* G_Match_SetAutorecordState
*/
static void G_Match_SetAutorecordState( const char *state )
{
	trap_ConfigString( CS_AUTORECORDSTATE, state );
}
示例#20
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();
}
示例#21
0
void G_PrecacheMedia( void )
{
	//
	// MODELS
	//

	// THIS ORDER MUST MATCH THE DEFINES IN gs_public.h
	// you can add more, max 255

	trap_ModelIndex( "#gunblade/gunblade.md3" );      // WEAP_GUNBLADE
	trap_ModelIndex( "#machinegun/machinegun.md3" );    // WEAP_MACHINEGUN
	trap_ModelIndex( "#riotgun/riotgun.md3" );        // WEAP_RIOTGUN
	trap_ModelIndex( "#glauncher/glauncher.md3" );    // WEAP_GRENADELAUNCHER
	trap_ModelIndex( "#rlauncher/rlauncher.md3" );    // WEAP_ROCKETLAUNCHER
	trap_ModelIndex( "#plasmagun/plasmagun.md3" );    // WEAP_PLASMAGUN
	trap_ModelIndex( "#lasergun/lasergun.md3" );      // WEAP_LASERGUN
	trap_ModelIndex( "#electrobolt/electrobolt.md3" ); // WEAP_ELECTROBOLT
	trap_ModelIndex( "#instagun/instagun.md3" );      // WEAP_INSTAGUN

	//-------------------

	// precache our basic player models, they are just a very few
	trap_ModelIndex( "$models/players/bigvic" );

	trap_SkinIndex( "models/players/bigvic/default" );

	// FIXME: Temporarily use normal gib until the head is fixed
	trap_ModelIndex( "models/objects/gibs/illuminati1/illuminati1.md3" );

	//
	// SOUNDS
	//

	// jalfixme : most of these sounds can be played from the clients

	trap_SoundIndex( S_WORLD_WATER_IN );    // feet hitting water
	trap_SoundIndex( S_WORLD_WATER_OUT );       // feet leaving water
	trap_SoundIndex( S_WORLD_UNDERWATER );

	trap_SoundIndex( S_WORLD_SLIME_IN );
	trap_SoundIndex( S_WORLD_SLIME_OUT );
	trap_SoundIndex( S_WORLD_UNDERSLIME );

	trap_SoundIndex( S_WORLD_LAVA_IN );
	trap_SoundIndex( S_WORLD_LAVA_OUT );
	trap_SoundIndex( S_WORLD_UNDERLAVA );

	trap_SoundIndex( va( S_PLAYER_BURN_1_to_2, 1 ) );
	trap_SoundIndex( va( S_PLAYER_BURN_1_to_2, 2 ) );

	//wsw: pb disable unreferenced sounds
	//trap_SoundIndex (S_LAND);				// landing thud
	trap_SoundIndex( S_HIT_WATER );

	trap_SoundIndex( S_WEAPON_NOAMMO );

	// announcer

	// readyup
	trap_SoundIndex( S_ANNOUNCER_READY_UP_POLITE );
	trap_SoundIndex( S_ANNOUNCER_READY_UP_PISSEDOFF );

	// countdown
	trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_GET_READY_TO_FIGHT_1_to_2, 1 ) );
	trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_GET_READY_TO_FIGHT_1_to_2, 2 ) );
	trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_READY_1_to_2, 1 ) );
	trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_READY_1_to_2, 2 ) );
	trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_COUNT_1_to_3_SET_1_to_2, 1, 1 ) );
	trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_COUNT_1_to_3_SET_1_to_2, 2, 1 ) );
	trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_COUNT_1_to_3_SET_1_to_2, 3, 1 ) );
	trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_COUNT_1_to_3_SET_1_to_2, 1, 2 ) );
	trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_COUNT_1_to_3_SET_1_to_2, 2, 2 ) );
	trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_COUNT_1_to_3_SET_1_to_2, 3, 2 ) );
	trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_FIGHT_1_to_2, 1 ) );
	trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_FIGHT_1_to_2, 2 ) );

	// postmatch
	trap_SoundIndex( va( S_ANNOUNCER_POSTMATCH_GAMEOVER_1_to_2, 1 ) );
	trap_SoundIndex( va( S_ANNOUNCER_POSTMATCH_GAMEOVER_1_to_2, 2 ) );

	// timeout
	trap_SoundIndex( va( S_ANNOUNCER_TIMEOUT_MATCH_RESUMED_1_to_2, 1 ) );
	trap_SoundIndex( va( S_ANNOUNCER_TIMEOUT_MATCH_RESUMED_1_to_2, 2 ) );
	trap_SoundIndex( va( S_ANNOUNCER_TIMEOUT_TIMEOUT_1_to_2, 1 ) );
	trap_SoundIndex( va( S_ANNOUNCER_TIMEOUT_TIMEOUT_1_to_2, 2 ) );
	trap_SoundIndex( va( S_ANNOUNCER_TIMEOUT_TIMEIN_1_to_2, 1 ) );
	trap_SoundIndex( va( S_ANNOUNCER_TIMEOUT_TIMEIN_1_to_2, 2 ) );

	// callvote
	trap_SoundIndex( va( S_ANNOUNCER_CALLVOTE_CALLED_1_to_2, 1 ) );
	trap_SoundIndex( va( S_ANNOUNCER_CALLVOTE_CALLED_1_to_2, 2 ) );
	trap_SoundIndex( va( S_ANNOUNCER_CALLVOTE_FAILED_1_to_2, 1 ) );
	trap_SoundIndex( va( S_ANNOUNCER_CALLVOTE_FAILED_1_to_2, 2 ) );
	trap_SoundIndex( va( S_ANNOUNCER_CALLVOTE_PASSED_1_to_2, 1 ) );
	trap_SoundIndex( va( S_ANNOUNCER_CALLVOTE_PASSED_1_to_2, 2 ) );
	trap_SoundIndex( S_ANNOUNCER_CALLVOTE_VOTE_NOW );

	// overtime
	trap_SoundIndex( S_ANNOUNCER_OVERTIME_GOING_TO_OVERTIME );
	trap_SoundIndex( S_ANNOUNCER_OVERTIME_OVERTIME );
	trap_SoundIndex( va( S_ANNOUNCER_OVERTIME_SUDDENDEATH_1_to_2, 1 ) );
	trap_SoundIndex( va( S_ANNOUNCER_OVERTIME_SUDDENDEATH_1_to_2, 2 ) );

	// score
	trap_SoundIndex( va( S_ANNOUNCER_SCORE_TAKEN_LEAD_1_to_2, 1 ) );
	trap_SoundIndex( va( S_ANNOUNCER_SCORE_TAKEN_LEAD_1_to_2, 2 ) );
	trap_SoundIndex( va( S_ANNOUNCER_SCORE_LOST_LEAD_1_to_2, 1 ) );
	trap_SoundIndex( va( S_ANNOUNCER_SCORE_LOST_LEAD_1_to_2, 2 ) );
	trap_SoundIndex( va( S_ANNOUNCER_SCORE_TIED_LEAD_1_to_2, 1 ) );
	trap_SoundIndex( va( S_ANNOUNCER_SCORE_TIED_LEAD_1_to_2, 2 ) );

	if( GS_TeamBasedGametype() )
	{
		trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_TAKEN_LEAD_1_to_2, 1 ) );
		trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_TAKEN_LEAD_1_to_2, 2 ) );
		trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_LOST_LEAD_1_to_2, 1 ) );
		trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_LOST_LEAD_1_to_2, 2 ) );
		trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_TIED_LEAD_1_to_2, 1 ) );
		trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_TIED_LEAD_1_to_2, 2 ) );
		trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_TIED_LEAD_1_to_2, 1 ) );
		trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_TIED_LEAD_1_to_2, 2 ) );
		//trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_1_to_4_TAKEN_LEAD_1_to_2, 3, 1 ) );
		//trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_1_to_4_TAKEN_LEAD_1_to_2, 3, 2 ) );
		//trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_1_to_4_TAKEN_LEAD_1_to_2, 4, 1 ) );
		//trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_1_to_4_TAKEN_LEAD_1_to_2, 4, 2 ) );
	}

	//
	// LIGHTSTYLES
	//

	// light animation tables. 'a' is total darkness, 'z' is doublebright.

	// 0 normal
	trap_ConfigString( CS_LIGHTS+0, "m" );

	// 1 FLICKER (first variety)
	trap_ConfigString( CS_LIGHTS+1, "mmnmmommommnonmmonqnmmo" );

	// 2 SLOW STRONG PULSE
	trap_ConfigString( CS_LIGHTS+2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba" );

	// 3 CANDLE (first variety)
	trap_ConfigString( CS_LIGHTS+3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg" );

	// 4 FAST STROBE
	trap_ConfigString( CS_LIGHTS+4, "mamamamamama" );

	// 5 GENTLE PULSE 1
	trap_ConfigString( CS_LIGHTS+5, "jklmnopqrstuvwxyzyxwvutsrqponmlkj" );

	// 6 FLICKER (second variety)
	trap_ConfigString( CS_LIGHTS+6, "nmonqnmomnmomomno" );

	// 7 CANDLE (second variety)
	trap_ConfigString( CS_LIGHTS+7, "mmmaaaabcdefgmmmmaaaammmaamm" );

	// 8 CANDLE (third variety)
	trap_ConfigString( CS_LIGHTS+8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa" );

	// 9 SLOW STROBE (fourth variety)
	trap_ConfigString( CS_LIGHTS+9, "aaaaaaaazzzzzzzz" );

	// 10 FLUORESCENT FLICKER
	trap_ConfigString( CS_LIGHTS+10, "mmamammmmammamamaaamammma" );

	// 11 SLOW PULSE NOT FADE TO BLACK
	trap_ConfigString( CS_LIGHTS+11, "abcdefghijklmnopqrrqponmlkjihgfedcba" );

	// styles 32-62 are assigned by the light program for switchable lights

	// 63 testing
	trap_ConfigString( CS_LIGHTS+63, "a" );
}