예제 #1
0
/*
======================
UI_ParseAnimationFile
======================
*/
static qboolean UI_ParseAnimationFile( const char *filename, uiPlayerInfo_t *pi ) {
	char		*text_p, *prev;
	int			len;
	int			i;
	char		*token;
	float		fps;
	int			skip;
	char		text[20000];
	fileHandle_t	f;
	animation_t *animations;

	animations = pi->animations;

	memset( animations, 0, sizeof( animation_t ) * MAX_ANIMATIONS );

	pi->fixedlegs = qfalse;
	pi->fixedtorso = qfalse;

	// load the file
	len = trap_FS_FOpenFile( filename, &f, FS_READ );
	if ( len <= 0 ) {
		return qfalse;
	}
	if ( len >= ( sizeof( text ) - 1 ) ) {
		Com_Printf( "File %s too long\n", filename );
		trap_FS_FCloseFile( f );
		return qfalse;
	}
	trap_FS_Read( text, len, f );
	text[len] = 0;
	trap_FS_FCloseFile( f );

	// parse the text
	text_p = text;
	skip = 0;	// quite the compiler warning

	// read optional parameters
	while ( 1 ) {
		prev = text_p;	// so we can unget
		token = COM_Parse( &text_p );
		if ( !token[0] ) {
			break;
		}
		if ( !Q_stricmp( token, "footsteps" ) ) {
			token = COM_Parse( &text_p );
			if ( !token[0] ) {
				break;
			}
			continue;
		} else if ( !Q_stricmp( token, "headoffset" ) ) {
			for ( i = 0 ; i < 3 ; i++ ) {
				token = COM_Parse( &text_p );
				if ( !token[0] ) {
					break;
				}
			}
			continue;
		} else if ( !Q_stricmp( token, "sex" ) ) {
			token = COM_Parse( &text_p );
			if ( !token[0] ) {
				break;
			}
			continue;
		} else if ( !Q_stricmp( token, "fixedlegs" ) ) {
			pi->fixedlegs = qtrue;
			continue;
		} else if ( !Q_stricmp( token, "fixedtorso" ) ) {
			pi->fixedtorso = qtrue;
			continue;
		}

		// if it is a number, start parsing animations
		if ( token[0] >= '0' && token[0] <= '9' ) {
			text_p = prev;	// unget the token
			break;
		}

		Com_Printf( "unknown token '%s' in %s\n", token, filename );
	}

	// read information for each frame
	for ( i = 0 ; i < MAX_ANIMATIONS ; i++ ) {

		token = COM_Parse( &text_p );
		if ( !token[0] ) {
			if( i >= TORSO_GETFLAG && i <= TORSO_NEGATIVE ) {
				animations[i].firstFrame = animations[TORSO_GESTURE].firstFrame;
				animations[i].frameLerp = animations[TORSO_GESTURE].frameLerp;
				animations[i].initialLerp = animations[TORSO_GESTURE].initialLerp;
				animations[i].loopFrames = animations[TORSO_GESTURE].loopFrames;
				animations[i].numFrames = animations[TORSO_GESTURE].numFrames;
				animations[i].reversed = qfalse;
				animations[i].flipflop = qfalse;
				continue;
			}
			break;
		}
		animations[i].firstFrame = atoi( token );
		// leg only frames are adjusted to not count the upper body only frames
		if ( i == LEGS_WALKCR ) {
			skip = animations[LEGS_WALKCR].firstFrame - animations[TORSO_GESTURE].firstFrame;
		}
		if ( i >= LEGS_WALKCR && i<TORSO_GETFLAG) {
			animations[i].firstFrame -= skip;
		}

		token = COM_Parse( &text_p );
		if ( !token[0] ) {
			break;
		}
		animations[i].numFrames = atoi( token );

		animations[i].reversed = qfalse;
		animations[i].flipflop = qfalse;
		// if numFrames is negative the animation is reversed
		if (animations[i].numFrames < 0) {
			animations[i].numFrames = -animations[i].numFrames;
			animations[i].reversed = qtrue;
		}

		token = COM_Parse( &text_p );
		if ( !token[0] ) {
			break;
		}
		animations[i].loopFrames = atoi( token );

		token = COM_Parse( &text_p );
		if ( !token[0] ) {
			break;
		}
		fps = atof( token );
		if ( fps == 0 ) {
			fps = 1;
		}
		animations[i].frameLerp = 1000 / fps;
		animations[i].initialLerp = 1000 / fps;
	}

	if ( i != MAX_ANIMATIONS ) {
		Com_Printf( "Error parsing animation file: %s\n", filename );
		return qfalse;
	}

	return qtrue;
}
예제 #2
0
파일: g_log.c 프로젝트: aufau/SaberMod
void G_LogWeaponOutput(void)
{
#ifdef LOGGING_WEAPONS
	int i,j,curwp;
	float pershot;
	fileHandle_t weaponfile;
	char string[1024];

	int totalpickups[WP_NUM_WEAPONS];
	int totaltime[WP_NUM_WEAPONS];
	int totaldeaths[WP_NUM_WEAPONS];
	int totaldamageMOD[MOD_MAX];
	int totalkillsMOD[MOD_MAX];
	int totaldamage[WP_NUM_WEAPONS];
	int totalkills[WP_NUM_WEAPONS];
	int totalshots[WP_NUM_WEAPONS];
	int percharacter[WP_NUM_WEAPONS];
	char info[MAX_INFO_STRING];
	char mapname[MAX_QPATH];
	char *nameptr, *unknownname="<Unknown>";

	if (!g_statLog.integer)
	{
		return;
	}

	G_LogPrintf( LOG_WEAPON_STATS, "*****************************Weapon Log:\n" );

	memset(totalpickups, 0, sizeof(totalpickups));
	memset(totaltime, 0, sizeof(totaltime));
	memset(totaldeaths, 0, sizeof(totaldeaths));
	memset(totaldamageMOD, 0, sizeof(totaldamageMOD));
	memset(totalkillsMOD, 0, sizeof(totalkillsMOD));
	memset(totaldamage, 0, sizeof(totaldamage));
	memset(totalkills, 0, sizeof(totalkills));
	memset(totalshots, 0, sizeof(totalshots));

	for (i=0; i<MAX_CLIENTS; i++)
	{
		if (G_WeaponLogClientTouch[i])
		{	// Ignore any entity/clients we don't care about!
			for (j=0;j<WP_NUM_WEAPONS;j++)
			{
				totalpickups[j] += G_WeaponLogPickups[i][j];
				totaltime[j] += G_WeaponLogTime[i][j];
				totaldeaths[j] += G_WeaponLogDeaths[i][j];
				totalshots[j] += G_WeaponLogFired[i][j];
			}

			for (j=0;j<MOD_MAX;j++)
			{
				totaldamageMOD[j] += G_WeaponLogDamage[i][j];
				totalkillsMOD[j] += G_WeaponLogKills[i][j];
			}
		}
	}

	// Now total the weapon data from the MOD data.
	for (j=0; j<MOD_MAX; j++)
	{
		if (j <= MOD_SENTRY)
		{
			curwp = weaponFromMOD[j];
			totaldamage[curwp] += totaldamageMOD[j];
			totalkills[curwp] += totalkillsMOD[j];
		}
	}

	G_LogPrintf( LOG_WEAPON_STATS, "****Data by Weapon:\n" );
	for (j=0; j<WP_NUM_WEAPONS; j++)
	{
		G_LogPrintf( LOG_WEAPON_STATS, "%15s:  Pickups: %4d,  Time:  %5d,  Deaths: %5d\n",
				weaponNameFromIndex[j], totalpickups[j], (int)(totaltime[j]/1000), totaldeaths[j]);
	}

	G_LogPrintf( LOG_WEAPON_STATS, "****Combat Data by Weapon:\n" );
	for (j=0; j<WP_NUM_WEAPONS; j++)
	{
		if (totalshots[j] > 0)
		{
			pershot = (float)(totaldamage[j])/(float)(totalshots[j]);
		}
		else
		{
			pershot = 0;
		}
		G_LogPrintf( LOG_WEAPON_STATS, "%15s:  Damage: %6d,  Kills: %5d,  Dmg per Shot: %f\n",
				weaponNameFromIndex[j], totaldamage[j], totalkills[j], pershot);
	}

	G_LogPrintf( LOG_WEAPON_STATS, "****Combat Data By Damage Type:\n" );
	for (j=0; j<MOD_MAX; j++)
	{
		G_LogPrintf( LOG_WEAPON_STATS, "%25s:  Damage: %6d,  Kills: %5d\n",
				modNames[j], totaldamageMOD[j], totalkillsMOD[j]);
	}

	G_LogPrintf( LOG_WEAPON_STATS, "\n");



	// Write the whole weapon statistic log out to a file.
	trap_FS_FOpenFile( g_statLogFile.string, &weaponfile, FS_APPEND );
	if (!weaponfile) {	//failed to open file, let's not crash, shall we?
		return;
	}

	// Write out the level name
	trap_GetServerinfo(info, sizeof(info));
	Q_strncpyz(mapname, Info_ValueForKey( info, "mapname" ), sizeof(mapname));

	Com_sprintf(string, sizeof(string), "\n\n\nLevel:\t%s\n\n\n", mapname);
	trap_FS_Write( string, strlen( string ), weaponfile);


	// Combat data per character

	// Start with Pickups per character
	Com_sprintf(string, sizeof(string), "Weapon Pickups per Player:\n\n");
	trap_FS_Write( string, strlen( string ), weaponfile);

	Com_sprintf(string, sizeof(string), "Player");
	trap_FS_Write(string, strlen(string), weaponfile);

	for (j=0; j<WP_NUM_WEAPONS; j++)
	{
		Com_sprintf(string, sizeof(string), "\t%s", weaponNameFromIndex[j]);
		trap_FS_Write(string, strlen(string), weaponfile);
	}
	Com_sprintf(string, sizeof(string), "\n");
	trap_FS_Write(string, strlen(string), weaponfile);

	// Cycle through each player, give their name and the number of times they picked up each weapon.
	for (i=0; i<MAX_CLIENTS; i++)
	{
		if (G_WeaponLogClientTouch[i])
		{	// Ignore any entity/clients we don't care about!
			if ( g_entities[i].client )
			{
				nameptr = g_entities[i].client->pers.netname;
			}
			else
			{
				nameptr = unknownname;
			}
			trap_FS_Write(nameptr, strlen(nameptr), weaponfile);

			for (j=0;j<WP_NUM_WEAPONS;j++)
			{
				Com_sprintf(string, sizeof(string), "\t%d", G_WeaponLogPickups[i][j]);
				trap_FS_Write(string, strlen(string), weaponfile);
			}

			Com_sprintf(string, sizeof(string), "\n");
			trap_FS_Write(string, strlen(string), weaponfile);
		}
	}

	// Sum up the totals.
	Com_sprintf(string, sizeof(string), "\n***TOTAL:");
	trap_FS_Write(string, strlen(string), weaponfile);

	for (j=0;j<WP_NUM_WEAPONS;j++)
	{
		Com_sprintf(string, sizeof(string), "\t%d", totalpickups[j]);
		trap_FS_Write(string, strlen(string), weaponfile);
	}

	Com_sprintf(string, sizeof(string), "\n\n\n");
	trap_FS_Write(string, strlen(string), weaponfile);


	// Weapon fires per character
	Com_sprintf(string, sizeof(string), "Weapon Shots per Player:\n\n");
	trap_FS_Write( string, strlen( string ), weaponfile);

	Com_sprintf(string, sizeof(string), "Player");
	trap_FS_Write(string, strlen(string), weaponfile);

	for (j=0; j<WP_NUM_WEAPONS; j++)
	{
		Com_sprintf(string, sizeof(string), "\t%s", weaponNameFromIndex[j]);
		trap_FS_Write(string, strlen(string), weaponfile);
	}
	Com_sprintf(string, sizeof(string), "\n");
	trap_FS_Write(string, strlen(string), weaponfile);

	// Cycle through each player, give their name and the number of times they picked up each weapon.
	for (i=0; i<MAX_CLIENTS; i++)
	{
		if (G_WeaponLogClientTouch[i])
		{	// Ignore any entity/clients we don't care about!
			if ( g_entities[i].client )
			{
				nameptr = g_entities[i].client->pers.netname;
			}
			else
			{
				nameptr = unknownname;
			}
			trap_FS_Write(nameptr, strlen(nameptr), weaponfile);

			for (j=0;j<WP_NUM_WEAPONS;j++)
			{
				Com_sprintf(string, sizeof(string), "\t%d", G_WeaponLogFired[i][j]);
				trap_FS_Write(string, strlen(string), weaponfile);
			}

			Com_sprintf(string, sizeof(string), "\n");
			trap_FS_Write(string, strlen(string), weaponfile);
		}
	}

	// Sum up the totals.
	Com_sprintf(string, sizeof(string), "\n***TOTAL:");
	trap_FS_Write(string, strlen(string), weaponfile);

	for (j=0;j<WP_NUM_WEAPONS;j++)
	{
		Com_sprintf(string, sizeof(string), "\t%d", totalshots[j]);
		trap_FS_Write(string, strlen(string), weaponfile);
	}

	Com_sprintf(string, sizeof(string), "\n\n\n");
	trap_FS_Write(string, strlen(string), weaponfile);


	// Weapon time per character
	Com_sprintf(string, sizeof(string), "Weapon Use Time per Player:\n\n");
	trap_FS_Write( string, strlen( string ), weaponfile);

	Com_sprintf(string, sizeof(string), "Player");
	trap_FS_Write(string, strlen(string), weaponfile);

	for (j=0; j<WP_NUM_WEAPONS; j++)
	{
		Com_sprintf(string, sizeof(string), "\t%s", weaponNameFromIndex[j]);
		trap_FS_Write(string, strlen(string), weaponfile);
	}
	Com_sprintf(string, sizeof(string), "\n");
	trap_FS_Write(string, strlen(string), weaponfile);

	// Cycle through each player, give their name and the number of times they picked up each weapon.
	for (i=0; i<MAX_CLIENTS; i++)
	{
		if (G_WeaponLogClientTouch[i])
		{	// Ignore any entity/clients we don't care about!
			if ( g_entities[i].client )
			{
				nameptr = g_entities[i].client->pers.netname;
			}
			else
			{
				nameptr = unknownname;
			}
			trap_FS_Write(nameptr, strlen(nameptr), weaponfile);

			for (j=0;j<WP_NUM_WEAPONS;j++)
			{
				Com_sprintf(string, sizeof(string), "\t%d", G_WeaponLogTime[i][j]);
				trap_FS_Write(string, strlen(string), weaponfile);
			}

			Com_sprintf(string, sizeof(string), "\n");
			trap_FS_Write(string, strlen(string), weaponfile);
		}
	}

	// Sum up the totals.
	Com_sprintf(string, sizeof(string), "\n***TOTAL:");
	trap_FS_Write(string, strlen(string), weaponfile);

	for (j=0;j<WP_NUM_WEAPONS;j++)
	{
		Com_sprintf(string, sizeof(string), "\t%d", totaltime[j]);
		trap_FS_Write(string, strlen(string), weaponfile);
	}

	Com_sprintf(string, sizeof(string), "\n\n\n");
	trap_FS_Write(string, strlen(string), weaponfile);



	// Weapon deaths per character
	Com_sprintf(string, sizeof(string), "Weapon Deaths per Player:\n\n");
	trap_FS_Write( string, strlen( string ), weaponfile);

	Com_sprintf(string, sizeof(string), "Player");
	trap_FS_Write(string, strlen(string), weaponfile);

	for (j=0; j<WP_NUM_WEAPONS; j++)
	{
		Com_sprintf(string, sizeof(string), "\t%s", weaponNameFromIndex[j]);
		trap_FS_Write(string, strlen(string), weaponfile);
	}
	Com_sprintf(string, sizeof(string), "\n");
	trap_FS_Write(string, strlen(string), weaponfile);

	// Cycle through each player, give their name and the number of times they picked up each weapon.
	for (i=0; i<MAX_CLIENTS; i++)
	{
		if (G_WeaponLogClientTouch[i])
		{	// Ignore any entity/clients we don't care about!
			if ( g_entities[i].client )
			{
				nameptr = g_entities[i].client->pers.netname;
			}
			else
			{
				nameptr = unknownname;
			}
			trap_FS_Write(nameptr, strlen(nameptr), weaponfile);

			for (j=0;j<WP_NUM_WEAPONS;j++)
			{
				Com_sprintf(string, sizeof(string), "\t%d", G_WeaponLogDeaths[i][j]);
				trap_FS_Write(string, strlen(string), weaponfile);
			}

			Com_sprintf(string, sizeof(string), "\n");
			trap_FS_Write(string, strlen(string), weaponfile);
		}
	}

	// Sum up the totals.
	Com_sprintf(string, sizeof(string), "\n***TOTAL:");
	trap_FS_Write(string, strlen(string), weaponfile);

	for (j=0;j<WP_NUM_WEAPONS;j++)
	{
		Com_sprintf(string, sizeof(string), "\t%d", totaldeaths[j]);
		trap_FS_Write(string, strlen(string), weaponfile);
	}

	Com_sprintf(string, sizeof(string), "\n\n\n");
	trap_FS_Write(string, strlen(string), weaponfile);




	// Weapon damage per character

	Com_sprintf(string, sizeof(string), "Weapon Damage per Player:\n\n");
	trap_FS_Write( string, strlen( string ), weaponfile);

	Com_sprintf(string, sizeof(string), "Player");
	trap_FS_Write(string, strlen(string), weaponfile);

	for (j=0; j<WP_NUM_WEAPONS; j++)
	{
		Com_sprintf(string, sizeof(string), "\t%s", weaponNameFromIndex[j]);
		trap_FS_Write(string, strlen(string), weaponfile);
	}
	Com_sprintf(string, sizeof(string), "\n");
	trap_FS_Write(string, strlen(string), weaponfile);

	// Cycle through each player, give their name and the number of times they picked up each weapon.
	for (i=0; i<MAX_CLIENTS; i++)
	{
		if (G_WeaponLogClientTouch[i])
		{	// Ignore any entity/clients we don't care about!

			// We must grab the totals from the damage types for the player and map them to the weapons.
			memset(percharacter, 0, sizeof(percharacter));
			for (j=0; j<MOD_MAX; j++)
			{
				if (j <= MOD_SENTRY)
				{
					curwp = weaponFromMOD[j];
					percharacter[curwp] += G_WeaponLogDamage[i][j];
				}
			}

			if ( g_entities[i].client )
			{
				nameptr = g_entities[i].client->pers.netname;
			}
			else
			{
				nameptr = unknownname;
			}
			trap_FS_Write(nameptr, strlen(nameptr), weaponfile);

			for (j=0;j<WP_NUM_WEAPONS;j++)
			{
				Com_sprintf(string, sizeof(string), "\t%d", percharacter[j]);
				trap_FS_Write(string, strlen(string), weaponfile);
			}

			Com_sprintf(string, sizeof(string), "\n");
			trap_FS_Write(string, strlen(string), weaponfile);
		}
	}

	// Sum up the totals.
	Com_sprintf(string, sizeof(string), "\n***TOTAL:");
	trap_FS_Write(string, strlen(string), weaponfile);

	for (j=0;j<WP_NUM_WEAPONS;j++)
	{
		Com_sprintf(string, sizeof(string), "\t%d", totaldamage[j]);
		trap_FS_Write(string, strlen(string), weaponfile);
	}

	Com_sprintf(string, sizeof(string), "\n\n\n");
	trap_FS_Write(string, strlen(string), weaponfile);



	// Weapon kills per character

	Com_sprintf(string, sizeof(string), "Weapon Kills per Player:\n\n");
	trap_FS_Write( string, strlen( string ), weaponfile);

	Com_sprintf(string, sizeof(string), "Player");
	trap_FS_Write(string, strlen(string), weaponfile);

	for (j=0; j<WP_NUM_WEAPONS; j++)
	{
		Com_sprintf(string, sizeof(string), "\t%s", weaponNameFromIndex[j]);
		trap_FS_Write(string, strlen(string), weaponfile);
	}
	Com_sprintf(string, sizeof(string), "\n");
	trap_FS_Write(string, strlen(string), weaponfile);

	// Cycle through each player, give their name and the number of times they picked up each weapon.
	for (i=0; i<MAX_CLIENTS; i++)
	{
		if (G_WeaponLogClientTouch[i])
		{	// Ignore any entity/clients we don't care about!

			// We must grab the totals from the damage types for the player and map them to the weapons.
			memset(percharacter, 0, sizeof(percharacter));
			for (j=0; j<MOD_MAX; j++)
			{
				if (j <= MOD_SENTRY)
				{
					curwp = weaponFromMOD[j];
					percharacter[curwp] += G_WeaponLogKills[i][j];
				}
			}

			if ( g_entities[i].client )
			{
				nameptr = g_entities[i].client->pers.netname;
			}
			else
			{
				nameptr = unknownname;
			}
			trap_FS_Write(nameptr, strlen(nameptr), weaponfile);

			for (j=0;j<WP_NUM_WEAPONS;j++)
			{
				Com_sprintf(string, sizeof(string), "\t%d", percharacter[j]);
				trap_FS_Write(string, strlen(string), weaponfile);
			}

			Com_sprintf(string, sizeof(string), "\n");
			trap_FS_Write(string, strlen(string), weaponfile);
		}
	}

	// Sum up the totals.
	Com_sprintf(string, sizeof(string), "\n***TOTAL:");
	trap_FS_Write(string, strlen(string), weaponfile);

	for (j=0;j<WP_NUM_WEAPONS;j++)
	{
		Com_sprintf(string, sizeof(string), "\t%d", totalkills[j]);
		trap_FS_Write(string, strlen(string), weaponfile);
	}

	Com_sprintf(string, sizeof(string), "\n\n\n");
	trap_FS_Write(string, strlen(string), weaponfile);



	// Damage type damage per character
	Com_sprintf(string, sizeof(string), "Typed Damage per Player:\n\n");
	trap_FS_Write( string, strlen( string ), weaponfile);

	Com_sprintf(string, sizeof(string), "Player");
	trap_FS_Write(string, strlen(string), weaponfile);

	for (j=0; j<MOD_MAX; j++)
	{
		Com_sprintf(string, sizeof(string), "\t%s", modNames[j]);
		trap_FS_Write(string, strlen(string), weaponfile);
	}
	Com_sprintf(string, sizeof(string), "\n");
	trap_FS_Write(string, strlen(string), weaponfile);

	// Cycle through each player, give their name and the number of times they picked up each weapon.
	for (i=0; i<MAX_CLIENTS; i++)
	{
		if (G_WeaponLogClientTouch[i])
		{	// Ignore any entity/clients we don't care about!
			if ( g_entities[i].client )
			{
				nameptr = g_entities[i].client->pers.netname;
			}
			else
			{
				nameptr = unknownname;
			}
			trap_FS_Write(nameptr, strlen(nameptr), weaponfile);

			for (j=0;j<MOD_MAX;j++)
			{
				Com_sprintf(string, sizeof(string), "\t%d", G_WeaponLogDamage[i][j]);
				trap_FS_Write(string, strlen(string), weaponfile);
			}

			Com_sprintf(string, sizeof(string), "\n");
			trap_FS_Write(string, strlen(string), weaponfile);
		}
	}

	// Sum up the totals.
	Com_sprintf(string, sizeof(string), "\n***TOTAL:");
	trap_FS_Write(string, strlen(string), weaponfile);

	for (j=0;j<MOD_MAX;j++)
	{
		Com_sprintf(string, sizeof(string), "\t%d", totaldamageMOD[j]);
		trap_FS_Write(string, strlen(string), weaponfile);
	}

	Com_sprintf(string, sizeof(string), "\n\n\n");
	trap_FS_Write(string, strlen(string), weaponfile);



	// Damage type kills per character
	Com_sprintf(string, sizeof(string), "Damage-Typed Kills per Player:\n\n");
	trap_FS_Write( string, strlen( string ), weaponfile);

	Com_sprintf(string, sizeof(string), "Player");
	trap_FS_Write(string, strlen(string), weaponfile);

	for (j=0; j<MOD_MAX; j++)
	{
		Com_sprintf(string, sizeof(string), "\t%s", modNames[j]);
		trap_FS_Write(string, strlen(string), weaponfile);
	}
	Com_sprintf(string, sizeof(string), "\n");
	trap_FS_Write(string, strlen(string), weaponfile);

	// Cycle through each player, give their name and the number of times they picked up each weapon.
	for (i=0; i<MAX_CLIENTS; i++)
	{
		if (G_WeaponLogClientTouch[i])
		{	// Ignore any entity/clients we don't care about!
			if ( g_entities[i].client )
			{
				nameptr = g_entities[i].client->pers.netname;
			}
			else
			{
				nameptr = unknownname;
			}
			trap_FS_Write(nameptr, strlen(nameptr), weaponfile);

			for (j=0;j<MOD_MAX;j++)
			{
				Com_sprintf(string, sizeof(string), "\t%d", G_WeaponLogKills[i][j]);
				trap_FS_Write(string, strlen(string), weaponfile);
			}

			Com_sprintf(string, sizeof(string), "\n");
			trap_FS_Write(string, strlen(string), weaponfile);
		}
	}

	// Sum up the totals.
	Com_sprintf(string, sizeof(string), "\n***TOTAL:");
	trap_FS_Write(string, strlen(string), weaponfile);

	for (j=0;j<MOD_MAX;j++)
	{
		Com_sprintf(string, sizeof(string), "\t%d", totalkillsMOD[j]);
		trap_FS_Write(string, strlen(string), weaponfile);
	}

	Com_sprintf(string, sizeof(string), "\n\n\n");
	trap_FS_Write(string, strlen(string), weaponfile);


	trap_FS_FCloseFile(weaponfile);


#endif //LOGGING_WEAPONS
}
예제 #3
0
static void CG_ServerCommand( void ) {
	const char  *cmd;
	char text[MAX_SAY_TEXT];

	cmd = CG_Argv( 0 );

	if ( !cmd[0] ) {
		// server claimed the command
		return;
	}

	if ( !strcmp( cmd, "startCam" ) ) {
		CG_StartCamera( CG_Argv( 1 ), atoi( CG_Argv( 2 ) ) );
		return;
	}

	if ( !strcmp( cmd, "stopCam" ) ) {
		CG_StopCamera();
		return;
	}

	if ( !strcmp( cmd, "mvspd" ) ) {
		CG_RequestMoveSpeed( CG_Argv( 1 ) );
		return;
	}

	if ( !strcmp( cmd, "dp" ) ) {    // dynamite print (what a hack :(

		CG_CenterPrint( va( "%s %d %s", CG_translateString( "dynamitetimer" ), atoi( CG_Argv( 1 ) ), CG_translateString( "seconds" ) ),
						SCREEN_HEIGHT - ( SCREEN_HEIGHT * 0.25 ), SMALLCHAR_WIDTH );
		return;
	}

	if ( !strcmp( cmd, "cp" ) ) {
		CG_CenterPrint( CG_Argv( 1 ), SCREEN_HEIGHT - ( SCREEN_HEIGHT * 0.25 ), SMALLCHAR_WIDTH );
		return;
	}

	if ( !strcmp( cmd, "cs" ) ) {
		CG_ConfigStringModified();
		return;
	}

	if ( !strcmp( cmd, "print" ) ) {
		CG_Printf( "%s", CG_Argv( 1 ) );
#ifdef MISSIONPACK
		cmd = CG_Argv( 1 );           // yes, this is obviously a hack, but so is the way we hear about
									  // votes passing or failing
		if ( !Q_stricmpn( cmd, "vote failed", 11 ) || !Q_stricmpn( cmd, "team vote failed", 16 ) ) {
			trap_S_StartLocalSound( cgs.media.voteFailed, CHAN_ANNOUNCER );
		} else if ( !Q_stricmpn( cmd, "vote passed", 11 ) || !Q_stricmpn( cmd, "team vote passed", 16 ) ) {
			trap_S_StartLocalSound( cgs.media.votePassed, CHAN_ANNOUNCER );
		}
#endif
		return;
	}

	if ( !strcmp( cmd, "chat" ) ) {
		if ( !cg_teamChatsOnly.integer ) {
			trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
			Q_strncpyz( text, CG_Argv( 1 ), MAX_SAY_TEXT );
			CG_RemoveChatEscapeChar( text );
			CG_Printf( "%s\n", text );
		}
		return;
	}

	if ( !strcmp( cmd, "tchat" ) ) {
		trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
		Q_strncpyz( text, CG_Argv( 1 ), MAX_SAY_TEXT );
		CG_RemoveChatEscapeChar( text );
		CG_AddToTeamChat( text );
		CG_Printf( "%s\n", text );
		return;
	}

	// NERVE - SMF - limbo chat
	if ( !strcmp( cmd, "lchat" ) ) {
		trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
		Q_strncpyz( text, CG_Argv( 1 ), MAX_SAY_TEXT );
		CG_RemoveChatEscapeChar( text );
//		CG_AddToLimboChat( text );
		trap_UI_LimboChat( text );
		CG_Printf( "%s\n", text );
		return;
	}
	// -NERVE - SMF

	if ( !strcmp( cmd, "vchat" ) ) {
//		CG_VoiceChat( SAY_ALL );
		return;
	}

	if ( !strcmp( cmd, "vtchat" ) ) {
//		CG_VoiceChat( SAY_TEAM );
		return;
	}

	if ( !strcmp( cmd, "vtell" ) ) {
//		CG_VoiceChat( SAY_TELL );
		return;
	}

	if ( !strcmp( cmd, "scores" ) ) {
		CG_ParseScores();
		return;
	}

	if ( !strcmp( cmd, "tinfo" ) ) {
		CG_ParseTeamInfo();
		return;
	}

	if ( !strcmp( cmd, "map_restart" ) ) {
		CG_MapRestart();
		return;
	}

	if ( Q_stricmp( cmd, "remapShader" ) == 0 ) {
		if ( trap_Argc() == 4 ) {
			trap_R_RemapShader( CG_Argv( 1 ), CG_Argv( 2 ), CG_Argv( 3 ) );
		}
	}

	// loaddeferred can be both a servercmd and a consolecmd
	if ( !strcmp( cmd, "loaddeferred" ) ) {  // spelling fixed (SA)
		CG_LoadDeferredPlayers();
		return;
	}

	// clientLevelShot is sent before taking a special screenshot for
	// the menu system during development
	if ( !strcmp( cmd, "clientLevelShot" ) ) {
		cg.levelShot = qtrue;
		return;
	}

	// NERVE - SMF
	if ( !Q_stricmp( cmd, "oid" ) ) {
		CG_ObjectivePrint( CG_Argv( 2 ), SMALLCHAR_WIDTH, atoi( CG_Argv( 1 ) ) );
		return;
	}
	// -NERVE - SMF


	//
	// music
	//

	// loops \/
	if ( !strcmp( cmd, "mu_start" ) ) {  // has optional parameter for fade-up time
		int fadeTime = 0;   // default to instant start

		Q_strncpyz( text, CG_Argv( 2 ), MAX_SAY_TEXT );
		if ( text && strlen( text ) ) {
			fadeTime = atoi( text );
		}

		trap_S_StartBackgroundTrack( CG_Argv( 1 ), CG_Argv( 1 ), fadeTime );
		return;
	}
	// plays once then back to whatever the loop was \/
	if ( !strcmp( cmd, "mu_play" ) ) {   // has optional parameter for fade-up time
		int fadeTime = 0;   // default to instant start

		Q_strncpyz( text, CG_Argv( 2 ), MAX_SAY_TEXT );
		if ( text && strlen( text ) ) {
			fadeTime = atoi( text );
		}

		trap_S_StartBackgroundTrack( CG_Argv( 1 ), "onetimeonly", fadeTime );
		return;
	}

	if ( !strcmp( cmd, "mu_stop" ) ) {   // has optional parameter for fade-down time
		int fadeTime = 0;   // default to instant stop

		Q_strncpyz( text, CG_Argv( 1 ), MAX_SAY_TEXT );
		if ( text && strlen( text ) ) {
			fadeTime = atoi( text );
		}
		trap_S_FadeBackgroundTrack( 0.0f, fadeTime, 0 );
		trap_S_StartBackgroundTrack( "", "", -2 ); // '-2' for 'queue looping track' (QUEUED_PLAY_LOOPED)
		return;
	}

	if ( !strcmp( cmd, "mu_fade" ) ) {
		trap_S_FadeBackgroundTrack( atof( CG_Argv( 1 ) ), atoi( CG_Argv( 2 ) ), 0 );
		return;
	}

	if ( !strcmp( cmd, "snd_fade" ) ) {
		trap_S_FadeAllSound( atof( CG_Argv( 1 ) ), atoi( CG_Argv( 2 ) ) );
		return;
	}

	if ( !strcmp( cmd, "rockandroll" ) ) {   // map loaded, game is ready to begin.
		CG_Fade( 0, 0, 0, 255, cg.time, 0 );      // go black
		trap_UI_Popup( "pregame" );                // start pregame menu
		trap_Cvar_Set( "cg_norender", "1" );    // don't render the world until the player clicks in and the 'playerstart' func has been called (g_main in G_UpdateCvars() ~ilne 949)

		trap_S_FadeAllSound( 1.0f, 1000 );    // fade sound up

		return;
	}



	// ensure a file gets into a build (mainly for scripted music calls)
	if ( !strcmp( cmd, "addToBuild" ) ) {
		fileHandle_t f;

		if ( !cg_buildScript.integer ) {
			return;
		}

		// just open the file so it gets copied to the build dir
		//CG_FileTouchForBuild(CG_Argv(1));
		trap_FS_FOpenFile( CG_Argv( 1 ), &f, FS_READ );
		trap_FS_FCloseFile( f );
		return;
	}


	CG_Printf( "Unknown client game command: %s\n", cmd );
}
예제 #4
0
int strap_FS_FOpenFile( const char *qpath, fileHandle_t *f, fsMode_t mode )
{
    return trap_FS_FOpenFile (qpath, f, mode);
}
예제 #5
0
/*
===============
CG_InitBuildables

Initialises the animation db
===============
*/
void CG_InitBuildables( void )
{
  char          filename[ MAX_QPATH ];
  char          soundfile[ MAX_QPATH ];
  char          *buildableName;
  char          *modelFile;
  int           i;
  int           j;
  fileHandle_t  f;

  memset( cg_buildables, 0, sizeof( cg_buildables ) );

  //default sounds
  for( j = BANIM_NONE + 1; j < MAX_BUILDABLE_ANIMATIONS; j++ )
  {
    strcpy( soundfile, cg_buildableSoundNames[ j - 1 ] );

    Com_sprintf( filename, sizeof( filename ), "sound/buildables/alien/%s", soundfile );
    defaultAlienSounds[ j ] = trap_S_RegisterSound( filename, qfalse );

    Com_sprintf( filename, sizeof( filename ), "sound/buildables/human/%s", soundfile );
    defaultHumanSounds[ j ] = trap_S_RegisterSound( filename, qfalse );
  }

  cg.buildablesFraction = 0.0f;

  for( i = BA_NONE + 1; i < BA_NUM_BUILDABLES; i++ )
  {
    buildableName = BG_Buildable( i )->name;

    //animation.cfg
    Com_sprintf( filename, sizeof( filename ), "models/buildables/%s/animation.cfg", buildableName );
    if ( !CG_ParseBuildableAnimationFile( filename, i ) )
      Com_Printf( S_COLOR_YELLOW "WARNING: failed to load animation file %s\n", filename );

    //sound.cfg
    Com_sprintf( filename, sizeof( filename ), "sound/buildables/%s/sound.cfg", buildableName );
    if ( !CG_ParseBuildableSoundFile( filename, i ) )
      Com_Printf( S_COLOR_YELLOW "WARNING: failed to load sound file %s\n", filename );

    //models
    for( j = 0; j <= 3; j++ )
    {
      modelFile = BG_BuildableConfig( i )->models[ j ];
      if( strlen( modelFile ) > 0 )
        cg_buildables[ i ].models[ j ] = trap_R_RegisterModel( modelFile );
    }

    //sounds
    for( j = BANIM_NONE + 1; j < MAX_BUILDABLE_ANIMATIONS; j++ )
    {
      strcpy( soundfile, cg_buildableSoundNames[ j - 1 ] );
      Com_sprintf( filename, sizeof( filename ), "sound/buildables/%s/%s", buildableName, soundfile );

      if( cg_buildables[ i ].sounds[ j ].enabled )
      {
        if( trap_FS_FOpenFile( filename, &f, FS_READ ) > 0 )
        {
          //file exists so close it
          trap_FS_FCloseFile( f );

          cg_buildables[ i ].sounds[ j ].sound = trap_S_RegisterSound( filename, qfalse );
        }
        else
        {
          //file doesn't exist - use default
          if( BG_Buildable( i )->team == TEAM_ALIENS )
            cg_buildables[ i ].sounds[ j ].sound = defaultAlienSounds[ j ];
          else
            cg_buildables[ i ].sounds[ j ].sound = defaultHumanSounds[ j ];
        }
      }
    }

    cg.buildablesFraction = (float)i / (float)( BA_NUM_BUILDABLES - 1 );
    trap_UpdateScreen( );
  }

  cgs.media.teslaZapTS = CG_RegisterTrailSystem( "models/buildables/tesla/zap" );
}
예제 #6
0
void BG_SiegeParseTeamFile(const char *filename)
{
	fileHandle_t f;
	int len;
	char teamInfo[2048];
	char parseBuf[1024];
	char lookString[256];
	int i = 1;
	qboolean success = qtrue;

	len = trap_FS_FOpenFile(filename, &f, FS_READ);

	if (!f || len >= 2048)
	{
		return;
	}

	trap_FS_Read(teamInfo, len, f);

	trap_FS_FCloseFile(f);

	teamInfo[len] = 0;

	if (BG_SiegeGetPairedValue(teamInfo, "name", parseBuf))
	{
		strcpy(bgSiegeTeams[bgNumSiegeTeams].name, parseBuf);
	}
	else
	{
		Com_Error(ERR_DROP, "Siege team with no name definition");
	}

//I don't entirely like doing things this way but it's the easiest way.
#ifdef CGAME
	if (BG_SiegeGetPairedValue(teamInfo, "FriendlyShader", parseBuf))
	{
		bgSiegeTeams[bgNumSiegeTeams].friendlyShader = trap_R_RegisterShaderNoMip(parseBuf);
	}
#else
	bgSiegeTeams[bgNumSiegeTeams].friendlyShader = 0;
#endif

	bgSiegeTeams[bgNumSiegeTeams].numClasses = 0;

	if (BG_SiegeGetValueGroup(teamInfo, "Classes", teamInfo))
	{
		while (success && i < MAX_SIEGE_CLASSES)
		{ //keep checking for group values named class# up to MAX_SIEGE_CLASSES until we can't find one.
			strcpy(lookString, va("class%i", i));

			success = BG_SiegeGetPairedValue(teamInfo, lookString, parseBuf);

			if (!success)
			{
				break;
			}

			bgSiegeTeams[bgNumSiegeTeams].classes[bgSiegeTeams[bgNumSiegeTeams].numClasses] = BG_SiegeFindClassByName(parseBuf);

			if (!bgSiegeTeams[bgNumSiegeTeams].classes[bgSiegeTeams[bgNumSiegeTeams].numClasses])
			{
				Com_Error(ERR_DROP, "Invalid class specified: '%s'", parseBuf);
			}

			bgSiegeTeams[bgNumSiegeTeams].numClasses++;

			i++;
		}
	}

	if (!bgSiegeTeams[bgNumSiegeTeams].numClasses)
	{
		Com_Error(ERR_DROP, "Team defined with no allowable classes\n");
	}

	//If we get here then it was a success, so increment the team number
	bgNumSiegeTeams++;
}
예제 #7
0
파일: g_saga.c 프로젝트: aufau/SaberMod
void InitSagaMode(void)
{
	vmCvar_t		mapname;
	char			levelname[512];
	char			goalreq[64];
	char			objectives[MAX_SAGA_INFO_SIZE];
	int				len = 0;
	fileHandle_t	f;

	if (g_gametype.integer != GT_SAGA)
	{
		goto failure;
	}

	imperial_goals_completed = 0;
	rebel_goals_completed = 0;

	saga_round_over = 0;

	trap_Cvar_Register( &mapname, "mapname", "", CVAR_SERVERINFO | CVAR_ROM );

	Com_sprintf(levelname, sizeof(levelname), "maps/%s.saga\0", mapname.string);

	if (!levelname[0])
	{
		goto failure;
	}

	len = trap_FS_FOpenFile(levelname, &f, FS_READ);

	if (!f || len >= MAX_SAGA_INFO_SIZE)
	{
		goto failure;
	}

	trap_FS_Read(saga_info, len, f);

	saga_valid = 1;

	if (GetValueGroup(saga_info, "Rebel", objectives))
	{
		if (GetPairedValue(objectives, "RequiredObjectives", goalreq))
		{
			rebel_goals_required = atoi(goalreq);
		}
		if (GetPairedValue(objectives, "attackers", goalreq))
		{
			rebel_attackers = atoi(goalreq);
		}
	}
	if (GetValueGroup(saga_info, "Imperial", objectives))
	{
		if (GetPairedValue(objectives, "RequiredObjectives", goalreq))
		{
			imperial_goals_required = atoi(goalreq);
		}
		if (GetPairedValue(objectives, "attackers", goalreq))
		{
			imperial_attackers = atoi(goalreq);
		}
	}

	return;

failure:
	saga_valid = 0;
}
예제 #8
0
/*
=================
UI_ForceConfigHandle
=================
*/
void UI_ForceConfigHandle( int oldindex, int newindex )
{
	fileHandle_t f;
	int len = 0;
	int i = 0;
	int c = 0;
	int iBuf = 0, forcePowerRank, currank;
	char fcfBuffer[8192];
	char singleBuf[64];
	char info[MAX_INFO_VALUE];
	int forceTeam = 0;

	if (oldindex == 0)
	{ //switching out from custom config, so first shove the current values into the custom storage
		i = 0;

		while (i < NUM_FORCE_POWERS)
		{
			gCustPowersRank[i] = uiForcePowersRank[i];
			i++;
		}
		gCustRank = uiForceRank;
		gCustSide = uiForceSide;
	}

	if (newindex == 0)
	{ //switching back to custom, shove the values back in from the custom storage
		i = 0;
		uiForceUsed = 0;
		gTouchedForce = qtrue;

		while (i < NUM_FORCE_POWERS)
		{
			uiForcePowersRank[i] = gCustPowersRank[i];
			uiForceUsed += uiForcePowersRank[i];
			i++;
		}
		uiForceRank = gCustRank;
		uiForceSide = gCustSide;

		UpdateForceUsed();
		return;
	}

	//If we made it here, we want to load in a new config
	if (uiForceSide == FORCE_LIGHTSIDE)
	{ //we should only be displaying lightside configs, so.. look in the light folder
		newindex += uiInfo.forceConfigLightIndexBegin;
		if (newindex >= uiInfo.forceConfigCount)
		{
			return;
		}
		len = trap_FS_FOpenFile(va("forcecfg/light/%s.fcf", uiInfo.forceConfigNames[newindex]), &f, FS_READ);
	}
	else
	{ //else dark
		newindex += uiInfo.forceConfigDarkIndexBegin;
		if (newindex >= uiInfo.forceConfigCount || newindex > uiInfo.forceConfigLightIndexBegin)
		{ //dark gets read in before light
			return;
		}
		len = trap_FS_FOpenFile(va("forcecfg/dark/%s.fcf", uiInfo.forceConfigNames[newindex]), &f, FS_READ);
	}

	if (len <= 0)
	{ //This should not have happened. But, before we quit out, attempt searching the other light/dark folder for the file.
		if (uiForceSide == FORCE_LIGHTSIDE)
		{
			len = trap_FS_FOpenFile(va("forcecfg/dark/%s.fcf", uiInfo.forceConfigNames[newindex]), &f, FS_READ);
		}
		else
		{
			len = trap_FS_FOpenFile(va("forcecfg/light/%s.fcf", uiInfo.forceConfigNames[newindex]), &f, FS_READ);
		}

		if (len <= 0)
		{ //still failure? Oh well.
			return;
		}
	}

	if (len >= 8192)
	{
		return;
	}

	trap_FS_Read(fcfBuffer, len, f);
	fcfBuffer[len] = 0;
	trap_FS_FCloseFile(f);

	i = 0;

	info[0] = '\0';
	trap_GetConfigString(CS_SERVERINFO, info, sizeof(info));

	if (atoi( Info_ValueForKey( info, "g_forceBasedTeams" ) ))
	{
		switch((int)(trap_Cvar_VariableValue("ui_myteam")))
		{
		case TEAM_RED:
			forceTeam = FORCE_DARKSIDE;
			break;
		case TEAM_BLUE:
			forceTeam = FORCE_LIGHTSIDE;
			break;
		default:
			break;
		}
	}

	BG_LegalizedForcePowers(fcfBuffer, uiMaxRank, ui_freeSaber.integer, forceTeam, atoi( Info_ValueForKey( info, "g_gametype" )), 0);
	//legalize the config based on the max rank

	//now that we're done with the handle, it's time to parse our force data out of the string
	//we store strings in rank-side-xxxxxxxxx format (where the x's are individual force power levels)
	while (fcfBuffer[i] && fcfBuffer[i] != '-')
	{
		singleBuf[c] = fcfBuffer[i];
		c++;
		i++;
	}
	singleBuf[c] = 0;
	c = 0;
	i++;

	iBuf = atoi(singleBuf);

	if (iBuf > uiMaxRank || iBuf < 0)
	{ //this force config uses a rank level higher than our currently restricted level.. so we can't use it
	  //FIXME: Print a message indicating this to the user
		return;
	}

	uiForceRank = iBuf;

	while (fcfBuffer[i] && fcfBuffer[i] != '-')
	{
		singleBuf[c] = fcfBuffer[i];
		c++;
		i++;
	}
	singleBuf[c] = 0;
	c = 0;
	i++;

	uiForceSide = atoi(singleBuf);

	if (uiForceSide != FORCE_LIGHTSIDE &&
		uiForceSide != FORCE_DARKSIDE)
	{
		uiForceSide = FORCE_LIGHTSIDE;
		return;
	}

	//clear out the existing powers
	while (c < NUM_FORCE_POWERS)
	{
		/*
		if (c==FP_LEVITATION)
		{
			uiForcePowersRank[c]=1;
		}
		else if (c==FP_SABER_OFFENSE && ui_freeSaber.integer)
		{
			uiForcePowersRank[c]=1;
		}
		else if (c==FP_SABER_DEFENSE && ui_freeSaber.integer)
		{
			uiForcePowersRank[c]=1;
		}
		else
		{
			uiForcePowersRank[c] = 0;
		}
		*/
		//rww - don't need to do these checks. Just trust whatever the saber config says.
		uiForcePowersRank[c] = 0;
		c++;
	}
	uiForceUsed = 0;
	uiForceAvailable = forceMasteryPoints[uiForceRank];
	gTouchedForce = qtrue;

	for (c=0;fcfBuffer[i]&&c<NUM_FORCE_POWERS;c++,i++)
	{
		singleBuf[0] = fcfBuffer[i];
		singleBuf[1] = 0;
		iBuf = atoi(singleBuf);	// So, that means that Force Power "c" wants to be set to rank "iBuf".
		
		if (iBuf < 0)
		{
			iBuf = 0;
		}

		forcePowerRank = iBuf;

		if (forcePowerRank > FORCE_LEVEL_3 || forcePowerRank < 0)
		{ //err..  not correct
			continue;  // skip this power
		}

		if (uiForcePowerDarkLight[c] && uiForcePowerDarkLight[c] != uiForceSide)
		{ //Apparently the user has crafted a force config that has powers that don't fit with the config's side.
			continue;  // skip this power
		}

		// Accrue cost for each assigned rank for this power.
		for (currank=FORCE_LEVEL_1;currank<=forcePowerRank;currank++)
		{	
			if (bgForcePowerCost[c][currank] > uiForceAvailable)
			{	// Break out, we can't afford any more power.
				break;
			}
			// Pay for this rank of this power.
			uiForceUsed += bgForcePowerCost[c][currank];
			uiForceAvailable -= bgForcePowerCost[c][currank];

			uiForcePowersRank[c]++;
		}
	}

	if (uiForcePowersRank[FP_LEVITATION] < 1)
	{
		uiForcePowersRank[FP_LEVITATION]=1;
	}
	if (uiForcePowersRank[FP_SABER_OFFENSE] < 1 && ui_freeSaber.integer)
	{
		uiForcePowersRank[FP_SABER_OFFENSE]=1;
	}
	if (uiForcePowersRank[FP_SABER_DEFENSE] < 1 && ui_freeSaber.integer)
	{
		uiForcePowersRank[FP_SABER_DEFENSE]=1;
	}

	UpdateForceUsed();
}
예제 #9
0
void UI_SaveForceTemplate()
{
	char *selectedName = UI_Cvar_VariableString("ui_SaveFCF");
	char fcfString[512];
	char forceStringValue[4];
	fileHandle_t f;
	int strPlace = 0;
	int forcePlace = 0;
	int i = 0;
	qboolean foundFeederItem = qfalse;

	if (!selectedName || !selectedName[0])
	{
		Com_Printf("You did not provide a name for the template.\n");
		return;
	}

	if (uiForceSide == FORCE_LIGHTSIDE)
	{ //write it into the light side folder
		trap_FS_FOpenFile(va("forcecfg/light/%s.fcf", selectedName), &f, FS_WRITE);
	}
	else
	{ //if it isn't light it must be dark
		trap_FS_FOpenFile(va("forcecfg/dark/%s.fcf", selectedName), &f, FS_WRITE);
	}

	if (!f)
	{
		Com_Printf("There was an error writing the template file (read-only?).\n");
		return;
	}

	Com_sprintf(fcfString, sizeof(fcfString), "%i-%i-", uiForceRank, uiForceSide);
	strPlace = strlen(fcfString);

	while (forcePlace < NUM_FORCE_POWERS)
	{
		Com_sprintf(forceStringValue, sizeof(forceStringValue), "%i", uiForcePowersRank[forcePlace]);
		//Just use the force digit even if multiple digits. Shouldn't be longer than 1.
		fcfString[strPlace] = forceStringValue[0];
		strPlace++;
		forcePlace++;
	}
	fcfString[strPlace] = '\n';
	fcfString[strPlace+1] = 0;

	trap_FS_Write(fcfString, strlen(fcfString), f);
	trap_FS_FCloseFile(f);

	Com_Printf("Template saved as \"%s\".\n", selectedName);

	//Now, update the FCF list
	UI_LoadForceConfig_List();

	//Then, scroll through and select the template for the file we just saved
	while (i < uiInfo.forceConfigCount)
	{
		if (!Q_stricmp(uiInfo.forceConfigNames[i], selectedName))
		{
			if ((uiForceSide == FORCE_LIGHTSIDE && uiInfo.forceConfigSide[i]) ||
				(uiForceSide == FORCE_DARKSIDE && !uiInfo.forceConfigSide[i]))
			{
				Menu_SetFeederSelection(NULL, FEEDER_FORCECFG, UI_TranslateFCFIndex(i), NULL);
				foundFeederItem = qtrue;
			}
		}

		i++;
	}

	//Else, go back to 0
	if (!foundFeederItem)
	{
		Menu_SetFeederSelection(NULL, FEEDER_FORCECFG, 0, NULL);
	}
}
예제 #10
0
/*
===============
G_MapExists

Check if a map exists
===============
*/
qboolean G_MapExists( char *name )
{
  return trap_FS_FOpenFile( va( "maps/%s.bsp", name ), NULL, FS_READ );
}
예제 #11
0
/*
============
G_InitGame

============
*/
void G_InitGame( int levelTime, int randomSeed, int restart ) {
	int					i;

	G_Printf ("------- Game Initialization -------\n");
	G_Printf ("gamename: %s\n", GAMEVERSION);
	G_Printf ("gamedate: %s\n", __DATE__);

	srand( randomSeed );

	G_RegisterCvars();

	G_ProcessIPBans();

	G_InitMemory();

	// set some level globals
	memset( &level, 0, sizeof( level ) );
	level.time = levelTime;
	level.startTime = levelTime;

	level.snd_fry = G_SoundIndex("sound/player/fry.wav");	// FIXME standing in lava / slime

	if ( g_gametype.integer != GT_SINGLE_PLAYER && g_logfile.string[0] ) {
		if ( g_logfileSync.integer ) {
			trap_FS_FOpenFile( g_logfile.string, &level.logFile, FS_APPEND_SYNC );
		} else {
			trap_FS_FOpenFile( g_logfile.string, &level.logFile, FS_APPEND );
		}
		if ( !level.logFile ) {
			G_Printf( "WARNING: Couldn't open logfile: %s\n", g_logfile.string );
		} else {
			char	serverinfo[MAX_INFO_STRING];

			trap_GetServerinfo( serverinfo, sizeof( serverinfo ) );

			G_LogPrintf("------------------------------------------------------------\n" );
			G_LogPrintf("InitGame: %s\n", serverinfo );
		}
	} else {
		G_Printf( "Not logging to disk.\n" );
	}

	G_InitWorldSession();

	// initialize all entities for this game
	memset( g_entities, 0, MAX_GENTITIES * sizeof(g_entities[0]) );
	level.gentities = g_entities;

	// initialize all clients for this game
	level.maxclients = g_maxclients.integer;
	memset( g_clients, 0, MAX_CLIENTS * sizeof(g_clients[0]) );
	level.clients = g_clients;

	// set client fields on player ents
	for ( i=0 ; i<level.maxclients ; i++ ) {
		g_entities[i].client = level.clients + i;
	}

	// always leave room for the max number of clients,
	// even if they aren't all used, so numbers inside that
	// range are NEVER anything but clients
	level.num_entities = MAX_CLIENTS;

	for ( i=0 ; i<MAX_CLIENTS ; i++ ) {
		g_entities[i].classname = "clientslot";
	}

	// let the server system know where the entites are
	trap_LocateGameData( level.gentities, level.num_entities, sizeof( gentity_t ), 
		&level.clients[0].ps, sizeof( level.clients[0] ) );

	// reserve some spots for dead player bodies
	InitBodyQue();

	ClearRegisteredItems();

	// parse the key/value pairs and spawn gentities
	G_SpawnEntitiesFromString();

	// general initialization
	G_FindTeams();

	// make sure we have flags for CTF, etc
	if( g_gametype.integer >= GT_TEAM ) {
		G_CheckTeamItems();
	}

	SaveRegisteredItems();

	G_Printf ("-----------------------------------\n");

	if( g_gametype.integer == GT_SINGLE_PLAYER || trap_Cvar_VariableIntegerValue( "com_buildScript" ) ) {
		G_ModelIndex( SP_PODIUM_MODEL );
	}

	if ( trap_Cvar_VariableIntegerValue( "bot_enable" ) ) {
		BotAISetup( restart );
		BotAILoadMap( restart );
		G_InitBots( restart );
	}

	G_RemapTeamShaders();

}
예제 #12
0
/*
===============
G_ParseMapRotationFile

Load the map rotations from a map rotation file
===============
*/
static qboolean G_ParseMapRotationFile( const char *fileName )
{
  char          *text_p;
  int           i, j, k;
  int           len;
  char          *token;
  char          text[ 20000 ];
  char          mrName[ MAX_QPATH ];
  qboolean      mrNameSet = qfalse;
  fileHandle_t  f;

  // load the file
  len = trap_FS_FOpenFile( fileName, &f, FS_READ );
  if( len < 0 )
    return qfalse;

  if( len == 0 || len >= sizeof( text ) - 1 )
  {
    trap_FS_FCloseFile( f );
    G_Printf( S_COLOR_RED "ERROR: map rotation file %s is %s\n", fileName,
      len == 0 ? "empty" : "too long" );
    return qfalse;
  }

  trap_FS_Read( text, len, f );
  text[ len ] = 0;
  trap_FS_FCloseFile( f );

  // parse the text
  text_p = text;

  // read optional parameters
  while( 1 )
  {
    token = COM_Parse( &text_p );

    if( !token )
      break;

    if( !Q_stricmp( token, "" ) )
      break;

    if( !Q_stricmp( token, "{" ) )
    {
      if( mrNameSet )
      {
        //check for name space clashes
        for( i = 0; i < mapRotations.numRotations; i++ )
        {
          if( !Q_stricmp( mapRotations.rotations[ i ].name, mrName ) )
          {
            G_Printf( S_COLOR_RED "ERROR: a map rotation is already named %s\n", mrName );
            return qfalse;
          }
        }

        Q_strncpyz( mapRotations.rotations[ mapRotations.numRotations ].name, mrName, MAX_QPATH );

        if( !G_ParseMapRotation( &mapRotations.rotations[ mapRotations.numRotations ], &text_p ) )
        {
          G_Printf( S_COLOR_RED "ERROR: %s: failed to parse map rotation %s\n", fileName, mrName );
          return qfalse;
        }

        //start parsing map rotations again
        mrNameSet = qfalse;

        if( mapRotations.numRotations == MAX_MAP_ROTATIONS )
        {
          G_Printf( S_COLOR_RED "ERROR: maximum number of map rotations (%d) reached\n",
                    MAX_MAP_ROTATIONS );
          return qfalse;
        }
        else
          mapRotations.numRotations++;

        continue;
      }
      else
      {
        G_Printf( S_COLOR_RED "ERROR: unamed map rotation\n" );
        return qfalse;
      }
    }

    if( !mrNameSet )
    {
      Q_strncpyz( mrName, token, sizeof( mrName ) );
      mrNameSet = qtrue;
    }
    else
    {
      G_Printf( S_COLOR_RED "ERROR: map rotation already named\n" );
      return qfalse;
    }
  }

  for( i = 0; i < mapRotations.numRotations; i++ )
  {
    for( j = 0; j < mapRotations.rotations[ i ].numMaps; j++ )
    {
      if( Q_stricmp( mapRotations.rotations[ i ].maps[ j ].name, "*VOTE*") != 0 &&
          !G_MapExists( mapRotations.rotations[ i ].maps[ j ].name ) )
      {
        G_Printf( S_COLOR_RED "ERROR: map \"%s\" doesn't exist\n",
          mapRotations.rotations[ i ].maps[ j ].name );
        return qfalse;
      }

      for( k = 0; k < mapRotations.rotations[ i ].maps[ j ].numConditions; k++ )
      {
        if( !G_MapExists( mapRotations.rotations[ i ].maps[ j ].conditions[ k ].dest ) &&
            !G_RotationExists( mapRotations.rotations[ i ].maps[ j ].conditions[ k ].dest ) )
        {
          G_Printf( S_COLOR_RED "ERROR: conditional destination \"%s\" doesn't exist\n",
            mapRotations.rotations[ i ].maps[ j ].conditions[ k ].dest );
          return qfalse;
        }

      }

    }
  }

  return qtrue;
}
예제 #13
0
/*
==================
getCustomVote
 *Returns a custom vote. This will go beyond MAX_CUSTOM_VOTES.
==================
 */
