示例#1
0
/*
==================
CL_ParseServerInfo
==================
*/
void
CL_ParseServerInfo(void)
{
    char *level;
    const char *mapname;
    int i, maxlen;
    int nummodels, numsounds;
    char model_precache[MAX_MODELS][MAX_QPATH];
    char sound_precache[MAX_SOUNDS][MAX_QPATH];

    Con_DPrintf("Serverinfo packet received.\n");
//
// wipe the client_state_t struct
//
    CL_ClearState();

// parse protocol version number
    i = MSG_ReadLong();
    if (!Protocol_Known(i)) {
	Con_Printf("Server returned unknown protocol version %i\n", i);
	return;
    }
    cl.protocol = i;

// parse maxclients
    cl.maxclients = MSG_ReadByte();
    if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD) {
	Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
	return;
    }
    cl.players = Hunk_AllocName(cl.maxclients * sizeof(*cl.players), "players");

// parse gametype
    cl.gametype = MSG_ReadByte();

// parse signon message
    level = cl.levelname;
    maxlen = sizeof(cl.levelname);
    snprintf(level, maxlen, "%s", MSG_ReadString());

// seperate the printfs so the server message can have a color
    Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36"
	       "\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n");
    Con_Printf("%c%s\n", 2, level);
    Con_Printf("Using protocol %i\n", cl.protocol);

//
// first we go through and touch all of the precache data that still
// happens to be in the cache, so precaching something else doesn't
// needlessly purge it
//

// precache models
    memset(cl.model_precache, 0, sizeof(cl.model_precache));
    for (nummodels = 1;; nummodels++) {
	char *in, *model;
	in = MSG_ReadString();
	if (!in[0])
	    break;
	if (nummodels == max_models(cl.protocol)) {
	    Host_Error("Server sent too many model precaches (max = %d)",
		       max_models(cl.protocol));
	    return;
	}
	model = model_precache[nummodels];
	maxlen = sizeof(model_precache[0]);
	snprintf(model, maxlen, "%s", in);
	Mod_TouchModel(model);
    }

// precache sounds
    memset(cl.sound_precache, 0, sizeof(cl.sound_precache));
    for (numsounds = 1;; numsounds++) {
	char *in, *sound;
	in = MSG_ReadString();
	if (!in[0])
	    break;
	if (numsounds == max_sounds(cl.protocol)) {
	    Host_Error("Server sent too many sound precaches (max = %d)",
		       max_sounds(cl.protocol));
	    return;
	}
	sound = sound_precache[numsounds];
	maxlen = sizeof(sound_precache[0]);
	snprintf(sound, maxlen, "%s", in);
	S_TouchSound(sound);
    }

// copy the naked name of the map file to the cl structure
    mapname = COM_SkipPath(model_precache[1]);
    COM_StripExtension(mapname, cl.mapname, sizeof(cl.mapname));

//
// now we try to load everything else until a cache allocation fails
//

    for (i = 1; i < nummodels; i++) {
	cl.model_precache[i] = Mod_ForName(model_precache[i], false);
	if (cl.model_precache[i] == NULL) {
	    Con_Printf("Model %s not found\n", model_precache[i]);
	    return;
	}
	CL_KeepaliveMessage();
    }

    S_BeginPrecaching();
    for (i = 1; i < numsounds; i++) {
	cl.sound_precache[i] = S_PrecacheSound(sound_precache[i]);
	CL_KeepaliveMessage();
    }
    S_EndPrecaching();


