/* ==================== CM_CreateShaderTextHash ===================== */ void CM_CreateShaderTextHash(void) { const char *p; qboolean hasNewLines; char *token; CCMShaderText *shader; p = shaderText; // look for label while (p) { p = SkipWhitespace(p, &hasNewLines); token = COM_ParseExt( &p, qtrue ); if ( !token[0] ) { break; } shader = new CCMShaderText(token, p); shaderTextTable.insert(shader); SkipBracedSection(&p); } }
void NPC_PrecacheAnimationCFG( const char *NPC_type ) { char filename[MAX_QPATH]; const char *token; const char *value; const char *p; int junk; if ( !Q_stricmp( "random", NPC_type ) ) {//sorry, can't precache a random just yet return; } p = NPCParms; COM_BeginParseSession(); // look for the right NPC while ( p ) { token = COM_ParseExt( &p, qtrue ); if ( token[0] == 0 ) { return; } if ( !Q_stricmp( token, NPC_type ) ) { break; } SkipBracedSection( &p ); } if ( !p ) { return; } if ( G_ParseLiteral( &p, "{" ) ) { return; } // parse the NPC info block while ( 1 ) { token = COM_ParseExt( &p, qtrue ); if ( !token[0] ) { gi.Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s'\n", NPC_type ); return; } if ( !Q_stricmp( token, "}" ) ) { break; } // legsmodel if ( !Q_stricmp( token, "legsmodel" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } //must copy data out of this pointer into a different part of memory because the funcs we're about to call will call COM_ParseExt Q_strncpyz( filename, value, sizeof( filename ), qtrue ); G_ParseAnimFileSet( filename, filename, &junk ); return; } // playerModel if ( !Q_stricmp( token, "playerModel" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } char animName[MAX_QPATH]; char *GLAName; char *slash = NULL; char *strippedName; int handle = gi.G2API_PrecacheGhoul2Model( va( "models/players/%s/model.glm", value ) ); if ( handle > 0 )//FIXME: isn't 0 a valid handle? { GLAName = gi.G2API_GetAnimFileNameIndex( handle ); if ( GLAName ) { Q_strncpyz( animName, GLAName, sizeof( animName ), qtrue ); slash = strrchr( animName, '/' ); if ( slash ) { *slash = 0; } strippedName = COM_SkipPath( animName ); //must copy data out of this pointer into a different part of memory because the funcs we're about to call will call COM_ParseExt Q_strncpyz( filename, value, sizeof( filename ), qtrue ); G_ParseAnimFileSet( value, strippedName, &junk );//qfalse ); //FIXME: still not precaching the animsounds.cfg? return; } } } } }
qboolean NPC_ParseParms( const char *NPCName, gentity_t *NPC ) { const char *token; const char *value; const char *p; int n; float f; char *patch; char sound[MAX_QPATH]; char playerModel[MAX_QPATH]; char customSkin[MAX_QPATH]; clientInfo_t *ci = &NPC->client->clientInfo; renderInfo_t *ri = &NPC->client->renderInfo; gNPCstats_t *stats = NULL; qboolean md3Model = qtrue; char surfOff[1024]; char surfOn[1024]; strcpy(customSkin,"default"); if ( !NPCName || !NPCName[0]) { NPCName = "Player"; } if ( NPC->NPC ) { stats = &NPC->NPC->stats; /* NPC->NPC->allWeaponOrder[0] = WP_BRYAR_PISTOL; NPC->NPC->allWeaponOrder[1] = WP_SABER; NPC->NPC->allWeaponOrder[2] = WP_IMOD; NPC->NPC->allWeaponOrder[3] = WP_SCAVENGER_RIFLE; NPC->NPC->allWeaponOrder[4] = WP_TRICORDER; NPC->NPC->allWeaponOrder[6] = WP_NONE; NPC->NPC->allWeaponOrder[6] = WP_NONE; NPC->NPC->allWeaponOrder[7] = WP_NONE; */ // fill in defaults stats->aggression = 3; stats->aim = 3; stats->earshot = 1024; stats->evasion = 3; stats->hfov = 90; stats->intelligence = 3; stats->move = 3; stats->reactions = 3; stats->vfov = 60; stats->vigilance = 0.1f; stats->visrange = 1024; stats->health = 0; stats->moveType = MT_RUNJUMP; stats->yawSpeed = 90; stats->walkSpeed = 90; stats->runSpeed = 300; stats->acceleration = 15;//Increase/descrease speed this much per frame (20fps) } else { stats = NULL; } Q_strncpyz( ci->name, NPCName, sizeof( ci->name ) ); NPC->playerModel = -1; //Set defaults //FIXME: should probably put default torso and head models, but what about enemies //that don't have any- like Stasis? //Q_strncpyz( ri->headModelName, DEFAULT_HEADMODEL, sizeof(ri->headModelName), qtrue); //Q_strncpyz( ri->torsoModelName, DEFAULT_TORSOMODEL, sizeof(ri->torsoModelName), qtrue); //Q_strncpyz( ri->legsModelName, DEFAULT_LEGSMODEL, sizeof(ri->legsModelName), qtrue); memset( ri->headModelName, 0, sizeof( ri->headModelName ) ); memset( ri->torsoModelName, 0, sizeof( ri->torsoModelName ) ); memset( ri->legsModelName, 0, sizeof( ri->legsModelName ) ); //FIXME: should we have one for weapon too? memset( (char *)surfOff, 0, sizeof(surfOff) ); memset( (char *)surfOn, 0, sizeof(surfOn) ); /* ri->headYawRangeLeft = 50; ri->headYawRangeRight = 50; ri->headPitchRangeUp = 40; ri->headPitchRangeDown = 50; ri->torsoYawRangeLeft = 60; ri->torsoYawRangeRight = 60; ri->torsoPitchRangeUp = 30; ri->torsoPitchRangeDown = 70; */ ri->headYawRangeLeft = 80; ri->headYawRangeRight = 80; ri->headPitchRangeUp = 45; ri->headPitchRangeDown = 45; ri->torsoYawRangeLeft = 60; ri->torsoYawRangeRight = 60; ri->torsoPitchRangeUp = 30; ri->torsoPitchRangeDown = 50; VectorCopy(playerMins, NPC->mins); VectorCopy(playerMaxs, NPC->maxs); NPC->client->crouchheight = CROUCH_MAXS_2; NPC->client->standheight = DEFAULT_MAXS_2; NPC->client->dismemberProbHead = 100; NPC->client->dismemberProbArms = 100; NPC->client->dismemberProbHands = 100; NPC->client->dismemberProbWaist = 100; NPC->client->dismemberProbLegs = 100; if ( !Q_stricmp( "random", NPCName ) ) {//Randomly assemble a starfleet guy NPC_BuildRandom( NPC ); } else { p = NPCParms; COM_BeginParseSession(); // look for the right NPC while ( p ) { token = COM_ParseExt( &p, qtrue ); if ( token[0] == 0 ) { return qfalse; } if ( !Q_stricmp( token, NPCName ) ) { break; } SkipBracedSection( &p ); } if ( !p ) { return qfalse; } if ( G_ParseLiteral( &p, "{" ) ) { return qfalse; } // parse the NPC info block while ( 1 ) { token = COM_ParseExt( &p, qtrue ); if ( !token[0] ) { gi.Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s'\n", NPCName ); return qfalse; } if ( !Q_stricmp( token, "}" ) ) { break; } //===MODEL PROPERTIES=========================================================== // headmodel if ( !Q_stricmp( token, "headmodel" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } if(!Q_stricmp("none", value)) { ri->headModelName[0] = NULL; //Zero the head clamp range so the torso & legs don't lag behind ri->headYawRangeLeft = ri->headYawRangeRight = ri->headPitchRangeUp = ri->headPitchRangeDown = 0; } else { Q_strncpyz( ri->headModelName, value, sizeof(ri->headModelName), qtrue); } continue; } // torsomodel if ( !Q_stricmp( token, "torsomodel" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } if(!Q_stricmp("none", value)) { ri->torsoModelName[0] = NULL; //Zero the torso clamp range so the legs don't lag behind ri->torsoYawRangeLeft = ri->torsoYawRangeRight = ri->torsoPitchRangeUp = ri->torsoPitchRangeDown = 0; } else { Q_strncpyz( ri->torsoModelName, value, sizeof(ri->torsoModelName), qtrue); } continue; } // legsmodel if ( !Q_stricmp( token, "legsmodel" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } Q_strncpyz( ri->legsModelName, value, sizeof(ri->legsModelName), qtrue); //Need to do this here to get the right index G_ParseAnimFileSet( ri->legsModelName, ri->legsModelName, &ci->animFileIndex ); continue; } // playerModel if ( !Q_stricmp( token, "playerModel" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } Q_strncpyz( playerModel, value, sizeof(playerModel), qtrue); md3Model = qfalse; continue; } // customSkin if ( !Q_stricmp( token, "customSkin" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } Q_strncpyz( customSkin, value, sizeof(customSkin), qtrue); continue; } // surfOff if ( !Q_stricmp( token, "surfOff" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } if ( surfOff[0] ) { strncat( (char *)surfOff, ",", sizeof(surfOff) ); strncat( (char *)surfOff, value, sizeof(surfOff) ); } else { Q_strncpyz( surfOff, value, sizeof(surfOff), qtrue); } continue; } // surfOn if ( !Q_stricmp( token, "surfOn" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } if ( surfOn[0] ) { strncat( (char *)surfOn, ",", sizeof(surfOn) ); strncat( (char *)surfOn, value, sizeof(surfOn) ); } else { Q_strncpyz( surfOn, value, sizeof(surfOn), qtrue); } continue; } //headYawRangeLeft if ( !Q_stricmp( token, "headYawRangeLeft" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 0 ) { gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName ); continue; } ri->headYawRangeLeft = n; continue; } //headYawRangeRight if ( !Q_stricmp( token, "headYawRangeRight" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 0 ) { gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName ); continue; } ri->headYawRangeRight = n; continue; } //headPitchRangeUp if ( !Q_stricmp( token, "headPitchRangeUp" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 0 ) { gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName ); continue; } ri->headPitchRangeUp = n; continue; } //headPitchRangeDown if ( !Q_stricmp( token, "headPitchRangeDown" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 0 ) { gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName ); continue; } ri->headPitchRangeDown = n; continue; } //torsoYawRangeLeft if ( !Q_stricmp( token, "torsoYawRangeLeft" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 0 ) { gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName ); continue; } ri->torsoYawRangeLeft = n; continue; } //torsoYawRangeRight if ( !Q_stricmp( token, "torsoYawRangeRight" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 0 ) { gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName ); continue; } ri->torsoYawRangeRight = n; continue; } //torsoPitchRangeUp if ( !Q_stricmp( token, "torsoPitchRangeUp" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 0 ) { gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName ); continue; } ri->torsoPitchRangeUp = n; continue; } //torsoPitchRangeDown if ( !Q_stricmp( token, "torsoPitchRangeDown" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 0 ) { gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName ); continue; } ri->torsoPitchRangeDown = n; continue; } // Uniform XYZ scale if ( !Q_stricmp( token, "scale" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 0 ) { gi.Printf( "bad %s in NPC '%s'\n", token, NPCName ); continue; } if (n != 100) { NPC->s.modelScale[0] = NPC->s.modelScale[1] = NPC->s.modelScale[2] = n/100.0f; } continue; } //X scale if ( !Q_stricmp( token, "scaleX" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 0 ) { gi.Printf( "bad %s in NPC '%s'\n", token, NPCName ); continue; } if (n != 100) { NPC->s.modelScale[0] = n/100.0f; } continue; } //Y scale if ( !Q_stricmp( token, "scaleY" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 0 ) { gi.Printf( "bad %s in NPC '%s'\n", token, NPCName ); continue; } if (n != 100) { NPC->s.modelScale[1] = n/100.0f; } continue; } //Z scale if ( !Q_stricmp( token, "scaleZ" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 0 ) { gi.Printf( "bad %s in NPC '%s'\n", token, NPCName ); continue; } if (n != 100) { NPC->s.modelScale[2] = n/100.0f; } continue; } //===AI STATS===================================================================== // aggression if ( !Q_stricmp( token, "aggression" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 1 || n > 5 ) { gi.Printf( "bad %s in NPC '%s'\n", token, NPCName ); continue; } if ( NPC->NPC ) { stats->aggression = n; } continue; } // aim if ( !Q_stricmp( token, "aim" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 1 || n > 5 ) { gi.Printf( "bad %s in NPC '%s'\n", token, NPCName ); continue; } if ( NPC->NPC ) { stats->aim = n; } continue; } // earshot if ( !Q_stricmp( token, "earshot" ) ) { if ( COM_ParseFloat( &p, &f ) ) { SkipRestOfLine( &p ); continue; } if ( f < 0.0f ) { gi.Printf( "bad %s in NPC '%s'\n", token, NPCName ); continue; } if ( NPC->NPC ) { stats->earshot = f; } continue; } // evasion if ( !Q_stricmp( token, "evasion" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 1 || n > 5 ) { gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName ); continue; } if ( NPC->NPC ) { stats->evasion = n; } continue; } // hfov if ( !Q_stricmp( token, "hfov" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 30 || n > 180 ) { gi.Printf( "bad %s in NPC '%s'\n", token, NPCName ); continue; } if ( NPC->NPC ) { stats->hfov = n;// / 2; //FIXME: Why was this being done?! } continue; } // intelligence if ( !Q_stricmp( token, "intelligence" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 1 || n > 5 ) { gi.Printf( "bad %s in NPC '%s'\n", token, NPCName ); continue; } if ( NPC->NPC ) { stats->intelligence = n; } continue; } // move if ( !Q_stricmp( token, "move" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 1 || n > 5 ) { gi.Printf( "bad %s in NPC '%s'\n", token, NPCName ); continue; } if ( NPC->NPC ) { stats->move = n; } continue; } // reactions if ( !Q_stricmp( token, "reactions" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 1 || n > 5 ) { gi.Printf( "bad %s in NPC '%s'\n", token, NPCName ); continue; } if ( NPC->NPC ) { stats->reactions = n; } continue; } // shootDistance if ( !Q_stricmp( token, "saberColor" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } if ( NPC->client ) { NPC->client->ps.saberColor = TranslateSaberColor( value ); } continue; } // shootDistance if ( !Q_stricmp( token, "shootDistance" ) ) { if ( COM_ParseFloat( &p, &f ) ) { SkipRestOfLine( &p ); continue; } if ( f < 0.0f ) { gi.Printf( "bad %s in NPC '%s'\n", token, NPCName ); continue; } if ( NPC->NPC ) { stats->shootDistance = f; } continue; } // shootDistance if ( !Q_stricmp( token, "health" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 0 ) { gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName ); continue; } if ( NPC->NPC ) { stats->health = n; } continue; } // vfov if ( !Q_stricmp( token, "vfov" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 30 || n > 180 ) { gi.Printf( "bad %s in NPC '%s'\n", token, NPCName ); continue; } if ( NPC->NPC ) { stats->vfov = n / 2; } continue; } // vigilance if ( !Q_stricmp( token, "vigilance" ) ) { if ( COM_ParseFloat( &p, &f ) ) { SkipRestOfLine( &p ); continue; } if ( f < 0.0f ) { gi.Printf( "bad %s in NPC '%s'\n", token, NPCName ); continue; } if ( NPC->NPC ) { stats->vigilance = f; } continue; } // visrange if ( !Q_stricmp( token, "visrange" ) ) { if ( COM_ParseFloat( &p, &f ) ) { SkipRestOfLine( &p ); continue; } if ( f < 0.0f ) { gi.Printf( "bad %s in NPC '%s'\n", token, NPCName ); continue; } if ( NPC->NPC ) { stats->visrange = f; } continue; } // race // if ( !Q_stricmp( token, "race" ) ) // { // if ( COM_ParseString( &p, &value ) ) // { // continue; // } // NPC->client->race = TranslateRaceName(value); // continue; // } // rank if ( !Q_stricmp( token, "rank" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } if ( NPC->NPC ) { NPC->NPC->rank = TranslateRankName(value); } continue; } // fullName if ( !Q_stricmp( token, "fullName" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } NPC->fullName = G_NewString(value); continue; } // playerTeam if ( !Q_stricmp( token, "playerTeam" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } NPC->client->playerTeam = TranslateTeamName(value); continue; } // enemyTeam if ( !Q_stricmp( token, "enemyTeam" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } NPC->client->enemyTeam = TranslateTeamName(value); continue; } // class if ( !Q_stricmp( token, "class" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } NPC->client->NPC_class = TranslateClassName(value); continue; } // dismemberment probability for head if ( !Q_stricmp( token, "dismemberProbHead" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 0 ) { gi.Printf( "bad %s in NPC '%s'\n", token, NPCName ); continue; } if ( NPC->NPC ) { NPC->client->dismemberProbHead = n; } continue; } // dismemberment probability for arms if ( !Q_stricmp( token, "dismemberProbArms" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 0 ) { gi.Printf( "bad %s in NPC '%s'\n", token, NPCName ); continue; } if ( NPC->NPC ) { NPC->client->dismemberProbArms = n; } continue; } // dismemberment probability for hands if ( !Q_stricmp( token, "dismemberProbHands" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 0 ) { gi.Printf( "bad %s in NPC '%s'\n", token, NPCName ); continue; } if ( NPC->NPC ) { NPC->client->dismemberProbHands = n; } continue; } // dismemberment probability for waist if ( !Q_stricmp( token, "dismemberProbWaist" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 0 ) { gi.Printf( "bad %s in NPC '%s'\n", token, NPCName ); continue; } if ( NPC->NPC ) { NPC->client->dismemberProbWaist = n; } continue; } // dismemberment probability for legs if ( !Q_stricmp( token, "dismemberProbLegs" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 0 ) { gi.Printf( "bad %s in NPC '%s'\n", token, NPCName ); continue; } if ( NPC->NPC ) { NPC->client->dismemberProbLegs = n; } continue; } //===MOVEMENT STATS============================================================ if ( !Q_stricmp( token, "width" ) ) { if ( COM_ParseInt( &p, &n ) ) { continue; } NPC->mins[0] = NPC->mins[1] = -n; NPC->maxs[0] = NPC->maxs[1] = n; continue; } if ( !Q_stricmp( token, "height" ) ) { if ( COM_ParseInt( &p, &n ) ) { continue; } NPC->mins[2] = DEFAULT_MINS_2;//Cannot change NPC->maxs[2] = NPC->client->standheight = n + DEFAULT_MINS_2; NPC->radius = n; continue; } if ( !Q_stricmp( token, "crouchheight" ) ) { if ( COM_ParseInt( &p, &n ) ) { continue; } NPC->client->crouchheight = n + DEFAULT_MINS_2; continue; } if ( !Q_stricmp( token, "movetype" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } if ( NPC->NPC ) { stats->moveType = (movetype_t)MoveTypeNameToEnum(value); } continue; } // yawSpeed if ( !Q_stricmp( token, "yawSpeed" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n <= 0) { gi.Printf( "bad %s in NPC '%s'\n", token, NPCName ); continue; } if ( NPC->NPC ) { stats->yawSpeed = ((float)(n)); } continue; } // walkSpeed if ( !Q_stricmp( token, "walkSpeed" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 0 ) { gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName ); continue; } if ( NPC->NPC ) { stats->walkSpeed = n; } continue; } //runSpeed if ( !Q_stricmp( token, "runSpeed" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 0 ) { gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName ); continue; } if ( NPC->NPC ) { stats->runSpeed = n; } continue; } //acceleration if ( !Q_stricmp( token, "acceleration" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 0 ) { gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName ); continue; } if ( NPC->NPC ) { stats->acceleration = n; } continue; } //===MISC=============================================================================== // default behavior if ( !Q_stricmp( token, "behavior" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < BS_DEFAULT || n >= NUM_BSTATES ) { gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName ); continue; } if ( NPC->NPC ) { NPC->NPC->defaultBehavior = (bState_t)(n); } continue; } // snd if ( !Q_stricmp( token, "snd" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } if ( !(NPC->svFlags&SVF_NO_BASIC_SOUNDS) ) { //FIXME: store this in some sound field or parse in the soundTable like the animTable... Q_strncpyz( sound, value, sizeof( sound ) ); patch = strstr( sound, "/" ); if ( patch ) { *patch = 0; } ci->customBasicSoundDir = G_NewString( sound ); } continue; } // sndcombat if ( !Q_stricmp( token, "sndcombat" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } if ( !(NPC->svFlags&SVF_NO_COMBAT_SOUNDS) ) { //FIXME: store this in some sound field or parse in the soundTable like the animTable... Q_strncpyz( sound, value, sizeof( sound ) ); patch = strstr( sound, "/" ); if ( patch ) { *patch = 0; } ci->customCombatSoundDir = G_NewString( sound ); } continue; } // sndextra if ( !Q_stricmp( token, "sndextra" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } if ( !(NPC->svFlags&SVF_NO_EXTRA_SOUNDS) ) { //FIXME: store this in some sound field or parse in the soundTable like the animTable... Q_strncpyz( sound, value, sizeof( sound ) ); patch = strstr( sound, "/" ); if ( patch ) { *patch = 0; } ci->customExtraSoundDir = G_NewString( sound ); } continue; } // sndjedi if ( !Q_stricmp( token, "sndjedi" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } if ( !(NPC->svFlags&SVF_NO_EXTRA_SOUNDS) ) { //FIXME: store this in some sound field or parse in the soundTable like the animTable... Q_strncpyz( sound, value, sizeof( sound ) ); patch = strstr( sound, "/" ); if ( patch ) { *patch = 0; } ci->customJediSoundDir = G_NewString( sound ); } continue; } gi.Printf( "WARNING: unknown keyword '%s' while parsing '%s'\n", token, NPCName ); SkipRestOfLine( &p ); } } ci->infoValid = qfalse; /* Ghoul2 Insert Start */ if ( !md3Model ) { NPC->weaponModel = -1; G_SetG2PlayerModel( NPC, playerModel, customSkin, surfOff, surfOn ); } /* Ghoul2 Insert End */ if( NPCsPrecached ) {//Spawning in after initial precache, our models are precached, we just need to set our clientInfo CG_RegisterClientModels( NPC->s.number ); CG_RegisterNPCCustomSounds( ci ); CG_RegisterNPCEffects( NPC->client->playerTeam ); } return qtrue; }
qboolean UI_SaberParseParm( const char *saberName, const char *parmname, char *saberData ) { const char *token; const char *value; const char *p; if ( !saberName || !saberName[0] ) { return qfalse; } //try to parse it out p = SaberParms; COM_BeginParseSession(); // look for the right saber while ( p ) { token = COM_ParseExt( &p, qtrue ); if ( token[0] == 0 ) { return qfalse; } if ( !Q_stricmp( token, saberName ) ) { break; } SkipBracedSection( &p ); } if ( !p ) { return qfalse; } if ( UI_ParseLiteral( &p, "{" ) ) { return qfalse; } // parse the saber info block while ( 1 ) { token = COM_ParseExt( &p, qtrue ); if ( !token[0] ) { ui.Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s'\n", saberName ); return qfalse; } if ( !Q_stricmp( token, "}" ) ) { break; } if ( !Q_stricmp( token, parmname ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } strcpy( saberData, value ); return qtrue; } SkipRestOfLine( &p ); continue; } return qfalse; }
/* ================= CM_ParseShader The current text pointer is at the explicit text definition of the shader. Parse it into the global shader variable. This extracts all the info from the shader required for physics and collision It is designed to *NOT* load any image files and not require any of the renderer to be initialised. ================= */ static void CM_ParseShader( CCMShader *shader, const char **text ) { char *token; token = COM_ParseExt( text, qtrue ); if ( token[0] != '{' ) { Com_Printf( S_COLOR_YELLOW "WARNING: expecting '{', found '%s' instead in shader '%s'\n", token, shader->shader ); return; } while ( true ) { token = COM_ParseExt( text, qtrue ); if ( !token[0] ) { Com_Printf( S_COLOR_YELLOW "WARNING: no concluding '}' in shader %s\n", shader->shader ); return; } // end of shader definition if ( token[0] == '}' ) { break; } // stage definition else if ( token[0] == '{' ) { SkipBracedSection( text ); continue; } // material deprecated as of 11 Jan 01 // material undeprecated as of 7 May 01 - q3map_material deprecated else if ( !Q_stricmp( token, "material" ) || !Q_stricmp( token, "q3map_material" ) ) { SV_ParseMaterial( shader, text ); } // sun parms // q3map_sun deprecated as of 11 Jan 01 else if ( !Q_stricmp( token, "sun" ) || !Q_stricmp( token, "q3map_sun" ) ) { // float a, b; token = COM_ParseExt( text, qfalse ); // shader->sunLight[0] = atof( token ); token = COM_ParseExt( text, qfalse ); // shader->sunLight[1] = atof( token ); token = COM_ParseExt( text, qfalse ); // shader->sunLight[2] = atof( token ); // VectorNormalize( shader->sunLight ); token = COM_ParseExt( text, qfalse ); // a = atof( token ); // VectorScale( shader->sunLight, a, shader->sunLight); token = COM_ParseExt( text, qfalse ); // a = DEG2RAD(atof( token )); token = COM_ParseExt( text, qfalse ); // b = DEG2RAD(atof( token )); // shader->sunDirection[0] = cos( a ) * cos( b ); // shader->sunDirection[1] = sin( a ) * cos( b ); // shader->sunDirection[2] = sin( b ); } else if ( !Q_stricmp( token, "surfaceParm" ) ) { SV_ParseSurfaceParm( shader, text ); continue; } else if ( !Q_stricmp( token, "fogParms" ) ) { vec3_t fogColor; if ( !CM_ParseVector( shader, text, 3, fogColor ) ) { return; } token = COM_ParseExt( text, qfalse ); if ( !token[0] ) { Com_Printf( S_COLOR_YELLOW "WARNING: missing parm for 'fogParms' keyword in shader '%s'\n", shader->shader ); continue; } // shader->depthForOpaque = atof( token ); // skip any old gradient directions SkipRestOfLine( (const char **)text ); continue; } } return; }
/* void NPC_Precache ( char *NPCName ) Precaches NPC skins, tgas and md3s. */ void NPC_Precache ( gentity_t *spawner ) { clientInfo_t ci={0}; renderInfo_t ri={0}; team_t playerTeam = TEAM_FREE; char *token; char *value; char *p; char *patch; char sound[MAX_QPATH]; if ( !Q_stricmp( "random", spawner->NPC_type ) ) {//sorry, can't precache a random just yet return; } p = NPCParms; COM_BeginParseSession(); // look for the right NPC while ( p ) { token = COM_ParseExt( &p, qtrue ); if ( token[0] == 0 ) return; if ( !Q_stricmp( token, spawner->NPC_type ) ) { break; } SkipBracedSection( &p ); } if ( !p ) { return; } if ( G_ParseLiteral( &p, "{" ) ) { return; } // parse the NPC info block while ( 1 ) { token = COM_ParseExt( &p, qtrue ); if ( !token[0] ) { gi.Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s'\n", spawner->NPC_type ); return; } if ( !Q_stricmp( token, "}" ) ) { break; } // headmodel if ( !Q_stricmp( token, "headmodel" ) ) { if ( G_ParseString( &p, &value ) ) { continue; } if(!Q_stricmp("none", value)) { } else { Q_strncpyz( ri.headModelName, value, sizeof(ri.headModelName), qtrue); } continue; } // torsomodel if ( !Q_stricmp( token, "torsomodel" ) ) { if ( G_ParseString( &p, &value ) ) { continue; } if(!Q_stricmp("none", value)) { } else { Q_strncpyz( ri.torsoModelName, value, sizeof(ri.torsoModelName), qtrue); } continue; } // legsmodel if ( !Q_stricmp( token, "legsmodel" ) ) { if ( G_ParseString( &p, &value ) ) { continue; } Q_strncpyz( ri.legsModelName, value, sizeof(ri.legsModelName), qtrue); continue; } // playerTeam if ( !Q_stricmp( token, "playerTeam" ) ) { if ( G_ParseString( &p, &value ) ) { continue; } playerTeam = TranslateTeamName(value); continue; } // snd if ( !Q_stricmp( token, "snd" ) ) { if ( G_ParseString( &p, &value ) ) { continue; } if ( !(spawner->svFlags&SVF_NO_BASIC_SOUNDS) ) { //FIXME: store this in some sound field or parse in the soundTable like the animTable... Q_strncpyz( sound, value, sizeof( sound ) ); patch = strstr( sound, "/" ); if ( patch ) { *patch = 0; } ci.customBasicSoundDir = G_NewString( sound ); } continue; } // sndcombat if ( !Q_stricmp( token, "sndcombat" ) ) { if ( G_ParseString( &p, &value ) ) { continue; } if ( !(spawner->svFlags&SVF_NO_COMBAT_SOUNDS) ) { //FIXME: store this in some sound field or parse in the soundTable like the animTable... Q_strncpyz( sound, value, sizeof( sound ) ); patch = strstr( sound, "/" ); if ( patch ) { *patch = 0; } ci.customCombatSoundDir = G_NewString( sound ); } continue; } // sndextra if ( !Q_stricmp( token, "sndextra" ) ) { if ( G_ParseString( &p, &value ) ) { continue; } if ( !(spawner->svFlags&SVF_NO_EXTRA_SOUNDS) ) { //FIXME: store this in some sound field or parse in the soundTable like the animTable... Q_strncpyz( sound, value, sizeof( sound ) ); patch = strstr( sound, "/" ); if ( patch ) { *patch = 0; } ci.customExtraSoundDir = G_NewString( sound ); } continue; } // sndscav if ( !Q_stricmp( token, "sndscav" ) ) { if ( G_ParseString( &p, &value ) ) { continue; } if ( !(spawner->svFlags&SVF_NO_SCAV_SOUNDS) ) { //FIXME: store this in some sound field or parse in the soundTable like the animTable... Q_strncpyz( sound, value, sizeof( sound ) ); patch = strstr( sound, "/" ); if ( patch ) { *patch = 0; } ci.customScavSoundDir = G_NewString( sound ); } continue; } } CG_RegisterClientRenderInfo( &ci, &ri ); CG_RegisterNPCCustomSounds( &ci ); CG_RegisterNPCEffects( playerTeam ); //FIXME: precache the beam-in/exit sound and effect if not silentspawn //FIXME: Look for a "sounds" directory and precache death, pain, alert sounds }
static qboolean CG_ParseLensFlareEffect(char** p, lensFlareEffect_t* lfe) { char* token; char* name; #if LFDEBUG CG_LoadingString("LF: CG_ParseLensFlareEffect()"); #endif ParseEffect: token = COM_Parse(p); if (!token[0]) { if (CG_PopFile()) { *p = lfbuf; goto ParseEffect; } return qfalse; } if (!Q_stricmp(token, "import")) { CG_PushFile("maps/import/", COM_Parse(p)); goto ParseEffect; } if (!Q_stricmp(token, "sunparm")) { token = COM_Parse(p); Q_strncpyz(cgs.sunFlareEffect, token, sizeof(cgs.sunFlareEffect)); token = COM_Parse(p); cgs.sunFlareYaw = atof(token); token = COM_Parse(p); cgs.sunFlarePitch = atof(token); token = COM_Parse(p); cgs.sunFlareDistance = atof(token); goto ParseEffect; } name = va("%s%s", lfNameBase, token); if (CG_FindLensFlareEffect(name)) { SkipBracedSection(p, 0); goto ParseEffect; } Q_strncpyz(lfe->name, name, sizeof(lfe->name)); token = COM_Parse(p); if (Q_stricmp(token, "{")) { CG_Printf(S_COLOR_YELLOW "read '%s', expected '{' in '%s'\n", token, lfe->name); return qfalse; } // set non-zero default values lfe->range = 400; lfe->fadeAngle = 20; while (1) { token = COM_Parse(p); if (!token[0]) { CG_Printf(S_COLOR_YELLOW "unexpected end of lens flare effect '%s'\n", lfe->name); return qfalse; } if (!Q_stricmp(token, "}")) break; if (!Q_stricmp(token, "{")) { if (lfe->numLensFlares >= MAX_LENSFLARES_PER_EFFECT) { CG_Printf(S_COLOR_YELLOW "too many lensflares in '%s' (max=%d)\n", lfe->name, MAX_LENSFLARES_PER_EFFECT); return qfalse; } if (!CG_ParseLensFlare(p, &lfe->lensFlares[lfe->numLensFlares], lfe->name)) return qfalse; lfe->numLensFlares++; } else if (!Q_stricmp(token, "range")) { token = COM_Parse(p); lfe->range = atof(token); lfe->rangeSqr = Square(lfe->range); } else if (!Q_stricmp(token, "fadeAngle")) { token = COM_Parse(p); lfe->fadeAngle = Com_Clamp(0, 180, atof(token)); } else { CG_Printf(S_COLOR_YELLOW "unexpected token '%s' in '%s'\n", token, lfe->name); return qfalse; } } CG_FinalizeLensFlareEffect(lfe); return qtrue; }
/* ================= CM_ParseShader The current text pointer is at the explicit text definition of the shader. Parse it into the global shader variable. This extracts all the info from the shader required for physics and collision It is designed to *NOT* load any image files and not require any of the renderer to be initialised. ================= */ static void CM_ParseShader( CCMShader *shader, const char **text ) { char *token; token = COM_ParseExt( text, qtrue ); if ( token[0] != '{' ) { Com_Printf( S_COLOR_YELLOW "WARNING: expecting '{', found '%s' instead in shader '%s'\n", token, shader->shader ); return; } while ( true ) { token = COM_ParseExt( text, qtrue ); if ( !token[0] ) { Com_Printf( S_COLOR_YELLOW "WARNING: no concluding '}' in shader %s\n", shader->shader ); return; } // end of shader definition if ( token[0] == '}' ) { break; } // stage definition else if ( token[0] == '{' ) { SkipBracedSection( text ); continue; } // material deprecated as of 11 Jan 01 // material undeprecated as of 7 May 01 - q3map_material deprecated else if ( !Q_stricmp( token, "material" ) || !Q_stricmp( token, "q3map_material" ) ) { SV_ParseMaterial( shader, text ); } // sun parms // q3map_sun deprecated as of 11 Jan 01 else if ( !Q_stricmp( token, "sun" ) || !Q_stricmp( token, "q3map_sun" ) ) { float a, b; token = COM_ParseExt( text, qfalse ); shader->sunLight[0] = atof( token ); token = COM_ParseExt( text, qfalse ); shader->sunLight[1] = atof( token ); token = COM_ParseExt( text, qfalse ); shader->sunLight[2] = atof( token ); VectorNormalize( shader->sunLight ); token = COM_ParseExt( text, qfalse ); a = atof( token ); VectorScale( shader->sunLight, a, shader->sunLight); token = COM_ParseExt( text, qfalse ); a = DEG2RAD(atof( token )); token = COM_ParseExt( text, qfalse ); b = DEG2RAD(atof( token )); shader->sunDirection[0] = cos( a ) * cos( b ); shader->sunDirection[1] = sin( a ) * cos( b ); shader->sunDirection[2] = sin( b ); } else if ( !Q_stricmp( token, "surfaceParm" ) ) { SV_ParseSurfaceParm( shader, text ); continue; } else if ( !Q_stricmp( token, "fogParms" ) ) { if ( !CM_ParseVector( shader, text, 3, shader->fogColor ) ) { return; } token = COM_ParseExt( text, qfalse ); if ( !token[0] ) { Com_Printf( S_COLOR_YELLOW "WARNING: missing parm for 'fogParms' keyword in shader '%s'\n", shader->shader ); continue; } shader->depthForOpaque = atof( token ); // skip any old gradient directions SkipRestOfLine( (const char **)text ); continue; } else if ( !Q_stricmp( token, "damageShader" ) ) { CCMShader *damageShader; token = COM_ParseExt( text, qfalse ); if ( !token[0] ) { Com_Printf( S_COLOR_YELLOW "WARNING: missing parm for 'damageShader' keyword in shader '%s'\n", shader->shader ); continue; } damageShader = CM_GetShaderInfo(token); if(damageShader) { shader->damageShaderNum = damageShader - cm.shaders; } token = COM_ParseExt( text, qfalse ); if(token) { shader->damage = atof(token); } continue; } // // location hit mesh load // else if ( !Q_stricmp( token, "hitLocation" ) ) { // grab the filename of the hit location texture token = COM_ParseExt( text, qfalse ); if ( !token[0] ) { break; } Q_strncpyz(shader->hitLocation, token, MAX_QPATH); continue; } // // location hit material mesh load // else if ( !Q_stricmp( token, "hitMaterial" ) ) { // grab the filename of the hit location texture token = COM_ParseExt( text, qfalse ); if ( !token[0] ) { break; } Q_strncpyz(shader->hitMaterial, token, MAX_QPATH); continue; } } return; }
qboolean BG_ParseRankNames( char* fileName, rankNames_t rankNames[] ) { fileHandle_t f; int file_len; char charText[20000]; char* textPtr; char* token; int i = 0; file_len = trap_FS_FOpenFile( fileName, &f, FS_READ ); if ( file_len<= 0 ) { return qfalse; } if ( file_len >= ( sizeof(charText) - 1) ) { Com_Printf( S_COLOR_RED "File length of %s is too long.\n", fileName ); } memset( &charText, 0, sizeof( charText ) ); memset( rankNames, 0, sizeof( rankNames ) ); trap_FS_Read( charText, file_len, f ); charText[file_len] = 0; trap_FS_FCloseFile( f ); COM_BeginParseSession(); textPtr = charText; token = COM_Parse( &textPtr ); if ( !token[0] ) { Com_Printf( S_COLOR_RED "No data found in buffer: %s\n", fileName ); return qfalse; } if ( Q_stricmpn( token, "{", 1 ) ) { Com_Printf( S_COLOR_RED "No beginning { found in %s\n", fileName ); return qfalse; } //Parse out the default cell. Default has no names anyway, //but in case a n00bie modder put names in anyway. SkipBracedSection( &textPtr ); while( 1 ) { //lastPtr = textPtr; token = COM_Parse( &textPtr ); if( !token[0] ) { break; } if ( i >= MAX_RANKS ) { break; } //If we hit an open brace (ie, assuming we hit the start of a new rank cell) if ( !Q_stricmpn( token, "{", 1 ) ) { while ( 1 ) { token = COM_Parse( &textPtr ); if( !token[0] ) { break; } //We hit a MenuTexture entry, since this uses { symbols, we'll skip these to stop errors. if ( !Q_stricmpn( token, "MenuTexture", 11 ) ) { SkipRestOfLine( &textPtr ); continue; } if ( !Q_stricmpn( token, "ConsoleName", 11) ) { if ( COM_ParseString( &textPtr, &token ) ) { continue; } Q_strncpyz( rankNames[i].consoleName, token, sizeof( rankNames[i].consoleName ) ); continue; } else if ( !Q_stricmpn( token, "FormalName", 10) ) { if ( COM_ParseString( &textPtr, &token ) ) { continue; } Q_strncpyz( rankNames[i].formalName, token, sizeof( rankNames[i].formalName ) ); continue; } //We hit the end of the cell. else if ( !Q_stricmpn( token, "}", 1 ) ) { break; } } //Error check. If we didn't get both a formal and console name, pwn the caller. ;P if ( !rankNames[i].consoleName[0] || !rankNames[i].formalName[0] ) { Com_Printf( S_COLOR_RED "One or more rank names were not found in rank#: %i\n", i ); return qfalse; } else { i++; } } } return qtrue; }
qboolean WP_SaberParseParms( const char *SaberName, saberInfo_t *saber, qboolean setColors ) { const char *token; const char *value; const char *p; float f; int n; if ( !saber ) { return qfalse; } //Set defaults so that, if it fails, there's at least something there WP_SaberSetDefaults( saber, setColors ); if ( !SaberName || !SaberName[0] ) { return qfalse; } saber->name = G_NewString( SaberName ); //try to parse it out p = SaberParms; COM_BeginParseSession(); // look for the right saber while ( p ) { token = COM_ParseExt( &p, qtrue ); if ( token[0] == 0 ) { return qfalse; } if ( !Q_stricmp( token, SaberName ) ) { break; } SkipBracedSection( &p ); } if ( !p ) { return qfalse; } if ( G_ParseLiteral( &p, "{" ) ) { return qfalse; } // parse the saber info block while ( 1 ) { token = COM_ParseExt( &p, qtrue ); if ( !token[0] ) { gi.Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s'\n", SaberName ); return qfalse; } if ( !Q_stricmp( token, "}" ) ) { break; } //saber fullName if ( !Q_stricmp( token, "name" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->fullName = G_NewString( value ); continue; } //saber type if ( !Q_stricmp( token, "saberType" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } int saberType = GetIDForString( SaberTable, value ); if ( saberType >= SABER_SINGLE && saberType <= NUM_SABERS ) { saber->type = (saberType_t)saberType; } continue; } //saber hilt if ( !Q_stricmp( token, "saberModel" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->model = G_NewString( value ); continue; } if ( !Q_stricmp( token, "customSkin" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->skin = G_NewString( value ); continue; } //on sound if ( !Q_stricmp( token, "soundOn" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->soundOn = G_SoundIndex( G_NewString( value ) ); continue; } //loop sound if ( !Q_stricmp( token, "soundLoop" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->soundLoop = G_SoundIndex( G_NewString( value ) ); continue; } //off sound if ( !Q_stricmp( token, "soundOff" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->soundOff = G_SoundIndex( G_NewString( value ) ); continue; } if ( !Q_stricmp( token, "numBlades" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 1 || n >= MAX_BLADES ) { G_Error( "WP_SaberParseParms: saber %s has illegal number of blades (%d) max: %d", SaberName, n, MAX_BLADES ); continue; } saber->numBlades = n; continue; } // saberColor if ( !Q_stricmpn( token, "saberColor", 10 ) ) { if ( !setColors ) {//don't actually want to set the colors //read the color out anyway just to advance the *p pointer COM_ParseString( &p, &value ); continue; } else { if (strlen(token)==10) { n = -1; } else if (strlen(token)==11) { n = atoi(&token[10])-1; if (n > 7 || n < 1 ) { gi.Printf( S_COLOR_YELLOW"WARNING: bad saberColor '%s' in %s\n", token, SaberName ); //read the color out anyway just to advance the *p pointer COM_ParseString( &p, &value ); continue; } } else { gi.Printf( S_COLOR_YELLOW"WARNING: bad saberColor '%s' in %s\n", token, SaberName ); //read the color out anyway just to advance the *p pointer COM_ParseString( &p, &value ); continue; } if ( COM_ParseString( &p, &value ) ) //read the color { continue; } if (n==-1) {//NOTE: this fills in the rest of the blades with the same color by default saber_colors_t color = TranslateSaberColor( value ); for ( n = 0; n < MAX_BLADES; n++ ) { saber->blade[n].color = color; } } else { saber->blade[n].color = TranslateSaberColor( value ); } continue; } } //saber length if ( !Q_stricmpn( token, "saberLength", 11 ) ) { if (strlen(token)==11) { n = -1; } else if (strlen(token)==12) { n = atoi(&token[11])-1; if (n > 7 || n < 1 ) { gi.Printf( S_COLOR_YELLOW"WARNING: bad saberLength '%s' in %s\n", token, SaberName ); continue; } } else { gi.Printf( S_COLOR_YELLOW"WARNING: bad saberLength '%s' in %s\n", token, SaberName ); continue; } if ( COM_ParseFloat( &p, &f ) ) { SkipRestOfLine( &p ); continue; } //cap if ( f < 4.0f ) { f = 4.0f; } if (n==-1) {//NOTE: this fills in the rest of the blades with the same length by default for ( n = 0; n < MAX_BLADES; n++ ) { saber->blade[n].lengthMax = f; } } else { saber->blade[n].lengthMax = f; } continue; } //blade radius if ( !Q_stricmpn( token, "saberRadius", 11 ) ) { if (strlen(token)==11) { n = -1; } else if (strlen(token)==12) { n = atoi(&token[11])-1; if (n > 7 || n < 1 ) { gi.Printf( S_COLOR_YELLOW"WARNING: bad saberRadius '%s' in %s\n", token, SaberName ); continue; } } else { gi.Printf( S_COLOR_YELLOW"WARNING: bad saberRadius '%s' in %s\n", token, SaberName ); continue; } if ( COM_ParseFloat( &p, &f ) ) { SkipRestOfLine( &p ); continue; } //cap if ( f < 0.25f ) { f = 0.25f; } if (n==-1) {//NOTE: this fills in the rest of the blades with the same length by default for ( n = 0; n < MAX_BLADES; n++ ) { saber->blade[n].radius = f; } } else { saber->blade[n].radius = f; } continue; } //locked saber style if ( !Q_stricmp( token, "saberStyle" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->style = TranslateSaberStyle( value ); continue; } //maxChain if ( !Q_stricmp( token, "maxChain" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->maxChain = n; continue; } //lockable if ( !Q_stricmp( token, "lockable" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->lockable = ((qboolean)(n!=0)); continue; } //throwable if ( !Q_stricmp( token, "throwable" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->throwable = ((qboolean)(n!=0)); continue; } //disarmable if ( !Q_stricmp( token, "disarmable" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->disarmable = ((qboolean)(n!=0)); continue; } //active blocking if ( !Q_stricmp( token, "blocking" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->activeBlocking = ((qboolean)(n!=0)); continue; } //twoHanded if ( !Q_stricmp( token, "twoHanded" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->twoHanded = ((qboolean)(n!=0)); continue; } //force power restrictions if ( !Q_stricmp( token, "forceRestrict" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } int fp = GetIDForString( FPTable, value ); if ( fp >= FP_FIRST && fp < NUM_FORCE_POWERS ) { saber->forceRestrictions |= (1<<fp); } continue; } //lockBonus if ( !Q_stricmp( token, "lockBonus" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->lockBonus = n; continue; } //parryBonus if ( !Q_stricmp( token, "parryBonus" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->parryBonus = n; continue; } //breakParryBonus if ( !Q_stricmp( token, "breakParryBonus" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->breakParryBonus = n; continue; } //disarmBonus if ( !Q_stricmp( token, "disarmBonus" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->disarmBonus = n; continue; } //single blade saber style if ( !Q_stricmp( token, "singleBladeStyle" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->singleBladeStyle = TranslateSaberStyle( value ); continue; } //single blade throwable if ( !Q_stricmp( token, "singleBladeThrowable" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->singleBladeThrowable = ((qboolean)(n!=0)); continue; } //broken replacement saber1 (right hand) if ( !Q_stricmp( token, "brokenSaber1" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->brokenSaber1 = G_NewString( value ); continue; } //broken replacement saber2 (left hand) if ( !Q_stricmp( token, "brokenSaber2" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->brokenSaber2 = G_NewString( value ); continue; } //spins and does damage on return from saberthrow if ( !Q_stricmp( token, "returnDamage" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->returnDamage = ((qboolean)(n!=0)); continue; } if ( !Q_stricmp( token, "notInMP" ) ) {//ignore this SkipRestOfLine( &p ); continue; } gi.Printf( "WARNING: unknown keyword '%s' while parsing '%s'\n", token, SaberName ); SkipRestOfLine( &p ); } //FIXME: precache the saberModel(s)? if ( saber->type == SABER_SITH_SWORD ) {//precache all the sith sword sounds Saber_SithSwordPrecache(); } return qtrue; }
/* ============== Bot_ScriptParseAllCharacters ============== */ void Bot_ScriptParseAllCharacters() { char *pScript; char *token; bot_script_global_data_t *bsd; char params[MAX_TOKEN_CHARS]; if(!level.scriptEntity) { return; } pScript = level.scriptEntity; COM_BeginParseSession("Bot_ScriptParse"); numScriptCharacters = 0; memset(botCharacterScriptData, 0, sizeof(botCharacterScriptData)); while(1) { token = COM_Parse(&pScript); // we are expecting a name here if(!token[0]) { // end of script break; } if(token[0] == '{' || token[0] == '}') { G_Error("Bot_ScriptParse(), Error (line %d): entry identifier expected, '%s' found.\n", 1 + COM_GetCurrentParseLine(), token); } // is this a bot? if(Q_stricmp(token, "BOT") != 0) { // not a bot, skip this whole entry SkipRestOfLine(&pScript); // skip this section SkipBracedSection(&pScript); // continue; } // this is the name if(numScriptCharacters == MAX_BOT_SCRIPT_CHARACTERS) { G_Error ("Bot_ScriptParse(), Error (line %d): MAX_BOT_SCRIPT_CHARACTERS exceeded (%i), too many bot script characters\n", 1 + COM_GetCurrentParseLine(), MAX_BOT_SCRIPT_CHARACTERS); break; } bsd = &botCharacterScriptData[numScriptCharacters++]; bsd->lineNum = 1 + COM_GetCurrentParseLine(); // read the name token = COM_Parse(&pScript); // we are expecting a name here if(!token[0]) { G_Error("Bot_ScriptParse(), Error (line %d): name expected, end of line found.\n", 1 + COM_GetCurrentParseLine()); } if(token[0] == '{' || token[0] == '}') { G_Error("Bot_ScriptParse(), Error (line %d): name expected, '%s' found.\n", 1 + COM_GetCurrentParseLine(), token); } // allocate the name bsd->name = G_Alloc(strlen(token) + 1); Q_strncpyz(bsd->name, token, strlen(token) + 1); // read the params memset(params, 0, sizeof(params)); while((token = COM_ParseExt(&pScript, qfalse)) && token[0]) { if(strlen(params) + strlen(token) >= sizeof(params)) { G_Error("Bot_ScriptParse(), Error (line %d): parameters exceed maximum size\n", 1 + COM_GetCurrentParseLine()); } if(strlen(params) > 0) { Q_strcat(params, sizeof(params), " "); } Q_strcat(params, sizeof(params), token); } // allocate the params bsd->params = G_Alloc(strlen(params) + 1); Q_strncpyz(bsd->params, params, strlen(params) + 1); // allocate memory for this character script bsd->data = G_Alloc(sizeof(bot_script_data_t)); memset(bsd->data, 0, sizeof(bot_script_data_t)); // now parse the script data for this character Bot_ScriptParse(bsd->data, &pScript); } }
/** * @brief Finds and loads all .shader files, combining them into * a single large text block that can be scanned for shader names */ int ScanAndLoadShaderFilesR1() { char **shaderFiles; char *buffers[MAX_SHADER_FILES]; char *p; int numShaderFiles, i; char *oldp, *token, *textEnd; char **hashMem; int shaderTextHashTableSizes[MAX_SHADERTEXT_HASH], hash; unsigned int size; char filename[MAX_QPATH]; long sum = 0, summand; Com_Memset(buffers, 0, MAX_SHADER_FILES); Com_Memset(shaderTextHashTableSizes, 0, MAX_SHADER_FILES); // scan for shader files shaderFiles = ri.FS_ListFiles("scripts", ".shader", &numShaderFiles); if (!shaderFiles || !numShaderFiles) { Ren_Print("----- ScanAndLoadShaderFilesR1 (no files)-----\n"); return 0; } Ren_Print("----- ScanAndLoadShaderFilesR1 (%i files)-----\n", numShaderFiles); if (numShaderFiles >= MAX_SHADER_FILES) { Ren_Drop("MAX_SHADER_FILES limit is reached!"); } // load and parse shader files for (i = 0; i < numShaderFiles; i++) { Com_sprintf(filename, sizeof(filename), "scripts/%s", shaderFiles[i]); COM_BeginParseSession(filename); Ren_Developer("...loading '%s'\n", filename); summand = ri.FS_ReadFile(filename, (void **)&buffers[i]); if (!buffers[i]) { Ren_Drop("Couldn't load %s", filename); // in this case shader file is cought/listed but the file can't be read - drop! } p = buffers[i]; while (1) { token = COM_ParseExt(&p, qtrue); if (!*token) { break; } // Step over the "table"/"guide" and the name if (!Q_stricmp(token, "table") || !Q_stricmp(token, "guide")) { token = COM_ParseExt2(&p, qtrue); if (!*token) { break; } } oldp = p; token = COM_ParseExt2(&p, qtrue); if (token[0] != '{' && token[1] != '\0') { Ren_Warning("WARNING: Bad shader file %s has incorrect syntax near token '%s' line %i\n", filename, token, COM_GetCurrentParseLine()); ri.FS_FreeFile(buffers[i]); buffers[i] = NULL; break; } SkipBracedSection(&oldp); p = oldp; } if (buffers[i]) { sum += summand; } } // build single large buffer s_shaderTextR1 = (char *)ri.Hunk_Alloc(sum + numShaderFiles * 2, h_low); s_shaderTextR1[0] = '\0'; textEnd = s_shaderTextR1; // free in reverse order, so the temp files are all dumped for (i = numShaderFiles - 1; i >= 0 ; i--) { if (!buffers[i]) { continue; } strcat(textEnd, buffers[i]); strcat(textEnd, "\n"); textEnd += strlen(textEnd); ri.FS_FreeFile(buffers[i]); } COM_Compress(s_shaderTextR1); // free up memory ri.FS_FreeFileList(shaderFiles); Com_Memset(shaderTextHashTableSizes, 0, sizeof(shaderTextHashTableSizes)); size = 0; p = s_shaderTextR1; // look for shader names while (1) { token = COM_ParseExt(&p, qtrue); if (token[0] == 0) { break; } // skip shader tables if (!Q_stricmp(token, "table")) { // skip table name (void) COM_ParseExt2(&p, qtrue); SkipBracedSection(&p); } // support shader templates else if (!Q_stricmp(token, "guide")) { // parse shader name token = COM_ParseExt2(&p, qtrue); //Ren_Print("...guided '%s'\n", token); hash = generateHashValue(token, MAX_SHADERTEXT_HASH); shaderTextHashTableSizes[hash]++; size++; // skip guide name token = COM_ParseExt2(&p, qtrue); // skip parameters token = COM_ParseExt2(&p, qtrue); if (Q_stricmp(token, "(")) { Ren_Warning("expected ( found '%s'\n", token); break; } while (1) { token = COM_ParseExt2(&p, qtrue); if (!token[0]) { break; } if (!Q_stricmp(token, ")")) { break; } } if (Q_stricmp(token, ")")) { Ren_Warning("expected ( found '%s'\n", token); break; } } else { hash = generateHashValue(token, MAX_SHADERTEXT_HASH); shaderTextHashTableSizes[hash]++; size++; SkipBracedSection(&p); } } //Ren_Print("Shader hash table size %i\n", size); size += MAX_SHADERTEXT_HASH; hashMem = (char **)ri.Hunk_Alloc(size * sizeof(char *), h_low); for (i = 0; i < MAX_SHADERTEXT_HASH; i++) { shaderTextHashTableR1[i] = hashMem; hashMem += shaderTextHashTableSizes[i] + 1; } Com_Memset(shaderTextHashTableSizes, 0, sizeof(shaderTextHashTableSizes)); p = s_shaderTextR1; // look for shader names while (1) { oldp = p; token = COM_ParseExt(&p, qtrue); if (token[0] == 0) { break; } // parse shader tables if (!Q_stricmp(token, "table")) { int depth; float values[FUNCTABLE_SIZE]; int numValues; shaderTable_t *tb; qboolean alreadyCreated; Com_Memset(&values, 0, sizeof(values)); Com_Memset(&table, 0, sizeof(table)); token = COM_ParseExt2(&p, qtrue); Q_strncpyz(table.name, token, sizeof(table.name)); // check if already created alreadyCreated = qfalse; hash = generateHashValue(table.name, MAX_SHADERTABLE_HASH); for (tb = shaderTableHashTable[hash]; tb; tb = tb->next) { if (Q_stricmp(tb->name, table.name) == 0) { // match found alreadyCreated = qtrue; break; } } depth = 0; numValues = 0; do { token = COM_ParseExt2(&p, qtrue); if (!Q_stricmp(token, "snap")) { table.snap = qtrue; } else if (!Q_stricmp(token, "clamp")) { table.clamp = qtrue; } else if (token[0] == '{') { depth++; } else if (token[0] == '}') { depth--; } else if (token[0] == ',') { continue; } else { if (numValues == FUNCTABLE_SIZE) { Ren_Warning("WARNING: FUNCTABLE_SIZE hit\n"); break; } values[numValues++] = atof(token); } } while (depth && p); if (!alreadyCreated) { Ren_Developer("...generating '%s'\n", table.name); GeneratePermanentShaderTable(values, numValues); } } // support shader templates else if (!Q_stricmp(token, "guide")) { // parse shader name oldp = p; token = COM_ParseExt2(&p, qtrue); //Ren_Print("...guided '%s'\n", token); hash = generateHashValue(token, MAX_SHADERTEXT_HASH); shaderTextHashTableR1[hash][shaderTextHashTableSizes[hash]++] = oldp; // skip guide name token = COM_ParseExt2(&p, qtrue); // skip parameters token = COM_ParseExt2(&p, qtrue); if (Q_stricmp(token, "(")) { Ren_Warning("expected ( found '%s'\n", token); break; } while (1) { token = COM_ParseExt2(&p, qtrue); if (!token[0]) { break; } if (!Q_stricmp(token, ")")) { break; } } if (Q_stricmp(token, ")")) { Ren_Warning("expected ( found '%s'\n", token); break; } } else { hash = generateHashValue(token, MAX_SHADERTEXT_HASH); shaderTextHashTableR1[hash][shaderTextHashTableSizes[hash]++] = oldp; SkipBracedSection(&p); } } return numShaderFiles; }
/** * @brief Scans the combined text description of all the shader files for * the given shader name. * @param[in] shaderName * @return NULL if not found, otherwise it will return a valid shader */ char *FindShaderInShaderTextR1(const char *shaderName) { char *token, *p; int i, hash; hash = generateHashValue(shaderName, MAX_SHADERTEXT_HASH); for (i = 0; shaderTextHashTableR1[hash][i]; i++) { p = shaderTextHashTableR1[hash][i]; token = COM_ParseExt2(&p, qtrue); if (!Q_stricmp(token, shaderName)) { //Ren_Print("found shader '%s' by hashing\n", shaderName); return p; } } p = s_shaderTextR1; if (!p) { return NULL; } // look for label while (1) { token = COM_ParseExt2(&p, qtrue); if (token[0] == 0) { break; } if (!Q_stricmp(token, shaderName)) { //Ren_Print("found shader '%s' by linear search\n", shaderName); return p; } // skip shader tables else if (!Q_stricmp(token, "table")) { // skip table name (void) COM_ParseExt2(&p, qtrue); SkipBracedSection(&p); } // support shader templates else if (!Q_stricmp(token, "guide")) { // parse shader name token = COM_ParseExt2(&p, qtrue); if (!Q_stricmp(token, shaderName)) { Ren_Print("found shader '%s' by linear search\n", shaderName); return p; } // skip guide name token = COM_ParseExt2(&p, qtrue); // skip parameters token = COM_ParseExt2(&p, qtrue); if (Q_stricmp(token, "(")) { break; } while (1) { token = COM_ParseExt2(&p, qtrue); if (!token[0]) { break; } if (!Q_stricmp(token, ")")) { break; } } if (Q_stricmp(token, ")")) { break; } } else { // skip the shader body SkipBracedSection(&p); } } return NULL; }
qboolean WP_SaberParseParms( const char *SaberName, saberInfo_t *saber ) { const char *token; const char *value; const char *p; char useSaber[1024]; float f; int n; qboolean triedDefault = qfalse; if ( !saber ) { return qfalse; } //Set defaults so that, if it fails, there's at least something there WP_SaberSetDefaults( saber ); if ( !SaberName || !SaberName[0] ) { strcpy(useSaber, DEFAULT_SABER); //default triedDefault = qtrue; } else { strcpy(useSaber, SaberName); } //try to parse it out p = SaberParms; COM_BeginParseSession("saberinfo"); // look for the right saber while ( p ) { token = COM_ParseExt( &p, qtrue ); if ( token[0] == 0 ) { if (!triedDefault) { //fall back to default and restart, should always be there p = SaberParms; COM_BeginParseSession("saberinfo"); strcpy(useSaber, DEFAULT_SABER); triedDefault = qtrue; } else { return qfalse; } } if ( !Q_stricmp( token, useSaber ) ) { break; } SkipBracedSection( &p ); } if ( !p ) { //even the default saber isn't found? return qfalse; } //got the name we're using for sure strcpy(saber->name, useSaber); if ( BG_ParseLiteral( &p, "{" ) ) { return qfalse; } // parse the saber info block while ( 1 ) { token = COM_ParseExt( &p, qtrue ); if ( !token[0] ) { Com_Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s'\n", useSaber ); return qfalse; } if ( !Q_stricmp( token, "}" ) ) { break; } //saber fullName if ( !Q_stricmp( token, "name" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } strcpy(saber->fullName, value); continue; } //saber type if ( !Q_stricmp( token, "saberType" ) ) { int saberType; if ( COM_ParseString( &p, &value ) ) { continue; } saberType = GetIDForString( SaberTable, value ); if ( saberType >= SABER_SINGLE && saberType <= NUM_SABERS ) { saber->type = (saberType_t)saberType; } continue; } //saber hilt if ( !Q_stricmp( token, "saberModel" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } strcpy(saber->model, value); continue; } if ( !Q_stricmp( token, "customSkin" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->skin = trap_R_RegisterSkin(value); continue; } //on sound if ( !Q_stricmp( token, "soundOn" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->soundOn = BG_SoundIndex( (char *)value ); continue; } //loop sound if ( !Q_stricmp( token, "soundLoop" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->soundLoop = BG_SoundIndex( (char *)value ); continue; } //off sound if ( !Q_stricmp( token, "soundOff" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->soundOff = BG_SoundIndex( (char *)value ); continue; } if ( !Q_stricmp( token, "numBlades" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } if ( n < 1 || n >= MAX_BLADES ) { Com_Error(ERR_DROP, "WP_SaberParseParms: saber %s has illegal number of blades (%d) max: %d", useSaber, n, MAX_BLADES ); continue; } saber->numBlades = n; continue; } // saberColor if ( !Q_stricmpn( token, "saberColor", 10 ) ) { if (strlen(token)==10) { n = -1; } else if (strlen(token)==11) { n = atoi(&token[10])-1; if (n > 7 || n < 1 ) { #ifndef FINAL_BUILD Com_Printf( S_COLOR_YELLOW"WARNING: bad saberColor '%s' in %s\n", token, useSaber ); #endif continue; } } else { #ifndef FINAL_BUILD Com_Printf( S_COLOR_YELLOW"WARNING: bad saberColor '%s' in %s\n", token, useSaber ); #endif continue; } if ( COM_ParseString( &p, &value ) ) //read the color { continue; } if (n==-1) {//NOTE: this fills in the rest of the blades with the same color by default saber_colors_t color = TranslateSaberColor( value ); for ( n = 0; n < MAX_BLADES; n++ ) { saber->blade[n].color = color; } } else { saber->blade[n].color = TranslateSaberColor( value ); } continue; } //saber length if ( !Q_stricmpn( token, "saberLength", 11 ) ) { if (strlen(token)==11) { n = -1; } else if (strlen(token)==12) { n = atoi(&token[11])-1; if (n > 7 || n < 1 ) { #ifndef FINAL_BUILD Com_Printf( S_COLOR_YELLOW"WARNING: bad saberLength '%s' in %s\n", token, useSaber ); #endif continue; } } else { #ifndef FINAL_BUILD Com_Printf( S_COLOR_YELLOW"WARNING: bad saberLength '%s' in %s\n", token, useSaber ); #endif continue; } if ( COM_ParseFloat( &p, &f ) ) { SkipRestOfLine( &p ); continue; } //cap if ( f < 4.0f ) { f = 4.0f; } if (n==-1) {//NOTE: this fills in the rest of the blades with the same length by default for ( n = 0; n < MAX_BLADES; n++ ) { saber->blade[n].lengthMax = f; } } else { saber->blade[n].lengthMax = f; } continue; } //blade radius if ( !Q_stricmpn( token, "saberRadius", 11 ) ) { if (strlen(token)==11) { n = -1; } else if (strlen(token)==12) { n = atoi(&token[11])-1; if (n > 7 || n < 1 ) { #ifndef FINAL_BUILD Com_Printf( S_COLOR_YELLOW"WARNING: bad saberRadius '%s' in %s\n", token, useSaber ); #endif continue; } } else { #ifndef FINAL_BUILD Com_Printf( S_COLOR_YELLOW"WARNING: bad saberRadius '%s' in %s\n", token, useSaber ); #endif continue; } if ( COM_ParseFloat( &p, &f ) ) { SkipRestOfLine( &p ); continue; } //cap if ( f < 0.25f ) { f = 0.25f; } if (n==-1) {//NOTE: this fills in the rest of the blades with the same length by default for ( n = 0; n < MAX_BLADES; n++ ) { saber->blade[n].radius = f; } } else { saber->blade[n].radius = f; } continue; } //locked saber style if ( !Q_stricmp( token, "saberStyle" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->style = TranslateSaberStyle( value ); continue; } //maxChain if ( !Q_stricmp( token, "maxChain" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->maxChain = n; continue; } //lockable if ( !Q_stricmp( token, "lockable" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->lockable = ((qboolean)(n!=0)); continue; } //throwable if ( !Q_stricmp( token, "throwable" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->throwable = ((qboolean)(n!=0)); continue; } //disarmable if ( !Q_stricmp( token, "disarmable" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->disarmable = ((qboolean)(n!=0)); continue; } //active blocking if ( !Q_stricmp( token, "blocking" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->activeBlocking = ((qboolean)(n!=0)); continue; } //twoHanded if ( !Q_stricmp( token, "twoHanded" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->twoHanded = ((qboolean)(n!=0)); continue; } //force power restrictions if ( !Q_stricmp( token, "forceRestrict" ) ) { int fp; if ( COM_ParseString( &p, &value ) ) { continue; } fp = GetIDForString( FPTable, value ); if ( fp >= FP_FIRST && fp < NUM_FORCE_POWERS ) { saber->forceRestrictions |= (1<<fp); } continue; } //lockBonus if ( !Q_stricmp( token, "lockBonus" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->lockBonus = n; continue; } //parryBonus if ( !Q_stricmp( token, "parryBonus" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->parryBonus = n; continue; } //breakParryBonus if ( !Q_stricmp( token, "breakParryBonus" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->breakParryBonus = n; continue; } //disarmBonus if ( !Q_stricmp( token, "disarmBonus" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->disarmBonus = n; continue; } //single blade saber style if ( !Q_stricmp( token, "singleBladeStyle" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->singleBladeStyle = TranslateSaberStyle( value ); continue; } //single blade throwable if ( !Q_stricmp( token, "singleBladeThrowable" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->singleBladeThrowable = ((qboolean)(n!=0)); continue; } //broken replacement saber1 (right hand) if ( !Q_stricmp( token, "brokenSaber1" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } //saber->brokenSaber1 = G_NewString( value ); continue; } //broken replacement saber2 (left hand) if ( !Q_stricmp( token, "brokenSaber2" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } //saber->brokenSaber2 = G_NewString( value ); continue; } //spins and does damage on return from saberthrow if ( !Q_stricmp( token, "returnDamage" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->returnDamage = ((qboolean)(n!=0)); continue; } //stops the saber from drawing marks on the world (good for real-sword type mods) if ( !Q_stricmp( token, "noWallMarks" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->noWallMarks = ((qboolean)(n!=0)); continue; } //stops the saber from drawing a dynamic light (good for real-sword type mods) if ( !Q_stricmp( token, "noDlight" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->noDlight = ((qboolean)(n!=0)); continue; } //stops the saber from drawing a blade (good for real-sword type mods) if ( !Q_stricmp( token, "noBlade" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->noBlade = ((qboolean)(n!=0)); continue; } //default (0) is normal, 1 is a motion blur and 2 is no trail at all (good for real-sword type mods) if ( !Q_stricmp( token, "trailStyle" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->trailStyle = n; continue; } //if set, the game will use this shader for marks on enemies instead of the default "gfx/damage/saberglowmark" if ( !Q_stricmp( token, "g2MarksShader" ) ) { if ( COM_ParseString( &p, &value ) ) { SkipRestOfLine( &p ); continue; } #ifdef QAGAME//cgame-only cares about this #elif defined CGAME saber->g2MarksShader = trap_R_RegisterShader( value ); #endif continue; } //if non-zero, uses damage done to calculate an appropriate amount of knockback if ( !Q_stricmp( token, "knockbackScale" ) ) { if ( COM_ParseFloat( &p, &f ) ) { SkipRestOfLine( &p ); continue; } saber->knockbackScale = f; continue; } //scale up or down the damage done by the saber if ( !Q_stricmp( token, "damageScale" ) ) { if ( COM_ParseFloat( &p, &f ) ) { SkipRestOfLine( &p ); continue; } saber->damageScale = f; continue; } //if non-zero, the saber never does dismemberment (good for pointed/blunt melee weapons) if ( !Q_stricmp( token, "noDismemberment" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->noDismemberment = ((qboolean)(n!=0)); continue; } //if non-zero, the saber will not do damage or any effects when it is idle (not in an attack anim). (good for real-sword type mods) if ( !Q_stricmp( token, "noIdleEffect" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->noIdleEffect = ((qboolean)(n!=0)); continue; } //spin sound (when thrown) if ( !Q_stricmp( token, "spinSound" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->spinSound = BG_SoundIndex( (char *)value ); continue; } //swing sound - NOTE: must provide all 3!!! if ( !Q_stricmp( token, "swingSound1" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->swingSound[0] = BG_SoundIndex( (char *)value ); continue; } //swing sound - NOTE: must provide all 3!!! if ( !Q_stricmp( token, "swingSound2" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->swingSound[1] = BG_SoundIndex( (char *)value ); continue; } //swing sound - NOTE: must provide all 3!!! if ( !Q_stricmp( token, "swingSound3" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->swingSound[2] = BG_SoundIndex( (char *)value ); continue; } //hit sound - NOTE: must provide all 3!!! if ( !Q_stricmp( token, "hitSound1" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->hitSound[0] = BG_SoundIndex( (char *)value ); continue; } //hit sound - NOTE: must provide all 3!!! if ( !Q_stricmp( token, "hitSound2" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->hitSound[1] = BG_SoundIndex( (char *)value ); continue; } //hit sound - NOTE: must provide all 3!!! if ( !Q_stricmp( token, "hitSound3" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->hitSound[2] = BG_SoundIndex( (char *)value ); continue; } //block sound - NOTE: must provide all 3!!! if ( !Q_stricmp( token, "blockSound1" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->blockSound[0] = BG_SoundIndex( (char *)value ); continue; } //block sound - NOTE: must provide all 3!!! if ( !Q_stricmp( token, "blockSound2" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->blockSound[1] = BG_SoundIndex( (char *)value ); continue; } //block sound - NOTE: must provide all 3!!! if ( !Q_stricmp( token, "blockSound3" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } saber->blockSound[2] = BG_SoundIndex( (char *)value ); continue; } //block effect - when saber/sword hits another saber/sword if ( !Q_stricmp( token, "blockEffect" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } #ifdef QAGAME//cgame-only cares about this #elif defined CGAME saber->blockEffect = trap_FX_RegisterEffect( (char *)value ); #endif continue; } //hit person effect - when saber/sword hits a person if ( !Q_stricmp( token, "hitPersonEffect" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } #ifdef QAGAME//cgame-only cares about this #elif defined CGAME saber->hitPersonEffect = trap_FX_RegisterEffect( (char *)value ); #endif continue; } //hit other effect - when saber/sword hits sopmething else damagable if ( !Q_stricmp( token, "hitOtherEffect" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } #ifdef QAGAME//cgame-only cares about this #elif defined CGAME saber->hitOtherEffect = trap_FX_RegisterEffect( (char *)value ); #endif continue; } //if non-zero, the saber will not do the big, white clash flare with other sabers if ( !Q_stricmp( token, "noClashFlare" ) ) { if ( COM_ParseInt( &p, &n ) ) { SkipRestOfLine( &p ); continue; } saber->noClashFlare = ((qboolean)(n!=0)); continue; } if ( !Q_stricmp( token, "notInMP" ) ) {//ignore this SkipRestOfLine( &p ); continue; } //FIXME: saber sounds (on, off, loop) #ifdef _DEBUG Com_Printf( "WARNING: unknown keyword '%s' while parsing '%s'\n", token, useSaber ); #endif SkipRestOfLine( &p ); } //FIXME: precache the saberModel(s)? return qtrue; }
/* void NPC_Precache ( char *NPCName ) Precaches NPC skins, tgas and md3s. */ void NPC_Precache ( gentity_t *spawner ) { clientInfo_t ci={0}; renderInfo_t ri={0}; team_t playerTeam = TEAM_FREE; const char *token; const char *value; const char *p; char *patch; char sound[MAX_QPATH]; qboolean md3Model = qfalse; char playerModel[MAX_QPATH]; char customSkin[MAX_QPATH]; if ( !Q_stricmp( "random", spawner->NPC_type ) ) {//sorry, can't precache a random just yet return; } strcpy(customSkin,"default"); p = NPCParms; COM_BeginParseSession(); // look for the right NPC while ( p ) { token = COM_ParseExt( &p, qtrue ); if ( token[0] == 0 ) { return; } if ( !Q_stricmp( token, spawner->NPC_type ) ) { break; } SkipBracedSection( &p ); } if ( !p ) { return; } if ( G_ParseLiteral( &p, "{" ) ) { return; } // parse the NPC info block while ( 1 ) { token = COM_ParseExt( &p, qtrue ); if ( !token[0] ) { gi.Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s'\n", spawner->NPC_type ); return; } if ( !Q_stricmp( token, "}" ) ) { break; } // headmodel if ( !Q_stricmp( token, "headmodel" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } if(!Q_stricmp("none", value)) { } else { Q_strncpyz( ri.headModelName, value, sizeof(ri.headModelName), qtrue); } md3Model = qtrue; continue; } // torsomodel if ( !Q_stricmp( token, "torsomodel" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } if(!Q_stricmp("none", value)) { } else { Q_strncpyz( ri.torsoModelName, value, sizeof(ri.torsoModelName), qtrue); } md3Model = qtrue; continue; } // legsmodel if ( !Q_stricmp( token, "legsmodel" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } Q_strncpyz( ri.legsModelName, value, sizeof(ri.legsModelName), qtrue); md3Model = qtrue; continue; } // playerModel if ( !Q_stricmp( token, "playerModel" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } Q_strncpyz( playerModel, value, sizeof(playerModel), qtrue); md3Model = qfalse; continue; } // customSkin if ( !Q_stricmp( token, "customSkin" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } Q_strncpyz( customSkin, value, sizeof(customSkin), qtrue); continue; } // playerTeam if ( !Q_stricmp( token, "playerTeam" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } playerTeam = TranslateTeamName(value); continue; } // snd if ( !Q_stricmp( token, "snd" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } if ( !(spawner->svFlags&SVF_NO_BASIC_SOUNDS) ) { //FIXME: store this in some sound field or parse in the soundTable like the animTable... Q_strncpyz( sound, value, sizeof( sound ) ); patch = strstr( sound, "/" ); if ( patch ) { *patch = 0; } ci.customBasicSoundDir = G_NewString( sound ); } continue; } // sndcombat if ( !Q_stricmp( token, "sndcombat" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } if ( !(spawner->svFlags&SVF_NO_COMBAT_SOUNDS) ) { //FIXME: store this in some sound field or parse in the soundTable like the animTable... Q_strncpyz( sound, value, sizeof( sound ) ); patch = strstr( sound, "/" ); if ( patch ) { *patch = 0; } ci.customCombatSoundDir = G_NewString( sound ); } continue; } // sndextra if ( !Q_stricmp( token, "sndextra" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } if ( !(spawner->svFlags&SVF_NO_EXTRA_SOUNDS) ) { //FIXME: store this in some sound field or parse in the soundTable like the animTable... Q_strncpyz( sound, value, sizeof( sound ) ); patch = strstr( sound, "/" ); if ( patch ) { *patch = 0; } ci.customExtraSoundDir = G_NewString( sound ); } continue; } // sndjedi if ( !Q_stricmp( token, "sndjedi" ) ) { if ( COM_ParseString( &p, &value ) ) { continue; } if ( !(spawner->svFlags&SVF_NO_EXTRA_SOUNDS) ) { //FIXME: store this in some sound field or parse in the soundTable like the animTable... Q_strncpyz( sound, value, sizeof( sound ) ); patch = strstr( sound, "/" ); if ( patch ) { *patch = 0; } ci.customJediSoundDir = G_NewString( sound ); } continue; } } if ( md3Model ) { CG_RegisterClientRenderInfo( &ci, &ri ); } else { char skinName[MAX_QPATH]; //precache ghoul2 model gi.G2API_PrecacheGhoul2Model( va( "models/players/%s/model.glm", playerModel ) ); //precache skin Com_sprintf( skinName, sizeof( skinName ), "models/players/%s/model_%s.skin", playerModel, customSkin ); // lets see if it's out there gi.RE_RegisterSkin( skinName ); } //precache this NPC's possible weapons NPC_PrecacheWeapons( playerTeam, spawner->spawnflags, spawner->NPC_type ); CG_RegisterNPCCustomSounds( &ci ); CG_RegisterNPCEffects( playerTeam ); //FIXME: Look for a "sounds" directory and precache death, pain, alert sounds }
//void UI_SaberGetHiltInfo( const char *singleHilts[MAX_SABER_HILTS], const char *staffHilts[MAX_SABER_HILTS] ) void UI_SaberGetHiltInfo(void){ int numSingleHilts = 0, numStaffHilts = 0; const char *saberName; const char *token; const char *p; //go through all the loaded sabers and put the valid ones in the proper list p = SaberParms; COM_BeginParseSession("saberlist"); // look for a saber while ( p ) { token = COM_ParseExt( &p, qtrue ); if ( token[0] == 0 ) {//invalid name continue; } saberName = String_Alloc( token ); //see if there's a "{" on the next line SkipRestOfLine( &p ); if ( UI_ParseLiteralSilent( &p, "{" ) ) {//nope, not a name, keep looking continue; } //this is a saber name if ( !UI_SaberValidForPlayerInMP( saberName ) ) { SkipBracedSection( &p ); continue; } if ( UI_IsSaberTwoHanded( saberName ) ) { #ifndef DYNAMICMEMORY_SABERS if ( numStaffHilts < MAX_SABER_HILTS-1 )//-1 because we have to NULL terminate the list { staffHilts[numStaffHilts++] = saberName; } else { Com_Printf( "WARNING: too many two-handed sabers, ignoring saber '%s'\n", saberName ); } #else UI_ReaAllocMem((void *)&saberStaffHiltInfo, sizeof(char *), numStaffHilts+1); saberStaffHiltInfo[numStaffHilts++] = (char *) saberName; #endif } else { #ifndef DYNAMICMEMORY_SABERS if ( numSingleHilts < MAX_SABER_HILTS-1 )//-1 because we have to NULL terminate the list { singleHilts[numSingleHilts++] = saberName; } else { Com_Printf( "WARNING: too many one-handed sabers, ignoring saber '%s'\n", saberName ); } #else UI_ReaAllocMem((void *)&saberSingleHiltInfo, sizeof(char *), numSingleHilts+1); saberSingleHiltInfo[numSingleHilts++] = (char *) saberName; #endif } //skip the whole braced section and move on to the next entry SkipBracedSection( &p ); } //null terminate the list so the UI code knows where to stop listing them #ifndef DYNAMICMEMORY_SABERS singleHilts[numSingleHilts] = NULL; staffHilts[numStaffHilts] = NULL; #else saberSingleHiltCount = numSingleHilts; saberStaffHiltCount = numStaffHilts; #endif }
/* ============== G_Script_ScriptParse Parses the script for the given entity ============== */ void G_Script_ScriptParse(gentity_t *ent) { char *pScript; qboolean wantName; qboolean inScript; int eventNum; g_script_event_t events[G_MAX_SCRIPT_STACK_ITEMS]; int numEventItems; g_script_event_t *curEvent; char params[MAX_INFO_STRING]; g_script_stack_action_t *action; int i; int bracketLevel; qboolean buildScript; if (!ent->scriptName) { return; } if (!level.scriptEntity) { return; } buildScript = trap_Cvar_VariableIntegerValue("com_buildScript"); pScript = level.scriptEntity; wantName = qtrue; inScript = qfalse; COM_BeginParseSession("G_Script_ScriptParse"); bracketLevel = 0; numEventItems = 0; memset(events, 0, sizeof (events)); for (;;) { char *token; 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 = qtrue; } 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 = qtrue; numEventItems = 0; } wantName = qfalse; } 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 // Nico, added "create" & "delete" condition if (!Q_stricmp(action->actionString, "set") || !Q_stricmp(action->actionString, "create") || !Q_stricmp(action->actionString, "delete")) { token = COM_Parse(&pScript); if (token[0] != '{') { COM_ParseError("'{' expected, found: %s.\n", token); } while ((token = COM_Parse(&pScript)) != NULL && (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, qfalse); 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")) && strlen(token)) { trap_SendServerCommand(-1, va("addToBuild %s\n", token)); } } if ((i == 0 || i == 1) && !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, qfalse); } } 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] == '}' && !--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; } }
void NPC_PrecacheAnimationCFG( const char *NPC_type ) { char *token; char *value; char *p; int junk; if ( !Q_stricmp( "random", NPC_type ) ) {//sorry, can't precache a random just yet return; } p = NPCParms; COM_BeginParseSession(); // look for the right NPC while ( p ) { token = COM_ParseExt( &p, qtrue ); if ( token[0] == 0 ) return; if ( !Q_stricmp( token, NPC_type ) ) { break; } SkipBracedSection( &p ); } if ( !p ) { return; } if ( G_ParseLiteral( &p, "{" ) ) { return; } // parse the NPC info block while ( 1 ) { token = COM_ParseExt( &p, qtrue ); if ( !token[0] ) { gi.Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s'\n", NPC_type ); return; } if ( !Q_stricmp( token, "}" ) ) { break; } // legsmodel if ( !Q_stricmp( token, "legsmodel" ) ) { if ( G_ParseString( &p, &value ) ) { continue; } G_ParseAnimFileSet( value, &junk, qfalse ); return; } } }