t_customvote getCustomVote(char* votecommand) {
	t_customvote result;
	fileHandle_t	file;
	char            buffer[4*1024];
	char	*token,*pointer;
	char	key[MAX_TOKEN_CHARS];

	trap_FS_FOpenFile(g_votecustom.string,&file,FS_READ);

	if(!file) {
		memset(&result,0,sizeof(result));
		return result;
	}

	memset(&buffer,0,sizeof(buffer));

	trap_FS_Read(&buffer,sizeof(buffer),file);

	trap_FS_FCloseFile(file);

	pointer = buffer;

	while ( qtrue ) {
	token = COM_Parse( &pointer );
		if ( !token[0] ) {
			break;
	}

		if ( strcmp( token, "{" ) ) {
		Com_Printf( "Missing { in votecustom.cfg\n" );
		break;
	}

		memset(&result,0,sizeof(result));

		while ( 1 ) {
			token = COM_ParseExt( &pointer, qtrue );
			if ( !token[0] ) {
					Com_Printf( "Unexpected end of customvote.cfg\n" );
					break;
			}
			if ( !strcmp( token, "}" ) ) {
					break;
			}
			Q_strncpyz( key, token, sizeof( key ) );

			token = COM_ParseExt( &pointer, qfalse );
			if ( !token[0] ) {
				Com_Printf("Invalid/missing argument to %s in customvote.cfg\n",key);
			}
			if(!Q_stricmp(key,"votecommand")) {
				Q_strncpyz(result.votename,token,sizeof(result.votename));
			} else if(!Q_stricmp(key,"displayname")) {
				Q_strncpyz(result.displayname,token,sizeof(result.displayname));
			} else if(!Q_stricmp(key,"command")) {
				Q_strncpyz(result.command,token,sizeof(result.command));
			} else {
				Com_Printf("Unknown key in customvote.cfg: %s\n",key);
			}

	}

		if(!Q_stricmp(result.votename,votecommand)) {
			return result;
		}
	}

	//Nothing was found
	memset(&result,0,sizeof(result));
	return result;
}
예제 #14
0
/*
===============
UI_DrawPlayer
===============
*/
void UI_DrawPlayer( float x, float y, float w, float h, uiPlayerInfo_t *pi, int time ) {
	refdef_t		refdef;
	refEntity_t		legs = {0};
	refEntity_t		torso = {0};
	refEntity_t		head = {0};
#ifdef TA_WEAPSYS
	refEntity_t		gun[MAX_HANDS] = {{0}};
#else
	refEntity_t		gun = {0};
#endif
	refEntity_t		barrel = {0};
	refEntity_t		flash = {0};
	vec3_t			origin;
	int				renderfx;
	vec3_t			mins = {-16, -16, -24};
	vec3_t			maxs = {16, 16, 32};
	float			len;
	float			xx;
	float			xscale;
	float			yscale;
#ifdef TA_WEAPSYS
	int				i;
	vec3_t			angles;
#ifdef TURTLEARENA // PLAYERS
	char *newTagNames[3] = { "tag_hand_primary", "tag_hand_secondary", NULL };
#endif
	char *originalTagNames[3] = { "tag_weapon", "tag_flag", NULL };
#endif

	if ( !pi->legsModel || !pi->torsoModel || !pi->headModel
#ifdef TA_PLAYERSYS
	|| !pi->playercfg.animations[0].numFrames ) {
#else
	|| !pi->animations[0].numFrames ) {
#endif
		return;
	}

	dp_realtime = time;

	if ( pi->pendingWeapon != WP_NUM_WEAPONS && dp_realtime > pi->weaponTimer ) {
		pi->weapon = pi->pendingWeapon;
		pi->lastWeapon = pi->pendingWeapon;
		pi->pendingWeapon = WP_NUM_WEAPONS;
		pi->weaponTimer = 0;
#ifndef TA_WEAPSYS_EX
		if( pi->currentWeapon != pi->weapon ) {
			trap_S_StartLocalSound( weaponChangeSound, CHAN_LOCAL );
		}
#endif
	}

	CG_AdjustFrom640( &x, &y, &w, &h );

	y -= jumpHeight;

	memset( &refdef, 0, sizeof( refdef ) );
	memset( &legs, 0, sizeof(legs) );
	memset( &torso, 0, sizeof(torso) );
	memset( &head, 0, sizeof(head) );

	refdef.rdflags = RDF_NOWORLDMODEL;

	AxisClear( refdef.viewaxis );

	refdef.x = x;
	refdef.y = y;
	refdef.width = w;
	refdef.height = h;

	if ( ui_stretch.integer ) {
		xscale = cgs.screenXScaleStretch;
		yscale = cgs.screenYScaleStretch;
	} else {
		xscale = cgs.screenXScale;
		yscale = cgs.screenYScale;
	}

	refdef.fov_x = (int)((float)refdef.width / xscale / 640.0f * 90.0f);
	xx = refdef.width / xscale / tan( refdef.fov_x / 360 * M_PI );
	refdef.fov_y = atan2( refdef.height / yscale, xx );
	refdef.fov_y *= ( 360 / M_PI );

	// calculate distance so the player nearly fills the box
	len = 0.7 * ( maxs[2] - mins[2] );		
	origin[0] = len / tan( DEG2RAD(refdef.fov_x) * 0.5 );
	origin[1] = 0.5 * ( mins[1] + maxs[1] );
	origin[2] = -0.5 * ( mins[2] + maxs[2] );

	refdef.time = dp_realtime;

	trap_R_ClearScene();

	// get the rotation information
	UI_PlayerAngles( pi, legs.axis, torso.axis, head.axis );
	
	// get the animation state (after rotation, to allow feet shuffle)
	UI_PlayerAnimation( pi, &legs.oldframe, &legs.frame, &legs.backlerp,
		 &torso.oldframe, &torso.frame, &torso.backlerp );

	renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW;

	//
	// add the legs
	//
	legs.hModel = pi->legsModel;
	legs.customSkin = CG_AddSkinToFrame( &pi->modelSkin );

	VectorCopy( origin, legs.origin );

	VectorCopy( origin, legs.lightingOrigin );
	legs.renderfx = renderfx;
	VectorCopy (legs.origin, legs.oldorigin);

	Byte4Copy( pi->c1RGBA, legs.shaderRGBA );

	CG_AddRefEntityWithMinLight( &legs );

	if (!legs.hModel) {
		return;
	}

	//
	// add the torso
	//
	torso.hModel = pi->torsoModel;
	if (!torso.hModel) {
		return;
	}

	torso.customSkin = legs.customSkin;

	VectorCopy( origin, torso.lightingOrigin );

	UI_PositionRotatedEntityOnTag( &torso, &legs, pi->legsModel, NULL, "tag_torso");

	torso.renderfx = renderfx;

	Byte4Copy( pi->c1RGBA, torso.shaderRGBA );

	CG_AddRefEntityWithMinLight( &torso );

	//
	// add the head
	//
	head.hModel = pi->headModel;
	if (!head.hModel) {
		return;
	}
	head.customSkin = legs.customSkin;

	VectorCopy( origin, head.lightingOrigin );

	UI_PositionRotatedEntityOnTag( &head, &torso, pi->torsoModel, NULL, "tag_head");

	head.renderfx = renderfx;

	Byte4Copy( pi->c1RGBA, head.shaderRGBA );

	CG_AddRefEntityWithMinLight( &head );

	//
	// add the gun
	//
	if ( pi->currentWeapon != WP_NONE ) {
#ifdef TA_WEAPSYS
		// get hands from cent
		for (i = 0; i < MAX_HANDS; i++)
		{
			memset( &gun[i], 0, sizeof(gun[i]) );
			gun[i].hModel = pi->weaponModel[i];
			VectorCopy( origin, gun[i].lightingOrigin );
			gun[i].renderfx = renderfx;
			Byte4Copy( pi->c1RGBA, gun[i].shaderRGBA );

			if (!originalTagNames[i]
#ifdef TURTLEARENA // PLAYERS
				|| !newTagNames[i]
#endif
				)
			{
				break;
			}

			if (!gun[i].hModel) {
				continue;
			}

			if (
#ifdef TURTLEARENA // PLAYERS
				!UI_PositionEntityOnTag( &gun[i], &torso, pi->torsoModel, NULL, newTagNames[i]) &&
#endif
				!UI_PositionEntityOnTag( &gun[i], &torso, pi->torsoModel, NULL, originalTagNames[i]))
			{
				// Failed to find tag
				continue;
			}

			CG_AddRefEntityWithMinLight( &gun[i] );
		}
#else
		memset( &gun, 0, sizeof(gun) );
		gun.hModel = pi->weaponModel;
		Byte4Copy( pi->c1RGBA, gun.shaderRGBA );
		VectorCopy( origin, gun.lightingOrigin );
		UI_PositionEntityOnTag( &gun, &torso, pi->torsoModel, NULL, "tag_weapon");
		gun.renderfx = renderfx;
		CG_AddRefEntityWithMinLight( &gun );
#endif
	}

	//
	// add the spinning barrel
	//
#ifdef TA_WEAPSYS
	for (i = 0; i < MAX_HANDS; i++)
#else
	if ( pi->barrelModel )
#endif
	{
#ifdef TA_WEAPSYS
		if (!pi->barrelModel[i])
			continue;
#else
		vec3_t	angles;
#endif

		memset( &barrel, 0, sizeof(barrel) );
		VectorCopy( origin, barrel.lightingOrigin );
		barrel.renderfx = renderfx;

#ifdef TA_WEAPSYS
		barrel.hModel = pi->barrelModel[i];
		VectorClear(angles);
		if (bg_weapongroupinfo[pi->realWeapon].weapon[i]->barrelSpin != BS_NONE)
		{
			if (i & 1)
				angles[bg_weapongroupinfo[pi->realWeapon].weapon[i]->barrelSpin]
						= 360-UI_MachinegunSpinAngle( pi );
			else
				angles[bg_weapongroupinfo[pi->realWeapon].weapon[i]->barrelSpin]
						= UI_MachinegunSpinAngle( pi );
		}
#else
		barrel.hModel = pi->barrelModel;
		angles[YAW] = 0;
		angles[PITCH] = 0;
		angles[ROLL] = UI_MachinegunSpinAngle( pi );
#endif
		AnglesToAxis( angles, barrel.axis );

#ifdef TA_WEAPSYS
		UI_PositionRotatedEntityOnTag( &barrel, &gun[i], pi->weaponModel[i], NULL, "tag_barrel");
#else
		UI_PositionRotatedEntityOnTag( &barrel, &gun, pi->weaponModel, NULL, "tag_barrel");
#endif

		CG_AddRefEntityWithMinLight( &barrel );
	}

	//
	// add muzzle flash
	//
	if ( dp_realtime <= pi->muzzleFlashTime ) {
#ifdef TA_WEAPSYS
		vec3_t *flashDlightColor;

		for (i = 0; i < MAX_HANDS; i++)
		{
			memset( &flash, 0, sizeof(flash) );
			flash.hModel = pi->flashModel[i];
			flashDlightColor = &pi->flashDlightColor[i];
			Byte4Copy( pi->c1RGBA, flash.shaderRGBA );

			if (!flash.hModel)
				continue;

			VectorCopy( origin, flash.lightingOrigin );
			UI_PositionEntityOnTag( &flash, &gun[i], pi->weaponModel[i], NULL, "tag_flash");
			flash.renderfx = renderfx;
			trap_R_AddRefEntityToScene( &flash );

			// make a dlight for the flash
			if ( *flashDlightColor[0] || *flashDlightColor[1] || *flashDlightColor[2] ) {
				trap_R_AddJuniorLightToScene( flash.origin, 200 + (rand()&31), 1.0f, *flashDlightColor[0],
					*flashDlightColor[1], *flashDlightColor[2] );
			}
		}
#else
		if ( pi->flashModel ) {
			memset( &flash, 0, sizeof(flash) );
			flash.hModel = pi->flashModel;
			Byte4Copy( pi->c1RGBA, flash.shaderRGBA );
			VectorCopy( origin, flash.lightingOrigin );
			UI_PositionEntityOnTag( &flash, &gun, pi->weaponModel, NULL, "tag_flash");
			flash.renderfx = renderfx;
			CG_AddRefEntityWithMinLight( &flash );
		}

		// make a dlight for the flash
		if ( pi->flashDlightColor[0] || pi->flashDlightColor[1] || pi->flashDlightColor[2] ) {
			trap_R_AddJuniorLightToScene( flash.origin, 200 + (rand()&31), 1.0f, pi->flashDlightColor[0],
				pi->flashDlightColor[1], pi->flashDlightColor[2] );
		}
#endif
	}

	//
	// add the chat icon
	//
	if ( pi->chat ) {
#ifdef TA_DATA // shaders
		UI_PlayerFloatSprite( pi, torso.origin, trap_R_RegisterShaderNoMip( "sprites/talkBalloon" ) );
#else
		UI_PlayerFloatSprite( pi, torso.origin, trap_R_RegisterShaderNoMip( "sprites/balloon3" ) );
#endif
	}

	//
	// add an accent light
	//
	origin[0] -= 100;	// + = behind, - = in front
	origin[1] += 100;	// + = left, - = right
	origin[2] += 100;	// + = above, - = below
	trap_R_AddJuniorLightToScene( origin, 500, 1.0, 1.0, 1.0, 1.0 );

	origin[0] -= 100;
	origin[1] -= 100;
	origin[2] -= 100;
	trap_R_AddJuniorLightToScene( origin, 500, 1.0, 1.0, 0.0, 0.0 );

	trap_R_RenderScene( &refdef );
}

