/* ================= 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 ); } }
/* ================== 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; }
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" ); } }
/* =============== PrintMatches =============== */ static void PrintMatches( const char *s ) { if ( !Q_stricmpn( s, shortestMatch, strlen( shortestMatch ) ) ) { Com_Printf( " %s\n", s ); } }
/* ==================== 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; }
/* ================= 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 ); }
/* ================== 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 ); }
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"); } }
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++; }
/* ================ 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 ) ); }
int Q_stricmp (const char *s1, const char *s2) { return (s1 && s2) ? Q_stricmpn (s1, s2, 99999) : -1; }
/* ================== 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" ); }
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; } } }
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); }
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 ); } } } }
/* ============== 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 ) ); } }
// 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; }
/* ============== 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 ) ) ); } }
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)); } } }
/* ============ 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); }
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; }
/* =============== 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; }
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(); }
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; }