Ejemplo n.º 1
0
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_Open(levelname, &f, FS_READ);

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

	trap->FS_Read(siege_info, len, f);

	trap->FS_Close(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
	{
		trap->Error( ERR_DROP, "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?!
		trap->Error( ERR_DROP, "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.
		trap->Error( ERR_DROP, "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;
}
Ejemplo n.º 2
0
void CG_InitSiegeMode(void)
{
	char			levelname[MAX_QPATH];
	char			btime[1024];
	char			teams[2048];
	char			teamInfo[MAX_SIEGE_INFO_SIZE];
	int				len = 0;
	int				i = 0;
	int				j = 0;
	siegeClass_t		*cl;
	siegeTeam_t		*sTeam;
	fileHandle_t	f;
	char			teamIcon[128];

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

	Com_sprintf(levelname, sizeof(levelname), "%s\0", cgs.mapname);

	i = strlen(levelname)-1;

	while (i > 0 && levelname[i] && levelname[i] != '.')
	{
		i--;
	}

	if (!i)
	{
		goto failure;
	}

	levelname[i] = '\0'; //kill the ".bsp"

	Com_sprintf(levelname, sizeof(levelname), "%s.siege\0", levelname); 

	if (!levelname || !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;

	if (BG_SiegeGetValueGroup(siege_info, "Teams", teams))
	{
		char buf[1024];

		//[SIEGECVARFIX]
		siege_Cvar_VariableStringBuffer("cg_siegeTeam1", buf, 1024);
		//trap_Cvar_VariableStringBuffer("cg_siegeTeam1", buf, 1024);
		//[SIEGECVARFIX]
		if (buf[0] && Q_stricmp(buf, "none"))
		{
			strcpy(team1, buf);
		}
		else
		{
			BG_SiegeGetPairedValue(teams, "team1", team1);
		}

		if (team1[0] == '@')
		{ //it's a damn stringed reference.
			char b[256];
			trap_SP_GetStringTextString(team1+1, b, 256);
			trap_Cvar_Set("cg_siegeTeam1Name", b);
		}
		else
		{
			trap_Cvar_Set("cg_siegeTeam1Name", team1);
		}

		//[SIEGECVARFIX]
		siege_Cvar_VariableStringBuffer("cg_siegeTeam2", buf, 1024);
		//trap_Cvar_VariableStringBuffer("cg_siegeTeam2", buf, 1024);
		//[/SIEGECVARFIX]
		if (buf[0] && Q_stricmp(buf, "none"))
		{
			strcpy(team2, buf);
		}
		else
		{
			BG_SiegeGetPairedValue(teams, "team2", team2);
		}

		if (team2[0] == '@')
		{ //it's a damn stringed reference.
			char b[256];
			trap_SP_GetStringTextString(team2+1, b, 256);
			trap_Cvar_Set("cg_siegeTeam2Name", b);
		}
		else
		{
			trap_Cvar_Set("cg_siegeTeam2Name", team2);
		}
	}
	else
	{
		CG_Error("Siege teams not defined");
	}

	if (BG_SiegeGetValueGroup(siege_info, team1, teamInfo))
	{
		if (BG_SiegeGetPairedValue(teamInfo, "TeamIcon", teamIcon))
		{
			trap_Cvar_Set( "team1_icon", teamIcon);
		}

		if (BG_SiegeGetPairedValue(teamInfo, "Timed", btime))
		{
			team1Timed = atoi(btime)*1000;
			CG_SetSiegeTimerCvar ( team1Timed );
		}
		else
		{
			team1Timed = 0;
		}
	}
	else
	{
		CG_Error("No team entry for '%s'\n", team1);
	}

	if (BG_SiegeGetPairedValue(siege_info, "mapgraphic", teamInfo))
	{
		trap_Cvar_Set("siege_mapgraphic", teamInfo);
	}
	else
	{
		trap_Cvar_Set("siege_mapgraphic", "gfx/mplevels/siege1_hoth");
	}

	if (BG_SiegeGetPairedValue(siege_info, "missionname", teamInfo))
	{
		trap_Cvar_Set("siege_missionname", teamInfo);
	}
	else
	{
		trap_Cvar_Set("siege_missionname", " ");
	}

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

		if (BG_SiegeGetPairedValue(teamInfo, "Timed", btime))
		{
			team2Timed = atoi(btime)*1000;
			CG_SetSiegeTimerCvar ( team2Timed );
		}
		else
		{
			team2Timed = 0;
		}
	}
	else
	{
		CG_Error("No team entry for '%s'\n", team2);
	}

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

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

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

	if (!bgNumSiegeTeams)
	{ //React same as with classes.
		CG_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, teamInfo))
	{
		if (BG_SiegeGetPairedValue(teamInfo, "UseTeam", btime))
		{
			BG_SiegeSetTeamTheme(SIEGETEAM_TEAM1, btime);
		}
		if (BG_SiegeGetPairedValue(teamInfo, "FriendlyShader", btime))
		{
			cgSiegeTeam1PlShader = trap_R_RegisterShaderNoMip(btime);
		}
		else
		{
			cgSiegeTeam1PlShader = 0;
		}
	}
	if (BG_SiegeGetValueGroup(siege_info, team2, teamInfo))
	{
		if (BG_SiegeGetPairedValue(teamInfo, "UseTeam", btime))
		{
			BG_SiegeSetTeamTheme(SIEGETEAM_TEAM2, btime);
		}
		if (BG_SiegeGetPairedValue(teamInfo, "FriendlyShader", btime))
		{
			cgSiegeTeam2PlShader = trap_R_RegisterShaderNoMip(btime);
		}
		else
		{
			cgSiegeTeam2PlShader = 0;
		}
	}

	//Now go through the classes used by the loaded teams and try to precache
	//any forced models or forced skins.
	i = SIEGETEAM_TEAM1;

	while (i <= SIEGETEAM_TEAM2)
	{
		j = 0;
		sTeam = BG_SiegeFindThemeForTeam(i);

		if (!sTeam)
		{
			i++;
			continue;
		}

		//Get custom team shaders while we're at it.
		if (i == SIEGETEAM_TEAM1)
		{
			cgSiegeTeam1PlShader = sTeam->friendlyShader;
		}
		else if (i == SIEGETEAM_TEAM2)
		{
			cgSiegeTeam2PlShader = sTeam->friendlyShader;
		}

		while (j < sTeam->numClasses)
		{
			cl = sTeam->classes[j];

			if (cl->forcedModel[0])
			{ //This class has a forced model, so precache it.
				trap_R_RegisterModel(va("models/players/%s/model.glm", cl->forcedModel));

				if (cl->forcedSkin[0])
				{ //also has a forced skin, precache it.
					char *useSkinName;

					if (strchr(cl->forcedSkin, '|'))
					{//three part skin
						useSkinName = va("models/players/%s/|%s", cl->forcedModel, cl->forcedSkin);
					}
					else
					{
						useSkinName = va("models/players/%s/model_%s.skin", cl->forcedModel, cl->forcedSkin);
					}

					trap_R_RegisterSkin(useSkinName);
				}
			}
			
			j++;
		}
		i++;
	}

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

	CG_PrecachePlayersForSiegeTeam(SIEGETEAM_TEAM1);
	CG_PrecachePlayersForSiegeTeam(SIEGETEAM_TEAM2);

	CG_PrecachePlayersForSiegeTeam(SIEGETEAM_TEAM1);
	CG_PrecachePlayersForSiegeTeam(SIEGETEAM_TEAM2);

	CG_PrecacheSiegeObjectiveAssetsForTeam(SIEGETEAM_TEAM1);
	CG_PrecacheSiegeObjectiveAssetsForTeam(SIEGETEAM_TEAM2);

	return;
failure:
	siege_valid = 0;
}
Ejemplo n.º 3
0
void CG_InitSiegeMode( void ) {
	char levelname[MAX_QPATH] = {};
	char btime[1024] = {};
	char teams[2048] = {};
	char teamIcon[MAX_QPATH] = {};
	const char *s;
	int len = 0, i = 0, j = 0;
	siegeClass_t *cl;
	siegeTeam_t *sTeam;
	fileHandle_t f;

	s = CG_ConfigString( CS_SIEGE_STATE );
	if ( s[0] ) {
		CG_ParseSiegeState( s );
	}

	s = CG_ConfigString( CS_SIEGE_WINTEAM );
	if ( s[0] ) {
		cg_siegeWinTeam = atoi( s );
	}

	if ( cgs.gametype == GT_SIEGE ) {
		CG_ParseSiegeObjectiveStatus( CG_ConfigString( CS_SIEGE_OBJECTIVES ) );
		cg_beatingSiegeTime = atoi( CG_ConfigString( CS_SIEGE_TIMEOVERRIDE ) );
		if ( cg_beatingSiegeTime ) {
			CG_SetSiegeTimerCvar( cg_beatingSiegeTime );
		}
	}

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

	// grab the .siege file
	Com_sprintf( levelname, sizeof(levelname), "maps/%s.siege", cgs.mapnameClean );

	len = trap->FS_Open( levelname, &f, FS_READ );
	if ( !f || len <= 0 || len >= MAX_SIEGE_INFO_SIZE ) {
		goto failure;
	}

	trap->FS_Read( siege_info, len, f );
	trap->FS_Close( f );

	siege_valid = qtrue;

	if ( BG_SiegeGetValueGroup( siege_info, "Teams", teams ) ) {
		char buf[1024];

		trap->Cvar_VariableStringBuffer( "cg_siegeTeam1", buf, sizeof(buf) );
		if ( buf[0] && Q_stricmp( buf, "none" ) ) {
			Q_strncpyz( team1, buf, sizeof(team1) );
		}
		else {
			BG_SiegeGetPairedValue( teams, "team1", team1 );
		}

		if ( team1[0] == '@' ) {
			// it's a damn stringed reference.
			char b[256];
			trap->SE_GetStringTextString( team1 + 1, b, sizeof(b) );
			trap->Cvar_Set( "cg_siegeTeam1Name", b );
		}
		else {
			trap->Cvar_Set( "cg_siegeTeam1Name", team1 );
		}

		trap->Cvar_VariableStringBuffer( "cg_siegeTeam2", buf, sizeof(buf) );
		if ( buf[0] && Q_stricmp( buf, "none" ) ) {
			Q_strncpyz( team2, buf, sizeof(team2) );
		}
		else {
			BG_SiegeGetPairedValue( teams, "team2", team2 );
		}

		if ( team2[0] == '@' ) {
			// it's a damn stringed reference.
			char b[256];
			trap->SE_GetStringTextString( team2 + 1, b, sizeof(b) );
			trap->Cvar_Set( "cg_siegeTeam2Name", b );
		}
		else {
			trap->Cvar_Set( "cg_siegeTeam2Name", team2 );
		}
	}
	else {
		trap->Error( ERR_DROP, "Siege teams not defined" );
	}

	static char teamInfo[MAX_SIEGE_INFO_SIZE] = {};
	teamInfo[0] = '\0';
	if ( BG_SiegeGetValueGroup( siege_info, team1, teamInfo ) ) {
		if ( BG_SiegeGetPairedValue( teamInfo, "TeamIcon", teamIcon ) )
			trap->Cvar_Set( "team1_icon", teamIcon );

		if ( BG_SiegeGetPairedValue( teamInfo, "Timed", btime ) ) {
			team1Timed = atoi( btime ) * 1000;
			CG_SetSiegeTimerCvar( team1Timed );
		}
		else {
			team1Timed = 0;
		}
	}
	else {
		trap->Error( ERR_DROP, "No team entry for '%s'\n", team1 );
	}

	if ( BG_SiegeGetPairedValue( siege_info, "mapgraphic", teamInfo ) ) {
		trap->Cvar_Set( "siege_mapgraphic", teamInfo );
	}
	else {
		trap->Cvar_Set( "siege_mapgraphic", "gfx/mplevels/siege1_hoth" );
	}

	if ( BG_SiegeGetPairedValue( siege_info, "missionname", teamInfo ) ) {
		trap->Cvar_Set( "siege_missionname", teamInfo );
	}
	else {
		trap->Cvar_Set( "siege_missionname", " " );
	}

	if ( BG_SiegeGetValueGroup( siege_info, team2, teamInfo ) ) {
		if ( BG_SiegeGetPairedValue( teamInfo, "TeamIcon", teamIcon ) ) {
			trap->Cvar_Set( "team2_icon", teamIcon );
		}

		if ( BG_SiegeGetPairedValue( teamInfo, "Timed", btime ) ) {
			team2Timed = atoi( btime ) * 1000;
			CG_SetSiegeTimerCvar( team2Timed );
		}
		else {
			team2Timed = 0;
		}
	}
	else {
		trap->Error( ERR_DROP, "No team entry for '%s'\n", team2 );
	}

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

	if ( !bgNumSiegeClasses ) {
		trap->Error( ERR_DROP, "Couldn't find any player classes for Siege" );
	}

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

	if ( !bgNumSiegeTeams ) {
		trap->Error( ERR_DROP, "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, teamInfo ) ) {
		if ( BG_SiegeGetPairedValue( teamInfo, "UseTeam", btime ) ) {
			BG_SiegeSetTeamTheme( SIEGETEAM_TEAM1, btime );
		}
		if ( BG_SiegeGetPairedValue( teamInfo, "FriendlyShader", btime ) ) {
			cgSiegeTeam1PlShader = trap->R_RegisterShaderNoMip( btime );
		}
		else {
			cgSiegeTeam1PlShader = 0;
		}
	}
	if ( BG_SiegeGetValueGroup( siege_info, team2, teamInfo ) ) {
		if ( BG_SiegeGetPairedValue( teamInfo, "UseTeam", btime ) ) {
			BG_SiegeSetTeamTheme( SIEGETEAM_TEAM2, btime );
		}
		if ( BG_SiegeGetPairedValue( teamInfo, "FriendlyShader", btime ) ) {
			cgSiegeTeam2PlShader = trap->R_RegisterShaderNoMip( btime );
		}
		else {
			cgSiegeTeam2PlShader = 0;
		}
	}

	//Now go through the classes used by the loaded teams and try to precache any forced models or forced skins.
	for ( i = SIEGETEAM_TEAM1; i <= SIEGETEAM_TEAM2; i++ ) {
		sTeam = BG_SiegeFindThemeForTeam( i );

		if ( !sTeam ) {
			continue;
		}

		//Get custom team shaders while we're at it.
		if ( i == SIEGETEAM_TEAM1 )
			cgSiegeTeam1PlShader = sTeam->friendlyShader;
		else if ( i == SIEGETEAM_TEAM2 )
			cgSiegeTeam2PlShader = sTeam->friendlyShader;

		for ( j = 0; j < sTeam->numClasses; j++ ) {
			cl = sTeam->classes[j];

			if ( cl->forcedModel[0] ) {
				// This class has a forced model, so precache it.
				trap->R_RegisterModel( va( "models/players/%s/model.glm", cl->forcedModel ) );

				if ( cl->forcedSkin[0] ) {
					// also has a forced skin, precache it.
					char useSkinName[MAX_QPATH];

					if ( strchr( cl->forcedSkin, '|' ) ) {
						Com_sprintf( useSkinName, sizeof(useSkinName), "models/players/%s/|%s",
							cl->forcedModel, cl->forcedSkin );
					}
					else {
						Com_sprintf( useSkinName, sizeof(useSkinName), "models/players/%s/model_%s.skin",
							cl->forcedModel, cl->forcedSkin );
					}

					trap->R_RegisterSkin( useSkinName );
				}
			}
		}
	}

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

	CG_PrecachePlayersForSiegeTeam( SIEGETEAM_TEAM1 );
	CG_PrecachePlayersForSiegeTeam( SIEGETEAM_TEAM2 );

	CG_PrecachePlayersForSiegeTeam( SIEGETEAM_TEAM1 );
	CG_PrecachePlayersForSiegeTeam( SIEGETEAM_TEAM2 );

	CG_PrecacheSiegeObjectiveAssetsForTeam( SIEGETEAM_TEAM1 );
	CG_PrecacheSiegeObjectiveAssetsForTeam( SIEGETEAM_TEAM2 );

	return;
failure:
	siege_valid = qfalse;
}