void WP_SaberSetColor( gentity_t *ent, int saberNum, int bladeNum, char *colorName ) { if ( !ent || !ent->client ) { return; } ent->client->ps.saber[saberNum].blade[bladeNum].color = TranslateSaberColor( colorName ); }
void WP_SaberSetColor( saberInfo_t *sabers, int saberNum, int bladeNum, char *colorName ) { if ( !sabers ) { return; } sabers[saberNum].blade[bladeNum].color = TranslateSaberColor( colorName ); }
static void Svcmd_SaberColor_f() {//FIXME: just list the colors, each additional listing sets that blade int saberNum = atoi(gi.argv(1)); char *color[MAX_BLADES]; int bladeNum; for ( bladeNum = 0; bladeNum < MAX_BLADES; bladeNum++ ) { color[bladeNum] = gi.argv(2+bladeNum); } if ( !VALIDSTRING( color ) || saberNum < 1 || saberNum > 2 ) { gi.Printf( "Usage: saberColor <saberNum> <blade1 color> <blade2 color> ... <blade8 color> \n" ); gi.Printf( "valid saberNums: 1 or 2\n" ); gi.Printf( "valid colors: red, orange, yellow, green, blue, and purple\n" ); return; } saberNum--; gentity_t *self = G_GetSelfForPlayerCmd(); for ( bladeNum = 0; bladeNum < MAX_BLADES; bladeNum++ ) { if ( !color[bladeNum] || !color[bladeNum][0] ) { break; } else { self->client->ps.saber[saberNum].blade[bladeNum].color = TranslateSaberColor( color[bladeNum] ); } } if ( saberNum == 0 ) { gi.cvar_set( "g_saber_color", color[0] ); } else if ( saberNum == 1 ) { gi.cvar_set( "g_saber2_color", color[0] ); } }
void Pickup_Saber( gentity_t *self, qboolean hadSaber, qboolean saberSolo, char *saberType, char *saberColor ) { //G_RemoveWeaponModels( ent );//??? if ( Q_stricmp( "player", saberType ) == 0 ) {//"player" means use cvar info G_SetSabersFromCVars( self ); } else { saberInfo_t newSaber={0}; if ( WP_SaberParseParms( saberType, &newSaber ) ) {//successfully found a saber .sab entry to use //FIXME: what about dual sabers? int saberNum = 0; if ( saberSolo//only supposed to use this one saber when grab this pickup || newSaber.twoHanded //new saber is two-handed || (hadSaber && self->client->ps.saber[0].twoHanded) )//old saber is two-handed {//replace the old right-hand saber and remove the left hand one WP_RemoveSaber( self, 1 ); } else {//add it as a second saber saberNum = 1; } WP_SetSaber( self, saberNum, saberType ); WP_SaberInitBladeData( self ); if ( self->client->ps.saber[saberNum].style ) { self->client->ps.saberStylesKnown |= (1<<self->client->ps.saber[saberNum].style); } if ( saberColor != NULL ) {//NPC_targetname = saberColor saber_colors_t saber_color = TranslateSaberColor( saberColor ); for ( int bladeNum = 0; bladeNum < MAX_BLADES; bladeNum++ ) { self->client->ps.saber[saberNum].blade[bladeNum].color = saber_color; } } } WP_SaberFreeStrings(newSaber); } }
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; }
void UI_SaberDrawBlade( itemDef_t *item, char *saberName, int saberModel, saberType_t saberType, vec3_t origin, float curYaw, int bladeNum ) { char bladeColorString[MAX_QPATH]; vec3_t angles={0}; if ( item->flags&(ITF_ISANYSABER) && item->flags&(ITF_ISCHARACTER) ) { //it's bolted to a dude! angles[YAW] = curYaw; } else { angles[PITCH] = curYaw; angles[ROLL] = 90; } if ( saberModel >= item->ghoul2.size() ) {//uhh... invalid index! return; } if ( (item->flags&ITF_ISSABER) && saberModel < 2 ) { DC->getCVarString( "ui_saber_color", bladeColorString, sizeof(bladeColorString) ); } else//if ( item->flags&ITF_ISSABER2 ) - presumed { DC->getCVarString( "ui_saber2_color", bladeColorString, sizeof(bladeColorString) ); } saber_colors_t bladeColor = TranslateSaberColor( bladeColorString ); float bladeLength = UI_SaberBladeLengthForSaber( saberName, bladeNum ); float bladeRadius = UI_SaberBladeRadiusForSaber( saberName, bladeNum ); vec3_t bladeOrigin={0}; vec3_t axis[3]={0}; mdxaBone_t boltMatrix; qboolean tagHack = qfalse; char *tagName = va( "*blade%d", bladeNum+1 ); int bolt = DC->g2_AddBolt( &item->ghoul2[saberModel], tagName ); if ( bolt == -1 ) { tagHack = qtrue; //hmm, just fall back to the most basic tag (this will also make it work with pre-JKA saber models bolt = DC->g2_AddBolt( &item->ghoul2[saberModel], "*flash" ); if ( bolt == -1 ) {//no tag_flash either?!! bolt = 0; } } DC->g2_GetBoltMatrix( item->ghoul2, saberModel, bolt, &boltMatrix, angles, origin, uiInfo.uiDC.realTime, NULL, vec3_origin );//NULL was cgs.model_draw // work the matrix axis stuff into the original axis and origins used. DC->g2_GiveMeVectorFromMatrix(boltMatrix, ORIGIN, bladeOrigin); DC->g2_GiveMeVectorFromMatrix(boltMatrix, NEGATIVE_X, axis[0]);//front (was NEGATIVE_Y, but the md3->glm exporter screws up this tag somethin' awful) DC->g2_GiveMeVectorFromMatrix(boltMatrix, NEGATIVE_Y, axis[1]);//right DC->g2_GiveMeVectorFromMatrix(boltMatrix, POSITIVE_Z, axis[2]);//up float scale = DC->xscale; if ( tagHack ) { switch ( saberType ) { case SABER_SINGLE: case SABER_DAGGER: case SABER_LANCE: break; case SABER_STAFF: if ( bladeNum == 1 ) { VectorScale( axis[0], -1, axis[0] ); VectorMA( bladeOrigin, 16*scale, axis[0], bladeOrigin ); } break; case SABER_BROAD: if ( bladeNum == 0 ) { VectorMA( bladeOrigin, -1*scale, axis[1], bladeOrigin ); } else if ( bladeNum == 1 ) { VectorMA( bladeOrigin, 1*scale, axis[1], bladeOrigin ); } break; case SABER_PRONG: if ( bladeNum == 0 ) { VectorMA( bladeOrigin, -3*scale, axis[1], bladeOrigin ); } else if ( bladeNum == 1 ) { VectorMA( bladeOrigin, 3*scale, axis[1], bladeOrigin ); } break; case SABER_ARC: VectorSubtract( axis[1], axis[2], axis[1] ); VectorNormalize( axis[1] ); switch ( bladeNum ) { case 0: VectorMA( bladeOrigin, 8*scale, axis[0], bladeOrigin ); VectorScale( axis[0], 0.75f, axis[0] ); VectorScale( axis[1], 0.25f, axis[1] ); VectorAdd( axis[0], axis[1], axis[0] ); break; case 1: VectorScale( axis[0], 0.25f, axis[0] ); VectorScale( axis[1], 0.75f, axis[1] ); VectorAdd( axis[0], axis[1], axis[0] ); break; case 2: VectorMA( bladeOrigin, -8*scale, axis[0], bladeOrigin ); VectorScale( axis[0], -0.25f, axis[0] ); VectorScale( axis[1], 0.75f, axis[1] ); VectorAdd( axis[0], axis[1], axis[0] ); break; case 3: VectorMA( bladeOrigin, -16*scale, axis[0], bladeOrigin ); VectorScale( axis[0], -0.75f, axis[0] ); VectorScale( axis[1], 0.25f, axis[1] ); VectorAdd( axis[0], axis[1], axis[0] ); break; } break; case SABER_SAI: if ( bladeNum == 1 ) { VectorMA( bladeOrigin, -3*scale, axis[1], bladeOrigin ); } else if ( bladeNum == 2 ) { VectorMA( bladeOrigin, 3*scale, axis[1], bladeOrigin ); } break; case SABER_CLAW: switch ( bladeNum ) { case 0: VectorMA( bladeOrigin, 2*scale, axis[0], bladeOrigin ); VectorMA( bladeOrigin, 2*scale, axis[2], bladeOrigin ); break; case 1: VectorMA( bladeOrigin, 2*scale, axis[0], bladeOrigin ); VectorMA( bladeOrigin, 2*scale, axis[2], bladeOrigin ); VectorMA( bladeOrigin, 2*scale, axis[1], bladeOrigin ); break; case 2: VectorMA( bladeOrigin, 2*scale, axis[0], bladeOrigin ); VectorMA( bladeOrigin, 2*scale, axis[2], bladeOrigin ); VectorMA( bladeOrigin, -2*scale, axis[1], bladeOrigin ); break; } break; case SABER_STAR: switch ( bladeNum ) { case 0: VectorMA( bladeOrigin, 8*scale, axis[0], bladeOrigin ); break; case 1: VectorScale( axis[0], 0.33f, axis[0] ); VectorScale( axis[2], 0.67f, axis[2] ); VectorAdd( axis[0], axis[2], axis[0] ); VectorMA( bladeOrigin, 8*scale, axis[0], bladeOrigin ); break; case 2: VectorScale( axis[0], -0.33f, axis[0] ); VectorScale( axis[2], 0.67f, axis[2] ); VectorAdd( axis[0], axis[2], axis[0] ); VectorMA( bladeOrigin, 8*scale, axis[0], bladeOrigin ); break; case 3: VectorScale( axis[0], -1, axis[0] ); VectorMA( bladeOrigin, 8*scale, axis[0], bladeOrigin ); break; case 4: VectorScale( axis[0], -0.33f, axis[0] ); VectorScale( axis[2], -0.67f, axis[2] ); VectorAdd( axis[0], axis[2], axis[0] ); VectorMA( bladeOrigin, 8*scale, axis[0], bladeOrigin ); break; case 5: VectorScale( axis[0], 0.33f, axis[0] ); VectorScale( axis[2], -0.67f, axis[2] ); VectorAdd( axis[0], axis[2], axis[0] ); VectorMA( bladeOrigin, 8*scale, axis[0], bladeOrigin ); break; } break; case SABER_TRIDENT: switch ( bladeNum ) { case 0: VectorMA( bladeOrigin, 24*scale, axis[0], bladeOrigin ); break; case 1: VectorMA( bladeOrigin, -6*scale, axis[1], bladeOrigin ); VectorMA( bladeOrigin, 24*scale, axis[0], bladeOrigin ); break; case 2: VectorMA( bladeOrigin, 6*scale, axis[1], bladeOrigin ); VectorMA( bladeOrigin, 24*scale, axis[0], bladeOrigin ); break; case 3: VectorMA( bladeOrigin, -32*scale, axis[0], bladeOrigin ); VectorScale( axis[0], -1, axis[0] ); break; } break; case SABER_SITH_SWORD: //no blade break; } } if ( saberType == SABER_SITH_SWORD ) {//draw no blade return; } UI_DoSaber( bladeOrigin, axis[0], bladeLength, bladeLength, bladeRadius, bladeColor ); }
void UI_SaberDrawBlade( itemDef_t *item, char *saberName, int saberModel, saberType_t saberType, vec3_t origin, vec3_t angles, int bladeNum ) { char bladeColorString[MAX_QPATH]; saber_colors_t bladeColor; float bladeLength,bladeRadius; vec3_t bladeOrigin={0}; vec3_t axis[3]={0}; // vec3_t angles={0}; mdxaBone_t boltMatrix; qboolean tagHack = qfalse; char *tagName; int bolt; float scale; //[RGBSabers] int snum; //[/RGBSabers] if ( (item->flags&ITF_ISSABER) && saberModel < 2 ) { //[RGBSabers] snum = 0; trap_Cvar_VariableStringBuffer("ui_saber_color", bladeColorString, sizeof(bladeColorString) ); } else//if ( item->flags&ITF_ISSABER2 ) - presumed { snum = 1; //[/RGBSabers] trap_Cvar_VariableStringBuffer("ui_saber2_color", bladeColorString, sizeof(bladeColorString) ); } if ( !trap_G2API_HasGhoul2ModelOnIndex(&(item->ghoul2),saberModel) ) {//invalid index! return; } bladeColor = TranslateSaberColor( bladeColorString ); bladeLength = UI_SaberBladeLengthForSaber( saberName, bladeNum ); bladeRadius = UI_SaberBladeRadiusForSaber( saberName, bladeNum ); tagName = va( "*blade%d", bladeNum+1 ); bolt = trap_G2API_AddBolt( item->ghoul2,saberModel, tagName ); if ( bolt == -1 ) { tagHack = qtrue; //hmm, just fall back to the most basic tag (this will also make it work with pre-JKA saber models bolt = trap_G2API_AddBolt( item->ghoul2,saberModel, "*flash" ); if ( bolt == -1 ) {//no tag_flash either?!! bolt = 0; } } // angles[PITCH] = curYaw; // angles[ROLL] = 0; trap_G2API_GetBoltMatrix( item->ghoul2, saberModel, bolt, &boltMatrix, angles, origin, uiInfo.uiDC.realTime, NULL, vec3_origin );//NULL was cgs.model_draw // work the matrix axis stuff into the original axis and origins used. BG_GiveMeVectorFromMatrix(&boltMatrix, ORIGIN, bladeOrigin); BG_GiveMeVectorFromMatrix(&boltMatrix, NEGATIVE_Y, axis[0]);//front (was NEGATIVE_Y, but the md3->glm exporter screws up this tag somethin' awful) // ...changed this back to NEGATIVE_Y BG_GiveMeVectorFromMatrix(&boltMatrix, NEGATIVE_X, axis[1]);//right ... and changed this to NEGATIVE_X BG_GiveMeVectorFromMatrix(&boltMatrix, POSITIVE_Z, axis[2]);//up // Where do I get scale from? // scale = DC->xscale; scale = 1.0f; if ( tagHack ) { switch ( saberType ) { case SABER_SINGLE: VectorMA( bladeOrigin, scale, axis[0], bladeOrigin ); break; case SABER_DAGGER: case SABER_LANCE: break; case SABER_STAFF: if ( bladeNum == 0 ) { VectorMA( bladeOrigin, 12*scale, axis[0], bladeOrigin ); } if ( bladeNum == 1 ) { VectorScale( axis[0], -1, axis[0] ); VectorMA( bladeOrigin, 12*scale, axis[0], bladeOrigin ); } break; case SABER_BROAD: if ( bladeNum == 0 ) { VectorMA( bladeOrigin, -1*scale, axis[1], bladeOrigin ); } else if ( bladeNum == 1 ) { VectorMA( bladeOrigin, 1*scale, axis[1], bladeOrigin ); } break; case SABER_PRONG: if ( bladeNum == 0 ) { VectorMA( bladeOrigin, -3*scale, axis[1], bladeOrigin ); } else if ( bladeNum == 1 ) { VectorMA( bladeOrigin, 3*scale, axis[1], bladeOrigin ); } break; case SABER_ARC: VectorSubtract( axis[1], axis[2], axis[1] ); VectorNormalize( axis[1] ); switch ( bladeNum ) { case 0: VectorMA( bladeOrigin, 8*scale, axis[0], bladeOrigin ); VectorScale( axis[0], 0.75f, axis[0] ); VectorScale( axis[1], 0.25f, axis[1] ); VectorAdd( axis[0], axis[1], axis[0] ); break; case 1: VectorScale( axis[0], 0.25f, axis[0] ); VectorScale( axis[1], 0.75f, axis[1] ); VectorAdd( axis[0], axis[1], axis[0] ); break; case 2: VectorMA( bladeOrigin, -8*scale, axis[0], bladeOrigin ); VectorScale( axis[0], -0.25f, axis[0] ); VectorScale( axis[1], 0.75f, axis[1] ); VectorAdd( axis[0], axis[1], axis[0] ); break; case 3: VectorMA( bladeOrigin, -16*scale, axis[0], bladeOrigin ); VectorScale( axis[0], -0.75f, axis[0] ); VectorScale( axis[1], 0.25f, axis[1] ); VectorAdd( axis[0], axis[1], axis[0] ); break; } break; case SABER_SAI: if ( bladeNum == 1 ) { VectorMA( bladeOrigin, -3*scale, axis[1], bladeOrigin ); } else if ( bladeNum == 2 ) { VectorMA( bladeOrigin, 3*scale, axis[1], bladeOrigin ); } break; case SABER_CLAW: switch ( bladeNum ) { case 0: VectorMA( bladeOrigin, 2*scale, axis[0], bladeOrigin ); VectorMA( bladeOrigin, 2*scale, axis[2], bladeOrigin ); break; case 1: VectorMA( bladeOrigin, 2*scale, axis[0], bladeOrigin ); VectorMA( bladeOrigin, 2*scale, axis[2], bladeOrigin ); VectorMA( bladeOrigin, 2*scale, axis[1], bladeOrigin ); break; case 2: VectorMA( bladeOrigin, 2*scale, axis[0], bladeOrigin ); VectorMA( bladeOrigin, 2*scale, axis[2], bladeOrigin ); VectorMA( bladeOrigin, -2*scale, axis[1], bladeOrigin ); break; } break; case SABER_STAR: switch ( bladeNum ) { case 0: VectorMA( bladeOrigin, 8*scale, axis[0], bladeOrigin ); break; case 1: VectorScale( axis[0], 0.33f, axis[0] ); VectorScale( axis[2], 0.67f, axis[2] ); VectorAdd( axis[0], axis[2], axis[0] ); VectorMA( bladeOrigin, 8*scale, axis[0], bladeOrigin ); break; case 2: VectorScale( axis[0], -0.33f, axis[0] ); VectorScale( axis[2], 0.67f, axis[2] ); VectorAdd( axis[0], axis[2], axis[0] ); VectorMA( bladeOrigin, 8*scale, axis[0], bladeOrigin ); break; case 3: VectorScale( axis[0], -1, axis[0] ); VectorMA( bladeOrigin, 8*scale, axis[0], bladeOrigin ); break; case 4: VectorScale( axis[0], -0.33f, axis[0] ); VectorScale( axis[2], -0.67f, axis[2] ); VectorAdd( axis[0], axis[2], axis[0] ); VectorMA( bladeOrigin, 8*scale, axis[0], bladeOrigin ); break; case 5: VectorScale( axis[0], 0.33f, axis[0] ); VectorScale( axis[2], -0.67f, axis[2] ); VectorAdd( axis[0], axis[2], axis[0] ); VectorMA( bladeOrigin, 8*scale, axis[0], bladeOrigin ); break; } break; case SABER_TRIDENT: switch ( bladeNum ) { case 0: VectorMA( bladeOrigin, 24*scale, axis[0], bladeOrigin ); break; case 1: VectorMA( bladeOrigin, -6*scale, axis[1], bladeOrigin ); VectorMA( bladeOrigin, 24*scale, axis[0], bladeOrigin ); break; case 2: VectorMA( bladeOrigin, 6*scale, axis[1], bladeOrigin ); VectorMA( bladeOrigin, 24*scale, axis[0], bladeOrigin ); break; case 3: VectorMA( bladeOrigin, -32*scale, axis[0], bladeOrigin ); VectorScale( axis[0], -1, axis[0] ); break; } break; case SABER_SITH_SWORD: //no blade break; } } if ( saberType == SABER_SITH_SWORD ) {//draw no blade return; } //[RGBSabers] UI_DoSaber( bladeOrigin, axis[0], bladeLength, bladeLength, bladeRadius, bladeColor, snum ); //[/RGBSabers] }
qboolean Pickup_Saber( gentity_t *self, qboolean hadSaber, gentity_t *pickUpSaber ) { //NOTE: loopAnim = saberSolo, alt_fire = saberLeftHand, NPC_type = saberType, NPC_targetname = saberColor qboolean foundIt = qfalse; if ( !pickUpSaber || !self || !self->client ) { return qfalse; } //G_RemoveWeaponModels( ent );//??? if ( Q_stricmp( "player", pickUpSaber->NPC_type ) == 0 ) {//"player" means use cvar info G_SetSabersFromCVars( self ); foundIt = qtrue; } else { saberInfo_t newSaber={0}; qboolean swapSabers = qfalse; if ( self->client->ps.weapon == WP_SABER && self->client->ps.weaponTime > 0 ) {//can't pick up a new saber while the old one is busy (also helps to work as a debouncer so you don't swap out sabers rapidly when touching more than one at a time) return qfalse; } if ( pickUpSaber->count == 1 && g_saberPickuppableDroppedSabers->integer ) { swapSabers = qtrue; } if ( WP_SaberParseParms( pickUpSaber->NPC_type, &newSaber ) ) {//successfully found a saber .sab entry to use int saberNum = 0; qboolean removeLeftSaber = qfalse; if ( pickUpSaber->alt_fire ) {//always go in the left hand if ( !hadSaber ) {//can't have a saber only in your left hand! return qfalse; } saberNum = 1; //just in case... removeLeftSaber = qtrue; } else if ( !hadSaber ) {//don't have a saber at all yet, put it in our right hand saberNum = 0; //just in case... removeLeftSaber = qtrue; } else if ( pickUpSaber->loopAnim//only supposed to use this one saber when grab this pickup || (newSaber.saberFlags&SFL_TWO_HANDED) //new saber is two-handed || (hadSaber && (self->client->ps.saber[0].saberFlags&SFL_TWO_HANDED)) )//old saber is two-handed {//replace the old right-hand saber and remove the left hand one saberNum = 0; removeLeftSaber = qtrue; } else {//have, at least, a saber in our right hand and the new one could go in either left or right hand if ( self->client->ps.dualSabers ) {//I already have 2 sabers vec3_t dir2Saber, rightDir; //to determine which one to replace, see which side of me it's on VectorSubtract( pickUpSaber->currentOrigin, self->currentOrigin, dir2Saber ); dir2Saber[2] = 0; AngleVectors( self->currentAngles, NULL, rightDir, NULL ); rightDir[2] = 0; if ( DotProduct( rightDir, dir2Saber ) > 0 ) { saberNum = 0; } else { saberNum = 1; //just in case... removeLeftSaber = qtrue; } } else {//just add it as a second saber saberNum = 1; //just in case... removeLeftSaber = qtrue; } } if ( saberNum == 0 ) {//want to reach out with right hand if ( self->client->ps.torsoAnim == BOTH_BUTTON_HOLD ) {//but only if already playing the pickup with left hand anim... NPC_SetAnim( self, SETANIM_TORSO, BOTH_SABERPULL, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD ); } if ( swapSabers ) {//drop first one where the one we're picking up is G_DropSaberItem( self->client->ps.saber[saberNum].name, self->client->ps.saber[saberNum].blade[0].color, pickUpSaber->currentOrigin, (float *)vec3_origin, pickUpSaber->currentAngles, pickUpSaber ); if ( removeLeftSaber ) {//drop other one at my origin G_DropSaberItem( self->client->ps.saber[1].name, self->client->ps.saber[1].blade[0].color, self->currentOrigin, (float *)vec3_origin, self->currentAngles, pickUpSaber ); } } } else { if ( swapSabers ) { G_DropSaberItem( self->client->ps.saber[saberNum].name, self->client->ps.saber[saberNum].blade[0].color, pickUpSaber->currentOrigin, (float *)vec3_origin, pickUpSaber->currentAngles, pickUpSaber ); } } if ( removeLeftSaber ) { WP_RemoveSaber( self, 1 ); } WP_SetSaber( self, saberNum, pickUpSaber->NPC_type ); WP_SaberInitBladeData( self ); if ( self->client->ps.saber[saberNum].stylesLearned ) { self->client->ps.saberStylesKnown |= self->client->ps.saber[saberNum].stylesLearned; } if ( self->client->ps.saber[saberNum].singleBladeStyle ) { self->client->ps.saberStylesKnown |= self->client->ps.saber[saberNum].singleBladeStyle; } if ( pickUpSaber->NPC_targetname != NULL ) {//NPC_targetname = saberColor saber_colors_t saber_color = TranslateSaberColor( pickUpSaber->NPC_targetname ); for ( int bladeNum = 0; bladeNum < MAX_BLADES; bladeNum++ ) { self->client->ps.saber[saberNum].blade[bladeNum].color = saber_color; } } if ( self->client->ps.torsoAnim == BOTH_BUTTON_HOLD || self->client->ps.torsoAnim == BOTH_SABERPULL ) {//don't let them attack right away, force them to finish the anim self->client->ps.weaponTime = self->client->ps.torsoAnimTimer; } foundIt = qtrue; } WP_SaberFreeStrings(newSaber); } return foundIt; }
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; }
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 UI_SaberDrawBlade( itemDef_t *item, char *saberName, int saberModel, saberType_t saberType, vector3 *origin, vector3 *angles, int bladeNum ) { vector3 org_, end, axis_[3] = { { 0.0f } }; // shut the compiler up mdxaBone_t boltMatrix; effectTrailArgStruct_t fx; saber_colors_t bladeColor; float bladeLength, bladeRadius; char bladeColorString[MAX_QPATH]; int snum; const char *tagName; int bolt; qboolean tagHack = qfalse; int styleToUse = atoi( UI_Cvar_VariableString( "cg_saberBladeStyle" ) ); if ( (item->flags&ITF_ISSABER) && saberModel < 2 ) { snum = 0; trap->Cvar_VariableStringBuffer( "ui_saber_color", bladeColorString, sizeof(bladeColorString) ); } else//if ( item->flags&ITF_ISSABER2 ) - presumed { snum = 1; trap->Cvar_VariableStringBuffer( "ui_saber2_color", bladeColorString, sizeof(bladeColorString) ); } if ( !trap->G2API_HasGhoul2ModelOnIndex( &(item->ghoul2), saberModel ) ) {//invalid index! return; } bladeColor = TranslateSaberColor( bladeColorString ); bladeLength = UI_SaberBladeLengthForSaber( saberName, bladeNum ); bladeRadius = UI_SaberBladeRadiusForSaber( saberName, bladeNum ); tagName = va( "*blade%d", bladeNum + 1 ); bolt = trap->G2API_AddBolt( item->ghoul2, saberModel, tagName ); if ( bolt == -1 ) { tagHack = qtrue; //hmm, just fall back to the most basic tag (this will also make it work with pre-JKA saber models bolt = trap->G2API_AddBolt( item->ghoul2, saberModel, "*flash" ); if ( bolt == -1 ) {//no tag_flash either?!! bolt = 0; } } // angles.pitch = curYaw; // angles.roll = 0; trap->G2API_GetBoltMatrix( item->ghoul2, saberModel, bolt, &boltMatrix, angles, origin, uiInfo.uiDC.realTime, NULL, &vec3_origin );//NULL was cgs.model_draw // work the matrix axis stuff into the original axis and origins used. BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, &org_ ); BG_GiveMeVectorFromMatrix( &boltMatrix, NEGATIVE_Y, &axis_[0] );//front (was NEGATIVE_Y, but the md3->glm exporter screws up this tag somethin' awful) // ...changed this back to NEGATIVE_Y BG_GiveMeVectorFromMatrix( &boltMatrix, NEGATIVE_X, &axis_[1] );//right ... and changed this to NEGATIVE_X BG_GiveMeVectorFromMatrix( &boltMatrix, POSITIVE_Z, &axis_[2] );//up VectorMA( &org_, bladeLength, &axis_[0], &end ); VectorAdd( &end, &axis_[0], &end ); if ( tagHack ) { switch ( saberType ) { default: case SABER_SINGLE: VectorMA( &org_, 1.0f, &axis_[0], &org_ ); break; case SABER_DAGGER: case SABER_LANCE: break; case SABER_STAFF: if ( bladeNum == 0 ) VectorMA( &org_, 12 * 1.0f, &axis_[0], &org_ ); if ( bladeNum == 1 ) { VectorScale( &axis_[0], -1, &axis_[0] ); VectorMA( &org_, 12 * 1.0f, &axis_[0], &org_ ); } break; case SABER_BROAD: if ( bladeNum == 0 ) VectorMA( &org_, -1 * 1.0f, &axis_[1], &org_ ); else if ( bladeNum == 1 ) VectorMA( &org_, 1 * 1.0f, &axis_[1], &org_ ); break; case SABER_PRONG: if ( bladeNum == 0 ) VectorMA( &org_, -3 * 1.0f, &axis_[1], &org_ ); else if ( bladeNum == 1 ) VectorMA( &org_, 3 * 1.0f, &axis_[1], &org_ ); break; case SABER_ARC: VectorSubtract( &axis_[1], &axis_[2], &axis_[1] ); VectorNormalize( &axis_[1] ); switch ( bladeNum ) { case 0: VectorMA( &org_, 8 * 1.0f, &axis_[0], &org_ ); VectorScale( &axis_[0], 0.75f, &axis_[0] ); VectorScale( &axis_[1], 0.25f, &axis_[1] ); VectorAdd( &axis_[0], &axis_[1], &axis_[0] ); break; case 1: VectorScale( &axis_[0], 0.25f, &axis_[0] ); VectorScale( &axis_[1], 0.75f, &axis_[1] ); VectorAdd( &axis_[0], &axis_[1], &axis_[0] ); break; case 2: VectorMA( &org_, -8 * 1.0f, &axis_[0], &org_ ); VectorScale( &axis_[0], -0.25f, &axis_[0] ); VectorScale( &axis_[1], 0.75f, &axis_[1] ); VectorAdd( &axis_[0], &axis_[1], &axis_[0] ); break; case 3: VectorMA( &org_, -16 * 1.0f, &axis_[0], &org_ ); VectorScale( &axis_[0], -0.75f, &axis_[0] ); VectorScale( &axis_[1], 0.25f, &axis_[1] ); VectorAdd( &axis_[0], &axis_[1], &axis_[0] ); break; default: break; } break; case SABER_SAI: if ( bladeNum == 1 ) VectorMA( &org_, -3 * 1.0f, &axis_[1], &org_ ); else if ( bladeNum == 2 ) VectorMA( &org_, 3 * 1.0f, &axis_[1], &org_ ); break; case SABER_CLAW: switch ( bladeNum ) { case 0: VectorMA( &org_, 2 * 1.0f, &axis_[0], &org_ ); VectorMA( &org_, 2 * 1.0f, &axis_[2], &org_ ); break; case 1: VectorMA( &org_, 2 * 1.0f, &axis_[0], &org_ ); VectorMA( &org_, 2 * 1.0f, &axis_[2], &org_ ); VectorMA( &org_, 2 * 1.0f, &axis_[1], &org_ ); break; case 2: VectorMA( &org_, 2 * 1.0f, &axis_[0], &org_ ); VectorMA( &org_, 2 * 1.0f, &axis_[2], &org_ ); VectorMA( &org_, -2 * 1.0f, &axis_[1], &org_ ); break; default: break; } break; case SABER_STAR: switch ( bladeNum ) { case 0: VectorMA( &org_, 8 * 1.0f, &axis_[0], &org_ ); break; case 1: VectorScale( &axis_[0], 0.33f, &axis_[0] ); VectorScale( &axis_[2], 0.67f, &axis_[2] ); VectorAdd( &axis_[0], &axis_[2], &axis_[0] ); VectorMA( &org_, 8 * 1.0f, &axis_[0], &org_ ); break; case 2: VectorScale( &axis_[0], -0.33f, &axis_[0] ); VectorScale( &axis_[2], 0.67f, &axis_[2] ); VectorAdd( &axis_[0], &axis_[2], &axis_[0] ); VectorMA( &org_, 8 * 1.0f, &axis_[0], &org_ ); break; case 3: VectorScale( &axis_[0], -1, &axis_[0] ); VectorMA( &org_, 8 * 1.0f, &axis_[0], &org_ ); break; case 4: VectorScale( &axis_[0], -0.33f, &axis_[0] ); VectorScale( &axis_[2], -0.67f, &axis_[2] ); VectorAdd( &axis_[0], &axis_[2], &axis_[0] ); VectorMA( &org_, 8 * 1.0f, &axis_[0], &org_ ); break; case 5: VectorScale( &axis_[0], 0.33f, &axis_[0] ); VectorScale( &axis_[2], -0.67f, &axis_[2] ); VectorAdd( &axis_[0], &axis_[2], &axis_[0] ); VectorMA( &org_, 8 * 1.0f, &axis_[0], &org_ ); break; default: break; } break; case SABER_TRIDENT: switch ( bladeNum ) { case 0: VectorMA( &org_, 24 * 1.0f, &axis_[0], &org_ ); break; case 1: VectorMA( &org_, -6 * 1.0f, &axis_[1], &org_ ); VectorMA( &org_, 24 * 1.0f, &axis_[0], &org_ ); break; case 2: VectorMA( &org_, 6 * 1.0f, &axis_[1], &org_ ); VectorMA( &org_, 24 * 1.0f, &axis_[0], &org_ ); break; case 3: VectorMA( &org_, -32 * 1.0f, &axis_[0], &org_ ); VectorScale( &axis_[0], -1, &axis_[0] ); break; default: break; } break; case SABER_SITH_SWORD: //no blade break; } } VectorCopy( &org_, &fx.mVerts[0].origin ); VectorMA( &end, 3.0f, &axis_[0], &fx.mVerts[1].origin ); VectorCopy( &end, &fx.mVerts[2].origin ); VectorMA( &org_, 3.0f, &axis_[0], &fx.mVerts[3].origin ); //Raz: Temporarily switch to basejka sabers for flame and electric users if ( bladeColor == SABER_FLAME1 || bladeColor == SABER_ELEC1 || bladeColor == SABER_FLAME2 || bladeColor == SABER_ELEC2 || bladeColor == SABER_BLACK ) styleToUse = 0; // Pass in the renderfx flags attached to the saber weapon model...this is done so that saber glows // will get rendered properly in a mirror...not sure if this is necessary?? //CG_DoSaber( org_, axis_[0], saberLen, client->saber[saberNum].blade[bladeNum].lengthMax, client->saber[saberNum].blade[bladeNum].radius, // scolor, renderfx, (qboolean)(saberNum==0&&bladeNum==0) ); switch ( styleToUse ) { case 0: UI_DoSaber( &org_, &axis_[0], bladeLength, bladeLength, bladeRadius, bladeColor, 0, qfalse, 0, snum ); break; /* case 1: UI_DoEp1Saber( fx.mVerts[0].origin, fx.mVerts[1].origin, fx.mVerts[2].origin, fx.mVerts[3].origin, bladeLength, bladeRadius, bladeColor, 0, false, false, 0, snum ); break; case 2: UI_DoEp2Saber( fx.mVerts[0].origin, fx.mVerts[1].origin, fx.mVerts[2].origin, fx.mVerts[3].origin, bladeLength, bladeRadius, bladeColor, 0, false, false, 0, snum ); break; case 3: UI_DoEp3Saber( fx.mVerts[0].origin, fx.mVerts[1].origin, fx.mVerts[2].origin, fx.mVerts[3].origin, bladeLength, bladeRadius, bladeColor, 0, false, false, 0, snum ); break; */ default: case 1: UI_DoSFXSaber( &fx.mVerts[0].origin, &fx.mVerts[1].origin, &fx.mVerts[2].origin, &fx.mVerts[3].origin, bladeLength, bladeRadius, bladeColor, 0, qfalse, qfalse, 0, snum ); break; /* case 5: UI_DoOTSaber( fx.mVerts[0].origin, fx.mVerts[1].origin, fx.mVerts[2].origin, fx.mVerts[3].origin, bladeLength, bladeRadius, bladeColor, 0, false, false, 0, snum ); break; */ } }