/*
==========================
UI_FileExists
==========================
*/
static qboolean	UI_FileExists(const char *filename) {
	int len;

	len = trap_FS_FOpenFile( filename, NULL, FS_READ );
	if (len>0) {
		return qtrue;
	}
	return qfalse;
}
예제 #15
0
파일: g_saga.c 프로젝트: Ichimoto/OpenJK
void InitSiegeMode(void)
{
	vmCvar_t		mapname;
	char			levelname[512];
	char			teamIcon[128];
	char			goalreq[64];
	char			teams[2048];
	static char objective[MAX_SIEGE_INFO_SIZE];
	char			objecStr[8192];
	int				len = 0;
	int				i = 0;
//	int				j = 0;
	int				objectiveNumTeam1 = 0;
	int				objectiveNumTeam2 = 0;
	fileHandle_t	f;

	objective[0] = '\0';

	if (level.gametype != GT_SIEGE)
	{
		goto failure;
	}

	//reset
	SiegeSetCompleteData(0);

	//get pers data in case it existed from last level
	if (g_siegeTeamSwitch.integer)
	{
		trap_SiegePersGet(&g_siegePersistant);
		if (g_siegePersistant.beatingTime)
		{
			trap_SetConfigstring(CS_SIEGE_TIMEOVERRIDE, va("%i", g_siegePersistant.lastTime));
		}
		else
		{
			trap_SetConfigstring(CS_SIEGE_TIMEOVERRIDE, "0");
		}
	}
	else
	{ //hmm, ok, nothing.
		trap_SetConfigstring(CS_SIEGE_TIMEOVERRIDE, "0");
	}

	imperial_goals_completed = 0;
	rebel_goals_completed = 0;

	trap_Cvar_Register( &mapname, "mapname", "", CVAR_SERVERINFO | CVAR_ROM );

	Com_sprintf(levelname, sizeof(levelname), "maps/%s.siege\0", mapname.string);

	if ( !levelname[0] )
	{
		goto failure;
	}

	len = trap_FS_FOpenFile(levelname, &f, FS_READ);

	if (!f || len >= MAX_SIEGE_INFO_SIZE)
	{
		goto failure;
	}

	trap_FS_Read(siege_info, len, f);

	trap_FS_FCloseFile(f);

	siege_valid = 1;

	//See if players should be specs or ingame preround
	if (BG_SiegeGetPairedValue(siege_info, "preround_state", teams))
	{
		if (teams[0])
		{
			g_preroundState = atoi(teams);
		}
	}

	if (BG_SiegeGetValueGroup(siege_info, "Teams", teams))
	{
		if (g_siegeTeam1.string[0] && Q_stricmp(g_siegeTeam1.string, "none"))
		{ //check for override
			strcpy(team1, g_siegeTeam1.string);
		}
		else
		{ //otherwise use level default
			BG_SiegeGetPairedValue(teams, "team1", team1);
		}

		if (g_siegeTeam2.string[0] && Q_stricmp(g_siegeTeam2.string, "none"))
		{ //check for override
			strcpy(team2, g_siegeTeam2.string);
		}
		else
		{ //otherwise use level default
			BG_SiegeGetPairedValue(teams, "team2", team2);
		}
	}
	else
	{
		G_Error("Siege teams not defined");
	}

	if (BG_SiegeGetValueGroup(siege_info, team2, gParseObjectives))
	{
		if (BG_SiegeGetPairedValue(gParseObjectives, "TeamIcon", teamIcon))
		{
			trap_Cvar_Set( "team2_icon", teamIcon);
		}

		if (BG_SiegeGetPairedValue(gParseObjectives, "RequiredObjectives", goalreq))
		{
			rebel_goals_required = atoi(goalreq);
		}
		if (BG_SiegeGetPairedValue(gParseObjectives, "Timed", goalreq))
		{
			rebel_time_limit = atoi(goalreq)*1000;
			if (g_siegeTeamSwitch.integer &&
				g_siegePersistant.beatingTime)
			{
				gRebelCountdown = level.time + g_siegePersistant.lastTime;
			}
			else
			{
				gRebelCountdown = level.time + rebel_time_limit;
			}
		}
		if (BG_SiegeGetPairedValue(gParseObjectives, "attackers", goalreq))
		{
			rebel_attackers = atoi(goalreq);
		}
	}

	if (BG_SiegeGetValueGroup(siege_info, team1, gParseObjectives))
	{

		if (BG_SiegeGetPairedValue(gParseObjectives, "TeamIcon", teamIcon))
		{
			trap_Cvar_Set( "team1_icon", teamIcon);
		}

		if (BG_SiegeGetPairedValue(gParseObjectives, "RequiredObjectives", goalreq))
		{
			imperial_goals_required = atoi(goalreq);
		}
		if (BG_SiegeGetPairedValue(gParseObjectives, "Timed", goalreq))
		{
			if (rebel_time_limit)
			{
				Com_Printf("Tried to set imperial time limit, but there's already a rebel time limit!\nOnly one team can have a time limit.\n");
			}
			else
			{
				imperial_time_limit = atoi(goalreq)*1000;
				if (g_siegeTeamSwitch.integer &&
					g_siegePersistant.beatingTime)
				{
					gImperialCountdown = level.time + g_siegePersistant.lastTime;
				}
				else
				{
					gImperialCountdown = level.time + imperial_time_limit;
				}
			}
		}
		if (BG_SiegeGetPairedValue(gParseObjectives, "attackers", goalreq))
		{
			imperial_attackers = atoi(goalreq);
		}
	}

	//Load the player class types
	BG_SiegeLoadClasses(NULL);

	if (!bgNumSiegeClasses)
	{ //We didn't find any?!
		G_Error("Couldn't find any player classes for Siege");
	}

	/*
	//We could probably just see what teams are used on this level,
	//then see what classes are used by those teams, and then precache
	//all weapons for said classes. However, I'm just going to do them
	//all for now.
	while (i < bgNumSiegeClasses)
	{
		cl = &bgSiegeClasses[i];
		j = 0;

		while (j < WP_NUM_WEAPONS)
		{
			if (cl->weapons & (1 << j))
			{ //we use this weapon so register it.
				RegisterItem(BG_FindItemForWeapon(j));
			}

			j++;
		}

		i++;
	}
	*/
	//Ok, I'm adding inventory item precaching now, so I'm finally going to optimize this
	//to only do weapons/items for the current teams used on the level.

	//Now load the teams since we have class data.
	BG_SiegeLoadTeams();

	if (!bgNumSiegeTeams)
	{ //React same as with classes.
		G_Error("Couldn't find any player teams for Siege");
	}

	//Get and set the team themes for each team. This will control which classes can be
	//used on each team.
	if (BG_SiegeGetValueGroup(siege_info, team1, gParseObjectives))
	{
		if (BG_SiegeGetPairedValue(gParseObjectives, "UseTeam", goalreq))
		{
			BG_SiegeSetTeamTheme(SIEGETEAM_TEAM1, goalreq);
		}

		//Now count up the objectives for this team.
		i = 1;
		strcpy(objecStr, va("Objective%i", i));
		while (BG_SiegeGetValueGroup(gParseObjectives, objecStr, objective))
		{
			objectiveNumTeam1++;
			i++;
			strcpy(objecStr, va("Objective%i", i));
		}
	}
	if (BG_SiegeGetValueGroup(siege_info, team2, gParseObjectives))
	{
		if (BG_SiegeGetPairedValue(gParseObjectives, "UseTeam", goalreq))
		{
			BG_SiegeSetTeamTheme(SIEGETEAM_TEAM2, goalreq);
		}

		//Now count up the objectives for this team.
		i = 1;
		strcpy(objecStr, va("Objective%i", i));
		while (BG_SiegeGetValueGroup(gParseObjectives, objecStr, objective))
		{
			objectiveNumTeam2++;
			i++;
			strcpy(objecStr, va("Objective%i", i));
		}
	}

	//Set the configstring to show status of all current objectives
	strcpy(gObjectiveCfgStr, "t1");
	while (objectiveNumTeam1 > 0)
	{ //mark them all as not completed since we just initialized
		Q_strcat(gObjectiveCfgStr, 1024, "-0");
		objectiveNumTeam1--;
	}
	//Finished doing team 1's objectives, now do team 2's
	Q_strcat(gObjectiveCfgStr, 1024, "|t2");
	while (objectiveNumTeam2 > 0)
	{
		Q_strcat(gObjectiveCfgStr, 1024, "-0");
		objectiveNumTeam2--;
	}

	//And finally set the actual config string
	trap_SetConfigstring(CS_SIEGE_OBJECTIVES, gObjectiveCfgStr);

	//precache saber data for classes that use sabers on both teams
	BG_PrecacheSabersForSiegeTeam(SIEGETEAM_TEAM1);
	BG_PrecacheSabersForSiegeTeam(SIEGETEAM_TEAM2);

	G_SiegeRegisterWeaponsAndHoldables(SIEGETEAM_TEAM1);
	G_SiegeRegisterWeaponsAndHoldables(SIEGETEAM_TEAM2);

	return;

failure:
	siege_valid = 0;
}
예제 #16
0
void *decoder_ogg_load( const char *filename, snd_info_t *info )
{
	OggVorbis_File vorbisfile;
	int filenum, bitstream, bytes_read, bytes_read_total;
	char *buffer;
	ov_callbacks callbacks = { ovcb_read, ovcb_seek, ovcb_close, ovcb_tell };

	trap_FS_FOpenFile( filename, &filenum, FS_READ|FS_NOSIZE );
	if( !filenum )
		return NULL;

	if( trap_FS_IsUrl( filename ) )
	{
		callbacks.seek_func = NULL;
		callbacks.tell_func = NULL;
	}

	qov_open_callbacks( (void *) (qintptr) filenum, &vorbisfile, NULL, 0, callbacks );

	if( callbacks.seek_func && !qov_seekable( &vorbisfile ) )
	{
		Com_Printf( "Error unsupported .ogg file (not seekable): %s\n", filename );
		qov_clear( &vorbisfile ); // Does FS_FCloseFile
		return NULL;
	}

	if( qov_streams( &vorbisfile ) != 1 )
	{
		Com_Printf( "Error unsupported .ogg file (multiple logical bitstreams): %s\n", filename );
		qov_clear( &vorbisfile ); // Does FS_FCloseFile
		return NULL;
	}

	if( !read_ogg_header( vorbisfile, info ) )
	{
		Com_Printf( "Error reading .ogg file header: %s\n", filename );
		qov_clear( &vorbisfile ); // Does FS_FCloseFile
		return NULL;
	}

	buffer = S_Malloc( info->size );

	bytes_read_total = 0;
	do
	{
#ifdef ENDIAN_BIG
		bytes_read = qov_read( &vorbisfile, buffer+bytes_read_total, info->size-bytes_read_total, 1, 2, 1, &bitstream );
#elif defined (ENDIAN_LITTLE)
		bytes_read = qov_read( &vorbisfile, buffer+bytes_read_total, info->size-bytes_read_total, 0, 2, 1, &bitstream );
#else
#error "runtime endianess detection support missing"
#endif
		bytes_read_total += bytes_read;
	}
	while( bytes_read > 0 && bytes_read_total < info->size );

	qov_clear( &vorbisfile ); // Does FS_FCloseFile
	if( !bytes_read_total )
	{
		Com_Printf( "Error reading .ogg file: %s\n", filename );
		S_Free( buffer );
		return NULL;
	}

	return buffer;
}
예제 #17
0
void UI_SaberLoadParms( void ) 
{
	int			len, totallen, saberExtFNLen, fileCnt, i;
	char		*holdChar, *marker;
	char		saberExtensionListBuf[2048];			//	The list of file names read in
	fileHandle_t f;
	char buffer[MAX_MENUFILE];

	//ui.Printf( "UI Parsing *.sab saber definitions\n" );
	
	ui_saber_parms_parsed = qtrue;
	UI_CacheSaberGlowGraphics();

	//set where to store the first one
	totallen = 0;
	marker = SaberParms;
	marker[0] = '\0';

	//now load in the extra .npc extensions
	fileCnt = trap_FS_GetFileList("ext_data/sabers", ".sab", saberExtensionListBuf, sizeof(saberExtensionListBuf) );

	holdChar = saberExtensionListBuf;
	for ( i = 0; i < fileCnt; i++, holdChar += saberExtFNLen + 1 ) 
	{
		saberExtFNLen = strlen( holdChar );

		len = trap_FS_FOpenFile( va( "ext_data/sabers/%s", holdChar), &f, FS_READ );

		if (!f)
		{
			continue;
		}

		if ( len == -1 ) 
		{
			Com_Printf( "UI_SaberLoadParms: error reading %s\n", holdChar );
		}
		else
		{
			if (len > sizeof(buffer) )
			{
				Com_Error( ERR_FATAL, "UI_SaberLoadParms: file %s too large to read (max=%d)", holdChar, sizeof(buffer) );
			}
			trap_FS_Read( buffer, len, f );
			trap_FS_FCloseFile( f );
			buffer[len] = 0;

			if ( totallen && *(marker-1) == '}' )
			{//don't let it end on a } because that should be a stand-alone token
				strcat( marker, " " );
				totallen++;
				marker++; 
			}
			len = COM_Compress( buffer );

			if ( totallen + len >= MAX_SABER_DATA_SIZE ) {
				Com_Error( ERR_FATAL, "UI_SaberLoadParms: ran out of space before reading %s\n(you must make the .sab files smaller)", holdChar );
			}
			strcat( marker, buffer );

			totallen += len;
			marker += len;
		}
	}
}
예제 #18
0
/*
===============
G_ParseMapRotationFile

Load the map rotations from a map rotation file
===============
*/
static bool G_ParseMapRotationFile( const char *fileName )
{
  char          *text_p;
  int           i;
  int           len;
  char          *token;
  char          text[ 20000 ];
  char          mrName[ MAX_QPATH ];
  bool      mrNameSet = false;
  fileHandle_t  f;

  // load the file
  len = trap_FS_FOpenFile( fileName, &f, FS_READ );
  if( len <= 0 )
    return false;

  if( len >= sizeof( text ) - 1 )
  {
    G_Printf( S_COLOR_RED "ERROR: map rotation file %s too long\n", fileName );
    return false;
  }

  trap_FS_Read( text, len, f );
  text[ len ] = 0;
  trap_FS_FCloseFile( f );

  // parse the text
  text_p = text;

  // read optional parameters
  while( 1 )
  {
    token = COM_Parse( &text_p );

    if( !token )
      break;

    if( !Q_stricmp( token, "" ) )
      break;

    if( !Q_stricmp( token, "{" ) )
    {
      if( mrNameSet )
      {
        //check for name space clashes
        for( i = 0; i < mapRotations.numRotations; i++ )
        {
          if( !Q_stricmp( mapRotations.rotations[ i ].name, mrName ) )
          {
            G_Printf( S_COLOR_RED "ERROR: a map rotation is already named %s\n", mrName );
            return false;
          }
        }

        Q_strncpyz( mapRotations.rotations[ mapRotations.numRotations ].name, mrName, MAX_QPATH );

        if( !G_ParseMapRotation( &mapRotations.rotations[ mapRotations.numRotations ], &text_p ) )
        {
          G_Printf( S_COLOR_RED "ERROR: %s: failed to parse map rotation %s\n", fileName, mrName );
          return false;
        }

        //start parsing particle systems again
        mrNameSet = false;

        if( mapRotations.numRotations == MAX_MAP_ROTATIONS )
        {
          G_Printf( S_COLOR_RED "ERROR: maximum number of map rotations (%d) reached\n",
                    MAX_MAP_ROTATIONS );
          return false;
        }
        else
          mapRotations.numRotations++;

        continue;
      }
      else
      {
        G_Printf( S_COLOR_RED "ERROR: unamed map rotation\n" );
        return false;
      }
    }

    if( !mrNameSet )
    {
      Q_strncpyz( mrName, token, sizeof( mrName ) );
      mrNameSet = true;
    }
    else
    {
      G_Printf( S_COLOR_RED "ERROR: map rotation already named\n" );
      return false;
    }
  }

  return true;
}
예제 #19
0
void BG_SiegeParseClassFile(const char *filename, siegeClassDesc_t *descBuffer)
{
	fileHandle_t f;
	int len;
	int i;
	char classInfo[4096];
	char parseBuf[4096];

	len = trap_FS_FOpenFile(filename, &f, FS_READ);

	if (!f || len >= 4096)
	{
		return;
	}

	trap_FS_Read(classInfo, len, f);

	trap_FS_FCloseFile(f);

	classInfo[len] = 0;

	//first get the description if we have a buffer for it
	if (descBuffer)
	{
		if (!BG_SiegeGetPairedValue(classInfo, "description", descBuffer->desc))
		{
			strcpy(descBuffer->desc, "DESCRIPTION UNAVAILABLE");
		}

		//Hit this assert?  Memory has already been trashed.  Increase
		//SIEGE_CLASS_DESC_LEN.
		assert(strlen(descBuffer->desc) < SIEGE_CLASS_DESC_LEN);
	}

	BG_SiegeGetValueGroup(classInfo, "ClassInfo", classInfo);

	//Parse name
	if (BG_SiegeGetPairedValue(classInfo, "name", parseBuf))
	{
		strcpy(bgSiegeClasses[bgNumSiegeClasses].name, parseBuf);
	}
	else
	{
		Com_Error(ERR_DROP, "Siege class without name entry");
	}

	//Parse forced model
	if (BG_SiegeGetPairedValue(classInfo, "model", parseBuf))
	{
		strcpy(bgSiegeClasses[bgNumSiegeClasses].forcedModel, parseBuf);
	}
	else
	{ //It's ok if there isn't one, it's optional.
		bgSiegeClasses[bgNumSiegeClasses].forcedModel[0] = 0;
	}

	//Parse forced skin
	if (BG_SiegeGetPairedValue(classInfo, "skin", parseBuf))
	{
		strcpy(bgSiegeClasses[bgNumSiegeClasses].forcedSkin, parseBuf);
	}
	else
	{ //It's ok if there isn't one, it's optional.
		bgSiegeClasses[bgNumSiegeClasses].forcedSkin[0] = 0;
	}

	//Parse first saber
	if (BG_SiegeGetPairedValue(classInfo, "saber1", parseBuf))
	{
		strcpy(bgSiegeClasses[bgNumSiegeClasses].saber1, parseBuf);
	}
	else
	{ //It's ok if there isn't one, it's optional.
		bgSiegeClasses[bgNumSiegeClasses].saber1[0] = 0;
	}

	//Parse second saber
	if (BG_SiegeGetPairedValue(classInfo, "saber2", parseBuf))
	{
		strcpy(bgSiegeClasses[bgNumSiegeClasses].saber2, parseBuf);
	}
	else
	{ //It's ok if there isn't one, it's optional.
		bgSiegeClasses[bgNumSiegeClasses].saber2[0] = 0;
	}

	//Parse forced saber stance
	if (BG_SiegeGetPairedValue(classInfo, "saberstyle", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].saberStance = BG_SiegeTranslateGenericTable(parseBuf, StanceTable, qtrue);
	}
	else
	{ //It's ok if there isn't one, it's optional.
		bgSiegeClasses[bgNumSiegeClasses].saberStance = 0;
	}

	//Parse forced saber color
	if (BG_SiegeGetPairedValue(classInfo, "sabercolor", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].forcedSaberColor = atoi(parseBuf);
		bgSiegeClasses[bgNumSiegeClasses].hasForcedSaberColor = qtrue;
	}
	else
	{ //It's ok if there isn't one, it's optional.
		bgSiegeClasses[bgNumSiegeClasses].hasForcedSaberColor = qfalse;
	}

	//Parse forced saber2 color
	if (BG_SiegeGetPairedValue(classInfo, "saber2color", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].forcedSaber2Color = atoi(parseBuf);
		bgSiegeClasses[bgNumSiegeClasses].hasForcedSaber2Color = qtrue;
	}
	else
	{ //It's ok if there isn't one, it's optional.
		bgSiegeClasses[bgNumSiegeClasses].hasForcedSaber2Color = qfalse;
	}

	//Parse weapons
	if (BG_SiegeGetPairedValue(classInfo, "weapons", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].weapons = BG_SiegeTranslateGenericTable(parseBuf, WPTable, qtrue);
	}
	else
	{
		Com_Error(ERR_DROP, "Siege class without weapons entry");
	}

	if (!(bgSiegeClasses[bgNumSiegeClasses].weapons & (1 << WP_SABER)))
	{ //make sure it has melee if there's no saber
		bgSiegeClasses[bgNumSiegeClasses].weapons |= (1 << WP_MELEE);

		//always give them this too if they are not a saber user
	}

	//Parse forcepowers
	if (BG_SiegeGetPairedValue(classInfo, "forcepowers", parseBuf))
	{
		BG_SiegeTranslateForcePowers(parseBuf, &bgSiegeClasses[bgNumSiegeClasses]);
	}
	else
	{ //fine, clear out the powers.
		i = 0;
		while (i < NUM_FORCE_POWERS)
		{
			bgSiegeClasses[bgNumSiegeClasses].forcePowerLevels[i] = 0;
			i++;
		}
	}

	//Parse classflags
	if (BG_SiegeGetPairedValue(classInfo, "classflags", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].classflags = BG_SiegeTranslateGenericTable(parseBuf, bgSiegeClassFlagNames, qtrue);
	}
	else
	{ //fine, we'll 0 it.
		bgSiegeClasses[bgNumSiegeClasses].classflags = 0;
	}

	//Parse maxhealth
	if (BG_SiegeGetPairedValue(classInfo, "maxhealth", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].maxhealth = atoi(parseBuf);
	}
	else
	{ //It's alright, just default to 100 then.
		bgSiegeClasses[bgNumSiegeClasses].maxhealth = 100;
	}

	//Parse starthealth
	if (BG_SiegeGetPairedValue(classInfo, "starthealth", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].starthealth = atoi(parseBuf);
	}
	else
	{ //It's alright, just default to 100 then.
		bgSiegeClasses[bgNumSiegeClasses].starthealth = bgSiegeClasses[bgNumSiegeClasses].maxhealth;
	}


	//Parse startarmor
	if (BG_SiegeGetPairedValue(classInfo, "maxarmor", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].maxarmor = atoi(parseBuf);
	}
	else
	{ //It's alright, just default to 0 then.
		bgSiegeClasses[bgNumSiegeClasses].maxarmor = 0;
	}

	//Parse startarmor
	if (BG_SiegeGetPairedValue(classInfo, "startarmor", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].startarmor = atoi(parseBuf);
		if (!bgSiegeClasses[bgNumSiegeClasses].maxarmor)
		{ //if they didn't specify a damn max armor then use this.
			bgSiegeClasses[bgNumSiegeClasses].maxarmor = bgSiegeClasses[bgNumSiegeClasses].startarmor;
		}
	}
	else
	{ //default to maxarmor.
		bgSiegeClasses[bgNumSiegeClasses].startarmor = bgSiegeClasses[bgNumSiegeClasses].maxarmor;
	}

	//Parse speed (this is a multiplier value)
	if (BG_SiegeGetPairedValue(classInfo, "speed", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].speed = atof(parseBuf);
	}
	else
	{ //It's alright, just default to 1 then.
		bgSiegeClasses[bgNumSiegeClasses].speed = 1.0f;
	}

	//Parse shader for ui to use
	if (BG_SiegeGetPairedValue(classInfo, "uishader", parseBuf))
	{
#ifdef QAGAME
		bgSiegeClasses[bgNumSiegeClasses].uiPortraitShader = 0;
		memset(bgSiegeClasses[bgNumSiegeClasses].uiPortrait,0,sizeof(bgSiegeClasses[bgNumSiegeClasses].uiPortrait));
#elif defined CGAME
		bgSiegeClasses[bgNumSiegeClasses].uiPortraitShader = 0;
		memset(bgSiegeClasses[bgNumSiegeClasses].uiPortrait,0,sizeof(bgSiegeClasses[bgNumSiegeClasses].uiPortrait));
#else //ui
		bgSiegeClasses[bgNumSiegeClasses].uiPortraitShader = trap_R_RegisterShaderNoMip(parseBuf);
		memcpy(bgSiegeClasses[bgNumSiegeClasses].uiPortrait,parseBuf,sizeof(bgSiegeClasses[bgNumSiegeClasses].uiPortrait));
#endif
	}
	else
	{ //I guess this is an essential.. we don't want to render bad shaders or anything.
		Com_Error(ERR_DROP, "Siege class without uishader entry");
	}

	//Parse shader for ui to use
	if (BG_SiegeGetPairedValue(classInfo, "class_shader", parseBuf))
	{
#ifdef QAGAME
		bgSiegeClasses[bgNumSiegeClasses].classShader = 0;
#else //cgame, ui
		bgSiegeClasses[bgNumSiegeClasses].classShader = trap_R_RegisterShaderNoMip(parseBuf);
		assert( bgSiegeClasses[bgNumSiegeClasses].classShader );
		if ( !bgSiegeClasses[bgNumSiegeClasses].classShader )
		{
			Com_Printf( "ERROR: could not find class_shader %s for class %s\n", parseBuf, bgSiegeClasses[bgNumSiegeClasses].name );
		}
		// A very hacky way to determine class . . . 
		else
#endif
		{
			// Find the base player class based on the icon name - very bad, I know.
			int titleLength,i,arrayTitleLength;
			char *holdBuf;

			titleLength = strlen(parseBuf);
			for (i=0;i<SPC_MAX;i++)
			{
				// Back up 
				arrayTitleLength = strlen(classTitles[i]);
				if (arrayTitleLength>titleLength)	// Too long
				{
					break;
				}

				holdBuf = parseBuf + ( titleLength - arrayTitleLength);
				if (!strcmp(holdBuf,classTitles[i]))
				{
					bgSiegeClasses[bgNumSiegeClasses].playerClass = i;
					break;
				}
			}

			// In case the icon name doesn't match up
			if (i>=SPC_MAX)
			{
				bgSiegeClasses[bgNumSiegeClasses].playerClass = SPC_INFANTRY;
			}
		}
	}
	else
	{ //No entry!  Bad bad bad
		Com_Printf( "ERROR: no class_shader defined for class %s\n", bgSiegeClasses[bgNumSiegeClasses].name );
	}

	//Parse holdable items to use
	if (BG_SiegeGetPairedValue(classInfo, "holdables", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].invenItems = BG_SiegeTranslateGenericTable(parseBuf, HoldableTable, qtrue);
	}
	else
	{ //Just don't start out with any then.
		bgSiegeClasses[bgNumSiegeClasses].invenItems = 0;
	}

	//Parse powerups to use
	if (BG_SiegeGetPairedValue(classInfo, "powerups", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].powerups = BG_SiegeTranslateGenericTable(parseBuf, PowerupTable, qtrue);
	}
	else
	{ //Just don't start out with any then.
		bgSiegeClasses[bgNumSiegeClasses].powerups = 0;
	}

	//A successful read.
	bgNumSiegeClasses++;
}
예제 #20
0
파일: snd_music.c 프로젝트: Picmip/qfusion
/*
* S_ReadPlaylistFile
*/
static bgTrack_t *S_ReadPlaylistFile( const char *filename, bool shuffle, bool loop ) {
	int filenum, length;
	char *tmpname = 0;
	size_t tmpname_size = 0;
	char *data, *line, *entry;
	playlistItem_t items[MAX_PLAYLIST_ITEMS];
	int i, numItems = 0;

	length = trap_FS_FOpenFile( filename, &filenum, FS_READ );
	if( length < 0 ) {
		return NULL;
	}

	// load the playlist into memory
	data = S_Malloc( length + 1 );
	trap_FS_Read( data, length, filenum );
	trap_FS_FCloseFile( filenum );

	srand( time( NULL ) );

	while( *data ) {
		size_t s;

		entry = data;

		// read the whole line
		for( line = data; *line != '\0' && *line != '\n'; line++ ) ;

		// continue reading from the next character, if possible
		data = ( *line == '\0' ? line : line + 1 );

		*line = '\0';

		// trim whitespaces, tabs, etc
		entry = Q_trim( entry );

		// special M3U entry or comment
		if( !*entry || *entry == '#' ) {
			continue;
		}

		if( trap_FS_IsUrl( entry ) ) {
			items[numItems].track = S_AllocTrack( entry );
		} else {
			// append the entry name to playlist path
			s = strlen( filename ) + 1 + strlen( entry ) + 1;
			if( s > tmpname_size ) {
				if( tmpname ) {
					S_Free( tmpname );
				}
				tmpname_size = s;
				tmpname = S_Malloc( tmpname_size );
			}

			Q_strncpyz( tmpname, filename, tmpname_size );
			COM_StripFilename( tmpname );
			Q_strncatz( tmpname, "/", tmpname_size );
			Q_strncatz( tmpname, entry, tmpname_size );
			COM_SanitizeFilePath( tmpname );

			items[numItems].track = S_AllocTrack( tmpname );
		}

		if( ++numItems == MAX_PLAYLIST_ITEMS ) {
			break;
		}
	}

	if( tmpname ) {
		S_Free( tmpname );
		tmpname = NULL;
	}

	if( !numItems ) {
		return NULL;
	}

	// set the playing order
	for( i = 0; i < numItems; i++ )
		items[i].order = ( shuffle ? ( rand() % numItems ) : i );

	// sort the playlist
	R_SortPlaylistItems( numItems, items );

	// link the playlist
	for( i = 1; i < numItems; i++ ) {
		items[i - 1].track->next = items[i].track;
		items[i].track->prev = items[i - 1].track;
		items[i].track->loop = loop;
	}
	items[numItems - 1].track->next = items[0].track;
	items[0].track->prev = items[numItems - 1].track;
	items[0].track->loop = loop;

	return items[0].track;
}
예제 #21
0
void CG_LoadLocations(void)
{
	fileHandle_t f;                     // handle of file on disk
	int          fLen = trap_FS_FOpenFile(va("maps/%s_loc_override.dat", cgs.rawmapname), &f, FS_READ);     // length of the file
	char         fBuffer[MAX_BUFFER];   // buffer to read the file into
	char         message[128] = "\0";    // location description
	char         temp[128]    = "\0";    // temporary buffer
	int          x            = 0;      // x-coord of the location
	int          y            = 0;      // y-coord of the location
	int          z            = 0;      // z-coord of the location
	int          p            = 0;      // current location in the file buffer
	int          t            = 0;      // current location in the temp buffer

	if (fLen < 0)
	{
		// open the location .dat file that matches the map's name
		fLen = trap_FS_FOpenFile(va("maps/%s_loc.dat", cgs.rawmapname), &f, FS_READ);

		if (fLen < 0)
		{
			CG_Printf("^dLoadLocations: ^3Warning: ^9No location data found for map ^2%s^9.\n", cgs.rawmapname);
			return;
		}
	}

	if (fLen > MAX_BUFFER)
	{
		trap_FS_FCloseFile(f);
		CG_Error("Location file is too big, make it smaller (max = %i bytes)\n", MAX_BUFFER);
	}

	trap_FS_Read(&fBuffer, fLen, f);                    // read the file into the buffer
	fBuffer[fLen] = '\0';                               // make sure it's null-terminated
	trap_FS_FCloseFile(f);                              // close the file, we're done with it

	CG_Printf("^dLoadLocations: ^9location data for map ^2%s ^9loaded\n", cgs.rawmapname);

	// start parsing!
	while (p < fLen)
	{
		// check for the beginning of a comment
		if (fBuffer[p++] == '/')
		{
			//check for single line comment
			if (fBuffer[p] == '/')
			{
				while (p < fLen && (fBuffer[p] != '\n' && fBuffer[p] != '\r'))
				{
					p++;
				}
			}
			// check for multiline comment
			else if (fBuffer[p] == '*')
			{
				while (p < fLen && (fBuffer[p] != '*' && fBuffer[p + 1] != '/'))
				{
					p++;
				}
			}
		}

		// parse the next line
		while (p < fLen && (fBuffer[p] != '\n' || fBuffer[p] != '\r'))
		{
			// grab the x-coord
			while (p < fLen && fBuffer[p] != ' ')
			{
				temp[t++] = fBuffer[p++];
			}
			temp[t] = '\0';
			x       = atoi(temp);
			t       = 0;
			memset(&temp, 0, sizeof(temp));

			if (p > fLen)
			{
				break;
			}

			p++;

			// grab the y-coord
			while (p < fLen && fBuffer[p] != ' ')
			{
				temp[t++] = fBuffer[p++];
			}
			temp[t] = '\0';
			y       = atoi(temp);
			t       = 0;
			memset(&temp, 0, sizeof(temp));

			if (p > fLen)
			{
				break;
			}

			p++;

			// grab the z-coord
			while (p < fLen && fBuffer[p] != ' ')
			{
				temp[t++] = fBuffer[p++];
			}
			temp[t] = '\0';
			z       = atoi(temp);
			t       = 0;

			memset(&temp, 0, sizeof(temp));
			if (p > fLen)
			{
				break;
			}

			p++;

			// grab the description
			while (p < fLen && fBuffer[p] != '\n' && fBuffer[p] != '\r')
			{
				// ignore quotation marks
				if (fBuffer[p] != '\"')
				{
					temp[t++] = fBuffer[p++];
				}
				else
				{
					p++;
				}
			}
			temp[t] = '\0';
			t       = 0;

			// if @, then keep the previous location name, otherwise, update message
			if (Q_stricmp(temp, "@"))
			{
				strcpy(message, temp);
			}

			if (p > fLen)
			{
				break;
			}

			if ((x != 0 || y != 0 || z != 0) && strlen(message) > 0)
			{
				location_t *loc = &cgs.location[cgs.numLocations];

				loc->index = cgs.numLocations;
				strcpy(loc->message, message);
				loc->origin[0] = x;
				loc->origin[1] = y;
				loc->origin[2] = z;
				cgs.numLocations++;

				if (cgs.numLocations == MAX_C_LOCATIONS)
				{
					CG_Printf("^9Too many locations specifed.\n");
					break;
				}
			}
		}
	}
	// ok we are succesfull
	CG_Printf("^2%i ^9locations loaded.\n", cgs.numLocations);
	cgs.locationsLoaded = qtrue;
}
예제 #22
0
파일: snd_music.c 프로젝트: Picmip/qfusion
/*
* S_BackgroundTrack_GetWavinfo
*/
static int S_BackgroundTrack_GetWavinfo( const char *name, wavinfo_t *info ) {
	short t;
	int samples, file;
	int iff_data, last_chunk;
	char chunkName[4];

	last_chunk = 0;
	memset( info, 0, sizeof( wavinfo_t ) );

	trap_FS_FOpenFile( name, &file, FS_READ );
	if( !file ) {
		return 0;
	}

	// find "RIFF" chunk
	if( !S_BackgroundTrack_FindNextChunk( "RIFF", &last_chunk, file ) ) {
		//Com_Printf( "Missing RIFF chunk\n" );
		return 0;
	}

	trap_FS_Read( chunkName, 4, file );
	if( !strncmp( chunkName, "WAVE", 4 ) ) {
		Com_Printf( "Missing WAVE chunk\n" );
		return 0;
	}

	// get "fmt " chunk
	iff_data = trap_FS_Tell( file ) + 4;
	last_chunk = iff_data;
	if( !S_BackgroundTrack_FindNextChunk( "fmt ", &last_chunk, file ) ) {
		Com_Printf( "Missing fmt chunk\n" );
		return 0;
	}

	trap_FS_Read( chunkName, 4, file );

	trap_FS_Read( &t, sizeof( t ), file );
	if( LittleShort( t ) != 1 ) {
		Com_Printf( "Microsoft PCM format only\n" );
		return 0;
	}

	trap_FS_Read( &t, sizeof( t ), file );
	info->channels = LittleShort( t );

	trap_FS_Read( &info->rate, sizeof( info->rate ), file );
	info->rate = LittleLong( info->rate );

	trap_FS_Seek( file, 4 + 2, FS_SEEK_CUR );

	trap_FS_Read( &t, sizeof( t ), file );
	info->width = LittleShort( t ) / 8;

	info->loopstart = 0;

	// find data chunk
	last_chunk = iff_data;
	if( !S_BackgroundTrack_FindNextChunk( "data", &last_chunk, file ) ) {
		Com_Printf( "Missing data chunk\n" );
		return 0;
	}

	trap_FS_Read( &samples, sizeof( samples ), file );
	info->samples = LittleLong( samples ) / info->width / info->channels;

	info->dataofs = trap_FS_Tell( file );

	return file;
}
예제 #23
0
/*
======================
CG_ParseBuildableAnimationFile

Read a configuration file containing animation counts and rates
models/buildables/hivemind/animation.cfg, etc
======================
*/
static qboolean CG_ParseBuildableAnimationFile( const char *filename, buildable_t buildable )
{
  char          *text_p;
  int           len;
  int           i;
  char          *token;
  float         fps;
  char          text[ 20000 ];
  fileHandle_t  f;
  animation_t   *animations;

  animations = cg_buildables[ buildable ].animations;

  // load the file
  len = trap_FS_FOpenFile( filename, &f, FS_READ );
  if( len < 0 )
    return qfalse;

  if( len == 0 || len >= sizeof( text ) - 1 )
  {
    trap_FS_FCloseFile( f );
    CG_Printf( "File %s is %s\n", filename, len == 0 ? "empty" : "too long" );
    return qfalse;
  }

  trap_FS_Read( text, len, f );
  text[ len ] = 0;
  trap_FS_FCloseFile( f );

  // parse the text
  text_p = text;

  // read information for each frame
  for( i = BANIM_NONE + 1; i < MAX_BUILDABLE_ANIMATIONS; i++ )
  {

    token = COM_Parse( &text_p );
    if( !*token )
      break;

    animations[ i ].firstFrame = atoi( token );

    token = COM_Parse( &text_p );
    if( !*token )
      break;

    animations[ i ].numFrames = atoi( token );
    animations[ i ].reversed = qfalse;
    animations[ i ].flipflop = qfalse;

    // if numFrames is negative the animation is reversed
    if( animations[ i ].numFrames < 0 )
    {
      animations[ i ].numFrames = -animations[ i ].numFrames;
      animations[ i ].reversed = qtrue;
    }

    token = COM_Parse( &text_p );
    if ( !*token )
      break;

    animations[i].loopFrames = atoi( token );

    token = COM_Parse( &text_p );
    if( !*token )
      break;

    fps = atof( token );
    if( fps == 0 )
      fps = 1;

    animations[ i ].frameLerp = 1000 / fps;
    animations[ i ].initialLerp = 1000 / fps;
  }

  if( i != MAX_BUILDABLE_ANIMATIONS )
  {
    CG_Printf( "Error parsing animation file: %s\n", filename );
    return qfalse;
  }

  return qtrue;
}
예제 #24
0
/*
=======================
UI_CalcPostGameStats
=======================
*/
static void UI_CalcPostGameStats() {
	char		map[MAX_QPATH];
	char		fileName[MAX_QPATH];
	char		info[MAX_INFO_STRING];
	fileHandle_t f;
	int size, game, time, adjustedTime;
	postGameInfo_t oldInfo;
	postGameInfo_t newInfo;
	qboolean newHigh = qfalse;

	trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) );
	Q_strncpyz( map, Info_ValueForKey( info, "mapname" ), sizeof(map) );
	game = atoi(Info_ValueForKey(info, "g_gametype"));

	// compose file name
	Com_sprintf(fileName, MAX_QPATH, "games/%s_%i.game", map, game);
	// see if we have one already
	memset(&oldInfo, 0, sizeof(postGameInfo_t));
	if (trap_FS_FOpenFile(fileName, &f, FS_READ) >= 0) {
	// if so load it
		size = 0;
		trap_FS_Read(&size, sizeof(int), f);
		if (size == sizeof(postGameInfo_t)) {
			trap_FS_Read(&oldInfo, sizeof(postGameInfo_t), f);
		}
		trap_FS_FCloseFile(f);
	}					 

	newInfo.accuracy = atoi(UI_Argv(3));
	newInfo.impressives = atoi(UI_Argv(4));
	newInfo.excellents = atoi(UI_Argv(5));
	newInfo.defends = atoi(UI_Argv(6));
	newInfo.assists = atoi(UI_Argv(7));
	newInfo.gauntlets = atoi(UI_Argv(8));
	newInfo.baseScore = atoi(UI_Argv(9));
	newInfo.perfects = atoi(UI_Argv(10));
	newInfo.redScore = atoi(UI_Argv(11));
	newInfo.blueScore = atoi(UI_Argv(12));
	time = atoi(UI_Argv(13));
	newInfo.captures = atoi(UI_Argv(14));

	newInfo.time = (time - trap_Cvar_VariableValue("ui_matchStartTime")) / 1000;
	adjustedTime = uiInfo.mapList[ui_currentMap.integer].timeToBeat[game];
	if (newInfo.time < adjustedTime) { 
		newInfo.timeBonus = (adjustedTime - newInfo.time) * 10;
	} else {
		newInfo.timeBonus = 0;
	}

	if (newInfo.redScore > newInfo.blueScore && newInfo.blueScore <= 0) {
		newInfo.shutoutBonus = 100;
	} else {
		newInfo.shutoutBonus = 0;
	}

	newInfo.skillBonus = trap_Cvar_VariableValue("g_spSkill");
	if (newInfo.skillBonus <= 0) {
		newInfo.skillBonus = 1;
	}
	newInfo.score = newInfo.baseScore + newInfo.shutoutBonus + newInfo.timeBonus;
	newInfo.score *= newInfo.skillBonus;

	// see if the score is higher for this one
	newHigh = (qboolean)(newInfo.redScore > newInfo.blueScore && newInfo.score > oldInfo.score);

	if  (newHigh) {
		// if so write out the new one
		uiInfo.newHighScoreTime = uiInfo.uiDC.realTime + 20000;
		if (trap_FS_FOpenFile(fileName, &f, FS_WRITE) >= 0) {
			size = sizeof(postGameInfo_t);
			trap_FS_Write(&size, sizeof(int), f);
			trap_FS_Write(&newInfo, sizeof(postGameInfo_t), f);
			trap_FS_FCloseFile(f);
		}
	}

	if (newInfo.time < oldInfo.time) {
		uiInfo.newBestTime = uiInfo.uiDC.realTime + 20000;
	}
 
	// put back all the ui overrides
	trap_Cvar_Set("capturelimit", UI_Cvar_VariableString("ui_saveCaptureLimit"));
	trap_Cvar_Set("fraglimit", UI_Cvar_VariableString("ui_saveFragLimit"));
	trap_Cvar_Set("duel_fraglimit", UI_Cvar_VariableString("ui_saveDuelLimit"));
	trap_Cvar_Set("cg_drawTimer", UI_Cvar_VariableString("ui_drawTimer"));
	trap_Cvar_Set("g_doWarmup", UI_Cvar_VariableString("ui_doWarmup"));
	trap_Cvar_Set("g_Warmup", UI_Cvar_VariableString("ui_Warmup"));
	trap_Cvar_Set("sv_pure", UI_Cvar_VariableString("ui_pure"));
	trap_Cvar_Set("g_friendlyFire", UI_Cvar_VariableString("ui_friendlyFire"));

	UI_SetBestScores(&newInfo, qtrue);
	UI_ShowPostGame(newHigh);


}
예제 #25
0
void CG_LoadHolsterData (clientInfo_t *ci)
{//adjusts the manual holster positional data based on the holster.cfg file associated with the model or simply
	//use the default values

	int				i;
	fileHandle_t	f;
	int				fLen = 0;
	char			fileBuffer[MAX_HOLSTER_INFO_SIZE];
	char			holsterTypeValue[MAX_QPATH];
	char			holsterTypeGroup[MAX_HOLSTER_INFO_SIZE];
	char			*s;
	vec3_t			vectorData;

	InitHolsterData(ci);

	if ( !ci->skinName || !Q_stricmp( "default", ci->skinName ) )
	{//try default holster.cfg first
		fLen = trap_FS_FOpenFile(va("models/players/%s/holster.cfg", ci->modelName), &f, FS_READ);

		if( !f )
		{//no file, use kyle's then.
			fLen = trap_FS_FOpenFile("models/players/kyle/holster.cfg", &f, FS_READ);
		}
	}
	else
	{//use the holster.cfg associated with this skin
		fLen = trap_FS_FOpenFile(va("models/players/%s/holster_%s.cfg", ci->modelName, ci->skinName), &f, FS_READ);
		if ( !f )
		{//fall back to default holster.cfg
			fLen = trap_FS_FOpenFile(va("models/players/%s/holster.cfg", ci->modelName), &f, FS_READ);
		}

		if( !f )
		{//still no dice, use kyle's then.
			fLen = trap_FS_FOpenFile("models/players/kyle/holster.cfg", &f, FS_READ);
		}
	}

	if ( !f || !fLen )
	{//couldn't open file or it was empty, just use the defaults
		return;
	}

	if( fLen >= MAX_HOLSTER_INFO_SIZE )
	{
		CG_Printf("Error: holster.cfg for %s is over the holster.cfg filesize limit.\n", ci->modelName);
		trap_FS_FCloseFile( f );
		return;
	}

	trap_FS_Read(fileBuffer, fLen, f);

	trap_FS_FCloseFile( f );

	s = fileBuffer;

	//parse file
	while( (s = BG_GetNextValueGroup(s, holsterTypeGroup)) != NULL )
	{
		if( !BG_SiegeGetPairedValue(holsterTypeGroup, "holsterType", holsterTypeValue) )
		{//couldn't find holster type in group
			CG_Printf("Error:  The holster.cfg for %s appears to be missing a holsterType in one of its define groups.\n", 
				ci->modelName);
			continue;
		}

		i = GetIDForString(holsterTypeTable, holsterTypeValue);

		if( i == -1 )
		{//bad holster type
			CG_Printf("Error:  The holster.cfg for %s has a bad holsterType in one of the define groups.\n", 
				ci->modelName);
			continue;
		}

		if( BG_SiegeGetPairedValue(holsterTypeGroup, "boneIndex", holsterTypeValue) )
		{//have bone index data for this holster type, use it
			if(!Q_stricmp(holsterTypeValue, "disabled") )
			{//disable the rendering of this holster type on this model
				ci->holsterData[i].boneIndex = HOLSTER_NONE;
			}
			else
			{
				ci->holsterData[i].boneIndex = GetIDForString(holsterBoneTable, holsterTypeValue);
			}
		}

		if( BG_SiegeGetPairedValue(holsterTypeGroup, "posOffset", holsterTypeValue) )
		{//parsing positional offset data
			sscanf (holsterTypeValue, "%f, %f, %f", &vectorData[0], &vectorData[1], &vectorData[2]);
			VectorCopy(vectorData, ci->holsterData[i].posOffset);
				
				//&ci->holsterData[i].posOffset[0], &ci->holsterData[i].posOffset[1], 
				//&ci->holsterData[i].posOffset[2]);
		}

		if( BG_SiegeGetPairedValue(holsterTypeGroup, "angOffset", holsterTypeValue) )
		{//parsing angular offset
			sscanf (holsterTypeValue, "%f, %f, %f", &vectorData[0], &vectorData[1], &vectorData[2]);
			VectorCopy(vectorData, ci->holsterData[i].angOffset);
		}
	}
#ifdef _DEBUG
	CG_Printf("Holstered Weapon Data Loaded for %s.\n", ci->modelName);
#endif
}
예제 #26
0
/*
======================
UI_ParseAnimationFile
======================
*/
static qboolean UI_ParseAnimationFile( const char *filename, playerInfo_t *pi ) {
	char		*text_p, *prev;
	int			len;
	int			i;
	char		*token;
	float		fps;
	int			skip;
	char		text[20000];
	fileHandle_t	f;

	token = NULL;
	i = 0;
	fps = 0;
	prev = 0;

	memset( pi->animations, 0, sizeof( animation_t ) * MAX_ANIMATIONS );

	// load the file
	len = trap_FS_FOpenFile( filename, &f, FS_READ );
	if ( len <= 0 ) {
		return qfalse;
	}
	if ( len >= ( sizeof( text ) - 1 ) ) {
		Com_Printf( "File %s too long\n", filename );
		return qfalse;
	}
	trap_FS_Read( text, len, f );
	text[len] = 0;
	trap_FS_FCloseFile( f );

	// parse the text
	text_p = text;
	skip = 0;	// quite the compiler warning

	// NERVE - SMF - new!!!!
	AnimParseAnimConfig( pi, filename, text );
	return qtrue;

	// -NERVE - SMF - This does not work with wolf's new animation system
/*
	// read optional parameters
	while ( 1 ) {
		prev = text_p;	// so we can unget
		token = COM_Parse( &text_p );
		if ( !token ) {
			break;
		}
		if ( !Q_stricmp( token, "footsteps" ) ) {
			token = COM_Parse( &text_p );
			if ( !token ) {
				break;
			}
			continue;
		} else if ( !Q_stricmp( token, "headoffset" ) ) {
			for ( i = 0 ; i < 3 ; i++ ) {
				token = COM_Parse( &text_p );
				if ( !token ) {
					break;
				}
			}
			continue;
		} else if ( !Q_stricmp( token, "sex" ) ) {
			token = COM_Parse( &text_p );
			if ( !token ) {
				break;
			}
			continue;
		}

		// if it is a number, start parsing animations
		if ( token[0] >= '0' && token[0] <= '9' ) {
			text_p = prev;	// unget the token
			break;
		}

		Com_Printf( "unknown token '%s' is %s\n", token, filename );
	}

	// read information for each frame
	for ( i = 0 ; i < MAX_ANIMATIONS ; i++ ) {

		token = COM_Parse( &text_p );
		if ( !token ) {
			break;
		}
		animations[i].firstFrame = atoi( token );
		// leg only frames are adjusted to not count the upper body only frames
		if ( i == LEGS_WALKCR ) {
			skip = animations[LEGS_WALKCR].firstFrame - animations[TORSO_GESTURE].firstFrame;
		}
		if ( i >= LEGS_WALKCR ) {
			animations[i].firstFrame -= skip;
		}

		token = COM_Parse( &text_p );
		if ( !token ) {
			break;
		}
		animations[i].numFrames = atoi( token );

		token = COM_Parse( &text_p );
		if ( !token ) {
			break;
		}
		animations[i].loopFrames = atoi( token );

		token = COM_Parse( &text_p );
		if ( !token ) {
			break;
		}
		fps = atof( token );
		if ( fps == 0 ) {
			fps = 1;
		}
		animations[i].frameLerp = 1000 / fps;
		animations[i].initialLerp = 1000 / fps;
	}

	if ( i != MAX_ANIMATIONS ) {
		Com_Printf( "Error parsing animation file: %s", filename );
		return qfalse;
	}

	return qtrue;
*/
}
예제 #27
0
static void G_AddBot( const char *name, int skill, const char *team, const char *spawnPoint, int playerClass, int playerWeapon, int characerIndex, const char *respawn, const char *scriptName, int rank, int skills[], qboolean pow ) {
#define	MAX_BOTNAMES 1024
	int				clientNum;
	char			*botinfo;
	gentity_t		*bot;
	char			*key;
	char			*s;
	char			*botname;
//	char			*model;
	char			userinfo[MAX_INFO_STRING];

	// get the botinfo from bots.txt
	// CHRUKER: b070 - Was 'wolfbot' but this must match in case
	botinfo = G_GetBotInfoByName( "Wolfbot" );
	if ( !botinfo ) {
		G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name );
		return;
	}

	// create the bot's userinfo
	userinfo[0] = '\0';

	botname = Info_ValueForKey( botinfo, "funname" );
	if( !botname[0] ) {
		botname = Info_ValueForKey( botinfo, "name" );
	}
	Info_SetValueForKey( userinfo, "name", botname );
	Info_SetValueForKey( userinfo, "rate", "25000" );
	Info_SetValueForKey( userinfo, "snaps", "20" );
	Info_SetValueForKey( userinfo, "skill", va("%i", skill) );

	s = Info_ValueForKey(botinfo, "aifile");
	if (!*s ) {
		trap_Printf( S_COLOR_RED "Error: bot has no aifile specified\n" );
		return;
	}

	// have the server allocate a client slot
	clientNum = trap_BotAllocateClient( 0 );	// Arnout: 0 means no prefered clientslot
	if ( clientNum == -1 ) {
		G_Printf( S_COLOR_RED "Unable to add bot.  All player slots are in use.\n" );
		G_Printf( S_COLOR_RED "Start server with more 'open' slots (or check setting of sv_maxclients cvar).\n" );
		return;
	}

	// initialize the bot settings
	if( !team || !*team ) {
		if( PickTeam(clientNum) == TEAM_AXIS) {
			team = "red";
		} else {
			team = "blue";
		}
	}
	Info_SetValueForKey( userinfo, "characterfile", Info_ValueForKey( botinfo, "aifile" ) );
	//Info_SetValueForKey( userinfo, "skill", va( "%i", skill ) );
	Info_SetValueForKey( userinfo, "team", team );

	if( spawnPoint && spawnPoint[0] ) {
		Info_SetValueForKey( userinfo, "spawnPoint", spawnPoint );
	}

	if (scriptName && scriptName[0]) {
		Info_SetValueForKey( userinfo, "scriptName", scriptName );
	}