// local state
    cl_entities[0].model = cl.model_precache[1];
    cl.worldmodel = BrushModel(cl_entities[0].model);

    R_NewMap();

    Hunk_Check();		// make sure nothing is hurt

    noclip_anglehack = false;	// noclip is turned off at start
}
示例#2
0
void CL_ParseServerInfo (void)
{
	char	*str;
	int		i;
	int		nummodels, numsounds;
	char	model_precache[MAX_MODELS][MAX_QPATH];
	char	sound_precache[MAX_SOUNDS][MAX_QPATH];
	
	Con_DPrintf ("Serverinfo packet received.\n");
//
// wipe the client_state_t struct
//
	CL_ClearState ();

// parse protocol version number
	i = MSG_ReadLong ();
	if (i != PROTOCOL_VERSION)
	{
		Con_Printf ("Server returned version %i, not %i", i, PROTOCOL_VERSION);
		return;
	}

// parse maxclients
	cl.maxclients = MSG_ReadByte ();
	if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
	{
		Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
		return;
	}
	cl.scores = (scoreboard_t*) Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores");

// parse gametype
	cl.gametype = MSG_ReadByte ();

// parse signon message
	str = MSG_ReadString ();
	strncpy (cl.levelname, str, sizeof(cl.levelname)-1);

// seperate the printfs so the server message can have a color
	Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n");
	Con_Printf ("%c%s\n", 2, str);

//
// first we go through and touch all of the precache data that still
// happens to be in the cache, so precaching something else doesn't
// needlessly purge it
//

// precache models
	memset (cl.model_precache, 0, sizeof(cl.model_precache));
	for (nummodels=1 ; ; nummodels++)
	{
		str = MSG_ReadString ();
		if (!str[0])
			break;
		if (nummodels==MAX_MODELS)
		{
			Con_Printf ("Server sent too many model precaches\n");
			return;
		}
		strcpy (model_precache[nummodels], str);
		Mod_TouchModel (str);
	}

// precache sounds
	memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
	for (numsounds=1 ; ; numsounds++)
	{
		str = MSG_ReadString ();
		if (!str[0])
			break;
		if (numsounds==MAX_SOUNDS)
		{
			Con_Printf ("Server sent too many sound precaches\n");
			return;
		}
		strcpy (sound_precache[numsounds], str);
		S_TouchSound (str);
	}

//
// now we try to load everything else until a cache allocation fails
//

	for (i=1 ; i<nummodels ; i++)
	{
		cl.model_precache[i] = Mod_ForName (model_precache[i], false);
		if (cl.model_precache[i] == NULL)
		{
			Con_Printf("Model %s not found\n", model_precache[i]);
			return;
		}
		CL_KeepaliveMessage ();
	}

	S_BeginPrecaching ();
	for (i=1 ; i<numsounds ; i++)
	{
		cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
		CL_KeepaliveMessage ();
	}
	S_EndPrecaching ();


// local state
	cl_entities[0].model = cl.worldmodel = cl.model_precache[1];
	
	R_NewMap ();

	Hunk_Check ();		// make sure nothing is hurt
	
	noclip_anglehack = false;		// noclip is turned off at start	
}
/*
==================
CL_ParseServerInfo
==================
*/
void CL_ParseServerInfo (void)
{
	const char	*str;
	int		i;
	int		nummodels, numsounds;
	char	model_precache[MAX_MODELS][MAX_QPATH];
	char	sound_precache[MAX_SOUNDS][MAX_QPATH];

	Con_DPrintf ("Serverinfo packet received.\n");
//
// wipe the client_state_t struct
//
	CL_ClearState ();

// parse protocol version number
	i = MSG_ReadLong ();
	//johnfitz -- support multiple protocols
	if (i != PROTOCOL_NETQUAKE && i != PROTOCOL_FITZQUAKE) {
		Con_Printf ("\n"); //becuase there's no newline after serverinfo print
		Host_Error ("Server returned version %i, not %i or %i\n", i, PROTOCOL_NETQUAKE, PROTOCOL_FITZQUAKE);
	}
	cl.protocol = i;
	//johnfitz

// parse maxclients
	cl.maxclients = MSG_ReadByte ();
	if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
	{
		Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
		return;
	}
	cl.scores = (scoreboard_t *) Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores");

// parse gametype
	cl.gametype = MSG_ReadByte ();

// parse signon message
	str = MSG_ReadString ();
	q_strlcpy (cl.levelname, str, sizeof(cl.levelname));

// seperate the printfs so the server message can have a color
	Con_Printf ("\n%s\n", Con_Quakebar(40)); //johnfitz
	Con_Printf ("%c%s\n", 2, str);

//johnfitz -- tell user which protocol this is
	Con_Printf ("Using protocol %i\n", i);

// first we go through and touch all of the precache data that still
// happens to be in the cache, so precaching something else doesn't
// needlessly purge it

// precache models
	memset (cl.model_precache, 0, sizeof(cl.model_precache));
	for (nummodels = 1 ; ; nummodels++)
	{
		str = MSG_ReadString ();
		if (!str[0])
			break;
		if (nummodels==MAX_MODELS)
		{
			Con_Printf ("Server sent too many model precaches\n");
			return;
		}
		q_strlcpy (model_precache[nummodels], str, MAX_QPATH);
		Mod_TouchModel (str);
	}

	//johnfitz -- check for excessive models
	if (nummodels >= 256)
		Con_Warning ("%i models exceeds standard limit of 256.\n", nummodels);
	//johnfitz

// precache sounds
	memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
	for (numsounds = 1 ; ; numsounds++)
	{
		str = MSG_ReadString ();
		if (!str[0])
			break;
		if (numsounds==MAX_SOUNDS)
		{
			Con_Printf ("Server sent too many sound precaches\n");
			return;
		}
		q_strlcpy (sound_precache[numsounds], str, MAX_QPATH);
		S_TouchSound (str);
	}

	//johnfitz -- check for excessive sounds
	if (numsounds >= 256)
		Con_Warning ("%i sounds exceeds standard limit of 256.\n", numsounds);
	//johnfitz

//
// now we try to load everything else until a cache allocation fails
//

	// copy the naked name of the map file to the cl structure -- O.S
	COM_StripExtension (COM_SkipPath(model_precache[1]), cl.mapname, sizeof(cl.mapname));

	for (i = 1; i < nummodels; i++)
	{
		cl.model_precache[i] = Mod_ForName (model_precache[i], false);
		if (cl.model_precache[i] == NULL)
		{
			Con_Printf("Model %s not found\n", model_precache[i]);
			return;
		}
		CL_KeepaliveMessage ();
	}

	S_BeginPrecaching ();
	for (i = 1; i < numsounds; i++)
	{
		cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
		CL_KeepaliveMessage ();
	}
	S_EndPrecaching ();

// local state
	cl_entities[0].model = cl.worldmodel = cl.model_precache[1];

	R_NewMap ();

	//johnfitz -- clear out string; we don't consider identical
	//messages to be duplicates if the map has changed in between
	con_lastcenterstring[0] = 0;
	//johnfitz

	Hunk_Check ();		// make sure nothing is hurt

	noclip_anglehack = false;		// noclip is turned off at start

	warn_about_nehahra_protocol = true; //johnfitz -- warn about nehahra protocol hack once per server connection

//johnfitz -- reset developer stats
	memset(&dev_stats, 0, sizeof(dev_stats));
	memset(&dev_peakstats, 0, sizeof(dev_peakstats));
	memset(&dev_overflows, 0, sizeof(dev_overflows));
}
/*
==================
CL_ParseServerInfo
==================
*/
static void CL_ParseServerInfo (void)
{
	const char	*str;
	int		i;
	int		nummodels, numsounds;
	char	model_precache[MAX_MODELS][MAX_QPATH];
	char	sound_precache[MAX_SOUNDS][MAX_QPATH];
// rjr	edict_t		*ent;

	Con_DPrintf ("Serverinfo packet received.\n");
//
// wipe the client_state_t struct
//
	CL_ClearState ();

// parse protocol version number
	cl_protocol = MSG_ReadLong ();
	switch (cl_protocol)
	{
	case PROTOCOL_RAVEN_111:
	case PROTOCOL_RAVEN_112:
	case PROTOCOL_UQE_113:
		Con_Printf ("\nServer using protocol %i\n", cl_protocol);
		break;
	default:
		Con_Printf ("\nServer returned version %i, not %i or %i\n",
				cl_protocol, PROTOCOL_RAVEN_112, PROTOCOL_UQE_113);
		return;
	}

// parse maxclients
	cl.maxclients = MSG_ReadByte ();
	if (cl.maxclients < 1 || cl.maxclients > MAX_CLIENTS)
	{
		Con_Printf("Bad maxclients (%d) from server\n", cl.maxclients);
		return;
	}
	cl.scores = (scoreboard_t *) Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores");

// parse gametype
	cl.gametype = MSG_ReadByte ();

	if (cl.gametype == GAME_DEATHMATCH && cl_protocol > PROTOCOL_RAVEN_111)
		sv_kingofhill = MSG_ReadShort ();

// parse signon message
	str = MSG_ReadString ();
	q_strlcpy (cl.levelname, str, sizeof(cl.levelname));

// seperate the printfs so the server message can have a color
	Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n");
	Con_Printf ("%c%s\n", 2, str);

//
// first we go through and touch all of the precache data that still
// happens to be in the cache, so precaching something else doesn't
// needlessly purge it
//

// precache models
	memset (cl.model_precache, 0, sizeof(cl.model_precache));
	for (nummodels = 1 ; ; nummodels++)
	{
		str = MSG_ReadString ();
		if (!str[0])
			break;
		if (nummodels == MAX_MODELS)
		{
			Con_Printf ("Server sent too many model precaches\n");
			return;
		}
		q_strlcpy (model_precache[nummodels], str, MAX_QPATH);
		Mod_TouchModel (str);
	}

// precache sounds
	memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
	for (numsounds = 1 ; ; numsounds++)
	{
		str = MSG_ReadString ();
		if (!str[0])
			break;
		if (numsounds == MAX_SOUNDS)
		{
			Con_Printf ("Server sent too many sound precaches\n");
			return;
		}
		q_strlcpy (sound_precache[numsounds], str, MAX_QPATH);
		S_TouchSound (str);
	}

//
// now we try to load everything else until a cache allocation fails
//

	if (precache.integer)
	{
		total_loading_size = nummodels + numsounds;
		current_loading_size = 1;
		loading_stage = 2;
	}

	// copy the naked name of the map file to the cl structure
	COM_StripExtension (COM_SkipPath(model_precache[1]), cl.mapname, sizeof(cl.mapname));

	//always precache the world!!!
	cl.model_precache[1] = Mod_ForName (model_precache[1], false);
	for (i = 2; i < nummodels; i++)
	{
		if (precache.integer)
		{
			cl.model_precache[i] = Mod_ForName (model_precache[i], false);
			current_loading_size++;
			D_ShowLoadingSize();
		}
		else
			cl.model_precache[i] = (model_t *)Mod_FindName (model_precache[i]);

		if (cl.model_precache[i] == NULL)
		{
			Host_Error("Model %s not found", model_precache[i]);
			return;
		}
		CL_KeepaliveMessage ();
	}

	player_models[0] = (model_t *)Mod_FindName ("models/paladin.mdl");
	// Note: old demo doesnt have necro and crusader classes. add
	// a GAME_OLD_DEMO flag check ?
	player_models[1] = (model_t *)Mod_FindName ("models/crusader.mdl");
	player_models[2] = (model_t *)Mod_FindName ("models/necro.mdl");
	player_models[3] = (model_t *)Mod_FindName ("models/assassin.mdl");
	if (gameflags & GAME_PORTALS)
		player_models[4] = (model_t *)Mod_FindName ("models/succubus.mdl");

	S_BeginPrecaching ();
	for (i = 1; i < numsounds; i++)
	{
		cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
		if (precache.integer)
		{
			current_loading_size++;
			D_ShowLoadingSize();
		}

		CL_KeepaliveMessage ();
	}
	S_EndPrecaching ();

	total_loading_size = 0;
	loading_stage = 0;

// local state
	cl_entities[0].model = cl.worldmodel = cl.model_precache[1];

	R_NewMap ();

	if (!sv.active)
	{
		PR_LoadStrings();
	}
	PR_LoadPuzzleStrings();
	// mission pack, objectives strings
	if (gameflags & GAME_PORTALS)
		PR_LoadInfoStrings();

	Hunk_Check ();		// make sure nothing is hurt

// we connected to the server, make sure the mouse is going - S.A.
	menu_disabled_mouse = false;
	IN_ActivateMouse();
}
示例#5
0
/*
==================
CL_ParseServerInfo
==================
*/
void CL_ParseServerInfo (void)
{
	char	*str;
	int		i;
	int		nummodels, numsounds;
	static char	model_precache[MAX_MODELS][MAX_QPATH];
	static char	sound_precache[MAX_SOUNDS][MAX_QPATH];
	
	Con_DPrintf ("Serverinfo packet received.\n");
//
// wipe the client_state_t struct
//
	CL_ClearState ();

// parse protocol version number
	i = MSG_ReadLong ();
	if (i != PROTOCOL_VERSION)
	{
		Con_Printf ("Server returned version %i, not %i", i, PROTOCOL_VERSION);
		return;
	}

// parse maxclients
	cl.maxclients = MSG_ReadByte ();
	if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
	{
		Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
		return;
	}
	cl.scores = Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores");

// parse gametype
	cl.gametype = MSG_ReadByte ();
	
	if (cl.gametype == GAME_DEATHMATCH)
		sv_kingofhill = MSG_ReadShort ();

// parse signon message
	str = MSG_ReadString ();
	strncpy (cl.levelname, str, sizeof(cl.levelname)-1);

// seperate the printfs so the server message can have a color
	Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n");
	Con_Printf ("%c%s\n", 2, str);

//
// first we go through and touch all of the precache data that still
// happens to be in the cache, so precaching something else doesn't
// needlessly purge it
//

// precache models
	memset (cl.model_precache, 0, sizeof(cl.model_precache));
	for (nummodels=1 ; ; nummodels++)
	{
		str = MSG_ReadString ();
		if (!str[0])
			break;
		if (nummodels==MAX_MODELS)
		{
			Con_Printf ("Server sent too many model precaches\n");
			return;
		}
		strcpy (model_precache[nummodels], str);
		Mod_TouchModel (str);
	}

// precache sounds
	memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
	for (numsounds=1 ; ; numsounds++)
	{
		str = MSG_ReadString ();
		if (!str[0])
			break;
		if (numsounds==MAX_SOUNDS)
		{
			Con_Printf ("Server sent too many sound precaches\n");
			return;
		}
		strcpy (sound_precache[numsounds], str);
		S_TouchSound (str);
	}

//
// now we try to load everything else until a cache allocation fails
//

	if (precache.value)
	{
		total_loading_size = nummodels + numsounds;
		current_loading_size = 1;
		loading_stage = 2;
	}

	//always precache the world!!!
	cl.model_precache[1] = Mod_ForName (model_precache[1], false);
	for (i=2 ; i<nummodels ; i++)
	{
		if (precache.value)
		{
			cl.model_precache[i] = Mod_ForName (model_precache[i], false);
			current_loading_size++;
			//SCR_DrawLoading();
			//D_ShowLoadingSize();
		}
		else
			cl.model_precache[i] = (model_t *)Mod_FindName (model_precache[i]);

		if (cl.model_precache[i] == NULL)
		{
			Con_Printf("Model %s not found\n", model_precache[i]);
			return;
		}
		CL_KeepaliveMessage ();
	}

	player_models[0] = (model_t *)Mod_FindName ("models/paladin.mdl");
	player_models[1] = (model_t *)Mod_FindName ("models/crusader.mdl");
	player_models[2] = (model_t *)Mod_FindName ("models/necro.mdl");
	player_models[3] = (model_t *)Mod_FindName ("models/assassin.mdl");
#ifndef NO_PRAVEUS
	player_models[4] = (model_t *)Mod_FindName ("models/succubus.mdl");
#endif
	S_BeginPrecaching ();
	for (i=1 ; i<numsounds ; i++)
	{
		cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
		if (precache.value)
		{
			current_loading_size++;
			//SCR_DrawLoading();
			//D_ShowLoadingSize();
		}

		CL_KeepaliveMessage ();
	}
	S_EndPrecaching ();

	total_loading_size = 0;
	loading_stage = 0;


// local state
	cl_entities[0].model = cl.worldmodel = cl.model_precache[1];
	
	R_NewMap ();

	puzzle_strings = (char *)COM_LoadHunkFile ("puzzles.txt");

	Hunk_Check ();		// make sure nothing is hurt
	
	noclip_anglehack = false;		// noclip is turned off at start	
	
}
示例#6
0
/*
==================
CL_ParseServerInfo
==================
*/
void CL_ParseServerInfo (void)
{
	char	*str, tempname[MAX_QPATH];;
	int		i;
	int		nummodels, numsounds;
	char	model_precache[MAX_MODELS][MAX_QPATH];
	char	sound_precache[MAX_SOUNDS][MAX_QPATH];
	extern qboolean r_loadq3player;

	//void R_PreMapLoad (char *);

	char	mapname[MAX_QPATH];
	
	Con_DPrintf ("Serverinfo packet received.\n");
//
// wipe the client_state_t struct
//
	CL_ClearState ();

// parse protocol version number
	i = MSG_ReadLong ();
	if (i != PROTOCOL_VERSION)
	{
		Con_Printf ("Server returned version %i, not %i", i, PROTOCOL_VERSION);
		return;
	}

// parse maxclients
	cl.maxclients = MSG_ReadByte ();
	if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
	{
		Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
		return;
	}
	cl.scores = Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores");

// parse gametype
	cl.gametype = MSG_ReadByte ();

// parse signon message
	str = MSG_ReadString ();
	strncpy (cl.levelname, str, sizeof(cl.levelname)-1);

// seperate the printfs so the server message can have a color
	Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n");
	Con_Printf ("%c%s\n", 2, str);

//
// first we go through and touch all of the precache data that still
// happens to be in the cache, so precaching something else doesn't
// needlessly purge it
//

// precache models
	for (i=0 ; i<NUM_MODELINDEX ; i++)
		cl_modelindex[i] = -1;

// precache models
	memset (cl.model_precache, 0, sizeof(cl.model_precache));
	for (nummodels=1 ; ; nummodels++)
	{
		str = MSG_ReadString ();

		if (!str[0])
			break;

		if (nummodels==MAX_MODELS)
		{
			Con_Printf ("Server sent too many model precaches\n");
			return;
     	}

		if (r_loadq3models.value)
		{
			if (!strcmp(str, "progs/player.mdl") &&
			    FS_FindFile("progs/player/head.md3") &&
			    FS_FindFile("progs/player/upper.md3") &&
			    FS_FindFile("progs/player/lower.md3"))
			{
				Q_strncpyz (tempname, "progs/player/lower.md3", MAX_QPATH);
				str = tempname;
				cl_modelindex[mi_player] = nummodels;
				r_loadq3player = true;
			}
			else
			{
				COM_StripExtension (str, tempname);
				strcat (tempname, ".md3");

				if (FS_FindFile(tempname))
					str = tempname;
			}
		}

        Q_strncpyz (model_precache[nummodels], str, sizeof(model_precache[nummodels]));

		Mod_TouchModel (str);

		if (!strcmp(model_precache[nummodels], "progs/player.mdl"))
			cl_modelindex[mi_player] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/eyes.mdl"))
			cl_modelindex[mi_eyes] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/missile.mdl"))
			cl_modelindex[mi_rocket] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/grenade.mdl"))
			cl_modelindex[mi_grenade] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/flame.mdl"))
			cl_modelindex[mi_flame1] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/flame2.mdl"))
			cl_modelindex[mi_flame2] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/s_expl.spr"))
			cl_modelindex[mi_explo1] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/s_explod.spr"))
			cl_modelindex[mi_explo2] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/s_bubble.spr"))
			cl_modelindex[mi_bubble] = nummodels;

		else if (!strcmp(model_precache[nummodels], "progs/gib1.mdl"))
			cl_modelindex[mi_gib1] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/gib2.mdl"))
			cl_modelindex[mi_gib2] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/gib3.mdl"))
			cl_modelindex[mi_gib3] = nummodels;

		else if (!strcmp(model_precache[nummodels], "progs/fish.mdl"))
			cl_modelindex[mi_fish] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/dog.mdl"))
			cl_modelindex[mi_dog] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/soldier.mdl"))
			cl_modelindex[mi_soldier] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/enforcer.mdl"))
			cl_modelindex[mi_enforcer] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/knight.mdl"))
			cl_modelindex[mi_knight] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/hknight.mdl"))
			cl_modelindex[mi_hknight] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/wizard.mdl"))
			cl_modelindex[mi_scrag] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/ogre.mdl"))
			cl_modelindex[mi_ogre] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/demon.mdl"))
			cl_modelindex[mi_fiend] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/shalrath.mdl"))
			cl_modelindex[mi_vore] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/shambler.mdl"))
			cl_modelindex[mi_shambler] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/h_dog.mdl"))
			cl_modelindex[mi_h_dog] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/h_guard.mdl"))
			cl_modelindex[mi_h_soldier] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/h_mega.mdl"))
			cl_modelindex[mi_h_enforcer] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/h_knight.mdl"))
			cl_modelindex[mi_h_knight] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/h_hknight.mdl"))
			cl_modelindex[mi_h_hknight] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/h_wizard.mdl"))
			cl_modelindex[mi_h_scrag] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/h_ogre.mdl"))
			cl_modelindex[mi_h_ogre] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/h_demon.mdl"))
			cl_modelindex[mi_h_fiend] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/h_shal.mdl"))
			cl_modelindex[mi_h_vore] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/h_shams.mdl"))
			cl_modelindex[mi_h_shambler] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/h_zombie.mdl"))
			cl_modelindex[mi_h_zombie] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/h_player.mdl"))
			cl_modelindex[mi_h_player] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/w_s_key.mdl"))
			cl_modelindex[mi_w_s_key] = nummodels;
		else if (!strcmp(model_precache[nummodels], "progs/w_g_key.mdl"))
			cl_modelindex[mi_w_g_key] = nummodels;
  }

    if (r_loadq3player)
	{
		if (nummodels + 1 >= MAX_MODELS)
		{
			Con_Printf ("Server sent too many model precaches -> can't load Q3 player model\n");
			Q_strncpyz (model_precache[cl_modelindex[mi_player]], cl_modelnames[mi_player], sizeof(model_precache[cl_modelindex[mi_player]]));
		}
		else
		{
			Q_strncpyz (model_precache[nummodels], "progs/player/upper.md3", sizeof(model_precache[nummodels]));
			cl_modelindex[mi_q3torso] = nummodels++;
			Q_strncpyz (model_precache[nummodels], "progs/player/head.md3", sizeof(model_precache[nummodels]));
			cl_modelindex[mi_q3head] = nummodels++;
		}
	}

// precache sounds
	memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
	for (numsounds=1 ; ; numsounds++)
	{
		str = MSG_ReadString ();
		if (!str[0])
			break;
		if (numsounds==MAX_SOUNDS)
		{
			Con_Printf ("Server sent too many sound precaches\n");
			return;
		}
		strcpy (sound_precache[numsounds], str);
		S_TouchSound (str);
	}

    //COM_StripExtension (COM_SkipPath(model_precache[1]), mapname);
	//R_PreMapLoad (mapname);

//
// now we try to load everything else until a cache allocation fails
//
      
    loading_num_step[loading_level] = nummodels + numsounds;
    sprintf(loading_name[loading_level], "Models and Sounds");

	for (i=1 ; i<nummodels ; i++)
	{
		cl.model_precache[i] = Mod_ForName (model_precache[i], false);
		if (cl.model_precache[i] == NULL)
		{
			Con_Printf("Model %s not found\n", model_precache[i]);
			return;
		}
		CL_KeepaliveMessage ();
	    loading_cur_step[loading_level]++;
	    SCR_UpdateScreen ();
	}

	// load the extra "no-flamed-torch" model
	cl.model_precache[nummodels] = Mod_ForName ("progs/flame0.mdl", false);
	cl_modelindex[mi_flame0] = nummodels++;

	cl.model_precache[nummodels] = Mod_ForName ("progs/flag.mdl", false);
    cl_modelindex[mi_flag] = nummodels++;

	S_BeginPrecaching ();
	for (i=1 ; i<numsounds ; i++)
	{
		cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
		CL_KeepaliveMessage ();
	    loading_cur_step[loading_level]++;
	    SCR_UpdateScreen ();
    }
	S_EndPrecaching ();

   	Clear_LoadingFill ();

// local state
	cl_entities[0].model = cl.worldmodel = cl.model_precache[1];
	
	R_NewMap ();

	Hunk_Check ();		// make sure nothing is hurt
	
	noclip_anglehack = false;		// noclip is turned off at start	
}