qboolean G_xpsave_load(gentity_t *ent) { int i, j; qboolean found = qfalse, XPSMuted = qfalse; int clientNum; g_xpsave_t *x = g_xpsaves[0]; time_t t; char agestr[MAX_STRING_CHARS]; //char desc[64]; // josh: Increased this // josh: TODO: tjw? What is this desc thing for? char desc[115]; int age; int eff_XPSaveMaxAge_xp = G_getXPSaveMaxAge_xp(); int eff_XPSaveMaxAge = G_getXPSaveMaxAge(); float startxptotal = 0.0f; if(!ent || !ent->client) return qfalse; if(!(g_XPSave.integer & XPSF_ENABLE)) return qfalse; if(!time(&t)) return qfalse; desc[0] = '\0'; clientNum = ent - g_entities; for(i=0; g_xpsaves[i]; i++) { if(!Q_stricmp(g_xpsaves[i]->guid, ent->client->sess.guid)) { found = qtrue; x = g_xpsaves[i]; break; } } if(!found) return qfalse; age = t - x->time; if(age > eff_XPSaveMaxAge) { return qfalse; } if(age <= eff_XPSaveMaxAge_xp) { for(i=0; i<SK_NUM_SKILLS; i++) { ent->client->sess.skillpoints[i] = x->skill[i]; // pheno: fix for session startxptotal value startxptotal += x->skill[i]; } ent->client->sess.startxptotal = startxptotal; ent->client->ps.stats[STAT_XP] = (int)ent->client->sess.startxptotal; Q_strcat(desc, sizeof(desc), "XP/"); if((g_XPDecay.integer & XPDF_ENABLE) && !(g_XPDecay.integer & XPDF_NO_DISCONNECT_DECAY)) { G_XPDecay(ent, age, qtrue); } } ent->client->sess.overall_killrating = x->kill_rating; ent->client->sess.overall_killvariance = x->kill_variance; //ent->client->sess.playerrating = x->playerrating; ent->client->sess.rating = x->rating; ent->client->sess.rating_variance = x->rating_variance; for(i=0; i<SK_NUM_SKILLS; i++) { for(j=0; j<NUM_SKILL_LEVELS; j++) { ent->client->sess.pr_skill_updates[i][j] = x->pr_skill_updates[i][j]; ent->client->sess.pr_skill[i][j] = x->pr_skill[i][j]; } } Q_strcat(desc, sizeof(desc), "ratings/"); if(x->mutetime != 0) { if(x->mutetime < 0){ ent->client->sess.auto_unmute_time = -1; XPSMuted = qtrue; }else if(x->mutetime > t){ ent->client->sess.auto_unmute_time = (level.time + 1000*(x->mutetime - t)); XPSMuted = qtrue;; } if(XPSMuted == qtrue){ CP("print \"^5You've been muted by XPSave\n\"" ); Q_strcat(desc, sizeof(desc), "mute/"); } } ent->client->sess.hits = x->hits; ent->client->sess.team_hits = x->team_hits; G_CalcRank(ent->client); BG_PlayerStateToEntityState(&ent->client->ps, &ent->s, level.time, qtrue); // tjw: trim last / from desc if(strlen(desc)) desc[strlen(desc)-1] = '\0'; G_shrubbot_duration(age, agestr, sizeof(agestr)); CP(va( "print \"^3server: loaded stored ^7%s^3 state from %s ago\n\"", desc, agestr)); // josh: check and update if disconnect found // cs: not for bots since it is pointless for them, plus we never want SetTeam failing for them if (!(ent->r.svFlags & SVF_BOT)) { Reconnect(x,ent); } return qtrue; }
/* ============== G_Script_ScriptParse Parses the script for the given entity ============== */ void G_Script_ScriptParse( gentity_t *ent ) { char *pScript; char *token; bool wantName; bool inScript; int eventNum; g_script_event_t events[G_MAX_SCRIPT_STACK_ITEMS]; int numEventItems; g_script_event_t *curEvent; // DHM - Nerve :: Some of our multiplayer script commands have longer parameters //char params[MAX_QPATH]; char params[MAX_INFO_STRING]; // dhm - end g_script_stack_action_t *action; int i; int bracketLevel; bool buildScript; if ( !ent->scriptName ) { return; } if ( !level.scriptEntity ) { return; } buildScript = trap_Cvar_VariableIntegerValue( "com_buildScript" ); pScript = level.scriptEntity; wantName = true; inScript = false; COM_BeginParseSession( "G_Script_ScriptParse" ); bracketLevel = 0; numEventItems = 0; memset( events, 0, sizeof( events ) ); while ( 1 ) { token = COM_Parse( &pScript ); if ( !token[0] ) { if ( !wantName ) { G_Error( "G_Script_ScriptParse(), Error (line %d): '}' expected, end of script found.\n", COM_GetCurrentParseLine() ); } break; } // end of script if ( token[0] == '}' ) { if ( inScript ) { break; } if ( wantName ) { G_Error( "G_Script_ScriptParse(), Error (line %d): '}' found, but not expected.\n", COM_GetCurrentParseLine() ); } wantName = true; } else if ( token[0] == '{' ) { if ( wantName ) { G_Error( "G_Script_ScriptParse(), Error (line %d): '{' found, NAME expected.\n", COM_GetCurrentParseLine() ); } } else if ( wantName ) { if ( !Q_stricmp( token, "bot" ) ) { // a bot, skip this whole entry SkipRestOfLine( &pScript ); // skip this section SkipBracedSection( &pScript ); // continue; } if ( !Q_stricmp( token, "entity" ) ) { // this is an entity, so go back to look for a name continue; } if ( !Q_stricmp( ent->scriptName, token ) ) { inScript = true; numEventItems = 0; } wantName = false; } else if ( inScript ) { Q_strlwr( token ); eventNum = G_Script_EventForString( token ); if ( eventNum < 0 ) { G_Error( "G_Script_ScriptParse(), Error (line %d): unknown event: %s.\n", COM_GetCurrentParseLine(), token ); } if ( numEventItems >= G_MAX_SCRIPT_STACK_ITEMS ) { G_Error( "G_Script_ScriptParse(), Error (line %d): G_MAX_SCRIPT_STACK_ITEMS reached (%d)\n", COM_GetCurrentParseLine(), G_MAX_SCRIPT_STACK_ITEMS ); } curEvent = &events[numEventItems]; curEvent->eventNum = eventNum; memset( params, 0, sizeof( params ) ); // parse any event params before the start of this event's actions while ( ( token = COM_Parse( &pScript ) ) != NULL && ( token[0] != '{' ) ) { if ( !token[0] ) { G_Error( "G_Script_ScriptParse(), Error (line %d): '}' expected, end of script found.\n", COM_GetCurrentParseLine() ); } if ( strlen( params ) ) { // add a space between each param Q_strcat( params, sizeof( params ), " " ); } Q_strcat( params, sizeof( params ), token ); } if ( strlen( params ) ) { // copy the params into the event curEvent->params = G_Alloc( strlen( params ) + 1 ); Q_strncpyz( curEvent->params, params, strlen( params ) + 1 ); } // parse the actions for this event while ( ( token = COM_Parse( &pScript ) ) != NULL && ( token[0] != '}' ) ) { if ( !token[0] ) { G_Error( "G_Script_ScriptParse(), Error (line %d): '}' expected, end of script found.\n", COM_GetCurrentParseLine() ); } action = G_Script_ActionForString( token ); if ( !action ) { G_Error( "G_Script_ScriptParse(), Error (line %d): unknown action: %s.\n", COM_GetCurrentParseLine(), token ); } curEvent->stack.items[curEvent->stack.numItems].action = action; memset( params, 0, sizeof( params ) ); // Ikkyo - Parse for {}'s if this is a set command if ( !Q_stricmp( action->actionString, "set" ) ) { token = COM_Parse( &pScript ); if ( token[0] != '{' ) { COM_ParseError( "'{' expected, found: %s.\n", token ); } while ( ( token = COM_Parse( &pScript ) ) && ( token[0] != '}' ) ) { if ( strlen( params ) ) { // add a space between each param Q_strcat( params, sizeof( params ), " " ); } if ( strrchr( token,' ' ) ) { // need to wrap this param in quotes since it has more than one word Q_strcat( params, sizeof( params ), "\"" ); } Q_strcat( params, sizeof( params ), token ); if ( strrchr( token,' ' ) ) { // need to wrap this param in quotes since it has mor Q_strcat( params, sizeof( params ), "\"" ); } } } else // hackly precaching of custom characters if ( !Q_stricmp( token, "spawnbot" ) ) { // this is fairly indepth, so I'll move it to a separate function for readability G_Script_ParseSpawnbot( &pScript, params, MAX_INFO_STRING ); } else { token = COM_ParseExt( &pScript, false ); for ( i = 0; token[0]; i++ ) { if ( strlen( params ) ) { // add a space between each param Q_strcat( params, sizeof( params ), " " ); } if ( i == 0 ) { // Special case: playsound's need to be cached on startup to prevent in-game pauses if ( !Q_stricmp( action->actionString, "playsound" ) ) { G_SoundIndex( token ); } else if ( !Q_stricmp( action->actionString, "changemodel" ) ) { G_ModelIndex( token ); } else if ( buildScript && ( !Q_stricmp( action->actionString, "mu_start" ) || !Q_stricmp( action->actionString, "mu_play" ) || !Q_stricmp( action->actionString, "mu_queue" ) || !Q_stricmp( action->actionString, "startcam" ) ) ) { if ( strlen( token ) ) { // we know there's a [0], but don't know if it's '0' trap_SendServerCommand( -1, va( "addToBuild %s\n", token ) ); } } } if ( i == 0 || i == 1 ) { if ( !Q_stricmp( action->actionString, "remapshader" ) ) { G_ShaderIndex( token ); } } if ( strrchr( token,' ' ) ) { // need to wrap this param in quotes since it has more than one word Q_strcat( params, sizeof( params ), "\"" ); } Q_strcat( params, sizeof( params ), token ); if ( strrchr( token,' ' ) ) { // need to wrap this param in quotes since it has more than one word Q_strcat( params, sizeof( params ), "\"" ); } token = COM_ParseExt( &pScript, false ); } } if ( strlen( params ) ) { // copy the params into the event curEvent->stack.items[curEvent->stack.numItems].params = G_Alloc( strlen( params ) + 1 ); Q_strncpyz( curEvent->stack.items[curEvent->stack.numItems].params, params, strlen( params ) + 1 ); } curEvent->stack.numItems++; if ( curEvent->stack.numItems >= G_MAX_SCRIPT_STACK_ITEMS ) { G_Error( "G_Script_ScriptParse(): script exceeded G_MAX_SCRIPT_STACK_ITEMS (%d), line %d\n", G_MAX_SCRIPT_STACK_ITEMS, COM_GetCurrentParseLine() ); } } numEventItems++; } else { // skip this character completely // TTimo gcc: suggest parentheses around assignment used as truth value while ( ( token = COM_Parse( &pScript ) ) != NULL ) { if ( !token[0] ) { G_Error( "G_Script_ScriptParse(), Error (line %d): '}' expected, end of script found.\n", COM_GetCurrentParseLine() ); } else if ( token[0] == '{' ) { bracketLevel++; } else if ( token[0] == '}' ) { if ( !--bracketLevel ) { break; } } } } } // alloc and copy the events into the gentity_t for this cast if ( numEventItems > 0 ) { ent->scriptEvents = G_Alloc( sizeof( g_script_event_t ) * numEventItems ); memcpy( ent->scriptEvents, events, sizeof( g_script_event_t ) * numEventItems ); ent->numScriptEvents = numEventItems; } }
static void GLSL_GetShaderHeader( GLenum shaderType, const GLcharARB *extra, char *dest, int size ) { float fbufWidthScale, fbufHeightScale; dest[0] = '\0'; // HACK: abuse the GLSL preprocessor to turn GLSL 1.20 shaders into 1.30 ones if(glRefConfig.glslMajorVersion > 1 || (glRefConfig.glslMajorVersion == 1 && glRefConfig.glslMinorVersion >= 30)) { Q_strcat(dest, size, "#version 130\n"); if(shaderType == GL_VERTEX_SHADER_ARB) { Q_strcat(dest, size, "#define attribute in\n"); Q_strcat(dest, size, "#define varying out\n"); } else { Q_strcat(dest, size, "#define varying in\n"); Q_strcat(dest, size, "out vec4 out_Color;\n"); Q_strcat(dest, size, "#define gl_FragColor out_Color\n"); } } else { Q_strcat(dest, size, "#version 120\n"); } // HACK: add some macros to avoid extra uniforms and save speed and code maintenance //Q_strcat(dest, size, // va("#ifndef r_SpecularExponent\n#define r_SpecularExponent %f\n#endif\n", r_specularExponent->value)); //Q_strcat(dest, size, // va("#ifndef r_SpecularScale\n#define r_SpecularScale %f\n#endif\n", r_specularScale->value)); //Q_strcat(dest, size, // va("#ifndef r_NormalScale\n#define r_NormalScale %f\n#endif\n", r_normalScale->value)); Q_strcat(dest, size, "#ifndef M_PI\n#define M_PI 3.14159265358979323846\n#endif\n"); //Q_strcat(dest, size, va("#ifndef MAX_SHADOWMAPS\n#define MAX_SHADOWMAPS %i\n#endif\n", MAX_SHADOWMAPS)); Q_strcat(dest, size, va("#ifndef deformGen_t\n" "#define deformGen_t\n" "#define DGEN_WAVE_SIN %i\n" "#define DGEN_WAVE_SQUARE %i\n" "#define DGEN_WAVE_TRIANGLE %i\n" "#define DGEN_WAVE_SAWTOOTH %i\n" "#define DGEN_WAVE_INVERSE_SAWTOOTH %i\n" "#define DGEN_BULGE %i\n" "#define DGEN_MOVE %i\n" "#endif\n", DGEN_WAVE_SIN, DGEN_WAVE_SQUARE, DGEN_WAVE_TRIANGLE, DGEN_WAVE_SAWTOOTH, DGEN_WAVE_INVERSE_SAWTOOTH, DGEN_BULGE, DGEN_MOVE)); Q_strcat(dest, size, va("#ifndef tcGen_t\n" "#define tcGen_t\n" "#define TCGEN_LIGHTMAP %i\n" "#define TCGEN_TEXTURE %i\n" "#define TCGEN_ENVIRONMENT_MAPPED %i\n" "#define TCGEN_FOG %i\n" "#define TCGEN_VECTOR %i\n" "#endif\n", TCGEN_LIGHTMAP, TCGEN_TEXTURE, TCGEN_ENVIRONMENT_MAPPED, TCGEN_FOG, TCGEN_VECTOR)); Q_strcat(dest, size, va("#ifndef colorGen_t\n" "#define colorGen_t\n" "#define CGEN_LIGHTING_DIFFUSE %i\n" "#endif\n", CGEN_LIGHTING_DIFFUSE)); Q_strcat(dest, size, va("#ifndef alphaGen_t\n" "#define alphaGen_t\n" "#define AGEN_LIGHTING_SPECULAR %i\n" "#define AGEN_PORTAL %i\n" "#endif\n", AGEN_LIGHTING_SPECULAR, AGEN_PORTAL)); Q_strcat(dest, size, va("#ifndef texenv_t\n" "#define texenv_t\n" "#define TEXENV_MODULATE %i\n" "#define TEXENV_ADD %i\n" "#define TEXENV_REPLACE %i\n" "#endif\n", GL_MODULATE, GL_ADD, GL_REPLACE)); fbufWidthScale = 1.0f / ((float)glConfig.vidWidth); fbufHeightScale = 1.0f / ((float)glConfig.vidHeight); Q_strcat(dest, size, va("#ifndef r_FBufScale\n#define r_FBufScale vec2(%f, %f)\n#endif\n", fbufWidthScale, fbufHeightScale)); if (r_materialGamma->value != 1.0f) Q_strcat(dest, size, va("#ifndef r_materialGamma\n#define r_materialGamma %f\n#endif\n", r_materialGamma->value)); if (r_lightGamma->value != 1.0f) Q_strcat(dest, size, va("#ifndef r_lightGamma\n#define r_lightGamma %f\n#endif\n", r_lightGamma->value)); if (r_framebufferGamma->value != 1.0f) Q_strcat(dest, size, va("#ifndef r_framebufferGamma\n#define r_framebufferGamma %f\n#endif\n", r_framebufferGamma->value)); if (r_tonemapGamma->value != 1.0f) Q_strcat(dest, size, va("#ifndef r_tonemapGamma\n#define r_tonemapGamma %f\n#endif\n", r_tonemapGamma->value)); if (extra) { Q_strcat(dest, size, extra); } // OK we added a lot of stuff but if we do something bad in the GLSL shaders then we want the proper line // so we have to reset the line counting Q_strcat(dest, size, "#line 0\n"); }
static void _Datagram_SearchForHosts (qboolean xmit) { int ret; int n; int i; struct qsockaddr readaddr; struct qsockaddr myaddr; int control; dfunc.GetSocketAddr (dfunc.controlSock, &myaddr); if (xmit) { SZ_Clear(&net_message); // save space for the header, filled in later MSG_WriteLong(&net_message, 0); MSG_WriteByte(&net_message, CCREQ_SERVER_INFO); MSG_WriteString(&net_message, "QUAKE"); MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION); *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); dfunc.Broadcast(dfunc.controlSock, net_message.data, net_message.cursize); SZ_Clear(&net_message); } while ((ret = dfunc.Read (dfunc.controlSock, net_message.data, net_message.maxsize, &readaddr)) > 0) { if (ret < sizeof(int)) continue; net_message.cursize = ret; // don't answer our own query if (dfunc.AddrCompare(&readaddr, &myaddr) >= 0) continue; // is the cache full? if (hostCacheCount == HOSTCACHESIZE) continue; MSG_BeginReading (); control = BigLong(*((int *)net_message.data)); MSG_ReadLong(); if (control == -1) continue; if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL) continue; if ((control & NETFLAG_LENGTH_MASK) != ret) continue; if (MSG_ReadByte() != CCREP_SERVER_INFO) continue; dfunc.GetAddrFromName(MSG_ReadString(), &readaddr); // search the cache for this server for (n = 0; n < hostCacheCount; n++) if (dfunc.AddrCompare(&readaddr, &hostcache[n].addr) == 0) break; // is it already there? if (n < hostCacheCount) continue; // add it hostCacheCount++; Q_strcpy(hostcache[n].name, MSG_ReadString()); Q_strcpy(hostcache[n].map, MSG_ReadString()); hostcache[n].users = MSG_ReadByte(); hostcache[n].maxusers = MSG_ReadByte(); if (MSG_ReadByte() != NET_PROTOCOL_VERSION) { Q_strcpy(hostcache[n].cname, hostcache[n].name); hostcache[n].cname[14] = 0; Q_strcpy(hostcache[n].name, "*"); Q_strcat(hostcache[n].name, hostcache[n].cname); } Q_memcpy(&hostcache[n].addr, &readaddr, sizeof(struct qsockaddr)); hostcache[n].driver = net_driverlevel; hostcache[n].ldriver = net_landriverlevel; Q_strcpy(hostcache[n].cname, dfunc.AddrToString(&readaddr)); // check for a name conflict for (i = 0; i < hostCacheCount; i++) { if (i == n) continue; if (Q_strcasecmp (hostcache[n].name, hostcache[i].name) == 0) { i = Q_strlen(hostcache[n].name); if (i < 15 && hostcache[n].name[i-1] > '8') { hostcache[n].name[i] = '0'; hostcache[n].name[i+1] = 0; } else hostcache[n].name[i-1]++; i = -1; } } } }
void InitSiegeMode(void) { vmCvar_t mapname; char levelname[512]; char teamIcon[128]; char goalreq[64]; char teams[2048]; static char objective[MAX_SIEGE_INFO_SIZE]; char objecStr[8192]; int len = 0; int i = 0; // int j = 0; int objectiveNumTeam1 = 0; int objectiveNumTeam2 = 0; fileHandle_t f; objective[0] = '\0'; if (level.gametype != GT_SIEGE) { goto failure; } //reset SiegeSetCompleteData(0); //get pers data in case it existed from last level if (g_siegeTeamSwitch.integer) { trap->SiegePersGet(&g_siegePersistant); if (g_siegePersistant.beatingTime) { trap->SetConfigstring(CS_SIEGE_TIMEOVERRIDE, va("%i", g_siegePersistant.lastTime)); } else { trap->SetConfigstring(CS_SIEGE_TIMEOVERRIDE, "0"); } } else { //hmm, ok, nothing. trap->SetConfigstring(CS_SIEGE_TIMEOVERRIDE, "0"); } imperial_goals_completed = 0; rebel_goals_completed = 0; trap->Cvar_Register( &mapname, "mapname", "", CVAR_SERVERINFO | CVAR_ROM ); Com_sprintf(levelname, sizeof(levelname), "maps/%s.siege\0", mapname.string); if ( !levelname[0] ) { goto failure; } len = trap->FS_Open(levelname, &f, FS_READ); if (!f || len >= MAX_SIEGE_INFO_SIZE) { goto failure; } trap->FS_Read(siege_info, len, f); trap->FS_Close(f); siege_valid = 1; //See if players should be specs or ingame preround if (BG_SiegeGetPairedValue(siege_info, "preround_state", teams)) { if (teams[0]) { g_preroundState = atoi(teams); } } if (BG_SiegeGetValueGroup(siege_info, "Teams", teams)) { if (g_siegeTeam1.string[0] && Q_stricmp(g_siegeTeam1.string, "none")) { //check for override strcpy(team1, g_siegeTeam1.string); } else { //otherwise use level default BG_SiegeGetPairedValue(teams, "team1", team1); } if (g_siegeTeam2.string[0] && Q_stricmp(g_siegeTeam2.string, "none")) { //check for override strcpy(team2, g_siegeTeam2.string); } else { //otherwise use level default BG_SiegeGetPairedValue(teams, "team2", team2); } } else { trap->Error( ERR_DROP, "Siege teams not defined" ); } if (BG_SiegeGetValueGroup(siege_info, team2, gParseObjectives)) { if (BG_SiegeGetPairedValue(gParseObjectives, "TeamIcon", teamIcon)) { trap->Cvar_Set( "team2_icon", teamIcon); } if (BG_SiegeGetPairedValue(gParseObjectives, "RequiredObjectives", goalreq)) { rebel_goals_required = atoi(goalreq); } if (BG_SiegeGetPairedValue(gParseObjectives, "Timed", goalreq)) { rebel_time_limit = atoi(goalreq)*1000; if (g_siegeTeamSwitch.integer && g_siegePersistant.beatingTime) { gRebelCountdown = level.time + g_siegePersistant.lastTime; } else { gRebelCountdown = level.time + rebel_time_limit; } } if (BG_SiegeGetPairedValue(gParseObjectives, "attackers", goalreq)) { rebel_attackers = atoi(goalreq); } } if (BG_SiegeGetValueGroup(siege_info, team1, gParseObjectives)) { if (BG_SiegeGetPairedValue(gParseObjectives, "TeamIcon", teamIcon)) { trap->Cvar_Set( "team1_icon", teamIcon); } if (BG_SiegeGetPairedValue(gParseObjectives, "RequiredObjectives", goalreq)) { imperial_goals_required = atoi(goalreq); } if (BG_SiegeGetPairedValue(gParseObjectives, "Timed", goalreq)) { if (rebel_time_limit) { Com_Printf("Tried to set imperial time limit, but there's already a rebel time limit!\nOnly one team can have a time limit.\n"); } else { imperial_time_limit = atoi(goalreq)*1000; if (g_siegeTeamSwitch.integer && g_siegePersistant.beatingTime) { gImperialCountdown = level.time + g_siegePersistant.lastTime; } else { gImperialCountdown = level.time + imperial_time_limit; } } } if (BG_SiegeGetPairedValue(gParseObjectives, "attackers", goalreq)) { imperial_attackers = atoi(goalreq); } } //Load the player class types BG_SiegeLoadClasses(NULL); if (!bgNumSiegeClasses) { //We didn't find any?! trap->Error( ERR_DROP, "Couldn't find any player classes for Siege" ); } /* //We could probably just see what teams are used on this level, //then see what classes are used by those teams, and then precache //all weapons for said classes. However, I'm just going to do them //all for now. while (i < bgNumSiegeClasses) { cl = &bgSiegeClasses[i]; j = 0; while (j < WP_NUM_WEAPONS) { if (cl->weapons & (1 << j)) { //we use this weapon so register it. RegisterItem(BG_FindItemForWeapon(j)); } j++; } i++; } */ //Ok, I'm adding inventory item precaching now, so I'm finally going to optimize this //to only do weapons/items for the current teams used on the level. //Now load the teams since we have class data. BG_SiegeLoadTeams(); if (!bgNumSiegeTeams) { //React same as with classes. trap->Error( ERR_DROP, "Couldn't find any player teams for Siege" ); } //Get and set the team themes for each team. This will control which classes can be //used on each team. if (BG_SiegeGetValueGroup(siege_info, team1, gParseObjectives)) { if (BG_SiegeGetPairedValue(gParseObjectives, "UseTeam", goalreq)) { BG_SiegeSetTeamTheme(SIEGETEAM_TEAM1, goalreq); } //Now count up the objectives for this team. i = 1; strcpy(objecStr, va("Objective%i", i)); while (BG_SiegeGetValueGroup(gParseObjectives, objecStr, objective)) { objectiveNumTeam1++; i++; strcpy(objecStr, va("Objective%i", i)); } } if (BG_SiegeGetValueGroup(siege_info, team2, gParseObjectives)) { if (BG_SiegeGetPairedValue(gParseObjectives, "UseTeam", goalreq)) { BG_SiegeSetTeamTheme(SIEGETEAM_TEAM2, goalreq); } //Now count up the objectives for this team. i = 1; strcpy(objecStr, va("Objective%i", i)); while (BG_SiegeGetValueGroup(gParseObjectives, objecStr, objective)) { objectiveNumTeam2++; i++; strcpy(objecStr, va("Objective%i", i)); } } //Set the configstring to show status of all current objectives strcpy(gObjectiveCfgStr, "t1"); while (objectiveNumTeam1 > 0) { //mark them all as not completed since we just initialized Q_strcat(gObjectiveCfgStr, 1024, "-0"); objectiveNumTeam1--; } //Finished doing team 1's objectives, now do team 2's Q_strcat(gObjectiveCfgStr, 1024, "|t2"); while (objectiveNumTeam2 > 0) { Q_strcat(gObjectiveCfgStr, 1024, "-0"); objectiveNumTeam2--; } //And finally set the actual config string trap->SetConfigstring(CS_SIEGE_OBJECTIVES, gObjectiveCfgStr); //precache saber data for classes that use sabers on both teams BG_PrecacheSabersForSiegeTeam(SIEGETEAM_TEAM1); BG_PrecacheSabersForSiegeTeam(SIEGETEAM_TEAM2); G_SiegeRegisterWeaponsAndHoldables(SIEGETEAM_TEAM1); G_SiegeRegisterWeaponsAndHoldables(SIEGETEAM_TEAM2); return; failure: siege_valid = 0; }
/* ==================== CL_UpdateLevelHunkUsage This updates the "hunkusage.dat" file with the current map and it's hunk usage count This is used for level loading, so we can show a percentage bar dependant on the amount of hunk memory allocated so far This will be slightly inaccurate if some settings like sound quality are changed, but these things should only account for a small variation (hopefully) ==================== */ void CL_UpdateLevelHunkUsage( void ) { int handle; char *memlistfile = "hunkusage.dat"; char *buf, *outbuf; char *buftrav, *outbuftrav; char *token; char outstr[256]; int len, memusage; memusage = Cvar_VariableIntegerValue( "com_hunkused" ) + Cvar_VariableIntegerValue( "hunk_soundadjust" ); len = FS_FOpenFileByMode( memlistfile, &handle, FS_READ ); if ( len >= 0 ) { // the file exists, so read it in, strip out the current entry for this map, and save it out, so we can append the new value buf = (char *)Z_Malloc( len + 1 ); memset( buf, 0, len + 1 ); outbuf = (char *)Z_Malloc( len + 1 ); memset( outbuf, 0, len + 1 ); FS_Read( (void *)buf, len, handle ); FS_FCloseFile( handle ); // now parse the file, filtering out the current map buftrav = buf; outbuftrav = outbuf; outbuftrav[0] = '\0'; while ( ( token = COM_Parse( &buftrav ) ) && token[0] ) { if ( !Q_strcasecmp( token, cl.mapname ) ) { // found a match token = COM_Parse( &buftrav ); // read the size if ( token && token[0] ) { if ( atoi( token ) == memusage ) { // if it is the same, abort this process Z_Free( buf ); Z_Free( outbuf ); return; } } } else { // send it to the outbuf Q_strcat( outbuftrav, len + 1, token ); Q_strcat( outbuftrav, len + 1, " " ); token = COM_Parse( &buftrav ); // read the size if ( token && token[0] ) { Q_strcat( outbuftrav, len + 1, token ); Q_strcat( outbuftrav, len + 1, "\n" ); } else { Com_Error( ERR_DROP, "hunkusage.dat file is corrupt\n" ); } } } #ifdef __MACOS__ //DAJ MacOS file typing { extern _MSL_IMP_EXP_C long _fcreator, _ftype; _ftype = 'TEXT'; _fcreator = 'WlfS'; } #endif handle = FS_FOpenFileWrite( memlistfile ); if ( handle < 0 ) { Com_Error( ERR_DROP, "cannot create %s\n", memlistfile ); } // input file is parsed, now output to the new file len = strlen( outbuf ); if ( FS_Write( (void *)outbuf, len, handle ) != len ) { Com_Error( ERR_DROP, "cannot write to %s\n", memlistfile ); } FS_FCloseFile( handle ); Z_Free( buf ); Z_Free( outbuf ); } // now append the current map to the current file FS_FOpenFileByMode( memlistfile, &handle, FS_APPEND ); if ( handle < 0 ) { Com_Error( ERR_DROP, "cannot write to hunkusage.dat, check disk full\n" ); } Com_sprintf( outstr, sizeof( outstr ), "%s %i\n", cl.mapname, memusage ); FS_Write( outstr, strlen( outstr ), handle ); FS_FCloseFile( handle ); // now just open it and close it, so it gets copied to the pak dir len = FS_FOpenFileByMode( memlistfile, &handle, FS_READ ); if ( len >= 0 ) { FS_FCloseFile( handle ); } }
/* ============== Win_CompleteCommand ============== */ static void Win_CompleteCommand(qboolean showMatches) { field_t *edit = &win_consoleField; field_t temp; if (win_acLength == 0) { // only look at the first token for completion purposes Cmd_TokenizeString(edit->buffer); Q_strncpyz(win_completionString, Cmd_Argv(0), sizeof(win_completionString)); if (win_completionString[0] == '\\' || win_completionString[0] == '/') { Q_strncpyz(win_completionString, win_completionString + 1, sizeof(win_completionString)); } win_matchCount = 0; win_matchIndex = 0; win_currentMatch[0] = 0; if (strlen(win_completionString) == 0) { return; } Cmd_CommandCompletion(Win_FindMatches); Cvar_CommandCompletion(Win_FindMatches); if (win_matchCount == 0) { return; // no matches } Com_Memcpy(&temp, edit, sizeof(field_t)); if (win_matchCount == 1) { Com_sprintf(edit->buffer, sizeof(edit->buffer), "%s", win_currentMatch); if (Cmd_Argc() == 1) { Q_strcat(win_consoleField.buffer, sizeof(win_consoleField.buffer), " "); } else { Win_ConcatRemaining(temp.buffer, win_completionString); } edit->cursor = strlen(edit->buffer); } else { // multiple matches, complete to shortest Com_sprintf(edit->buffer, sizeof(edit->buffer), "%s", win_currentMatch); win_acLength = edit->cursor = strlen(edit->buffer); Win_ConcatRemaining(temp.buffer, win_completionString); showMatches = qtrue; } } else if (win_matchCount != 1) { // get the next match and show instead char lastMatch[MAX_TOKEN_CHARS]; Q_strncpyz(lastMatch, win_currentMatch, sizeof(lastMatch)); win_matchIndex++; if (win_matchIndex == win_matchCount) { win_matchIndex = 0; } win_findMatchIndex = 0; Cmd_CommandCompletion(Win_FindIndexMatch); Cvar_CommandCompletion(Win_FindIndexMatch); Com_Memcpy(&temp, edit, sizeof(field_t)); // and print it Com_sprintf(edit->buffer, sizeof(edit->buffer), "%s", win_currentMatch); edit->cursor = strlen(edit->buffer); Win_ConcatRemaining(temp.buffer, lastMatch); } // hijack it if (win_matchCount == 1) { win_acLength = strlen(win_currentMatch); } // run through again, printing matches if (showMatches && win_matchCount > 0) { memcpy(&temp, edit, sizeof(*edit)); temp.buffer[win_acLength] = '\0'; Sys_Print(va("] %s\n", temp.buffer)); Cmd_CommandCompletion(Win_PrintMatches); Cvar_CommandCompletion(Win_PrintCvarMatches); } }
void CG_CheckSVStringEdRef(char *buf, const char *str) { //I don't really like doing this. But it utilizes the system that was already in place. int i = 0; int b = 0; int strLen = 0; qboolean gotStrip = qfalse; if (!str || !str[0]) { if (str) { strcpy(buf, str); } return; } strcpy(buf, str); strLen = strlen(str); if (strLen >= MAX_STRINGED_SV_STRING) { return; } while (i < strLen && str[i]) { gotStrip = qfalse; if (str[i] == '@' && (i+1) < strLen) { if (str[i+1] == '@' && (i+2) < strLen) { if (str[i+2] == '@' && (i+3) < strLen) { //@@@ should mean to insert a StringEd reference here, so insert it into buf at the current place char stringRef[MAX_STRINGED_SV_STRING]; int r = 0; /*while (i < strLen && str[i] == '@') { i++; }*/ // Oh c'mon. i += 3; while (i < strLen && str[i] && str[i] != ' ' && str[i] != ':' && str[i] != '.' && str[i] != '\n') { stringRef[r] = str[i]; r++; i++; } stringRef[r] = 0; buf[b] = 0; // Bugfix -> DONT JUMP TO CONCLUSIONS, SILLY RAVEN { char buffer2[1024]; strcpy(buffer2, CG_GetStringEdString2(stringRef)); if(Q_stricmp(buffer2, stringRef)) { Q_strcat(buf, MAX_STRINGED_SV_STRING, buffer2); return; } } Q_strcat(buf, MAX_STRINGED_SV_STRING, CG_GetStringEdString("MP_SVGAME", stringRef)); // Might be a valid point...but WTF seriously b = strlen(buf); } } } if (!gotStrip) { buf[b] = str[i]; b++; } i++; } buf[b] = 0; }
int main ( int argc, char **argv ) { char commandLine[ MAX_STRING_CHARS ] = { 0 }; // int startTime, endTime; SET_CRT_DEBUG_FIELD( _CRTDBG_LEAK_CHECK_DF ); // _CrtSetBreakAlloc(34804); Sys_CreateConsole(); // no abort/retry/fail errors SetErrorMode( SEM_FAILCRITICALERRORS ); // get the initial time base Sys_Milliseconds(); Sys_SetBinaryPath( Sys_Dirname( argv[ 0 ] ) ); Sys_SetDefaultInstallPath( DEFAULT_BASEDIR ); // Concatenate the command line for passing to Com_Init for( int i = 1; i < argc; i++ ) { const bool containsSpaces = (strchr(argv[i], ' ') != NULL); if (containsSpaces) Q_strcat( commandLine, sizeof( commandLine ), "\"" ); Q_strcat( commandLine, sizeof( commandLine ), argv[ i ] ); if (containsSpaces) Q_strcat( commandLine, sizeof( commandLine ), "\"" ); Q_strcat( commandLine, sizeof( commandLine ), " " ); } Com_Init( commandLine ); QuickMemTest(); // hide the early console since we've reached the point where we // have a working graphics subsystems if ( !com_viewlog->integer ) { Sys_ShowConsole( 0, qfalse ); } // main game loop while( 1 ) { // if not running as a game client, sleep a bit if ( g_wv.isMinimized ) { Sleep( 5 ); } #ifdef _DEBUG if (!g_wv.activeApp) { Sleep(50); } #endif // _DEBUG // make sure mouse and joystick are only called once a frame IN_Frame(); // run the game Com_Frame(); } }
bool CMapzoneData::LoadFromFile(const char *szMapName) { bool toReturn = false; char zoneFilePath[MAX_PATH]; Q_strcpy(zoneFilePath, c_mapPath); Q_strcat(zoneFilePath, szMapName, MAX_PATH); Q_strncat(zoneFilePath, c_zoneFileEnding, MAX_PATH); DevLog("Looking for zone file: %s \n", zoneFilePath); KeyValues* zoneKV = new KeyValues(szMapName); if (zoneKV->LoadFromFile(filesystem, zoneFilePath, "MOD")) { // Go through checkpoints for (KeyValues *cp = zoneKV->GetFirstSubKey(); cp; cp = cp->GetNextKey()) { // Load position information (will default to 0 if the keys don't exist) Vector* pos = new Vector(cp->GetFloat("xPos"), cp->GetFloat("yPos"), cp->GetFloat("zPos")); QAngle* rot = new QAngle(cp->GetFloat("xRot"), cp->GetFloat("yRot"), cp->GetFloat("zRot")); Vector* scaleMins = new Vector(cp->GetFloat("xScaleMins"), cp->GetFloat("yScaleMins"), cp->GetFloat("zScaleMins")); Vector* scaleMaxs = new Vector(cp->GetFloat("xScaleMaxs"), cp->GetFloat("yScaleMaxs"), cp->GetFloat("zScaleMaxs")); // Do specific things for different types of checkpoints // 0 = start, 1 = checkpoint, 2 = end, 3 = Onehop, 4 = OnehopReset, 5 = Checkpoint_teleport, 6 = Multihop, 7 = stage int zoneType = -1; int index = -1; bool shouldStop = false; bool shouldTilt = true; float holdTime = 1.0f; //int destinationIndex = -1; bool limitingspeed = true; float maxleavespeed = 290.0f; const char * linkedtrigger = NULL; if (Q_strcmp(cp->GetName(), "start") == 0) { zoneType = MOMZONETYPE_START; limitingspeed = cp->GetBool("limitingspeed"); maxleavespeed = cp->GetFloat("leavespeed"); } else if (Q_strcmp(cp->GetName(), "checkpoint") == 0) { zoneType = MOMZONETYPE_CP; index = cp->GetInt("number", -1); } else if (Q_strcmp(cp->GetName(), "end") == 0) { zoneType = MOMZONETYPE_STOP; } else if (Q_strcmp(cp->GetName(), "onehop") == 0) { zoneType = MOMZONETYPE_ONEHOP; shouldStop = cp->GetBool("stop", false); shouldTilt = cp->GetBool("resetang", true); holdTime = cp->GetFloat("hold", 1); //destinationIndex = cp->GetInt("destination", 1); linkedtrigger = cp->GetString("destinationname", NULL); } else if (Q_strcmp(cp->GetName(), "resetonehop") == 0) { zoneType = MOMZONETYPE_RESETONEHOP; } else if (Q_strcmp(cp->GetName(), "checkpoint_teleport") == 0) { zoneType = MOMZONETYPE_CPTELE; //destinationIndex = cp->GetInt("destination", -1); shouldStop = cp->GetBool("stop", false); shouldTilt = cp->GetBool("resetang", true); linkedtrigger = cp->GetString("destinationname", NULL); } else if (Q_strcmp(cp->GetName(), "multihop") == 0) { zoneType = MOMZONETYPE_MULTIHOP; shouldStop = cp->GetBool("stop", false); shouldTilt = cp->GetBool("resetang", true); holdTime = cp->GetFloat("hold", 1); //destinationIndex = cp->GetInt("destination", 1); linkedtrigger = cp->GetString("destinationname", NULL); } else if (Q_strcmp(cp->GetName(), "stage") == 0) { zoneType = MOMZONETYPE_STAGE; index = cp->GetInt("number", 0); } else { Warning("Error while reading zone file: Unknown mapzone type %s!\n", cp->GetName()); continue; } // Add element m_zones.AddToTail(new CMapzone(zoneType, pos, rot, scaleMins, scaleMaxs, index, shouldStop, shouldTilt, holdTime, limitingspeed, maxleavespeed, MAKE_STRING(linkedtrigger))); } DevLog("Successfully loaded map zone file %s!\n", zoneFilePath); toReturn = true; } zoneKV->deleteThis(); return toReturn; }
/** * @brief - send name, team and value when there is a winner - else empty string * and TEAM_FREE = 0 (client structure is only used for awards!) * - connectedClients have a team but keep the check for TEAM_FREE * ... we'll never know for sure, connectedClients are determined in CalculateRanks */ void G_BuildEndgameStats(void) { char buffer[1024]; int i, j; gclient_t *best = NULL; int bestClientNum = -1; float mapXP, bestMapXP = 0.f; G_CalcClientAccuracies(); for (i = 0; i < level.numConnectedClients; i++) { level.clients[i].hasaward = qfalse; } *buffer = '\0'; // highest ranking officer - check rank, then medals and XP for (i = 0; i < level.numConnectedClients; i++) { gclient_t *cl = &level.clients[level.sortedClients[i]]; if (cl->sess.sessionTeam == TEAM_FREE) { continue; } if (!best || cl->sess.rank > best->sess.rank) { best = cl; bestClientNum = level.sortedClients[i]; } else if (cl->sess.rank == best->sess.rank && cl->medals > best->medals) { best = cl; bestClientNum = level.sortedClients[i]; } else if (cl->sess.rank == best->sess.rank && cl->medals == best->medals && cl->ps.persistant[PERS_SCORE] > best->ps.persistant[PERS_SCORE]) { best = cl; bestClientNum = level.sortedClients[i]; } } if (best) { best->hasaward = qtrue; Q_strcat(buffer, 1024, va("%i 0 %i ", bestClientNum, best->sess.sessionTeam)); } else { Q_strcat(buffer, 1024, "-1 0 0 "); } best = NULL; #ifdef FEATURE_RATING // highest rated player - check skill rating for (i = 0; i < level.numConnectedClients; i++) { gclient_t *cl = &level.clients[level.sortedClients[i]]; if (cl->sess.sessionTeam == TEAM_FREE) { continue; } if (cl->sess.mu - 3 * cl->sess.sigma <= 0) { continue; } if (!best || (cl->sess.mu - 3 * cl->sess.sigma) > (best->sess.mu - 3 * best->sess.sigma)) { best = cl; bestClientNum = level.sortedClients[i]; } } if (best) { best->hasaward = qtrue; Q_strcat(buffer, 1024, va("%i %.2f %i ", bestClientNum, MIN(best->sess.mu - 3 * best->sess.sigma, 50.f), best->sess.sessionTeam)); } else { Q_strcat(buffer, 1024, "-1 0 0 "); } best = NULL; #endif // highest experience points - check XP (total in campaign, otherwise this map only then total XP) for (i = 0; i < level.numConnectedClients; i++) { gclient_t *cl = &level.clients[level.sortedClients[i]]; if (cl->sess.sessionTeam == TEAM_FREE) { continue; } if (cl->ps.persistant[PERS_SCORE] <= 0) { continue; } if (g_gametype.integer == GT_WOLF_CAMPAIGN) { if (!best || cl->ps.persistant[PERS_SCORE] > best->ps.persistant[PERS_SCORE]) { best = cl; bestClientNum = level.sortedClients[i]; } } else { mapXP = 0.f; for (j = 0; j < SK_NUM_SKILLS; j++) { mapXP += (cl->sess.skillpoints[j] - cl->sess.startskillpoints[j]); } if (!best || mapXP > bestMapXP) { best = cl; bestMapXP = mapXP; bestClientNum = level.sortedClients[i]; } else if (mapXP == bestMapXP && cl->ps.persistant[PERS_SCORE] > best->ps.persistant[PERS_SCORE]) { best = cl; bestMapXP = mapXP; bestClientNum = level.sortedClients[i]; } } } if (best) { best->hasaward = qtrue; if (g_gametype.integer == GT_WOLF_CAMPAIGN) { Q_strcat(buffer, 1024, va("%i %i %i ", bestClientNum, best->ps.persistant[PERS_SCORE], best->sess.sessionTeam)); } else { Q_strcat(buffer, 1024, va("%i %i %i ", bestClientNum, (int)bestMapXP, best->sess.sessionTeam)); } } else { Q_strcat(buffer, 1024, "-1 0 0 "); } best = NULL; // most highly decorated - check medals then XP for (i = 0; i < level.numConnectedClients; i++) { gclient_t *cl = &level.clients[level.sortedClients[i]]; if (cl->sess.sessionTeam == TEAM_FREE) { continue; } if (cl->medals <= 0) { continue; } if (!best || cl->medals > best->medals) { best = cl; bestClientNum = level.sortedClients[i]; } else if (cl->medals == best->medals && cl->ps.persistant[PERS_SCORE] > best->ps.persistant[PERS_SCORE]) { best = cl; bestClientNum = level.sortedClients[i]; } } if (best) { best->hasaward = qtrue; Q_strcat(buffer, 1024, va("%i %i %i ", bestClientNum, best->medals, best->sess.sessionTeam)); } else { Q_strcat(buffer, 1024, "-1 0 0 "); } // highest fragger - check kills, then damage given for (i = 0; i < level.numConnectedClients; i++) { gclient_t *cl = &level.clients[level.sortedClients[i]]; if (cl->sess.sessionTeam == TEAM_FREE) { continue; } if (cl->sess.kills <= 0) { continue; } if (!best || cl->sess.kills > best->sess.kills) { best = cl; bestClientNum = level.sortedClients[i]; } else if (cl->sess.kills == best->sess.kills && cl->sess.damage_given > best->sess.damage_given) { best = cl; bestClientNum = level.sortedClients[i]; } } if (best) { best->hasaward = qtrue; Q_strcat(buffer, 1024, va("%i %i %i ", bestClientNum, best->sess.kills, best->sess.sessionTeam)); } else { Q_strcat(buffer, 1024, "-1 0 0 "); } best = NULL; // highest skills - check skills points (this map only, min lvl 1) for (i = 0; i < SK_NUM_SKILLS; i++) { best = NULL; for (j = 0; j < level.numConnectedClients; j++) { gclient_t *cl = &level.clients[level.sortedClients[j]]; if (cl->sess.sessionTeam == TEAM_FREE) { continue; } if ((cl->sess.skillpoints[i] - cl->sess.startskillpoints[i]) <= 0) { continue; } if (cl->sess.skill[i] < 1) { continue; } if (!best || (cl->sess.skillpoints[i] - cl->sess.startskillpoints[i]) > (best->sess.skillpoints[i] - best->sess.startskillpoints[i])) { best = cl; bestClientNum = level.sortedClients[j]; } } if (best) { best->hasaward = qtrue; Q_strcat(buffer, 1024, va("%i %i %i ", bestClientNum, (int)(best->sess.skillpoints[i] - best->sess.startskillpoints[i]), best->sess.sessionTeam)); } else { Q_strcat(buffer, 1024, "-1 0 0 "); } } best = NULL; // highest accuracy for (i = 0; i < level.numConnectedClients; i++) { gclient_t *cl = &level.clients[level.sortedClients[i]]; if (cl->sess.sessionTeam == TEAM_FREE) { continue; } if (cl->acc <= 0) { continue; } if (!best || cl->acc > best->acc) { best = cl; bestClientNum = level.sortedClients[i]; } } if (best) { best->hasaward = qtrue; Q_strcat(buffer, 1024, va("%i %.2f %i ", bestClientNum, best->acc < 100.f ? (double)best->acc : 100., best->sess.sessionTeam)); } else { Q_strcat(buffer, 1024, "-1 0 0 "); } best = NULL; // highest HS percentage for (i = 0; i < level.numConnectedClients; i++) { gclient_t *cl = &level.clients[level.sortedClients[i]]; if (cl->sess.sessionTeam == TEAM_FREE) { continue; } if (cl->hspct <= 0) { continue; } if (!best || cl->hspct > best->hspct) { best = cl; bestClientNum = level.sortedClients[i]; } } if (best) { best->hasaward = qtrue; Q_strcat(buffer, 1024, va("%i %.2f %i ", bestClientNum, best->hspct < 100.f ? (double)best->hspct : 100., best->sess.sessionTeam)); } else { Q_strcat(buffer, 1024, "-1 0 0 "); } best = NULL; // best survivor - check time played percentage (min 50% of map duration) for (i = 0; i < level.numConnectedClients; i++) { gclient_t *cl = &level.clients[level.sortedClients[i]]; if (cl->sess.sessionTeam == TEAM_FREE) { continue; } if ((level.time - cl->pers.enterTime) / (float)(level.time - level.intermissiontime) < 0.5f) { continue; } if (!best || (cl->sess.time_played / (float)(level.time - cl->pers.enterTime)) > (best->sess.time_played / (float)(level.time - best->pers.enterTime))) { best = cl; bestClientNum = level.sortedClients[i]; } } if (best) { best->hasaward = qtrue; Q_strcat(buffer, 1024, va("%i %.2f %i ", bestClientNum, MIN(100. * best->sess.time_played / (double)(level.time - best->pers.enterTime), 100.), best->sess.sessionTeam)); } else { Q_strcat(buffer, 1024, "-1 0 0 "); } best = NULL; // most gibs - check gibs, then damage given for (i = 0; i < level.numConnectedClients; i++) { gclient_t *cl = &level.clients[level.sortedClients[i]]; if (cl->sess.sessionTeam == TEAM_FREE) { continue; } if (cl->sess.gibs <= 0) { continue; } if (!best || cl->sess.gibs > best->sess.gibs) { best = cl; bestClientNum = level.sortedClients[i]; } else if (cl->sess.gibs == best->sess.gibs && cl->sess.damage_given > best->sess.damage_given) { best = cl; bestClientNum = level.sortedClients[i]; } } if (best) { best->hasaward = qtrue; Q_strcat(buffer, 1024, va("%i %i %i ", bestClientNum, best->sess.gibs, best->sess.sessionTeam)); } else { Q_strcat(buffer, 1024, "-1 0 0 "); } best = NULL; // most selfkill - check selfkills, then deaths for (i = 0; i < level.numConnectedClients; i++) { gclient_t *cl = &level.clients[level.sortedClients[i]]; if (cl->sess.sessionTeam == TEAM_FREE) { continue; } if (cl->sess.self_kills <= 0) { continue; } if (!best || cl->sess.self_kills > best->sess.self_kills) { best = cl; bestClientNum = level.sortedClients[i]; } else if (cl->sess.self_kills == best->sess.self_kills && cl->sess.deaths > best->sess.deaths) { best = cl; bestClientNum = level.sortedClients[i]; } } if (best) { best->hasaward = qtrue; Q_strcat(buffer, 1024, va("%i %i %i ", bestClientNum, best->sess.self_kills, best->sess.sessionTeam)); } else { Q_strcat(buffer, 1024, "-1 0 0 "); } best = NULL; // most deaths - check deaths, then damage received for (i = 0; i < level.numConnectedClients; i++) { gclient_t *cl = &level.clients[level.sortedClients[i]]; if (cl->sess.sessionTeam == TEAM_FREE) { continue; } if (cl->sess.deaths <= 0) { continue; } if (!best || cl->sess.deaths > best->sess.deaths) { best = cl; bestClientNum = level.sortedClients[i]; } else if (cl->sess.deaths == best->sess.deaths && cl->sess.damage_received > best->sess.damage_received) { best = cl; bestClientNum = level.sortedClients[i]; } } if (best) { best->hasaward = qtrue; Q_strcat(buffer, 1024, va("%i %i %i ", bestClientNum, best->sess.deaths, best->sess.sessionTeam)); } else { Q_strcat(buffer, 1024, "-1 0 0 "); } best = NULL; // I ain't got no friends award - check team kills, then team damage given (min 5 tks) for (i = 0; i < level.numConnectedClients; i++) { gclient_t *cl = &level.clients[level.sortedClients[i]]; if (cl->sess.sessionTeam == TEAM_FREE) { continue; } if (!best || cl->sess.team_kills > best->sess.team_kills) { best = cl; bestClientNum = level.sortedClients[i]; } else if (cl->sess.team_kills == best->sess.team_kills && cl->sess.team_damage_given > best->sess.team_damage_given) { best = cl; bestClientNum = level.sortedClients[i]; } } if (best) { best->hasaward = qtrue; } Q_strcat(buffer, 1024, va("%i %i %i ", best && best->sess.team_kills >= 5 ? bestClientNum : -1, best ? best->sess.team_kills : 0, best && best->sess.team_kills >= 5 ? best->sess.sessionTeam : TEAM_FREE)); best = NULL; // welcome newbie! award - dont get this if any other award given or > 100 xp (this map) for (i = 0; i < level.numConnectedClients; i++) { gclient_t *cl = &level.clients[level.sortedClients[i]]; if (cl->sess.sessionTeam == TEAM_FREE) { continue; } if (!best || (cl->ps.persistant[PERS_SCORE] / (float)(level.time - cl->pers.enterTime)) > (best->ps.persistant[PERS_SCORE] / (float)(level.time - best->pers.enterTime))) { best = cl; bestClientNum = level.sortedClients[i]; } } if (best) { if ((best->sess.startxptotal - best->ps.persistant[PERS_SCORE]) >= 100 || best->medals || best->hasaward) { best = NULL; } } Q_strcat(buffer, 1024, va("%i %i %i ", best ? bestClientNum : -1, best ? best->ps.persistant[PERS_SCORE] : 0, best ? best->sess.sessionTeam : TEAM_FREE)); trap_SetConfigstring(CS_ENDGAME_STATS, buffer); }
static void saveZonFile(const char* szMapName) { KeyValues* zoneKV = new KeyValues(szMapName); CBaseEntity* pEnt = gEntList.FindEntityByClassname(NULL, "trigger_momentum_*"); while (pEnt) { KeyValues* subKey = NULL; if (pEnt->ClassMatches("trigger_momentum_timer_start")) { CTriggerTimerStart* pTrigger = dynamic_cast<CTriggerTimerStart*>(pEnt); subKey = new KeyValues("start"); if (pTrigger) { subKey->SetFloat("leavespeed", pTrigger->GetMaxLeaveSpeed()); subKey->SetBool("limitingspeed", pTrigger->IsLimitingSpeed()); } } else if (pEnt->ClassMatches("trigger_momentum_timer_stop")) { subKey = new KeyValues("end"); } else if (pEnt->ClassMatches("trigger_momentum_timer_checkpoint")) { CTriggerCheckpoint* pTrigger = dynamic_cast<CTriggerCheckpoint*>(pEnt); if (pTrigger) { subKey = new KeyValues("checkpoint"); subKey->SetInt("number", pTrigger->GetCheckpointNumber()); } } else if (pEnt->ClassMatches("trigger_momentum_onehop")) { CTriggerOnehop* pTrigger = dynamic_cast<CTriggerOnehop*>(pEnt); if (pTrigger) { subKey = new KeyValues("onehop"); //subKey->SetInt("destination", pTrigger->GetDestinationIndex()); subKey->SetBool("stop", pTrigger->ShouldStopPlayer()); subKey->SetBool("resetang", pTrigger->ShouldResetAngles()); subKey->SetFloat("hold", pTrigger->GetHoldTeleportTime()); subKey->SetString("destinationname", pTrigger->m_target.ToCStr()); } } else if (pEnt->ClassMatches("trigger_momentum_resetonehop")) { subKey = new KeyValues("resetonehop"); } else if (pEnt->ClassMatches("trigger_momentum_teleport_checkpoint")) { CTriggerTeleportCheckpoint* pTrigger = dynamic_cast<CTriggerTeleportCheckpoint*>(pEnt); if (pTrigger) { subKey = new KeyValues("checkpoint_teleport"); //subKey->SetInt("destination", pTrigger->GetDestinationCheckpointNumber()); subKey->SetBool("stop", pTrigger->ShouldStopPlayer()); subKey->SetBool("resetang", pTrigger->ShouldResetAngles()); subKey->SetString("destinationname", pTrigger->m_target.ToCStr()); } } else if (pEnt->ClassMatches("trigger_momentum_multihop")) { CTriggerMultihop* pTrigger = dynamic_cast<CTriggerMultihop*>(pEnt); if (pTrigger) { subKey = new KeyValues("multihop"); //subKey->SetInt("destination", pTrigger->GetDestinationIndex()); subKey->SetBool("stop", pTrigger->ShouldStopPlayer()); subKey->SetFloat("hold", pTrigger->GetHoldTeleportTime()); subKey->SetBool("resetang", pTrigger->ShouldResetAngles()); subKey->SetString("destinationname", pTrigger->m_target.ToCStr()); } } else if (pEnt->ClassMatches("trigger_momentum_timer_stage")) { CTriggerStage *pTrigger = dynamic_cast<CTriggerStage*>(pEnt); if (pTrigger) { subKey = new KeyValues("stage"); subKey->SetInt("number", pTrigger->GetStageNumber()); } } if (subKey) { subKey->SetFloat("xPos", pEnt->GetAbsOrigin().x); subKey->SetFloat("yPos", pEnt->GetAbsOrigin().y); subKey->SetFloat("zPos", pEnt->GetAbsOrigin().z); subKey->SetFloat("xRot", pEnt->GetAbsAngles().x); subKey->SetFloat("yRot", pEnt->GetAbsAngles().y); subKey->SetFloat("zRot", pEnt->GetAbsAngles().z); subKey->SetFloat("xScaleMins", pEnt->WorldAlignMins().x); subKey->SetFloat("yScaleMins", pEnt->WorldAlignMins().y); subKey->SetFloat("zScaleMins", pEnt->WorldAlignMins().z); subKey->SetFloat("xScaleMaxs", pEnt->WorldAlignMaxs().x); subKey->SetFloat("yScaleMaxs", pEnt->WorldAlignMaxs().y); subKey->SetFloat("zScaleMaxs", pEnt->WorldAlignMaxs().z); zoneKV->AddSubKey(subKey); } pEnt = gEntList.FindEntityByClassname(pEnt, "trigger_momentum_*"); } if (zoneKV->GetFirstSubKey())//not empty { char zoneFilePath[MAX_PATH]; Q_strcpy(zoneFilePath, "maps/"); Q_strcat(zoneFilePath, szMapName, MAX_PATH); Q_strncat(zoneFilePath, ".zon", MAX_PATH); zoneKV->SaveToFile(filesystem, zoneFilePath, "MOD"); zoneKV->deleteThis(); } }
/** * @brief Test given language by trying to set locale. * @param[in] localeID language abbreviation. * @return true if setting given language is possible. */ static bool CL_LanguageTest (const char* localeID) { #ifndef _WIN32 int i; language_t* language; localeMapping_t* mapping; #endif char languagePath[MAX_OSPATH]; assert(localeID); /* Find the proper *.mo file. */ if (fs_i18ndir->string[0] != '\0') Q_strncpyz(languagePath, fs_i18ndir->string, sizeof(languagePath)); else #ifdef LOCALEDIR Com_sprintf(languagePath, sizeof(languagePath), LOCALEDIR); #else Com_sprintf(languagePath, sizeof(languagePath), "%s/" BASEDIRNAME "/i18n/", FS_GetCwd()); #endif Com_DPrintf(DEBUG_CLIENT, "CL_LanguageTest: using mo files from '%s'\n", languagePath); Q_strcat(languagePath, sizeof(languagePath), "%s/LC_MESSAGES/ufoai.mo", localeID); /* No *.mo file -> no language. */ if (!FS_FileExists("%s", languagePath)) { Com_DPrintf(DEBUG_CLIENT, "CL_LanguageTest: locale '%s' not found.\n", localeID); return false; } #ifdef _WIN32 if (Sys_Setenv("LANGUAGE=%s", localeID) == 0) { Com_DPrintf(DEBUG_CLIENT, "CL_LanguageTest: locale '%s' found.\n", localeID); return true; } #else for (i = 0, language = languageList; i < languageCount; language = language->next, i++) { if (Q_streq(localeID, language->localeID)) break; } if (i == languageCount) { Com_DPrintf(DEBUG_CLIENT, "CL_LanguageTest: Could not find locale with id '%s'\n", localeID); return false; } mapping = language->localeMapping; if (!mapping) { Com_DPrintf(DEBUG_CLIENT, "No locale mappings for locale with id '%s'\n", localeID); return false; } /* Cycle through all mappings, but stop at first locale possible to set. */ do { /* setlocale() will return nullptr if no setting possible. */ if (setlocale(LC_MESSAGES, mapping->localeMapping)) { Com_DPrintf(DEBUG_CLIENT, "CL_LanguageTest: language '%s' with locale '%s' found.\n", localeID, mapping->localeMapping); return true; } else Com_DPrintf(DEBUG_CLIENT, "CL_LanguageTest: language '%s' with locale '%s' not found on your system.\n", localeID, mapping->localeMapping); mapping = mapping->next; } while (mapping); Com_DPrintf(DEBUG_CLIENT, "CL_LanguageTest: not possible to use language '%s'.\n", localeID); #endif return false; }
/** * @brief Prints the (UFOpaedia and other) description for aircraft items * @param item The object definition of the item * @sa UP_Article * Not only called from UFOpaedia but also from other places to display * @todo Don't display things like speed for base defence items - a missile * facility isn't getting slower or faster due a special weapon or ammunition */ void UP_AircraftItemDescription (const objDef_t* item) { static char itemText[1024]; const technology_t* tech; /* Set menu text node content to null. */ cgi->INV_ItemDescription(nullptr); *itemText = '\0'; /* no valid item id given */ if (!item) { cgi->Cvar_Set("mn_item", ""); cgi->Cvar_Set("mn_itemname", ""); cgi->Cvar_Set("mn_upmodel_top", ""); cgi->UI_ResetData(TEXT_ITEMDESCRIPTION); return; } tech = RS_GetTechForItem(item); /* select item */ cgi->Cvar_Set("mn_item", "%s", item->id); cgi->Cvar_Set("mn_itemname", "%s", _(item->name)); if (tech->mdl) cgi->Cvar_Set("mn_upmodel_top", "%s", tech->mdl); else cgi->Cvar_Set("mn_upmodel_top", ""); /* set description text */ if (RS_IsResearched_ptr(tech)) { const objDef_t* ammo = nullptr; switch (item->craftitem.type) { case AC_ITEM_WEAPON: Q_strcat(itemText, sizeof(itemText), _("Weight:\t%s\n"), AII_WeightToName(AII_GetItemWeightBySize(item))); break; case AC_ITEM_BASE_MISSILE: case AC_ITEM_BASE_LASER: Q_strcat(itemText, sizeof(itemText), _("Weapon for base defence system\n")); break; case AC_ITEM_AMMO: ammo = item; break; default: break; } /* check ammo of weapons */ if (item->craftitem.type <= AC_ITEM_WEAPON) { for(int i = 0; i < item->numAmmos; i++) if (item->ammos[i]->isVirtual) { ammo = item->ammos[i]; break; } } if (ammo) { /* We display the characteristics of this ammo */ Q_strcat(itemText, sizeof(itemText), _("Ammo:\t%i\n"), ammo->ammo); if (!EQUAL(ammo->craftitem.weaponDamage, 0)) Q_strcat(itemText, sizeof(itemText), _("Damage:\t%i\n"), (int) ammo->craftitem.weaponDamage); Q_strcat(itemText, sizeof(itemText), _("Reloading time:\t%i\n"), (int) ammo->craftitem.weaponDelay); } /* We write the range of the weapon */ if (!EQUAL(item->craftitem.stats[AIR_STATS_WRANGE], 0)) Q_strcat(itemText, sizeof(itemText), "%s:\t%i\n", UP_AircraftStatToName(AIR_STATS_WRANGE), AIR_AircraftMenuStatsValues(item->craftitem.stats[AIR_STATS_WRANGE], AIR_STATS_WRANGE)); /* we scan all stats except weapon range */ for (int i = 0; i < AIR_STATS_MAX; i++) { const char* statsName = UP_AircraftStatToName(i); if (i == AIR_STATS_WRANGE) continue; if (item->craftitem.stats[i] > 2.0f) Q_strcat(itemText, sizeof(itemText), "%s:\t+%i\n", statsName, AIR_AircraftMenuStatsValues(item->craftitem.stats[i], i)); else if (item->craftitem.stats[i] < -2.0f) Q_strcat(itemText, sizeof(itemText), "%s:\t%i\n", statsName, AIR_AircraftMenuStatsValues(item->craftitem.stats[i], i)); else if (item->craftitem.stats[i] > 1.0f) Q_strcat(itemText, sizeof(itemText), _("%s:\t+%i %%\n"), statsName, (int)(item->craftitem.stats[i] * 100) - 100); else if (!EQUAL(item->craftitem.stats[i], 0)) Q_strcat(itemText, sizeof(itemText), _("%s:\t%i %%\n"), statsName, (int)(item->craftitem.stats[i] * 100) - 100); } } else { Q_strcat(itemText, sizeof(itemText), _("Unknown - need to research this")); } cgi->Cvar_Set("mn_upmetadata", "1"); cgi->UI_RegisterText(TEXT_ITEMDESCRIPTION, itemText); }
qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir ) { byte buf[MAX_SYSPATH]; char *buffer; string result; int i, size; search_t *t; file_t *f; if( FS_FileSize( "maps.lst", onlyingamedir ) > 0 && !fRefresh ) { MsgDev( D_NOTE, "maps.lst is exist: %s\n", onlyingamedir ? "basedir" : "gamedir" ); return true; // exist } t = FS_Search( "maps/*.bsp", false, onlyingamedir ); if( !t ) { if( onlyingamedir ) { // mod doesn't contain any maps (probably this is a bot) return Cmd_CheckMapsList_R( fRefresh, false ); } return false; } buffer = Mem_Alloc( host.mempool, t->numfilenames * 2 * sizeof( result )); for( i = 0; i < t->numfilenames; i++ ) { char *ents = NULL, *pfile; int ver = -1, lumpofs = 0, lumplen = 0; string mapname, message, entfilename; const char *ext = FS_FileExtension( t->filenames[i] ); if( Q_stricmp( ext, "bsp" )) continue; f = FS_Open( t->filenames[i], "rb", onlyingamedir ); FS_FileBase( t->filenames[i], mapname ); if( f ) { int num_spawnpoints = 0; dheader_t *header; Q_memset( buf, 0, MAX_SYSPATH ); FS_Read( f, buf, MAX_SYSPATH ); ver = *(uint *)buf; switch( ver ) { case Q1BSP_VERSION: case HLBSP_VERSION: case XTBSP_VERSION: header = (dheader_t *)buf; if( header->lumps[LUMP_ENTITIES].fileofs <= 1024 ) { lumpofs = header->lumps[LUMP_PLANES].fileofs; lumplen = header->lumps[LUMP_PLANES].filelen; } else { lumpofs = header->lumps[LUMP_ENTITIES].fileofs; lumplen = header->lumps[LUMP_ENTITIES].filelen; } break; } Q_strncpy( entfilename, t->filenames[i], sizeof( entfilename )); FS_StripExtension( entfilename ); FS_DefaultExtension( entfilename, ".ent" ); ents = FS_LoadFile( entfilename, NULL, true ); if( !ents && lumplen >= 10 ) { FS_Seek( f, lumpofs, SEEK_SET ); ents = (char *)Mem_Alloc( host.mempool, lumplen + 1 ); FS_Read( f, ents, lumplen ); } if( ents ) { // if there are entities to parse, a missing message key just // means there is no title, so clear the message string now char token[2048]; qboolean worldspawn = true; Q_strncpy( message, "No Title", MAX_STRING ); pfile = ents; while(( pfile = COM_ParseFile( pfile, token )) != NULL ) { if( token[0] == '}' && worldspawn ) worldspawn = false; else if( !Q_strcmp( token, "message" ) && worldspawn ) { // get the message contents pfile = COM_ParseFile( pfile, message ); } else if( !Q_strcmp( token, "classname" )) { pfile = COM_ParseFile( pfile, token ); if( !Q_strcmp( token, GI->mp_entity )) num_spawnpoints++; } if( num_spawnpoints ) break; // valid map } Mem_Free( ents ); } if( f ) FS_Close( f ); if( num_spawnpoints ) { // format: mapname "maptitle"\n Q_sprintf( result, "%s \"%s\"\n", mapname, message ); Q_strcat( buffer, result ); // add new string } } } if( t ) Mem_Free( t ); // free search result size = Q_strlen( buffer ); if( !size ) { if( buffer ) Mem_Free( buffer ); if( onlyingamedir ) return Cmd_CheckMapsList_R( fRefresh, false ); return false; } // write generated maps.lst if( FS_WriteFile( "maps.lst", buffer, Q_strlen( buffer ))) { if( buffer ) Mem_Free( buffer ); return true; } return false; }
/* ================= main ================= */ int main( int argc, char **argv ) { int i; char commandLine[ MAX_STRING_CHARS ] = { 0 }; #ifndef DEDICATED // SDL version check // Compile time # if !SDL_VERSION_ATLEAST(MINSDL_MAJOR,MINSDL_MINOR,MINSDL_PATCH) # error A more recent version of SDL is required # endif // Run time SDL_version ver; SDL_GetVersion( &ver ); #define MINSDL_VERSION \ XSTRING(MINSDL_MAJOR) "." \ XSTRING(MINSDL_MINOR) "." \ XSTRING(MINSDL_PATCH) if( SDL_VERSIONNUM( ver.major, ver.minor, ver.patch ) < SDL_VERSIONNUM( MINSDL_MAJOR, MINSDL_MINOR, MINSDL_PATCH ) ) { Sys_Dialog( DT_ERROR, va( "SDL version " MINSDL_VERSION " or greater is required, " "but only version %d.%d.%d was found. You may be able to obtain a more recent copy " "from http://www.libsdl.org/.", ver.major, ver.minor, ver.patch ), "SDL Library Too Old" ); Sys_Exit( 1 ); } #endif Sys_PlatformInit( ); // Set the initial time base Sys_Milliseconds( ); #ifdef MACOS_X // This is passed if we are launched by double-clicking if ( argc >= 2 && Q_strncmp ( argv[1], "-psn", 4 ) == 0 ) argc = 1; #endif Sys_ParseArgs( argc, argv ); Sys_SetBinaryPath( Sys_Dirname( argv[ 0 ] ) ); Sys_SetDefaultInstallPath( DEFAULT_BASEDIR ); // Concatenate the command line for passing to Com_Init for( i = 1; i < argc; i++ ) { const qboolean containsSpaces = strchr(argv[i], ' ') != NULL; if (containsSpaces) Q_strcat( commandLine, sizeof( commandLine ), "\"" ); Q_strcat( commandLine, sizeof( commandLine ), argv[ i ] ); if (containsSpaces) Q_strcat( commandLine, sizeof( commandLine ), "\"" ); Q_strcat( commandLine, sizeof( commandLine ), " " ); } Com_Init( commandLine ); NET_Init( ); CON_Init( ); signal( SIGILL, Sys_SigHandler ); signal( SIGFPE, Sys_SigHandler ); signal( SIGSEGV, Sys_SigHandler ); signal( SIGTERM, Sys_SigHandler ); signal( SIGINT, Sys_SigHandler ); while( 1 ) { IN_Frame( ); Com_Frame( ); } return 0; }
/** * @brief Console completion for command and variables * @sa Key_CompleteCommand * @sa Cmd_CompleteCommand * @sa Cvar_CompleteVariable * @param[in] s The string to complete * @param[out] target The target buffer of the completed command/cvar * @param[in] bufSize the target buffer size - might not be bigger than MAXCMDLINE * @param[out] pos The position in the buffer after command completion * @param[in] offset The input buffer position to put the completed command to */ bool Com_ConsoleCompleteCommand (const char* s, char* target, size_t bufSize, uint32_t* pos, uint32_t offset) { const char* cmd = nullptr, *cvar = nullptr, *use = nullptr; char cmdLine[MAXCMDLINE] = ""; char cmdBase[MAXCMDLINE] = ""; bool append = true; if (!s[0] || s[0] == ' ') return false; if (s[0] == '\\' || s[0] == '/') { /* maybe we are using the same buffers - and we want to keep the slashes */ if (s == target) offset++; s++; } assert(bufSize <= MAXCMDLINE); assert(pos); /* don't try to search a command or cvar if we are already in the * parameter stage */ if (strstr(s, " ")) { int cntParams; char* tmp; Q_strncpyz(cmdLine, s, sizeof(cmdLine)); /* remove the last whitespace */ cmdLine[strlen(cmdLine) - 1] = '\0'; tmp = cmdBase; while (*s != ' ') *tmp++ = *s++; /* get rid of the whitespace */ s++; /* terminate the string at whitespace position to separate the cmd */ *tmp = '\0'; /* now strip away that part that is not yet completed */ tmp = strrchr(cmdLine, ' '); if (tmp) *tmp = '\0'; cntParams = Cmd_CompleteCommandParameters(cmdBase, s, &cmd); if (cntParams > 1) Com_Printf("\n"); if (cmd) { /* append the found parameter */ Q_strcat(cmdLine, sizeof(cmdLine), " %s", cmd); append = false; use = cmdLine; } else return false; } else { /* Cmd_GenericCompleteFunction uses one static buffer for output, so backup one completion here if available */ static char cmdBackup[MAX_QPATH]; int cntCvar; int cntCmd = Cmd_CompleteCommand(s, &cmd); if (cmd) Q_strncpyz(cmdBackup, cmd, sizeof(cmdBackup)); cntCvar = Cvar_CompleteVariable(s, &cvar); /* complete as much as possible, append only if one single match is found */ if (cntCmd > 0 && !cntCvar) { use = cmd; if (cntCmd != 1) append = false; } else if (!cntCmd && cntCvar > 0) { use = cvar; if (cntCvar != 1) append = false; } else if (cmd && cvar) { int maxLength = std::min(strlen(cmdBackup),strlen(cvar)); int idx = 0; /* try to find similar content of cvar and cmd match */ Q_strncpyz(cmdLine, cmdBackup,sizeof(cmdLine)); for (; idx < maxLength; idx++) { if (cmdBackup[idx] != cvar[idx]) { cmdLine[idx] = '\0'; break; } } if (idx == maxLength) cmdLine[idx] = '\0'; use = cmdLine; append = false; } } if (use) { Q_strncpyz(&target[offset], use, bufSize - offset); *pos = strlen(target); if (append) target[(*pos)++] = ' '; target[*pos] = '\0'; return true; } return false; }
// Shows best/worst accuracy for all weapons, or sorted // accuracies for a single weapon. void G_weaponRankings_cmd(gentity_t * ent, unsigned int dwCommand, qboolean state) { gclient_t *cl; int c = 0, i, wBestAcc; unsigned int shots; // CHRUKER: b068 - unsigned char z[MAX_STRING_CHARS]; if(trap_Argc() < 2) { G_weaponStatsLeaders_cmd(ent, state, qfalse); return; } wBestAcc = (state) ? 0 : 99999; // Find the weapon trap_Argv(1, z, sizeof(z)); if((iWeap = atoi(z)) == 0 || iWeap < WS_KNIFE || iWeap >= WS_MAX) { for(iWeap = WS_SYRINGE; iWeap >= WS_KNIFE; iWeap--) { if(!Q_stricmp(z, aWeaponInfo[iWeap].pszCode)) { break; } } } if(iWeap < WS_KNIFE) { G_commandHelp(ent, (state) ? "topshots" : "bottomshots", dwCommand); Q_strncpyz(z, "^3Available weapon codes:^7\n", sizeof(z)); for(i = WS_KNIFE; i < WS_MAX; i++) { Q_strcat(z, sizeof(z), va(" %s - %s\n", aWeaponInfo[i].pszCode, aWeaponInfo[i].pszName)); } CP(va("print \"%s\"", z)); return; } memcpy(&level.sortedStats, &level.sortedClients, sizeof(level.sortedStats)); qsort(level.sortedStats, level.numConnectedClients, sizeof(level.sortedStats[0]), SortStats); z[0] = 0; for(i = 0; i < level.numConnectedClients; i++) { cl = &level.clients[level.sortedStats[i]]; if(cl->sess.sessionTeam == TEAM_SPECTATOR) { continue; } shots = cl->sess.aWeaponStats[iWeap].atts; if(shots >= cQualifyingShots[iWeap]) { float acc = (float)(cl->sess.aWeaponStats[iWeap].hits * 100.0) / (float)shots; c++; wBestAcc = (((state) ? acc : wBestAcc) > ((state) ? wBestAcc : acc)) ? (int)acc : wBestAcc; Q_strcat(z, sizeof(z), va(" %d %d %d %d %d", level.sortedStats[i], cl->sess.aWeaponStats[iWeap].hits, shots, cl->sess.aWeaponStats[iWeap].kills, cl->sess.aWeaponStats[iWeap].deaths)); } } CP(va("astats%s %d %d %d%s", ((state) ? "" : "b"), c, iWeap, wBestAcc, z)); }
/** * @brief Dumps OpenGL state for debugging - typically every capability set with glEnable(). */ void R_DumpOpenGlState (void) { #define CAPABILITY( X ) {GL_ ## X, # X} /* List taken from here: http://www.khronos.org/opengles/sdk/1.1/docs/man/glIsEnabled.xml */ const struct { GLenum idx; const char * text; } openGLCaps[] = { CAPABILITY(ALPHA_TEST), CAPABILITY(BLEND), CAPABILITY(COLOR_ARRAY), CAPABILITY(COLOR_LOGIC_OP), CAPABILITY(COLOR_MATERIAL), CAPABILITY(CULL_FACE), CAPABILITY(DEPTH_TEST), CAPABILITY(DITHER), CAPABILITY(FOG), CAPABILITY(LIGHTING), CAPABILITY(LINE_SMOOTH), CAPABILITY(MULTISAMPLE), CAPABILITY(NORMAL_ARRAY), CAPABILITY(NORMALIZE), CAPABILITY(POINT_SMOOTH), CAPABILITY(POLYGON_OFFSET_FILL), CAPABILITY(RESCALE_NORMAL), CAPABILITY(SAMPLE_ALPHA_TO_COVERAGE), CAPABILITY(SAMPLE_ALPHA_TO_ONE), CAPABILITY(SAMPLE_COVERAGE), CAPABILITY(SCISSOR_TEST), CAPABILITY(STENCIL_TEST), CAPABILITY(VERTEX_ARRAY) }; #undef CAPABILITY char s[1024] = ""; GLint i; GLint maxTexUnits = 0; GLint activeTexUnit = 0; GLint activeClientTexUnit = 0; GLint activeTexId = 0; GLfloat texEnvMode = 0; const char * texEnvModeStr = "UNKNOWN"; GLfloat color[4]; for (i = 0; i < sizeof(openGLCaps)/sizeof(openGLCaps[0]); i++) { if (glIsEnabled(openGLCaps[i].idx)) { Q_strcat(s, sizeof(s), openGLCaps[i].text); Q_strcat(s, sizeof(s), " "); } } glGetFloatv(GL_CURRENT_COLOR, color); Com_Printf("OpenGL enabled caps: %s color %f %f %f %f \n", s, color[0], color[1], color[2], color[3]); glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexUnit); glGetIntegerv(GL_CLIENT_ACTIVE_TEXTURE, &activeClientTexUnit); glGetIntegerv(GL_MAX_TEXTURE_UNITS, &maxTexUnits); for (i = GL_TEXTURE0; i < GL_TEXTURE0 + maxTexUnits; i++) { glActiveTexture(i); glClientActiveTexture(i); strcpy(s, ""); if (glIsEnabled (GL_TEXTURE_2D)) strcat(s, "enabled, "); if (glIsEnabled (GL_TEXTURE_COORD_ARRAY)) strcat(s, "with texcoord array, "); if (i == activeTexUnit) strcat(s, "active, "); if (i == activeClientTexUnit) strcat(s, "client active, "); glGetIntegerv(GL_TEXTURE_BINDING_2D, &activeTexId); glGetTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &texEnvMode); if (fabs(texEnvMode - GL_ADD) < 0.1f) texEnvModeStr = "ADD"; if (fabs(texEnvMode - GL_MODULATE) < 0.1f) texEnvModeStr = "MODULATE"; if (fabs(texEnvMode - GL_DECAL) < 0.1f) texEnvModeStr = "DECAL"; if (fabs(texEnvMode - GL_BLEND) < 0.1f) texEnvModeStr = "BLEND"; if (fabs(texEnvMode - GL_REPLACE) < 0.1f) texEnvModeStr = "REPLACE"; if (fabs(texEnvMode - GL_COMBINE) < 0.1f) texEnvModeStr = "COMBINE"; Com_Printf("Texunit: %d texID %d %s texEnv mode %s\n", i - GL_TEXTURE0, activeTexId, s, texEnvModeStr); } glActiveTexture(activeTexUnit); glClientActiveTexture(activeClientTexUnit); }
/* =============== CG_HumanText =============== */ static void CG_HumanText( char *text, playerState_t *ps ) { char *name; int ammo, clips; upgrade_t upgrade = UP_NONE; if( cg.weaponSelect <= 32 ) name = cg_weapons[ cg.weaponSelect ].humanName; else if( cg.weaponSelect > 32 ) { name = cg_upgrades[ cg.weaponSelect - 32 ].humanName; upgrade = cg.weaponSelect - 32; } BG_UnpackAmmoArray( ps->weapon, &ps->ammo, ps->powerups, &ammo, &clips ); if( !ammo && !clips && !BG_FindInfinteAmmoForWeapon( ps->weapon ) ) { //no ammo switch( ps->weapon ) { case WP_MACHINEGUN: case WP_CHAINGUN: case WP_SHOTGUN: case WP_LAUNCHER: case WP_ROCKET_LAUNCHER: Q_strcat( text, MAX_TUTORIAL_TEXT, va( "Find an Armoury and press %s for more ammo\n", CG_KeyNameForCommand( "buy ammo" ) ) ); break; case WP_LAS_GUN: case WP_MASS_DRIVER: Q_strcat( text, MAX_TUTORIAL_TEXT, va( "Find a Reactor or Repeater and press %s for more ammo\n", CG_KeyNameForCommand( "buy ammo" ) ) ); break; default: break; } } else { switch( ps->weapon ) { case WP_LAUNCHER: Q_strcat( text, MAX_TUTORIAL_TEXT, va( "Press %s to fire the %s\n", CG_KeyNameForCommand( "+attack" ), BG_FindHumanNameForWeapon( ps->weapon ) ) ); Q_strcat( text, MAX_TUTORIAL_TEXT, va( "Press %s to fire incendiary grenade\n", CG_KeyNameForCommand( "+button5" ) ) ); break; case WP_PISTOL: case WP_MACHINEGUN: case WP_SHOTGUN: case WP_LAS_GUN: case WP_CHAINGUN: case WP_MASS_DRIVER: case WP_ROCKET_LAUNCHER: Q_strcat( text, MAX_TUTORIAL_TEXT, va( "Press %s to fire the %s\n", CG_KeyNameForCommand( "+attack" ), BG_FindHumanNameForWeapon( ps->weapon ) ) ); Q_strcat( text, MAX_TUTORIAL_TEXT, va( "Hold %s to zoom\n", CG_KeyNameForCommand( "+button5" ) ) ); break; case WP_HBUILD: case WP_HBUILD2: CG_HumanCkitText( text, ps ); break; default: break; } } Q_strcat( text, MAX_TUTORIAL_TEXT, va( "Press %s and ", CG_KeyNameForCommand( "weapprev" ) ) ); Q_strcat( text, MAX_TUTORIAL_TEXT, va( "%s to select an upgrade\n", CG_KeyNameForCommand( "weapnext" ) ) ); if( upgrade == UP_NONE || ( upgrade > UP_NONE && BG_FindUsableForUpgrade( upgrade ) ) ) { Q_strcat( text, MAX_TUTORIAL_TEXT, va( "Press %s to use the %s\n", CG_KeyNameForCommand( "+button2" ), name ) ); } if( ps->stats[ STAT_HEALTH ] <= 35 && BG_InventoryContainsUpgrade( UP_MEDKIT, ps->stats ) ) { Q_strcat( text, MAX_TUTORIAL_TEXT, va( "Press %s to use your %s\n", CG_KeyNameForCommand( "itemact medkit" ), BG_FindHumanNameForUpgrade( UP_MEDKIT ) ) ); } Q_strcat( text, MAX_TUTORIAL_TEXT, va( "Press %s to use a structure\n", CG_KeyNameForCommand( "+button7" ) ) ); }
void CG_Credits_Init( LPCSTR psStripReference, vec4_t *pv4Color) { // Play the light side end credits music. if ( g_entities[0].client->sess.mission_objectives[0].status != 2 ) { cgi_S_StartBackgroundTrack( "music/endcredits.mp3", NULL, false ); } // Play the dark side end credits music. else { cgi_S_StartBackgroundTrack( "music/vjun3/vjun3_explore.mp3", NULL, false ); } // 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; int iAdvanceCount; unsigned int uiLetter = cgi_AnyLanguage_ReadCharFromString(psTextParse, &iAdvanceCount, &bIsTrailingPunctuation); psTextParse += iAdvanceCount; // 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 (!strnicmp(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) { assert(0); // this means we're attempting to display asian credits, and we don't // support these now because the auto-capitalisation rules etc would have to // be inhibited. Q_strcat(sLine, sizeof(sLine), va("%c%c",uiLetter >> 8, uiLetter & 0xFF)); } else { Q_strcat(sLine, sizeof(sLine), va("%c",uiLetter & 0xFF)); } } }
/* =============== CG_TutorialText Returns context help for the current class/weapon =============== */ const char *CG_TutorialText( void ) { playerState_t *ps; static char text[ MAX_TUTORIAL_TEXT ]; CG_GetBindings( ); text[ 0 ] = '\0'; ps = &cg.snap->ps; if( !cg.intermissionStarted && !cg.demoPlayback ) { if( ps->persistant[ PERS_TEAM ] == TEAM_SPECTATOR || ps->pm_flags & PMF_FOLLOW ) { CG_SpectatorText( text, ps ); } else if( ps->stats[ STAT_HEALTH ] > 0 ) { switch( ps->stats[ STAT_PCLASS ] ) { case PCL_ALIEN_BUILDER0: case PCL_ALIEN_BUILDER0_UPG: CG_AlienBuilderText( text, ps ); break; case PCL_ALIEN_LEVEL0: CG_AlienLevel0Text( text, ps ); break; case PCL_ALIEN_LEVEL1: case PCL_ALIEN_LEVEL1_UPG: CG_AlienLevel1Text( text, ps ); break; case PCL_ALIEN_LEVEL2: case PCL_ALIEN_LEVEL2_UPG: CG_AlienLevel2Text( text, ps ); break; case PCL_ALIEN_LEVEL3: case PCL_ALIEN_LEVEL3_UPG: CG_AlienLevel3Text( text, ps ); break; case PCL_ALIEN_LEVEL4: CG_AlienLevel4Text( text, ps ); break; case PCL_HUMAN: CG_HumanText( text, ps ); break; default: break; } if( ps->stats[ STAT_PTEAM ] == PTE_ALIENS && BG_UpgradeClassAvailable( ps ) ) { Q_strcat( text, MAX_TUTORIAL_TEXT, va( "Press %s to evolve\n", CG_KeyNameForCommand( "+button7" ) ) ); } } Q_strcat( text, MAX_TUTORIAL_TEXT, "Press ESC for the menu" ); } return text; }
void UI_LoadPanel_RenderLoadingText(panel_button_t *button) { uiClientState_t cstate; char downloadName[MAX_INFO_VALUE]; char buff[2560]; char *p, *s = ""; float y; trap_GetClientState(&cstate); Com_sprintf(buff, sizeof(buff), trap_TranslateString("Connecting to:\n %s^*\n\n%s"), cstate.servername, Info_ValueForKey(cstate.updateInfoString, "motd")); if (trap_Cvar_VariableValue("com_updateavailable")) { Q_strcat(buff, sizeof(buff), "\n\nYour ET:L client is outdated. New update is available for download at www.etlegacy.com"); } trap_Cvar_VariableStringBuffer("cl_downloadName", downloadName, sizeof(downloadName)); if (!connect_ownerdraw) { if (!trap_Cvar_VariableValue("ui_connecting")) { switch (cstate.connState) { case CA_CONNECTING: s = va(trap_TranslateString("Awaiting connection...%i"), cstate.connectPacketCount); break; case CA_CHALLENGING: s = va(trap_TranslateString("Awaiting challenge...%i"), cstate.connectPacketCount); break; case CA_DISCONNECTED: case CA_CONNECTED: if (*downloadName || cstate.connState == CA_DISCONNECTED) { s = (char *)UI_DownloadInfo(downloadName); } else { s = trap_TranslateString("Awaiting gamestate..."); } break; case CA_LOADING: case CA_PRIMED: default: break; } } else if (trap_Cvar_VariableValue("ui_dl_running")) { // only toggle during a disconnected download s = (char *)UI_DownloadInfo(downloadName); } Q_strcat(buff, sizeof(buff), va("\n\n%s^*", s)); if (cstate.connState < CA_CONNECTED && *cstate.messageString) { Q_strcat(buff, sizeof(buff), va("\n\n%s^*", cstate.messageString)); } } BG_FitTextToWidth_Ext(buff, button->font->scalex, button->rect.w, sizeof(buff), button->font->font); //UI_DrawRect( button->rect.x, button->rect.y, button->rect.w, button->rect.h, colorRed ); y = button->rect.y + 12; s = p = buff; while (*p) { if (*p == '\n') { *p++ = '\0'; Text_Paint_Ext(button->rect.x + 4, y, button->font->scalex, button->font->scaley, button->font->colour, s, 0, 0, 0, button->font->font); y += 8; s = p; } else { p++; } } }
/* =============== UI_PlayerInfo_SetWeapon =============== */ static void UI_PlayerInfo_SetWeapon( playerInfo_t *pi, weapon_t weaponNum ) { gitem_t * item; char path[MAX_QPATH]; pi->currentWeapon = weaponNum; tryagain: pi->realWeapon = weaponNum; pi->weaponModel = 0; pi->barrelModel = 0; pi->flashModel = 0; if ( weaponNum == WP_NONE ) { return; } // NERVE - SMF - multiplayer only hack to show correct panzerfaust and venom barrel if ( weaponNum == WP_PANZERFAUST ) { pi->weaponModel = trap_R_RegisterModel( "models/multiplayer/panzerfaust/multi_pf.md3" ); return; } else if ( weaponNum == WP_VENOM ) { pi->barrelModel = trap_R_RegisterModel( "models/weapons2/venom/venom_barrel.md3" ); } // -NERVE - SMF for ( item = bg_itemlist + 1; item->classname ; item++ ) { if ( item->giType != IT_WEAPON ) { continue; } if ( item->giTag == weaponNum ) { break; } } if ( item->classname ) { pi->weaponModel = trap_R_RegisterModel( item->world_model[0] ); } if ( pi->weaponModel == 0 ) { // if( weaponNum == WP_MACHINEGUN ) { //----(SA) removing old weapon references if ( weaponNum == WP_MP40 ) { weaponNum = WP_NONE; goto tryagain; } // weaponNum = WP_MACHINEGUN; //----(SA) removing old weapon references weaponNum = WP_MP40; goto tryagain; } COM_StripExtension( item->world_model[0], path, sizeof(path) ); Q_strcat( path, sizeof(path), "_flash.md3" ); pi->flashModel = trap_R_RegisterModel( path ); switch ( weaponNum ) { case WP_GAUNTLET: MAKERGB( pi->flashDlightColor, 0.6, 0.6, 1 ); break; // case WP_MACHINEGUN: // MAKERGB( pi->flashDlightColor, 1, 1, 0 ); // break; // case WP_SHOTGUN: // MAKERGB( pi->flashDlightColor, 1, 1, 0 ); // break; case WP_GRENADE_LAUNCHER: MAKERGB( pi->flashDlightColor, 1, 0.7, 0.5 ); break; case WP_ROCKET_LAUNCHER: MAKERGB( pi->flashDlightColor, 1, 0.75, 0 ); break; case WP_FLAMETHROWER: MAKERGB( pi->flashDlightColor, 0.6, 0.6, 1 ); break; // case WP_RAILGUN: // MAKERGB( pi->flashDlightColor, 1, 0.5, 0 ); // break; // case WP_BFG: // MAKERGB( pi->flashDlightColor, 1, 0.7, 1 ); // break; // case WP_GRAPPLING_HOOK: // MAKERGB( pi->flashDlightColor, 0.6, 0.6, 1 ); // break; default: MAKERGB( pi->flashDlightColor, 1, 1, 1 ); break; } }
/*QUAKED script_mover (0.5 0.25 1.0) ? TRIGGERSPAWN SOLID EXPLOSIVEDAMAGEONLY RESURECTABLE COMPASS ALLIED AXIS MOUNTED_GUN Scripted brush entity. A simplified means of moving brushes around based on events. "modelscale" - Scale multiplier (defaults to 1, and scales uniformly) "modelscale_vec" - Set scale per-axis. Overrides "modelscale", so if you have both the "modelscale" is ignored "model2" optional md3 to draw over the solid clip brush "scriptname" name used for scripting purposes (like aiName in AI scripting) "health" optionally make this entity damagable "description" used with health, if the entity is damagable, it draws a healthbar with this description above it. */ void SP_script_mover( gentity_t *ent ) { float scale[3] = {1,1,1}; vec3_t scalevec; char tagname[MAX_QPATH]; char* modelname; char* tagent; char cs[MAX_INFO_STRING]; char* s; if ( !ent->model ) { G_Error( "script_mover must have a \"model\"\n" ); } if ( !ent->scriptName ) { G_Error( "script_mover must have a \"scriptname\"\n" ); } ent->blocked = script_mover_blocked; // first position at start VectorCopy( ent->s.origin, ent->pos1 ); // VectorCopy( ent->r.currentOrigin, ent->pos1 ); VectorCopy( ent->pos1, ent->pos2 ); // don't go anywhere just yet trap_SetBrushModel( ent, ent->model ); InitMover( ent ); ent->reached = NULL; ent->s.animMovetype = 0; ent->s.density = 0; if ( ent->spawnflags & 256 ) { ent->s.density |= 2; } if ( ent->spawnflags & 8 ) { ent->use = script_mover_use; } if ( ent->spawnflags & 16 ) { ent->s.time2 = 1; } else { ent->s.time2 = 0; } if ( ent->spawnflags & 32 ) { ent->s.teamNum = TEAM_ALLIES; } else if ( ent->spawnflags & 64 ) { ent->s.teamNum = TEAM_AXIS; } else { ent->s.teamNum = TEAM_FREE; } if ( ent->spawnflags & 1 ) { ent->use = script_mover_use; trap_UnlinkEntity( ent ); // make sure it's not visible return; } G_SetAngle( ent, ent->s.angles ); G_SpawnInt( "health", "0", &ent->health ); if ( ent->health ) { ent->takedamage = true; ent->count = ent->health; // client needs to know about it as well ent->s.effect1Time = ent->count; ent->s.dl_intensity = 255; if ( G_SpawnString( "description", "", &s ) ) { trap_GetConfigstring( CS_SCRIPT_MOVER_NAMES, cs, sizeof( cs ) ); Info_SetValueForKey( cs, va( "%i",ent - g_entities ), s ); trap_SetConfigstring( CS_SCRIPT_MOVER_NAMES, cs ); } } else { ent->count = 0; } ent->die = script_mover_die; // look for general scaling if ( G_SpawnFloat( "modelscale", "1", &scale[0] ) ) { scale[2] = scale[1] = scale[0]; } if ( G_SpawnString( "model2", "", &modelname ) ) { COM_StripExtension( modelname, tagname ); Q_strcat( tagname, MAX_QPATH, ".tag" ); ent->tagNumber = trap_LoadTag( tagname ); /* if( !(ent->tagNumber = trap_LoadTag( tagname )) ) { Com_Error( ERR_DROP, "Failed to load Tag File (%s)\n", tagname ); }*/ } // look for axis specific scaling if ( G_SpawnVector( "modelscale_vec", "1 1 1", &scalevec[0] ) ) { VectorCopy( scalevec, scale ); } if ( scale[0] != 1 || scale[1] != 1 || scale[2] != 1 ) { ent->s.density |= 1; // scale is stored in 'angles2' VectorCopy( scale, ent->s.angles2 ); } if ( ent->spawnflags & 128 ) { ent->s.density |= 4; ent->waterlevel = 0; if ( G_SpawnString( "gun", "", &modelname ) ) { if ( !Q_stricmp( modelname, "browning" ) ) { ent->s.density |= 8; } } G_SpawnString( "tagent", "", &tagent ); Q_strncpyz( ent->tagBuffer, tagent, 16 ); ent->s.powerups = -1; } ent->think = script_mover_spawn; ent->nextthink = level.time + FRAMETIME; }
/* =============== UI_PlayerInfo_SetWeapon =============== */ static void UI_PlayerInfo_SetWeapon( uiPlayerInfo_t *pi, weapon_t weaponNum ) { gitem_t * item; char path[MAX_QPATH]; pi->currentWeapon = weaponNum; tryagain: pi->realWeapon = weaponNum; pi->weaponModel = 0; pi->barrelModel = 0; pi->flashModel = 0; if ( weaponNum == WP_NONE ) { return; } item = BG_FindItemForWeapon( weaponNum ); if ( item ) { pi->weaponModel = trap_R_RegisterModel( item->world_model[0] ); } if( pi->weaponModel == 0 ) { if( weaponNum == WP_MACHINEGUN ) { weaponNum = WP_NONE; goto tryagain; } weaponNum = WP_MACHINEGUN; goto tryagain; } COM_StripExtension( item->world_model[0], path, sizeof(path) ); Q_strcat( path, sizeof(path), "_barrel.md3" ); pi->barrelModel = trap_R_RegisterModel( path ); COM_StripExtension( item->world_model[0], path, sizeof(path) ); Q_strcat( path, sizeof(path), "_flash.md3" ); pi->flashModel = trap_R_RegisterModel( path ); switch( weaponNum ) { case WP_GAUNTLET: MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 ); break; case WP_MACHINEGUN: MAKERGB( pi->flashDlightColor, 1, 1, 0 ); break; case WP_SHOTGUN: MAKERGB( pi->flashDlightColor, 1, 1, 0 ); break; case WP_GRENADE_LAUNCHER: MAKERGB( pi->flashDlightColor, 1, 0.7f, 0.5f ); break; case WP_ROCKET_LAUNCHER: MAKERGB( pi->flashDlightColor, 1, 0.75f, 0 ); break; case WP_LIGHTNING: MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 ); break; case WP_RAILGUN: MAKERGB( pi->flashDlightColor, 1, 0.5f, 0 ); break; case WP_PLASMAGUN: MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 ); break; case WP_BFG: MAKERGB( pi->flashDlightColor, 1, 0.7f, 1 ); break; case WP_GRAPPLING_HOOK: MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 ); break; #ifdef MISSIONPACK case WP_NAILGUN: MAKERGB( pi->flashDlightColor, 1, 0.75f, 0 ); break; case WP_PROX_LAUNCHER: MAKERGB( pi->flashDlightColor, 1, 0.70f, 0 ); break; case WP_CHAINGUN: MAKERGB( pi->flashDlightColor, 1, 1, 0 ); break; #endif default: MAKERGB( pi->flashDlightColor, 1, 1, 1 ); break; } }
// just copied it from CG_CheckSVStringEdRef( void CL_CheckSVStringEdRef(char *buf, const char *str) { //I don't really like doing this. But it utilizes the system that was already in place. int i = 0; int b = 0; int strLen = 0; qboolean gotStrip = qfalse; if (!str || !str[0]) { if (str) { strcpy(buf, str); } return; } strcpy(buf, str); strLen = strlen(str); if (strLen >= MAX_STRINGED_SV_STRING) { return; } while (i < strLen && str[i]) { gotStrip = qfalse; if (str[i] == '@' && (i+1) < strLen) { if (str[i+1] == '@' && (i+2) < strLen) { if (str[i+2] == '@' && (i+3) < strLen) { //@@@ should mean to insert a StringEd reference here, so insert it into buf at the current place char stringRef[MAX_STRINGED_SV_STRING]; int r = 0; while (i < strLen && str[i] == '@') { i++; } while (i < strLen && str[i] && str[i] != ' ' && str[i] != ':' && str[i] != '.' && str[i] != '\n') { stringRef[r] = str[i]; r++; i++; } stringRef[r] = 0; buf[b] = 0; Q_strcat(buf, MAX_STRINGED_SV_STRING, SE_GetString("MP_SVGAME", stringRef)); b = strlen(buf); } } } if (!gotStrip) { buf[b] = str[i]; b++; } i++; } buf[b] = 0; }
/* =============== G_ParseMapCommandSection Parse a map rotation command section =============== */ static qboolean G_ParseMapCommandSection( node_t *node, char **text_p ) { char *token; map_t *map = &node->u.map; int commandLength = 0; // read optional parameters while ( 1 ) { token = COM_Parse( text_p ); if ( !*token ) { break; } if ( !Q_stricmp( token, "" ) ) { return qfalse; } if ( !Q_stricmp( token, "}" ) ) { if ( commandLength > 0 ) { // Replace last ; with \n map->postCommand[ commandLength - 1 ] = '\n'; } return qtrue; //reached the end of this command section } if ( !Q_stricmp( token, "layouts" ) ) { token = COM_ParseExt( text_p, qfalse ); map->layouts[ 0 ] = '\0'; while ( token[ 0 ] != 0 ) { Q_strcat( map->layouts, sizeof( map->layouts ), token ); Q_strcat( map->layouts, sizeof( map->layouts ), " " ); token = COM_ParseExt( text_p, qfalse ); } continue; } // Parse the rest of the line into map->postCommand Q_strcat( map->postCommand, sizeof( map->postCommand ), token ); Q_strcat( map->postCommand, sizeof( map->postCommand ), " " ); token = COM_ParseExt( text_p, qfalse ); while ( token[ 0 ] != 0 ) { Q_strcat( map->postCommand, sizeof( map->postCommand ), token ); Q_strcat( map->postCommand, sizeof( map->postCommand ), " " ); token = COM_ParseExt( text_p, qfalse ); } commandLength = strlen( map->postCommand ); map->postCommand[ commandLength - 1 ] = ';'; } return qfalse; }
void GLSL_InitGPUShaders(void) { int startTime, endTime; int i; char extradefines[1024]; int attribs; int numGenShaders = 0, numLightShaders = 0, numEtcShaders = 0; ri.Printf(PRINT_ALL, "------- GLSL_InitGPUShaders -------\n"); R_IssuePendingRenderCommands(); startTime = ri.Milliseconds(); for (i = 0; i < GENERICDEF_COUNT; i++) { attribs = ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | ATTR_NORMAL | ATTR_COLOR; extradefines[0] = '\0'; if (i & GENERICDEF_USE_DEFORM_VERTEXES) Q_strcat(extradefines, 1024, "#define USE_DEFORM_VERTEXES\n"); if (i & GENERICDEF_USE_TCGEN_AND_TCMOD) { Q_strcat(extradefines, 1024, "#define USE_TCGEN\n"); Q_strcat(extradefines, 1024, "#define USE_TCMOD\n"); } if (i & GENERICDEF_USE_VERTEX_ANIMATION) { Q_strcat(extradefines, 1024, "#define USE_VERTEX_ANIMATION\n"); attribs |= ATTR_POSITION2 | ATTR_NORMAL2; } if (i & GENERICDEF_USE_FOG) Q_strcat(extradefines, 1024, "#define USE_FOG\n"); if (i & GENERICDEF_USE_RGBAGEN) Q_strcat(extradefines, 1024, "#define USE_RGBAGEN\n"); if (!GLSL_InitGPUShader(&tr.genericShader[i], "generic", attribs, qtrue, extradefines, qtrue, fallbackShader_generic_vp, fallbackShader_generic_fp)) { ri.Error(ERR_FATAL, "Could not load generic shader!"); } GLSL_InitUniforms(&tr.genericShader[i]); GLSL_SetUniformInt(&tr.genericShader[i], UNIFORM_DIFFUSEMAP, TB_DIFFUSEMAP); GLSL_SetUniformInt(&tr.genericShader[i], UNIFORM_LIGHTMAP, TB_LIGHTMAP); GLSL_FinishGPUShader(&tr.genericShader[i]); numGenShaders++; } attribs = ATTR_POSITION | ATTR_TEXCOORD; if (!GLSL_InitGPUShader(&tr.textureColorShader, "texturecolor", attribs, qtrue, NULL, qfalse, fallbackShader_texturecolor_vp, fallbackShader_texturecolor_fp)) { ri.Error(ERR_FATAL, "Could not load texturecolor shader!"); } GLSL_InitUniforms(&tr.textureColorShader); GLSL_SetUniformInt(&tr.textureColorShader, UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP); GLSL_FinishGPUShader(&tr.textureColorShader); numEtcShaders++; for (i = 0; i < FOGDEF_COUNT; i++) { attribs = ATTR_POSITION | ATTR_POSITION2 | ATTR_NORMAL | ATTR_NORMAL2 | ATTR_TEXCOORD; extradefines[0] = '\0'; if (i & FOGDEF_USE_DEFORM_VERTEXES) Q_strcat(extradefines, 1024, "#define USE_DEFORM_VERTEXES\n"); if (i & FOGDEF_USE_VERTEX_ANIMATION) Q_strcat(extradefines, 1024, "#define USE_VERTEX_ANIMATION\n"); if (!GLSL_InitGPUShader(&tr.fogShader[i], "fogpass", attribs, qtrue, extradefines, qtrue, fallbackShader_fogpass_vp, fallbackShader_fogpass_fp)) { ri.Error(ERR_FATAL, "Could not load fogpass shader!"); } GLSL_InitUniforms(&tr.fogShader[i]); GLSL_FinishGPUShader(&tr.fogShader[i]); numEtcShaders++; } for (i = 0; i < DLIGHTDEF_COUNT; i++) { attribs = ATTR_POSITION | ATTR_NORMAL | ATTR_TEXCOORD; extradefines[0] = '\0'; if (i & DLIGHTDEF_USE_DEFORM_VERTEXES) { Q_strcat(extradefines, 1024, "#define USE_DEFORM_VERTEXES\n"); } if (!GLSL_InitGPUShader(&tr.dlightShader[i], "dlight", attribs, qtrue, extradefines, qtrue, fallbackShader_dlight_vp, fallbackShader_dlight_fp)) { ri.Error(ERR_FATAL, "Could not load dlight shader!"); } GLSL_InitUniforms(&tr.dlightShader[i]); GLSL_SetUniformInt(&tr.dlightShader[i], UNIFORM_DIFFUSEMAP, TB_DIFFUSEMAP); GLSL_FinishGPUShader(&tr.dlightShader[i]); numEtcShaders++; } for (i = 0; i < LIGHTDEF_COUNT; i++) { int lightType = i & LIGHTDEF_LIGHTTYPE_MASK; qboolean fastLight = !(r_normalMapping->integer || r_specularMapping->integer); // skip impossible combos if ((i & LIGHTDEF_USE_PARALLAXMAP) && !r_parallaxMapping->integer) continue; if (!lightType && (i & LIGHTDEF_USE_PARALLAXMAP)) continue; if (!lightType && (i & LIGHTDEF_USE_SHADOWMAP)) continue; attribs = ATTR_POSITION | ATTR_TEXCOORD | ATTR_COLOR | ATTR_NORMAL; extradefines[0] = '\0'; if (r_specularIsMetallic->value) Q_strcat(extradefines, 1024, "#define SPECULAR_IS_METALLIC\n"); if (r_glossIsRoughness->value) Q_strcat(extradefines, 1024, "#define GLOSS_IS_ROUGHNESS\n"); if (r_dlightMode->integer >= 2) Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n"); if (glRefConfig.swizzleNormalmap) Q_strcat(extradefines, 1024, "#define SWIZZLE_NORMALMAP\n"); if (r_hdr->integer && !glRefConfig.floatLightmap) Q_strcat(extradefines, 1024, "#define RGBM_LIGHTMAP\n"); if (lightType) { Q_strcat(extradefines, 1024, "#define USE_LIGHT\n"); if (fastLight) Q_strcat(extradefines, 1024, "#define USE_FAST_LIGHT\n"); switch (lightType) { case LIGHTDEF_USE_LIGHTMAP: Q_strcat(extradefines, 1024, "#define USE_LIGHTMAP\n"); if (r_deluxeMapping->integer && !fastLight) Q_strcat(extradefines, 1024, "#define USE_DELUXEMAP\n"); attribs |= ATTR_LIGHTCOORD | ATTR_LIGHTDIRECTION; break; case LIGHTDEF_USE_LIGHT_VECTOR: Q_strcat(extradefines, 1024, "#define USE_LIGHT_VECTOR\n"); break; case LIGHTDEF_USE_LIGHT_VERTEX: Q_strcat(extradefines, 1024, "#define USE_LIGHT_VERTEX\n"); attribs |= ATTR_LIGHTDIRECTION; break; default: break; } if (r_normalMapping->integer) { Q_strcat(extradefines, 1024, "#define USE_NORMALMAP\n"); #ifdef USE_VERT_TANGENT_SPACE Q_strcat(extradefines, 1024, "#define USE_VERT_TANGENT_SPACE\n"); attribs |= ATTR_TANGENT; #endif if ((i & LIGHTDEF_USE_PARALLAXMAP) && !(i & LIGHTDEF_ENTITY) && r_parallaxMapping->integer) { Q_strcat(extradefines, 1024, "#define USE_PARALLAXMAP\n"); if (r_parallaxMapping->integer > 1) Q_strcat(extradefines, 1024, "#define USE_RELIEFMAP\n"); } } if (r_specularMapping->integer) Q_strcat(extradefines, 1024, "#define USE_SPECULARMAP\n"); if (r_cubeMapping->integer) Q_strcat(extradefines, 1024, "#define USE_CUBEMAP\n"); } if (i & LIGHTDEF_USE_SHADOWMAP) { Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n"); if (r_sunlightMode->integer == 1) Q_strcat(extradefines, 1024, "#define SHADOWMAP_MODULATE\n"); else if (r_sunlightMode->integer == 2) Q_strcat(extradefines, 1024, "#define USE_PRIMARY_LIGHT\n"); } if (i & LIGHTDEF_USE_TCGEN_AND_TCMOD) { Q_strcat(extradefines, 1024, "#define USE_TCGEN\n"); Q_strcat(extradefines, 1024, "#define USE_TCMOD\n"); } if (i & LIGHTDEF_ENTITY) { Q_strcat(extradefines, 1024, "#define USE_VERTEX_ANIMATION\n#define USE_MODELMATRIX\n"); attribs |= ATTR_POSITION2 | ATTR_NORMAL2; #ifdef USE_VERT_TANGENT_SPACE if (r_normalMapping->integer) { attribs |= ATTR_TANGENT2; } #endif } if (!GLSL_InitGPUShader(&tr.lightallShader[i], "lightall", attribs, qtrue, extradefines, qtrue, fallbackShader_lightall_vp, fallbackShader_lightall_fp)) { ri.Error(ERR_FATAL, "Could not load lightall shader!"); } GLSL_InitUniforms(&tr.lightallShader[i]); GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_DIFFUSEMAP, TB_DIFFUSEMAP); GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_LIGHTMAP, TB_LIGHTMAP); GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_NORMALMAP, TB_NORMALMAP); GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_DELUXEMAP, TB_DELUXEMAP); GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_SPECULARMAP, TB_SPECULARMAP); GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_SHADOWMAP, TB_SHADOWMAP); GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_CUBEMAP, TB_CUBEMAP); GLSL_FinishGPUShader(&tr.lightallShader[i]); numLightShaders++; } attribs = ATTR_POSITION | ATTR_POSITION2 | ATTR_NORMAL | ATTR_NORMAL2 | ATTR_TEXCOORD; extradefines[0] = '\0'; if (!GLSL_InitGPUShader(&tr.shadowmapShader, "shadowfill", attribs, qtrue, extradefines, qtrue, fallbackShader_shadowfill_vp, fallbackShader_shadowfill_fp)) { ri.Error(ERR_FATAL, "Could not load shadowfill shader!"); } GLSL_InitUniforms(&tr.shadowmapShader); GLSL_FinishGPUShader(&tr.shadowmapShader); numEtcShaders++; attribs = ATTR_POSITION | ATTR_NORMAL; extradefines[0] = '\0'; Q_strcat(extradefines, 1024, "#define USE_PCF\n#define USE_DISCARD\n"); if (!GLSL_InitGPUShader(&tr.pshadowShader, "pshadow", attribs, qtrue, extradefines, qtrue, fallbackShader_pshadow_vp, fallbackShader_pshadow_fp)) { ri.Error(ERR_FATAL, "Could not load pshadow shader!"); } GLSL_InitUniforms(&tr.pshadowShader); GLSL_SetUniformInt(&tr.pshadowShader, UNIFORM_SHADOWMAP, TB_DIFFUSEMAP); GLSL_FinishGPUShader(&tr.pshadowShader); numEtcShaders++; attribs = ATTR_POSITION | ATTR_TEXCOORD; extradefines[0] = '\0'; if (!GLSL_InitGPUShader(&tr.down4xShader, "down4x", attribs, qtrue, extradefines, qtrue, fallbackShader_down4x_vp, fallbackShader_down4x_fp)) { ri.Error(ERR_FATAL, "Could not load down4x shader!"); } GLSL_InitUniforms(&tr.down4xShader); GLSL_SetUniformInt(&tr.down4xShader, UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP); GLSL_FinishGPUShader(&tr.down4xShader); numEtcShaders++; attribs = ATTR_POSITION | ATTR_TEXCOORD; extradefines[0] = '\0'; if (!GLSL_InitGPUShader(&tr.bokehShader, "bokeh", attribs, qtrue, extradefines, qtrue, fallbackShader_bokeh_vp, fallbackShader_bokeh_fp)) { ri.Error(ERR_FATAL, "Could not load bokeh shader!"); } GLSL_InitUniforms(&tr.bokehShader); GLSL_SetUniformInt(&tr.bokehShader, UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP); GLSL_FinishGPUShader(&tr.bokehShader); numEtcShaders++; attribs = ATTR_POSITION | ATTR_TEXCOORD; extradefines[0] = '\0'; if (!GLSL_InitGPUShader(&tr.tonemapShader, "tonemap", attribs, qtrue, extradefines, qtrue, fallbackShader_tonemap_vp, fallbackShader_tonemap_fp)) { ri.Error(ERR_FATAL, "Could not load tonemap shader!"); } GLSL_InitUniforms(&tr.tonemapShader); GLSL_SetUniformInt(&tr.tonemapShader, UNIFORM_TEXTUREMAP, TB_COLORMAP); GLSL_SetUniformInt(&tr.tonemapShader, UNIFORM_LEVELSMAP, TB_LEVELSMAP); GLSL_FinishGPUShader(&tr.tonemapShader); numEtcShaders++; for (i = 0; i < 2; i++) { attribs = ATTR_POSITION | ATTR_TEXCOORD; extradefines[0] = '\0'; if (!i) Q_strcat(extradefines, 1024, "#define FIRST_PASS\n"); if (!GLSL_InitGPUShader(&tr.calclevels4xShader[i], "calclevels4x", attribs, qtrue, extradefines, qtrue, fallbackShader_calclevels4x_vp, fallbackShader_calclevels4x_fp)) { ri.Error(ERR_FATAL, "Could not load calclevels4x shader!"); } GLSL_InitUniforms(&tr.calclevels4xShader[i]); GLSL_SetUniformInt(&tr.calclevels4xShader[i], UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP); GLSL_FinishGPUShader(&tr.calclevels4xShader[i]); numEtcShaders++; } attribs = ATTR_POSITION | ATTR_TEXCOORD; extradefines[0] = '\0'; if (r_shadowFilter->integer >= 1) Q_strcat(extradefines, 1024, "#define USE_SHADOW_FILTER\n"); if (r_shadowFilter->integer >= 2) Q_strcat(extradefines, 1024, "#define USE_SHADOW_FILTER2\n"); if (r_shadowCascadeZFar->integer != 0) Q_strcat(extradefines, 1024, "#define USE_SHADOW_CASCADE\n"); Q_strcat(extradefines, 1024, va("#define r_shadowMapSize %f\n", r_shadowMapSize->value)); Q_strcat(extradefines, 1024, va("#define r_shadowCascadeZFar %f\n", r_shadowCascadeZFar->value)); if (!GLSL_InitGPUShader(&tr.shadowmaskShader, "shadowmask", attribs, qtrue, extradefines, qtrue, fallbackShader_shadowmask_vp, fallbackShader_shadowmask_fp)) { ri.Error(ERR_FATAL, "Could not load shadowmask shader!"); } GLSL_InitUniforms(&tr.shadowmaskShader); GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SCREENDEPTHMAP, TB_COLORMAP); GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP, TB_SHADOWMAP); GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP2, TB_SHADOWMAP2); GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP3, TB_SHADOWMAP3); GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP4, TB_SHADOWMAP4); GLSL_FinishGPUShader(&tr.shadowmaskShader); numEtcShaders++; attribs = ATTR_POSITION | ATTR_TEXCOORD; extradefines[0] = '\0'; if (!GLSL_InitGPUShader(&tr.ssaoShader, "ssao", attribs, qtrue, extradefines, qtrue, fallbackShader_ssao_vp, fallbackShader_ssao_fp)) { ri.Error(ERR_FATAL, "Could not load ssao shader!"); } GLSL_InitUniforms(&tr.ssaoShader); GLSL_SetUniformInt(&tr.ssaoShader, UNIFORM_SCREENDEPTHMAP, TB_COLORMAP); GLSL_FinishGPUShader(&tr.ssaoShader); numEtcShaders++; for (i = 0; i < 2; i++) { attribs = ATTR_POSITION | ATTR_TEXCOORD; extradefines[0] = '\0'; if (i & 1) Q_strcat(extradefines, 1024, "#define USE_VERTICAL_BLUR\n"); else Q_strcat(extradefines, 1024, "#define USE_HORIZONTAL_BLUR\n"); if (!GLSL_InitGPUShader(&tr.depthBlurShader[i], "depthBlur", attribs, qtrue, extradefines, qtrue, fallbackShader_depthblur_vp, fallbackShader_depthblur_fp)) { ri.Error(ERR_FATAL, "Could not load depthBlur shader!"); } GLSL_InitUniforms(&tr.depthBlurShader[i]); GLSL_SetUniformInt(&tr.depthBlurShader[i], UNIFORM_SCREENIMAGEMAP, TB_COLORMAP); GLSL_SetUniformInt(&tr.depthBlurShader[i], UNIFORM_SCREENDEPTHMAP, TB_LIGHTMAP); GLSL_FinishGPUShader(&tr.depthBlurShader[i]); numEtcShaders++; } #if 0 attribs = ATTR_POSITION | ATTR_TEXCOORD; extradefines[0] = '\0'; if (!GLSL_InitGPUShader(&tr.testcubeShader, "testcube", attribs, qtrue, extradefines, qtrue, NULL, NULL)) { ri.Error(ERR_FATAL, "Could not load testcube shader!"); } GLSL_InitUniforms(&tr.testcubeShader); GLSL_SetUniformInt(&tr.testcubeShader, UNIFORM_TEXTUREMAP, TB_COLORMAP); GLSL_FinishGPUShader(&tr.testcubeShader); numEtcShaders++; #endif endTime = ri.Milliseconds(); ri.Printf(PRINT_ALL, "loaded %i GLSL shaders (%i gen %i light %i etc) in %5.2f seconds\n", numGenShaders + numLightShaders + numEtcShaders, numGenShaders, numLightShaders, numEtcShaders, (endTime - startTime) / 1000.0); }
/** * @brief Base Summary menu init function. * @note Should be called whenever the Base Summary menu gets active. */ static void BaseSummary_Init (const base_t *base) { static char textStatsBuffer[1024]; static char textInfoBuffer[256]; const aliensCont_t *containment = base->alienscont; int i; baseCapacities_t cap; const production_queue_t *queue; const technology_t *tech; int tmp; /* wipe away old buffers */ textStatsBuffer[0] = textInfoBuffer[0] = 0; Q_strcat(textInfoBuffer, _("^BAircraft\n"), sizeof(textInfoBuffer)); for (i = 0; i <= MAX_HUMAN_AIRCRAFT_TYPE; i++) { const aircraftType_t airType = (aircraftType_t)i; const int count = AIR_CountTypeInBase(base, airType); if (count == 0) continue; Q_strcat(textInfoBuffer, va("\t%s:\t\t\t\t%i\n", AIR_GetAircraftString(airType), count), sizeof(textInfoBuffer)); } Q_strcat(textInfoBuffer, "\n", sizeof(textInfoBuffer)); Q_strcat(textInfoBuffer, _("^BEmployees\n"), sizeof(textInfoBuffer)); for (i = 0; i < MAX_EMPL; i++) { const employeeType_t emplType = (employeeType_t)i; tmp = E_CountHired(base, emplType); if (tmp == 0) continue; Q_strcat(textInfoBuffer, va("\t%s:\t\t\t\t%i\n", E_GetEmployeeString(emplType, tmp), tmp), sizeof(textInfoBuffer)); } Q_strcat(textInfoBuffer, "\n", sizeof(textInfoBuffer)); Q_strcat(textInfoBuffer, _("^BAliens\n"), sizeof(textInfoBuffer)); for (i = 0; i < ccs.numAliensTD; i++) { if (!containment[i].amountAlive && !containment[i].amountDead) continue; Q_strcat(textInfoBuffer, va("\t%s:\t\t\t\t%i/%i\n", _(containment[i].teamDef->name), containment[i].amountAlive, containment[i].amountDead), sizeof(textInfoBuffer)); } /* link into the menu */ cgi->UI_RegisterText(TEXT_STANDARD, textInfoBuffer); Q_strcat(textStatsBuffer, _("^BBuildings\t\t\t\t\t\tCapacity\t\t\t\tAmount\n"), sizeof(textStatsBuffer)); for (i = 0; i < ccs.numBuildingTemplates; i++) { const building_t* b = &ccs.buildingTemplates[i]; /* only show already researched buildings */ if (!RS_IsResearched_ptr(b->tech)) continue; cap = B_GetCapacityFromBuildingType(b->buildingType); if (cap == MAX_CAP) continue; if (!B_GetNumberOfBuildingsInBaseByBuildingType(base, b->buildingType)) continue; /* Check if building is functional (see comments in B_UpdateBaseCapacities) */ if (B_GetBuildingStatus(base, b->buildingType)) { Q_strcat(textStatsBuffer, va("%s:\t\t\t\t\t\t%i/%i", _(b->name), CAP_GetCurrent(base, cap), CAP_GetMax(base, cap)), sizeof(textStatsBuffer)); } else { if (b->buildingStatus == B_STATUS_UNDER_CONSTRUCTION) { const float remaining = B_GetConstructionTimeRemain(b); const float timeLeft = std::max(0.0f, remaining); Q_strcat(textStatsBuffer, va("%s:\t\t\t\t\t\t%3.1f %s", _(b->name), timeLeft, ngettext("day", "days", timeLeft)), sizeof(textStatsBuffer)); } else { Q_strcat(textStatsBuffer, va("%s:\t\t\t\t\t\t%i/%i", _(b->name), CAP_GetCurrent(base, cap), 0), sizeof(textStatsBuffer)); } } Q_strcat(textStatsBuffer, va("\t\t\t\t%i\n", B_GetNumberOfBuildingsInBaseByBuildingType(base, b->buildingType)), sizeof(textStatsBuffer)); } Q_strcat(textStatsBuffer, "\n", sizeof(textStatsBuffer)); Q_strcat(textStatsBuffer, _("^BProduction\t\t\t\t\t\tQuantity\t\t\t\tPercent\n"), sizeof(textStatsBuffer)); queue = PR_GetProductionForBase(base); if (queue->numItems > 0) { for (i = 0; i < queue->numItems; i++) { const production_t *production = &queue->items[i]; const char *name = PR_GetName(&production->data); /** @todo use the same method as we do in PR_ProductionInfo */ Q_strcat(textStatsBuffer, va(_("%s\t\t\t\t\t\t%d\t\t\t\t%.2f%%\n"), name, production->amount, PR_GetProgress(production) * 100), sizeof(textStatsBuffer)); } } else { Q_strcat(textStatsBuffer, _("Nothing\n"), sizeof(textStatsBuffer)); } Q_strcat(textStatsBuffer, "\n", sizeof(textStatsBuffer)); Q_strcat(textStatsBuffer, _("^BResearch\t\t\t\t\t\tScientists\t\t\t\tPercent\n"), sizeof(textStatsBuffer)); tmp = 0; for (i = 0; i < ccs.numTechnologies; i++) { tech = RS_GetTechByIDX(i); if (tech->base == base && (tech->statusResearch == RS_RUNNING || tech->statusResearch == RS_PAUSED)) { Q_strcat(textStatsBuffer, va(_("%s\t\t\t\t\t\t%d\t\t\t\t%1.2f%%\n"), _(tech->name), tech->scientists, (1 - tech->time / tech->overallTime) * 100), sizeof(textStatsBuffer)); tmp++; } } if (!tmp) Q_strcat(textStatsBuffer, _("Nothing\n"), sizeof(textStatsBuffer)); /* link into the menu */ cgi->UI_RegisterText(TEXT_STATS_BASESUMMARY, textStatsBuffer); }