Beispiel #1
0
/*
=================
CG_Say
=================
*/
static void CG_Say( const char *name, int clientNum, saymode_t mode, const char *text )
{
	char prefix[ 21 ] = "";
	char *ignore = "";
	char *location = "";
	char color;
	char *maybeColon;

	if ( clientNum >= 0 && clientNum < MAX_CLIENTS )
	{
		clientInfo_t *ci = &cgs.clientinfo[ clientNum ];
		char         *tcolor = S_COLOR_WHITE;

		name = ci->name;

		if ( ci->team == TEAM_ALIENS )
		{
			tcolor = S_COLOR_RED;
		}
		else if ( ci->team == TEAM_HUMANS )
		{
			tcolor = S_COLOR_CYAN;
		}

		if ( cg_chatTeamPrefix.integer )
		{
			Com_sprintf( prefix, sizeof( prefix ), "[%s%c" S_COLOR_WHITE "] ",
			             tcolor, toupper( * ( BG_TeamName( ci->team ) ) ) );
		}

		if ( Com_ClientListContains( &cgs.ignoreList, clientNum ) )
		{
			ignore = "[skipnotify]";
		}

		if ( ( mode == SAY_TEAM || mode == SAY_AREA ) &&
		     cg.snap->ps.pm_type != PM_INTERMISSION )
		{
			int locationNum;

			if ( clientNum == cg.snap->ps.clientNum )
			{
				centity_t *locent;

				locent = CG_GetPlayerLocation();

				if ( locent )
				{
					locationNum = locent->currentState.generic1;
				}
				else
				{
					locationNum = 0;
				}
			}
			else
			{
				locationNum = ci->location;
			}

			if ( locationNum > 0 && locationNum < MAX_LOCATIONS )
			{
				const char *s = CG_ConfigString( CS_LOCATIONS + locationNum );

				if ( *s )
				{
					location = va( " (%s" S_COLOR_WHITE ")", s );
				}
			}
		}
	}
	else if ( name )
	{
		Q_strcat( prefix, sizeof( prefix ), "[ADMIN]" );
	}
	else
	{
		name = "console";
	}

	// IRC-like /me parsing
	if ( mode != SAY_RAW && Q_stricmpn( text, "/me ", 4 ) == 0 )
	{
		text += 4;
		Q_strcat( prefix, sizeof( prefix ), "* " );
		maybeColon = "";
	}
	else
	{
		maybeColon = ":";
	}

	color = '0' + UI_GetChatColour( mode, cgs.clientinfo[ clientNum ].team );

	switch ( mode )
	{
		case SAY_ALL:
			// might already be ignored but in that case no harm is done
			if ( cg_teamChatsOnly.integer )
			{
				ignore = "[skipnotify]";
			}

		case SAY_ALL_ADMIN:
			CG_Printf(  "%s%s%s^7%s ^%c%s\n",
			           ignore, prefix, name, maybeColon, color, text );
			break;

		case SAY_TEAM:
			CG_Printf( "%s%s(%s^7)%s%s ^%c%s\n",
			           ignore, prefix, name, location, maybeColon, color, text );
			break;

		case SAY_ADMINS:
		case SAY_ADMINS_PUBLIC:
			CG_Printf( "%s%s%s%s^7%s ^%c%s\n",
			           ignore, prefix,
			           ( mode == SAY_ADMINS ) ? "[ADMIN]" : "[PLAYER]",
			           name, maybeColon, color, text );
			break;

		case SAY_AREA:
		case SAY_AREA_TEAM:
			CG_Printf( "%s%s<%s^7>%s%s ^%c%s\n",
			           ignore, prefix, name, location, maybeColon, color, text );
			break;

		case SAY_PRIVMSG:
		case SAY_TPRIVMSG:
			CG_Printf( "%s%s[%s^7 -> %s^7]%s ^%c%s\n",
			           ignore, prefix, name, cgs.clientinfo[ cg.clientNum ].name,
			           maybeColon, color, text );

			if ( !ignore[ 0 ] )
			{
				CG_CenterPrint( va( "^%cPrivate message from: " S_COLOR_WHITE "%s",
				                    color, name ), 200, GIANTCHAR_WIDTH * 4 );

				if ( clientNum < 0 || clientNum >= MAX_CLIENTS )
				{
					clientNum = cg.clientNum;
				}

				CG_Printf(_( ">> to reply, say: /m %d [your message] <<\n"), clientNum );
			}

			break;

		case SAY_RAW:
			CG_Printf( "%s\n", text );
			break;

		case SAY_DEFAULT:
		default:
			break;
	}

	switch ( mode )
	{
		case SAY_TEAM:
		case SAY_AREA:
		case SAY_TPRIVMSG:
			if ( cg.snap->ps.stats[ STAT_TEAM ] == TEAM_ALIENS )
			{
				trap_S_StartLocalSound( cgs.media.alienTalkSound, CHAN_LOCAL_SOUND );
				break;
			}
			else if ( cg.snap->ps.stats[ STAT_TEAM ] == TEAM_HUMANS )
			{
				trap_S_StartLocalSound( cgs.media.humanTalkSound, CHAN_LOCAL_SOUND );
				break;
			}

		default:
			trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
	}
}
Beispiel #2
0
/*
==================
SV_Map_f

Restart the server on a different map
==================
*/
static void SV_Map_f( void ) {
	char		*cmd;
	char		*map;
	qboolean	killBots, cheat;
	char		expanded[MAX_QPATH];
	char		mapname[MAX_QPATH];

	map = Cmd_Argv(1);
	if ( !map ) {
		return;
	}

	// make sure the level exists before trying to change, so that
	// a typo at the server console won't end the game
	Com_sprintf (expanded, sizeof(expanded), "maps/%s.bsp", map);
	if ( FS_ReadFile (expanded, NULL) == -1 ) {
		Com_Printf ("Can't find map %s\n", expanded);
		return;
	}

	// force latched values to get set
	Cvar_Get ("g_gametype", "0", CVAR_SERVERINFO | CVAR_USERINFO | CVAR_LATCH );

	cmd = Cmd_Argv(0);
	if( Q_stricmpn( cmd, "sp", 2 ) == 0 ) {
		Cvar_SetValue( "g_gametype", GT_SINGLE_PLAYER );
		Cvar_SetValue( "g_doWarmup", 0 );
		// may not set sv_maxclients directly, always set latched
		Cvar_SetLatched( "sv_maxclients", "8" );
		cmd += 2;
		if (!Q_stricmp( cmd, "devmap" ) ) {
			cheat = qtrue;
		} else {
			cheat = qfalse;
		}
		killBots = qtrue;
	}
	else {
		if ( !Q_stricmp( cmd, "devmap" ) ) {
			cheat = qtrue;
			killBots = qtrue;
		} else {
			cheat = qfalse;
			killBots = qfalse;
		}
		if( sv_gametype->integer == GT_SINGLE_PLAYER ) {
			Cvar_SetValue( "g_gametype", GT_FFA );
		}
	}

	// save the map name here cause on a map restart we reload the q3config.cfg
	// and thus nuke the arguments of the map command
	Q_strncpyz(mapname, map, sizeof(mapname));

	// start up the map
	SV_SpawnServer( mapname, killBots );

	// set the cheat value
	// if the level was started with "map <levelname>", then
	// cheats will not be allowed.  If started with "devmap <levelname>"
	// then cheats will be allowed
	if ( cheat ) {
		Cvar_Set( "sv_cheats", "1" );
	} else {
		Cvar_Set( "sv_cheats", "0" );
	}
}
qboolean HTTPCreateWebadminMessage(ftRequest_t* request, msg_t* msg, char* sessionkey, httpPostVals_t* values)
{
	byte *buf;
	char qpath[MAX_QPATH];
	int len;
	const char *session;
	char banmsg[1024];

	buf = NULL;

	MSG_Init(msg, buf, 0);
	Com_Printf("URL: %s\n", request->url);
	if(!Q_strncmp(request->url, "/files", 6))
	{
		if(request->url[6] != '/' || request->url[7] == '\0')
		{
			return qfalse;
		}
		Com_sprintf(qpath, sizeof(qpath), "/webadmindata/%s", &request->url[7]);

		if(strstr(qpath, "..") != NULL || strstr(qpath, "::") != NULL)
		{
			return qfalse;
		}
		len = FS_ReadFile(qpath, (void**)&buf);

		if(len < 0)
		{
			return qfalse;
		}
		msg->data = buf;
		msg->cursize = len;
		msg->maxsize = len;
		FS_FreeFileKeepBuf( );
		return qtrue;
	}

	len = 0x20000;

	buf = Z_Malloc(len);
	if(buf == NULL)
	{
		return qfalse;
	}

	msg->data = buf;
	msg->cursize = 0;
	msg->maxsize = len;

	if (Q_stricmpn(request->url, "/webadmin", 9))
	{
		Webadmin_BuildMessage(msg, NULL, qfalse, NULL ,request->url, values);
		return qtrue;
	}

	qboolean invalidlogin = qfalse;
	const char* username = NULL;
	const char* password = NULL;


	if(SV_PlayerBannedByip(&request->remote, banmsg, sizeof(banmsg)))
	{
		Webadmin_BuildMessage(msg, NULL, qfalse, banmsg, request->url, values);
		return qtrue;
	}

	username = Auth_FindSessionID(sessionkey);

	if(username == NULL)
	{

		username = HTTP_GetFormDataItem(values, "username");
		password = HTTP_GetFormDataItem(values, "password");

		if(username[0] && password[0])
		{
			session = Auth_GetSessionId(username, password);
			if(session == NULL)
			{
				Com_Printf("^1Invalid login\n");
				invalidlogin = qtrue;
				SV_PlayerAddBanByip(&request->remote, "Invalid login attempt. You have to wait 20 seconds", Com_GetRealtime() + 10);
				username = NULL;
			}else {
				Com_Printf("^2Successful login with username: %s\n", username);
			}


		}else {
			Com_Printf("No login!\n");
			session = NULL;
			username = NULL;
		}

		/* not longer than 127 or overflow */
		if(session != NULL)
		{
			strcpy(sessionkey, session);
		}
	}else{
		Com_Printf("Already logged in as: %s\n", username);
	}

	Webadmin_BuildMessage(msg, username, invalidlogin, NULL, request->url, values);

	return qtrue;
}
Beispiel #4
0
static void GLimp_InitExtensions( void )
{
	if ( !r_allowExtensions->integer )
	{
		Com_Printf ("*** IGNORING OPENGL EXTENSIONS ***\n" );
		g_bDynamicGlowSupported = false;
		ri->Cvar_Set( "r_DynamicGlow","0" );
		return;
	}

	Com_Printf ("Initializing OpenGL extensions\n" );

	// Select our tc scheme
	GLW_InitTextureCompression();

	// GL_EXT_texture_env_add
	glConfig.textureEnvAddAvailable = qfalse;
	if ( GL_CheckForExtension( "EXT_texture_env_add" ) )
	{
		if ( r_ext_texture_env_add->integer )
		{
			glConfig.textureEnvAddAvailable = qtrue;
			Com_Printf ("...using GL_EXT_texture_env_add\n" );
		}
		else
		{
			glConfig.textureEnvAddAvailable = qfalse;
			Com_Printf ("...ignoring GL_EXT_texture_env_add\n" );
		}
	}
	else
	{
		Com_Printf ("...GL_EXT_texture_env_add not found\n" );
	}

	// GL_EXT_texture_filter_anisotropic
	glConfig.maxTextureFilterAnisotropy = 0;
	if ( GL_CheckForExtension( "EXT_texture_filter_anisotropic" ) )
	{
#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF	//can't include glext.h here ... sigh
		qglGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glConfig.maxTextureFilterAnisotropy );
		Com_Printf ("...GL_EXT_texture_filter_anisotropic available\n" );

		if ( r_ext_texture_filter_anisotropic->integer > 1 )
		{
			Com_Printf ("...using GL_EXT_texture_filter_anisotropic\n" );
		}
		else
		{
			Com_Printf ("...ignoring GL_EXT_texture_filter_anisotropic\n" );
		}
		ri->Cvar_SetValue( "r_ext_texture_filter_anisotropic_avail", glConfig.maxTextureFilterAnisotropy );
		if ( r_ext_texture_filter_anisotropic->value > glConfig.maxTextureFilterAnisotropy )
		{
			ri->Cvar_SetValue( "r_ext_texture_filter_anisotropic_avail", glConfig.maxTextureFilterAnisotropy );
		}
	}
	else
	{
		Com_Printf ("...GL_EXT_texture_filter_anisotropic not found\n" );
		ri->Cvar_Set( "r_ext_texture_filter_anisotropic_avail", "0" );
	}

	// GL_EXT_clamp_to_edge
	glConfig.clampToEdgeAvailable = qtrue;
	Com_Printf ("...using GL_EXT_texture_edge_clamp\n" );

	// GL_ARB_multitexture
	qglMultiTexCoord2fARB = NULL;
	qglActiveTextureARB = NULL;
	qglClientActiveTextureARB = NULL;
	if ( GL_CheckForExtension( "GL_ARB_multitexture" ) )
	{
		if ( r_ext_multitexture->integer )
		{
			qglMultiTexCoord2fARB = ( PFNGLMULTITEXCOORD2FARBPROC ) SDL_GL_GetProcAddress( "glMultiTexCoord2fARB" );
			qglActiveTextureARB = ( PFNGLACTIVETEXTUREARBPROC ) SDL_GL_GetProcAddress( "glActiveTextureARB" );
			qglClientActiveTextureARB = ( PFNGLCLIENTACTIVETEXTUREARBPROC ) SDL_GL_GetProcAddress( "glClientActiveTextureARB" );

			if ( qglActiveTextureARB )
			{
				qglGetIntegerv( GL_MAX_ACTIVE_TEXTURES_ARB, &glConfig.maxActiveTextures );

				if ( glConfig.maxActiveTextures > 1 )
				{
					Com_Printf ("...using GL_ARB_multitexture\n" );
				}
				else
				{
					qglMultiTexCoord2fARB = NULL;
					qglActiveTextureARB = NULL;
					qglClientActiveTextureARB = NULL;
					Com_Printf ("...not using GL_ARB_multitexture, < 2 texture units\n" );
				}
			}
		}
		else
		{
			Com_Printf ("...ignoring GL_ARB_multitexture\n" );
		}
	}
	else
	{
		Com_Printf ("...GL_ARB_multitexture not found\n" );
	}

	// GL_EXT_compiled_vertex_array
	qglLockArraysEXT = NULL;
	qglUnlockArraysEXT = NULL;
	if ( GL_CheckForExtension( "GL_EXT_compiled_vertex_array" ) )
	{
		if ( r_ext_compiled_vertex_array->integer )
		{
			Com_Printf ("...using GL_EXT_compiled_vertex_array\n" );
			qglLockArraysEXT = ( void ( APIENTRY * )( int, int ) ) SDL_GL_GetProcAddress( "glLockArraysEXT" );
			qglUnlockArraysEXT = ( void ( APIENTRY * )( void ) ) SDL_GL_GetProcAddress( "glUnlockArraysEXT" );
			if (!qglLockArraysEXT || !qglUnlockArraysEXT) {
				Com_Error (ERR_FATAL, "bad getprocaddress");
			}
		}
		else
		{
			Com_Printf ("...ignoring GL_EXT_compiled_vertex_array\n" );
		}
	}
	else
	{
		Com_Printf ("...GL_EXT_compiled_vertex_array not found\n" );
	}

	qglPointParameterfEXT = NULL;
	qglPointParameterfvEXT = NULL;

	//3d textures -rww
	qglTexImage3DEXT = NULL;
	qglTexSubImage3DEXT = NULL;

	if ( GL_CheckForExtension( "GL_EXT_point_parameters" ) )
	{
		if ( r_ext_compiled_vertex_array->integer )
		{
			Com_Printf ("...using GL_EXT_point_parameters\n" );
			qglPointParameterfEXT = ( void ( APIENTRY * )( GLenum, GLfloat) ) SDL_GL_GetProcAddress( "glPointParameterfEXT" );
			qglPointParameterfvEXT = ( void ( APIENTRY * )( GLenum, GLfloat *) ) SDL_GL_GetProcAddress( "glPointParameterfvEXT" );

			//3d textures -rww
			qglTexImage3DEXT = (void ( APIENTRY * ) (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *) ) SDL_GL_GetProcAddress( "glTexImage3DEXT" );
			qglTexSubImage3DEXT = (void ( APIENTRY * ) (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *) ) SDL_GL_GetProcAddress( "glTexSubImage3DEXT" );

			if (!qglPointParameterfEXT || !qglPointParameterfvEXT)
			{
				Com_Error (ERR_FATAL, "bad getprocaddress");
			}
		}
		else
		{
			Com_Printf ("...ignoring GL_EXT_point_parameters\n" );
		}
	}
	else
	{
		Com_Printf ("...GL_EXT_point_parameters not found\n" );
	}

	bool bNVRegisterCombiners = false;
	// Register Combiners.
	if ( GL_CheckForExtension( "GL_NV_register_combiners" ) )
	{
		// NOTE: This extension requires multitexture support (over 2 units).
		if ( glConfig.maxActiveTextures >= 2 )
		{
			bNVRegisterCombiners = true;
			// Register Combiners function pointer address load.	- AReis
			// NOTE: VV guys will _definetly_ not be able to use regcoms. Pixel Shaders are just as good though :-)
			// NOTE: Also, this is an nVidia specific extension (of course), so fragment shaders would serve the same purpose
			// if we needed some kind of fragment/pixel manipulation support.
			qglCombinerParameterfvNV = (PFNGLCOMBINERPARAMETERFVNVPROC)SDL_GL_GetProcAddress( "glCombinerParameterfvNV" );
			qglCombinerParameterivNV = (PFNGLCOMBINERPARAMETERIVNVPROC)SDL_GL_GetProcAddress( "glCombinerParameterivNV" );
			qglCombinerParameterfNV = (PFNGLCOMBINERPARAMETERFNVPROC)SDL_GL_GetProcAddress( "glCombinerParameterfNV" );
			qglCombinerParameteriNV = (PFNGLCOMBINERPARAMETERINVPROC)SDL_GL_GetProcAddress( "glCombinerParameteriNV" );
			qglCombinerInputNV = (PFNGLCOMBINERINPUTNVPROC)SDL_GL_GetProcAddress( "glCombinerInputNV" );
			qglCombinerOutputNV = (PFNGLCOMBINEROUTPUTNVPROC)SDL_GL_GetProcAddress( "glCombinerOutputNV" );
			qglFinalCombinerInputNV = (PFNGLFINALCOMBINERINPUTNVPROC)SDL_GL_GetProcAddress( "glFinalCombinerInputNV" );
			qglGetCombinerInputParameterfvNV	= (PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC)SDL_GL_GetProcAddress( "glGetCombinerInputParameterfvNV" );
			qglGetCombinerInputParameterivNV	= (PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC)SDL_GL_GetProcAddress( "glGetCombinerInputParameterivNV" );
			qglGetCombinerOutputParameterfvNV = (PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC)SDL_GL_GetProcAddress( "glGetCombinerOutputParameterfvNV" );
			qglGetCombinerOutputParameterivNV = (PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC)SDL_GL_GetProcAddress( "glGetCombinerOutputParameterivNV" );
			qglGetFinalCombinerInputParameterfvNV = (PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC)SDL_GL_GetProcAddress( "glGetFinalCombinerInputParameterfvNV" );
			qglGetFinalCombinerInputParameterivNV = (PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC)SDL_GL_GetProcAddress( "glGetFinalCombinerInputParameterivNV" );

			// Validate the functions we need.
			if ( !qglCombinerParameterfvNV || !qglCombinerParameterivNV || !qglCombinerParameterfNV || !qglCombinerParameteriNV || !qglCombinerInputNV ||
				 !qglCombinerOutputNV || !qglFinalCombinerInputNV || !qglGetCombinerInputParameterfvNV || !qglGetCombinerInputParameterivNV ||
				 !qglGetCombinerOutputParameterfvNV || !qglGetCombinerOutputParameterivNV || !qglGetFinalCombinerInputParameterfvNV || !qglGetFinalCombinerInputParameterivNV )
			{
				bNVRegisterCombiners = false;
				qglCombinerParameterfvNV = NULL;
				qglCombinerParameteriNV = NULL;
				Com_Printf ("...GL_NV_register_combiners failed\n" );
			}
		}
		else
		{
			bNVRegisterCombiners = false;
			Com_Printf ("...ignoring GL_NV_register_combiners\n" );
		}
	}
	else
	{
		bNVRegisterCombiners = false;
		Com_Printf ("...GL_NV_register_combiners not found\n" );
	}

	// NOTE: Vertex and Fragment Programs are very dependant on each other - this is actually a
	// good thing! So, just check to see which we support (one or the other) and load the shared
	// function pointers. ARB rocks!

	// Vertex Programs.
	bool bARBVertexProgram = false;
	if ( GL_CheckForExtension( "GL_ARB_vertex_program" ) )
	{
		bARBVertexProgram = true;
	}
	else
	{
		bARBVertexProgram = false;
		Com_Printf ("...GL_ARB_vertex_program not found\n" );
	}

	// Fragment Programs.
	bool bARBFragmentProgram = false;
	if ( GL_CheckForExtension( "GL_ARB_fragment_program" ) )
	{
		bARBFragmentProgram = true;
	}
	else
	{
		bARBFragmentProgram = false;
		Com_Printf ("...GL_ARB_fragment_program not found\n" );
	}

	// If we support one or the other, load the shared function pointers.
	if ( bARBVertexProgram || bARBFragmentProgram )
	{
		qglProgramStringARB					= (PFNGLPROGRAMSTRINGARBPROC)  SDL_GL_GetProcAddress("glProgramStringARB");
		qglBindProgramARB					= (PFNGLBINDPROGRAMARBPROC)    SDL_GL_GetProcAddress("glBindProgramARB");
		qglDeleteProgramsARB				= (PFNGLDELETEPROGRAMSARBPROC) SDL_GL_GetProcAddress("glDeleteProgramsARB");
		qglGenProgramsARB					= (PFNGLGENPROGRAMSARBPROC)    SDL_GL_GetProcAddress("glGenProgramsARB");
		qglProgramEnvParameter4dARB			= (PFNGLPROGRAMENVPARAMETER4DARBPROC)    SDL_GL_GetProcAddress("glProgramEnvParameter4dARB");
		qglProgramEnvParameter4dvARB		= (PFNGLPROGRAMENVPARAMETER4DVARBPROC)   SDL_GL_GetProcAddress("glProgramEnvParameter4dvARB");
		qglProgramEnvParameter4fARB			= (PFNGLPROGRAMENVPARAMETER4FARBPROC)    SDL_GL_GetProcAddress("glProgramEnvParameter4fARB");
		qglProgramEnvParameter4fvARB		= (PFNGLPROGRAMENVPARAMETER4FVARBPROC)   SDL_GL_GetProcAddress("glProgramEnvParameter4fvARB");
		qglProgramLocalParameter4dARB		= (PFNGLPROGRAMLOCALPARAMETER4DARBPROC)  SDL_GL_GetProcAddress("glProgramLocalParameter4dARB");
		qglProgramLocalParameter4dvARB		= (PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) SDL_GL_GetProcAddress("glProgramLocalParameter4dvARB");
		qglProgramLocalParameter4fARB		= (PFNGLPROGRAMLOCALPARAMETER4FARBPROC)  SDL_GL_GetProcAddress("glProgramLocalParameter4fARB");
		qglProgramLocalParameter4fvARB		= (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) SDL_GL_GetProcAddress("glProgramLocalParameter4fvARB");
		qglGetProgramEnvParameterdvARB		= (PFNGLGETPROGRAMENVPARAMETERDVARBPROC) SDL_GL_GetProcAddress("glGetProgramEnvParameterdvARB");
		qglGetProgramEnvParameterfvARB		= (PFNGLGETPROGRAMENVPARAMETERFVARBPROC) SDL_GL_GetProcAddress("glGetProgramEnvParameterfvARB");
		qglGetProgramLocalParameterdvARB	= (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) SDL_GL_GetProcAddress("glGetProgramLocalParameterdvARB");
		qglGetProgramLocalParameterfvARB	= (PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) SDL_GL_GetProcAddress("glGetProgramLocalParameterfvARB");
		qglGetProgramivARB					= (PFNGLGETPROGRAMIVARBPROC)     SDL_GL_GetProcAddress("glGetProgramivARB");
		qglGetProgramStringARB				= (PFNGLGETPROGRAMSTRINGARBPROC) SDL_GL_GetProcAddress("glGetProgramStringARB");
		qglIsProgramARB						= (PFNGLISPROGRAMARBPROC)        SDL_GL_GetProcAddress("glIsProgramARB");

		// Validate the functions we need.
		if ( !qglProgramStringARB || !qglBindProgramARB || !qglDeleteProgramsARB || !qglGenProgramsARB ||
			 !qglProgramEnvParameter4dARB || !qglProgramEnvParameter4dvARB || !qglProgramEnvParameter4fARB ||
             !qglProgramEnvParameter4fvARB || !qglProgramLocalParameter4dARB || !qglProgramLocalParameter4dvARB ||
             !qglProgramLocalParameter4fARB || !qglProgramLocalParameter4fvARB || !qglGetProgramEnvParameterdvARB ||
             !qglGetProgramEnvParameterfvARB || !qglGetProgramLocalParameterdvARB || !qglGetProgramLocalParameterfvARB ||
             !qglGetProgramivARB || !qglGetProgramStringARB || !qglIsProgramARB )
		{
			bARBVertexProgram = false;
			bARBFragmentProgram = false;
			qglGenProgramsARB = NULL;	//clear ptrs that get checked
			qglProgramEnvParameter4fARB = NULL;
			Com_Printf ("...ignoring GL_ARB_vertex_program\n" );
			Com_Printf ("...ignoring GL_ARB_fragment_program\n" );
		}
	}

	// Figure out which texture rectangle extension to use.
	bool bTexRectSupported = false;
	if ( Q_stricmpn( glConfig.vendor_string, "ATI Technologies",16 )==0
		&& Q_stricmpn( glConfig.version_string, "1.3.3",5 )==0
		&& glConfig.version_string[5] < '9' ) //1.3.34 and 1.3.37 and 1.3.38 are broken for sure, 1.3.39 is not
	{
		g_bTextureRectangleHack = true;
	}

	if ( GL_CheckForExtension( "GL_NV_texture_rectangle" ) || GL_CheckForExtension( "GL_EXT_texture_rectangle" ) )
	{
		bTexRectSupported = true;
	}

	// Find out how many general combiners they have.
	#define GL_MAX_GENERAL_COMBINERS_NV       0x854D
	GLint iNumGeneralCombiners = 0;
	if(bNVRegisterCombiners)
		qglGetIntegerv( GL_MAX_GENERAL_COMBINERS_NV, &iNumGeneralCombiners );

	// Only allow dynamic glows/flares if they have the hardware
	if ( bTexRectSupported && bARBVertexProgram && qglActiveTextureARB && glConfig.maxActiveTextures >= 4 &&
		( ( bNVRegisterCombiners && iNumGeneralCombiners >= 2 ) || bARBFragmentProgram ) )
	{
		g_bDynamicGlowSupported = true;
		// this would overwrite any achived setting gwg
		// Cvar_Set( "r_DynamicGlow", "1" );
	}
	else
	{
		g_bDynamicGlowSupported = false;
		ri->Cvar_Set( "r_DynamicGlow","0" );
	}
}
Beispiel #5
0
/*
===============
PrintMatches

===============
*/
static void PrintMatches( const char *s ) {
	if ( !Q_stricmpn( s, shortestMatch, strlen( shortestMatch ) ) ) {
		Com_Printf( "    %s\n", s );
	}
}
Beispiel #6
0
/*
====================
RE_RegisterModel

Loads in a model for the given name

Zero will be returned if the model fails to load.
An entry will be retained for failed models as an
optimization to prevent disk rescanning if they are
asked for again.
====================
*/
qhandle_t RE_RegisterModel( const char *name )
{
	model_t   *mod;
	unsigned  *buffer;
	int       bufferLen = 0;
	int       lod;
	int       ident;
	qboolean  loaded;
	qhandle_t hModel;
	int       numLoaded;

	if ( !name || !name[ 0 ] )
	{
		ri.Printf( PRINT_ALL, "RE_RegisterModel: NULL name\n" );
		return 0;
	}

	if ( strlen( name ) >= MAX_QPATH )
	{
		Com_Printf( "Model name exceeds MAX_QPATH\n" );
		return 0;
	}

	// search the currently loaded models
	for ( hModel = 1; hModel < tr.numModels; hModel++ )
	{
		mod = tr.models[ hModel ];

		if ( !strcmp( mod->name, name ) )
		{
			if ( mod->type == MOD_BAD )
			{
				return 0;
			}

			return hModel;
		}
	}

	// allocate a new model_t
	if ( ( mod = R_AllocModel() ) == NULL )
	{
		ri.Printf( PRINT_WARNING, "RE_RegisterModel: R_AllocModel() failed for '%s'\n", name );
		return 0;
	}

	// only set the name after the model has been successfully loaded
	Q_strncpyz( mod->name, name, sizeof( mod->name ) );

	// make sure the render thread is stopped
	R_SyncRenderThread();

	mod->numLods = 0;

	// load the files
	numLoaded = 0;

#if defined( COMPAT_ET )

	if ( strstr( name, ".mds" ) || strstr( name, ".mdm" ) || strstr( name, ".mdx" ) || strstr( name, ".md5mesh" ) || strstr( name, ".psk" ) )
#else
	if ( strstr( name, ".md5mesh" ) || strstr( name, ".psk" ) )
#endif
	{
		// try loading skeletal file

		loaded = qfalse;
		bufferLen = ri.FS_ReadFile( name, ( void ** ) &buffer );

		if ( buffer )
		{
			loadmodel = mod;

			ident = LittleLong( * ( unsigned * ) buffer );
#if defined( COMPAT_ET )
#if 0

			if ( ident == MDS_IDENT )
			{
				loaded = R_LoadMDS( mod, buffer, name );
			}
			else
#endif
				if ( ident == MDM_IDENT )
				{
					loaded = R_LoadMDM( mod, buffer, name );
				}
				else if ( ident == MDX_IDENT )
				{
					loaded = R_LoadMDX( mod, buffer, name );
				}

#endif

#if defined( USE_REFENTITY_ANIMATIONSYSTEM )

			if ( !Q_stricmpn( ( const char * ) buffer, "MD5Version", 10 ) )
			{
				loaded = R_LoadMD5( mod, buffer, bufferLen, name );
			}
			else if ( !Q_stricmpn( ( const char * ) buffer, PSK_IDENTSTRING, PSK_IDENTLEN ) )
			{
				loaded = R_LoadPSK( mod, buffer, bufferLen, name );
			}

#endif
			ri.FS_FreeFile( buffer );
		}

		if ( loaded )
		{
			// make sure the VBO glState entries are save
			R_BindNullVBO();
			R_BindNullIBO();

			return mod->index;
		}
	}

	for ( lod = MD3_MAX_LODS - 1; lod >= 0; lod-- )
	{
		char filename[ 1024 ];

		strcpy( filename, name );

		if ( lod != 0 )
		{
			char namebuf[ 80 ];

			if ( strrchr( filename, '.' ) )
			{
				*strrchr( filename, '.' ) = 0;
			}

			sprintf( namebuf, "_%d.md3", lod );
			strcat( filename, namebuf );
		}

		filename[ strlen( filename ) - 1 ] = 'c';  // try MDC first
		ri.FS_ReadFile( filename, ( void ** ) &buffer );

		if ( !buffer )
		{
			filename[ strlen( filename ) - 1 ] = '3';  // try MD3 second
			ri.FS_ReadFile( filename, ( void ** ) &buffer );

			if ( !buffer )
			{
				continue;
			}
		}

		loadmodel = mod;

		ident = LittleLong( * ( unsigned * ) buffer );

		if ( ident == MD3_IDENT )
		{
			loaded = R_LoadMD3( mod, lod, buffer, bufferLen, name );
			ri.FS_FreeFile( buffer );
		}

#if defined( COMPAT_ET )
		else if ( ident == MDC_IDENT )
		{
			loaded = R_LoadMDC( mod, lod, buffer, bufferLen, name );
			ri.FS_FreeFile( buffer );
		}

#endif
		else
		{
			ri.FS_FreeFile( buffer );

			ri.Printf( PRINT_WARNING, "RE_RegisterModel: unknown fileid for %s\n", name );
			goto fail;
		}

		if ( !loaded )
		{
			if ( lod == 0 )
			{
				goto fail;
			}
			else
			{
				break;
			}
		}
		else
		{
			// make sure the VBO glState entries are save
			R_BindNullVBO();
			R_BindNullIBO();

			mod->numLods++;
			numLoaded++;
			// if we have a valid model and are biased
			// so that we won't see any higher detail ones,
			// stop loading them
//          if ( lod <= r_lodbias->integer ) {
//              break;
//          }
		}
	}

	// make sure the VBO glState entries are save
	R_BindNullVBO();
	R_BindNullIBO();

	if ( numLoaded )
	{
		// duplicate into higher lod spots that weren't
		// loaded, in case the user changes r_lodbias on the fly
		for ( lod--; lod >= 0; lod-- )
		{
			mod->numLods++;
			mod->mdv[ lod ] = mod->mdv[ lod + 1 ];
		}

		return mod->index;
	}

#ifdef _DEBUG
	else
	{
		ri.Printf( PRINT_WARNING, "couldn't load '%s'\n", name );
	}

#endif

fail:
	// we still keep the model_t around, so if the model name is asked for
	// again, we won't bother scanning the filesystem
	mod->type = MOD_BAD;

	// make sure the VBO glState entries are save
	R_BindNullVBO();
	R_BindNullIBO();

	return 0;
}
Beispiel #7
0
/*
=================
CG_ServerCommand

The string has been tokenized and can be retrieved with
Cmd_Argc() / Cmd_Argv()
=================
*/
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, "cp" ) ) {
		CG_CenterPrint( CG_Argv(1), SCREEN_HEIGHT * 0.30, BIGCHAR_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;
	}
	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, "loaddefered" ) ) {	// FIXME: spelled wrong, but not changing for demo
		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;
	}

	// CORKSCREW accuracy challenge

	if ( !strcmp( cmd, "drawchallengeinfo" ) ) {
		cg.encryptChallengeInfo = ( rand() % 9000 ) + 1000;
		cg.drawChallengeInfoScreenshotTime = 0;
		cg.drawChallengeInfo = qtrue;
		cg.drawChallengeInfoScreenshot = qtrue;
		cg.showScores = qtrue;
		return;
	}

	CG_Printf( "Unknown client game command: %s\n", cmd );
}
Beispiel #8
0
/*
==================
SV_Map_f

Restart the server on a different map
==================
*/
static void SV_Map_f( void ) {
	char        *cmd;
	char        *map;
	char mapname[MAX_QPATH];
	qboolean killBots, cheat;
	char expanded[MAX_QPATH];
	// TTimo: unused
//	int			savegameTime = -1;

	map = Cmd_Argv( 1 );
	if ( !map ) {
		return;
	}

	// make sure the level exists before trying to change, so that
	// a typo at the server console won't end the game
	Com_sprintf( expanded, sizeof( expanded ), "maps/%s.bsp", map );
	if ( FS_ReadFile( expanded, NULL ) == -1 ) {
		Com_Printf( "Can't find map %s\n", expanded );
		return;
	}

	Cvar_Set( "gamestate", va( "%i", GS_INITIALIZE ) );       // NERVE - SMF - reset gamestate on map/devmap
	Cvar_Set( "savegame_loading", "0" );  // make sure it's turned off

	Cvar_Set( "g_currentRound", "0" );            // NERVE - SMF - reset the current round
	Cvar_Set( "g_nextTimeLimit", "0" );           // NERVE - SMF - reset the next time limit

	// force latched values to get set
	// DHM - Nerve :: default to GT_WOLF
	Cvar_Get( "g_gametype", "5", CVAR_SERVERINFO | CVAR_USERINFO | CVAR_LATCH );

	// Rafael gameskill
	Cvar_Get( "g_gameskill", "3", CVAR_SERVERINFO | CVAR_LATCH );
	// done

	cmd = Cmd_Argv( 0 );
	if ( Q_stricmpn( cmd, "sp", 2 ) == 0 ) {
		Cvar_SetValue( "g_gametype", GT_SINGLE_PLAYER );
		Cvar_SetValue( "g_doWarmup", 0 );
		// may not set sv_maxclients directly, always set latched
#ifdef __MACOS__
		Cvar_SetLatched( "sv_maxclients", "16" ); //DAJ HOG
#else
		Cvar_SetLatched( "sv_maxclients", "32" ); // Ridah, modified this
#endif
		cmd += 2;
		killBots = qtrue;
		if ( !Q_stricmp( cmd, "devmap" ) ) {
			cheat = qtrue;
		} else {
			cheat = qfalse;
		}
	} else {
		if ( !Q_stricmp( cmd, "devmap" ) ) {
			cheat = qtrue;
			killBots = qtrue;
		} else {
			cheat = qfalse;
			killBots = qfalse;
		}
		if ( sv_gametype->integer == GT_SINGLE_PLAYER ) {
			Cvar_SetValue( "g_gametype", GT_FFA );
		}
	}

	// save the map name here cause on a map restart we reload the q3config.cfg
	// and thus nuke the arguments of the map command
	Q_strncpyz( mapname, map, sizeof( mapname ) );

	// start up the map
	SV_SpawnServer( mapname, killBots );

	// set the cheat value
	// if the level was started with "map <levelname>", then
	// cheats will not be allowed.  If started with "devmap <levelname>"
	// then cheats will be allowed
	if ( cheat ) {
		Cvar_Set( "sv_cheats", "1" );
	} else {
		Cvar_Set( "sv_cheats", "0" );
	}
}
/*
=================
CG_ServerCommand

The string has been tokenized and can be retrieved with
Cmd_Argc() / Cmd_Argv()
=================
*/
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, "cp" ) ) {
		CG_CenterPrint( CG_Argv(1), SCREEN_HEIGHT * 0.30, BIGCHAR_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 ) {
                        if( cg_chatBeep.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" ) ) {
                if( cg_teamChatBeep.integer )
                        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;
	}
	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, "accs" ) ) {
                CG_ParseAccuracy();
                return;
        }


	if ( !strcmp( cmd, "ddtaken" ) ) {
		CG_ParseDDtimetaken();
		return;
	}

	if ( !strcmp( cmd, "dompointnames" ) ) {
		CG_ParseDomPointNames();
		return;
	}

	if ( !strcmp( cmd, "domStatus" ) ) {
		CG_ParseDomStatus();
		return;
	}

	if ( !strcmp( cmd, "elimination" ) ) {
		CG_ParseElimination();
		return;
	}

	if ( !strcmp( cmd, "mappage" ) ) {
		CG_ParseMappage();
		return;
	}

	if ( !strcmp( cmd, "attackingteam" ) ) {
		CG_ParseAttackingTeam();
		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)
		{
			char shader1[MAX_QPATH];
			char shader2[MAX_QPATH];
			char shader3[MAX_QPATH];

			Q_strncpyz(shader1, CG_Argv(1), sizeof(shader1));
			Q_strncpyz(shader2, CG_Argv(2), sizeof(shader2));
			Q_strncpyz(shader3, CG_Argv(3), sizeof(shader3));

			trap_R_RemapShader(shader1, shader2, shader3);
		}
		
		return;
	}

	// loaddeferred can be both a servercmd and a consolecmd
	if ( !strcmp( cmd, "loaddefered" ) ) {	// FIXME: spelled wrong, but not changing for demo
		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;
	}

	// challenge completed is determened by the server. A client should consider this message valid:
	if ( !strcmp( cmd, "ch" ) ) {
		CG_ParseChallenge();
		return;
	}
        
        if ( !strcmp (cmd, "oh") ) {
            CG_ParseObeliskHealth();
            return;
        }

        if ( !strcmp( cmd, "respawn" ) ) {
		CG_ParseRespawnTime();
		return;
	}

        if ( !strcmp( cmd, "team" ) ) {
		CG_ParseTeam();
		return;
	}

        if ( !strcmp( cmd, "customvotes" ) ) {
            char infoString[1024];
            int i;
            //TODO: Create a ParseCustomvotes function
            memset(&infoString,0,sizeof(infoString));
            for(i=1;i<=12;i++) {
                Q_strcat(infoString,sizeof(infoString),CG_Argv( i ));
                Q_strcat(infoString,sizeof(infoString)," ");
            }
            trap_Cvar_Set("cg_vote_custom_commands",infoString);
		return;
	}

	CG_Printf( "Unknown client game command: %s\n", cmd );
}
Beispiel #10
0
qboolean WP_BreakSaber( gentity_t *ent, const char *surfName, saberType_t saberType )
{//Make sure there *is* one specified and not using dualSabers
	if ( ent == NULL || ent->client == NULL )
	{//invalid ent or client
		return qfalse;
	}

	if ( ent->s.number < MAX_CLIENTS )
	{//player
		//if ( g_spskill->integer < 3 )
		{//only on the hardest level?
			//FIXME: add a cvar?
			return qfalse;
		}
	}

	if ( ent->health <= 0 )
	{//not if they're dead
		return qfalse;
	}

	if ( ent->client->ps.weapon != WP_SABER )
	{//not holding saber
		return qfalse;
	}

	if ( ent->client->ps.dualSabers )
	{//FIXME: handle this?
		return qfalse;
	}

	if ( !ent->client->ps.saber[0].brokenSaber1 ) 
	{//not breakable into another type of saber
		return qfalse;
	}

	if ( PM_SaberInStart( ent->client->ps.saberMove ) //in a start
		|| PM_SaberInTransition( ent->client->ps.saberMove ) //in a transition
		|| PM_SaberInAttack( ent->client->ps.saberMove ) )//in an attack
	{//don't break when in the middle of an attack
		return qfalse;
	}

	if ( Q_stricmpn( "w_", surfName, 2 ) 
		&& Q_stricmpn( "saber_", surfName, 6 ) //hack because using mod-community made saber
		&& Q_stricmp( "cylinder01", surfName ) )//hack because using mod-community made saber
	{//didn't hit my weapon
		return qfalse;
	}

	//Sith Sword should ALWAYS do this
	if ( saberType != SABER_SITH_SWORD && Q_irand( 0, 50 ) )//&& Q_irand( 0, 10 ) )
	{//10% chance - FIXME: extern this, too?
		return qfalse;
	}

	//break it
	char	*replacementSaber1 = G_NewString( ent->client->ps.saber[0].brokenSaber1 );
	char	*replacementSaber2 = G_NewString( ent->client->ps.saber[0].brokenSaber2 );
	int		i, originalNumBlades = ent->client->ps.saber[0].numBlades;
	qboolean	broken = qfalse;
	saber_colors_t	colors[MAX_BLADES];

	//store the colors
	for ( i = 0; i < MAX_BLADES; i++ )
	{
		colors[i] = ent->client->ps.saber[0].blade[i].color;
	}

	//FIXME: chance of dropping the right-hand one?  Based on damage, or...?
	//FIXME: sound & effect when this happens, and send them into a broken parry?

	//remove saber[0], replace with replacementSaber1
	if ( replacementSaber1 )
	{
		WP_RemoveSaber( ent, 0 );
		WP_SetSaber( ent, 0, replacementSaber1 );
		for ( i = 0; i < ent->client->ps.saber[0].numBlades; i++ )
		{
			ent->client->ps.saber[0].blade[i].color = colors[i];
		}
		broken = qtrue;
		//change my saberent's model and skin to match my new right-hand saber
		WP_SetSaberEntModelSkin( ent, &g_entities[ent->client->ps.saberEntityNum] );
	}

	if ( originalNumBlades <= 1 ) 
	{//nothing to split off
		//FIXME: handle this?
	}
	else
	{
		//remove saber[1], replace with replacementSaber2
		if ( replacementSaber2 )
		{//FIXME: 25% chance that it just breaks - just spawn the second saber piece and toss it away immediately, can't be picked up.
			//shouldn't be one in this hand, but just in case, remove it
			WP_RemoveSaber( ent, 1 );
			WP_SetSaber( ent, 1, replacementSaber2 );

			//put the remainder of the original saber's blade colors onto this saber's blade(s)
			for ( i = ent->client->ps.saber[0].numBlades; i < MAX_BLADES; i++ )
			{
				ent->client->ps.saber[1].blade[i-ent->client->ps.saber[0].numBlades].color = colors[i];
			}
			broken = qtrue;
		}
	}
	return broken;
}
/*
==================
SV_Map_f

Restart the server on a different map
==================
*/
static void SV_Map_f(void) {

    char      *cmd;
    char      *searchmap;
    char      mapname[MAX_QPATH];
    qboolean  killBots, cheat;

    if (Cmd_Argc() < 2) {
        return;
    }

    searchmap = SV_GetMapSoundingLike(Cmd_Argv(1));
    if (!searchmap) {
        return;
    }

    // force latched values to get set
    Cvar_Get ("g_gametype", "0", CVAR_SERVERINFO | CVAR_USERINFO | CVAR_LATCH);

    cmd = Cmd_Argv(0);
    if (Q_stricmpn(cmd, "sp", 2) == 0) {
        Cvar_SetValue("g_gametype", GT_SINGLE_PLAYER);
        Cvar_SetValue("g_doWarmup", 0);
        // may not set sv_maxclients directly, always set latched
        Cvar_SetLatched("sv_maxclients", "8");
        cmd += 2;
        cheat = qfalse;
        killBots = qtrue;
    }
    else {

        if (!Q_stricmp( cmd, "devmap") || !Q_stricmp(cmd, "spdevmap") ) {
            cheat = qtrue;
            killBots = qtrue;
        } else {
            cheat = qfalse;
            killBots = qfalse;
        }

        if (sv_gametype->integer == GT_SINGLE_PLAYER) {
            Cvar_SetValue("g_gametype", GT_FFA);
        }

    }

    // save the map name here cause on a map restart we reload the q3config.cfg
    // and thus nuke the arguments of the map command
    Q_strncpyz(mapname, searchmap, sizeof(mapname));

    // start up the map
    SV_SpawnServer(mapname, killBots);

    // set the cheat value
    // if the level was started with "map <levelname>", then
    // cheats will not be allowed.  If started with "devmap <levelname>"
    // then cheats will be allowed
    if (cheat) {
        Cvar_Set("sv_cheats", "1");
    } else {
        Cvar_Set("sv_cheats", "0");
    }

}
Beispiel #12
0
qboolean WP_SaberParseParms( const char *SaberName, saberInfo_t *saber, qboolean setColors ) 
{
	const char	*token;
	const char	*value;
	const char	*p;
	float	f;
	int		n;

	if ( !saber ) 
	{
		return qfalse;
	}
	
	//Set defaults so that, if it fails, there's at least something there
	WP_SaberSetDefaults( saber, setColors );

	if ( !SaberName || !SaberName[0] ) 
	{
		return qfalse;
	}

	saber->name = G_NewString( SaberName );
	//try to parse it out
	p = SaberParms;
	COM_BeginParseSession();

	// look for the right saber
	while ( p )
	{
		token = COM_ParseExt( &p, qtrue );
		if ( token[0] == 0 )
		{
			return qfalse;
		}

		if ( !Q_stricmp( token, SaberName ) ) 
		{
			break;
		}

		SkipBracedSection( &p );
	}
	if ( !p ) 
	{
		return qfalse;
	}

	if ( G_ParseLiteral( &p, "{" ) ) 
	{
		return qfalse;
	}
		
	// parse the saber info block
	while ( 1 ) 
	{
		token = COM_ParseExt( &p, qtrue );
		if ( !token[0] ) 
		{
			gi.Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s'\n", SaberName );
			return qfalse;
		}

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

		//saber fullName
		if ( !Q_stricmp( token, "name" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->fullName = G_NewString( value );
			continue;
		}

		//saber type
		if ( !Q_stricmp( token, "saberType" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			int saberType = GetIDForString( SaberTable, value );
			if ( saberType >= SABER_SINGLE && saberType <= NUM_SABERS )
			{
				saber->type = (saberType_t)saberType;
			}
			continue;
		}

		//saber hilt
		if ( !Q_stricmp( token, "saberModel" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->model = G_NewString( value );
			continue;
		}

		if ( !Q_stricmp( token, "customSkin" ) )
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->skin = G_NewString( value );
			continue;
		}

		//on sound
		if ( !Q_stricmp( token, "soundOn" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->soundOn = G_SoundIndex( G_NewString( value ) );
			continue;
		}

		//loop sound
		if ( !Q_stricmp( token, "soundLoop" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->soundLoop = G_SoundIndex( G_NewString( value ) );
			continue;
		}

		//off sound
		if ( !Q_stricmp( token, "soundOff" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->soundOff = G_SoundIndex( G_NewString( value ) );
			continue;
		}

		if ( !Q_stricmp( token, "numBlades" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			if ( n < 1 || n >= MAX_BLADES )
			{
				G_Error( "WP_SaberParseParms: saber %s has illegal number of blades (%d) max: %d", SaberName, n, MAX_BLADES );
				continue;
			}
			saber->numBlades = n;
			continue;
		}

		// saberColor
		if ( !Q_stricmpn( token, "saberColor", 10 ) ) 
		{
			if ( !setColors )
			{//don't actually want to set the colors
				//read the color out anyway just to advance the *p pointer
				COM_ParseString( &p, &value );
				continue;
			}
			else
			{
				if (strlen(token)==10)
				{
					n = -1;
				}
				else if (strlen(token)==11)
				{
					n = atoi(&token[10])-1;
					if (n > 7 || n < 1 )
					{
						gi.Printf( S_COLOR_YELLOW"WARNING: bad saberColor '%s' in %s\n", token, SaberName );
						//read the color out anyway just to advance the *p pointer
						COM_ParseString( &p, &value );
						continue;
					}
				}
				else
				{
					gi.Printf( S_COLOR_YELLOW"WARNING: bad saberColor '%s' in %s\n", token, SaberName );
					//read the color out anyway just to advance the *p pointer
					COM_ParseString( &p, &value );
					continue;
				}

				if ( COM_ParseString( &p, &value ) )	//read the color
				{
					continue;
				}

				if (n==-1)
				{//NOTE: this fills in the rest of the blades with the same color by default
					saber_colors_t color = TranslateSaberColor( value );
					for ( n = 0; n < MAX_BLADES; n++ )
					{
						saber->blade[n].color = color;
					}
				} else 
				{
					saber->blade[n].color = TranslateSaberColor( value );
				}
				continue;
			}
		}

		//saber length
		if ( !Q_stricmpn( token, "saberLength", 11 ) ) 
		{
			if (strlen(token)==11)
			{
				n = -1;
			}
			else if (strlen(token)==12)
			{
				n = atoi(&token[11])-1;
				if (n > 7 || n < 1 )
				{
					gi.Printf( S_COLOR_YELLOW"WARNING: bad saberLength '%s' in %s\n", token, SaberName );
					continue;
				}
			}
			else
			{
				gi.Printf( S_COLOR_YELLOW"WARNING: bad saberLength '%s' in %s\n", token, SaberName );
				continue;
			}

			if ( COM_ParseFloat( &p, &f ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			//cap
			if ( f < 4.0f )
			{
				f = 4.0f;
			}

			if (n==-1)
			{//NOTE: this fills in the rest of the blades with the same length by default
				for ( n = 0; n < MAX_BLADES; n++ )
				{
					saber->blade[n].lengthMax = f;
				}
			}
			else
			{
				saber->blade[n].lengthMax = f;
			}
			continue;
		}

		//blade radius
		if ( !Q_stricmpn( token, "saberRadius", 11 ) ) 
		{
			if (strlen(token)==11)
			{
				n = -1;
			}
			else if (strlen(token)==12)
			{
				n = atoi(&token[11])-1;
				if (n > 7 || n < 1 )
				{
					gi.Printf( S_COLOR_YELLOW"WARNING: bad saberRadius '%s' in %s\n", token, SaberName );
					continue;
				}
			}
			else
			{
				gi.Printf( S_COLOR_YELLOW"WARNING: bad saberRadius '%s' in %s\n", token, SaberName );
				continue;
			}

			if ( COM_ParseFloat( &p, &f ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			//cap
			if ( f < 0.25f )
			{
				f = 0.25f;
			}
			if (n==-1)
			{//NOTE: this fills in the rest of the blades with the same length by default
				for ( n = 0; n < MAX_BLADES; n++ )
				{
					saber->blade[n].radius = f;
				}
			}
			else
			{
				saber->blade[n].radius = f;
			}
			continue;
		}

		//locked saber style
		if ( !Q_stricmp( token, "saberStyle" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->style = TranslateSaberStyle( value );
			continue;
		}

		//maxChain
		if ( !Q_stricmp( token, "maxChain" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->maxChain = n;
			continue;
		}

		//lockable
		if ( !Q_stricmp( token, "lockable" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->lockable = ((qboolean)(n!=0));
			continue;
		}

		//throwable
		if ( !Q_stricmp( token, "throwable" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->throwable = ((qboolean)(n!=0));
			continue;
		}

		//disarmable
		if ( !Q_stricmp( token, "disarmable" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->disarmable = ((qboolean)(n!=0));
			continue;
		}

		//active blocking
		if ( !Q_stricmp( token, "blocking" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->activeBlocking = ((qboolean)(n!=0));
			continue;
		}

		//twoHanded
		if ( !Q_stricmp( token, "twoHanded" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->twoHanded = ((qboolean)(n!=0));
			continue;
		}

		//force power restrictions
		if ( !Q_stricmp( token, "forceRestrict" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			int fp = GetIDForString( FPTable, value );
			if ( fp >= FP_FIRST && fp < NUM_FORCE_POWERS )
			{
				saber->forceRestrictions |= (1<<fp);
			}
			continue;
		}

		//lockBonus
		if ( !Q_stricmp( token, "lockBonus" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->lockBonus = n;
			continue;
		}

		//parryBonus
		if ( !Q_stricmp( token, "parryBonus" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->parryBonus = n;
			continue;
		}

		//breakParryBonus
		if ( !Q_stricmp( token, "breakParryBonus" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->breakParryBonus = n;
			continue;
		}

		//disarmBonus
		if ( !Q_stricmp( token, "disarmBonus" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->disarmBonus = n;
			continue;
		}

		//single blade saber style
		if ( !Q_stricmp( token, "singleBladeStyle" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->singleBladeStyle = TranslateSaberStyle( value );
			continue;
		}

		//single blade throwable
		if ( !Q_stricmp( token, "singleBladeThrowable" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->singleBladeThrowable = ((qboolean)(n!=0));
			continue;
		}

		//broken replacement saber1 (right hand)
		if ( !Q_stricmp( token, "brokenSaber1" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->brokenSaber1 = G_NewString( value );
			continue;
		}
		
		//broken replacement saber2 (left hand)
		if ( !Q_stricmp( token, "brokenSaber2" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->brokenSaber2 = G_NewString( value );
			continue;
		}

		//spins and does damage on return from saberthrow
		if ( !Q_stricmp( token, "returnDamage" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->returnDamage = ((qboolean)(n!=0));
			continue;
		}

		if ( !Q_stricmp( token, "notInMP" ) ) 
		{//ignore this
			SkipRestOfLine( &p );
			continue;
		}

		gi.Printf( "WARNING: unknown keyword '%s' while parsing '%s'\n", token, SaberName );
		SkipRestOfLine( &p );
	}

	//FIXME: precache the saberModel(s)?

	if ( saber->type == SABER_SITH_SWORD )
	{//precache all the sith sword sounds
		Saber_SithSwordPrecache();
	}

	return qtrue;
}
/*
=================
PlayerModel_BuildList
=================
*/
static void PlayerModel_BuildList( void )
{
	int		numdirs;
	int		numfiles;
	char	dirlist[2048];
	char	filelist[2048];
	char	skinname[64];
	char*	dirptr;
	char*	fileptr;
	int		i;
	int		j;
	int		dirlen;
	int		filelen;
	qboolean precache;

	precache = trap_Cvar_VariableValue("com_buildscript");

	s_playermodel.modelpage = 0;
	s_playermodel.nummodels = 0;

	// iterate directory of all player models
	numdirs = trap_FS_GetFileList("models/players", "/", dirlist, 2048 );
	dirptr  = dirlist;
	for (i=0; i<numdirs && s_playermodel.nummodels < MAX_PLAYERMODELS; i++,dirptr+=dirlen+1)
	{
		dirlen = (int)strlen(dirptr);
		
		if (dirlen && dirptr[dirlen-1]=='/') dirptr[dirlen-1]='\0';

		if (!strcmp(dirptr,".") || !strcmp(dirptr,".."))
			continue;
			
		// iterate all skin files in directory
		numfiles = trap_FS_GetFileList( va("models/players/%s",dirptr), "tga", filelist, 2048 );
		fileptr  = filelist;
		for (j=0; j<numfiles && s_playermodel.nummodels < MAX_PLAYERMODELS;j++,fileptr+=filelen+1)
		{
			filelen = (int)strlen(fileptr);

			COM_StripExtension(fileptr,skinname);

			// look for icon_????
			if (!Q_stricmpn(skinname,"icon_",5))
			{
				Com_sprintf( s_playermodel.modelnames[s_playermodel.nummodels++],
					sizeof( s_playermodel.modelnames[s_playermodel.nummodels] ),
					"models/players/%s/%s", dirptr, skinname );
				//if (s_playermodel.nummodels >= MAX_PLAYERMODELS)
				//	return;
			}

			if( precache ) {
				trap_S_RegisterSound( va( "sound/player/announce/%s_wins.wav", skinname), qfalse );
			}
		}
	}	

	//APSFIXME - Degenerate no models case

	s_playermodel.numpages = s_playermodel.nummodels/MAX_MODELSPERPAGE;
	if (s_playermodel.nummodels % MAX_MODELSPERPAGE)
		s_playermodel.numpages++;
}
Beispiel #14
0
/*
================
CG_ParseServerinfo

This is called explicitly when the gamestate is first received,
and whenever the server updates any serverinfo flagged cvars
================
*/
void CG_ParseServerinfo( void ) {
	const char *info = NULL, *tinfo = NULL;
	char *mapname;
	int i, value;

	info = CG_ConfigString( CS_SERVERINFO );

	cgs.debugMelee = atoi( Info_ValueForKey( info, "g_debugMelee" ) ); //trap->Cvar_GetHiddenVarValue("g_iknowkungfu");
	cgs.stepSlideFix = atoi( Info_ValueForKey( info, "g_stepSlideFix" ) );

	cgs.noSpecMove = atoi( Info_ValueForKey( info, "g_noSpecMove" ) );

	cgs.siegeTeamSwitch = atoi( Info_ValueForKey( info, "g_siegeTeamSwitch" ) );

	cgs.showDuelHealths = atoi( Info_ValueForKey( info, "g_showDuelHealths" ) );

	cgs.gametype = atoi( Info_ValueForKey( info, "g_gametype" ) );
	trap->Cvar_Set("g_gametype", va("%i", cgs.gametype));
	cgs.needpass = atoi( Info_ValueForKey( info, "g_needpass" ) );
	cgs.jediVmerc = atoi( Info_ValueForKey( info, "g_jediVmerc" ) );

	// this changes on map_restart, attempt to precache weapons
	value = atoi( Info_ValueForKey( info, "g_weaponDisable" ) );
	if ( cgs.wDisable != value ) {
		gitem_t *item = NULL;
		itemInfo_t *itemInfo = NULL;

		cgs.wDisable = value;

		for ( i=1, item=bg_itemlist, itemInfo = cg_items;
			i<bg_numItems;
			i++, item++, itemInfo++ )
		{// register all weapons that aren't disabled
			if ( item->giType == IT_WEAPON )
				CG_RegisterWeapon( item->giTag );
		}
	}

	cgs.fDisable = atoi( Info_ValueForKey( info, "g_forcePowerDisable" ) );
	cgs.dmflags = atoi( Info_ValueForKey( info, "dmflags" ) );
	cgs.duel_fraglimit = atoi( Info_ValueForKey( info, "duel_fraglimit" ) );
	cgs.capturelimit = atoi( Info_ValueForKey( info, "capturelimit" ) );

	// reset fraglimit warnings
	i = atoi( Info_ValueForKey( info, "fraglimit" ) );
	if ( cgs.fraglimit < i )
		cg.fraglimitWarnings &= ~(1|2|4);
	cgs.fraglimit = i;

	// reset timelimit warnings
	i = atoi( Info_ValueForKey( info, "timelimit" ) );
	if ( cgs.timelimit != i )
		cg.timelimitWarnings &= ~(1|2);
	cgs.timelimit = i;

	cgs.maxclients = Com_Clampi( 0, MAX_CLIENTS, atoi( Info_ValueForKey( info, "sv_maxclients" ) ) );

	cgs.isJAPlus = qfalse;
	cgs.isJAPro = qfalse;
	cgs.cinfo = 0;
	cgs.jcinfo = 0;
	cgs.restricts = 0;
	if (!Q_stricmpn(Info_ValueForKey(info, "gamename"), "JA+ Mod", 7) || !Q_stricmpn(Info_ValueForKey(info, "gamename"), "^4U^3A^5Galaxy", 14 )) {	//uag :s - yes its fatz
		cgs.isJAPlus = qtrue;
		cgs.cinfo = atoi (Info_ValueForKey (info, "jp_cinfo" ));//[JAPRO - Clientside - All - Add jp_cinfo variable to get cinfo from japlus servers]
	} 
	else if (!Q_stricmpn(Info_ValueForKey(info, "gamename"), "japro", 5)) {
		cgs.isJAPro = qtrue;
		cgs.jcinfo= atoi (Info_ValueForKey (info, "jcinfo" ));//[JAPRO - Clientside - All - Add gamename variable to get jcinfo from japro servers]
	}
	cgs.restricts = atoi (Info_ValueForKey (info, "restricts" ));//[JAPRO - Clientside - All - Add gamename variable to get jcinfo from japro servers]

	mapname = Info_ValueForKey( info, "mapname" );
	//rww - You must do this one here, Info_ValueForKey always uses the same memory pointer.
	trap->Cvar_Set ( "ui_about_mapname", mapname );

	Com_sprintf( cgs.mapname, sizeof( cgs.mapname ), "maps/%s.bsp", mapname );
//	Q_strncpyz( cgs.redTeam, Info_ValueForKey( info, "g_redTeam" ), sizeof(cgs.redTeam) );
//	trap->Cvar_Set("g_redTeam", cgs.redTeam);
//	Q_strncpyz( cgs.blueTeam, Info_ValueForKey( info, "g_blueTeam" ), sizeof(cgs.blueTeam) );
//	trap->Cvar_Set("g_blueTeam", cgs.blueTeam);

	trap->Cvar_Set ( "ui_about_gametype", va("%i", cgs.gametype ) );
	trap->Cvar_Set ( "ui_about_fraglimit", va("%i", cgs.fraglimit ) );
	trap->Cvar_Set ( "ui_about_duellimit", va("%i", cgs.duel_fraglimit ) );
	trap->Cvar_Set ( "ui_about_capturelimit", va("%i", cgs.capturelimit ) );
	trap->Cvar_Set ( "ui_about_timelimit", va("%i", cgs.timelimit ) );
	trap->Cvar_Set ( "ui_about_maxclients", va("%i", cgs.maxclients ) );
	trap->Cvar_Set ( "ui_about_dmflags", va("%i", cgs.dmflags ) );
	trap->Cvar_Set ( "ui_about_hostname", Info_ValueForKey( info, "sv_hostname" ) );
	trap->Cvar_Set ( "ui_about_needpass", Info_ValueForKey( info, "g_needpass" ) );
	trap->Cvar_Set ( "ui_about_botminplayers", Info_ValueForKey ( info, "bot_minplayers" ) );

	//Set the siege teams based on what the server has for overrides.
	trap->Cvar_Set("cg_siegeTeam1", Info_ValueForKey(info, "g_siegeTeam1"));
	trap->Cvar_Set("cg_siegeTeam2", Info_ValueForKey(info, "g_siegeTeam2"));

	tinfo = CG_ConfigString( CS_TERRAINS + 1 );
	if ( !tinfo || !*tinfo )
	{
		cg.mInRMG = qfalse;
	}
	else
	{
		int weather = 0;

		cg.mInRMG = qtrue;
		trap->Cvar_Set("RMG", "1");

		weather = atoi( Info_ValueForKey( info, "RMG_weather" ) );

		trap->Cvar_Set("RMG_weather", va("%i", weather));

		if (weather == 1 || weather == 2)
		{
			cg.mRMGWeather = qtrue;
		}
		else
		{
			cg.mRMGWeather = qfalse;
		}
	}

	Q_strncpyz( cgs.voteString, CG_ConfigString( CS_VOTE_STRING ), sizeof( cgs.voteString ) );

	// synchronise our expected snaps/sec with the server's framerate
	i = atoi( Info_ValueForKey( info, "sv_fps" ) );
	if ( i )
		trap->Cvar_Set( "snaps", va( "%i", i ) );
}
Beispiel #15
0
int Q_stricmp (const char *s1, const char *s2) {
	return (s1 && s2) ? Q_stricmpn (s1, s2, 99999) : -1;
}
Beispiel #16
0
/*
==================
SV_Map_f

Restart the server on a different map
==================
*/
static void SV_Map_f( void ) {
	char		*cmd = NULL, *map = NULL;
	qboolean	killBots=qfalse, cheat=qfalse;
	char		expanded[MAX_QPATH] = {0}, mapname[MAX_QPATH] = {0};

	map = Cmd_Argv(1);
	if ( !map )
		return;

	// make sure the level exists before trying to change, so that
	// a typo at the server console won't end the game
	if (strchr (map, '\\') ) {
		Com_Printf ("Can't have mapnames with a \\\n");
		return;
	}

	Com_sprintf (expanded, sizeof(expanded), "maps/%s.bsp", map);
	if ( FS_ReadFile (expanded, NULL) == -1 ) {
		Com_Printf ("Can't find map %s\n", expanded);
		return;
	}

	// force latched values to get set
	Cvar_Get ("g_gametype", "0", CVAR_SERVERINFO | CVAR_LATCH );

	cmd = Cmd_Argv(0);
	if ( !Q_stricmpn( cmd, "devmap", 6 ) ) {
		cheat = qtrue;
		killBots = qtrue;
	} else {
		cheat = qfalse;
		killBots = qfalse;
	}

	// save the map name here cause on a map restart we reload the jampconfig.cfg
	// and thus nuke the arguments of the map command
	Q_strncpyz(mapname, map, sizeof(mapname));

	ForceReload_e eForceReload = eForceReload_NOTHING;	// default for normal load

//	if ( !Q_stricmp( cmd, "devmapbsp") ) {	// not relevant in MP codebase
//		eForceReload = eForceReload_BSP;
//	}
//	else
	if ( !Q_stricmp( cmd, "devmapmdl") ) {
		eForceReload = eForceReload_MODELS;
	}
	else
	if ( !Q_stricmp( cmd, "devmapall") ) {
		eForceReload = eForceReload_ALL;
	}

	// start up the map
	SV_SpawnServer( mapname, killBots, eForceReload );

	// set the cheat value
	// if the level was started with "map <levelname>", then
	// cheats will not be allowed.  If started with "devmap <levelname>"
	// then cheats will be allowed
	Cvar_Set( "sv_cheats", cheat ? "1" : "0" );
}
Beispiel #17
0
void Script_ConditionalScript(itemDef_t *item, qboolean *bAbort, char **args)
{
	const char *cvar;
	const char *script1;
	const char *script2;
	const char *token;
	int        testtype;  // 0: check val not 0
	// 1: check cvar not empty
	int testval;

	if (String_Parse(args, &cvar) &&
	    Int_Parse(args, &testtype) &&
	    String_Parse(args, &token) && (token && *token == '(') &&
	    String_Parse(args, &script1) &&
	    String_Parse(args, &token) && (token && *token == ')') &&
	    String_Parse(args, &token) && (token && *token == '(') &&
	    String_Parse(args, &script2) &&
	    String_Parse(args, &token) && (token && *token == ')'))
	{
		float val;

		switch (testtype)
		{
		default:
		case 0:
			val = DC->getCVarValue(cvar);
			if (val == 0.f)
			{
				Item_RunScript(item, bAbort, script2);
			}
			else
			{
				Item_RunScript(item, bAbort, script1);
			}
			break;
		case 1:
		{
			char buff[1024];

			DC->getCVarString(cvar, buff, sizeof(buff));
			if (!buff[0])
			{
				Item_RunScript(item, bAbort, script2);
			}
			else
			{
				Item_RunScript(item, bAbort, script1);
			}
		}
		break;
		case 3:
			if (Int_Parse(args, &testval))
			{
				int testVal;

				val     = DC->getCVarValue(cvar);
				testVal = (int)val;
				if (testVal != testval)
				{
					Item_RunScript(item, bAbort, script2);
				}
				else
				{
					Item_RunScript(item, bAbort, script1);
				}
			}
			break;
		case 2:
			// special tests
			if (!Q_stricmp(cvar, "UIProfileIsActiveProfile"))
			{
				char ui_profileStr[256];
				char cl_profileStr[256];

				DC->getCVarString("ui_profile", ui_profileStr, sizeof(ui_profileStr));
				Q_CleanStr(ui_profileStr);
				Q_CleanDirName(ui_profileStr);

				DC->getCVarString("cl_profile", cl_profileStr, sizeof(cl_profileStr));

				if (!Q_stricmp(ui_profileStr, cl_profileStr))
				{
					Item_RunScript(item, bAbort, script1);
				}
				else
				{
					Item_RunScript(item, bAbort, script2);
				}
			}
			else if (!Q_stricmp(cvar, "UIProfileValidName"))
			{
				char ui_profileStr[256];
				char ui_profileCleanedStr[256];

				DC->getCVarString("ui_profile", ui_profileStr, sizeof(ui_profileStr));
				Q_strncpyz(ui_profileCleanedStr, ui_profileStr, sizeof(ui_profileCleanedStr));
				Q_CleanStr(ui_profileCleanedStr);
				Q_CleanDirName(ui_profileCleanedStr);

				if (*ui_profileStr && *ui_profileCleanedStr)
				{
					Item_RunScript(item, bAbort, script1);
				}
				else
				{
					Item_RunScript(item, bAbort, script2);
				}

			}
			else if (!Q_stricmp(cvar, "UIProfileAlreadyExists"))
			{
				char         ui_profileCleanedStr[256];
				qboolean     alreadyExists = qfalse;
				fileHandle_t f;

				DC->getCVarString("ui_profile", ui_profileCleanedStr, sizeof(ui_profileCleanedStr));
				Q_CleanStr(ui_profileCleanedStr);
				Q_CleanDirName(ui_profileCleanedStr);

				if (trap_FS_FOpenFile(va("profiles/%s/profile.dat", ui_profileCleanedStr), &f, FS_READ) >= 0)
				{
					alreadyExists = qtrue;
					trap_FS_FCloseFile(f);
				}

				if (alreadyExists)
				{
					Item_RunScript(item, bAbort, script1);
				}
				else
				{
					Item_RunScript(item, bAbort, script2);
				}
			}
			else if (!Q_stricmp(cvar, "UIProfileAlreadyExists_Rename"))
			{
				char         ui_profileCleanedStr[256];
				qboolean     alreadyExists = qfalse;
				fileHandle_t f;

				DC->getCVarString("ui_profile_renameto", ui_profileCleanedStr, sizeof(ui_profileCleanedStr));
				Q_CleanStr(ui_profileCleanedStr);
				Q_CleanDirName(ui_profileCleanedStr);

				if (trap_FS_FOpenFile(va("profiles/%s/profile.dat", ui_profileCleanedStr), &f, FS_READ) >= 0)
				{
					alreadyExists = qtrue;
					trap_FS_FCloseFile(f);
				}

				if (alreadyExists)
				{
					Item_RunScript(item, bAbort, script1);
				}
				else
				{
					Item_RunScript(item, bAbort, script2);
				}
			}
			else if (!Q_stricmp(cvar, "ReadyToCreateProfile"))
			{
				char         ui_profileStr[256], ui_profileCleanedStr[256];
				int          ui_rate;
				qboolean     alreadyExists = qfalse;
				fileHandle_t f;

				DC->getCVarString("ui_profile", ui_profileStr, sizeof(ui_profileStr));

				Q_strncpyz(ui_profileCleanedStr, ui_profileStr, sizeof(ui_profileCleanedStr));
				Q_CleanStr(ui_profileCleanedStr);
				Q_CleanDirName(ui_profileCleanedStr);

				if (trap_FS_FOpenFile(va("profiles/%s/profile.dat", ui_profileCleanedStr), &f, FS_READ) >= 0)
				{
					alreadyExists = qtrue;
					trap_FS_FCloseFile(f);
				}

				ui_rate = (int)DC->getCVarValue("ui_rate");

				if (!alreadyExists && *ui_profileStr && ui_rate > 0)
				{
					Item_RunScript(item, bAbort, script1);
				}
				else
				{
					Item_RunScript(item, bAbort, script2);
				}
			}
			else if (!Q_stricmp(cvar, "vidrestartIsRequired"))
			{
				int  ui_r_mode                           = DC->getCVarValue("ui_r_mode");
				int  ui_r_colorbits                      = DC->getCVarValue("ui_r_colorbits");
				int  ui_r_fullscreen                     = DC->getCVarValue("ui_r_fullscreen");
				int  ui_r_noborder                       = DC->getCVarValue("ui_r_noborder");
				int  ui_r_texturebits                    = DC->getCVarValue("ui_r_texturebits");
				int  ui_r_depthbits                      = DC->getCVarValue("ui_r_depthbits");
				int  ui_r_ext_compressed_textures        = DC->getCVarValue("ui_r_ext_compressed_textures");
				int  ui_r_allowextensions                = DC->getCVarValue("ui_r_allowextensions");
				int  ui_s_khz                            = DC->getCVarValue("ui_s_khz");
				int  ui_r_detailtextures                 = DC->getCVarValue("ui_r_detailtextures");
				int  ui_r_subdivisions                   = DC->getCVarValue("ui_r_subdivisions");
				int  ui_r_ext_texture_filter_anisotropic = DC->getCVarValue("ui_r_ext_texture_filter_anisotropic");
				int  ui_cg_shadows                       = DC->getCVarValue("ui_cg_shadows");
				char ui_r_texturemode[MAX_CVAR_VALUE_STRING];

				int  r_mode                           = DC->getCVarValue("r_mode");
				int  r_colorbits                      = DC->getCVarValue("r_colorbits");
				int  r_fullscreen                     = DC->getCVarValue("r_fullscreen");
				int  r_noborder                       = DC->getCVarValue("r_noborder");
				int  r_texturebits                    = DC->getCVarValue("r_texturebits");
				int  r_depthbits                      = DC->getCVarValue("r_depthbits");
				int  r_ext_compressed_textures        = DC->getCVarValue("r_ext_compressed_textures");
				int  r_allowextensions                = DC->getCVarValue("r_allowextensions");
				int  s_khz                            = DC->getCVarValue("s_khz");
				int  r_detailtextures                 = DC->getCVarValue("r_detailtextures");
				int  r_subdivisions                   = DC->getCVarValue("r_subdivisions");
				int  r_ext_texture_filter_anisotropic = DC->getCVarValue("r_ext_texture_filter_anisotropic");
				int  cg_shadows                       = DC->getCVarValue("cg_shadows");
				char r_texturemode[MAX_CVAR_VALUE_STRING];

				trap_Cvar_VariableStringBuffer("ui_r_texturemode", ui_r_texturemode, sizeof(ui_r_texturemode));
				trap_Cvar_VariableStringBuffer("r_texturemode", r_texturemode, sizeof(r_texturemode));

				if (ui_r_subdivisions != r_subdivisions ||
				    ui_r_mode != r_mode ||
				    ui_r_colorbits != r_colorbits ||
				    ui_r_fullscreen != r_fullscreen ||
				    ui_r_noborder != r_noborder ||
				    ui_r_texturebits != r_texturebits ||
				    ui_r_depthbits != r_depthbits ||
				    ui_r_ext_compressed_textures != r_ext_compressed_textures ||
				    ui_r_allowextensions != r_allowextensions ||
				    ui_s_khz != s_khz ||
				    ui_r_detailtextures != r_detailtextures ||
				    ui_r_ext_texture_filter_anisotropic != r_ext_texture_filter_anisotropic ||
				    ui_cg_shadows != cg_shadows ||
				    Q_stricmp(r_texturemode, ui_r_texturemode))
				{
					Item_RunScript(item, bAbort, script1);
				}
				else
				{
					Item_RunScript(item, bAbort, script2);
				}
				/*} else if( !Q_stricmpn( cvar, "voteflags", 9 ) ) {
				char info[MAX_INFO_STRING];
				int voteflags = atoi(cvar + 9);

				trap_Cvar_VariableStringBuffer( "cg_ui_voteFlags", info, sizeof(info) );

				if( (atoi(info) & item->voteFlag) != item->voteFlag ) {
				Item_RunScript( item, bAbort, script1 );
				} else {
				Item_RunScript( item, bAbort, script2 );
				}*/
#ifndef CGAMEDLL
			}
			else if (!Q_stricmpn(cvar, "serversort_", 11))
			{
				int sorttype = atoi(cvar + 11);

				if (sorttype != uiInfo.serverStatus.sortKey)
				{
					Item_RunScript(item, bAbort, script2);
				}
				else
				{
					Item_RunScript(item, bAbort, script1);
				}
			}
			else if (!Q_stricmp(cvar, "ValidReplaySelected"))
			{
				if (uiInfo.demoIndex >= 0 && uiInfo.demoIndex < uiInfo.demoCount)
				{
					Item_RunScript(item, bAbort, script1);
				}
				else
				{
					Item_RunScript(item, bAbort, script2);
				}
#endif // !CGAMEDLL
			}
			else if (!Q_stricmp(cvar, "ROldModeCheck"))
			{
				char r_oldModeStr[256];
				int  r_oldMode;
				int  r_mode = DC->getCVarValue("r_mode");

				DC->getCVarString("r_oldMode", r_oldModeStr, sizeof(r_oldModeStr));
				r_oldMode = atoi(r_oldModeStr);

				if (*r_oldModeStr && r_oldMode != r_mode)
				{
					Item_RunScript(item, bAbort, script1);
				}
				else
				{
					if (r_oldMode == r_mode)
					{
						trap_Cvar_Set("r_oldMode", "");   // clear it
					}

					Item_RunScript(item, bAbort, script2);
				}
			}

			break;
		}
	}
}
Beispiel #18
0
void G_xpsave_readconfig() 
{
	g_xpsave_t *x = g_xpsaves[0];
	g_mapstat_t *m = g_mapstats[0];
	int xc = 0;
	int mc = 0;
	fileHandle_t f;
	int i, j;
	int len;
	char *cnf, *cnf2;
	char *t;
	qboolean xpsave_open;
	qboolean mapstat_open;
	qboolean serverstat_open;
	qboolean found_serverstat = qfalse;
	float skill;
	char buffer[MAX_STRING_CHARS];

	if(!(g_XPSave.integer & XPSF_ENABLE))
		return;	
	if(!g_XPSaveFile.string[0])
		return;
	len = trap_FS_FOpenFile(g_XPSaveFile.string, &f, FS_READ) ; 
	if(len < 0) {
		G_Printf("readconfig: could not open xpsave file %s\n",
			g_XPSaveFile.string);
		return;
	}
	cnf = malloc(len+1);
	cnf2 = cnf;
	trap_FS_Read(cnf, len, f);
	*(cnf + len) = '\0';
	trap_FS_FCloseFile(f);

	G_xpsave_cleanup();
	
	t = COM_Parse(&cnf);
	xpsave_open = qfalse;
	mapstat_open = qfalse;
	serverstat_open = qfalse;
	while(*t) {
		if(!Q_stricmp(t, "[xpsave]") ||
			!Q_stricmp(t, "[mapstat]") ||
			!Q_stricmp(t, "[serverstat]")
			) {

			if(xpsave_open)
				g_xpsaves[xc++] = x;
			if(mapstat_open)
				g_mapstats[mc++] = m;
			xpsave_open = qfalse;
			mapstat_open = qfalse;
			serverstat_open = qfalse;
		}

		if(xpsave_open) {
			if(!Q_stricmp(t, "guid")) {
				G_shrubbot_readconfig_string(&cnf, 
					x->guid, sizeof(x->guid)); 
			}
			else if(!Q_stricmp(t, "name")) {
				G_shrubbot_readconfig_string(&cnf, 
					x->name, sizeof(x->name)); 
			}
			else if(!Q_stricmp(t, "time")) {
				G_shrubbot_readconfig_int(&cnf, &x->time);
			}
			else if(!Q_stricmpn(t, "skill[", 6)) {
				for(i=0; i<SK_NUM_SKILLS; i++) {
					if(Q_stricmp(t, va("skill[%i]", i)))
						continue;		
					G_shrubbot_readconfig_float(&cnf,
						&skill);
					x->skill[i] = skill;
					break;
				}
			}
			else if(!Q_stricmp(t, "kill_rating")) {
				G_shrubbot_readconfig_float(&cnf, &x->kill_rating);
			}
			else if(!Q_stricmp(t, "kill_variance")) {
				G_shrubbot_readconfig_float(&cnf, &x->kill_variance);
			}
			else if(!Q_stricmp(t, "rating")) {
				G_shrubbot_readconfig_float(&cnf,
					&x->rating);
			}
			else if(!Q_stricmp(t, "rating_variance")) {
				G_shrubbot_readconfig_float(&cnf,
					&x->rating_variance);
			}
			else if(!Q_stricmp(t, "mutetime")) {
				G_shrubbot_readconfig_int(&cnf, &x->mutetime);
			}
			else if(!Q_stricmpn(t, "pr_skill[", 9)) {
				for(i=0; i<SK_NUM_SKILLS; i++) {
					if(Q_stricmp(t, va("pr_skill[%i]", i)))
						continue;		
					G_shrubbot_readconfig_string(&cnf,
						buffer, sizeof(buffer));
					sscanf(buffer,
						"%i %f %i %f %i %f %i %f %i %f",
						&x->pr_skill_updates[i][0],
						&x->pr_skill[i][0],
						&x->pr_skill_updates[i][1],
						&x->pr_skill[i][1],
						&x->pr_skill_updates[i][2],
						&x->pr_skill[i][2],
						&x->pr_skill_updates[i][3],
						&x->pr_skill[i][3],
						&x->pr_skill_updates[i][4],
						&x->pr_skill[i][4]);
					break;
				}
			}
			else {
				G_Printf("xpsave: [xpsave] parse error near "
					"%s on line %d\n", 
					t, 
					COM_GetCurrentParseLine());
			}
		}
		else if(mapstat_open) {
			if(!Q_stricmp(t, "name")) {
				G_shrubbot_readconfig_string(&cnf, 
					m->name, sizeof(m->name)); 
			}
			else if(!Q_stricmp(t, "rating")) {
				G_shrubbot_readconfig_float(&cnf,
					&m->rating);
			}
			else if(!Q_stricmp(t, "rating_variance")) {
				G_shrubbot_readconfig_float(&cnf,
					&m->rating_variance);
			}
			else if(!Q_stricmp(t, "spree_record")) {
				G_shrubbot_readconfig_int(&cnf,
					&m->spreeRecord);
			}
			else if(!Q_stricmp(t, "spree_name")) {
				G_shrubbot_readconfig_string(&cnf, 
					m->spreeName, sizeof(m->spreeName)); 
			}
			else {
				G_Printf("xpsave: [mapstat] parse error near "
					"%s on line %d\n", 
					t, 
					COM_GetCurrentParseLine());
			}
		}
		else if(serverstat_open) {
			if(!Q_stricmp(t, "rating")) {
				G_shrubbot_readconfig_float(&cnf,
					&g_serverstat.rating);
			}
			else if(!Q_stricmp(t, "rating_variance")) {
				G_shrubbot_readconfig_float(&cnf,
					&g_serverstat.rating_variance);
			}
			else if(!Q_stricmp(t, "distance_rating")) {
				G_shrubbot_readconfig_float(&cnf,
					&g_serverstat.distance_rating);
			}
			else if(!Q_stricmp(t, "distance_variance")) {
				G_shrubbot_readconfig_float(&cnf,
					&g_serverstat.distance_variance);
			}
			else {
				G_Printf("xpsave: [serverstat] parse error near "
					"%s on line %d\n", 
					t, 
					COM_GetCurrentParseLine());
			}
		}

		if(!Q_stricmp(t, "[xpsave]")) {
			if(xc >= MAX_XPSAVES) {
				G_Printf("xpsave: error MAX_XPSAVES exceeded");
				return;
			}
			x = malloc(sizeof(g_xpsave_t));
			x->guid[0] = '\0';
			x->name[0] = '\0';
			x->kill_rating = 0.0f;
			x->kill_variance = SIGMA2_DELTA;
			x->rating = 0.0f;
			x->rating_variance = SIGMA2_THETA;
			for(i=0; i<SK_NUM_SKILLS; i++) {
				x->skill[i] = 0.0f;
				for(j=0; j<NUM_SKILL_LEVELS; j++) {
					x->pr_skill_updates[i][j] = 0;
					x->pr_skill[i][j] = 0.0f;
				}
			}
			x->mutetime = 0;
			x->hits = 0;
			x->team_hits = 0;
			x->time = 0;
			xpsave_open = qtrue;
		}
		if(!Q_stricmp(t, "[mapstat]")) {
			if(mc >= MAX_MAPSTATS) {
				G_Printf("xpsave: error MAX_MAPSTATS exceeded");
				return;
			}
			m = malloc(sizeof(g_mapstat_t));
			m->name[0] = '\0';
			m->rating = 0.0f;
			m->rating_variance = SIGMA2_GAMMA;
			m->spreeRecord = 0;
			m->spreeName[0] = '\0';
			mapstat_open = qtrue;
		}
		if(!Q_stricmp(t, "[serverstat]")) {
			// server prior = 2.6, NOT 0
			g_serverstat.rating = 2.6f;
			g_serverstat.rating_variance = SIGMA2_PSI;
			g_serverstat.distance_rating = 0.0f;
			g_serverstat.distance_variance = SIGMA2_DELTA;
			serverstat_open = qtrue;
			found_serverstat = qtrue;
		}
		t = COM_Parse(&cnf);
	}
	if(xpsave_open)
		g_xpsaves[xc++] = x;
	else if(mapstat_open)
		g_mapstats[mc++] = m;

	free(cnf2);
	if (!found_serverstat) {
		// server prior = 2.6, NOT 0
		g_serverstat.rating = 2.6f;
		g_serverstat.rating_variance = SIGMA2_PSI;
	}
	G_Printf("xpsave: loaded %d mapstats, %d xpsaves\n", mc, xc);
}
Beispiel #19
0
void G_SpawnGEntityFromSpawnVars( qboolean inSubBSP ) {
	int			i;
	gentity_t	*ent;
	char		*s, *value, *gametypeName;
	static char *gametypeNames[] = {"ffa", "holocron", "jedimaster", "duel", "powerduel", "single", "team", "siege", "ctf", "cty"};

	// get the next free entity
	if ( level.entCount > (MAX_GENTITIES - g_objectMargin.integer))
	{
		G_Printf("ERROR :Run out of entities\n");
		return;
	}
	ent = G_Spawn();

	for ( i = 0 ; i < level.numSpawnVars ; i++ ) {
		BG_ParseField( fields, level.spawnVars[i][0], level.spawnVars[i][1], (byte *)ent );
	}

	if ( level.stripping == qtrue )
	{
		// strip out any undesirable object classes.
		if( Q_stricmpn( "item_", ent->classname, 5 ) == 0  ||
			Q_stricmpn( "trigger_", ent->classname, 8 ) == 0 ||
			Q_stricmpn( "target_", ent->classname, 7 ) == 0 ||
			Q_stricmpn( "NPC_", ent->classname, 4 ) == 0 )	
		{
			G_FreeEntity( ent );
			return;
		}

	}

	// check for "notsingle" flag
	if ( g_gametype.integer == GT_SINGLE_PLAYER ) {
		G_SpawnInt( "notsingle", "0", &i );
		if ( i ) {
			G_FreeEntity( ent );
			return;
		}
	}
	// check for "notteam" flag (GT_FFA, GT_DUEL, GT_SINGLE_PLAYER)
	if ( g_gametype.integer >= GT_TEAM ) {
		G_SpawnInt( "notteam", "0", &i );
		if ( i ) {
			G_FreeEntity( ent );
			return;
		}
	} else {
		G_SpawnInt( "notfree", "0", &i );
		if ( i ) {
			G_FreeEntity( ent );
			return;
		}
	}

	G_SpawnInt( "notta", "0", &i );
	if ( i ) {
		G_FreeEntity( ent );
		return;
	}

	if( G_SpawnString( "gametype", NULL, &value ) ) {
		if( g_gametype.integer >= GT_FFA && g_gametype.integer < GT_MAX_GAME_TYPE ) {
			gametypeName = gametypeNames[g_gametype.integer];

			s = strstr( value, gametypeName );
			if( !s ) {
				G_FreeEntity( ent );
				return;
			}
		}
	}

	// move editor origin to pos
	VectorCopy( ent->s.origin, ent->s.pos.trBase );
	VectorCopy( ent->s.origin, ent->r.currentOrigin );

	// if we didn't get a classname, don't bother spawning anything
	if ( !G_CallSpawn( ent ) ) {
		G_FreeEntity( ent );
	}

	//Tag on the ICARUS scripting information only to valid recipients
	if ( trap_ICARUS_ValidEnt( ent ) )
	{
		trap_ICARUS_InitEnt( ent );

		if ( ent->classname && ent->classname[0] )
		{
			if ( Q_strncmp( "NPC_", ent->classname, 4 ) != 0 )
			{//Not an NPC_spawner (rww - probably don't even care for MP, but whatever)
				G_ActivateBehavior( ent, BSET_SPAWN );
			}
		}
	}
}
Beispiel #20
0
/*
==============
Win_PrintMatches
==============
*/
static void Win_PrintMatches( const char *s ) {
	if ( !Q_stricmpn( s, win_currentMatch, win_acLength ) ) {
		Sys_Print( va( "  ^9%s^0\n", s ) );
	}
}
Beispiel #21
0
// return is either NULL for good else error message to display...
//
const char *CStringEdPackage::ParseLine( const char *psLine )
{
	const char *psErrorMessage = NULL;

	if (psLine)
	{
		if (CheckLineForKeyword( sSE_KEYWORD_VERSION, psLine ))
		{
			// VERSION 	"1"
			//
			const char *psVersionNumber = InsideQuotes( psLine );
			int		iVersionNumber = atoi( psVersionNumber );

			if (iVersionNumber != iSE_VERSION)
			{
				psErrorMessage = va("Unexpected version number %d, expecting %d!\n", iVersionNumber, iSE_VERSION);
			}
		}
		else
		if (	CheckLineForKeyword(sSE_KEYWORD_CONFIG, psLine)
			||	CheckLineForKeyword(sSE_KEYWORD_FILENOTES, psLine)
			||	CheckLineForKeyword(sSE_KEYWORD_NOTES, psLine)
			)
		{
			// not used ingame, but need to absorb the token
		}
		else
		if (CheckLineForKeyword(sSE_KEYWORD_REFERENCE, psLine))
		{
			// REFERENCE	GUARD_GOOD_TO_SEE_YOU
			//
			const char *psLocalReference = InsideQuotes( psLine );
			AddEntry( psLocalReference );
		}
		else
		if (CheckLineForKeyword(sSE_KEYWORD_FLAGS, psLine))
		{
			// FLAGS 	FLAG_CAPTION FLAG_TYPEMATIC
			//
			const char *psReference = GetCurrentReference_ParseOnly();
			if (psReference[0])
			{
				static const char sSeperators[] = " \t";
				char sFlags[1024]={0};	// 1024 chars should be enough to store 8 flag names
				strncpy(sFlags, psLine, sizeof(sFlags)-1);
				char *psToken = strtok( sFlags, sSeperators );
				while( psToken != NULL )
				{
					// psToken = flag name (in caps)
					//
					Q_strupr(psToken);	// jic
					AddFlagReference( psReference, psToken );

					// read next flag for this string...
					//
					psToken = strtok( NULL, sSeperators );
				}
			}
			else
			{
				psErrorMessage = "Error parsing file: Unexpected \"" sSE_KEYWORD_FLAGS "\"\n";
			}
		}
		else
		if (CheckLineForKeyword(sSE_KEYWORD_ENDMARKER, psLine))
		{
			// ENDMARKER
			//
			m_bEndMarkerFound_ParseOnly = SE_TRUE;	// the only major error checking I bother to do (for file truncation)
		}
		else
		if (!Q_stricmpn(sSE_KEYWORD_LANG, psLine, strlen(sSE_KEYWORD_LANG)))
		{
			// LANG_ENGLISH 	"GUARD:  Good to see you, sir.  Taylor is waiting for you in the clean tent.  We need to get you suited up.  "
			//
			const char *psReference = GetCurrentReference_ParseOnly();
			if ( psReference[0] )
			{
				psLine += strlen(sSE_KEYWORD_LANG);

				// what language is this?...
				//
				const char *psWordEnd = psLine;
				while (*psWordEnd && *psWordEnd != ' ' && *psWordEnd != '\t')
				{
					psWordEnd++;
				}
				char sThisLanguage[1024]={0};
				size_t iCharsToCopy = psWordEnd - psLine;
				if (iCharsToCopy > sizeof(sThisLanguage)-1)
				{
					iCharsToCopy = sizeof(sThisLanguage)-1;
				}
				strncpy(sThisLanguage, psLine, iCharsToCopy);	// already declared as {0} so no need to zero-cap dest buffer

				psLine += strlen(sThisLanguage);
				const char *_psSentence = ConvertCRLiterals_Read( InsideQuotes( psLine ) );

				// Dammit, I hate having to do crap like this just because other people mess up and put
				//	stupid data in their text, so I have to cope with it.
				//
				// note hackery with _psSentence and psSentence because of const-ness. bleurgh. Just don't ask.
				//
				char *psSentence = CopeWithDumbStringData( _psSentence, sThisLanguage );

				if ( m_bLoadingEnglish_ParseOnly )
				{
					// if loading just "english", then go ahead and store it...
					//
					SetString( psReference, psSentence, SE_FALSE );
				}
				else
				{
					// if loading a foreign language...
					//
					SE_BOOL bSentenceIsEnglish = (!Q_stricmp(sThisLanguage,"english")) ? SE_TRUE: SE_FALSE;	// see whether this is the english master or not

					// this check can be omitted, I'm just being extra careful here...
					//
					if ( !bSentenceIsEnglish )
					{
						// basically this is just checking that an .STE file override is the same language as the .STR...
						//
						if (Q_stricmp( m_strLoadingLanguage_ParseOnly.c_str(), sThisLanguage ))
						{
							psErrorMessage = va("Language \"%s\" found when expecting \"%s\"!\n", sThisLanguage, m_strLoadingLanguage_ParseOnly.c_str());
						}
					}

					if (!psErrorMessage)
					{
						SetString( psReference, psSentence, bSentenceIsEnglish );
					}
				}

				Z_Free( psSentence );
			}
			else
			{
				psErrorMessage = "Error parsing file: Unexpected \"" sSE_KEYWORD_LANG "\"\n";
			}
		}
		else
		{
			psErrorMessage = va("Unknown keyword at linestart: \"%s\"\n", psLine);
		}
	}

	return psErrorMessage;
}
Beispiel #22
0
/*
==============
Win_PrintCvarMatches

ydnar: to display cvar values
==============
*/
static void Win_PrintCvarMatches( const char *s ) {
	if ( !Q_stricmpn( s, win_currentMatch, win_acLength ) ) {
		Sys_Print( va( "  ^9%s = ^5%s^0\n", s, Cvar_VariableString( s ) ) );
	}
}
Beispiel #23
0
void CG_Credits_Init( LPCSTR psStripReference, vec4_t *pv4Color)
{
	// could make these into parameters later, but for now...
	//
	ghFontHandle = cgs.media.qhFontMedium;
	gfFontScale = 1.0f;

	memcpy(gv4Color,pv4Color,sizeof(gv4Color));	// memcpy so we can poke into alpha channel

	// first, ask the strlen of the final string...
	//	
	int iStrLen = cgi_SP_GetStringTextString( psStripReference, NULL, 0 );
	if (!iStrLen)
	{
#ifndef FINAL_BUILD
		Com_Printf("WARNING: CG_Credits_Init(): invalid text key :'%s'\n", psStripReference);
#endif
		return; 
	}
	//
	// malloc space to hold it...
	//
	char *psMallocText = (char *) cgi_Z_Malloc( iStrLen+1, TAG_TEMP_WORKSPACE );
	//
	// now get the string...
	//	
	iStrLen = cgi_SP_GetStringTextString( psStripReference, psMallocText, iStrLen+1 );
	//ensure we found a match
	if (!iStrLen)
	{
		assert(0);	// should never get here now, but wtf?
		cgi_Z_Free(psMallocText);
#ifndef FINAL_BUILD
		Com_Printf("WARNING: CG_Credits_Init(): invalid text key :'%s'\n", psStripReference);
#endif
		return; 
	}

	// read whole string in and process as cards, lines etc...
	//
	typedef enum
	{
		eNothing = 0,
		eLine,
		eDotEntry,
		eTitle,
		eCard,
		eFinished,
	} Mode_e;
	Mode_e eMode = eNothing;

	qboolean bCardsFinished = qfalse;
	int iLineNumber = 0;
	const char *psTextParse = psMallocText;
	while (*psTextParse != NULL)
	{
		// read a line...
		//	
		char sLine[MAX_LINE_BYTES];
			 sLine[0]='\0';
		qboolean bWasCommand = qtrue;
		while (1)
		{
			qboolean bIsTrailingPunctuation;
			unsigned int uiLetter = cgi_AnyLanguage_ReadCharFromString(&psTextParse, &bIsTrailingPunctuation);

			// concat onto string so far...
			//
			if (uiLetter == 32 && sLine[0] == '\0')
			{
				continue;	// unless it's a space at the start of a line, in which case ignore it.
			}

			if (uiLetter == '\n' || uiLetter == '\0' )
			{
				// have we got a command word?...
				//
				if (!Q_stricmpn(sLine,"(#",2))
				{
					// yep...
					//
					if (!stricmp(sLine, "(#CARD)"))
					{
						if (!bCardsFinished)
						{
							eMode = eCard;
						}
						else
						{
							#ifndef FINAL_BUILD
							Com_Printf( S_COLOR_YELLOW "CG_Credits_Init(): No current support for cards after scroll!\n" );
							#endif
							eMode = eNothing;
						}
						break;
					}
					else
					if (!stricmp(sLine, "(#TITLE)"))
					{
						eMode = eTitle;
						bCardsFinished = qtrue;
						break;
					}
					else
					if (!stricmp(sLine, "(#LINE)"))
					{
						eMode = eLine;
						bCardsFinished = qtrue;
						break;
					}
					else
					if (!stricmp(sLine, "(#DOTENTRY)"))
					{
						eMode = eDotEntry;
						bCardsFinished = qtrue;
						break;
					}
					else
					{
						#ifndef FINAL_BUILD
						Com_Printf( S_COLOR_YELLOW "CG_Credits_Init(): bad keyword \"%s\"!\n", sLine );
						#endif
						eMode = eNothing;
					}
				}
				else
				{
					// I guess not...
					//
					bWasCommand = qfalse;
					break;
				}
			}
			else
			{
				// must be a letter...
				//
				if (uiLetter > 255)
				{
					Q_strcat(sLine, sizeof(sLine), va("%c%c",uiLetter >> 8, uiLetter & 0xFF));
				}
				else
				{
					Q_strcat(sLine, sizeof(sLine), va("%c",uiLetter & 0xFF));
				}
			}
		}
Beispiel #24
0
/*
============
Cmd_ExecuteString

A complete command line has been parsed, so try to execute it
============
*/
void	Cmd_ExecuteString( const char *text )
{
	cmd_function_t	*cmd, **prev;
	char arg0[MAX_TOKEN_CHARS];
#ifdef PUNKBUSTER
	/* Trap commands going to PunkBuster here */
	if(!Q_stricmpn(text, "pb_sv_", 6))
	{
		if(gamebinary_initialized == qtrue)
			PbSvAddEvent(14, -1, strlen(text), (char*)text);
		
		return;
	}
#endif
	// execute the command line
	Cmd_TokenizeString( text );		
	if ( !Cmd_Argc() ) {
		Cmd_EndTokenizedString( );
		return;		// no tokens
	}

	Q_strncpyz(arg0, Cmd_Argv(0), sizeof(arg0));
	
	//Legacy fallback
	if(!Q_stricmpn(arg0, "dvar", 4))
	{
		arg0[0] = 'c';
	}else if(!Q_stricmpn(arg0, "auth", 4)){
		if(!Q_stricmp(arg0, "authChangePassword"))
		{
			Q_strncpyz(arg0, "changePassword", sizeof(arg0));
			Com_PrintWarning("\"authchangePassword\" is deprecated and will be removed soon. Use \"changePassword\" instead\n");
		}
		else if(!Q_stricmp(arg0, "authSetAdmin"))
		{
			Q_strncpyz(arg0, "AdminAddAdminWithPassword", sizeof(arg0));
			Com_PrintWarning("\"authSetAdmin\" is deprecated and will be removed soon. Use \"AdminAddAdminWithPassword\" instead\n");
		}
		else if(!Q_stricmp(arg0, "authUnsetAdmin"))
		{
			Q_strncpyz(arg0, "AdminRemoveAdmin", sizeof(arg0));
			Com_PrintWarning("\"authUnsetAdmin\" is deprecated and will be removed soon. Use \"AdminRemoveAdmin\" instead\n");
		}
		else if(!Q_stricmp(arg0, "authListAdmins"))
		{
			Q_strncpyz(arg0, "adminListAdmins", sizeof(arg0));
			Com_PrintWarning("\"authListAdmins\" is deprecated and will be removed soon. Use \"adminListAdmins\" instead\n");
		}
	}else if(!Q_stricmp(arg0, "cmdpowerlist")){
		Q_strncpyz(arg0, "AdminListCommands", sizeof(arg0));
		Com_PrintWarning("\"cmdpowerlist\" is deprecated and will be removed soon. Use \"AdminListCommands\" instead\n");
	}
	else if(!Q_stricmp(arg0, "setCmdMinPower")){
		Q_strncpyz(arg0, "AdminChangeCommandPower", sizeof(arg0));
		Com_PrintWarning("\"setCmdMinPower\" is deprecated and will be removed soon. Use \"AdminChangeCommandPower\" instead\n");
	}
	// check registered command functions	
	for ( prev = &cmd_functions ; *prev ; prev = &cmd->next ) {
		cmd = *prev;
		if ( !Q_stricmp( arg0, cmd->name ) ) {
			// rearrange the links so that the command will be
			// near the head of the list next time it is used
			*prev = cmd->next;
			cmd->next = cmd_functions;
			cmd_functions = cmd;

			// perform the action
			if ( !cmd->function ) {
				// let the cgame or game handle it
				break;
			} else {
				cmd->function ();
			}
			Cmd_EndTokenizedString( );
			return;
		}
	}
	
	// check cvars
	if ( Cvar_Command() ) {
		Cmd_EndTokenizedString( );
		return;
	}

	// check server game commands
	if ( com_sv_running && com_sv_running->boolean && SV_GameCommand() ) {
		Cmd_EndTokenizedString( );
		return;
	}

	Cmd_EndTokenizedString( );

	if(!Q_stricmpn(arg0, "bind", 4))
		return;

	if(!Q_stricmpn(arg0, "unbindall", 9))
		return;

	if(!Q_stricmpn(arg0, "con_showchannel", 15))
		return;

	Com_Printf("Bad command or cvar: %s\n", arg0);
}
Beispiel #25
0
qboolean BG_ParseRankNames( char* fileName, rankNames_t rankNames[] ) {
	fileHandle_t	f;
	int				file_len;
	char			charText[20000];
	char*			textPtr;
	char*			token;
	int				i = 0;

	file_len = trap_FS_FOpenFile( fileName, &f, FS_READ );

	if ( file_len<= 0 ) {
		return qfalse;
	}

	if ( file_len >= ( sizeof(charText) - 1) ) {
		Com_Printf( S_COLOR_RED "File length of %s is too long.\n", fileName );
	}

	memset( &charText, 0, sizeof( charText ) );
	memset( rankNames, 0, sizeof( rankNames ) );

	trap_FS_Read( charText, file_len, f );

	charText[file_len] = 0;

	trap_FS_FCloseFile( f );

	COM_BeginParseSession();

	textPtr = charText;

	token = COM_Parse( &textPtr );

	if ( !token[0] ) {
		Com_Printf( S_COLOR_RED "No data found in buffer: %s\n", fileName );
		return qfalse;
	}

	if ( Q_stricmpn( token, "{", 1 ) ) {
		Com_Printf( S_COLOR_RED "No beginning { found in %s\n", fileName );
		return qfalse;
	}

	//Parse out the default cell.  Default has no names anyway,
	//but in case a n00bie modder put names in anyway.
	SkipBracedSection( &textPtr );

	while( 1 ) {
		//lastPtr = textPtr;
		token = COM_Parse( &textPtr );
		if( !token[0] ) {
			break;
		}

		if ( i >= MAX_RANKS ) {
			break;
		}

		//If we hit an open brace (ie, assuming we hit the start of a new rank cell)
		if ( !Q_stricmpn( token, "{", 1 ) ) {
			while ( 1 ) {
				token = COM_Parse( &textPtr );
				if( !token[0] ) {
					break;
				}

				//We hit a MenuTexture entry, since this uses { symbols, we'll skip these to stop errors.
				if ( !Q_stricmpn( token, "MenuTexture", 11 ) ) {
					SkipRestOfLine( &textPtr );
					continue;
				}

				if ( !Q_stricmpn( token, "ConsoleName", 11) ) {
					if ( COM_ParseString( &textPtr, &token ) ) {
						continue;
					}

					Q_strncpyz( rankNames[i].consoleName, token, sizeof( rankNames[i].consoleName ) );

					continue;
				}
				else if ( !Q_stricmpn( token, "FormalName", 10) ) {
					if ( COM_ParseString( &textPtr, &token ) ) {
						continue;
					}

					Q_strncpyz( rankNames[i].formalName, token, sizeof( rankNames[i].formalName ) );

					continue;
				}
				//We hit the end of the cell.
				else if ( !Q_stricmpn( token, "}", 1 ) ) {
					break;
				}
			}

			//Error check.  If we didn't get both a formal and console name, pwn the caller. ;P
			if ( !rankNames[i].consoleName[0] || !rankNames[i].formalName[0] ) {
				Com_Printf( S_COLOR_RED "One or more rank names were not found in rank#: %i\n", i );
				return qfalse;
			}
			else {
				i++;
			}
		}
	}
	return qtrue;
}
Beispiel #26
0
/*
===============
RE_RegisterSkin

===============
*/
qhandle_t RE_RegisterSkin(const char *name)
{
	qhandle_t       hSkin;
	skin_t         *skin;
	skinSurface_t  *surf;
	skinModel_t    *model;		//----(SA) added
	char           *text, *text_p;
	char           *token;
	char            surfName[MAX_QPATH];

	if(!name || !name[0])
	{
		Com_Printf("Empty name passed to RE_RegisterSkin\n");
		return 0;
	}

	if(strlen(name) >= MAX_QPATH)
	{
		Com_Printf("Skin name exceeds MAX_QPATH\n");
		return 0;
	}


	// see if the skin is already loaded
	for(hSkin = 1; hSkin < tr.numSkins; hSkin++)
	{
		skin = tr.skins[hSkin];
		if(!Q_stricmp(skin->name, name))
		{
			if(skin->numSurfaces == 0)
			{
				return 0;		// default skin
			}
			return hSkin;
		}
	}

	// allocate a new skin
	if(tr.numSkins == MAX_SKINS)
	{
		ri.Printf(PRINT_WARNING, "WARNING: RE_RegisterSkin( '%s' ) MAX_SKINS hit\n", name);
		return 0;
	}

//----(SA)  moved things around slightly to fix the problem where you restart
//          a map that has ai characters who had invalid skin names entered
//          in thier "skin" or "head" field

	// make sure the render thread is stopped
	R_SyncRenderThread();

#if 0
	// If not a .skin file, load as a single shader
	if(strcmp(name + strlen(name) - 5, ".skin"))
	{
		skin->numSurfaces = 1;
		skin->surfaces[0] = ri.Hunk_Alloc(sizeof(skin->surfaces[0]), h_low);
		skin->surfaces[0]->shader = R_FindShader(name, SHADER_3D_DYNAMIC, true);
		return hSkin;
	}
#endif

	// load and parse the skin file
	ri.FS_ReadFile(name, (void **)&text);
	if(!text)
	{
		return 0;
	}

	tr.numSkins++;
	skin = (skin_t*)ri.Hunk_Alloc(sizeof(skin_t), h_low);
	tr.skins[hSkin] = skin;
	Q_strncpyz(skin->name, name, sizeof(skin->name));
	skin->numSurfaces = 0;
	skin->numModels = 0;		//----(SA) added

//----(SA)  end

	text_p = text;
	while(text_p && *text_p)
	{
		// get surface name
		token = CommaParse(&text_p);
		Q_strncpyz(surfName, token, sizeof(surfName));

		if(!token[0])
		{
			break;
		}
		// lowercase the surface name so skin compares are faster
		Q_strlwr(surfName);

		if(*text_p == ',')
		{
			text_p++;
		}

		if(!Q_stricmpn(token, "tag_", 4))
		{
			continue;
		}

		if(!Q_stricmpn(token, "md3_", 4))
		{
			// this is specifying a model
			model = skin->models[skin->numModels] = (skinModel_t*)ri.Hunk_Alloc(sizeof(*skin->models[0]), h_low);
			Q_strncpyz(model->type, token, sizeof(model->type));
			model->hash = Com_HashKey(model->type, sizeof(model->type));

			// get the model name
			token = CommaParse(&text_p);

			Q_strncpyz(model->model, token, sizeof(model->model));

			skin->numModels++;
			continue;
		}

		// parse the shader name
		token = CommaParse(&text_p);

		surf = skin->surfaces[skin->numSurfaces] = (skinSurface_t*)ri.Hunk_Alloc(sizeof(*skin->surfaces[0]), h_low);
		Q_strncpyz(surf->name, surfName, sizeof(surf->name));

		// RB: bspSurface not not have ::hash yet
//		surf->hash = Com_HashKey(surf->name, sizeof(surf->name));
		surf->shader = R_FindShader(token, SHADER_3D_DYNAMIC, true);
		skin->numSurfaces++;
	}

	ri.FS_FreeFile(text);

	// never let a skin have 0 shaders
	if(skin->numSurfaces == 0)
	{
		return 0;				// use default skin
	}

	return hSkin;
}
Beispiel #27
0
qboolean R_LoadPSK(model_t *mod, void *buffer, int bufferSize, const char *modName)
{
	int         i, j, k;
	memStream_t *stream = NULL;

	axChunkHeader_t chunkHeader;

	int       numPoints;
	axPoint_t *point;
	axPoint_t *points = NULL;

	int        numVertexes;
	axVertex_t *vertex;
	axVertex_t *vertexes = NULL;

	//int       numSmoothGroups;
	int          numTriangles;
	axTriangle_t *triangle;
	axTriangle_t *triangles = NULL;

	int          numMaterials;
	axMaterial_t *material;
	axMaterial_t *materials = NULL;

	int               numReferenceBones;
	axReferenceBone_t *refBone;
	axReferenceBone_t *refBones = NULL;

	int            numWeights;
	axBoneWeight_t *axWeight;
	axBoneWeight_t *axWeights = NULL;

	md5Model_t  *md5;
	md5Bone_t   *md5Bone;
	md5Weight_t *weight;

	vec3_t boneOrigin;
	quat_t boneQuat;
	//mat4_t        boneMat;

	int materialIndex, oldMaterialIndex;

	int numRemaining;

	growList_t sortedTriangles;
	growList_t vboVertexes;
	growList_t vboTriangles;
	growList_t vboSurfaces;

	int numBoneReferences;
	int boneReferences[MAX_BONES];

	mat4_t unrealToQuake;

#define DeallocAll() Com_Dealloc(materials); \
	Com_Dealloc(points); \
	Com_Dealloc(vertexes); \
	Com_Dealloc(triangles); \
	Com_Dealloc(refBones); \
	Com_Dealloc(axWeights); \
	FreeMemStream(stream);

	//MatrixSetupScale(unrealToQuake, 1, -1, 1);
	mat4_from_angles(unrealToQuake, 0, 90, 0);

	stream = AllocMemStream(buffer, bufferSize);
	GetChunkHeader(stream, &chunkHeader);

	// check indent again
	if (Q_stricmpn(chunkHeader.ident, "ACTRHEAD", 8))
	{
		Ren_Warning("R_LoadPSK: '%s' has wrong chunk indent ('%s' should be '%s')\n", modName, chunkHeader.ident, "ACTRHEAD");
		DeallocAll();
		return qfalse;
	}

	PrintChunkHeader(&chunkHeader);

	mod->type      = MOD_MD5;
	mod->dataSize += sizeof(md5Model_t);
	md5            = mod->md5 = ri.Hunk_Alloc(sizeof(md5Model_t), h_low);

	// read points
	GetChunkHeader(stream, &chunkHeader);

	if (Q_stricmpn(chunkHeader.ident, "PNTS0000", 8))
	{
		Ren_Warning("R_LoadPSK: '%s' has wrong chunk indent ('%s' should be '%s')\n", modName, chunkHeader.ident, "PNTS0000");
		DeallocAll();
		return qfalse;
	}

	if (chunkHeader.dataSize != sizeof(axPoint_t))
	{
		Ren_Warning("R_LoadPSK: '%s' has wrong chunk dataSize ('%i' should be '%i')\n", modName, chunkHeader.dataSize, ( int ) sizeof(axPoint_t));
		DeallocAll();
		return qfalse;
	}

	PrintChunkHeader(&chunkHeader);

	numPoints = chunkHeader.numData;
	points    = Com_Allocate(numPoints * sizeof(axPoint_t));

	for (i = 0, point = points; i < numPoints; i++, point++)
	{
		point->point[0] = MemStreamGetFloat(stream);
		point->point[1] = MemStreamGetFloat(stream);
		point->point[2] = MemStreamGetFloat(stream);

#if 0
		// HACK convert from Unreal coordinate system to the Quake one
		MatrixTransformPoint2(unrealToQuake, point->point);
#endif
	}

	// read vertices
	GetChunkHeader(stream, &chunkHeader);

	if (Q_stricmpn(chunkHeader.ident, "VTXW0000", 8))
	{
		Ren_Warning("R_LoadPSK: '%s' has wrong chunk indent ('%s' should be '%s')\n", modName, chunkHeader.ident, "VTXW0000");
		DeallocAll();
		return qfalse;
	}

	if (chunkHeader.dataSize != sizeof(axVertex_t))
	{
		Ren_Warning("R_LoadPSK: '%s' has wrong chunk dataSize ('%i' should be '%i')\n", modName, chunkHeader.dataSize, ( int ) sizeof(axVertex_t));
		DeallocAll();
		return qfalse;
	}

	PrintChunkHeader(&chunkHeader);

	numVertexes = chunkHeader.numData;
	vertexes    = Com_Allocate(numVertexes * sizeof(axVertex_t));

	{
		int tmpVertexInt = -1; // tmp vertex member values - MemStreamGet functions return -1 if they fail
		                       // now we print a warning if they do or abort if pointIndex is invalid

		for (i = 0, vertex = vertexes; i < numVertexes; i++, vertex++)
		{
			tmpVertexInt = MemStreamGetShort(stream);
			if (tmpVertexInt < 0 || tmpVertexInt >= numPoints)
			{
				ri.Printf(PRINT_ERROR, "R_LoadPSK: '%s' has vertex with point index out of range (%i while max %i)\n", modName, tmpVertexInt, numPoints);
				DeallocAll();
				return qfalse;
			}
			vertex->pointIndex = tmpVertexInt;

			tmpVertexInt = MemStreamGetShort(stream);
			if (tmpVertexInt < 0)
			{
				Ren_Warning("R_LoadPSK: MemStream NULL or empty (vertex->unknownA)\n");
			}
			vertex->unknownA = tmpVertexInt;

			vertex->st[0] = MemStreamGetFloat(stream);
			if (vertex->st[0] == -1)
			{
				Ren_Warning("R_LoadPSK: MemStream possibly NULL or empty (vertex->st[0])\n");
			}

			vertex->st[1] = MemStreamGetFloat(stream);
			if (vertex->st[1] == -1)
			{
				Ren_Warning("R_LoadPSK: MemStream possibly NULL or empty (vertex->st[1])\n");
			}

			tmpVertexInt = MemStreamGetC(stream);
			if (tmpVertexInt < 0)
			{
				Ren_Warning("R_LoadPSK: MemStream NULL or empty (vertex->materialIndex)\n");
			}
			vertex->materialIndex = tmpVertexInt;

			tmpVertexInt = MemStreamGetC(stream);
			if (tmpVertexInt < 0)
			{
				Ren_Warning("R_LoadPSK: MemStream NULL or empty (vertex->materialIndex)\n");
			}
			vertex->reserved = tmpVertexInt;

			tmpVertexInt = MemStreamGetShort(stream);
			if (tmpVertexInt < 0)
			{
				Ren_Warning("R_LoadPSK: MemStream NULL or empty (vertex->materialIndex)\n");
			}
			vertex->unknownB = tmpVertexInt;
#if 0
			Ren_Print("R_LoadPSK: axVertex_t(%i):\n"
			          "axVertex:pointIndex: %i\n"
			          "axVertex:unknownA: %i\n"
			          "axVertex::st: %f %f\n"
			          "axVertex:materialIndex: %i\n"
			          "axVertex:reserved: %d\n"
			          "axVertex:unknownB: %d\n",
			          i,
			          vertex->pointIndex,
			          vertex->unknownA,
			          vertex->st[0], vertex->st[1],
			          vertex->materialIndex,
			          vertex->reserved,
			          vertex->unknownB);
#endif
		}


		// read triangles
		GetChunkHeader(stream, &chunkHeader);

		if (Q_stricmpn(chunkHeader.ident, "FACE0000", 8))
		{
			Ren_Warning("R_LoadPSK: '%s' has wrong chunk indent ('%s' should be '%s')\n", modName, chunkHeader.ident, "FACE0000");
			DeallocAll();
			return qfalse;
		}

		if (chunkHeader.dataSize != sizeof(axTriangle_t))
		{
			Ren_Warning("R_LoadPSK: '%s' has wrong chunk dataSize ('%i' should be '%i')\n", modName, chunkHeader.dataSize, ( int ) sizeof(axTriangle_t));
			DeallocAll();
			return qfalse;
		}

		PrintChunkHeader(&chunkHeader);

		numTriangles = chunkHeader.numData;
		triangles    = Com_Allocate(numTriangles * sizeof(axTriangle_t));

		for (i = 0, triangle = triangles; i < numTriangles; i++, triangle++)
		{
			for (j = 0; j < 3; j++)
			//for(j = 2; j >= 0; j--)
			{
				tmpVertexInt = MemStreamGetShort(stream);

				if (tmpVertexInt < 0)
				{
					Ren_Warning("R_LoadPSK: '%s' MemStream NULL or empty (triangle->indexes[%i])\n", modName, j);
					DeallocAll();
					return qfalse;
				}

				if (tmpVertexInt >= numVertexes)
				{
					Ren_Warning("R_LoadPSK: '%s' has triangle with vertex index out of range (%i while max %i)\n", modName, tmpVertexInt, numVertexes);
					DeallocAll();
					return qfalse;
				}

				triangle->indexes[j] = tmpVertexInt;
			}

			triangle->materialIndex   = MemStreamGetC(stream);
			triangle->materialIndex2  = MemStreamGetC(stream);
			triangle->smoothingGroups = MemStreamGetLong(stream);
		}
	}
	// read materials
	GetChunkHeader(stream, &chunkHeader);

	if (Q_stricmpn(chunkHeader.ident, "MATT0000", 8))
	{
		Ren_Warning("R_LoadPSK: '%s' has wrong chunk indent ('%s' should be '%s')\n", modName, chunkHeader.ident, "MATT0000");
		DeallocAll();
		return qfalse;
	}

	if (chunkHeader.dataSize != sizeof(axMaterial_t))
	{
		Ren_Warning("R_LoadPSK: '%s' has wrong chunk dataSize ('%i' should be '%i')\n", modName, chunkHeader.dataSize, ( int ) sizeof(axMaterial_t));
		DeallocAll();
		return qfalse;
	}

	PrintChunkHeader(&chunkHeader);

	numMaterials = chunkHeader.numData;
	materials    = Com_Allocate(numMaterials * sizeof(axMaterial_t));

	for (i = 0, material = materials; i < numMaterials; i++, material++)
	{
		MemStreamRead(stream, material->name, sizeof(material->name));

		Ren_Print("R_LoadPSK: material name: '%s'\n", material->name);

		material->shaderIndex = MemStreamGetLong(stream);
		material->polyFlags   = MemStreamGetLong(stream);
		material->auxMaterial = MemStreamGetLong(stream);
		material->auxFlags    = MemStreamGetLong(stream);
		material->lodBias     = MemStreamGetLong(stream);
		material->lodStyle    = MemStreamGetLong(stream);
	}

	for (i = 0, vertex = vertexes; i < numVertexes; i++, vertex++)
	{
		if (vertex->materialIndex < 0 || vertex->materialIndex >= numMaterials)
		{
			Ren_Warning("R_LoadPSK: '%s' has vertex with material index out of range (%i while max %i)\n", modName, vertex->materialIndex, numMaterials);
			DeallocAll();
			return qfalse;
		}
	}

	for (i = 0, triangle = triangles; i < numTriangles; i++, triangle++)
	{
		if (triangle->materialIndex < 0 || triangle->materialIndex >= numMaterials)
		{
			Ren_Warning("R_LoadPSK: '%s' has triangle with material index out of range (%i while max %i)\n", modName, triangle->materialIndex, numMaterials);
			DeallocAll();
			return qfalse;
		}
	}

	// read reference bones
	GetChunkHeader(stream, &chunkHeader);

	if (Q_stricmpn(chunkHeader.ident, "REFSKELT", 8))
	{
		Ren_Warning("R_LoadPSK: '%s' has wrong chunk indent ('%s' should be '%s')\n", modName, chunkHeader.ident, "REFSKELT");
		DeallocAll();
		return qfalse;
	}

	if (chunkHeader.dataSize != sizeof(axReferenceBone_t))
	{
		Ren_Warning("R_LoadPSK: '%s' has wrong chunk dataSize ('%i' should be '%i')\n", modName, chunkHeader.dataSize, ( int ) sizeof(axReferenceBone_t));
		DeallocAll();
		return qfalse;
	}

	PrintChunkHeader(&chunkHeader);

	numReferenceBones = chunkHeader.numData;
	refBones          = Com_Allocate(numReferenceBones * sizeof(axReferenceBone_t));

	for (i = 0, refBone = refBones; i < numReferenceBones; i++, refBone++)
	{
		MemStreamRead(stream, refBone->name, sizeof(refBone->name));

		//Ren_Print("R_LoadPSK: reference bone name: '%s'\n", refBone->name);

		refBone->flags       = MemStreamGetLong(stream);
		refBone->numChildren = MemStreamGetLong(stream);
		refBone->parentIndex = MemStreamGetLong(stream);

		GetBone(stream, &refBone->bone);

#if 0
		Ren_Print("R_LoadPSK: axReferenceBone_t(%i):\n"
		          "axReferenceBone_t::name: '%s'\n"
		          "axReferenceBone_t::flags: %i\n"
		          "axReferenceBone_t::numChildren %i\n"
		          "axReferenceBone_t::parentIndex: %i\n"
		          "axReferenceBone_t::quat: %f %f %f %f\n"
		          "axReferenceBone_t::position: %f %f %f\n"
		          "axReferenceBone_t::length: %f\n"
		          "axReferenceBone_t::xSize: %f\n"
		          "axReferenceBone_t::ySize: %f\n"
		          "axReferenceBone_t::zSize: %f\n",
		          i,
		          refBone->name,
		          refBone->flags,
		          refBone->numChildren,
		          refBone->parentIndex,
		          refBone->bone.quat[0], refBone->bone.quat[1], refBone->bone.quat[2], refBone->bone.quat[3],
		          refBone->bone.position[0], refBone->bone.position[1], refBone->bone.position[2],
		          refBone->bone.length,
		          refBone->bone.xSize,
		          refBone->bone.ySize,
		          refBone->bone.zSize);
#endif
	}

	// read  bone weights
	GetChunkHeader(stream, &chunkHeader);

	if (Q_stricmpn(chunkHeader.ident, "RAWWEIGHTS", 10))
	{
		Ren_Warning("R_LoadPSK: '%s' has wrong chunk indent ('%s' should be '%s')\n", modName, chunkHeader.ident, "RAWWEIGHTS");
		DeallocAll();
		return qfalse;
	}

	if (chunkHeader.dataSize != sizeof(axBoneWeight_t))
	{
		Ren_Warning("R_LoadPSK: '%s' has wrong chunk dataSize ('%i' should be '%i')\n", modName, chunkHeader.dataSize, ( int ) sizeof(axBoneWeight_t));
		DeallocAll();
		return qfalse;
	}

	PrintChunkHeader(&chunkHeader);

	numWeights = chunkHeader.numData;
	axWeights  = Com_Allocate(numWeights * sizeof(axBoneWeight_t));

	for (i = 0, axWeight = axWeights; i < numWeights; i++, axWeight++)
	{
		axWeight->weight     = MemStreamGetFloat(stream);
		axWeight->pointIndex = MemStreamGetLong(stream);
		axWeight->boneIndex  = MemStreamGetLong(stream);

#if 0
		Ren_Print("R_LoadPSK: axBoneWeight_t(%i):\n"
		          "axBoneWeight_t::weight: %f\n"
		          "axBoneWeight_t::pointIndex %i\n"
		          "axBoneWeight_t::boneIndex: %i\n",
		          i,
		          axWeight->weight,
		          axWeight->pointIndex,
		          axWeight->boneIndex);
#endif
	}

	//
	// convert the model to an internal MD5 representation
	//
	md5->numBones = numReferenceBones;

	// calc numMeshes <number>

	/*
	numSmoothGroups = 0;
	for(i = 0, triangle = triangles; i < numTriangles; i++, triangle++)
	{
	        if(triangle->smoothingGroups)
	        {

	        }
	}
	*/

	if (md5->numBones < 1)
	{
		Ren_Warning("R_LoadPSK: '%s' has no bones\n", modName);
		DeallocAll();
		return qfalse;
	}

	if (md5->numBones > MAX_BONES)
	{
		Ren_Warning("R_LoadPSK: '%s' has more than %i bones (%i)\n", modName, MAX_BONES, md5->numBones);
		DeallocAll();
		return qfalse;
	}

	//Ren_Print("R_LoadPSK: '%s' has %i bones\n", modName, md5->numBones);

	// copy all reference bones
	md5->bones = ri.Hunk_Alloc(sizeof(*md5Bone) * md5->numBones, h_low);

	for (i = 0, md5Bone = md5->bones, refBone = refBones; i < md5->numBones; i++, md5Bone++, refBone++)
	{
		Q_strncpyz(md5Bone->name, refBone->name, sizeof(md5Bone->name));

		if (i == 0)
		{
			md5Bone->parentIndex = refBone->parentIndex - 1;
		}
		else
		{
			md5Bone->parentIndex = refBone->parentIndex;
		}

		//Ren_Print("R_LoadPSK: '%s' has bone '%s' with parent index %i\n", modName, md5Bone->name, md5Bone->parentIndex);

		if (md5Bone->parentIndex >= md5->numBones)
		{
			DeallocAll();
			Ren_Drop("R_LoadPSK: '%s' has bone '%s' with bad parent index %i while numBones is %i", modName,
			         md5Bone->name, md5Bone->parentIndex, md5->numBones);
		}

		for (j = 0; j < 3; j++)
		{
			boneOrigin[j] = refBone->bone.position[j];
		}

		// I have really no idea why the .psk format stores the first quaternion with inverted quats.
		// Furthermore only the X and Z components of the first quat are inverted ?!?!
		if (i == 0)
		{
			boneQuat[0] = refBone->bone.quat[0];
			boneQuat[1] = -refBone->bone.quat[1];
			boneQuat[2] = refBone->bone.quat[2];
			boneQuat[3] = refBone->bone.quat[3];
		}
		else
		{
			boneQuat[0] = -refBone->bone.quat[0];
			boneQuat[1] = -refBone->bone.quat[1];
			boneQuat[2] = -refBone->bone.quat[2];
			boneQuat[3] = refBone->bone.quat[3];
		}

		VectorCopy(boneOrigin, md5Bone->origin);
		//MatrixTransformPoint(unrealToQuake, boneOrigin, md5Bone->origin);

		quat_copy(boneQuat, md5Bone->rotation);

		//QuatClear(md5Bone->rotation);

#if 0
		Ren_Print("R_LoadPSK: md5Bone_t(%i):\n"
		          "md5Bone_t::name: '%s'\n"
		          "md5Bone_t::parentIndex: %i\n"
		          "md5Bone_t::quat: %f %f %f %f\n"
		          "md5bone_t::position: %f %f %f\n",
		          i,
		          md5Bone->name,
		          md5Bone->parentIndex,
		          md5Bone->rotation[0], md5Bone->rotation[1], md5Bone->rotation[2], md5Bone->rotation[3],
		          md5Bone->origin[0], md5Bone->origin[1], md5Bone->origin[2]);
#endif

		if (md5Bone->parentIndex >= 0)
		{
			vec3_t rotated;
			quat_t quat;

			md5Bone_t *parent;

			parent = &md5->bones[md5Bone->parentIndex];

			QuatTransformVector(parent->rotation, md5Bone->origin, rotated);
			//QuatTransformVector(md5Bone->rotation, md5Bone->origin, rotated);

			VectorAdd(parent->origin, rotated, md5Bone->origin);

			QuatMultiply1(parent->rotation, md5Bone->rotation, quat);
			quat_copy(quat, md5Bone->rotation);
		}

		MatrixSetupTransformFromQuat(md5Bone->inverseTransform, md5Bone->rotation, md5Bone->origin);
		mat4_inverse_self(md5Bone->inverseTransform);

#if 0
		Ren_Print("R_LoadPSK: md5Bone_t(%i):\n"
		          "md5Bone_t::name: '%s'\n"
		          "md5Bone_t::parentIndex: %i\n"
		          "md5Bone_t::quat: %f %f %f %f\n"
		          "md5bone_t::position: %f %f %f\n",
		          i,
		          md5Bone->name,
		          md5Bone->parentIndex,
		          md5Bone->rotation[0], md5Bone->rotation[1], md5Bone->rotation[2], md5Bone->rotation[3],
		          md5Bone->origin[0], md5Bone->origin[1], md5Bone->origin[2]);
#endif
	}

	Com_InitGrowList(&vboVertexes, 10000);

	for (i = 0, vertex = vertexes; i < numVertexes; i++, vertex++)
	{
		md5Vertex_t *vboVert = Com_Allocate(sizeof(*vboVert));

		for (j = 0; j < 3; j++)
		{
			vboVert->position[j] = points[vertex->pointIndex].point[j];
		}

		vboVert->texCoords[0] = vertex->st[0];
		vboVert->texCoords[1] = vertex->st[1];

		// find number of associated weights
		vboVert->numWeights = 0;

		for (j = 0, axWeight = axWeights; j < numWeights; j++, axWeight++)
		{
			if (axWeight->pointIndex == vertex->pointIndex && axWeight->weight > 0.0f)
			{
				vboVert->numWeights++;
			}
		}

		if (vboVert->numWeights > MAX_WEIGHTS)
		{
			DeallocAll();
			Ren_Drop("R_LoadPSK: vertex %i requires more weights %i than the maximum of %i in model '%s'", i, vboVert->numWeights, MAX_WEIGHTS, modName);
			//Ren_Warning( "R_LoadPSK: vertex %i requires more weights %i than the maximum of %i in model '%s'\n", i, vboVert->numWeights, MAX_WEIGHTS, modName);
		}

		vboVert->weights = ri.Hunk_Alloc(sizeof(*vboVert->weights) * vboVert->numWeights, h_low);

		for (j = 0, axWeight = axWeights, k = 0; j < numWeights; j++, axWeight++)
		{
			if (axWeight->pointIndex == vertex->pointIndex && axWeight->weight > 0.0f)
			{
				weight = ri.Hunk_Alloc(sizeof(*weight), h_low);

				weight->boneIndex  = axWeight->boneIndex;
				weight->boneWeight = axWeight->weight;

				// FIXME?
				weight->offset[0] = refBones[axWeight->boneIndex].bone.xSize;
				weight->offset[1] = refBones[axWeight->boneIndex].bone.ySize;
				weight->offset[2] = refBones[axWeight->boneIndex].bone.zSize;

				vboVert->weights[k++] = weight;
			}
		}

		Com_AddToGrowList(&vboVertexes, vboVert);
	}

	ClearBounds(md5->bounds[0], md5->bounds[1]);

	for (i = 0, vertex = vertexes; i < numVertexes; i++, vertex++)
	{
		AddPointToBounds(points[vertex->pointIndex].point, md5->bounds[0], md5->bounds[1]);
	}

#if 0
	Ren_Print("R_LoadPSK: AABB (%i %i %i) (%i %i %i)\n",
	          ( int ) md5->bounds[0][0],
	          ( int ) md5->bounds[0][1],
	          ( int ) md5->bounds[0][2],
	          ( int ) md5->bounds[1][0],
	          ( int ) md5->bounds[1][1],
	          ( int ) md5->bounds[1][2]);
#endif

	// sort triangles
	qsort(triangles, numTriangles, sizeof(axTriangle_t), CompareTrianglesByMaterialIndex);

	Com_InitGrowList(&sortedTriangles, 1000);

	for (i = 0, triangle = triangles; i < numTriangles; i++, triangle++)
	{
		skelTriangle_t *sortTri = Com_Allocate(sizeof(*sortTri));

		for (j = 0; j < 3; j++)
		{
			sortTri->indexes[j]  = triangle->indexes[j];
			sortTri->vertexes[j] = Com_GrowListElement(&vboVertexes, triangle->indexes[j]);
		}

		sortTri->referenced = qfalse;

		Com_AddToGrowList(&sortedTriangles, sortTri);
	}

	// calc tangent spaces
#if 1
	{
		md5Vertex_t *v0, *v1, *v2;
		const float *p0, *p1, *p2;
		const float *t0, *t1, *t2;
		vec3_t      tangent = { 0, 0, 0 };
		vec3_t      binormal;
		vec3_t      normal;

		for (j = 0; j < vboVertexes.currentElements; j++)
		{
			v0 = Com_GrowListElement(&vboVertexes, j);

			VectorClear(v0->tangent);
			VectorClear(v0->binormal);
			VectorClear(v0->normal);
		}

		for (j = 0; j < sortedTriangles.currentElements; j++)
		{
			skelTriangle_t *tri = Com_GrowListElement(&sortedTriangles, j);

			v0 = Com_GrowListElement(&vboVertexes, tri->indexes[0]);
			v1 = Com_GrowListElement(&vboVertexes, tri->indexes[1]);
			v2 = Com_GrowListElement(&vboVertexes, tri->indexes[2]);

			p0 = v0->position;
			p1 = v1->position;
			p2 = v2->position;

			t0 = v0->texCoords;
			t1 = v1->texCoords;
			t2 = v2->texCoords;

#if 1
			R_CalcTangentSpace(tangent, binormal, normal, p0, p1, p2, t0, t1, t2);
#else
			R_CalcNormalForTriangle(normal, p0, p1, p2);
			R_CalcTangentsForTriangle(tangent, binormal, p0, p1, p2, t0, t1, t2);
#endif

			for (k = 0; k < 3; k++)
			{
				float *v;

				v0 = Com_GrowListElement(&vboVertexes, tri->indexes[k]);

				v = v0->tangent;
				VectorAdd(v, tangent, v);

				v = v0->binormal;
				VectorAdd(v, binormal, v);

				v = v0->normal;
				VectorAdd(v, normal, v);
			}
		}

		for (j = 0; j < vboVertexes.currentElements; j++)
		{
			v0 = Com_GrowListElement(&vboVertexes, j);

			VectorNormalize(v0->tangent);
			VectorNormalize(v0->binormal);
			VectorNormalize(v0->normal);
		}
	}
#else
	{
		float       bb, s, t;
		vec3_t      bary;
		vec3_t      faceNormal;
		md5Vertex_t *dv[3];

		for (j = 0; j < sortedTriangles.currentElements; j++)
		{
			skelTriangle_t *tri = Com_GrowListElement(&sortedTriangles, j);

			dv[0] = Com_GrowListElement(&vboVertexes, tri->indexes[0]);
			dv[1] = Com_GrowListElement(&vboVertexes, tri->indexes[1]);
			dv[2] = Com_GrowListElement(&vboVertexes, tri->indexes[2]);

			R_CalcNormalForTriangle(faceNormal, dv[0]->position, dv[1]->position, dv[2]->position);

			// calculate barycentric basis for the triangle
			bb = (dv[1]->texCoords[0] - dv[0]->texCoords[0]) * (dv[2]->texCoords[1] - dv[0]->texCoords[1]) - (dv[2]->texCoords[0] - dv[0]->texCoords[0]) * (dv[1]->texCoords[1] -
			                                                                                                                                                dv[0]->texCoords[1]);

			if (fabs(bb) < 0.00000001f)
			{
				continue;
			}

			// do each vertex
			for (k = 0; k < 3; k++)
			{
				// calculate s tangent vector
				s       = dv[k]->texCoords[0] + 10.0f;
				t       = dv[k]->texCoords[1];
				bary[0] = ((dv[1]->texCoords[0] - s) * (dv[2]->texCoords[1] - t) - (dv[2]->texCoords[0] - s) * (dv[1]->texCoords[1] - t)) / bb;
				bary[1] = ((dv[2]->texCoords[0] - s) * (dv[0]->texCoords[1] - t) - (dv[0]->texCoords[0] - s) * (dv[2]->texCoords[1] - t)) / bb;
				bary[2] = ((dv[0]->texCoords[0] - s) * (dv[1]->texCoords[1] - t) - (dv[1]->texCoords[0] - s) * (dv[0]->texCoords[1] - t)) / bb;

				dv[k]->tangent[0] = bary[0] * dv[0]->position[0] + bary[1] * dv[1]->position[0] + bary[2] * dv[2]->position[0];
				dv[k]->tangent[1] = bary[0] * dv[0]->position[1] + bary[1] * dv[1]->position[1] + bary[2] * dv[2]->position[1];
				dv[k]->tangent[2] = bary[0] * dv[0]->position[2] + bary[1] * dv[1]->position[2] + bary[2] * dv[2]->position[2];

				VectorSubtract(dv[k]->tangent, dv[k]->position, dv[k]->tangent);
				VectorNormalize(dv[k]->tangent);

				// calculate t tangent vector (binormal)
				s       = dv[k]->texCoords[0];
				t       = dv[k]->texCoords[1] + 10.0f;
				bary[0] = ((dv[1]->texCoords[0] - s) * (dv[2]->texCoords[1] - t) - (dv[2]->texCoords[0] - s) * (dv[1]->texCoords[1] - t)) / bb;
				bary[1] = ((dv[2]->texCoords[0] - s) * (dv[0]->texCoords[1] - t) - (dv[0]->texCoords[0] - s) * (dv[2]->texCoords[1] - t)) / bb;
				bary[2] = ((dv[0]->texCoords[0] - s) * (dv[1]->texCoords[1] - t) - (dv[1]->texCoords[0] - s) * (dv[0]->texCoords[1] - t)) / bb;

				dv[k]->binormal[0] = bary[0] * dv[0]->position[0] + bary[1] * dv[1]->position[0] + bary[2] * dv[2]->position[0];
				dv[k]->binormal[1] = bary[0] * dv[0]->position[1] + bary[1] * dv[1]->position[1] + bary[2] * dv[2]->position[1];
				dv[k]->binormal[2] = bary[0] * dv[0]->position[2] + bary[1] * dv[1]->position[2] + bary[2] * dv[2]->position[2];

				VectorSubtract(dv[k]->binormal, dv[k]->position, dv[k]->binormal);
				VectorNormalize(dv[k]->binormal);

				// calculate the normal as cross product N=TxB
#if 0
				CrossProduct(dv[k]->tangent, dv[k]->binormal, dv[k]->normal);
				VectorNormalize(dv[k]->normal);

				// Gram-Schmidt orthogonalization process for B
				// compute the cross product B=NxT to obtain
				// an orthogonal basis
				CrossProduct(dv[k]->normal, dv[k]->tangent, dv[k]->binormal);

				if (DotProduct(dv[k]->normal, faceNormal) < 0)
				{
					VectorInverse(dv[k]->normal);
					//VectorInverse(dv[k]->tangent);
					//VectorInverse(dv[k]->binormal);
				}

#else
				VectorAdd(dv[k]->normal, faceNormal, dv[k]->normal);
#endif
			}
		}

#if 1

		for (j = 0; j < vboVertexes.currentElements; j++)
		{
			dv[0] = Com_GrowListElement(&vboVertexes, j);
			//VectorNormalize(dv[0]->tangent);
			//VectorNormalize(dv[0]->binormal);
			VectorNormalize(dv[0]->normal);
		}

#endif
	}
#endif

#if 0
	{
		md5Vertex_t *v0, *v1;

		// do another extra smoothing for normals to avoid flat shading
		for (j = 0; j < vboVertexes.currentElements; j++)
		{
			v0 = Com_GrowListElement(&vboVertexes, j);

			for (k = 0; k < vboVertexes.currentElements; k++)
			{
				if (j == k)
				{
					continue;
				}

				v1 = Com_GrowListElement(&vboVertexes, k);

				if (VectorCompare(v0->position, v1->position))
				{
					VectorAdd(v0->position, v1->normal, v0->normal);
				}
			}

			VectorNormalize(v0->normal);
		}
	}
#endif

	// split the surfaces into VBO surfaces by the maximum number of GPU vertex skinning bones
	Com_InitGrowList(&vboSurfaces, 10);

	materialIndex = oldMaterialIndex = -1;

	for (i = 0; i < numTriangles; i++)
	{
		triangle      = &triangles[i];
		materialIndex = triangle->materialIndex;

		if (materialIndex != oldMaterialIndex)
		{
			oldMaterialIndex = materialIndex;

			numRemaining = sortedTriangles.currentElements - i;

			while (numRemaining)
			{
				numBoneReferences = 0;
				Com_Memset(boneReferences, 0, sizeof(boneReferences));

				Com_InitGrowList(&vboTriangles, 1000);

				for (j = i; j < sortedTriangles.currentElements; j++)
				{
					skelTriangle_t *sortTri;

					triangle      = &triangles[j];
					materialIndex = triangle->materialIndex;

					if (materialIndex != oldMaterialIndex)
					{
						continue;
					}

					sortTri = Com_GrowListElement(&sortedTriangles, j);

					if (sortTri->referenced)
					{
						continue;
					}

					if (AddTriangleToVBOTriangleList(&vboTriangles, sortTri, &numBoneReferences, boneReferences))
					{
						sortTri->referenced = qtrue;
					}
				}

				for (j = 0; j < MAX_BONES; j++)
				{
					if (boneReferences[j] > 0)
					{
						Ren_Print("R_LoadPSK: referenced bone: '%s'\n", (j < numReferenceBones) ? refBones[j].name : NULL);
					}
				}

				if (!vboTriangles.currentElements)
				{
					Ren_Warning("R_LoadPSK: could not add triangles to a remaining VBO surface for model '%s'\n", modName);
					break;
				}

				// FIXME skinIndex
				AddSurfaceToVBOSurfacesList2(&vboSurfaces, &vboTriangles, &vboVertexes, md5, vboSurfaces.currentElements, materials[oldMaterialIndex].name, numBoneReferences, boneReferences);
				numRemaining -= vboTriangles.currentElements;

				Com_DestroyGrowList(&vboTriangles);
			}
		}
	}

	for (j = 0; j < sortedTriangles.currentElements; j++)
	{
		skelTriangle_t *sortTri = Com_GrowListElement(&sortedTriangles, j);
		Com_Dealloc(sortTri);
	}

	Com_DestroyGrowList(&sortedTriangles);

	for (j = 0; j < vboVertexes.currentElements; j++)
	{
		md5Vertex_t *v = Com_GrowListElement(&vboVertexes, j);
		Com_Dealloc(v);
	}

	Com_DestroyGrowList(&vboVertexes);

	// move VBO surfaces list to hunk
	md5->numVBOSurfaces = vboSurfaces.currentElements;
	md5->vboSurfaces    = ri.Hunk_Alloc(md5->numVBOSurfaces * sizeof(*md5->vboSurfaces), h_low);

	for (i = 0; i < md5->numVBOSurfaces; i++)
	{
		md5->vboSurfaces[i] = ( srfVBOMD5Mesh_t * ) Com_GrowListElement(&vboSurfaces, i);
	}

	Com_DestroyGrowList(&vboSurfaces);

	FreeMemStream(stream);
	Com_Dealloc(points);
	Com_Dealloc(vertexes);
	Com_Dealloc(triangles);
	Com_Dealloc(materials);

	Ren_Developer("%i VBO surfaces created for PSK model '%s'\n", md5->numVBOSurfaces, modName);

	return qtrue;
}
void SV_ExecuteRemoteCmd(int clientnum, const char *msg){
	char sv_outputbuf[SV_OUTPUTBUF_LENGTH];
	char cmd[30];
	char buffer[256];
	char oldinvokerguid[9];
	int i = 0;
	int j = 0;
	int powercmd;
	int power;
	client_t *cl;

        if(!cmdSystemInitialized){
	    SV_SendServerCommand(redirectClient, "e \"Error: Remote control system is not initialized\n\"");
	    Com_Printf("Error: Remote control system is not initialized\n");
            return;
        }


	if(clientnum < 0 || clientnum > 63) return;
	cl = &svs.clients[clientnum];
	redirectClient = cl;

	while ( msg[i] != ' ' && msg[i] != '\0' && msg[i] != '\n' && i < 32 ){
		i++;
	}
	
	if(i > 29 || i < 3) return;
	Q_strncpyz(cmd,msg,i+1);


	//Prevent buffer overflow as well as prevent the execution of priveleged commands by using seperator characters
	Q_strncpyz(buffer,msg,256);
	Q_strchrrepl(buffer,';','\0');
	Q_strchrrepl(buffer,'\n','\0');
	Q_strchrrepl(buffer,'\r','\0');
	// start redirecting all print outputs to the packet

        power = SV_RemoteCmdGetClPower(cl);
        powercmd = Cmd_GetPower(cmd);

	if(powercmd == -1){
            SV_SendServerCommand(redirectClient, "e \"^5Command^2: %s\n^3Command execution failed - Invalid command invoked - Type ^2$cmdlist ^3to get a list of all available commands\"", buffer);
            return;
	}
	if(powercmd > power){
            SV_SendServerCommand(redirectClient, "e \"^5Command^2: %s\n^3Command execution failed - Insufficient power to execute this command.\n^3You need at least ^6%i ^3powerpoints to invoke this command.\n^3Type ^2$cmdlist ^3to get a list of all available commands\"",
            buffer, powercmd);
	    return;
	}
        if(SV_UseUids())
		Com_Printf( "Command execution: %s   Invoked by: %s   InvokerUID: %i Power: %i\n", buffer, cl->name, cl->uid, power);
	else
		Com_Printf( "Command execution: %s   Invoked by: %s   InvokerGUID: %s Power: %i\n", buffer, cl->name, cl->pbguid, power);

	Com_BeginRedirect(sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_ReliableSendRedirect);

	i = cmdInvoker.currentCmdPower;
	cmdInvoker.currentCmdPower = power;
	cmdInvoker.authserver = qfalse;

	if(SV_UseUids()){
		j = cmdInvoker.currentCmdInvoker;
		cmdInvoker.currentCmdInvoker = cl->uid;
	}else{
		Q_strncpyz(oldinvokerguid, cmdInvoker.currentCmdInvokerGuid, sizeof(oldinvokerguid));
		Q_strncpyz(cmdInvoker.currentCmdInvokerGuid, &cl->pbguid[24], sizeof(cmdInvoker.currentCmdInvokerGuid));
	}

	cmdInvoker.clientnum = clientnum;

	Cmd_ExecuteSingleCommand( 0, 0, buffer );

	if(!Q_stricmpn(buffer, "pb_sv_", 6)) PbServerForceProcess();

	SV_SendServerCommand(redirectClient, "e \"^5Command^2: %s\"", buffer);

	cmdInvoker.currentCmdPower = i;
	if(SV_UseUids()){
		cmdInvoker.currentCmdInvoker = j;
	}else{
		//Q_strncpyz(cmdInvoker.currentCmdInvokerGuid, oldinvokerguid, sizeof(cmdInvoker.currentCmdInvokerGuid));
		Q_strncpyz(cmdInvoker.currentCmdInvokerGuid, "N/A", sizeof(cmdInvoker.currentCmdInvokerGuid));
	}
	cmdInvoker.clientnum = -1;

	Com_EndRedirect();
}
Beispiel #29
0
void CG_ParseServerinfo( void ) {
	const char *info = NULL, *tinfo = NULL;
	char *mapname;
	int i;

	info = CG_ConfigString( CS_SERVERINFO );

	cgs.debugMelee = atoi( Info_ValueForKey( info, "g_debugMelee" ) ); //trap->Cvar_GetHiddenVarValue("g_iknowkungfu");
	cgs.stepSlideFix = atoi( Info_ValueForKey( info, "g_stepSlideFix" ) );

	cgs.noSpecMove = atoi( Info_ValueForKey( info, "g_noSpecMove" ) );

	trap->Cvar_Set("bg_fighterAltControl", Info_ValueForKey( info, "bg_fighterAltControl" ));

	cgs.siegeTeamSwitch = atoi( Info_ValueForKey( info, "g_siegeTeamSwitch" ) );

	cgs.showDuelHealths = atoi( Info_ValueForKey( info, "g_showDuelHealths" ) );

	cgs.gametype = atoi( Info_ValueForKey( info, "g_gametype" ) );
	trap->Cvar_Set("g_gametype", va("%i", cgs.gametype));
	cgs.needpass = atoi( Info_ValueForKey( info, "needpass" ) );
	cgs.jediVmerc = atoi( Info_ValueForKey( info, "g_jediVmerc" ) );
	cgs.wDisable = atoi( Info_ValueForKey( info, "wdisable" ) );
	cgs.fDisable = atoi( Info_ValueForKey( info, "fdisable" ) );
	cgs.dmflags = atoi( Info_ValueForKey( info, "dmflags" ) );
	cgs.duel_fraglimit = atoi( Info_ValueForKey( info, "duel_fraglimit" ) );
	cgs.capturelimit = atoi( Info_ValueForKey( info, "capturelimit" ) );

	// reset fraglimit warnings
	i = atoi( Info_ValueForKey( info, "fraglimit" ) );
	if ( cgs.fraglimit < i )
		cg.fraglimitWarnings &= ~(1|2|4);
	cgs.fraglimit = i;

	// reset timelimit warnings
	i = atoi( Info_ValueForKey( info, "timelimit" ) );
	if ( cgs.timelimit != i )
		cg.timelimitWarnings &= ~(1|2);
	cgs.timelimit = i;

	cgs.maxclients = Com_Clampi( 0, MAX_CLIENTS, atoi( Info_ValueForKey( info, "sv_maxclients" ) ) );

	cgs.japp.jp_cinfo = atoi( Info_ValueForKey( info, "jp_cinfo" ) );
	cgs.japp.overbounce = atoi( Info_ValueForKey( info, "pmove_overbounce" ) );
	
	//Raz: Server support flags
	tinfo = Info_ValueForKey( info, "ssf" );
	if ( !Q_stricmpn( Info_ValueForKey( info, "gamename" ), "JA+ Mod", 7 ) )
		cg.japp.SSF = JAPLUS_SERVER_FLAGS;

#if MAC_PORT
	if ( tinfo[0] && sscanf( tinfo, "%X", &cg.japp.SSF ) != 1 )
#else
	if ( tinfo[0] && sscanf_s( tinfo, "%X", &cg.japp.SSF ) != 1 )
#endif
		CG_SecurityLogPrintf( "CG_ParseServerinfo: serverinfo 'ssf' was found, but invalid.\n"  );
	Com_Printf( "Server support hints: 0x%X\n", cg.japp.SSF );

	mapname = Info_ValueForKey( info, "mapname" );

	//rww - You must do this one here, Info_ValueForKey always uses the same memory pointer.
	trap->Cvar_Set ( "ui_about_mapname", mapname );

	Com_sprintf( cgs.mapname, sizeof( cgs.mapname ), "maps/%s.bsp", mapname );
//	Q_strncpyz( cgs.redTeam, Info_ValueForKey( info, "g_redTeam" ), sizeof(cgs.redTeam) );
//	trap->Cvar_Set("g_redTeam", cgs.redTeam);
//	Q_strncpyz( cgs.blueTeam, Info_ValueForKey( info, "g_blueTeam" ), sizeof(cgs.blueTeam) );
//	trap->Cvar_Set("g_blueTeam", cgs.blueTeam);

	trap->Cvar_Set ( "ui_about_gametype", va("%i", cgs.gametype ) );
	trap->Cvar_Set ( "ui_about_fraglimit", va("%i", cgs.fraglimit ) );
	trap->Cvar_Set ( "ui_about_duellimit", va("%i", cgs.duel_fraglimit ) );
	trap->Cvar_Set ( "ui_about_capturelimit", va("%i", cgs.capturelimit ) );
	trap->Cvar_Set ( "ui_about_timelimit", va("%i", cgs.timelimit ) );
	trap->Cvar_Set ( "ui_about_maxclients", va("%i", cgs.maxclients ) );
	trap->Cvar_Set ( "ui_about_dmflags", va("%i", cgs.dmflags ) );
	trap->Cvar_Set ( "ui_about_hostname", Info_ValueForKey( info, "sv_hostname" ) );
	trap->Cvar_Set ( "ui_about_needpass", Info_ValueForKey( info, "g_needpass" ) );
	trap->Cvar_Set ( "ui_about_botminplayers", Info_ValueForKey ( info, "bot_minplayers" ) );

	//Set the siege teams based on what the server has for overrides.
	trap->Cvar_Set("cg_siegeTeam1", Info_ValueForKey(info, "g_siegeTeam1"));
	trap->Cvar_Set("cg_siegeTeam2", Info_ValueForKey(info, "g_siegeTeam2"));

	tinfo = CG_ConfigString( CS_TERRAINS + 1 );
	if ( !tinfo || !*tinfo )
	{
		cg.mInRMG = qfalse;
	}
	else
	{
		int weather = 0;

		cg.mInRMG = qtrue;
		trap->Cvar_Set("RMG", "1");

		weather = atoi( Info_ValueForKey( info, "RMG_weather" ) );

		trap->Cvar_Set("RMG_weather", va("%i", weather));

		if (weather == 1 || weather == 2)
		{
			cg.mRMGWeather = qtrue;
		}
		else
		{
			cg.mRMGWeather = qfalse;
		}
	}

//	cg.japp.mod = GetMod( info );
	Q_strncpyz( cgs.japp.serverName, Info_ValueForKey( info, "sv_hostname" ), sizeof( cgs.japp.serverName ) );
	CPM_UpdateSettings( !!(cgs.japp.jp_cinfo & CINFO_CPMPHYSICS) );

	//Fix f****d up vote strings =o
	Q_strncpyz( cgs.voteString, CG_ConfigString( CS_VOTE_STRING ), sizeof( cgs.voteString ) );

	//Raz: Synchronise our expected snaps/sec with the server's framerate
	//		OpenJK servers will try to match us to the sv_fps too (sv_client.cpp -> SV_UserinfoChanged)
	i = atoi( Info_ValueForKey( info, "sv_fps" ) );
	if ( i )
		trap->Cvar_Set( "snaps", va( "%i", i ) );
}
	qboolean TeamCommand( int clientNum, char *cmd, char *param )
	{
		//gentity_t	*ent = &g_entities[clientNum];
		char		 parm[1024];
		char		 cmdLocal[1024];
	
		/**************************************************
		* Set the uiFeedback to qfalse, as we expect it to be.
		**************************************************/

		uiCaller = clientNum;
		uiFeedBack = qfalse;

		/**************************************************
		* Retrieve the parameter that could have been set.
		**************************************************/

		if ( trap_Argc() >= 2 )
		{
			if ( param == NULL )
			{
				trap_Argv( 1, parm, sizeof( parm ));
			}
			else
			{
				Q_strncpyz( parm, param, sizeof( parm ));
			}
		}

		/**************************************************
		* Team Management Requests
		**************************************************/

		if ( Q_stricmp( cmd, "~pmngt" ) == 0 )
		{
			/**************************************************
			* Set the uiFeedback to qtrue, as this is a ui command!
			**************************************************/

			uiFeedBack = qtrue;

			/**************************************************
			* Change the command pointer to accept the parameter.
			**************************************************/

			Q_strncpyz( cmdLocal, parm, sizeof( cmdLocal ));
			trap_Argv( 2, parm, sizeof( parm ));
			cmd = ( char * ) &cmdLocal;

			/**************************************************
			* Received when team management is toggled off.
			**************************************************/

			if ( Q_stricmp( cmd, "off" ) == 0 )
			{
				g_entities[clientNum].client->pers.partyManagement = qfalse;
				return qtrue;
			}

			/**************************************************
			* Received when team management is toggled on.
			**************************************************/

			if ( Q_stricmp( cmd, "on" ) == 0 )
			{
				g_entities[clientNum].client->pers.partyManagement = level.time;
				return qtrue;
			}
		}

		/**************************************************
		* These are the party-prefixed commands, dealing with your party.
		**************************************************/

		if ( Q_stricmpn( cmd, "party", 5 ) == 0 )
		{
			/**************************************************
			* Increment the command pointer to remove the prefix.
			**************************************************/

			cmd += 5;

			/**************************************************
			* Accepts the party invitation in the provided slot.
			**************************************************/

			if ( Q_stricmp( cmd, "accept" ) == 0 )
			{
				if (( uiFeedBack && trap_Argc() <= 2 ) || ( !uiFeedBack && trap_Argc() <= 1 ))
				{
					SendSystem( clientNum, "This command requires a parameter." );
					return qtrue;
				}

				TeamPartyCommandAccept( clientNum, atoi( parm ));
				return qtrue;
			}

			/**************************************************
			* Changes the authority of the party leader to another member. The identifier is the slot!
			**************************************************/

			if ( Q_stricmp( cmd, "changeleader" ) == 0 )
			{
				if (( uiFeedBack && trap_Argc() <= 2 ) || ( !uiFeedBack && trap_Argc() <= 1 ))
				{
					SendSystem( clientNum, "This command requires a parameter." );
					return qtrue;
				}

				TeamPartyCommandChangeLeader( clientNum, atoi( parm ), qfalse );
				return qtrue;
			}

			/**************************************************
			* Creates a new party. Find the first slot and set the client as leader.
			**************************************************/

			if ( Q_stricmp( cmd, "create" ) == 0 )
			{
				TeamPartyCommandCreate( clientNum );
				return qtrue;
			}	

			/**************************************************
			* Disbands the party, removes all members and the leader.
			**************************************************/

			if ( Q_stricmp( cmd, "disband" ) == 0 )
			{
				TeamPartyCommandDisband( clientNum );
				return qtrue;
			}

			/**************************************************
			* Dismisses the target member from the party. The identifier is the slot!
			**************************************************/

			if ( Q_stricmp( cmd, "dismiss" ) == 0 )
			{
				if (( uiFeedBack && trap_Argc() <= 2 ) || ( !uiFeedBack && trap_Argc() <= 1 ))
				{
					SendSystem( clientNum, "This command requires a parameter." );
					return qtrue;
				}

				TeamPartyCommandDismiss( clientNum, atoi( parm ));
				return qtrue;
			}

			/**************************************************
			* Invites a player to join your party. The parameter can be a identifier or name.
			**************************************************/

			if ( Q_stricmp( cmd, "invite" ) == 0 )
			{
				TeamPartyCommandInvite( clientNum, parm );
				return qtrue;
			}

			/**************************************************
			* Leave your current party. This may not be performed by the leader.
			**************************************************/

			if ( Q_stricmp( cmd, "leave" ) == 0 )
			{
				TeamPartyCommandLeave( clientNum, qfalse );
				return qtrue;
			}

			/**************************************************
			* Rejects the party invitation in the provided slot.
			**************************************************/

			if ( Q_stricmp( cmd, "reject" ) == 0 )
			{
				if (( uiFeedBack && trap_Argc() <= 2 ) || ( !uiFeedBack && trap_Argc() <= 1 ))
				{
					SendSystem( clientNum, "This command requires a parameter." );
					return qtrue;
				}

				TeamPartyCommandReject( clientNum, atoi( parm ));
				return qtrue;
			}

			/**************************************************
			* Refresh the list, we expect a time stamp to be
			* send (or if it's insane, ignore it) to save some
			* bandwidth and only generate a delta.
			**************************************************/

			if ( !Q_stricmp( cmd, "listrefresh" ))
			{
				TeamPartyListRefresh( clientNum, atoi( parm ));
				return qtrue;
			}

			/**************************************************
			* Register yourself on the list of players seeking
			* a party. We use concat data to get the entered
			* string.
			**************************************************/

			if ( !Q_stricmp( cmd, "listregister" ))
			{
				TeamPartyListRegister( clientNum, ConcatArgs((( uiFeedBack ) ? 2 : 1 )));
				return qtrue;
			}

			/**************************************************
			* Unregister yourself from the list. You must be
			* placed on the list for this to work, you'll be
			* removed then.
			**************************************************/

			if ( !Q_stricmp( cmd, "listunregister" ))
			{
				TeamPartyListUnregister( clientNum, qfalse );
				return qtrue;
			}
		}

		return qfalse;
	}