/*	if (playerClass > 0) {
		Info_SetValueForKey( userinfo, "pClass", va("%i", playerClass) );
	}

	if (playerWeapon) {
		Info_SetValueForKey( userinfo, "pWeapon", va("%i", playerWeapon) );
	}*/
	// END Mad Doc - TDF

	key = "wolfbot";
	if (!Q_stricmp( (char *)name, key )) {
		// read the botnames file, and pick a name that doesnt exist
		fileHandle_t f;
		int len, i, j, k;
		qboolean setname = qfalse;
		char botnames[8192], *pbotnames, *listbotnames[MAX_BOTNAMES], *token, *oldpbotnames;
		int	lengthbotnames[MAX_BOTNAMES];

		len = trap_FS_FOpenFile( "botfiles/botnames.txt", &f, FS_READ );

		if (len >= 0) {
			if (len > sizeof(botnames)) {
				G_Error( "botfiles/botnames.txt is too big (max = %i)", (int)sizeof(botnames) );
			}
			memset( botnames, 0, sizeof(botnames) );
			trap_FS_Read( botnames, len, f );
			pbotnames = botnames;
			// read them in
			i = 0;
			oldpbotnames = pbotnames;
			while ((token = COM_Parse( &pbotnames ))) {
				if (!token[0]) break;
				listbotnames[i] = strstr( oldpbotnames, token );
				lengthbotnames[i] = strlen(token);
				listbotnames[i][lengthbotnames[i]] = 0;
				oldpbotnames = pbotnames;
				if (++i == MAX_BOTNAMES) break;
			}
			//
			if (i > 2) {
				j = rand() % (i-1);	// start at a random spot inthe list
				for( k = j + 1; k != j; k++ ) {
					if( k == i ) {
						k = -1;	// gets increased on next loop
						continue;
					}
					if (ClientFromName( listbotnames[k] ) == -1) {
						// found an unused name
						Info_SetValueForKey( userinfo, "name", listbotnames[k]  );
						setname = qtrue;
						break;
					}
				}
			}
			//
			trap_FS_FCloseFile( f );
		}

		if (!setname) {
			Info_SetValueForKey( userinfo, "name", va("wolfbot_%i", clientNum+1)  );
		}
	} else {
		Info_SetValueForKey( userinfo, "name", name );
	}

	// if a character was specified, put the index of that character filename in the CS_CHARACTERS table in the userinfo
	if( characerIndex != -1 ) {
		Info_SetValueForKey( userinfo, "ch", va( "%i", characerIndex ) );
	}

	// if a rank was specified, use that
/*	if (rank != -1) {
		Info_SetValueForKey(userinfo, "rank", va("%i", rank));
	}*/

	// END Mad Doc - TDF
	
	bot = &g_entities[ clientNum ];
	bot->r.svFlags |= SVF_BOT;
	if( pow ) {
		bot->r.svFlags |= SVF_POW;
	}
	bot->inuse = qtrue;
	bot->aiName = bot->client->pers.netname;

	// register the userinfo
	trap_SetUserinfo( clientNum, userinfo );

	// have it connect to the game as a normal client
	if ((s = ClientConnect( clientNum, qtrue, qtrue ))) {
		G_Printf( S_COLOR_RED "Unable to add bot: %s\n", s );
		return;
	}

	SetTeam( bot, (char *)team, qtrue, -1, -1, qfalse );

/*	if( skills ) {
		int i;
		
		for( i = 0; i < SK_NUM_SKILLS; i++ ) {
			bot->client->sess.skill[i] = skills[i];
		}
	}*/
	return;
}
예제 #28
0
/*
=================
CG_ParseVoiceChats
=================
*/
int CG_ParseVoiceChats( const char *filename, voiceChatList_t *voiceChatList, int maxVoiceChats ) {
	int	len, i;
	fileHandle_t f;
	char buf[MAX_VOICEFILESIZE];
	char **p, *ptr;
	char *token;
	voiceChat_t *voiceChats;
	qboolean compress;
	sfxHandle_t sound;

	compress = qtrue;
	if (cg_buildScript.integer) {
		compress = qfalse;
	}

	len = trap_FS_FOpenFile( filename, &f, FS_READ );
	if ( !f ) {
		trap_Print( va( S_COLOR_RED "voice chat file not found: %s\n", filename ) );
		return qfalse;
	}
	if ( len >= MAX_VOICEFILESIZE ) {
		trap_Print( va( S_COLOR_RED "voice chat file too large: %s is %i, max allowed is %i\n", filename, len, MAX_VOICEFILESIZE ) );
		trap_FS_FCloseFile( f );
		return qfalse;
	}

	trap_FS_Read( buf, len, f );
	buf[len] = 0;
	trap_FS_FCloseFile( f );

	ptr = buf;
	p = &ptr;

	Com_sprintf(voiceChatList->name, sizeof(voiceChatList->name), "%s", filename);
	voiceChats = voiceChatList->voiceChats;
	for ( i = 0; i < maxVoiceChats; i++ ) {
		voiceChats[i].id[0] = 0;
	}
	token = COM_ParseExt(p, qtrue);
	if (!token[0]) {
		return qtrue;
	}
	if (!Q_stricmp(token, "female")) {
		voiceChatList->gender = GENDER_FEMALE;
	}
	else if (!Q_stricmp(token, "male")) {
		voiceChatList->gender = GENDER_MALE;
	}
	else if (!Q_stricmp(token, "neuter")) {
		voiceChatList->gender = GENDER_NEUTER;
	}
	else {
		trap_Print( va( S_COLOR_RED "expected gender not found in voice chat file: %s\n", filename ) );
		return qfalse;
	}

	voiceChatList->numVoiceChats = 0;
	while ( 1 ) {
		token = COM_ParseExt(p, qtrue);
		if (!token[0]) {
			return qtrue;
		}
		Com_sprintf(voiceChats[voiceChatList->numVoiceChats].id, sizeof( voiceChats[voiceChatList->numVoiceChats].id ), "%s", token);
		token = COM_ParseExt(p, qtrue);
		if (Q_stricmp(token, "{")) {
			trap_Print( va( S_COLOR_RED "expected { found %s in voice chat file: %s\n", token, filename ) );
			return qfalse;
		}
		voiceChats[voiceChatList->numVoiceChats].numSounds = 0;
		while(1) {
			token = COM_ParseExt(p, qtrue);
			if (!token[0]) {
				return qtrue;
			}
			if (!Q_stricmp(token, "}"))
				break;
			sound = trap_S_RegisterSound( token, compress );
			voiceChats[voiceChatList->numVoiceChats].sounds[voiceChats[voiceChatList->numVoiceChats].numSounds] = sound;
			token = COM_ParseExt(p, qtrue);
			if (!token[0]) {
				return qtrue;
			}
			Com_sprintf(voiceChats[voiceChatList->numVoiceChats].chats[
							voiceChats[voiceChatList->numVoiceChats].numSounds], MAX_CHATSIZE, "%s", token);
			if (sound)
				voiceChats[voiceChatList->numVoiceChats].numSounds++;
			if (voiceChats[voiceChatList->numVoiceChats].numSounds >= MAX_VOICESOUNDS)
				break;
		}
		voiceChatList->numVoiceChats++;
		if (voiceChatList->numVoiceChats >= maxVoiceChats)
			return qtrue;
	}
	return qtrue;
}
예제 #29
0
void BotUtilizePersonality(bot_state_t *bs)
{
	fileHandle_t f;
	int len, rlen;
	int failed;
	int i;
	//char buf[131072];
	char *readbuf, *group;

	len = trap_FS_FOpenFile(bs->settings.personalityfile, &f, FS_READ);

	failed = 0;

	if (!f)
	{
		G_Printf(S_COLOR_RED "Error: Specified personality not found\n");
		return;
	}

	char *buf = (char *)B_TempAlloc(len + 1);
	trap_FS_Read(buf, len, f);

	buf[len] = 0;

	readbuf = (char *)B_TempAlloc(1024);
	group = (char *)B_TempAlloc(len);

	if (!GetValueGroup(buf, "GeneralBotInfo", group))
	{
		G_Printf(S_COLOR_RED "Personality file contains no GeneralBotInfo group\n");
		failed = 1; //set failed so we know to set everything to default values
	}

	if (!failed && GetPairedValue(group, "reflex", readbuf))
	{
		bs->skills.reflex = atoi(readbuf);
	}
	else
	{
		bs->skills.reflex = 100; //default
	}

	if (!failed && GetPairedValue(group, "accuracy", readbuf))
	{
		bs->skills.accuracy = atof(readbuf);
	}
	else
	{
		bs->skills.accuracy = 10; //default
	}

	if (!failed && GetPairedValue(group, "turnspeed", readbuf))
	{
		bs->skills.turnspeed = atof(readbuf);
	}
	else
	{
		bs->skills.turnspeed = 0.01f; //default
	}

	if (!failed && GetPairedValue(group, "turnspeed_combat", readbuf))
	{
		bs->skills.turnspeed_combat = atof(readbuf);
	}
	else
	{
		bs->skills.turnspeed_combat = 0.05f; //default
	}

	if (!failed && GetPairedValue(group, "maxturn", readbuf))
	{
		bs->skills.maxturn = atof(readbuf);
	}
	else
	{
		bs->skills.maxturn = 360; //default
	}

	if (!failed && GetPairedValue(group, "perfectaim", readbuf))
	{
		bs->skills.perfectaim = atoi(readbuf);
	}
	else
	{
		bs->skills.perfectaim = 0; //default
	}
/*
	if (!failed && GetPairedValue(group, "chatability", readbuf))
	{
		bs->canChat = atoi(readbuf);
	}
	else
	{
		bs->canChat = 0; //default
	}

	if (!failed && GetPairedValue(group, "chatfrequency", readbuf))
	{
		bs->chatFrequency = atoi(readbuf);
	}
	else
	{
		bs->chatFrequency = 5; //default
	}
*/
	if (!failed && GetPairedValue(group, "hatelevel", readbuf))
	{
		bs->loved_death_thresh = atoi(readbuf);
	}
	else
	{
		bs->loved_death_thresh = 3; //default
	}

	if (!failed && GetPairedValue(group, "camper", readbuf))
	{
		bs->isCamper = atoi(readbuf);
	}
	else
	{
		bs->isCamper = 0; //default
	}

	if (!failed && GetPairedValue(group, "saberspecialist", readbuf))
	{
		bs->saberSpecialist = atoi(readbuf);
	}
	else
	{
		bs->saberSpecialist = 0; //default
	}

	if (!failed && GetPairedValue(group, "forceinfo", readbuf))
	{
		Com_sprintf(bs->forceinfo, sizeof(bs->forceinfo), "%s\0", readbuf);
	}
	else
	{
		Com_sprintf(bs->forceinfo, sizeof(bs->forceinfo), "%s\0", DEFAULT_FORCEPOWERS);
	}

	i = 0;

/*
	while (i < MAX_CHAT_BUFFER_SIZE)
	{ //clear out the chat buffer for this bot
		gBotChatBuffer[bs->client][i] = '\0';
		i++;
	}

	if (bs->canChat)
	{
		if (!ReadChatGroups(bs, buf))
		{
			bs->canChat = 0;
		}
	}
*/
	if (GetValueGroup(buf, "BotWeaponWeights", group))
	{
		if (GetPairedValue(group, "WP_STUN_BATON", readbuf))
		{
			bs->botWeaponWeights[WP_STUN_BATON] = atoi(readbuf);
			bs->botWeaponWeights[WP_MELEE] = bs->botWeaponWeights[WP_STUN_BATON];
		}

		if (GetPairedValue(group, "WP_SABER", readbuf))
		{
			bs->botWeaponWeights[WP_SABER] = atoi(readbuf);
		}

		if (GetPairedValue(group, "WP_BRYAR_PISTOL", readbuf))
		{
			bs->botWeaponWeights[WP_BRYAR_PISTOL] = atoi(readbuf);
		}

		if (GetPairedValue(group, "WP_BLASTER", readbuf))
		{
			bs->botWeaponWeights[WP_BLASTER] = atoi(readbuf);
		}

		if (GetPairedValue(group, "WP_DISRUPTOR", readbuf))
		{
			bs->botWeaponWeights[WP_DISRUPTOR] = atoi(readbuf);
		}

		if (GetPairedValue(group, "WP_BOWCASTER", readbuf))
		{
			bs->botWeaponWeights[WP_BOWCASTER] = atoi(readbuf);
		}

		if (GetPairedValue(group, "WP_REPEATER", readbuf))
		{
			bs->botWeaponWeights[WP_REPEATER] = atoi(readbuf);
		}

		if (GetPairedValue(group, "WP_DEMP2", readbuf))
		{
			bs->botWeaponWeights[WP_DEMP2] = atoi(readbuf);
		}

		if (GetPairedValue(group, "WP_FLECHETTE", readbuf))
		{
			bs->botWeaponWeights[WP_FLECHETTE] = atoi(readbuf);
		}

		if (GetPairedValue(group, "WP_ROCKET_LAUNCHER", readbuf))
		{
			bs->botWeaponWeights[WP_ROCKET_LAUNCHER] = atoi(readbuf);
		}

		if (GetPairedValue(group, "WP_THERMAL", readbuf))
		{
			bs->botWeaponWeights[WP_THERMAL] = atoi(readbuf);
		}

		if (GetPairedValue(group, "WP_TRIP_MINE", readbuf))
		{
			bs->botWeaponWeights[WP_TRIP_MINE] = atoi(readbuf);
		}

		if (GetPairedValue(group, "WP_DET_PACK", readbuf))
		{
			bs->botWeaponWeights[WP_DET_PACK] = atoi(readbuf);
		}
	}

	bs->lovednum = 0;

	if (GetValueGroup(buf, "EmotionalAttachments", group))
	{
		ParseEmotionalAttachments(bs, group);
	}

	B_TempFree(len + 1); //buf
	B_TempFree(1024); //readbuf
	B_TempFree(len); //group
	trap_FS_FCloseFile(f);
}
예제 #30
0
//===========================================================================
// Routine      : AOTCTC_Holocron_Loadpositions
// Description  : Loads holocron positions from .hpf file on disk
void AOTCTC_Holocron_Loadpositions( void )
{// Does each online player's data.
	char *s, *t;
	int len;
	fileHandle_t	f;
	char *buf;
	//[DynamicMemoryTweaks]
	char	loadPath[MAX_QPATH];
	//[/DynamicMemoryTweaks]
	int statnum = 0;
	float stats[50*3]; // 1 extra.
	int holocron_number = 0;
	//[RawMapName]
	//vmCvar_t		mapname;
	//[/RawMapName]

	G_Printf("^5Loading holocron position table...");

	//[RawMapName]
	//loadPath = (char *)B_TempAlloc(1024*4);
	//trap_Cvar_Register( &mapname, "mapname", "", CVAR_SERVERINFO | CVAR_ROM );

	//Com_sprintf(loadPath, 1024*4, "holocron_positions/%s.hpf\0", mapname.string);
	Com_sprintf(loadPath, sizeof(loadPath), "holocron_positions/%s.hpf", level.rawmapname);
	//[/RawMapName]

	len = trap_FS_FOpenFile( loadPath, &f, FS_READ );
	if ( !f )
	{
		G_Printf(" ^3FAILED!!!\n");
		G_Printf("^5No file exists! (^3%s^5)\n", loadPath);
		return;
	}
	if ( !len )
	{ //empty file
		G_Printf(" ^3FAILED!!!\n");
		G_Printf("^5Empty file!\n");
		trap_FS_FCloseFile( f );
		return;
	}

	if ( (buf = BG_TempAlloc(len+1)) == 0 )
	{//alloc memory for buffer
		G_Printf(" ^3FAILED!!!\n");
		G_Printf("^5Unable to allocate buffer.\n");
		return;
	}
	trap_FS_Read( buf, len, f );
	trap_FS_FCloseFile( f );

	for (t = s = buf; *t; /* */ ) 
	{
		s = strchr(s, ' ');
		
		if (!s)
			break;

		while (*s == ' ')
			*s++ = 0;

		if (*t)
		{
			if (statnum == 0)
			{
				number_of_holocronpositions = atoi(t);
				
				if (number_of_holocronpositions <= 18)
				{
					G_Printf(" ^3FAILED!!!\n");
					G_Printf("^5You need at least 18 holocron points!\n");
					return;
				}
			}

			stats[statnum] = (float)atof(t);
			statnum++;
		}

		t = s;
	}

	statnum = 1;

	while (holocron_number < number_of_holocronpositions)
	{
		int reference = 0;

		while (reference <= 2)
		{
			holocrons[holocron_number].origin[reference] = stats[statnum];
			statnum++;
			reference++;
		}

		holocron_number++;
	}

	BG_TempFree(len+1);

	G_Printf(" ^3Completed OK.\n");
	G_Printf("^5Total Holocron Positions: ^7%i^5.\n", number_of_holocronpositions);
	holocrons_loaded = qtrue;
}