codemp/game/NPC_stats.c File Reference

#include "b_local.h"
#include "b_public.h"
#include "anims.h"
#include "../ghoul2/G2.h"
#include "../namespace_begin.h"
#include "../namespace_end.h"

Go to the source code of this file.

Defines

#define stringIDExpand(str, strEnum)   str, strEnum, ENUM2STRING(strEnum)
#define MAX_NPC_DATA_SIZE   0x20000

Functions

qboolean WP_SaberParseParms (const char *SaberName, saberInfo_t *saber)
void WP_RemoveSaber (saberInfo_t *sabers, int saberNum)
int NPC_ReactionTime (void)
qboolean BG_ParseLiteral (const char **data, const char *string)
saber_colors_t TranslateSaberColor (const char *name)
qboolean G_ParseAnimFileSet (const char *filename, const char *animCFG, int *animFileIndex)
void NPC_PrecacheAnimationCFG (const char *NPC_type)
int NPC_WeaponsForTeam (team_t team, int spawnflags, const char *NPC_type)
void NPC_PrecacheWeapons (team_t playerTeam, int spawnflags, char *NPCtype)
void NPC_Precache (gentity_t *spawner)
void SetupGameGhoul2Model (gentity_t *ent, char *modelname, char *skinName)
qboolean NPC_ParseParms (const char *NPCName, gentity_t *NPC)
void NPC_LoadParms (void)

Variables

qboolean NPCsPrecached
stringID_table_t TeamTable []
stringID_table_t ClassTable []
stringID_table_t BSTable []
stringID_table_t BSETTable []
stringID_table_t WPTable []
stringID_table_t FPTable []
char * TeamNames [TEAM_NUM_TEAMS]
char * ClassNames [CLASS_NUM_CLASSES]
char NPCParms [MAX_NPC_DATA_SIZE]
char NPCFile [MAX_QPATH]
char npcParseBuffer [MAX_NPC_DATA_SIZE]


Define Documentation

#define MAX_NPC_DATA_SIZE   0x20000
 

Definition at line 236 of file NPC_stats.c.

Referenced by NPC_LoadParms().

#define stringIDExpand str,
strEnum   )     str, strEnum, ENUM2STRING(strEnum)
 

Definition at line 104 of file NPC_stats.c.


Function Documentation

qboolean BG_ParseLiteral const char **  data,
const char *  string
 

Definition at line 129 of file bg_saberLoad.c.

References COM_ParseExt(), Com_Printf(), Q_stricmp(), qboolean, qfalse, and qtrue.

Referenced by NPC_ParseParms(), NPC_Precache(), NPC_PrecacheAnimationCFG(), WP_SaberParseParm(), and WP_SaberParseParms().

00130 {
00131         const char      *token;
00132 
00133         token = COM_ParseExt( data, qtrue );
00134         if ( token[0] == 0 ) 
00135         {
00136                 Com_Printf( "unexpected EOF\n" );
00137                 return qtrue;
00138         }
00139 
00140         if ( Q_stricmp( token, string ) ) 
00141         {
00142                 Com_Printf( "required string '%s' missing\n", string );
00143                 return qtrue;
00144         }
00145 
00146         return qfalse;
00147 }

qboolean G_ParseAnimFileSet const char *  filename,
const char *  animCFG,
int *  animFileIndex
 

Definition at line 424 of file NPC_stats.c.

References BG_ParseAnimationFile(), NULL, qboolean, qfalse, and qtrue.

Referenced by NPC_PrecacheAnimationCFG().

00425 {
00426         *animFileIndex = BG_ParseAnimationFile(filename, NULL, qfalse);
00427         //if it's humanoid we should have it cached and return it, if it is not it will be loaded (unless it's also cached already)
00428 
00429         if (*animFileIndex == -1)
00430         {
00431                 return qfalse;
00432         }
00433 
00434         //I guess this isn't really even needed game-side.
00435         //BG_ParseAnimationSndFile(filename, *animFileIndex);
00436         return qtrue;
00437 }

void NPC_LoadParms void   ) 
 

Definition at line 3241 of file NPC_stats.c.

References COM_Compress(), Com_Printf(), fileHandle_t, FS_READ, G_Error(), MAX_NPC_DATA_SIZE, NPCParms, npcParseBuffer, NULL, qfalse, strcat(), strlen(), trap_FS_FCloseFile(), trap_FS_FOpenFile(), trap_FS_GetFileList(), trap_FS_Read(), and va().

Referenced by NPC_InitGame().

03242 {
03243         int                     len, totallen, npcExtFNLen, mainBlockLen, fileCnt, i;
03244 //      const char      *filename = "ext_data/NPC2.cfg";
03245         char             *holdChar, *marker;
03246         char            npcExtensionListBuf[2048];                      //      The list of file names read in
03247         fileHandle_t f;
03248         len = 0;
03249 
03250         //remember where to store the next one
03251         totallen = mainBlockLen = len;
03252         marker = NPCParms+totallen;
03253         *marker = 0;
03254 
03255         //now load in the extra .npc extensions
03256         fileCnt = trap_FS_GetFileList("ext_data/NPCs", ".npc", npcExtensionListBuf, sizeof(npcExtensionListBuf) );
03257 
03258 #ifdef _XBOX
03259         npcParseBuffer = (char *) Z_Malloc(MAX_NPC_DATA_SIZE, TAG_TEMP_WORKSPACE, qfalse, 4);
03260 #endif
03261 
03262         holdChar = npcExtensionListBuf;
03263         for ( i = 0; i < fileCnt; i++, holdChar += npcExtFNLen + 1 ) 
03264         {
03265                 npcExtFNLen = strlen( holdChar );
03266 
03267 //              Com_Printf( "Parsing %s\n", holdChar );
03268 
03269                 len = trap_FS_FOpenFile(va( "ext_data/NPCs/%s", holdChar), &f, FS_READ);
03270 
03271                 if ( len == -1 ) 
03272                 {
03273                         Com_Printf( "error reading file\n" );
03274                 }
03275                 else
03276                 {
03277                         if ( totallen + len >= MAX_NPC_DATA_SIZE ) {
03278                                 G_Error( "NPC extensions (*.npc) are too large" );
03279                         }
03280                         trap_FS_Read(npcParseBuffer, len, f);
03281                         npcParseBuffer[len] = 0;
03282 
03283                         len = COM_Compress( npcParseBuffer );
03284 
03285                         strcat( marker, npcParseBuffer );
03286                         strcat(marker, "\n");
03287                         len++;
03288                         trap_FS_FCloseFile(f);
03289 
03290                         totallen += len;
03291                         marker = NPCParms+totallen;
03292                         //*marker = 0; //rww - make sure this is null or strcat will not append to the correct place
03293                         //rww  12/19/02-actually the probelm was npcParseBuffer not being nul-term'd, which could cause issues in the strcat too
03294                 }
03295         }
03296 
03297 #ifdef _XBOX
03298         Z_Free(npcParseBuffer);
03299         npcParseBuffer = NULL;
03300 #endif
03301 
03302 }

qboolean NPC_ParseParms const char *  NPCName,
gentity_t NPC
 

*WP_BLASTER_PISTOL*/WP_SABER ) //?!

Definition at line 974 of file NPC_stats.c.

References gNPCstats_e::acceleration, gNPCstats_e::aggression, gNPCstats_e::aim, playerState_s::ammo, atoi(), BG_ParseLiteral(), BG_TempAlloc(), BG_TempFree(), saberInfo_t::blade, bState_t, class_t, CLASS_VEHICLE, ClassTable, gentity_s::client, bladeInfo_t::color, COM_BeginParseSession(), COM_ParseExt(), COM_ParseFloat(), COM_ParseInt(), COM_ParseString(), Com_Printf(), Com_sprintf(), CROUCH_MAXS_2, playerState_s::crouchheight, entityShared_t::currentOrigin, playerState_s::customRGBA, DEFAULT_MAXS_2, DEFAULT_MINS_2, gNPC_t::defaultBehavior, gNPCstats_e::earshot, EF2_FLYING, playerState_s::eFlags2, gclient_s::enemyTeam, gNPCstats_e::evasion, playerState_s::fd, forcedata_s::forcePowerLevel, forcedata_s::forcePowerMax, forcedata_s::forcePowersKnown, FP_FIRST, FPTable, gentity_s::fullName, G_ModelIndex(), G_NewString(), G_SetOrigin(), gentity_t, GetIDForString(), gNPCstats_t, renderInfo_s::headPitchRangeDown, renderInfo_s::headPitchRangeUp, renderInfo_s::headYawRangeLeft, renderInfo_s::headYawRangeRight, gNPCstats_e::health, gNPCstats_e::hfov, playerState_s::iModelScale, gNPCstats_e::intelligence, bladeInfo_t::lengthMax, gentity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, MAX_BLADES, MAX_QPATH, clientPersistant_t::maxHealth, entityShared_t::maxs, memset(), entityShared_t::mins, gentity_s::modelScale, gNPCstats_e::move, gentity_s::NPC, NPC, entityState_s::NPC_class, gclient_s::NPC_class, NPC_Precache(), gentity_s::NPC_type, NPCFile, NPCParms, entityState_s::npcSaber1, entityState_s::npcSaber2, NULL, NUM_BSTATES, NUM_FORCE_POWERS, entityState_s::number, playerState_s::origin, entityState_s::origin, gclient_s::pers, playerMaxs, playerMins, gclient_s::playerTeam, gclient_s::ps, Q_irand(), Q_strcat(), Q_stricmp(), Q_strncpyz(), qboolean, qfalse, qtrue, gentity_s::r, bladeInfo_t::radius, gentity_s::radius, gNPC_t::rank, gNPCstats_e::reactions, gclient_s::renderInfo, renderInfo_t, gNPCstats_e::runSpeed, gentity_s::s, S_COLOR_RED, S_COLOR_YELLOW, gclient_s::saber, saber_colors_t, forcedata_s::saberAnimLevel, saberInfo_t::saberFlags, SCF_ALT_FIRE, gNPC_t::scriptFlags, SetupGameGhoul2Model(), SFL_TWO_HANDED, gNPCstats_e::shootDistance, SkipBracedSection(), SkipRestOfLine(), playerState_s::standheight, STAT_MAX_HEALTH, STAT_WEAPONS, playerState_s::stats, gNPC_t::stats, strcpy(), strstr(), SVF_NO_BASIC_SOUNDS, SVF_NO_COMBAT_SOUNDS, SVF_NO_EXTRA_SOUNDS, entityShared_t::svFlags, team_t, entityState_s::teamowner, TeamTable, renderInfo_s::torsoPitchRangeDown, renderInfo_s::torsoPitchRangeUp, renderInfo_s::torsoYawRangeLeft, renderInfo_s::torsoYawRangeRight, TranslateSaberColor(), trap_LinkEntity(), vehicleInfo_t::type, va(), vec3_t, VectorCopy, VectorSet, gNPCstats_e::vfov, VH_FIGHTER, gNPCstats_e::vigilance, gNPCstats_e::visrange, gNPCstats_e::walkSpeed, playerState_s::weapon, weaponData, WP_NONE, WP_NUM_WEAPONS, WP_RemoveSaber(), WP_SaberParseParms(), WPTable, and gNPCstats_e::yawSpeed.

Referenced by NPC_Spawn_Do().

00975 {
00976         const char      *token;
00977         const char      *value;
00978         const char      *p;
00979         int             n;
00980         float   f;
00981         char    *patch;
00982         char    sound[MAX_QPATH];
00983         char    playerModel[MAX_QPATH];
00984         char    customSkin[MAX_QPATH];
00985         renderInfo_t    *ri = &NPC->client->renderInfo;
00986         gNPCstats_t             *stats = NULL;
00987         qboolean        md3Model = qtrue;
00988         char    surfOff[1024];
00989         char    surfOn[1024];
00990         qboolean parsingPlayer = qfalse;
00991         vec3_t playerMins;
00992         vec3_t playerMaxs;
00993         int npcSaber1 = 0;
00994         int npcSaber2 = 0;
00995 
00996         VectorSet(playerMins, -15, -15, DEFAULT_MINS_2);
00997         VectorSet(playerMaxs, 15, 15, DEFAULT_MAXS_2);
00998 
00999         strcpy(customSkin,"default");
01000         if ( !NPCName || !NPCName[0]) 
01001         {
01002                 NPCName = "Player";
01003         }
01004 
01005         if ( !NPC->s.number && NPC->client != NULL )
01006         {//player, only want certain data
01007                 parsingPlayer = qtrue;
01008         }
01009 
01010         if ( NPC->NPC )
01011         {
01012                 stats = &NPC->NPC->stats;
01013 /*
01014         NPC->NPC->allWeaponOrder[0]     = WP_BRYAR_PISTOL;
01015         NPC->NPC->allWeaponOrder[1]     = WP_SABER;
01016         NPC->NPC->allWeaponOrder[2]     = WP_IMOD;
01017         NPC->NPC->allWeaponOrder[3]     = WP_SCAVENGER_RIFLE;
01018         NPC->NPC->allWeaponOrder[4]     = WP_TRICORDER;
01019         NPC->NPC->allWeaponOrder[6]     = WP_NONE;
01020         NPC->NPC->allWeaponOrder[6]     = WP_NONE;
01021         NPC->NPC->allWeaponOrder[7]     = WP_NONE;
01022 */
01023                 // fill in defaults
01024                 stats->aggression       = 3;
01025                 stats->aim                      = 3;
01026                 stats->earshot          = 1024;
01027                 stats->evasion          = 3;
01028                 stats->hfov                     = 90;
01029                 stats->intelligence     = 3;
01030                 stats->move                     = 3;
01031                 stats->reactions        = 3;
01032                 stats->vfov                     = 60;
01033                 stats->vigilance        = 0.1f;
01034                 stats->visrange         = 1024;
01035 
01036                 stats->health           = 0;
01037 
01038                 stats->yawSpeed         = 90;
01039                 stats->walkSpeed        = 90;
01040                 stats->runSpeed         = 300;
01041                 stats->acceleration     = 15;//Increase/descrease speed this much per frame (20fps)
01042         }
01043         else
01044         {
01045                 stats = NULL;
01046         }
01047 
01048         //Set defaults
01049         //FIXME: should probably put default torso and head models, but what about enemies
01050         //that don't have any- like Stasis?
01051         //Q_strncpyz( ri->headModelName,        DEFAULT_HEADMODEL,  sizeof(ri->headModelName),  qtrue);
01052         //Q_strncpyz( ri->torsoModelName, DEFAULT_TORSOMODEL, sizeof(ri->torsoModelName),       qtrue);
01053         //Q_strncpyz( ri->legsModelName,        DEFAULT_LEGSMODEL,  sizeof(ri->legsModelName),  qtrue);
01054         //FIXME: should we have one for weapon too?
01055         memset( (char *)surfOff, 0, sizeof(surfOff) );
01056         memset( (char *)surfOn, 0, sizeof(surfOn) );
01057         
01058         /*
01059         ri->headYawRangeLeft = 50;
01060         ri->headYawRangeRight = 50;
01061         ri->headPitchRangeUp = 40;
01062         ri->headPitchRangeDown = 50;
01063         ri->torsoYawRangeLeft = 60;
01064         ri->torsoYawRangeRight = 60;
01065         ri->torsoPitchRangeUp = 30;
01066         ri->torsoPitchRangeDown = 70;
01067         */
01068 
01069         ri->headYawRangeLeft = 80;
01070         ri->headYawRangeRight = 80;
01071         ri->headPitchRangeUp = 45;
01072         ri->headPitchRangeDown = 45;
01073         ri->torsoYawRangeLeft = 60;
01074         ri->torsoYawRangeRight = 60;
01075         ri->torsoPitchRangeUp = 30;
01076         ri->torsoPitchRangeDown = 50;
01077 
01078         VectorCopy(playerMins, NPC->r.mins);
01079         VectorCopy(playerMaxs, NPC->r.maxs);
01080         NPC->client->ps.crouchheight = CROUCH_MAXS_2;
01081         NPC->client->ps.standheight = DEFAULT_MAXS_2;
01082 
01083         //rwwFIXMEFIXME: ...
01084         /*
01085         NPC->client->moveType           = MT_RUNJUMP;
01086 
01087         NPC->client->dismemberProbHead = 100;
01088         NPC->client->dismemberProbArms = 100;
01089         NPC->client->dismemberProbHands = 100;
01090         NPC->client->dismemberProbWaist = 100;
01091         NPC->client->dismemberProbLegs = 100;
01092 
01093         NPC->s.modelScale[0] = NPC->s.modelScale[1] = NPC->s.modelScale[2] = 1.0f;
01094         */
01095 
01096         NPC->client->ps.customRGBA[0]=255;
01097         NPC->client->ps.customRGBA[1]=255;
01098         NPC->client->ps.customRGBA[2]=255;
01099         NPC->client->ps.customRGBA[3]=255;
01100 
01101         if ( !Q_stricmp( "random", NPCName ) )
01102         {//Randomly assemble a starfleet guy
01103                 //NPC_BuildRandom( NPC );
01104                 Com_Printf("RANDOM NPC NOT SUPPORTED IN MP\n");
01105                 return qfalse;
01106         }
01107         else
01108         {
01109                 int fp;
01110 
01111                 p = NPCParms;
01112                 COM_BeginParseSession(NPCFile);
01113 
01114                 // look for the right NPC
01115                 while ( p ) 
01116                 {
01117                         token = COM_ParseExt( &p, qtrue );
01118                         if ( token[0] == 0 )
01119                         {
01120                                 return qfalse;
01121                         }
01122 
01123                         if ( !Q_stricmp( token, NPCName ) ) 
01124                         {
01125                                 break;
01126                         }
01127 
01128                         SkipBracedSection( &p );
01129                 }
01130                 if ( !p ) 
01131                 {
01132                         return qfalse;
01133                 }
01134 
01135                 if ( BG_ParseLiteral( &p, "{" ) ) 
01136                 {
01137                         return qfalse;
01138                 }
01139                         
01140                 // parse the NPC info block
01141                 while ( 1 ) 
01142                 {
01143                         token = COM_ParseExt( &p, qtrue );
01144                         if ( !token[0] ) 
01145                         {
01146                                 Com_Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s'\n", NPCName );
01147                                 return qfalse;
01148                         }
01149 
01150                         if ( !Q_stricmp( token, "}" ) ) 
01151                         {
01152                                 break;
01153                         }
01154         //===MODEL PROPERTIES===========================================================
01155                         // custom color
01156                         if ( !Q_stricmp( token, "customRGBA" ) ) 
01157                         {
01158                                 if ( COM_ParseString( &p, &value ) ) 
01159                                 {
01160                                         continue;
01161                                 }
01162                                 if ( !Q_stricmp( value, "random") )
01163                                 {
01164                                         NPC->client->ps.customRGBA[0]=Q_irand(0,255);
01165                                         NPC->client->ps.customRGBA[1]=Q_irand(0,255);
01166                                         NPC->client->ps.customRGBA[2]=Q_irand(0,255);
01167                                         NPC->client->ps.customRGBA[3]=255;
01168                                 } 
01169                                 else 
01170                                 {
01171                                         NPC->client->ps.customRGBA[0]=atoi(value);
01172                                         
01173                                         if ( COM_ParseInt( &p, &n ) ) 
01174                                         {
01175                                                 continue;
01176                                         }
01177                                         NPC->client->ps.customRGBA[1]=n;
01178                                         
01179                                         if ( COM_ParseInt( &p, &n ) ) 
01180                                         {
01181                                                 continue;
01182                                         }
01183                                         NPC->client->ps.customRGBA[2]=n;
01184                                         
01185                                         if ( COM_ParseInt( &p, &n ) ) 
01186                                         {
01187                                                 continue;
01188                                         }
01189                                         NPC->client->ps.customRGBA[3]=n;
01190                                 }
01191                                 continue;
01192                         }
01193 
01194                         // headmodel
01195                         if ( !Q_stricmp( token, "headmodel" ) ) 
01196                         {
01197                                 if ( COM_ParseString( &p, &value ) ) 
01198                                 {
01199                                         continue;
01200                                 }
01201 
01202                                 if(!Q_stricmp("none", value))
01203                                 {
01204                                         //Zero the head clamp range so the torso & legs don't lag behind
01205                                         ri->headYawRangeLeft = 
01206                                         ri->headYawRangeRight = 
01207                                         ri->headPitchRangeUp = 
01208                                         ri->headPitchRangeDown = 0;
01209                                 }
01210                                 continue;
01211                         }
01212                         
01213                         // torsomodel
01214                         if ( !Q_stricmp( token, "torsomodel" ) ) 
01215                         {
01216                                 if ( COM_ParseString( &p, &value ) ) 
01217                                 {
01218                                         continue;
01219                                 }
01220 
01221                                 if(!Q_stricmp("none", value))
01222                                 {
01223                                         //Zero the torso clamp range so the legs don't lag behind
01224                                         ri->torsoYawRangeLeft = 
01225                                         ri->torsoYawRangeRight = 
01226                                         ri->torsoPitchRangeUp = 
01227                                         ri->torsoPitchRangeDown = 0;
01228                                 }
01229                                 continue;
01230                         }
01231 
01232                         // legsmodel
01233                         if ( !Q_stricmp( token, "legsmodel" ) ) 
01234                         {
01235                                 if ( COM_ParseString( &p, &value ) ) 
01236                                 {
01237                                         continue;
01238                                 }
01239                                 /*
01240                                 Q_strncpyz( ri->legsModelName, value, sizeof(ri->legsModelName), qtrue);                        
01241                                 //Need to do this here to get the right index
01242                                 G_ParseAnimFileSet( ri->legsModelName, ri->legsModelName, &ci->animFileIndex );
01243                                 */
01244                                 continue;
01245                         }
01246 
01247                         // playerModel
01248                         if ( !Q_stricmp( token, "playerModel" ) ) 
01249                         {
01250                                 if ( COM_ParseString( &p, &value ) ) 
01251                                 {
01252                                         continue;
01253                                 }
01254                                 Q_strncpyz( playerModel, value, sizeof(playerModel));                   
01255                                 md3Model = qfalse;
01256                                 continue;
01257                         }
01258                         
01259                         // customSkin
01260                         if ( !Q_stricmp( token, "customSkin" ) ) 
01261                         {
01262                                 if ( COM_ParseString( &p, &value ) ) 
01263                                 {
01264                                         continue;
01265                                 }
01266                                 Q_strncpyz( customSkin, value, sizeof(customSkin));                     
01267                                 continue;
01268                         }
01269 
01270                         // surfOff
01271                         if ( !Q_stricmp( token, "surfOff" ) ) 
01272                         {
01273                                 if ( COM_ParseString( &p, &value ) ) 
01274                                 {
01275                                         continue;
01276                                 }
01277                                 if ( surfOff[0] )
01278                                 {
01279                                         Q_strcat( (char *)surfOff, sizeof(surfOff), "," );
01280                                         Q_strcat( (char *)surfOff, sizeof(surfOff), value );
01281                                 }
01282                                 else
01283                                 {
01284                                         Q_strncpyz( surfOff, value, sizeof(surfOff));
01285                                 }
01286                                 continue;
01287                         }
01288                         
01289                         // surfOn
01290                         if ( !Q_stricmp( token, "surfOn" ) ) 
01291                         {
01292                                 if ( COM_ParseString( &p, &value ) ) 
01293                                 {
01294                                         continue;
01295                                 }
01296                                 if ( surfOn[0] )
01297                                 {
01298                                         Q_strcat( (char *)surfOn, sizeof(surfOn), "," );
01299                                         Q_strcat( (char *)surfOn, sizeof(surfOn), value );
01300                                 }
01301                                 else
01302                                 {
01303                                         Q_strncpyz( surfOn, value, sizeof(surfOn));
01304                                 }
01305                                 continue;
01306                         }
01307                         
01308                         //headYawRangeLeft
01309                         if ( !Q_stricmp( token, "headYawRangeLeft" ) ) 
01310                         {
01311                                 if ( COM_ParseInt( &p, &n ) ) 
01312                                 {
01313                                         SkipRestOfLine( &p );
01314                                         continue;
01315                                 }
01316                                 if ( n < 0 ) 
01317                                 {
01318                                         Com_Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
01319                                         continue;
01320                                 }
01321                                 ri->headYawRangeLeft = n;
01322                                 continue;
01323                         }
01324 
01325                         //headYawRangeRight
01326                         if ( !Q_stricmp( token, "headYawRangeRight" ) ) 
01327                         {
01328                                 if ( COM_ParseInt( &p, &n ) ) 
01329                                 {
01330                                         SkipRestOfLine( &p );
01331                                         continue;
01332                                 }
01333                                 if ( n < 0 ) 
01334                                 {
01335                                         Com_Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
01336                                         continue;
01337                                 }
01338                                 ri->headYawRangeRight = n;
01339                                 continue;
01340                         }
01341 
01342                         //headPitchRangeUp
01343                         if ( !Q_stricmp( token, "headPitchRangeUp" ) ) 
01344                         {
01345                                 if ( COM_ParseInt( &p, &n ) ) 
01346                                 {
01347                                         SkipRestOfLine( &p );
01348                                         continue;
01349                                 }
01350                                 if ( n < 0 ) 
01351                                 {
01352                                         Com_Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
01353                                         continue;
01354                                 }
01355                                 ri->headPitchRangeUp = n;
01356                                 continue;
01357                         }
01358                         
01359                         //headPitchRangeDown
01360                         if ( !Q_stricmp( token, "headPitchRangeDown" ) ) 
01361                         {
01362                                 if ( COM_ParseInt( &p, &n ) ) 
01363                                 {
01364                                         SkipRestOfLine( &p );
01365                                         continue;
01366                                 }
01367                                 if ( n < 0 ) 
01368                                 {
01369                                         Com_Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
01370                                         continue;
01371                                 }
01372                                 ri->headPitchRangeDown = n;
01373                                 continue;
01374                         }
01375 
01376                         //torsoYawRangeLeft
01377                         if ( !Q_stricmp( token, "torsoYawRangeLeft" ) ) 
01378                         {
01379                                 if ( COM_ParseInt( &p, &n ) ) 
01380                                 {
01381                                         SkipRestOfLine( &p );
01382                                         continue;
01383                                 }
01384                                 if ( n < 0 ) 
01385                                 {
01386                                         Com_Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
01387                                         continue;
01388                                 }
01389                                 ri->torsoYawRangeLeft = n;
01390                                 continue;
01391                         }
01392 
01393                         //torsoYawRangeRight
01394                         if ( !Q_stricmp( token, "torsoYawRangeRight" ) ) 
01395                         {
01396                                 if ( COM_ParseInt( &p, &n ) ) 
01397                                 {
01398                                         SkipRestOfLine( &p );
01399                                         continue;
01400                                 }
01401                                 if ( n < 0 ) 
01402                                 {
01403                                         Com_Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
01404                                         continue;
01405                                 }
01406                                 ri->torsoYawRangeRight = n;
01407                                 continue;
01408                         }
01409 
01410                         //torsoPitchRangeUp
01411                         if ( !Q_stricmp( token, "torsoPitchRangeUp" ) ) 
01412                         {
01413                                 if ( COM_ParseInt( &p, &n ) ) 
01414                                 {
01415                                         SkipRestOfLine( &p );
01416                                         continue;
01417                                 }
01418                                 if ( n < 0 ) 
01419                                 {
01420                                         Com_Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
01421                                         continue;
01422                                 }
01423                                 ri->torsoPitchRangeUp = n;
01424                                 continue;
01425                         }
01426 
01427                         //torsoPitchRangeDown
01428                         if ( !Q_stricmp( token, "torsoPitchRangeDown" ) ) 
01429                         {
01430                                 if ( COM_ParseInt( &p, &n ) ) 
01431                                 {
01432                                         SkipRestOfLine( &p );
01433                                         continue;
01434                                 }
01435                                 if ( n < 0 ) 
01436                                 {
01437                                         Com_Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
01438                                         continue;
01439                                 }
01440                                 ri->torsoPitchRangeDown = n;
01441                                 continue;
01442                         }
01443 
01444                         // Uniform XYZ scale
01445                         if ( !Q_stricmp( token, "scale" ) ) 
01446                         {
01447                                 if ( COM_ParseInt( &p, &n ) ) 
01448                                 {
01449                                         SkipRestOfLine( &p );
01450                                         continue;
01451                                 }
01452                                 if ( n < 0 ) 
01453                                 {
01454                                         Com_Printf(  "bad %s in NPC '%s'\n", token, NPCName );
01455                                         continue;
01456                                 }
01457                                 if (n != 100)
01458                                 {
01459                                         NPC->client->ps.iModelScale = n; //so the client knows
01460                                         if (n >= 1024)
01461                                         {
01462                                                 Com_Printf("WARNING: MP does not support scaling up to or over 1024%\n");
01463                                                 n = 1023;
01464                                         }
01465 
01466                                         NPC->modelScale[0] = NPC->modelScale[1] = NPC->modelScale[2] = n/100.0f;
01467                                 }
01468                                 continue;
01469                         }
01470 
01471                         //X scale
01472                         if ( !Q_stricmp( token, "scaleX" ) ) 
01473                         {
01474                                 if ( COM_ParseInt( &p, &n ) ) 
01475                                 {
01476                                         SkipRestOfLine( &p );
01477                                         continue;
01478                                 }
01479                                 if ( n < 0 ) 
01480                                 {
01481                                         Com_Printf(  "bad %s in NPC '%s'\n", token, NPCName );
01482                                         continue;
01483                                 }
01484                                 if (n != 100)
01485                                 {
01486                                         Com_Printf("MP doesn't support xyz scaling, use 'scale'.\n");
01487                                         //NPC->s.modelScale[0] = n/100.0f;
01488                                 }
01489                                 continue;
01490                         }
01491 
01492                         //Y scale
01493                         if ( !Q_stricmp( token, "scaleY" ) ) 
01494                         {
01495                                 if ( COM_ParseInt( &p, &n ) ) 
01496                                 {
01497                                         SkipRestOfLine( &p );
01498                                         continue;
01499                                 }
01500                                 if ( n < 0 ) 
01501                                 {
01502                                         Com_Printf(  "bad %s in NPC '%s'\n", token, NPCName );
01503                                         continue;
01504                                 }
01505                                 if (n != 100)
01506                                 {
01507                                         Com_Printf("MP doesn't support xyz scaling, use 'scale'.\n");
01508                                         //NPC->s.modelScale[1] = n/100.0f;
01509                                 }
01510                                 continue;
01511                         }
01512 
01513                         //Z scale
01514                         if ( !Q_stricmp( token, "scaleZ" ) ) 
01515                         {
01516                                 if ( COM_ParseInt( &p, &n ) ) 
01517                                 {
01518                                         SkipRestOfLine( &p );
01519                                         continue;
01520                                 }
01521                                 if ( n < 0 ) 
01522                                 {
01523                                         Com_Printf(  "bad %s in NPC '%s'\n", token, NPCName );
01524                                         continue;
01525                                 }
01526                                 if (n != 100)
01527                                 {
01528                                         Com_Printf("MP doesn't support xyz scaling, use 'scale'.\n");
01529                                 //      NPC->s.modelScale[2] = n/100.0f;
01530                                 }
01531                                 continue;
01532                         }
01533 
01534         //===AI STATS=====================================================================
01535                         if ( !parsingPlayer )
01536                         {
01537                                 // aggression
01538                                 if ( !Q_stricmp( token, "aggression" ) ) {
01539                                         if ( COM_ParseInt( &p, &n ) ) {
01540                                                 SkipRestOfLine( &p );
01541                                                 continue;
01542                                         }
01543                                         if ( n < 1 || n > 5 ) {
01544                                                 Com_Printf(  "bad %s in NPC '%s'\n", token, NPCName );
01545                                                 continue;
01546                                         }
01547                                         if ( NPC->NPC )
01548                                         {
01549                                                 stats->aggression = n;
01550                                         }
01551                                         continue;
01552                                 }
01553 
01554                                 // aim
01555                                 if ( !Q_stricmp( token, "aim" ) ) {
01556                                         if ( COM_ParseInt( &p, &n ) ) {
01557                                                 SkipRestOfLine( &p );
01558                                                 continue;
01559                                         }
01560                                         if ( n < 1 || n > 5 ) {
01561                                                 Com_Printf( "bad %s in NPC '%s'\n", token, NPCName );
01562                                                 continue;
01563                                         }
01564                                         if ( NPC->NPC )
01565                                         {
01566                                                 stats->aim = n;
01567                                         }
01568                                         continue;
01569                                 }
01570 
01571                                 // earshot
01572                                 if ( !Q_stricmp( token, "earshot" ) ) {
01573                                         if ( COM_ParseFloat( &p, &f ) ) {
01574                                                 SkipRestOfLine( &p );
01575                                                 continue;
01576                                         }
01577                                         if ( f < 0.0f ) 
01578                                         {
01579                                                 Com_Printf( "bad %s in NPC '%s'\n", token, NPCName );
01580                                                 continue;
01581                                         }
01582                                         if ( NPC->NPC )
01583                                         {
01584                                                 stats->earshot = f;
01585                                         }
01586                                         continue;
01587                                 }
01588 
01589                                 // evasion
01590                                 if ( !Q_stricmp( token, "evasion" ) ) 
01591                                 {
01592                                         if ( COM_ParseInt( &p, &n ) ) 
01593                                         {
01594                                                 SkipRestOfLine( &p );
01595                                                 continue;
01596                                         }
01597                                         if ( n < 1 || n > 5 ) 
01598                                         {
01599                                                 Com_Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
01600                                                 continue;
01601                                         }
01602                                         if ( NPC->NPC )
01603                                         {
01604                                                 stats->evasion = n;
01605                                         }
01606                                         continue;
01607                                 }
01608 
01609                                 // hfov
01610                                 if ( !Q_stricmp( token, "hfov" ) ) {
01611                                         if ( COM_ParseInt( &p, &n ) ) {
01612                                                 SkipRestOfLine( &p );
01613                                                 continue;
01614                                         }
01615                                         if ( n < 30 || n > 180 ) {
01616                                                 Com_Printf(  "bad %s in NPC '%s'\n", token, NPCName );
01617                                                 continue;
01618                                         }
01619                                         if ( NPC->NPC )
01620                                         {
01621                                                 stats->hfov = n;// / 2; //FIXME: Why was this being done?!
01622                                         }
01623                                         continue;
01624                                 }
01625 
01626                                 // intelligence
01627                                 if ( !Q_stricmp( token, "intelligence" ) ) {
01628                                         if ( COM_ParseInt( &p, &n ) ) {
01629                                                 SkipRestOfLine( &p );
01630                                                 continue;
01631                                         }
01632                                         if ( n < 1 || n > 5 ) {
01633                                                 Com_Printf(  "bad %s in NPC '%s'\n", token, NPCName );
01634                                                 continue;
01635                                         }
01636                                         if ( NPC->NPC )
01637                                         {
01638                                                 stats->intelligence = n;
01639                                         }
01640                                         continue;
01641                                 }
01642                                 
01643                                 // move
01644                                 if ( !Q_stricmp( token, "move" ) ) {
01645                                         if ( COM_ParseInt( &p, &n ) ) {
01646                                                 SkipRestOfLine( &p );
01647                                                 continue;
01648                                         }
01649                                         if ( n < 1 || n > 5 ) {
01650                                                 Com_Printf(  "bad %s in NPC '%s'\n", token, NPCName );
01651                                                 continue;
01652                                         }
01653                                         if ( NPC->NPC )
01654                                         {
01655                                                 stats->move = n;
01656                                         }
01657                                         continue;
01658                                 }
01659 
01660                                 // reactions
01661                                 if ( !Q_stricmp( token, "reactions" ) ) {
01662                                         if ( COM_ParseInt( &p, &n ) ) {
01663                                                 SkipRestOfLine( &p );
01664                                                 continue;
01665                                         }
01666                                         if ( n < 1 || n > 5 ) {
01667                                                 Com_Printf( "bad %s in NPC '%s'\n", token, NPCName );
01668                                                 continue;
01669                                         }
01670                                         if ( NPC->NPC )
01671                                         {
01672                                                 stats->reactions = n;
01673                                         }
01674                                         continue;
01675                                 }
01676 
01677                                 // shootDistance
01678                                 if ( !Q_stricmp( token, "shootDistance" ) ) {
01679                                         if ( COM_ParseFloat( &p, &f ) ) {
01680                                                 SkipRestOfLine( &p );
01681                                                 continue;
01682                                         }
01683                                         if ( f < 0.0f ) 
01684                                         {
01685                                                 Com_Printf( "bad %s in NPC '%s'\n", token, NPCName );
01686                                                 continue;
01687                                         }
01688                                         if ( NPC->NPC )
01689                                         {
01690                                                 stats->shootDistance = f;
01691                                         }
01692                                         continue;
01693                                 }
01694 
01695                                 // vfov
01696                                 if ( !Q_stricmp( token, "vfov" ) ) {
01697                                         if ( COM_ParseInt( &p, &n ) ) {
01698                                                 SkipRestOfLine( &p );
01699                                                 continue;
01700                                         }
01701                                         if ( n < 30 || n > 180 ) {
01702                                                 Com_Printf(  "bad %s in NPC '%s'\n", token, NPCName );
01703                                                 continue;
01704                                         }
01705                                         if ( NPC->NPC )
01706                                         {
01707                                                 stats->vfov = n / 2;
01708                                         }
01709                                         continue;
01710                                 }
01711 
01712                                 // vigilance
01713                                 if ( !Q_stricmp( token, "vigilance" ) ) {
01714                                         if ( COM_ParseFloat( &p, &f ) ) {
01715                                                 SkipRestOfLine( &p );
01716                                                 continue;
01717                                         }
01718                                         if ( f < 0.0f ) 
01719                                         {
01720                                                 Com_Printf( "bad %s in NPC '%s'\n", token, NPCName );
01721                                                 continue;
01722                                         }
01723                                         if ( NPC->NPC )
01724                                         {
01725                                                 stats->vigilance = f;
01726                                         }
01727                                         continue;
01728                                 }
01729 
01730                                 // visrange
01731                                 if ( !Q_stricmp( token, "visrange" ) ) {
01732                                         if ( COM_ParseFloat( &p, &f ) ) {
01733                                                 SkipRestOfLine( &p );
01734                                                 continue;
01735                                         }
01736                                         if ( f < 0.0f ) 
01737                                         {
01738                                                 Com_Printf( "bad %s in NPC '%s'\n", token, NPCName );
01739                                                 continue;
01740                                         }
01741                                         if ( NPC->NPC )
01742                                         {
01743                                                 stats->visrange = f;
01744                                         }
01745                                         continue;
01746                                 }
01747 
01748                                 // race
01749                 //              if ( !Q_stricmp( token, "race" ) ) 
01750                 //              {
01751                 //                      if ( COM_ParseString( &p, &value ) ) 
01752                 //                      {
01753                 //                              continue;
01754                 //                      }
01755                 //                      NPC->client->race = TranslateRaceName(value);
01756                 //                      continue;
01757                 //              }
01758 
01759                                 // rank
01760                                 if ( !Q_stricmp( token, "rank" ) ) 
01761                                 {
01762                                         if ( COM_ParseString( &p, &value ) ) 
01763                                         {
01764                                                 continue;
01765                                         }
01766                                         if ( NPC->NPC )
01767                                         {
01768                                                 NPC->NPC->rank = TranslateRankName(value);
01769                                         }
01770                                         continue;
01771                                 }
01772                         }
01773 
01774                         // health
01775                         if ( !Q_stricmp( token, "health" ) ) 
01776                         {
01777                                 if ( COM_ParseInt( &p, &n ) ) 
01778                                 {
01779                                         SkipRestOfLine( &p );
01780                                         continue;
01781                                 }
01782                                 if ( n < 0 ) 
01783                                 {
01784                                         Com_Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
01785                                         continue;
01786                                 }
01787                                 if ( NPC->NPC )
01788                                 {
01789                                         stats->health = n;
01790                                 }
01791                                 else if ( parsingPlayer )
01792                                 {
01793                                         NPC->client->ps.stats[STAT_MAX_HEALTH] = NPC->client->pers.maxHealth = n;
01794                                 }
01795                                 continue;
01796                         }
01797 
01798                         // fullName
01799                         if ( !Q_stricmp( token, "fullName" ) ) 
01800                         {
01801                                 if ( COM_ParseString( &p, &value ) ) 
01802                                 {
01803                                         continue;
01804                                 }
01805                                 NPC->fullName = G_NewString(value);
01806                                 continue;
01807                         }
01808 
01809                         // playerTeam
01810                         if ( !Q_stricmp( token, "playerTeam" ) ) 
01811                         {
01812                                 char tk[4096]; //rww - hackilicious!
01813 
01814                                 if ( COM_ParseString( &p, &value ) ) 
01815                                 {
01816                                         continue;
01817                                 }
01818                                 Com_sprintf(tk, sizeof(tk), "NPC%s", token);
01819                                 NPC->client->playerTeam = NPC->s.teamowner = (team_t)GetIDForString( TeamTable, tk );//TranslateTeamName(value);
01820                                 continue;
01821                         }
01822 
01823                         // enemyTeam
01824                         if ( !Q_stricmp( token, "enemyTeam" ) ) 
01825                         {
01826                                 char tk[4096]; //rww - hackilicious!
01827 
01828                                 if ( COM_ParseString( &p, &value ) ) 
01829                                 {
01830                                         continue;
01831                                 }
01832                                 Com_sprintf(tk, sizeof(tk), "NPC%s", token);
01833                                 NPC->client->enemyTeam = (team_t)GetIDForString( TeamTable, tk );//TranslateTeamName(value);
01834                                 continue;
01835                         }
01836 
01837                         // class
01838                         if ( !Q_stricmp( token, "class" ) ) 
01839                         {
01840                                 if ( COM_ParseString( &p, &value ) ) 
01841                                 {
01842                                         continue;
01843                                 }
01844                                 NPC->client->NPC_class = (class_t)GetIDForString( ClassTable, value );
01845                                 NPC->s.NPC_class = NPC->client->NPC_class; //we actually only need this value now, but at the moment I don't feel like changing the 200+ references to client->NPC_class.
01846 
01847                                 // No md3's for vehicles.
01848                                 if ( NPC->client->NPC_class == CLASS_VEHICLE )
01849                                 {
01850                                         if ( !NPC->m_pVehicle )
01851                                         {//you didn't spawn this guy right!
01852                                                 Com_Printf ( S_COLOR_RED "ERROR: Tried to spawn a vehicle NPC (%s) without using NPC_Vehicle or 'NPC spawn vehicle <vehiclename>'!!!  Bad, bad, bad!  Shame on you!\n", NPCName );
01853                                                 return qfalse;
01854                                         }
01855                                         md3Model = qfalse;
01856                                 }
01857 
01858                                 continue;
01859                         }
01860 
01861                         // dismemberment probability for head
01862                         if ( !Q_stricmp( token, "dismemberProbHead" ) ) {
01863                                 if ( COM_ParseInt( &p, &n ) ) {
01864                                         SkipRestOfLine( &p );
01865                                         continue;
01866                                 }
01867                                 if ( n < 0 ) 
01868                                 {
01869                                         Com_Printf( "bad %s in NPC '%s'\n", token, NPCName );
01870                                         continue;
01871                                 }
01872                                 if ( NPC->NPC )
01873                                 {
01874                                 //      NPC->client->dismemberProbHead = n;
01875                                         //rwwFIXMEFIXME: support for this?
01876                                 }
01877                                 continue;
01878                         }
01879 
01880                         // dismemberment probability for arms
01881                         if ( !Q_stricmp( token, "dismemberProbArms" ) ) {
01882                                 if ( COM_ParseInt( &p, &n ) ) {
01883                                         SkipRestOfLine( &p );
01884                                         continue;
01885                                 }
01886                                 if ( n < 0 ) 
01887                                 {
01888                                         Com_Printf( "bad %s in NPC '%s'\n", token, NPCName );
01889                                         continue;
01890                                 }
01891                                 if ( NPC->NPC )
01892                                 {
01893                                 //      NPC->client->dismemberProbArms = n;
01894                                 }
01895                                 continue;
01896                         }
01897 
01898                         // dismemberment probability for hands
01899                         if ( !Q_stricmp( token, "dismemberProbHands" ) ) {
01900                                 if ( COM_ParseInt( &p, &n ) ) {
01901                                         SkipRestOfLine( &p );
01902                                         continue;
01903                                 }
01904                                 if ( n < 0 ) 
01905                                 {
01906                                         Com_Printf( "bad %s in NPC '%s'\n", token, NPCName );
01907                                         continue;
01908                                 }
01909                                 if ( NPC->NPC )
01910                                 {
01911                                 //      NPC->client->dismemberProbHands = n;
01912                                 }
01913                                 continue;
01914                         }
01915 
01916                         // dismemberment probability for waist
01917                         if ( !Q_stricmp( token, "dismemberProbWaist" ) ) {
01918                                 if ( COM_ParseInt( &p, &n ) ) {
01919                                         SkipRestOfLine( &p );
01920                                         continue;
01921                                 }
01922                                 if ( n < 0 ) 
01923                                 {
01924                                         Com_Printf( "bad %s in NPC '%s'\n", token, NPCName );
01925                                         continue;
01926                                 }
01927                                 if ( NPC->NPC )
01928                                 {
01929                                 //      NPC->client->dismemberProbWaist = n;
01930                                 }
01931                                 continue;
01932                         }
01933 
01934                         // dismemberment probability for legs
01935                         if ( !Q_stricmp( token, "dismemberProbLegs" ) ) {
01936                                 if ( COM_ParseInt( &p, &n ) ) {
01937                                         SkipRestOfLine( &p );
01938                                         continue;
01939                                 }
01940                                 if ( n < 0 ) 
01941                                 {
01942                                         Com_Printf( "bad %s in NPC '%s'\n", token, NPCName );
01943                                         continue;
01944                                 }
01945                                 if ( NPC->NPC )
01946                                 {
01947                                 //      NPC->client->dismemberProbLegs = n;
01948                                 }
01949                                 continue;
01950                         }
01951 
01952         //===MOVEMENT STATS============================================================
01953                         
01954                         if ( !Q_stricmp( token, "width" ) ) 
01955                         {
01956                                 if ( COM_ParseInt( &p, &n ) ) 
01957                                 {
01958                                         continue;
01959                                 }
01960 
01961                                 NPC->r.mins[0] = NPC->r.mins[1] = -n;
01962                                 NPC->r.maxs[0] = NPC->r.maxs[1] = n;
01963                                 continue;
01964                         }
01965 
01966                         if ( !Q_stricmp( token, "height" ) ) 
01967                         {
01968                                 if ( COM_ParseInt( &p, &n ) ) 
01969                                 {
01970                                         continue;
01971                                 }
01972                                 if ( NPC->client->NPC_class == CLASS_VEHICLE
01973                                         && NPC->m_pVehicle
01974                                         && NPC->m_pVehicle->m_pVehicleInfo
01975                                         && NPC->m_pVehicle->m_pVehicleInfo->type == VH_FIGHTER )
01976                                 {//a flying vehicle's origin must be centered in bbox and it should spawn on the ground
01977                                         //trace_t               tr;
01978                                         //vec3_t                bottom;
01979                                         //float         adjust = 32.0f;
01980                                         NPC->r.maxs[2] = NPC->client->ps.standheight = (n/2.0f);
01981                                         NPC->r.mins[2] = -NPC->r.maxs[2];
01982                                         NPC->s.origin[2] += (DEFAULT_MINS_2-NPC->r.mins[2])+0.125f;
01983                                         VectorCopy(NPC->s.origin, NPC->client->ps.origin);
01984                                         VectorCopy(NPC->s.origin, NPC->r.currentOrigin);
01985                                         G_SetOrigin( NPC, NPC->s.origin );
01986                                         trap_LinkEntity(NPC);
01987                                         //now trace down
01988                                         /*
01989                                         VectorCopy( NPC->s.origin, bottom );
01990                                         bottom[2] -= adjust;
01991                                         trap_Trace( &tr, NPC->s.origin, NPC->r.mins, NPC->r.maxs, bottom, NPC->s.number, MASK_NPCSOLID );
01992                                         if ( !tr.allsolid && !tr.startsolid )
01993                                         {
01994                                                 G_SetOrigin( NPC, tr.endpos );
01995                                                 trap_LinkEntity(NPC);
01996                                         }
01997                                         */
01998                                 }
01999                                 else
02000                                 {
02001                                         NPC->r.mins[2] = DEFAULT_MINS_2;//Cannot change
02002                                         NPC->r.maxs[2] = NPC->client->ps.standheight = n + DEFAULT_MINS_2;
02003                                 }
02004                                 NPC->radius = n;
02005                                 continue;
02006                         }
02007 
02008                         if ( !Q_stricmp( token, "crouchheight" ) ) 
02009                         {
02010                                 if ( COM_ParseInt( &p, &n ) ) 
02011                                 {
02012                                         continue;
02013                                 }
02014 
02015                                 NPC->client->ps.crouchheight = n + DEFAULT_MINS_2;
02016                                 continue;
02017                         }
02018 
02019                         if ( !parsingPlayer )
02020                         {
02021                                 if ( !Q_stricmp( token, "movetype" ) ) 
02022                                 {
02023                                         if ( COM_ParseString( &p, &value ) ) 
02024                                         {
02025                                                 continue;
02026                                         }
02027                                         if ( Q_stricmp( "flyswim", value ) == 0 )
02028                                         {
02029                                                 NPC->client->ps.eFlags2 |= EF2_FLYING;
02030                                         }
02031                                         //NPC->client->moveType = (movetype_t)MoveTypeNameToEnum(value);
02032                                         //rwwFIXMEFIXME: support for movetypes
02033                                         continue;
02034                                 }
02035                                         
02036                                 // yawSpeed
02037                                 if ( !Q_stricmp( token, "yawSpeed" ) ) {
02038                                         if ( COM_ParseInt( &p, &n ) ) {
02039                                                 SkipRestOfLine( &p );
02040                                                 continue;
02041                                         }
02042                                         if ( n <= 0) {
02043                                                 Com_Printf(  "bad %s in NPC '%s'\n", token, NPCName );
02044                                                 continue;
02045                                         }
02046                                         if ( NPC->NPC )
02047                                         {
02048                                                 stats->yawSpeed = ((float)(n));
02049                                         }
02050                                         continue;
02051                                 }
02052 
02053                                 // walkSpeed
02054                                 if ( !Q_stricmp( token, "walkSpeed" ) ) 
02055                                 {
02056                                         if ( COM_ParseInt( &p, &n ) ) 
02057                                         {
02058                                                 SkipRestOfLine( &p );
02059                                                 continue;
02060                                         }
02061                                         if ( n < 0 ) 
02062                                         {
02063                                                 Com_Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
02064                                                 continue;
02065                                         }
02066                                         if ( NPC->NPC )
02067                                         {
02068                                                 stats->walkSpeed = n;
02069                                         }
02070                                         continue;
02071                                 }
02072                                 
02073                                 //runSpeed
02074                                 if ( !Q_stricmp( token, "runSpeed" ) ) 
02075                                 {
02076                                         if ( COM_ParseInt( &p, &n ) ) 
02077                                         {
02078                                                 SkipRestOfLine( &p );
02079                                                 continue;
02080                                         }
02081                                         if ( n < 0 ) 
02082                                         {
02083                                                 Com_Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
02084                                                 continue;
02085                                         }
02086                                         if ( NPC->NPC )
02087                                         {
02088                                                 stats->runSpeed = n;
02089                                         }
02090                                         continue;
02091                                 }
02092 
02093                                 //acceleration
02094                                 if ( !Q_stricmp( token, "acceleration" ) ) 
02095                                 {
02096                                         if ( COM_ParseInt( &p, &n ) ) 
02097                                         {
02098                                                 SkipRestOfLine( &p );
02099                                                 continue;
02100                                         }
02101                                         if ( n < 0 ) 
02102                                         {
02103                                                 Com_Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
02104                                                 continue;
02105                                         }
02106                                         if ( NPC->NPC )
02107                                         {
02108                                                 stats->acceleration = n;
02109                                         }
02110                                         continue;
02111                                 }
02112                                 //sex - skip in MP
02113                                 if ( !Q_stricmp( token, "sex" ) ) 
02114                                 {
02115                                         SkipRestOfLine( &p );
02116                                         continue;
02117                                 }
02118 //===MISC===============================================================================
02119                                 // default behavior
02120                                 if ( !Q_stricmp( token, "behavior" ) ) 
02121                                 {
02122                                         if ( COM_ParseInt( &p, &n ) ) 
02123                                         {
02124                                                 SkipRestOfLine( &p );
02125                                                 continue;
02126                                         }
02127                                         if ( n < BS_DEFAULT || n >= NUM_BSTATES ) 
02128                                         {
02129                                                 Com_Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
02130                                                 continue;
02131                                         }
02132                                         if ( NPC->NPC )
02133                                         {
02134                                                 NPC->NPC->defaultBehavior = (bState_t)(n);
02135                                         }
02136                                         continue;
02137                                 }
02138                         }
02139 
02140                         // snd
02141                         if ( !Q_stricmp( token, "snd" ) ) 
02142                         {
02143                                 if ( COM_ParseString( &p, &value ) ) 
02144                                 {
02145                                         continue;
02146                                 }
02147                                 if ( !(NPC->r.svFlags&SVF_NO_BASIC_SOUNDS) )
02148                                 {
02149                                         //FIXME: store this in some sound field or parse in the soundTable like the animTable...
02150                                         Q_strncpyz( sound, value, sizeof( sound ) );
02151                                         patch = strstr( sound, "/" );
02152                                         if ( patch ) 
02153                                         {
02154                                                 *patch = 0;
02155                                         }
02156                                 //      ci->customBasicSoundDir = G_NewString( sound );
02157                                         //rwwFIXMEFIXME: Hooray for violating client server rules
02158                                 }
02159                                 continue;
02160                         }
02161 
02162                         // sndcombat
02163                         if ( !Q_stricmp( token, "sndcombat" ) ) 
02164                         {
02165                                 if ( COM_ParseString( &p, &value ) ) 
02166                                 {
02167                                         continue;
02168                                 }
02169                                 if ( !(NPC->r.svFlags&SVF_NO_COMBAT_SOUNDS) )
02170                                 {
02171                                         //FIXME: store this in some sound field or parse in the soundTable like the animTable...
02172                                         Q_strncpyz( sound, value, sizeof( sound ) );
02173                                         patch = strstr( sound, "/" );
02174                                         if ( patch ) 
02175                                         {
02176                                                 *patch = 0;
02177                                         }
02178                                 //      ci->customCombatSoundDir = G_NewString( sound );
02179                                 }
02180                                 continue;
02181                         }
02182                         
02183                         // sndextra
02184                         if ( !Q_stricmp( token, "sndextra" ) ) 
02185                         {
02186                                 if ( COM_ParseString( &p, &value ) ) 
02187                                 {
02188                                         continue;
02189                                 }
02190                                 if ( !(NPC->r.svFlags&SVF_NO_EXTRA_SOUNDS) )
02191                                 {
02192                                         //FIXME: store this in some sound field or parse in the soundTable like the animTable...
02193                                         Q_strncpyz( sound, value, sizeof( sound ) );
02194                                         patch = strstr( sound, "/" );
02195                                         if ( patch ) 
02196                                         {
02197                                                 *patch = 0;
02198                                         }
02199                                 //      ci->customExtraSoundDir = G_NewString( sound );
02200                                 }
02201                                 continue;
02202                         }
02203 
02204                         // sndjedi
02205                         if ( !Q_stricmp( token, "sndjedi" ) ) 
02206                         {
02207                                 if ( COM_ParseString( &p, &value ) ) 
02208                                 {
02209                                         continue;
02210                                 }
02211                                 if ( !(NPC->r.svFlags&SVF_NO_EXTRA_SOUNDS) )
02212                                 {
02213                                         //FIXME: store this in some sound field or parse in the soundTable like the animTable...
02214                                         Q_strncpyz( sound, value, sizeof( sound ) );
02215                                         patch = strstr( sound, "/" );
02216                                         if ( patch ) 
02217                                         {
02218                                                 *patch = 0;
02219                                         }
02220                                         //ci->customJediSoundDir = G_NewString( sound );
02221                                 }
02222                                 continue;
02223                         }
02224 
02225                         //New NPC/jedi stats:
02226                         //starting weapon
02227                         if ( !Q_stricmp( token, "weapon" ) ) 
02228                         {
02229                                 int weap;
02230 
02231                                 if ( COM_ParseString( &p, &value ) ) 
02232                                 {
02233                                         continue;
02234                                 }
02235                                 //FIXME: need to precache the weapon, too?  (in above func)
02236                                 weap = GetIDForString( WPTable, value );
02237                                 if ( weap >= WP_NONE && weap <= WP_NUM_WEAPONS )
02238                                 {
02239                                         NPC->client->ps.weapon = weap;
02240                                         NPC->client->ps.stats[STAT_WEAPONS] |= ( 1 << NPC->client->ps.weapon );
02241                                         if ( weap > WP_NONE )
02242                                         {
02243                                         //      RegisterItem( FindItemForWeapon( (weapon_t)(NPC->client->ps.weapon) ) );        //precache the weapon
02244                                                 NPC->client->ps.ammo[weaponData[NPC->client->ps.weapon].ammoIndex] = 100;//FIXME: max ammo!
02245                                         }
02246                                 }
02247                                 continue;
02248                         }
02249                         
02250                         if ( !parsingPlayer )
02251                         {
02252                                 //altFire
02253                                 if ( !Q_stricmp( token, "altFire" ) ) 
02254                                 {
02255                                         if ( COM_ParseInt( &p, &n ) ) 
02256                                         {
02257                                                 SkipRestOfLine( &p );
02258                                                 continue;
02259                                         }
02260                                         if ( NPC->NPC )
02261                                         {
02262                                                 if ( n != 0 )
02263                                                 {
02264                                                         NPC->NPC->scriptFlags |= SCF_ALT_FIRE;
02265                                                 }
02266                                         }
02267                                         continue;
02268                                 }
02269                                 //Other unique behaviors/numbers that are currently hardcoded?
02270                         }
02271 
02272                         //force powers
02273                         fp = GetIDForString( FPTable, token );
02274                         if ( fp >= FP_FIRST && fp < NUM_FORCE_POWERS )
02275                         {
02276                                 if ( COM_ParseInt( &p, &n ) ) 
02277                                 {
02278                                         SkipRestOfLine( &p );
02279                                         continue;
02280                                 }
02281                                 //FIXME: need to precache the fx, too?  (in above func)
02282                                 //cap
02283                                 if ( n > 5 )
02284                                 {
02285                                         n = 5;
02286                                 }
02287                                 else if ( n < 0 )
02288                                 {
02289                                         n = 0;
02290                                 }
02291                                 if ( n )
02292                                 {//set
02293                                         NPC->client->ps.fd.forcePowersKnown |= ( 1 << fp );
02294                                 }
02295                                 else
02296                                 {//clear
02297                                         NPC->client->ps.fd.forcePowersKnown &= ~( 1 << fp );
02298                                 }
02299                                 NPC->client->ps.fd.forcePowerLevel[fp] = n;
02300                                 continue;
02301                         }
02302 
02303                         //max force power
02304                         if ( !Q_stricmp( token, "forcePowerMax" ) ) 
02305                         {
02306                                 if ( COM_ParseInt( &p, &n ) ) 
02307                                 {
02308                                         SkipRestOfLine( &p );
02309                                         continue;
02310                                 }
02311                                 NPC->client->ps.fd.forcePowerMax = n;
02312                                 continue;
02313                         }
02314 
02315                         //force regen rate - default is 100ms
02316                         if ( !Q_stricmp( token, "forceRegenRate" ) ) 
02317                         {
02318                                 if ( COM_ParseInt( &p, &n ) ) 
02319                                 {
02320                                         SkipRestOfLine( &p );
02321                                         continue;
02322                                 }
02323                                 //NPC->client->ps.forcePowerRegenRate = n;
02324                                 //rwwFIXMEFIXME: support this?
02325                                 continue;
02326                         }
02327 
02328                         //force regen amount - default is 1 (points per second)
02329                         if ( !Q_stricmp( token, "forceRegenAmount" ) ) 
02330                         {
02331                                 if ( COM_ParseInt( &p, &n ) ) 
02332                                 {
02333                                         SkipRestOfLine( &p );
02334                                         continue;
02335                                 }
02336                                 //NPC->client->ps.forcePowerRegenAmount = n;
02337                                 //rwwFIXMEFIXME: support this?
02338                                 continue;
02339                         }
02340 
02341                         //have a sabers.cfg and just name your saber in your NPCs.cfg/ICARUS script
02342                         //saber name
02343                         if ( !Q_stricmp( token, "saber" ) ) 
02344                         {
02345                                 char *saberName;
02346 
02347                                 if ( COM_ParseString( &p, &value ) ) 
02348                                 {
02349                                         continue;
02350                                 }
02351 
02352                                 saberName = (char *)BG_TempAlloc(4096);//G_NewString( value );
02353                                 strcpy(saberName, value);
02354 
02355                                 WP_SaberParseParms( saberName, &NPC->client->saber[0] );
02356                                 npcSaber1 = G_ModelIndex(va("@%s", saberName));
02357 
02358                                 BG_TempFree(4096);
02359                                 continue;
02360                         }
02361                         
02362                         //second saber name
02363                         if ( !Q_stricmp( token, "saber2" ) ) 
02364                         {
02365                                 if ( COM_ParseString( &p, &value ) ) 
02366                                 {
02367                                         continue;
02368                                 }
02369 
02370                                 if ( !(NPC->client->saber[0].saberFlags&SFL_TWO_HANDED) )
02371                                 {//can't use a second saber if first one is a two-handed saber...?
02372                                         char *saberName = (char *)BG_TempAlloc(4096);//G_NewString( value );
02373                                         strcpy(saberName, value);
02374 
02375                                         WP_SaberParseParms( saberName, &NPC->client->saber[1] );
02376                                         if ( (NPC->client->saber[1].saberFlags&SFL_TWO_HANDED) )
02377                                         {//tsk tsk, can't use a twoHanded saber as second saber
02378                                                 WP_RemoveSaber( NPC->client->saber, 1 );
02379                                         }
02380                                         else
02381                                         {
02382                                                 //NPC->client->ps.dualSabers = qtrue;
02383                                                 npcSaber2 = G_ModelIndex(va("@%s", saberName));
02384                                         }
02385                                         BG_TempFree(4096);
02386                                 }
02387                                 continue;
02388                         }
02389 
02390                         // saberColor
02391                         if ( !Q_stricmp( token, "saberColor" ) ) 
02392                         {
02393                                 if ( COM_ParseString( &p, &value ) ) 
02394                                 {
02395                                         continue;
02396                                 }
02397                                 if ( NPC->client )
02398                                 {
02399                                         saber_colors_t color = TranslateSaberColor( value );
02400                                         for ( n = 0; n < MAX_BLADES; n++ )
02401                                         {
02402                                                 NPC->client->saber[0].blade[n].color = color;
02403                                         }
02404                                 }
02405                                 continue;
02406                         }
02407 
02408                         if ( !Q_stricmp( token, "saberColor2" ) ) 
02409                         {
02410                                 if ( COM_ParseString( &p, &value ) ) 
02411                                 {
02412                                         continue;
02413                                 }
02414                                 if ( NPC->client )
02415                                 {
02416                                         NPC->client->saber[0].blade[1].color = TranslateSaberColor( value );
02417                                 }
02418                                 continue;
02419                         }
02420 
02421                         if ( !Q_stricmp( token, "saberColor3" ) ) 
02422                         {
02423                                 if ( COM_ParseString( &p, &value ) ) 
02424                                 {
02425                                         continue;
02426                                 }
02427                                 if ( NPC->client )
02428                                 {
02429                                         NPC->client->saber[0].blade[2].color = TranslateSaberColor( value );
02430                                 }
02431                                 continue;
02432                         }
02433 
02434                         if ( !Q_stricmp( token, "saberColor4" ) ) 
02435                         {
02436                                 if ( COM_ParseString( &p, &value ) ) 
02437                                 {
02438                                         continue;
02439                                 }
02440                                 if ( NPC->client )
02441                                 {
02442                                         NPC->client->saber[0].blade[3].color = TranslateSaberColor( value );
02443                                 }
02444                                 continue;
02445                         }
02446 
02447                         if ( !Q_stricmp( token, "saberColor5" ) ) 
02448                         {
02449                                 if ( COM_ParseString( &p, &value ) ) 
02450                                 {
02451                                         continue;
02452                                 }
02453                                 if ( NPC->client )
02454                                 {
02455                                         NPC->client->saber[0].blade[4].color = TranslateSaberColor( value );
02456                                 }
02457                                 continue;
02458                         }
02459 
02460                         if ( !Q_stricmp( token, "saberColor6" ) ) 
02461                         {
02462                                 if ( COM_ParseString( &p, &value ) ) 
02463                                 {
02464                                         continue;
02465                                 }
02466                                 if ( NPC->client )
02467                                 {
02468                                         NPC->client->saber[0].blade[5].color = TranslateSaberColor( value );
02469                                 }
02470                                 continue;
02471                         }
02472 
02473                         if ( !Q_stricmp( token, "saberColor7" ) ) 
02474                         {
02475                                 if ( COM_ParseString( &p, &value ) ) 
02476                                 {
02477                                         continue;
02478                                 }
02479                                 if ( NPC->client )
02480                                 {
02481                                         NPC->client->saber[0].blade[6].color = TranslateSaberColor( value );
02482                                 }
02483                                 continue;
02484                         }
02485 
02486                         if ( !Q_stricmp( token, "saberColor8" ) ) 
02487                         {
02488                                 if ( COM_ParseString( &p, &value ) ) 
02489                                 {
02490                                         continue;
02491                                 }
02492                                 if ( NPC->client )
02493                                 {
02494                                         NPC->client->saber[0].blade[7].color = TranslateSaberColor( value );
02495                                 }
02496                                 continue;
02497                         }
02498 
02499                         if ( !Q_stricmp( token, "saber2Color" ) ) 
02500                         {
02501                                 if ( COM_ParseString( &p, &value ) ) 
02502                                 {
02503                                         continue;
02504                                 }
02505                                 if ( NPC->client )
02506                                 {
02507                                         saber_colors_t color = TranslateSaberColor( value );
02508                                         for ( n = 0; n < MAX_BLADES; n++ )
02509                                         {
02510                                                 NPC->client->saber[1].blade[n].color = color;
02511                                         }
02512                                 }
02513                                 continue;
02514                         }
02515 
02516                         if ( !Q_stricmp( token, "saber2Color2" ) ) 
02517                         {
02518                                 if ( COM_ParseString( &p, &value ) ) 
02519                                 {
02520                                         continue;
02521                                 }
02522                                 if ( NPC->client )
02523                                 {
02524                                         NPC->client->saber[1].blade[1].color = TranslateSaberColor( value );
02525                                 }
02526                                 continue;
02527                         }
02528 
02529                         if ( !Q_stricmp( token, "saber2Color3" ) ) 
02530                         {
02531                                 if ( COM_ParseString( &p, &value ) ) 
02532                                 {
02533                                         continue;
02534                                 }
02535                                 if ( NPC->client )
02536                                 {
02537                                         NPC->client->saber[1].blade[2].color = TranslateSaberColor( value );
02538                                 }
02539                                 continue;
02540                         }
02541 
02542                         if ( !Q_stricmp( token, "saber2Color4" ) ) 
02543                         {
02544                                 if ( COM_ParseString( &p, &value ) ) 
02545                                 {
02546                                         continue;
02547                                 }
02548                                 if ( NPC->client )
02549                                 {
02550                                         NPC->client->saber[1].blade[3].color = TranslateSaberColor( value );
02551                                 }
02552                                 continue;
02553                         }
02554 
02555                         if ( !Q_stricmp( token, "saber2Color5" ) ) 
02556                         {
02557                                 if ( COM_ParseString( &p, &value ) ) 
02558                                 {
02559                                         continue;
02560                                 }
02561                                 if ( NPC->client )
02562                                 {
02563                                         NPC->client->saber[1].blade[4].color = TranslateSaberColor( value );
02564                                 }
02565                                 continue;
02566                         }
02567 
02568                         if ( !Q_stricmp( token, "saber2Color6" ) ) 
02569                         {
02570                                 if ( COM_ParseString( &p, &value ) ) 
02571                                 {
02572                                         continue;
02573                                 }
02574                                 if ( NPC->client )
02575                                 {
02576                                         NPC->client->saber[1].blade[5].color = TranslateSaberColor( value );
02577                                 }
02578                                 continue;
02579                         }
02580 
02581                         if ( !Q_stricmp( token, "saber2Color7" ) ) 
02582                         {
02583                                 if ( COM_ParseString( &p, &value ) ) 
02584                                 {
02585                                         continue;
02586                                 }
02587                                 if ( NPC->client )
02588                                 {
02589                                         NPC->client->saber[1].blade[6].color = TranslateSaberColor( value );
02590                                 }
02591                                 continue;
02592                         }
02593 
02594                         if ( !Q_stricmp( token, "saber2Color8" ) ) 
02595                         {
02596                                 if ( COM_ParseString( &p, &value ) ) 
02597                                 {
02598                                         continue;
02599                                 }
02600                                 if ( NPC->client )
02601                                 {
02602                                         NPC->client->saber[1].blade[7].color = TranslateSaberColor( value );
02603                                 }
02604                                 continue;
02605                         }
02606 
02607                         //saber length
02608                         if ( !Q_stricmp( token, "saberLength" ) ) 
02609                         {
02610                                 if ( COM_ParseFloat( &p, &f ) ) 
02611                                 {
02612                                         SkipRestOfLine( &p );
02613                                         continue;
02614                                 }
02615                                 //cap
02616                                 if ( f < 4.0f )
02617                                 {
02618                                         f = 4.0f;
02619                                 }
02620 
02621                                 for ( n = 0; n < MAX_BLADES; n++ )
02622                                 {
02623                                         NPC->client->saber[0].blade[n].lengthMax = f;
02624                                 }
02625                                 continue;
02626                         }
02627 
02628                         if ( !Q_stricmp( token, "saberLength2" ) ) 
02629                         {
02630                                 if ( COM_ParseFloat( &p, &f ) ) 
02631                                 {
02632                                         SkipRestOfLine( &p );
02633                                         continue;
02634                                 }
02635                                 //cap
02636                                 if ( f < 4.0f )
02637                                 {
02638                                         f = 4.0f;
02639                                 }
02640                                 NPC->client->saber[0].blade[1].lengthMax = f;
02641                                 continue;
02642                         }
02643 
02644                         if ( !Q_stricmp( token, "saberLength3" ) ) 
02645                         {
02646                                 if ( COM_ParseFloat( &p, &f ) ) 
02647                                 {
02648                                         SkipRestOfLine( &p );
02649                                         continue;
02650                                 }
02651                                 //cap
02652                                 if ( f < 4.0f )
02653                                 {
02654                                         f = 4.0f;
02655                                 }
02656                                 NPC->client->saber[0].blade[2].lengthMax = f;
02657                                 continue;
02658                         }
02659 
02660                         if ( !Q_stricmp( token, "saberLength4" ) ) 
02661                         {
02662                                 if ( COM_ParseFloat( &p, &f ) ) 
02663                                 {
02664                                         SkipRestOfLine( &p );
02665                                         continue;
02666                                 }
02667                                 //cap
02668                                 if ( f < 4.0f )
02669                                 {
02670                                         f = 4.0f;
02671                                 }
02672                                 NPC->client->saber[0].blade[3].lengthMax = f;
02673                                 continue;
02674                         }
02675 
02676                         if ( !Q_stricmp( token, "saberLength5" ) ) 
02677                         {
02678                                 if ( COM_ParseFloat( &p, &f ) ) 
02679                                 {
02680                                         SkipRestOfLine( &p );
02681                                         continue;
02682                                 }
02683                                 //cap
02684                                 if ( f < 4.0f )
02685                                 {
02686                                         f = 4.0f;
02687                                 }
02688                                 NPC->client->saber[0].blade[4].lengthMax = f;
02689                                 continue;
02690                         }
02691 
02692                         if ( !Q_stricmp( token, "saberLength6" ) ) 
02693                         {
02694                                 if ( COM_ParseFloat( &p, &f ) ) 
02695                                 {
02696                                         SkipRestOfLine( &p );
02697                                         continue;
02698                                 }
02699                                 //cap
02700                                 if ( f < 4.0f )
02701                                 {
02702                                         f = 4.0f;
02703                                 }
02704                                 NPC->client->saber[0].blade[5].lengthMax = f;
02705                                 continue;
02706                         }
02707 
02708                         if ( !Q_stricmp( token, "saberLength7" ) ) 
02709                         {
02710                                 if ( COM_ParseFloat( &p, &f ) ) 
02711                                 {
02712                                         SkipRestOfLine( &p );
02713                                         continue;
02714                                 }
02715                                 //cap
02716                                 if ( f < 4.0f )
02717                                 {
02718                                         f = 4.0f;
02719                                 }
02720                                 NPC->client->saber[0].blade[6].lengthMax = f;
02721                                 continue;
02722                         }
02723 
02724                         if ( !Q_stricmp( token, "saberLength8" ) ) 
02725                         {
02726                                 if ( COM_ParseFloat( &p, &f ) ) 
02727                                 {
02728                                         SkipRestOfLine( &p );
02729                                         continue;
02730                                 }
02731                                 //cap
02732                                 if ( f < 4.0f )
02733                                 {
02734                                         f = 4.0f;
02735                                 }
02736                                 NPC->client->saber[0].blade[7].lengthMax = f;
02737                                 continue;
02738                         }
02739 
02740                         if ( !Q_stricmp( token, "saber2Length" ) ) 
02741                         {
02742                                 if ( COM_ParseFloat( &p, &f ) ) 
02743                                 {
02744                                         SkipRestOfLine( &p );
02745                                         continue;
02746                                 }
02747                                 //cap
02748                                 if ( f < 4.0f )
02749                                 {
02750                                         f = 4.0f;
02751                                 }
02752                                 for ( n = 0; n < MAX_BLADES; n++ )
02753                                 {
02754                                         NPC->client->saber[1].blade[n].lengthMax = f;
02755                                 }
02756                                 continue;
02757                         }
02758 
02759                         if ( !Q_stricmp( token, "saber2Length2" ) ) 
02760                         {
02761                                 if ( COM_ParseFloat( &p, &f ) ) 
02762                                 {
02763                                         SkipRestOfLine( &p );
02764                                         continue;
02765                                 }
02766                                 //cap
02767                                 if ( f < 4.0f )
02768                                 {
02769                                         f = 4.0f;
02770                                 }
02771                                 NPC->client->saber[1].blade[1].lengthMax = f;
02772                                 continue;
02773                         }
02774 
02775                         if ( !Q_stricmp( token, "saber2Length3" ) ) 
02776                         {
02777                                 if ( COM_ParseFloat( &p, &f ) ) 
02778                                 {
02779                                         SkipRestOfLine( &p );
02780                                         continue;
02781                                 }
02782                                 //cap
02783                                 if ( f < 4.0f )
02784                                 {
02785                                         f = 4.0f;
02786                                 }
02787                                 NPC->client->saber[1].blade[2].lengthMax = f;
02788                                 continue;
02789                         }
02790 
02791                         if ( !Q_stricmp( token, "saber2Length4" ) ) 
02792                         {
02793                                 if ( COM_ParseFloat( &p, &f ) ) 
02794                                 {
02795                                         SkipRestOfLine( &p );
02796                                         continue;
02797                                 }
02798                                 //cap
02799                                 if ( f < 4.0f )
02800                                 {
02801                                         f = 4.0f;
02802                                 }
02803                                 NPC->client->saber[1].blade[3].lengthMax = f;
02804                                 continue;
02805                         }
02806 
02807                         if ( !Q_stricmp( token, "saber2Length5" ) ) 
02808                         {
02809                                 if ( COM_ParseFloat( &p, &f ) ) 
02810                                 {
02811                                         SkipRestOfLine( &p );
02812                                         continue;
02813                                 }
02814                                 //cap
02815                                 if ( f < 4.0f )
02816                                 {
02817                                         f = 4.0f;
02818                                 }
02819                                 NPC->client->saber[1].blade[4].lengthMax = f;
02820                                 continue;
02821                         }
02822 
02823                         if ( !Q_stricmp( token, "saber2Length6" ) ) 
02824                         {
02825                                 if ( COM_ParseFloat( &p, &f ) ) 
02826                                 {
02827                                         SkipRestOfLine( &p );
02828                                         continue;
02829                                 }
02830                                 //cap
02831                                 if ( f < 4.0f )
02832                                 {
02833                                         f = 4.0f;
02834                                 }
02835                                 NPC->client->saber[1].blade[5].lengthMax = f;
02836                                 continue;
02837                         }
02838 
02839                         if ( !Q_stricmp( token, "saber2Length7" ) ) 
02840                         {
02841                                 if ( COM_ParseFloat( &p, &f ) ) 
02842                                 {
02843                                         SkipRestOfLine( &p );
02844                                         continue;
02845                                 }
02846                                 //cap
02847                                 if ( f < 4.0f )
02848                                 {
02849                                         f = 4.0f;
02850                                 }
02851                                 NPC->client->saber[1].blade[6].lengthMax = f;
02852                                 continue;
02853                         }
02854 
02855                         if ( !Q_stricmp( token, "saber2Length8" ) ) 
02856                         {
02857                                 if ( COM_ParseFloat( &p, &f ) ) 
02858                                 {
02859                                         SkipRestOfLine( &p );
02860                                         continue;
02861                                 }
02862                                 //cap
02863                                 if ( f < 4.0f )
02864                                 {
02865                                         f = 4.0f;
02866                                 }
02867                                 NPC->client->saber[1].blade[7].lengthMax = f;
02868                                 continue;
02869                         }
02870 
02871                         //saber radius
02872                         if ( !Q_stricmp( token, "saberRadius" ) ) 
02873                         {
02874                                 if ( COM_ParseFloat( &p, &f ) ) 
02875                                 {
02876                                         SkipRestOfLine( &p );
02877                                         continue;
02878                                 }
02879                                 //cap
02880                                 if ( f < 0.25f )
02881                                 {
02882                                         f = 0.25f;
02883                                 }
02884                                 for ( n = 0; n < MAX_BLADES; n++ )
02885                                 {
02886                                         NPC->client->saber[0].blade[n].radius = f;
02887                                 }
02888                                 continue;
02889                         }
02890 
02891                         if ( !Q_stricmp( token, "saberRadius2" ) ) 
02892                         {
02893                                 if ( COM_ParseFloat( &p, &f ) ) 
02894                                 {
02895                                         SkipRestOfLine( &p );
02896                                         continue;
02897                                 }
02898                                 //cap
02899                                 if ( f < 0.25f )
02900                                 {
02901                                         f = 0.25f;
02902                                 }
02903                                 NPC->client->saber[0].blade[1].radius = f;
02904                                 continue;
02905                         }
02906 
02907                         if ( !Q_stricmp( token, "saberRadius3" ) ) 
02908                         {
02909                                 if ( COM_ParseFloat( &p, &f ) ) 
02910                                 {
02911                                         SkipRestOfLine( &p );
02912                                         continue;
02913                                 }
02914                                 //cap
02915                                 if ( f < 0.25f )
02916                                 {
02917                                         f = 0.25f;
02918                                 }
02919                                 NPC->client->saber[0].blade[2].radius = f;
02920                                 continue;
02921                         }
02922 
02923                         if ( !Q_stricmp( token, "saberRadius4" ) ) 
02924                         {
02925                                 if ( COM_ParseFloat( &p, &f ) ) 
02926                                 {
02927                                         SkipRestOfLine( &p );
02928                                         continue;
02929                                 }
02930                                 //cap
02931                                 if ( f < 0.25f )
02932                                 {
02933                                         f = 0.25f;
02934                                 }
02935                                 NPC->client->saber[0].blade[3].radius = f;
02936                                 continue;
02937                         }
02938 
02939                         if ( !Q_stricmp( token, "saberRadius5" ) ) 
02940                         {
02941                                 if ( COM_ParseFloat( &p, &f ) ) 
02942                                 {
02943                                         SkipRestOfLine( &p );
02944                                         continue;
02945                                 }
02946                                 //cap
02947                                 if ( f < 0.25f )
02948                                 {
02949                                         f = 0.25f;
02950                                 }
02951                                 NPC->client->saber[0].blade[4].radius = f;
02952                                 continue;
02953                         }
02954 
02955                         if ( !Q_stricmp( token, "saberRadius6" ) ) 
02956                         {
02957                                 if ( COM_ParseFloat( &p, &f ) ) 
02958                                 {
02959                                         SkipRestOfLine( &p );
02960                                         continue;
02961                                 }
02962                                 //cap
02963                                 if ( f < 0.25f )
02964                                 {
02965                                         f = 0.25f;
02966                                 }
02967                                 NPC->client->saber[0].blade[5].radius = f;
02968                                 continue;
02969                         }
02970 
02971                         if ( !Q_stricmp( token, "saberRadius7" ) ) 
02972                         {
02973                                 if ( COM_ParseFloat( &p, &f ) ) 
02974                                 {
02975                                         SkipRestOfLine( &p );
02976                                         continue;
02977                                 }
02978                                 //cap
02979                                 if ( f < 0.25f )
02980                                 {
02981                                         f = 0.25f;
02982                                 }
02983                                 NPC->client->saber[0].blade[6].radius = f;
02984                                 continue;
02985                         }
02986 
02987                         if ( !Q_stricmp( token, "saberRadius8" ) ) 
02988                         {
02989                                 if ( COM_ParseFloat( &p, &f ) ) 
02990                                 {
02991                                         SkipRestOfLine( &p );
02992                                         continue;
02993                                 }
02994                                 //cap
02995                                 if ( f < 0.25f )
02996                                 {
02997                                         f = 0.25f;
02998                                 }
02999                                 NPC->client->saber[0].blade[7].radius = f;
03000                                 continue;
03001                         }
03002 
03003                         if ( !Q_stricmp( token, "saber2Radius" ) ) 
03004                         {
03005                                 if ( COM_ParseFloat( &p, &f ) ) 
03006                                 {
03007                                         SkipRestOfLine( &p );
03008                                         continue;
03009                                 }
03010                                 //cap
03011                                 if ( f < 0.25f )
03012                                 {
03013                                         f = 0.25f;
03014                                 }
03015                                 for ( n = 0; n < MAX_BLADES; n++ )
03016                                 {
03017                                         NPC->client->saber[1].blade[n].radius = f;
03018                                 }
03019                                 continue;
03020                         }
03021 
03022                         if ( !Q_stricmp( token, "saber2Radius2" ) ) 
03023                         {
03024                                 if ( COM_ParseFloat( &p, &f ) ) 
03025                                 {
03026                                         SkipRestOfLine( &p );
03027                                         continue;
03028                                 }
03029                                 //cap
03030                                 if ( f < 0.25f )
03031                                 {
03032                                         f = 0.25f;
03033                                 }
03034                                 NPC->client->saber[1].blade[1].radius = f;
03035                                 continue;
03036                         }
03037 
03038                         if ( !Q_stricmp( token, "saber2Radius3" ) ) 
03039                         {
03040                                 if ( COM_ParseFloat( &p, &f ) ) 
03041                                 {
03042                                         SkipRestOfLine( &p );
03043                                         continue;
03044                                 }
03045                                 //cap
03046                                 if ( f < 0.25f )
03047                                 {
03048                                         f = 0.25f;
03049                                 }
03050                                 NPC->client->saber[1].blade[2].radius = f;
03051                                 continue;
03052                         }
03053 
03054                         if ( !Q_stricmp( token, "saber2Radius4" ) ) 
03055                         {
03056                                 if ( COM_ParseFloat( &p, &f ) ) 
03057                                 {
03058                                         SkipRestOfLine( &p );
03059                                         continue;
03060                                 }
03061                                 //cap
03062                                 if ( f < 0.25f )
03063                                 {
03064                                         f = 0.25f;
03065                                 }
03066                                 NPC->client->saber[1].blade[3].radius = f;
03067                                 continue;
03068                         }
03069 
03070                         if ( !Q_stricmp( token, "saber2Radius5" ) ) 
03071                         {
03072                                 if ( COM_ParseFloat( &p, &f ) ) 
03073                                 {
03074                                         SkipRestOfLine( &p );
03075                                         continue;
03076                                 }
03077                                 //cap
03078                                 if ( f < 0.25f )
03079                                 {
03080                                         f = 0.25f;
03081                                 }
03082                                 NPC->client->saber[1].blade[4].radius = f;
03083                                 continue;
03084                         }
03085 
03086                         if ( !Q_stricmp( token, "saber2Radius6" ) ) 
03087                         {
03088                                 if ( COM_ParseFloat( &p, &f ) ) 
03089                                 {
03090                                         SkipRestOfLine( &p );
03091                                         continue;
03092                                 }
03093                                 //cap
03094                                 if ( f < 0.25f )
03095                                 {
03096                                         f = 0.25f;
03097                                 }
03098                                 NPC->client->saber[1].blade[5].radius = f;
03099                                 continue;
03100                         }
03101 
03102                         if ( !Q_stricmp( token, "saber2Radius7" ) ) 
03103                         {
03104                                 if ( COM_ParseFloat( &p, &f ) ) 
03105                                 {
03106                                         SkipRestOfLine( &p );
03107                                         continue;
03108                                 }
03109                                 //cap
03110                                 if ( f < 0.25f )
03111                                 {
03112                                         f = 0.25f;
03113                                 }
03114                                 NPC->client->saber[1].blade[6].radius = f;
03115                                 continue;
03116                         }
03117 
03118                         if ( !Q_stricmp( token, "saber2Radius8" ) ) 
03119                         {
03120                                 if ( COM_ParseFloat( &p, &f ) ) 
03121                                 {
03122                                         SkipRestOfLine( &p );
03123                                         continue;
03124                                 }
03125                                 //cap
03126                                 if ( f < 0.25f )
03127                                 {
03128                                         f = 0.25f;
03129                                 }
03130                                 NPC->client->saber[1].blade[7].radius = f;
03131                                 continue;
03132                         }
03133 
03134                         //ADD:
03135                         //saber sounds (on, off, loop)
03136                         //loop sound (like Vader's breathing or droid bleeps, etc.)
03137 
03138                         //starting saber style
03139                         if ( !Q_stricmp( token, "saberStyle" ) ) 
03140                         {
03141                                 if ( COM_ParseInt( &p, &n ) ) 
03142                                 {
03143                                         SkipRestOfLine( &p );
03144                                         continue;
03145                                 }
03146                                 //cap
03147                                 if ( n < 0 )
03148                                 {
03149                                         n = 0;
03150                                 }
03151                                 else if ( n > 5 )
03152                                 {
03153                                         n = 5;
03154                                 }
03155                                 NPC->client->ps.fd.saberAnimLevel = n;
03156                                 /*
03157                                 if ( parsingPlayer )
03158                                 {
03159                                         cg.saberAnimLevelPending = n;
03160                                 }
03161                                 */
03162                                 continue;
03163                         }
03164 
03165                         if ( !parsingPlayer )
03166                         {
03167                                 Com_Printf( "WARNING: unknown keyword '%s' while parsing '%s'\n", token, NPCName );
03168                         }
03169                         SkipRestOfLine( &p );
03170                 }
03171         }
03172 
03173 /*
03174 Ghoul2 Insert Start
03175 */
03176         if ( !md3Model )
03177         {
03178                 qboolean setTypeBack = qfalse;
03179 
03180                 if (npcSaber1 == 0)
03181                 { //use "kyle" for a default then
03182                         npcSaber1 = G_ModelIndex("@Kyle");
03183                         WP_SaberParseParms( "Kyle", &NPC->client->saber[0] );
03184                 }
03185 
03186                 NPC->s.npcSaber1 = npcSaber1;
03187                 NPC->s.npcSaber2 = npcSaber2;
03188 
03189                 if (!customSkin[0])
03190                 {
03191                         strcpy(customSkin, "default");
03192                 }
03193 
03194                 if ( NPC->client && NPC->client->NPC_class == CLASS_VEHICLE )
03195                 { //vehicles want their names fed in as models
03196                         //we put the $ in front to indicate a name and not a model
03197                         strcpy(playerModel, va("$%s", NPCName));
03198                 }
03199                 SetupGameGhoul2Model(NPC, playerModel, customSkin);
03200 
03201                 if (!NPC->NPC_type)
03202                 { //just do this for now so NPC_Precache can see the name.
03203                         NPC->NPC_type = (char *)NPCName;
03204                         setTypeBack = qtrue;
03205                 }
03206 
03207                 NPC_Precache(NPC); //this will just soundindex some values for sounds on the client,
03208 
03209                 if (setTypeBack)
03210                 { //don't want this being set if we aren't ready yet.
03211                         NPC->NPC_type = NULL;
03212                 }
03213         }
03214         else
03215         {
03216                 Com_Printf("MD3 MODEL NPC'S ARE NOT SUPPORTED IN MP!\n");
03217                 return qfalse;
03218         }
03219 /*
03220 Ghoul2 Insert End
03221 */
03222         /*
03223         if(     NPCsPrecached )
03224         {//Spawning in after initial precache, our models are precached, we just need to set our clientInfo
03225                 CG_RegisterClientModels( NPC->s.number );
03226                 CG_RegisterNPCCustomSounds( ci );
03227                 CG_RegisterNPCEffects( NPC->client->playerTeam );
03228         }
03229         */
03230         //rwwFIXMEFIXME: Do something here I guess to properly precache stuff.
03231 
03232         return qtrue;
03233 }

void NPC_Precache gentity_t spawner  ) 
 

Definition at line 599 of file NPC_stats.c.

References BG_FindItemForWeapon(), BG_ParseLiteral(), CLASS_VEHICLE, gentity_s::client, COM_BeginParseSession(), COM_ParseExt(), COM_ParseString(), Com_Printf(), Com_sprintf(), entityState_s::csSounds_Combat, entityState_s::csSounds_Extra, entityState_s::csSounds_Jedi, entityState_s::csSounds_Std, G_ModelIndex(), G_SoundIndex(), gentity_t, GetIDForString(), MAX_QPATH, gclient_s::NPC_class, NPC_PrecacheWeapons(), gentity_s::NPC_type, NPCFile, NPCParms, NPCTEAM_FREE, npcteam_t, Q_stricmp(), Q_strncpyz(), qboolean, qfalse, qtrue, gentity_s::r, RegisterItem(), gentity_s::s, S_COLOR_RED, SkipBracedSection(), gentity_s::spawnflags, strcat(), strcpy(), strstr(), SVF_NO_BASIC_SOUNDS, SVF_NO_COMBAT_SOUNDS, SVF_NO_EXTRA_SOUNDS, entityShared_t::svFlags, team_t, TeamTable, va(), weapon_t, WP_NONE, WP_NUM_WEAPONS, and WPTable.

Referenced by NPC_ParseParms(), NPC_PrecacheType(), and SP_NPC_spawner().

00600 {
00601         npcteam_t                       playerTeam = NPCTEAM_FREE;
00602         const char      *token;
00603         const char      *value;
00604         const char      *p;
00605         char    *patch;
00606         char    sound[MAX_QPATH];
00607         qboolean        md3Model = qfalse;
00608         char    playerModel[MAX_QPATH];
00609         char    customSkin[MAX_QPATH];
00610 
00611         if ( !Q_stricmp( "random", spawner->NPC_type ) )
00612         {//sorry, can't precache a random just yet
00613                 return;
00614         }
00615         strcpy(customSkin,"default");
00616 
00617         p = NPCParms;
00618         COM_BeginParseSession(NPCFile);
00619 
00620         // look for the right NPC
00621         while ( p ) 
00622         {
00623                 token = COM_ParseExt( &p, qtrue );
00624                 if ( token[0] == 0 )
00625                         return;
00626 
00627                 if ( !Q_stricmp( token, spawner->NPC_type ) ) 
00628                 {
00629                         break;
00630                 }
00631 
00632                 SkipBracedSection( &p );
00633         }
00634 
00635         if ( !p ) 
00636         {
00637                 return;
00638         }
00639 
00640         if ( BG_ParseLiteral( &p, "{" ) ) 
00641         {
00642                 return;
00643         }
00644 
00645         // parse the NPC info block
00646         while ( 1 ) 
00647         {
00648                 token = COM_ParseExt( &p, qtrue );
00649                 if ( !token[0] ) 
00650                 {
00651                         Com_Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s'\n", spawner->NPC_type );
00652                         return;
00653                 }
00654 
00655                 if ( !Q_stricmp( token, "}" ) ) 
00656                 {
00657                         break;
00658                 }
00659 
00660                 // headmodel
00661                 if ( !Q_stricmp( token, "headmodel" ) ) 
00662                 {
00663                         if ( COM_ParseString( &p, &value ) ) 
00664                         {
00665                                 continue;
00666                         }
00667 
00668                         if(!Q_stricmp("none", value))
00669                         {
00670                         }
00671                         else
00672                         {
00673                                 //Q_strncpyz( ri.headModelName, value, sizeof(ri.headModelName), qtrue);
00674                         }
00675                         md3Model = qtrue;
00676                         continue;
00677                 }
00678                 
00679                 // torsomodel
00680                 if ( !Q_stricmp( token, "torsomodel" ) ) 
00681                 {
00682                         if ( COM_ParseString( &p, &value ) ) 
00683                         {
00684                                 continue;
00685                         }
00686 
00687                         if(!Q_stricmp("none", value))
00688                         {
00689                         }
00690                         else
00691                         {
00692                                 //Q_strncpyz( ri.torsoModelName, value, sizeof(ri.torsoModelName), qtrue);
00693                         }
00694                         md3Model = qtrue;
00695                         continue;
00696                 }
00697 
00698                 // legsmodel
00699                 if ( !Q_stricmp( token, "legsmodel" ) ) 
00700                 {
00701                         if ( COM_ParseString( &p, &value ) ) 
00702                         {
00703                                 continue;
00704                         }
00705                         //Q_strncpyz( ri.legsModelName, value, sizeof(ri.legsModelName), qtrue);                        
00706                         md3Model = qtrue;
00707                         continue;
00708                 }
00709 
00710                 // playerModel
00711                 if ( !Q_stricmp( token, "playerModel" ) ) 
00712                 {
00713                         if ( COM_ParseString( &p, &value ) ) 
00714                         {
00715                                 continue;
00716                         }
00717                         Q_strncpyz( playerModel, value, sizeof(playerModel));                   
00718                         md3Model = qfalse;
00719                         continue;
00720                 }
00721 
00722                 // customSkin
00723                 if ( !Q_stricmp( token, "customSkin" ) ) 
00724                 {
00725                         if ( COM_ParseString( &p, &value ) ) 
00726                         {
00727                                 continue;
00728                         }
00729                         Q_strncpyz( customSkin, value, sizeof(customSkin));                     
00730                         continue;
00731                 }
00732 
00733                 // playerTeam
00734                 if ( !Q_stricmp( token, "playerTeam" ) ) 
00735                 {
00736                         char tk[4096]; //rww - hackilicious!
00737 
00738                         if ( COM_ParseString( &p, &value ) ) 
00739                         {
00740                                 continue;
00741                         }
00742                         //playerTeam = TranslateTeamName(value);
00743                         Com_sprintf(tk, sizeof(tk), "NPC%s", token);
00744                         playerTeam = (team_t)GetIDForString( TeamTable, tk );
00745                         continue;
00746                 }
00747 
00748         
00749                 // snd
00750                 if ( !Q_stricmp( token, "snd" ) ) {
00751                         if ( COM_ParseString( &p, &value ) ) {
00752                                 continue;
00753                         }
00754                         if ( !(spawner->r.svFlags&SVF_NO_BASIC_SOUNDS) )
00755                         {
00756                                 //FIXME: store this in some sound field or parse in the soundTable like the animTable...
00757                                 Q_strncpyz( sound, value, sizeof( sound ) );
00758                                 patch = strstr( sound, "/" );
00759                                 if ( patch ) 
00760                                 {
00761                                         *patch = 0;
00762                                 }
00763                                 spawner->s.csSounds_Std = G_SoundIndex( va("*$%s", sound) );
00764                         }
00765                         continue;
00766                 }
00767 
00768                 // sndcombat
00769                 if ( !Q_stricmp( token, "sndcombat" ) ) {
00770                         if ( COM_ParseString( &p, &value ) ) {
00771                                 continue;
00772                         }
00773                         if ( !(spawner->r.svFlags&SVF_NO_COMBAT_SOUNDS) )
00774                         {
00775                                 //FIXME: store this in some sound field or parse in the soundTable like the animTable...
00776                                 Q_strncpyz( sound, value, sizeof( sound ) );
00777                                 patch = strstr( sound, "/" );
00778                                 if ( patch ) 
00779                                 {
00780                                         *patch = 0;
00781                                 }
00782                                 spawner->s.csSounds_Combat = G_SoundIndex( va("*$%s", sound) );
00783                         }
00784                         continue;
00785                 }
00786                 
00787                 // sndextra
00788                 if ( !Q_stricmp( token, "sndextra" ) ) {
00789                         if ( COM_ParseString( &p, &value ) ) {
00790                                 continue;
00791                         }
00792                         if ( !(spawner->r.svFlags&SVF_NO_EXTRA_SOUNDS) )
00793                         {
00794                                 //FIXME: store this in some sound field or parse in the soundTable like the animTable...
00795                                 Q_strncpyz( sound, value, sizeof( sound ) );
00796                                 patch = strstr( sound, "/" );
00797                                 if ( patch ) 
00798                                 {
00799                                         *patch = 0;
00800                                 }
00801                                 spawner->s.csSounds_Extra = G_SoundIndex( va("*$%s", sound) );
00802                         }
00803                         continue;
00804                 }
00805 
00806                 // sndjedi
00807                 if ( !Q_stricmp( token, "sndjedi" ) ) {
00808                         if ( COM_ParseString( &p, &value ) ) {
00809                                 continue;
00810                         }
00811                         if ( !(spawner->r.svFlags&SVF_NO_EXTRA_SOUNDS) )
00812                         {
00813                                 //FIXME: store this in some sound field or parse in the soundTable like the animTable...
00814                                 Q_strncpyz( sound, value, sizeof( sound ) );
00815                                 patch = strstr( sound, "/" );
00816                                 if ( patch ) 
00817                                 {
00818                                         *patch = 0;
00819                                 }
00820                                 spawner->s.csSounds_Jedi = G_SoundIndex( va("*$%s", sound) );
00821                         }
00822                         continue;
00823                 }
00824 
00825                 if (!Q_stricmp(token, "weapon"))
00826                 {
00827                         int curWeap;
00828 
00829                         if (COM_ParseString(&p, &value))
00830                         {
00831                                 continue;
00832                         }
00833 
00834                         curWeap = GetIDForString( WPTable, value );
00835 
00836                         if (curWeap > WP_NONE && curWeap < WP_NUM_WEAPONS)
00837                         {
00838                                 RegisterItem(BG_FindItemForWeapon((weapon_t)curWeap));
00839                         }
00840                         continue;
00841                 }
00842         }
00843 
00844         // If we're not a vehicle, then an error here would be valid...
00845         if ( !spawner->client || spawner->client->NPC_class != CLASS_VEHICLE )
00846         {
00847                 if ( md3Model )
00848                 {
00849                         Com_Printf("MD3 model using NPCs are not supported in MP\n");
00850                 }
00851                 else
00852                 { //if we have a model/skin then index them so they'll be registered immediately
00853                         //when the client gets a configstring update.
00854                         char modelName[MAX_QPATH];
00855 
00856                         Com_sprintf(modelName, sizeof(modelName), "models/players/%s/model.glm", playerModel);
00857                         if (customSkin[0])
00858                         { //append it after a *
00859                                 strcat( modelName, va("*%s", customSkin) );
00860                         }
00861 
00862                         G_ModelIndex(modelName);
00863                 }
00864         }
00865 
00866         //precache this NPC's possible weapons
00867         NPC_PrecacheWeapons( playerTeam, spawner->spawnflags, spawner->NPC_type );
00868 
00869 //      CG_RegisterNPCCustomSounds( &ci );
00870 //      CG_RegisterNPCEffects( playerTeam );
00871         //rwwFIXMEFIXME: same
00872         //FIXME: Look for a "sounds" directory and precache death, pain, alert sounds
00873 }

void NPC_PrecacheAnimationCFG const char *  NPC_type  ) 
 

Definition at line 439 of file NPC_stats.c.

References BG_ParseLiteral(), COM_BeginParseSession(), COM_ParseExt(), COM_ParseString(), Com_Printf(), G_ParseAnimFileSet(), MAX_QPATH, NPCFile, NPCParms, Q_stricmp(), Q_strncpyz(), qtrue, S_COLOR_RED, and SkipBracedSection().

Referenced by SP_NPC_spawner().

00440 {
00441 #if 0 //rwwFIXMEFIXME: Actually precache stuff here.
00442         char    filename[MAX_QPATH];
00443         const char      *token;
00444         const char      *value;
00445         const char      *p;
00446         int             junk;
00447 
00448         if ( !Q_stricmp( "random", NPC_type ) )
00449         {//sorry, can't precache a random just yet
00450                 return;
00451         }
00452 
00453         p = NPCParms;
00454         COM_BeginParseSession(NPCFile);
00455 
00456         // look for the right NPC
00457         while ( p ) 
00458         {
00459                 token = COM_ParseExt( &p, qtrue );
00460                 if ( token[0] == 0 )
00461                         return;
00462 
00463                 if ( !Q_stricmp( token, NPC_type ) ) 
00464                 {
00465                         break;
00466                 }
00467 
00468                 SkipBracedSection( &p );
00469         }
00470 
00471         if ( !p ) 
00472         {
00473                 return;
00474         }
00475 
00476         if ( BG_ParseLiteral( &p, "{" ) ) 
00477         {
00478                 return;
00479         }
00480 
00481         // parse the NPC info block
00482         while ( 1 ) 
00483         {
00484                 token = COM_ParseExt( &p, qtrue );
00485                 if ( !token[0] ) 
00486                 {
00487                         Com_Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s'\n", NPC_type );
00488                         return;
00489                 }
00490 
00491                 if ( !Q_stricmp( token, "}" ) ) 
00492                 {
00493                         break;
00494                 }
00495 
00496                 // legsmodel
00497                 if ( !Q_stricmp( token, "legsmodel" ) ) 
00498                 {
00499                         if ( COM_ParseString( &p, &value ) ) 
00500                         {
00501                                 continue;
00502                         }
00503                         //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
00504                         Q_strncpyz( filename, value, sizeof( filename ) );
00505                         G_ParseAnimFileSet( filename, filename, &junk );
00506                         return;
00507                 }
00508 
00509                 // playerModel
00510                 if ( !Q_stricmp( token, "playerModel" ) ) 
00511                 {
00512                         if ( COM_ParseString( &p, &value ) ) 
00513                         {
00514                                 continue;
00515                         }
00516                         /*
00517                         char    animName[MAX_QPATH];
00518                         char    *GLAName;
00519                         char    *slash = NULL;
00520                         char    *strippedName;
00521                         
00522                         int handle = gi.G2API_PrecacheGhoul2Model( va( "models/players/%s/model.glm", value ) );
00523                         if ( handle > 0 )//FIXME: isn't 0 a valid handle?
00524                         {
00525                                 GLAName = gi.G2API_GetAnimFileNameIndex( handle );
00526                                 if ( GLAName )
00527                                 {
00528                                         Q_strncpyz( animName, GLAName, sizeof( animName ), qtrue );
00529                                         slash = strrchr( animName, '/' );
00530                                         if ( slash )
00531                                         {
00532                                                 *slash = 0;
00533                                         }
00534                                         strippedName = COM_SkipPath( animName );
00535 
00536                                         //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
00537                                         Q_strncpyz( filename, value, sizeof( filename ), qtrue );
00538                                         G_ParseAnimFileSet( value, strippedName, &junk );//qfalse );
00539                                         //FIXME: still not precaching the animsounds.cfg?
00540                                         return;
00541                                 }
00542                         }
00543                         */
00544                         //rwwFIXMEFIXME: Do this properly.
00545                 }
00546         }
00547 #endif
00548 }

void NPC_PrecacheWeapons team_t  playerTeam,
int  spawnflags,
char *  NPCtype
 

Definition at line 551 of file NPC_stats.c.

References BG_FindItemForWeapon(), bg_itemlist, CG_RegisterItemVisuals(), gitem_t, NPC_WeaponsForTeam(), RegisterItem(), strcat(), strcpy(), strstr(), team_t, weapon_t, weaponData, WP_NUM_WEAPONS, and WP_SABER.

Referenced by NPC_Precache().

00552 {
00553         int weapons = NPC_WeaponsForTeam( playerTeam, spawnflags, NPCtype );
00554         int curWeap;
00555 
00556         for ( curWeap = WP_SABER; curWeap < WP_NUM_WEAPONS; curWeap++ )
00557         {
00558                 if (weapons & (1 << curWeap))
00559                 {
00560                         RegisterItem(BG_FindItemForWeapon((weapon_t)curWeap));
00561                 }
00562         }
00563 
00564 #if 0 //rwwFIXMEFIXME: actually precache weapons here
00565         int weapons = NPC_WeaponsForTeam( playerTeam, spawnflags, NPCtype );
00566         gitem_t *item;
00567         for ( int curWeap = WP_SABER; curWeap < WP_NUM_WEAPONS; curWeap++ )
00568         {
00569                 if ( (weapons & ( 1 << curWeap )) )
00570                 {
00571                         item = FindItemForWeapon( ((weapon_t)(curWeap)) );      //precache the weapon
00572                         CG_RegisterItemSounds( (item-bg_itemlist) );
00573                         CG_RegisterItemVisuals( (item-bg_itemlist) );
00574                         //precache the in-hand/in-world ghoul2 weapon model
00575 
00576                         char weaponModel[64];
00577                         
00578                         strcpy (weaponModel, weaponData[curWeap].weaponMdl);    
00579                         if (char *spot = strstr(weaponModel, ".md3") ) {
00580                                 *spot = 0;
00581                                 spot = strstr(weaponModel, "_w");//i'm using the in view weapon array instead of scanning the item list, so put the _w back on
00582                                 if (!spot) {
00583                                         strcat (weaponModel, "_w");
00584                                 }
00585                                 strcat (weaponModel, ".glm");   //and change to ghoul2
00586                         }
00587                         gi.G2API_PrecacheGhoul2Model( weaponModel ); // correct way is item->world_model
00588                 }
00589         }
00590 #endif
00591 }

int NPC_ReactionTime void   ) 
 

Definition at line 220 of file NPC_stats.c.

References NPCInfo, gNPCstats_e::reactions, and gNPC_t::stats.

00221 {
00222         return 200 * ( 6 - NPCInfo->stats.reactions );
00223 }

int NPC_WeaponsForTeam team_t  team,
int  spawnflags,
const char *  NPC_type
 

Definition at line 509 of file NPC_spawn.c.

References NPCTEAM_ENEMY, NPCTEAM_NEUTRAL, NPCTEAM_PLAYER, Q_stricmp(), Q_strncmp(), SFB_PHASER, SFB_RIFLEMAN, team_t, WP_BLASTER, WP_BOWCASTER, WP_DISRUPTOR, WP_FLECHETTE, WP_NONE, WP_REPEATER, WP_ROCKET_LAUNCHER, WP_SABER, WP_STUN_BATON, and WP_THERMAL.

Referenced by NPC_PrecacheWeapons(), and NPC_SetWeapons().

00510 {
00511         //*** not sure how to handle this, should I pass in class instead of team and go from there? - dmv
00512         switch(team)
00513         {
00514         // no longer exists
00515 //      case TEAM_BORG:
00516 //              break;
00517 
00518 //      case TEAM_HIROGEN:
00519 //              if( Q_stricmp( "hirogenalpha", NPC_type ) == 0 )
00520 //                      return ( 1 << WP_BLASTER);
00521                 //Falls through
00522 
00523 //      case TEAM_KLINGON:
00524 
00525                 //NOTENOTE: Falls through
00526 
00527 //      case TEAM_IMPERIAL:
00528         case NPCTEAM_ENEMY:
00529                 if ( Q_stricmp( "tavion", NPC_type ) == 0 || 
00530                         Q_strncmp( "reborn", NPC_type, 6 ) == 0 || 
00531                         Q_stricmp( "desann", NPC_type ) == 0 || 
00532                         Q_strncmp( "shadowtrooper", NPC_type, 13 ) == 0 )
00533                         return ( 1 << WP_SABER);
00534 //                      return ( 1 << WP_IMPERIAL_BLADE);
00535                 //NOTENOTE: Falls through if not a knife user
00536 
00537 //      case TEAM_SCAVENGERS:
00538 //      case TEAM_MALON:
00539                 //FIXME: default weapon in npc config?
00540                 if ( Q_strncmp( "stofficer", NPC_type, 9 ) == 0 )
00541                 {
00542                         return ( 1 << WP_FLECHETTE);
00543                 }
00544                 if ( Q_stricmp( "stcommander", NPC_type ) == 0 )
00545                 {
00546                         return ( 1 << WP_REPEATER);
00547                 }
00548                 if ( Q_stricmp( "swamptrooper", NPC_type ) == 0 )
00549                 {
00550                         return ( 1 << WP_FLECHETTE);
00551                 }
00552                 if ( Q_stricmp( "swamptrooper2", NPC_type ) == 0 )
00553                 {
00554                         return ( 1 << WP_REPEATER);
00555                 }
00556                 if ( Q_stricmp( "rockettrooper", NPC_type ) == 0 )
00557                 {
00558                         return ( 1 << WP_ROCKET_LAUNCHER);
00559                 }
00560                 if ( Q_strncmp( "shadowtrooper", NPC_type, 13 ) == 0 )
00561                 {
00562                         return ( 1 << WP_SABER);//|( 1 << WP_RAPID_CONCUSSION)?
00563                 }
00564                 if ( Q_stricmp( "imperial", NPC_type ) == 0 )
00565                 {
00566                         //return ( 1 << WP_BLASTER_PISTOL);
00567                         return ( 1 << WP_BLASTER);
00568                 }
00569                 if ( Q_strncmp( "impworker", NPC_type, 9 ) == 0 )
00570                 {
00571                         //return ( 1 << WP_BLASTER_PISTOL);
00572                         return ( 1 << WP_BLASTER);
00573                 }
00574                 if ( Q_stricmp( "stormpilot", NPC_type ) == 0 )
00575                 {
00576                         //return ( 1 << WP_BLASTER_PISTOL);
00577                         return ( 1 << WP_BLASTER);
00578                 }
00579                 if ( Q_stricmp( "galak", NPC_type ) == 0 )
00580                 {
00581                         return ( 1 << WP_BLASTER);
00582                 }
00583                 if ( Q_stricmp( "galak_mech", NPC_type ) == 0 )
00584                 {
00585                         return ( 1 << WP_REPEATER);
00586                 }
00587                 if ( Q_strncmp( "ugnaught", NPC_type, 8 ) == 0 )
00588                 {
00589                         return WP_NONE;
00590                 }
00591                 if ( Q_stricmp( "granshooter", NPC_type ) == 0 )
00592                 {
00593                         return ( 1 << WP_BLASTER);
00594                 }
00595                 if ( Q_stricmp( "granboxer", NPC_type ) == 0 )
00596                 {
00597                         return ( 1 << WP_STUN_BATON);
00598                 }
00599                 if ( Q_strncmp( "gran", NPC_type, 4 ) == 0 )
00600                 {
00601                         return (( 1 << WP_THERMAL)|( 1 << WP_STUN_BATON));
00602                 }
00603                 if ( Q_stricmp( "rodian", NPC_type ) == 0 )
00604                 {
00605                         return ( 1 << WP_DISRUPTOR);
00606                 }
00607                 if ( Q_stricmp( "rodian2", NPC_type ) == 0 )
00608                 {
00609                         return ( 1 << WP_BLASTER);
00610                 }
00611 
00612                 if (( Q_stricmp( "interrogator",NPC_type) == 0) || ( Q_stricmp( "sentry",NPC_type) == 0) || (Q_strncmp( "protocol",NPC_type,8) == 0) )
00613                 {
00614                         return WP_NONE;
00615                 }
00616 
00617                 if ( Q_strncmp( "weequay", NPC_type, 7 ) == 0 )
00618                 {
00619                         return ( 1 << WP_BOWCASTER);//|( 1 << WP_STAFF )(FIXME: new weap?)
00620                 }
00621                 if ( Q_stricmp( "impofficer", NPC_type ) == 0 )
00622                 {
00623                         return ( 1 << WP_BLASTER);
00624                 }
00625                 if ( Q_stricmp( "impcommander", NPC_type ) == 0 )
00626                 {
00627                         return ( 1 << WP_BLASTER);
00628                 }
00629                 if (( Q_stricmp( "probe", NPC_type ) == 0 ) || ( Q_stricmp( "seeker", NPC_type ) == 0 ))
00630                 {
00631                         //return ( 1 << WP_BOT_LASER);
00632                         return 0;
00633                 }       
00634                 if ( Q_stricmp( "remote", NPC_type ) == 0 )
00635                 {
00636                         //return ( 1 << WP_BOT_LASER );
00637                         return 0;
00638                 }       
00639                 if ( Q_stricmp( "trandoshan", NPC_type ) == 0 )
00640                 {
00641                         return (1<<WP_REPEATER);
00642                 }
00643                 if ( Q_stricmp( "atst", NPC_type ) == 0 )
00644                 {
00645                         //return (( 1 << WP_ATST_MAIN)|( 1 << WP_ATST_SIDE));
00646                         return 0;
00647                 }
00648                 if ( Q_stricmp( "mark1", NPC_type ) == 0 )
00649                 {
00650                         //return ( 1 << WP_BOT_LASER);
00651                         return 0;
00652                 }
00653                 if ( Q_stricmp( "mark2", NPC_type ) == 0 )
00654                 {
00655                         //return ( 1 << WP_BOT_LASER);
00656                         return 0;
00657                 }
00658                 if ( Q_stricmp( "minemonster", NPC_type ) == 0 )
00659                 {
00660                         return (( 1 << WP_STUN_BATON));
00661                 }
00662                 if ( Q_stricmp( "howler", NPC_type ) == 0 )
00663                 {
00664                         return (( 1 << WP_STUN_BATON));
00665                 }
00666                 //Stormtroopers, etc.
00667                 return ( 1 << WP_BLASTER);
00668                 break;
00669 
00670         case NPCTEAM_PLAYER:
00671                 
00672 //              if(spawnflags & SFB_TRICORDER)
00673 //                      return ( 1 << WP_TRICORDER);
00674                 
00675                 if(spawnflags & SFB_RIFLEMAN)
00676                         return ( 1 << WP_REPEATER);
00677                 
00678                 if(spawnflags & SFB_PHASER)
00679                         //return ( 1 << WP_BLASTER_PISTOL);
00680                         return ( 1 << WP_BLASTER);
00681 
00682                 if ( Q_strncmp( "jedi", NPC_type, 4 ) == 0 || Q_stricmp( "luke", NPC_type ) == 0 )
00683                         return ( 1 << WP_SABER);
00684 
00685                 if ( Q_strncmp( "prisoner", NPC_type, 8 ) == 0 )
00686                 {
00687                         return WP_NONE;
00688                 }
00689                 if ( Q_strncmp( "bespincop", NPC_type, 9 ) == 0 )
00690                 {
00691                         //return ( 1 << WP_BLASTER_PISTOL);
00692                         return ( 1 << WP_BLASTER);
00693                 }
00694 
00695                 if ( Q_stricmp( "MonMothma", NPC_type ) == 0 )
00696                 {
00697                         return WP_NONE;
00698                 }
00699 
00700                 //rebel
00701                 return ( 1 << WP_BLASTER);
00702                 break;
00703 
00704         case NPCTEAM_NEUTRAL:
00705 
00706                 if ( Q_stricmp( "mark1", NPC_type ) == 0 )
00707                 {
00708                         return WP_NONE;
00709                 }       
00710                 if ( Q_stricmp( "mark2", NPC_type ) == 0 )
00711                 {
00712                         return WP_NONE;
00713                 }       
00714                 if ( Q_strncmp( "ugnaught", NPC_type, 8 ) == 0 )
00715                 {
00716                         return WP_NONE;
00717                 }       
00718                 if ( Q_stricmp( "bartender", NPC_type ) == 0 )
00719                 {
00720                         return WP_NONE;
00721                 }
00722                 if ( Q_stricmp( "morgankatarn", NPC_type ) == 0 )
00723                 {
00724                         return WP_NONE;
00725                 }
00726         
00727                 break;
00728 
00729         // these no longer exist
00730 //      case TEAM_FORGE:
00731 //              return ( 1 << WP_STUN_BATON);
00732 //              break;
00733 
00734 //      case TEAM_STASIS:
00735 //              return ( 1 << WP_STUN_BATON);
00736 //              break;
00737 
00738 //      case TEAM_PARASITE:
00739 //              break;
00740 
00741 //      case TEAM_8472:
00742 //              break;
00743 
00744         default:
00745                 break;
00746         }
00747 
00748         return WP_NONE;
00749 }

void SetupGameGhoul2Model gentity_t ent,
char *  modelname,
char *  skinName
 

Definition at line 1519 of file g_client.c.

References BG_GetVehicleModelName(), BG_IsValidCharacterModel(), BG_ParseAnimationFile(), BG_ValidateSkinForTeam(), bgHumanoidAnimations, BGPAFtextLoaded, bgSiegeClasses, BONE_ANGLES_POSTMULT, BONE_ANIM_OVERRIDE_LOOP, CLASS_VEHICLE, gentity_s::client, Com_Error(), Com_Printf(), Com_sprintf(), d_perPlayerGhoul2, ERR_DROP, siegeClass_t::forcedSkin, g2SaberInstance, g_gametype, G_ModelIndex(), G_PlayerHasCustomSkeleton(), G_SaberModelSetup(), g_trueJedi, gentity_t, gentity_s::ghoul2, GT_SIEGE, GT_TEAM, turretStats_t::gunnerViewTag, vmCvar_t::integer, level, gentity_s::localAnimIndex, Vehicle_s::m_iDroidUnitTag, Vehicle_s::m_iExhaustTag, Vehicle_s::m_iGunnerViewTag, Vehicle_s::m_iMuzzleTag, gentity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, MAX_CLIENTS, MAX_QPATH, MAX_VEHICLE_EXHAUSTS, MAX_VEHICLE_MUZZLES, MAX_VEHICLE_TURRET_MUZZLES, entityState_s::modelGhoul2, entityState_s::modelindex, NEGATIVE_Y, NEGATIVE_Z, gentity_s::noLumbar, entityState_s::NPC_class, gclient_s::NPC_class, NULL, entityState_s::number, POSITIVE_X, POSITIVE_Z, precachedKyle, gclient_s::ps, Q_strrchr(), qfalse, qtrue, gentity_s::s, gclient_s::sess, clientSession_t::sessionTeam, gclient_s::siegeClass, vehicleInfo_t::skin, strcat(), strchr(), strcpy(), strstr(), level_locals_t::time, trap_G2_HaveWeGhoul2Models(), trap_G2API_AddBolt(), trap_G2API_AttachInstanceToEntNum(), trap_G2API_CleanGhoul2Models(), trap_G2API_CopySpecificGhoul2Model(), trap_G2API_DuplicateGhoul2Instance(), trap_G2API_GetGLAName(), trap_G2API_InitGhoul2Model(), trap_G2API_SetBoltInfo(), trap_G2API_SetBoneAngles(), trap_G2API_SetBoneAnim(), trap_G2API_SetSkin(), trap_R_RegisterSkin(), vehicleInfo_t::turret, va(), vec3_t, playerState_s::weapon, and WP_SABER.

Referenced by ClientBegin(), ClientUserinfoChanged(), and NPC_ParseParms().

01520 {
01521         int handle;
01522         char            afilename[MAX_QPATH];
01523 #if 0
01524         char             *slash;
01525 #endif
01526         char            GLAName[MAX_QPATH];
01527         vec3_t  tempVec = {0,0,0};
01528 
01529         // First things first.  If this is a ghoul2 model, then let's make sure we demolish this first.
01530         if (ent->ghoul2 && trap_G2_HaveWeGhoul2Models(ent->ghoul2))
01531         {
01532                 trap_G2API_CleanGhoul2Models(&(ent->ghoul2));
01533         }
01534 
01535         //rww - just load the "standard" model for the server"
01536         if (!precachedKyle)
01537         {
01538                 int defSkin;
01539 
01540                 Com_sprintf( afilename, sizeof( afilename ), "models/players/kyle/model.glm" );
01541                 handle = trap_G2API_InitGhoul2Model(&precachedKyle, afilename, 0, 0, -20, 0, 0);
01542 
01543                 if (handle<0)
01544                 {
01545                         return;
01546                 }
01547 
01548                 defSkin = trap_R_RegisterSkin("models/players/kyle/model_default.skin");
01549                 trap_G2API_SetSkin(precachedKyle, 0, defSkin, defSkin);
01550         }
01551 
01552         if (precachedKyle && trap_G2_HaveWeGhoul2Models(precachedKyle))
01553         {
01554                 if (d_perPlayerGhoul2.integer || ent->s.number >= MAX_CLIENTS ||
01555                         G_PlayerHasCustomSkeleton(ent))
01556                 { //rww - allow option for perplayer models on server for collision and bolt stuff.
01557                         char modelFullPath[MAX_QPATH];
01558                         char truncModelName[MAX_QPATH];
01559                         char skin[MAX_QPATH];
01560                         char vehicleName[MAX_QPATH];
01561                         int skinHandle = 0;
01562                         int i = 0;
01563                         char *p;
01564 
01565                         // If this is a vehicle, get it's model name.
01566                         if ( ent->client->NPC_class == CLASS_VEHICLE )
01567                         {
01568                                 strcpy(vehicleName, modelname);
01569                                 BG_GetVehicleModelName(modelname);
01570                                 strcpy(truncModelName, modelname);
01571                                 skin[0] = 0;
01572                                 if ( ent->m_pVehicle
01573                                         && ent->m_pVehicle->m_pVehicleInfo
01574                                         && ent->m_pVehicle->m_pVehicleInfo->skin
01575                                         && ent->m_pVehicle->m_pVehicleInfo->skin[0] )
01576                                 {
01577                                         skinHandle = trap_R_RegisterSkin(va("models/players/%s/model_%s.skin", modelname, ent->m_pVehicle->m_pVehicleInfo->skin));
01578                                 }
01579                                 else
01580                                 {
01581                                         skinHandle = trap_R_RegisterSkin(va("models/players/%s/model_default.skin", modelname));
01582                                 }
01583                         }
01584                         else
01585                         {
01586                                 if (skinName && skinName[0])
01587                                 {
01588                                         strcpy(skin, skinName);
01589                                         strcpy(truncModelName, modelname);
01590                                 }
01591                                 else
01592                                 {
01593                                         strcpy(skin, "default");
01594 
01595                                         strcpy(truncModelName, modelname);
01596                                         p = Q_strrchr(truncModelName, '/');
01597 
01598                                         if (p)
01599                                         {
01600                                                 *p = 0;
01601                                                 p++;
01602 
01603                                                 while (p && *p)
01604                                                 {
01605                                                         skin[i] = *p;
01606                                                         i++;
01607                                                         p++;
01608                                                 }
01609                                                 skin[i] = 0;
01610                                                 i = 0;
01611                                         }
01612 
01613                                         if (!BG_IsValidCharacterModel(truncModelName, skin))
01614                                         {
01615                                                 strcpy(truncModelName, "kyle");
01616                                                 strcpy(skin, "default");
01617                                         }
01618 
01619                                         if ( g_gametype.integer >= GT_TEAM && g_gametype.integer != GT_SIEGE && !g_trueJedi.integer )
01620                                         {
01621                                                 BG_ValidateSkinForTeam( truncModelName, skin, ent->client->sess.sessionTeam, NULL );
01622                                         }
01623                                         else if (g_gametype.integer == GT_SIEGE)
01624                                         { //force skin for class if appropriate
01625                                                 if (ent->client->siegeClass != -1)
01626                                                 {
01627                                                         siegeClass_t *scl = &bgSiegeClasses[ent->client->siegeClass];
01628                                                         if (scl->forcedSkin[0])
01629                                                         {
01630                                                                 strcpy(skin, scl->forcedSkin);
01631                                                         }
01632                                                 }
01633                                         }
01634                                 }
01635                         }
01636 
01637                         if (skin[0])
01638                         {
01639                                 char *useSkinName;
01640 
01641                                 if (strchr(skin, '|'))
01642                                 {//three part skin
01643                                         useSkinName = va("models/players/%s/|%s", truncModelName, skin);
01644                                 }
01645                                 else
01646                                 {
01647                                         useSkinName = va("models/players/%s/model_%s.skin", truncModelName, skin);
01648                                 }
01649 
01650                                 skinHandle = trap_R_RegisterSkin(useSkinName);
01651                         }
01652 
01653                         strcpy(modelFullPath, va("models/players/%s/model.glm", truncModelName));
01654                         handle = trap_G2API_InitGhoul2Model(&ent->ghoul2, modelFullPath, 0, skinHandle, -20, 0, 0);
01655 
01656                         if (handle<0)
01657                         { //Huh. Guess we don't have this model. Use the default.
01658 
01659                                 if (ent->ghoul2 && trap_G2_HaveWeGhoul2Models(ent->ghoul2))
01660                                 {
01661                                         trap_G2API_CleanGhoul2Models(&(ent->ghoul2));
01662                                 }
01663                                 ent->ghoul2 = NULL;
01664                                 trap_G2API_DuplicateGhoul2Instance(precachedKyle, &ent->ghoul2);
01665                         }
01666                         else
01667                         {
01668                                 trap_G2API_SetSkin(ent->ghoul2, 0, skinHandle, skinHandle);
01669 
01670                                 GLAName[0] = 0;
01671                                 trap_G2API_GetGLAName( ent->ghoul2, 0, GLAName);
01672 
01673                                 if (!GLAName[0] || (!strstr(GLAName, "players/_humanoid/") && ent->s.number < MAX_CLIENTS && !G_PlayerHasCustomSkeleton(ent)))
01674                                 { //a bad model
01675                                         trap_G2API_CleanGhoul2Models(&(ent->ghoul2));
01676                                         ent->ghoul2 = NULL;
01677                                         trap_G2API_DuplicateGhoul2Instance(precachedKyle, &ent->ghoul2);
01678                                 }
01679 
01680                                 if (ent->s.number >= MAX_CLIENTS)
01681                                 {
01682                                         ent->s.modelGhoul2 = 1; //so we know to free it on the client when we're removed.
01683 
01684                                         if (skin[0])
01685                                         { //append it after a *
01686                                                 strcat( modelFullPath, va("*%s", skin) );
01687                                         }
01688 
01689                                         if ( ent->client->NPC_class == CLASS_VEHICLE )
01690                                         { //vehicles are tricky and send over their vehicle names as the model (the model is then retrieved based on the vehicle name)
01691                                                 ent->s.modelindex = G_ModelIndex(vehicleName);
01692                                         }
01693                                         else
01694                                         {
01695                                                 ent->s.modelindex = G_ModelIndex(modelFullPath);
01696                                         }
01697                                 }
01698                         }
01699                 }
01700                 else
01701                 {
01702                         trap_G2API_DuplicateGhoul2Instance(precachedKyle, &ent->ghoul2);
01703                 }
01704         }
01705         else
01706         {
01707                 return;
01708         }
01709 
01710         //Attach the instance to this entity num so we can make use of client-server
01711         //shared operations if possible.
01712         trap_G2API_AttachInstanceToEntNum(ent->ghoul2, ent->s.number, qtrue);
01713 
01714         // The model is now loaded.
01715 
01716         GLAName[0] = 0;
01717 
01718         if (!BGPAFtextLoaded)
01719         {
01720                 if (BG_ParseAnimationFile("models/players/_humanoid/animation.cfg", bgHumanoidAnimations, qtrue) == -1)
01721                 {
01722                         Com_Printf( "Failed to load humanoid animation file\n");
01723                         return;
01724                 }
01725         }
01726 
01727         if (ent->s.number >= MAX_CLIENTS || G_PlayerHasCustomSkeleton(ent))
01728         {
01729                 ent->localAnimIndex = -1;
01730 
01731                 GLAName[0] = 0;
01732                 trap_G2API_GetGLAName(ent->ghoul2, 0, GLAName);
01733 
01734                 if (GLAName[0] &&
01735                         !strstr(GLAName, "players/_humanoid/") /*&&
01736                         !strstr(GLAName, "players/rockettrooper/")*/)
01737                 { //it doesn't use humanoid anims.
01738                         char *slash = Q_strrchr( GLAName, '/' );
01739                         if ( slash )
01740                         {
01741                                 strcpy(slash, "/animation.cfg");
01742 
01743                                 ent->localAnimIndex = BG_ParseAnimationFile(GLAName, NULL, qfalse);
01744                         }
01745                 }
01746                 else
01747                 { //humanoid index.
01748                         if (strstr(GLAName, "players/rockettrooper/"))
01749                         {
01750                                 ent->localAnimIndex = 1;
01751                         }
01752                         else
01753                         {
01754                                 ent->localAnimIndex = 0;
01755                         }
01756                 }
01757 
01758                 if (ent->localAnimIndex == -1)
01759                 {
01760                         Com_Error(ERR_DROP, "NPC had an invalid GLA\n");
01761                 }
01762         }
01763         else
01764         {
01765                 GLAName[0] = 0;
01766                 trap_G2API_GetGLAName(ent->ghoul2, 0, GLAName);
01767 
01768                 if (strstr(GLAName, "players/rockettrooper/"))
01769                 {
01770                         //assert(!"Should not have gotten in here with rockettrooper skel");
01771                         ent->localAnimIndex = 1;
01772                 }
01773                 else
01774                 {
01775                         ent->localAnimIndex = 0;
01776                 }
01777         }
01778 
01779         if (ent->s.NPC_class == CLASS_VEHICLE &&
01780                 ent->m_pVehicle)
01781         { //do special vehicle stuff
01782                 char strTemp[128];
01783                 int i;
01784 
01785                 // Setup the default first bolt
01786                 i = trap_G2API_AddBolt( ent->ghoul2, 0, "model_root" );
01787 
01788                 // Setup the droid unit.
01789                 ent->m_pVehicle->m_iDroidUnitTag = trap_G2API_AddBolt( ent->ghoul2, 0, "*droidunit" );
01790 
01791                 // Setup the Exhausts.
01792                 for ( i = 0; i < MAX_VEHICLE_EXHAUSTS; i++ )
01793                 {
01794                         Com_sprintf( strTemp, 128, "*exhaust%i", i + 1 );
01795                         ent->m_pVehicle->m_iExhaustTag[i] = trap_G2API_AddBolt( ent->ghoul2, 0, strTemp );
01796                 }
01797 
01798                 // Setup the Muzzles.
01799                 for ( i = 0; i < MAX_VEHICLE_MUZZLES; i++ )
01800                 {
01801                         Com_sprintf( strTemp, 128, "*muzzle%i", i + 1 );
01802                         ent->m_pVehicle->m_iMuzzleTag[i] = trap_G2API_AddBolt( ent->ghoul2, 0, strTemp );
01803                         if ( ent->m_pVehicle->m_iMuzzleTag[i] == -1 )
01804                         {//ergh, try *flash?
01805                                 Com_sprintf( strTemp, 128, "*flash%i", i + 1 );
01806                                 ent->m_pVehicle->m_iMuzzleTag[i] = trap_G2API_AddBolt( ent->ghoul2, 0, strTemp );
01807                         }
01808                 }
01809 
01810                 // Setup the Turrets.
01811                 for ( i = 0; i < MAX_VEHICLE_TURRET_MUZZLES; i++ )
01812                 {
01813                         if ( ent->m_pVehicle->m_pVehicleInfo->turret[i].gunnerViewTag )
01814                         {
01815                                 ent->m_pVehicle->m_iGunnerViewTag[i] = trap_G2API_AddBolt( ent->ghoul2, 0, ent->m_pVehicle->m_pVehicleInfo->turret[i].gunnerViewTag );
01816                         }
01817                         else
01818                         {
01819                                 ent->m_pVehicle->m_iGunnerViewTag[i] = -1;
01820                         }
01821                 }
01822         }
01823         
01824         if (ent->client->ps.weapon == WP_SABER || ent->s.number < MAX_CLIENTS)
01825         { //a player or NPC saber user
01826                 trap_G2API_AddBolt(ent->ghoul2, 0, "*r_hand");
01827                 trap_G2API_AddBolt(ent->ghoul2, 0, "*l_hand");
01828 
01829                 //rhand must always be first bolt. lhand always second. Whichever you want the
01830                 //jetpack bolted to must always be third.
01831                 trap_G2API_AddBolt(ent->ghoul2, 0, "*chestg");
01832 
01833                 //claw bolts
01834                 trap_G2API_AddBolt(ent->ghoul2, 0, "*r_hand_cap_r_arm");
01835                 trap_G2API_AddBolt(ent->ghoul2, 0, "*l_hand_cap_l_arm");
01836 
01837                 trap_G2API_SetBoneAnim(ent->ghoul2, 0, "model_root", 0, 12, BONE_ANIM_OVERRIDE_LOOP, 1.0f, level.time, -1, -1);
01838                 trap_G2API_SetBoneAngles(ent->ghoul2, 0, "upper_lumbar", tempVec, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, NULL, 0, level.time);
01839                 trap_G2API_SetBoneAngles(ent->ghoul2, 0, "cranium", tempVec, BONE_ANGLES_POSTMULT, POSITIVE_Z, NEGATIVE_Y, POSITIVE_X, NULL, 0, level.time);
01840 
01841                 if (!g2SaberInstance)
01842                 {
01843                         trap_G2API_InitGhoul2Model(&g2SaberInstance, "models/weapons2/saber/saber_w.glm", 0, 0, -20, 0, 0);
01844 
01845                         if (g2SaberInstance)
01846                         {
01847                                 // indicate we will be bolted to model 0 (ie the player) on bolt 0 (always the right hand) when we get copied
01848                                 trap_G2API_SetBoltInfo(g2SaberInstance, 0, 0);
01849                                 // now set up the gun bolt on it
01850                                 trap_G2API_AddBolt(g2SaberInstance, 0, "*blade1");
01851                         }
01852                 }
01853 
01854                 if (G_SaberModelSetup(ent))
01855                 {
01856                         if (g2SaberInstance)
01857                         {
01858                                 trap_G2API_CopySpecificGhoul2Model(g2SaberInstance, 0, ent->ghoul2, 1); 
01859                         }
01860                 }
01861         }
01862 
01863         if (ent->s.number >= MAX_CLIENTS)
01864         { //some extra NPC stuff
01865                 if (trap_G2API_AddBolt(ent->ghoul2, 0, "lower_lumbar") == -1)
01866                 { //check now to see if we have this bone for setting anims and such
01867                         ent->noLumbar = qtrue;
01868                 }
01869         }
01870 }

saber_colors_t TranslateSaberColor const char *  name  ) 
 

Definition at line 149 of file bg_saberLoad.c.

00150 {
00151         if ( !Q_stricmp( name, "red" ) ) 
00152         {
00153                 return SABER_RED;
00154         }
00155         if ( !Q_stricmp( name, "orange" ) ) 
00156         {
00157                 return SABER_ORANGE;
00158         }
00159         if ( !Q_stricmp( name, "yellow" ) ) 
00160         {
00161                 return SABER_YELLOW;
00162         }
00163         if ( !Q_stricmp( name, "green" ) ) 
00164         {
00165                 return SABER_GREEN;
00166         }
00167         if ( !Q_stricmp( name, "blue" ) ) 
00168         {
00169                 return SABER_BLUE;
00170         }
00171         if ( !Q_stricmp( name, "purple" ) ) 
00172         {
00173                 return SABER_PURPLE;
00174         }
00175         if ( !Q_stricmp( name, "random" ) ) 
00176         {
00177                 return ((saber_colors_t)(Q_irand( SABER_ORANGE, SABER_PURPLE )));
00178         }
00179         return SABER_BLUE;
00180 }

void WP_RemoveSaber saberInfo_t sabers,
int  saberNum
 

Definition at line 2664 of file bg_saberLoad.c.

References BG_SI_Deactivate(), BG_SI_SetLength(), saberInfo_t::model, name, strcpy(), and WP_SaberSetDefaults().

Referenced by NPC_ParseParms(), and WP_SetSaber().

02665 {
02666         if ( !sabers )
02667         {
02668                 return;
02669         }
02670         //reset everything for this saber just in case
02671         WP_SaberSetDefaults( &sabers[saberNum] );
02672 
02673         strcpy(sabers[saberNum].name, "none");
02674         sabers[saberNum].model[0] = 0;
02675 
02676         //ent->client->ps.dualSabers = qfalse;
02677         BG_SI_Deactivate(&sabers[saberNum]);
02678         BG_SI_SetLength(&sabers[saberNum], 0.0f);
02679 //      if ( ent->weaponModel[saberNum] > 0 )
02680 //      {
02681 //              gi.G2API_RemoveGhoul2Model( ent->ghoul2, ent->weaponModel[saberNum] );
02682 //              ent->weaponModel[saberNum] = -1;
02683 //      }
02684 //      if ( saberNum == 1 )
02685 //      {
02686 //              ent->client->ps.dualSabers = qfalse;
02687 //      }
02688 }

qboolean WP_SaberParseParms const char *  SaberName,
saberInfo_t saber
 

Definition at line 617 of file bg_saberLoad.c.

References saberInfo_t::animSpeedScale, animTable, atoi(), BG_ParseLiteral(), BG_SoundIndex(), saberInfo_t::blade, saberInfo_t::bladeEffect, saberInfo_t::bladeEffect2, saberInfo_t::bladeStyle2Start, saberInfo_t::block2Sound, saberInfo_t::blockEffect, saberInfo_t::blockEffect2, saberInfo_t::blockSound, saberInfo_t::bounce2Sound, saberInfo_t::bounceSound, saberInfo_t::bowAnim, saberInfo_t::breakParryBonus, saberInfo_t::breakParryBonus2, bladeInfo_t::color, COM_BeginParseSession(), Com_Error(), COM_ParseExt(), COM_ParseFloat(), COM_ParseInt(), COM_ParseString(), Com_Printf(), saberInfo_t::damageScale, saberInfo_t::damageScale2, DEFAULT_SABER, saberInfo_t::disarmBonus, saberInfo_t::disarmBonus2, saberInfo_t::drawAnim, ERR_DROP, saberInfo_t::flourishAnim, saberInfo_t::forceRestrictions, FP_FIRST, FPTable, saberInfo_t::fullName, saberInfo_t::g2MarksShader, saberInfo_t::g2MarksShader2, saberInfo_t::g2WeaponMarkShader, saberInfo_t::g2WeaponMarkShader2, GetIDForString(), saberInfo_t::gloatAnim, saberInfo_t::hit2Sound, saberInfo_t::hitOtherEffect, saberInfo_t::hitOtherEffect2, saberInfo_t::hitPersonEffect, saberInfo_t::hitPersonEffect2, saberInfo_t::hitSound, saberInfo_t::jumpAtkBackMove, saberInfo_t::jumpAtkFwdMove, saberInfo_t::jumpAtkLeftMove, saberInfo_t::jumpAtkRightMove, saberInfo_t::jumpAtkUpMove, saberInfo_t::kataMove, saberInfo_t::knockbackScale, saberInfo_t::knockbackScale2, bladeInfo_t::lengthMax, saberInfo_t::lockBonus, LS_INVALID, LS_MOVE_MAX, saberInfo_t::lungeAtkMove, MAX_ANIMATIONS, MAX_BLADES, saberInfo_t::maxChain, saberInfo_t::meditateAnim, saberInfo_t::model, saberInfo_t::moveSpeedScale, saberInfo_t::name, NUM_FORCE_POWERS, NUM_SABERS, saberInfo_t::numBlades, saberInfo_t::parryBonus, saberInfo_t::putawayAnim, Q_stricmp(), Q_stricmpn(), qboolean, qfalse, qtrue, bladeInfo_t::radius, saberInfo_t::readyAnim, S_COLOR_RED, S_COLOR_YELLOW, saber_colors_t, SABER_SINGLE, saberInfo_t::saberFlags, saberInfo_t::saberFlags2, SaberMoveTable, SaberTable, saberType_t, SFL2_ALWAYS_BLOCK, SFL2_ALWAYS_BLOCK2, SFL2_NO_BLADE, SFL2_NO_BLADE2, SFL2_NO_CLASH_FLARE, SFL2_NO_CLASH_FLARE2, SFL2_NO_DISMEMBERMENT, SFL2_NO_DISMEMBERMENT2, SFL2_NO_DLIGHT, SFL2_NO_DLIGHT2, SFL2_NO_IDLE_EFFECT, SFL2_NO_IDLE_EFFECT2, SFL2_NO_MANUAL_DEACTIVATE, SFL2_NO_MANUAL_DEACTIVATE2, SFL2_NO_WALL_MARKS, SFL2_NO_WALL_MARKS2, SFL2_TRANSITION_DAMAGE, SFL2_TRANSITION_DAMAGE2, SFL_BOLT_TO_WRIST, SFL_BOUNCE_ON_WALLS, SFL_NO_BACK_ATTACK, SFL_NO_CARTWHEELS, SFL_NO_FLIPS, SFL_NO_KICKS, SFL_NO_MIRROR_ATTACKS, SFL_NO_PULL_ATTACK, SFL_NO_ROLL_STAB, SFL_NO_ROLLS, SFL_NO_STABDOWN, SFL_NO_WALL_FLIPS, SFL_NO_WALL_GRAB, SFL_NO_WALL_RUNS, SFL_NOT_ACTIVE_BLOCKING, SFL_NOT_DISARMABLE, SFL_NOT_LOCKABLE, SFL_NOT_THROWABLE, SFL_RETURN_DAMAGE, SFL_SINGLE_BLADE_THROWABLE, SFL_TWO_HANDED, saberInfo_t::singleBladeStyle, saberInfo_t::skin, SkipBracedSection(), SkipRestOfLine(), saberInfo_t::soundLoop, saberInfo_t::soundOff, saberInfo_t::soundOn, saberInfo_t::spinSound, saberInfo_t::splashDamage, saberInfo_t::splashDamage2, saberInfo_t::splashKnockback, saberInfo_t::splashKnockback2, saberInfo_t::splashRadius, saberInfo_t::splashRadius2, SS_NONE, SS_NUM_SABER_STYLES, strcpy(), strlen(), saberInfo_t::stylesForbidden, saberInfo_t::stylesLearned, saberInfo_t::swingSound, saberInfo_t::tauntAnim, saberInfo_t::trailStyle, saberInfo_t::trailStyle2, TranslateSaberColor(), TranslateSaberStyle(), trap_FX_RegisterEffect(), trap_R_RegisterShader(), trap_R_RegisterSkin(), saberInfo_t::type, and WP_SaberSetDefaults().

Referenced by BG_PrecacheSabersForSiegeTeam(), NPC_ParseParms(), and WP_SetSaber().

00618 {
00619         const char      *token;
00620         const char      *value;
00621         const char      *p;
00622         char    useSaber[1024];
00623         float   f;
00624         int             n;
00625         qboolean        triedDefault = qfalse;
00626         int saberMove = LS_INVALID;
00627         int     anim = -1;
00628         
00629         if ( !saber ) 
00630         {
00631                 return qfalse;
00632         }
00633         
00634         //Set defaults so that, if it fails, there's at least something there
00635         WP_SaberSetDefaults( saber );
00636 
00637         if ( !SaberName || !SaberName[0] ) 
00638         {
00639                 strcpy(useSaber, DEFAULT_SABER); //default
00640                 triedDefault = qtrue;
00641         }
00642         else
00643         {
00644                 strcpy(useSaber, SaberName);
00645         }
00646 
00647         //try to parse it out
00648         p = SaberParms;
00649         COM_BeginParseSession("saberinfo");
00650 
00651         // look for the right saber
00652         while ( p )
00653         {
00654                 token = COM_ParseExt( &p, qtrue );
00655                 if ( token[0] == 0 )
00656                 {
00657                         if (!triedDefault)
00658                         { //fall back to default and restart, should always be there
00659                                 p = SaberParms;
00660                                 COM_BeginParseSession("saberinfo");
00661                                 strcpy(useSaber, DEFAULT_SABER);
00662                                 triedDefault = qtrue;
00663                         }
00664                         else
00665                         {
00666                                 return qfalse;
00667                         }
00668                 }
00669 
00670                 if ( !Q_stricmp( token, useSaber ) ) 
00671                 {
00672                         break;
00673                 }
00674 
00675                 SkipBracedSection( &p );
00676         }
00677         if ( !p ) 
00678         { //even the default saber isn't found?
00679                 return qfalse;
00680         }
00681 
00682         //got the name we're using for sure
00683         strcpy(saber->name, useSaber);
00684 
00685         if ( BG_ParseLiteral( &p, "{" ) ) 
00686         {
00687                 return qfalse;
00688         }
00689                 
00690         // parse the saber info block
00691         while ( 1 ) 
00692         {
00693                 token = COM_ParseExt( &p, qtrue );
00694                 if ( !token[0] ) 
00695                 {
00696                         Com_Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s'\n", useSaber );
00697                         return qfalse;
00698                 }
00699 
00700                 if ( !Q_stricmp( token, "}" ) ) 
00701                 {
00702                         break;
00703                 }
00704 
00705                 //saber fullName
00706                 if ( !Q_stricmp( token, "name" ) ) 
00707                 {
00708                         if ( COM_ParseString( &p, &value ) ) 
00709                         {
00710                                 continue;
00711                         }
00712                         strcpy(saber->fullName, value);
00713                         continue;
00714                 }
00715 
00716                 //saber type
00717                 if ( !Q_stricmp( token, "saberType" ) ) 
00718                 {
00719                         int saberType;
00720 
00721                         if ( COM_ParseString( &p, &value ) ) 
00722                         {
00723                                 continue;
00724                         }
00725                         saberType = GetIDForString( SaberTable, value );
00726                         if ( saberType >= SABER_SINGLE && saberType <= NUM_SABERS )
00727                         {
00728                                 saber->type = (saberType_t)saberType;
00729                         }
00730                         continue;
00731                 }
00732 
00733                 //saber hilt
00734                 if ( !Q_stricmp( token, "saberModel" ) ) 
00735                 {
00736                         if ( COM_ParseString( &p, &value ) ) 
00737                         {
00738                                 continue;
00739                         }
00740                         strcpy(saber->model, value);
00741                         continue;
00742                 }
00743 
00744                 if ( !Q_stricmp( token, "customSkin" ) )
00745                 {
00746                         if ( COM_ParseString( &p, &value ) ) 
00747                         {
00748                                 continue;
00749                         }
00750                         saber->skin = trap_R_RegisterSkin(value);
00751                         continue;
00752                 }
00753 
00754                 //on sound
00755                 if ( !Q_stricmp( token, "soundOn" ) ) 
00756                 {
00757                         if ( COM_ParseString( &p, &value ) ) 
00758                         {
00759                                 continue;
00760                         }
00761                         saber->soundOn = BG_SoundIndex( (char *)value );
00762                         continue;
00763                 }
00764 
00765                 //loop sound
00766                 if ( !Q_stricmp( token, "soundLoop" ) ) 
00767                 {
00768                         if ( COM_ParseString( &p, &value ) ) 
00769                         {
00770                                 continue;
00771                         }
00772                         saber->soundLoop = BG_SoundIndex( (char *)value );
00773                         continue;
00774                 }
00775 
00776                 //off sound
00777                 if ( !Q_stricmp( token, "soundOff" ) ) 
00778                 {
00779                         if ( COM_ParseString( &p, &value ) ) 
00780                         {
00781                                 continue;
00782                         }
00783                         saber->soundOff = BG_SoundIndex( (char *)value );
00784                         continue;
00785                 }
00786 
00787                 if ( !Q_stricmp( token, "numBlades" ) ) 
00788                 {
00789                         if ( COM_ParseInt( &p, &n ) ) 
00790                         {
00791                                 SkipRestOfLine( &p );
00792                                 continue;
00793                         }
00794                         if ( n < 1 || n > MAX_BLADES )
00795                         {
00796                                 Com_Error(ERR_DROP, "WP_SaberParseParms: saber %s has illegal number of blades (%d) max: %d", useSaber, n, MAX_BLADES );
00797                                 continue;
00798                         }
00799                         saber->numBlades = n;
00800                         continue;
00801                 }
00802 
00803                 // saberColor
00804                 if ( !Q_stricmpn( token, "saberColor", 10 ) ) 
00805                 {
00806                         if (strlen(token)==10)
00807                         {
00808                                 n = -1;
00809                         }
00810                         else if (strlen(token)==11)
00811                         {
00812                                 n = atoi(&token[10])-1;
00813                                 if (n > 7 || n < 1 )
00814                                 {
00815                                         Com_Printf( S_COLOR_YELLOW"WARNING: bad saberColor '%s' in %s\n", token, useSaber );
00816                                         continue;
00817                                 }
00818                         }
00819                         else
00820                         {
00821                                 Com_Printf( S_COLOR_YELLOW"WARNING: bad saberColor '%s' in %s\n", token, useSaber );
00822                                 continue;
00823                         }
00824 
00825                         if ( COM_ParseString( &p, &value ) )    //read the color
00826                         {
00827                                 continue;
00828                         }
00829 
00830                         if (n==-1)
00831                         {//NOTE: this fills in the rest of the blades with the same color by default
00832                                 saber_colors_t color = TranslateSaberColor( value );
00833                                 for ( n = 0; n < MAX_BLADES; n++ )
00834                                 {
00835                                         saber->blade[n].color = color;
00836                                 }
00837                         } else 
00838                         {
00839                                 saber->blade[n].color = TranslateSaberColor( value );
00840                         }
00841                         continue;
00842                 }
00843 
00844                 //saber length
00845                 if ( !Q_stricmpn( token, "saberLength", 11 ) ) 
00846                 {
00847                         if (strlen(token)==11)
00848                         {
00849                                 n = -1;
00850                         }
00851                         else if (strlen(token)==12)
00852                         {
00853                                 n = atoi(&token[11])-1;
00854                                 if (n > 7 || n < 1 )
00855                                 {
00856                                         Com_Printf( S_COLOR_YELLOW"WARNING: bad saberLength '%s' in %s\n", token, useSaber );
00857                                         continue;
00858                                 }
00859                         }
00860                         else
00861                         {
00862                                 Com_Printf( S_COLOR_YELLOW"WARNING: bad saberLength '%s' in %s\n", token, useSaber );
00863                                 continue;
00864                         }
00865 
00866                         if ( COM_ParseFloat( &p, &f ) ) 
00867                         {
00868                                 SkipRestOfLine( &p );
00869                                 continue;
00870                         }
00871                         //cap
00872                         if ( f < 4.0f )
00873                         {
00874                                 f = 4.0f;
00875                         }
00876 
00877                         if (n==-1)
00878                         {//NOTE: this fills in the rest of the blades with the same length by default
00879                                 for ( n = 0; n < MAX_BLADES; n++ )
00880                                 {
00881                                         saber->blade[n].lengthMax = f;
00882                                 }
00883                         }
00884                         else
00885                         {
00886                                 saber->blade[n].lengthMax = f;
00887                         }
00888                         continue;
00889                 }
00890 
00891                 //blade radius
00892                 if ( !Q_stricmpn( token, "saberRadius", 11 ) ) 
00893                 {
00894                         if (strlen(token)==11)
00895                         {
00896                                 n = -1;
00897                         }
00898                         else if (strlen(token)==12)
00899                         {
00900                                 n = atoi(&token[11])-1;
00901                                 if (n > 7 || n < 1 )
00902                                 {
00903                                         Com_Printf( S_COLOR_YELLOW"WARNING: bad saberRadius '%s' in %s\n", token, useSaber );
00904                                         continue;
00905                                 }
00906                         }
00907                         else
00908                         {
00909                                 Com_Printf( S_COLOR_YELLOW"WARNING: bad saberRadius '%s' in %s\n", token, useSaber );
00910                                 continue;
00911                         }
00912 
00913                         if ( COM_ParseFloat( &p, &f ) ) 
00914                         {
00915                                 SkipRestOfLine( &p );
00916                                 continue;
00917                         }
00918                         //cap
00919                         if ( f < 0.25f )
00920                         {
00921                                 f = 0.25f;
00922                         }
00923                         if (n==-1)
00924                         {//NOTE: this fills in the rest of the blades with the same length by default
00925                                 for ( n = 0; n < MAX_BLADES; n++ )
00926                                 {
00927                                         saber->blade[n].radius = f;
00928                                 }
00929                         }
00930                         else
00931                         {
00932                                 saber->blade[n].radius = f;
00933                         }
00934                         continue;
00935                 }
00936 
00937                 //locked saber style
00938                 if ( !Q_stricmp( token, "saberStyle" ) ) 
00939                 {
00940                         int style, styleNum;
00941                         if ( COM_ParseString( &p, &value ) ) 
00942                         {
00943                                 continue;
00944                         }
00945                         //OLD WAY: only allowed ONE style
00946                         style = TranslateSaberStyle( value );
00947                         //learn only this style
00948                         saber->stylesLearned = (1<<style);
00949                         //forbid all other styles
00950                         saber->stylesForbidden = 0;
00951                         for ( styleNum = SS_NONE+1; styleNum < SS_NUM_SABER_STYLES; styleNum++ )
00952                         {
00953                                 if ( styleNum != style )
00954                                 {
00955                                         saber->stylesForbidden |= (1<<styleNum);
00956                                 }
00957                         }
00958                         continue;
00959                 }
00960 
00961                 //learned saber style
00962                 if ( !Q_stricmp( token, "saberStyleLearned" ) ) 
00963                 {
00964                         if ( COM_ParseString( &p, &value ) ) 
00965                         {
00966                                 continue;
00967                         }
00968                         saber->stylesLearned |= (1<<TranslateSaberStyle( value ));
00969                         continue;
00970                 }
00971 
00972                 //forbidden saber style
00973                 if ( !Q_stricmp( token, "saberStyleForbidden" ) ) 
00974                 {
00975                         if ( COM_ParseString( &p, &value ) ) 
00976                         {
00977                                 continue;
00978                         }
00979                         saber->stylesForbidden |= (1<<TranslateSaberStyle( value ));
00980                         continue;
00981                 }
00982 
00983                 //maxChain
00984                 if ( !Q_stricmp( token, "maxChain" ) ) 
00985                 {
00986                         if ( COM_ParseInt( &p, &n ) ) 
00987                         {
00988                                 SkipRestOfLine( &p );
00989                                 continue;
00990                         }
00991                         saber->maxChain = n;
00992                         continue;
00993                 }
00994 
00995                 //lockable
00996                 if ( !Q_stricmp( token, "lockable" ) ) 
00997                 {
00998                         if ( COM_ParseInt( &p, &n ) ) 
00999                         {
01000                                 SkipRestOfLine( &p );
01001                                 continue;
01002                         }
01003                         if ( n == 0 )
01004                         {
01005                                 saber->saberFlags |= SFL_NOT_LOCKABLE;
01006                         }
01007                         continue;
01008                 }
01009 
01010                 //throwable
01011                 if ( !Q_stricmp( token, "throwable" ) ) 
01012                 {
01013                         if ( COM_ParseInt( &p, &n ) ) 
01014                         {
01015                                 SkipRestOfLine( &p );
01016                                 continue;
01017                         }
01018                         if ( n == 0 )
01019                         {
01020                                 saber->saberFlags |= SFL_NOT_THROWABLE;
01021                         }
01022                         continue;
01023                 }
01024 
01025                 //disarmable
01026                 if ( !Q_stricmp( token, "disarmable" ) ) 
01027                 {
01028                         if ( COM_ParseInt( &p, &n ) ) 
01029                         {
01030                                 SkipRestOfLine( &p );
01031                                 continue;
01032                         }
01033                         if ( n == 0 )
01034                         {
01035                                 saber->saberFlags |= SFL_NOT_DISARMABLE;
01036                         }
01037                         continue;
01038                 }
01039 
01040                 //active blocking
01041                 if ( !Q_stricmp( token, "blocking" ) ) 
01042                 {
01043                         if ( COM_ParseInt( &p, &n ) ) 
01044                         {
01045                                 SkipRestOfLine( &p );
01046                                 continue;
01047                         }
01048                         if ( n == 0 )
01049                         {
01050                                 saber->saberFlags |= SFL_NOT_ACTIVE_BLOCKING;
01051                         }
01052                         continue;
01053                 }
01054 
01055                 //twoHanded
01056                 if ( !Q_stricmp( token, "twoHanded" ) ) 
01057                 {
01058                         if ( COM_ParseInt( &p, &n ) ) 
01059                         {
01060                                 SkipRestOfLine( &p );
01061                                 continue;
01062                         }
01063                         if ( n )
01064                         {
01065                                 saber->saberFlags |= SFL_TWO_HANDED;
01066                         }
01067                         continue;
01068                 }
01069 
01070                 //force power restrictions
01071                 if ( !Q_stricmp( token, "forceRestrict" ) ) 
01072                 {
01073                         int fp;
01074 
01075                         if ( COM_ParseString( &p, &value ) ) 
01076                         {
01077                                 continue;
01078                         }
01079                         fp = GetIDForString( FPTable, value );
01080                         if ( fp >= FP_FIRST && fp < NUM_FORCE_POWERS )
01081                         {
01082                                 saber->forceRestrictions |= (1<<fp);
01083                         }
01084                         continue;
01085                 }
01086 
01087                 //lockBonus
01088                 if ( !Q_stricmp( token, "lockBonus" ) ) 
01089                 {
01090                         if ( COM_ParseInt( &p, &n ) ) 
01091                         {
01092                                 SkipRestOfLine( &p );
01093                                 continue;
01094                         }
01095                         saber->lockBonus = n;
01096                         continue;
01097                 }
01098 
01099                 //parryBonus
01100                 if ( !Q_stricmp( token, "parryBonus" ) ) 
01101                 {
01102                         if ( COM_ParseInt( &p, &n ) ) 
01103                         {
01104                                 SkipRestOfLine( &p );
01105                                 continue;
01106                         }
01107                         saber->parryBonus = n;
01108                         continue;
01109                 }
01110 
01111                 //breakParryBonus
01112                 if ( !Q_stricmp( token, "breakParryBonus" ) ) 
01113                 {
01114                         if ( COM_ParseInt( &p, &n ) ) 
01115                         {
01116                                 SkipRestOfLine( &p );
01117                                 continue;
01118                         }
01119                         saber->breakParryBonus = n;
01120                         continue;
01121                 }
01122 
01123                 //breakParryBonus2
01124                 if ( !Q_stricmp( token, "breakParryBonus2" ) ) 
01125                 {
01126                         if ( COM_ParseInt( &p, &n ) ) 
01127                         {
01128                                 SkipRestOfLine( &p );
01129                                 continue;
01130                         }
01131                         saber->breakParryBonus2 = n;
01132                         continue;
01133                 }
01134 
01135                 //disarmBonus
01136                 if ( !Q_stricmp( token, "disarmBonus" ) ) 
01137                 {
01138                         if ( COM_ParseInt( &p, &n ) ) 
01139                         {
01140                                 SkipRestOfLine( &p );
01141                                 continue;
01142                         }
01143                         saber->disarmBonus = n;
01144                         continue;
01145                 }
01146 
01147                 //disarmBonus2
01148                 if ( !Q_stricmp( token, "disarmBonus2" ) ) 
01149                 {
01150                         if ( COM_ParseInt( &p, &n ) ) 
01151                         {
01152                                 SkipRestOfLine( &p );
01153                                 continue;
01154                         }
01155                         saber->disarmBonus2 = n;
01156                         continue;
01157                 }
01158 
01159                 //single blade saber style
01160                 if ( !Q_stricmp( token, "singleBladeStyle" ) ) 
01161                 {
01162                         if ( COM_ParseString( &p, &value ) ) 
01163                         {
01164                                 continue;
01165                         }
01166                         saber->singleBladeStyle = TranslateSaberStyle( value );
01167                         continue;
01168                 }
01169 
01170                 //single blade throwable
01171                 if ( !Q_stricmp( token, "singleBladeThrowable" ) ) 
01172                 {
01173                         if ( COM_ParseInt( &p, &n ) ) 
01174                         {
01175                                 SkipRestOfLine( &p );
01176                                 continue;
01177                         }
01178                         if ( n )
01179                         {
01180                                 saber->saberFlags |= SFL_SINGLE_BLADE_THROWABLE;
01181                         }
01182                         continue;
01183                 }
01184 
01185                 //broken replacement saber1 (right hand)
01186                 if ( !Q_stricmp( token, "brokenSaber1" ) ) 
01187                 {
01188                         if ( COM_ParseString( &p, &value ) ) 
01189                         {
01190                                 continue;
01191                         }
01192                         //saber->brokenSaber1 = G_NewString( value );
01193                         continue;
01194                 }
01195                 
01196                 //broken replacement saber2 (left hand)
01197                 if ( !Q_stricmp( token, "brokenSaber2" ) ) 
01198                 {
01199                         if ( COM_ParseString( &p, &value ) ) 
01200                         {
01201                                 continue;
01202                         }
01203                         //saber->brokenSaber2 = G_NewString( value );
01204                         continue;
01205                 }
01206 
01207                 //spins and does damage on return from saberthrow
01208                 if ( !Q_stricmp( token, "returnDamage" ) ) 
01209                 {
01210                         if ( COM_ParseInt( &p, &n ) ) 
01211                         {
01212                                 SkipRestOfLine( &p );
01213                                 continue;
01214                         }
01215                         if ( n )
01216                         {
01217                                 saber->saberFlags |= SFL_RETURN_DAMAGE;
01218                         }
01219                         continue;
01220                 }
01221 
01222                 //spin sound (when thrown)
01223                 if ( !Q_stricmp( token, "spinSound" ) ) 
01224                 {
01225                         if ( COM_ParseString( &p, &value ) ) 
01226                         {
01227                                 continue;
01228                         }
01229                         saber->spinSound = BG_SoundIndex( (char *)value );
01230                         continue;
01231                 }
01232 
01233                 //swing sound - NOTE: must provide all 3!!!
01234                 if ( !Q_stricmp( token, "swingSound1" ) ) 
01235                 {
01236                         if ( COM_ParseString( &p, &value ) ) 
01237                         {
01238                                 continue;
01239                         }
01240                         saber->swingSound[0] = BG_SoundIndex( (char *)value );
01241                         continue;
01242                 }
01243 
01244                 //swing sound - NOTE: must provide all 3!!!
01245                 if ( !Q_stricmp( token, "swingSound2" ) ) 
01246                 {
01247                         if ( COM_ParseString( &p, &value ) ) 
01248                         {
01249                                 continue;
01250                         }
01251                         saber->swingSound[1] = BG_SoundIndex( (char *)value );
01252                         continue;
01253                 }
01254 
01255                 //swing sound - NOTE: must provide all 3!!!
01256                 if ( !Q_stricmp( token, "swingSound3" ) ) 
01257                 {
01258                         if ( COM_ParseString( &p, &value ) ) 
01259                         {
01260                                 continue;
01261                         }
01262                         saber->swingSound[2] = BG_SoundIndex( (char *)value );
01263                         continue;
01264                 }
01265 
01266                 //you move faster/slower when using this saber
01267                 if ( !Q_stricmp( token, "moveSpeedScale" ) ) 
01268                 {
01269                         if ( COM_ParseFloat( &p, &f ) ) 
01270                         {
01271                                 SkipRestOfLine( &p );
01272                                 continue;
01273                         }
01274                         saber->moveSpeedScale = f;
01275                         continue;
01276                 }
01277 
01278                 //plays normal attack animations faster/slower
01279                 if ( !Q_stricmp( token, "animSpeedScale" ) ) 
01280                 {
01281                         if ( COM_ParseFloat( &p, &f ) ) 
01282                         {
01283                                 SkipRestOfLine( &p );
01284                                 continue;
01285                         }
01286                         saber->animSpeedScale = f;
01287                         continue;
01288                 }
01289 
01290                 //if non-zero, the saber will bounce back when it hits solid architecture (good for real-sword type mods)
01291                 if ( !Q_stricmp( token, "bounceOnWalls" ) ) 
01292                 {
01293                         if ( COM_ParseInt( &p, &n ) ) 
01294                         {
01295                                 SkipRestOfLine( &p );
01296                                 continue;
01297                         }
01298                         if ( n )
01299                         {
01300                                 saber->saberFlags |= SFL_BOUNCE_ON_WALLS;
01301                         }
01302                         continue;
01303                 }
01304 
01305                 //if set, saber model is bolted to wrist, not in hand... useful for things like claws & shields, etc.
01306                 if ( !Q_stricmp( token, "boltToWrist" ) ) 
01307                 {
01308                         if ( COM_ParseInt( &p, &n ) ) 
01309                         {
01310                                 SkipRestOfLine( &p );
01311                                 continue;
01312                         }
01313                         if ( n )
01314                         {
01315                                 saber->saberFlags |= SFL_BOLT_TO_WRIST;
01316                         }
01317                         continue;
01318                 }
01319 
01320                 //kata move
01321                 if ( !Q_stricmp( token, "kataMove" ) ) 
01322                 {
01323                         if ( COM_ParseString( &p, &value ) ) 
01324                         {
01325                                 continue;
01326                         }
01327                         saberMove = GetIDForString( SaberMoveTable, value );
01328                         if ( saberMove >= LS_INVALID && saberMove < LS_MOVE_MAX )
01329                         {
01330                                 saber->kataMove = saberMove;                            //LS_INVALID - if set, player will execute this move when they press both attack buttons at the same time 
01331                         }
01332                         continue;
01333                 }
01334                 //lungeAtkMove move
01335                 if ( !Q_stricmp( token, "lungeAtkMove" ) ) 
01336                 {
01337                         if ( COM_ParseString( &p, &value ) ) 
01338                         {
01339                                 continue;
01340                         }
01341                         saberMove = GetIDForString( SaberMoveTable, value );
01342                         if ( saberMove >= LS_INVALID && saberMove < LS_MOVE_MAX )
01343                         {
01344                                 saber->lungeAtkMove = saberMove;
01345                         }
01346                         continue;
01347                 }
01348                 //jumpAtkUpMove move
01349                 if ( !Q_stricmp( token, "jumpAtkUpMove" ) ) 
01350                 {
01351                         if ( COM_ParseString( &p, &value ) ) 
01352                         {
01353                                 continue;
01354                         }
01355                         saberMove = GetIDForString( SaberMoveTable, value );
01356                         if ( saberMove >= LS_INVALID && saberMove < LS_MOVE_MAX )
01357                         {
01358                                 saber->jumpAtkUpMove = saberMove;
01359                         }
01360                         continue;
01361                 }
01362                 //jumpAtkFwdMove move
01363                 if ( !Q_stricmp( token, "jumpAtkFwdMove" ) ) 
01364                 {
01365                         if ( COM_ParseString( &p, &value ) ) 
01366                         {
01367                                 continue;
01368                         }
01369                         saberMove = GetIDForString( SaberMoveTable, value );
01370                         if ( saberMove >= LS_INVALID && saberMove < LS_MOVE_MAX )
01371                         {
01372                                 saber->jumpAtkFwdMove = saberMove;
01373                         }
01374                         continue;
01375                 }
01376                 //jumpAtkBackMove move
01377                 if ( !Q_stricmp( token, "jumpAtkBackMove" ) ) 
01378                 {
01379                         if ( COM_ParseString( &p, &value ) ) 
01380                         {
01381                                 continue;
01382                         }
01383                         saberMove = GetIDForString( SaberMoveTable, value );
01384                         if ( saberMove >= LS_INVALID && saberMove < LS_MOVE_MAX )
01385                         {
01386                                 saber->jumpAtkBackMove = saberMove;
01387                         }
01388                         continue;
01389                 }
01390                 //jumpAtkRightMove move
01391                 if ( !Q_stricmp( token, "jumpAtkRightMove" ) ) 
01392                 {
01393                         if ( COM_ParseString( &p, &value ) ) 
01394                         {
01395                                 continue;
01396                         }
01397                         saberMove = GetIDForString( SaberMoveTable, value );
01398                         if ( saberMove >= LS_INVALID && saberMove < LS_MOVE_MAX )
01399                         {
01400                                 saber->jumpAtkRightMove = saberMove;
01401                         }
01402                         continue;
01403                 }
01404                 //jumpAtkLeftMove move
01405                 if ( !Q_stricmp( token, "jumpAtkLeftMove" ) ) 
01406                 {
01407                         if ( COM_ParseString( &p, &value ) ) 
01408                         {
01409                                 continue;
01410                         }
01411                         saberMove = GetIDForString( SaberMoveTable, value );
01412                         if ( saberMove >= LS_INVALID && saberMove < LS_MOVE_MAX )
01413                         {
01414                                 saber->jumpAtkLeftMove = saberMove;
01415                         }
01416                         continue;
01417                 }
01418                 //readyAnim
01419                 if ( !Q_stricmp( token, "readyAnim" ) ) 
01420                 {
01421                         if ( COM_ParseString( &p, &value ) ) 
01422                         {
01423                                 continue;
01424                         }
01425                         anim = GetIDForString( animTable, value );
01426                         if ( anim >= 0 && anim < MAX_ANIMATIONS )
01427                         {
01428                                 saber->readyAnim = anim;
01429                         }
01430                         continue;
01431                 }
01432                 //drawAnim
01433                 if ( !Q_stricmp( token, "drawAnim" ) ) 
01434                 {
01435                         if ( COM_ParseString( &p, &value ) ) 
01436                         {
01437                                 continue;
01438                         }
01439                         anim = GetIDForString( animTable, value );
01440                         if ( anim >= 0 && anim < MAX_ANIMATIONS )
01441                         {
01442                                 saber->drawAnim = anim;
01443                         }
01444                         continue;
01445                 }
01446                 //putawayAnim
01447                 if ( !Q_stricmp( token, "putawayAnim" ) ) 
01448                 {
01449                         if ( COM_ParseString( &p, &value ) ) 
01450                         {
01451                                 continue;
01452                         }
01453                         anim = GetIDForString( animTable, value );
01454                         if ( anim >= 0 && anim < MAX_ANIMATIONS )
01455                         {
01456                                 saber->putawayAnim = anim;
01457                         }
01458                         continue;
01459                 }
01460                 //tauntAnim
01461                 if ( !Q_stricmp( token, "tauntAnim" ) ) 
01462                 {
01463                         if ( COM_ParseString( &p, &value ) ) 
01464                         {
01465                                 continue;
01466                         }
01467                         anim = GetIDForString( animTable, value );
01468                         if ( anim >= 0 && anim < MAX_ANIMATIONS )
01469                         {
01470                                 saber->tauntAnim = anim;
01471                         }
01472                         continue;
01473                 }
01474                 //bowAnim
01475                 if ( !Q_stricmp( token, "bowAnim" ) ) 
01476                 {
01477                         if ( COM_ParseString( &p, &value ) ) 
01478                         {
01479                                 continue;
01480                         }
01481                         anim = GetIDForString( animTable, value );
01482                         if ( anim >= 0 && anim < MAX_ANIMATIONS )
01483                         {
01484                                 saber->bowAnim = anim;
01485                         }
01486                         continue;
01487                 }
01488                 //meditateAnim
01489                 if ( !Q_stricmp( token, "meditateAnim" ) ) 
01490                 {
01491                         if ( COM_ParseString( &p, &value ) ) 
01492                         {
01493                                 continue;
01494                         }
01495                         anim = GetIDForString( animTable, value );
01496                         if ( anim >= 0 && anim < MAX_ANIMATIONS )
01497                         {
01498                                 saber->meditateAnim = anim;
01499                         }
01500                         continue;
01501                 }
01502                 //flourishAnim
01503                 if ( !Q_stricmp( token, "flourishAnim" ) ) 
01504                 {
01505                         if ( COM_ParseString( &p, &value ) ) 
01506                         {
01507                                 continue;
01508                         }
01509                         anim = GetIDForString( animTable, value );
01510                         if ( anim >= 0 && anim < MAX_ANIMATIONS )
01511                         {
01512                                 saber->flourishAnim = anim;
01513                         }
01514                         continue;
01515                 }
01516                 //gloatAnim
01517                 if ( !Q_stricmp( token, "gloatAnim" ) ) 
01518                 {
01519                         if ( COM_ParseString( &p, &value ) ) 
01520                         {
01521                                 continue;
01522                         }
01523                         anim = GetIDForString( animTable, value );
01524                         if ( anim >= 0 && anim < MAX_ANIMATIONS )
01525                         {
01526                                 saber->gloatAnim = anim;
01527                         }
01528                         continue;
01529                 }
01530 
01531                 //if set, cannot do roll-stab move at end of roll
01532                 if ( !Q_stricmp( token, "noRollStab" ) ) 
01533                 {
01534                         if ( COM_ParseInt( &p, &n ) ) 
01535                         {
01536                                 SkipRestOfLine( &p );
01537                                 continue;
01538                         }
01539                         if ( n )
01540                         {
01541                                 saber->saberFlags |= SFL_NO_ROLL_STAB;
01542                         }
01543                         continue;
01544                 }
01545 
01546                 //if set, cannot do pull+attack move (move not available in MP anyway)
01547                 if ( !Q_stricmp( token, "noPullAttack" ) ) 
01548                 {
01549                         if ( COM_ParseInt( &p, &n ) ) 
01550                         {
01551                                 SkipRestOfLine( &p );
01552                                 continue;
01553                         }
01554                         if ( n )
01555                         {
01556                                 saber->saberFlags |= SFL_NO_PULL_ATTACK;
01557                         }
01558                         continue;
01559                 }
01560 
01561                 //if set, cannot do back-stab moves
01562                 if ( !Q_stricmp( token, "noBackAttack" ) ) 
01563                 {
01564                         if ( COM_ParseInt( &p, &n ) ) 
01565                         {
01566                                 SkipRestOfLine( &p );
01567                                 continue;
01568                         }
01569                         if ( n )
01570                         {
01571                                 saber->saberFlags |= SFL_NO_BACK_ATTACK;
01572                         }
01573                         continue;
01574                 }
01575 
01576                 //if set, cannot do stabdown move (when enemy is on ground)
01577                 if ( !Q_stricmp( token, "noStabDown" ) ) 
01578                 {
01579                         if ( COM_ParseInt( &p, &n ) ) 
01580                         {
01581                                 SkipRestOfLine( &p );
01582                                 continue;
01583                         }
01584                         if ( n )
01585                         {
01586                                 saber->saberFlags |= SFL_NO_STABDOWN;
01587                         }
01588                         continue;
01589                 }
01590 
01591                 //if set, cannot side-run or forward-run on walls
01592                 if ( !Q_stricmp( token, "noWallRuns" ) ) 
01593                 {
01594                         if ( COM_ParseInt( &p, &n ) ) 
01595                         {
01596                                 SkipRestOfLine( &p );
01597                                 continue;
01598                         }
01599                         if ( n )
01600                         {
01601                                 saber->saberFlags |= SFL_NO_WALL_RUNS;
01602                         }
01603                         continue;
01604                 }
01605 
01606                 //if set, cannot do backflip off wall or side-flips off walls
01607                 if ( !Q_stricmp( token, "noWallFlips" ) ) 
01608                 {
01609                         if ( COM_ParseInt( &p, &n ) ) 
01610                         {
01611                                 SkipRestOfLine( &p );
01612                                 continue;
01613                         }
01614                         if ( n )
01615                         {
01616                                 saber->saberFlags |= SFL_NO_WALL_FLIPS;
01617                         }
01618                         continue;
01619                 }
01620 
01621                 //if set, cannot grab wall & jump off
01622                 if ( !Q_stricmp( token, "noWallGrab" ) ) 
01623                 {
01624                         if ( COM_ParseInt( &p, &n ) ) 
01625                         {
01626                                 SkipRestOfLine( &p );
01627                                 continue;
01628                         }
01629                         if ( n )
01630                         {
01631                                 saber->saberFlags |= SFL_NO_WALL_GRAB;
01632                         }
01633                         continue;
01634                 }
01635 
01636                 //if set, cannot roll
01637                 if ( !Q_stricmp( token, "noRolls" ) ) 
01638                 {
01639                         if ( COM_ParseInt( &p, &n ) ) 
01640                         {
01641                                 SkipRestOfLine( &p );
01642                                 continue;
01643                         }
01644                         if ( n )
01645                         {
01646                                 saber->saberFlags |= SFL_NO_ROLLS;
01647                         }
01648                         continue;
01649                 }
01650 
01651                 //if set, cannot do flips
01652                 if ( !Q_stricmp( token, "noFlips" ) ) 
01653                 {
01654                         if ( COM_ParseInt( &p, &n ) ) 
01655                         {
01656                                 SkipRestOfLine( &p );
01657                                 continue;
01658                         }
01659                         if ( n )
01660                         {
01661                                 saber->saberFlags |= SFL_NO_FLIPS;
01662                         }
01663                         continue;
01664                 }
01665 
01666                 //if set, cannot do cartwheels
01667                 if ( !Q_stricmp( token, "noCartwheels" ) ) 
01668                 {
01669                         if ( COM_ParseInt( &p, &n ) ) 
01670                         {
01671                                 SkipRestOfLine( &p );
01672                                 continue;
01673                         }
01674                         if ( n )
01675                         {
01676                                 saber->saberFlags |= SFL_NO_CARTWHEELS;
01677                         }
01678                         continue;
01679                 }
01680 
01681                 //if set, cannot do kicks (can't do kicks anyway if using a throwable saber/sword)
01682                 if ( !Q_stricmp( token, "noKicks" ) ) 
01683                 {
01684                         if ( COM_ParseInt( &p, &n ) ) 
01685                         {
01686                                 SkipRestOfLine( &p );
01687                                 continue;
01688                         }
01689                         if ( n )
01690                         {
01691                                 saber->saberFlags |= SFL_NO_KICKS;
01692                         }
01693                         continue;
01694                 }
01695 
01696                 //if set, cannot do the simultaneous attack left/right moves (only available in Dual Lightsaber Combat Style)
01697                 if ( !Q_stricmp( token, "noMirrorAttacks" ) ) 
01698                 {
01699                         if ( COM_ParseInt( &p, &n ) ) 
01700                         {
01701                                 SkipRestOfLine( &p );
01702                                 continue;
01703                         }
01704                         if ( n )
01705                         {
01706                                 saber->saberFlags |= SFL_NO_MIRROR_ATTACKS;
01707                         }
01708                         continue;
01709                 }
01710 
01711                 //stays on in water
01712                 if ( !Q_stricmp( token, "onInWater" ) ) 
01713                 {//ignore in MP
01714                         SkipRestOfLine( &p );
01715                         continue;
01716                 }
01717 
01718                 if ( !Q_stricmp( token, "notInMP" ) ) 
01719                 {//ignore this
01720                         SkipRestOfLine( &p );
01721                         continue;
01722                 }
01723 
01724 //===ABOVE THIS, ALL VALUES ARE GLOBAL TO THE SABER========================================================
01725                 //bladeStyle2Start - where to start using the second set of blade data
01726                 if ( !Q_stricmp( token, "bladeStyle2Start" ) ) 
01727                 {
01728                         if ( COM_ParseInt( &p, &n ) ) 
01729                         {
01730                                 SkipRestOfLine( &p );
01731                                 continue;
01732                         }
01733                         saber->bladeStyle2Start = n;
01734                         continue;
01735                 }
01736 //===BLADE-SPECIFIC FIELDS=================================================================================
01737 
01738                 //===PRIMARY BLADE====================================
01739                 //stops the saber from drawing marks on the world (good for real-sword type mods)
01740                 if ( !Q_stricmp( token, "noWallMarks" ) ) 
01741                 {
01742                         if ( COM_ParseInt( &p, &n ) ) 
01743                         {
01744                                 SkipRestOfLine( &p );
01745                                 continue;
01746                         }
01747                         if ( n )
01748                         {
01749                                 saber->saberFlags2 |= SFL2_NO_WALL_MARKS;
01750                         }
01751                         continue;
01752                 }
01753 
01754                 //stops the saber from drawing a dynamic light (good for real-sword type mods)
01755                 if ( !Q_stricmp( token, "noDlight" ) ) 
01756                 {
01757                         if ( COM_ParseInt( &p, &n ) ) 
01758                         {
01759                                 SkipRestOfLine( &p );
01760                                 continue;
01761                         }
01762                         if ( n )
01763                         {
01764                                 saber->saberFlags2 |= SFL2_NO_DLIGHT;
01765                         }
01766                         continue;
01767                 }
01768 
01769                 //stops the saber from drawing a blade (good for real-sword type mods)
01770                 if ( !Q_stricmp( token, "noBlade" ) ) 
01771                 {
01772                         if ( COM_ParseInt( &p, &n ) ) 
01773                         {
01774                                 SkipRestOfLine( &p );
01775                                 continue;
01776                         }
01777                         if ( n )
01778                         {
01779                                 saber->saberFlags2 |= SFL2_NO_BLADE;
01780                         }
01781                         continue;
01782                 }
01783 
01784                 //default (0) is normal, 1 is a motion blur and 2 is no trail at all (good for real-sword type mods)
01785                 if ( !Q_stricmp( token, "trailStyle" ) ) 
01786                 {
01787                         if ( COM_ParseInt( &p, &n ) ) 
01788                         {
01789                                 SkipRestOfLine( &p );
01790                                 continue;
01791                         }
01792                         saber->trailStyle = n;
01793                         continue;
01794                 }
01795 
01796                 //if set, the game will use this shader for marks on enemies instead of the default "gfx/damage/saberglowmark"
01797                 if ( !Q_stricmp( token, "g2MarksShader" ) ) 
01798                 {
01799                         if ( COM_ParseString( &p, &value ) ) 
01800                         {
01801                                 SkipRestOfLine( &p );
01802                                 continue;
01803                         }
01804 #ifdef QAGAME//cgame-only cares about this
01805                         SkipRestOfLine(&p);
01806 #elif defined CGAME
01807                         saber->g2MarksShader = trap_R_RegisterShader( value );
01808 #else
01809                         SkipRestOfLine(&p);
01810 #endif
01811                         continue;
01812                 }
01813 
01814                 //if set, the game will use this shader for marks on enemies instead of the default "gfx/damage/saberglowmark"
01815                 if ( !Q_stricmp( token, "g2WeaponMarkShader" ) ) 
01816                 {
01817                         if ( COM_ParseString( &p, &value ) ) 
01818                         {
01819                                 SkipRestOfLine( &p );
01820                                 continue;
01821                         }
01822 #ifdef QAGAME//cgame-only cares about this
01823                         SkipRestOfLine(&p);
01824 #elif defined CGAME
01825                         saber->g2WeaponMarkShader = trap_R_RegisterShader( value );
01826 #else
01827                         SkipRestOfLine(&p);
01828 #endif
01829                         continue;
01830                 }
01831 
01832                 //if non-zero, uses damage done to calculate an appropriate amount of knockback
01833                 if ( !Q_stricmp( token, "knockbackScale" ) ) 
01834                 {
01835                         if ( COM_ParseFloat( &p, &f ) ) 
01836                         {
01837                                 SkipRestOfLine( &p );
01838                                 continue;
01839                         }
01840                         saber->knockbackScale = f;
01841                         continue;
01842                 }
01843 
01844                 //scale up or down the damage done by the saber
01845                 if ( !Q_stricmp( token, "damageScale" ) ) 
01846                 {
01847                         if ( COM_ParseFloat( &p, &f ) ) 
01848                         {
01849                                 SkipRestOfLine( &p );
01850                                 continue;
01851                         }
01852                         saber->damageScale = f;
01853                         continue;
01854                 }
01855 
01856                 //if non-zero, the saber never does dismemberment (good for pointed/blunt melee weapons)
01857                 if ( !Q_stricmp( token, "noDismemberment" ) ) 
01858                 {
01859                         if ( COM_ParseInt( &p, &n ) ) 
01860                         {
01861                                 SkipRestOfLine( &p );
01862                                 continue;
01863                         }
01864                         if ( n )
01865                         {
01866                                 saber->saberFlags2 |= SFL2_NO_DISMEMBERMENT;
01867                         }
01868                         continue;
01869                 }
01870 
01871                 //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)
01872                 if ( !Q_stricmp( token, "noIdleEffect" ) ) 
01873                 {
01874                         if ( COM_ParseInt( &p, &n ) ) 
01875                         {
01876                                 SkipRestOfLine( &p );
01877                                 continue;
01878                         }
01879                         if ( n )
01880                         {
01881                                 saber->saberFlags2 |= SFL2_NO_IDLE_EFFECT;
01882                         }
01883                         continue;
01884                 }
01885 
01886                 //if set, the blades will always be blocking (good for things like shields that should always block)
01887                 if ( !Q_stricmp( token, "alwaysBlock" ) ) 
01888                 {
01889                         if ( COM_ParseInt( &p, &n ) ) 
01890                         {
01891                                 SkipRestOfLine( &p );
01892                                 continue;
01893                         }
01894                         if ( n )
01895                         {
01896                                 saber->saberFlags2 |= SFL2_ALWAYS_BLOCK;
01897                         }
01898                         continue;
01899                 }
01900 
01901                 //if set, the blades cannot manually be toggled on and off
01902                 if ( !Q_stricmp( token, "noManualDeactivate" ) ) 
01903                 {
01904                         if ( COM_ParseInt( &p, &n ) ) 
01905                         {
01906                                 SkipRestOfLine( &p );
01907                                 continue;
01908                         }
01909                         if ( n )
01910                         {
01911                                 saber->saberFlags2 |= SFL2_NO_MANUAL_DEACTIVATE;
01912                         }
01913                         continue;
01914                 }
01915 
01916                 //if set, the blade does damage in start, transition and return anims (like strong style does)
01917                 if ( !Q_stricmp( token, "transitionDamage" ) ) 
01918                 {
01919                         if ( COM_ParseInt( &p, &n ) ) 
01920                         {
01921                                 SkipRestOfLine( &p );
01922                                 continue;
01923                         }
01924                         if ( n )
01925                         {
01926                                 saber->saberFlags2 |= SFL2_TRANSITION_DAMAGE;
01927                         }
01928                         continue;
01929                 }
01930 
01931                 //splashRadius - radius of splashDamage
01932                 if ( !Q_stricmp( token, "splashRadius" ) ) 
01933                 {
01934                         if ( COM_ParseFloat( &p, &f ) ) 
01935                         {
01936                                 SkipRestOfLine( &p );
01937                                 continue;
01938                         }
01939                         saber->splashRadius = f;
01940                         continue;
01941                 }
01942                 
01943                 //splashDamage - amount of splashDamage, 100% at a distance of 0, 0% at a distance = splashRadius
01944                 if ( !Q_stricmp( token, "splashDamage" ) ) 
01945                 {
01946                         if ( COM_ParseInt( &p, &n ) ) 
01947                         {
01948                                 SkipRestOfLine( &p );
01949                                 continue;
01950                         }
01951                         saber->splashDamage = n;
01952                         continue;
01953                 }
01954 
01955                 //splashKnockback - amount of splashKnockback, 100% at a distance of 0, 0% at a distance = splashRadius
01956                 if ( !Q_stricmp( token, "splashKnockback" ) ) 
01957                 {
01958                         if ( COM_ParseFloat( &p, &f ) ) 
01959                         {
01960                                 SkipRestOfLine( &p );
01961                                 continue;
01962                         }
01963                         saber->splashKnockback = f;
01964                         continue;
01965                 }
01966 
01967                 //hit sound - NOTE: must provide all 3!!!
01968                 if ( !Q_stricmp( token, "hitSound1" ) ) 
01969                 {
01970                         if ( COM_ParseString( &p, &value ) ) 
01971                         {
01972                                 continue;
01973                         }
01974                         saber->hitSound[0] = BG_SoundIndex( (char *)value );
01975                         continue;
01976                 }
01977 
01978                 //hit sound - NOTE: must provide all 3!!!
01979                 if ( !Q_stricmp( token, "hitSound2" ) ) 
01980                 {
01981                         if ( COM_ParseString( &p, &value ) ) 
01982                         {
01983                                 continue;
01984                         }
01985                         saber->hitSound[1] = BG_SoundIndex( (char *)value );
01986                         continue;
01987                 }
01988 
01989                 //hit sound - NOTE: must provide all 3!!!
01990                 if ( !Q_stricmp( token, "hitSound3" ) ) 
01991                 {
01992                         if ( COM_ParseString( &p, &value ) ) 
01993                         {
01994                                 continue;
01995                         }
01996                         saber->hitSound[2] = BG_SoundIndex( (char *)value );
01997                         continue;
01998                 }
01999 
02000                 //block sound - NOTE: must provide all 3!!!
02001                 if ( !Q_stricmp( token, "blockSound1" ) ) 
02002                 {
02003                         if ( COM_ParseString( &p, &value ) ) 
02004                         {
02005                                 continue;
02006                         }
02007                         saber->blockSound[0] = BG_SoundIndex( (char *)value );
02008                         continue;
02009                 }
02010 
02011                 //block sound - NOTE: must provide all 3!!!
02012                 if ( !Q_stricmp( token, "blockSound2" ) ) 
02013                 {
02014                         if ( COM_ParseString( &p, &value ) ) 
02015                         {
02016                                 continue;
02017                         }
02018                         saber->blockSound[1] = BG_SoundIndex( (char *)value );
02019                         continue;
02020                 }
02021 
02022                 //block sound - NOTE: must provide all 3!!!
02023                 if ( !Q_stricmp( token, "blockSound3" ) ) 
02024                 {
02025                         if ( COM_ParseString( &p, &value ) ) 
02026                         {
02027                                 continue;
02028                         }
02029                         saber->blockSound[2] = BG_SoundIndex( (char *)value );
02030                         continue;
02031                 }
02032 
02033                 //bounce sound - NOTE: must provide all 3!!!
02034                 if ( !Q_stricmp( token, "bounceSound1" ) ) 
02035                 {
02036                         if ( COM_ParseString( &p, &value ) ) 
02037                         {
02038                                 continue;
02039                         }
02040                         saber->bounceSound[0] = BG_SoundIndex( (char *)value );
02041                         continue;
02042                 }
02043 
02044                 //bounce sound - NOTE: must provide all 3!!!
02045                 if ( !Q_stricmp( token, "bounceSound2" ) ) 
02046                 {
02047                         if ( COM_ParseString( &p, &value ) ) 
02048                         {
02049                                 continue;
02050                         }
02051                         saber->bounceSound[1] = BG_SoundIndex( (char *)value );
02052                         continue;
02053                 }
02054 
02055                 //bounce sound - NOTE: must provide all 3!!!
02056                 if ( !Q_stricmp( token, "bounceSound3" ) ) 
02057                 {
02058                         if ( COM_ParseString( &p, &value ) ) 
02059                         {
02060                                 continue;
02061                         }
02062                         saber->bounceSound[2] = BG_SoundIndex( (char *)value );
02063                         continue;
02064                 }
02065 
02066                 //block effect - when saber/sword hits another saber/sword
02067                 if ( !Q_stricmp( token, "blockEffect" ) ) 
02068                 {
02069                         if ( COM_ParseString( &p, &value ) ) 
02070                         {
02071                                 continue;
02072                         }
02073 #ifdef QAGAME//cgame-only cares about this
02074                         SkipRestOfLine(&p);
02075 #elif defined CGAME
02076                         saber->blockEffect = trap_FX_RegisterEffect( (char *)value );
02077 #else
02078                         SkipRestOfLine(&p);
02079 #endif
02080                         continue;
02081                 }
02082 
02083                 //hit person effect - when saber/sword hits a person
02084                 if ( !Q_stricmp( token, "hitPersonEffect" ) ) 
02085                 {
02086                         if ( COM_ParseString( &p, &value ) ) 
02087                         {
02088                                 continue;
02089                         }
02090 #ifdef QAGAME//cgame-only cares about this
02091                         SkipRestOfLine(&p);
02092 #elif defined CGAME
02093                         saber->hitPersonEffect = trap_FX_RegisterEffect( (char *)value );
02094 #else
02095                         SkipRestOfLine(&p);
02096 #endif
02097                         continue;
02098                 }
02099 
02100                 //hit other effect - when saber/sword hits sopmething else damagable
02101                 if ( !Q_stricmp( token, "hitOtherEffect" ) ) 
02102                 {
02103                         if ( COM_ParseString( &p, &value ) ) 
02104                         {
02105                                 continue;
02106                         }
02107 #ifdef QAGAME//cgame-only cares about this
02108                         SkipRestOfLine(&p);
02109 #elif defined CGAME
02110                         saber->hitOtherEffect = trap_FX_RegisterEffect( (char *)value );
02111 #else
02112                         SkipRestOfLine(&p);
02113 #endif
02114                         continue;
02115                 }
02116 
02117                 //blade effect
02118                 if ( !Q_stricmp( token, "bladeEffect" ) ) 
02119                 {
02120                         if ( COM_ParseString( &p, &value ) ) 
02121                         {
02122                                 continue;
02123                         }
02124 #ifdef QAGAME//cgame-only cares about this
02125                         SkipRestOfLine(&p);
02126 #elif defined CGAME
02127                         saber->bladeEffect = trap_FX_RegisterEffect( (char *)value );
02128 #else
02129                         SkipRestOfLine(&p);
02130 #endif
02131                         continue;
02132                 }
02133 
02134                 //if non-zero, the saber will not do the big, white clash flare with other sabers
02135                 if ( !Q_stricmp( token, "noClashFlare" ) ) 
02136                 {
02137                         if ( COM_ParseInt( &p, &n ) ) 
02138                         {
02139                                 SkipRestOfLine( &p );
02140                                 continue;
02141                         }
02142                         if ( n )
02143                         {
02144                                 saber->saberFlags2 |= SFL2_NO_CLASH_FLARE;
02145                         }
02146                         continue;
02147                 }
02148 
02149                 //===SECONDARY BLADE====================================
02150                 //stops the saber from drawing marks on the world (good for real-sword type mods)
02151                 if ( !Q_stricmp( token, "noWallMarks2" ) ) 
02152                 {
02153                         if ( COM_ParseInt( &p, &n ) ) 
02154                         {
02155                                 SkipRestOfLine( &p );
02156                                 continue;
02157                         }
02158                         if ( n )
02159                         {
02160                                 saber->saberFlags2 |= SFL2_NO_WALL_MARKS2;
02161                         }
02162                         continue;
02163                 }
02164 
02165                 //stops the saber from drawing a dynamic light (good for real-sword type mods)
02166                 if ( !Q_stricmp( token, "noDlight2" ) ) 
02167                 {
02168                         if ( COM_ParseInt( &p, &n ) ) 
02169                         {
02170                                 SkipRestOfLine( &p );
02171                                 continue;
02172                         }
02173                         if ( n )
02174                         {
02175                                 saber->saberFlags2 |= SFL2_NO_DLIGHT2;
02176                         }
02177                         continue;
02178                 }
02179 
02180                 //stops the saber from drawing a blade (good for real-sword type mods)
02181                 if ( !Q_stricmp( token, "noBlade2" ) ) 
02182                 {
02183                         if ( COM_ParseInt( &p, &n ) ) 
02184                         {
02185                                 SkipRestOfLine( &p );
02186                                 continue;
02187                         }
02188                         if ( n )
02189                         {
02190                                 saber->saberFlags2 |= SFL2_NO_BLADE2;
02191                         }
02192                         continue;
02193                 }
02194 
02195                 //default (0) is normal, 1 is a motion blur and 2 is no trail at all (good for real-sword type mods)
02196                 if ( !Q_stricmp( token, "trailStyle2" ) ) 
02197                 {
02198                         if ( COM_ParseInt( &p, &n ) ) 
02199                         {
02200                                 SkipRestOfLine( &p );
02201                                 continue;
02202                         }
02203                         saber->trailStyle2 = n;
02204                         continue;
02205                 }
02206 
02207                 //if set, the game will use this shader for marks on enemies instead of the default "gfx/damage/saberglowmark"
02208                 if ( !Q_stricmp( token, "g2MarksShader2" ) ) 
02209                 {
02210                         if ( COM_ParseString( &p, &value ) ) 
02211                         {
02212                                 SkipRestOfLine( &p );
02213                                 continue;
02214                         }
02215 #ifdef QAGAME//cgame-only cares about this
02216                         SkipRestOfLine(&p);
02217 #elif defined CGAME
02218                         saber->g2MarksShader2 = trap_R_RegisterShader( value );
02219 #else
02220                         SkipRestOfLine(&p);
02221 #endif
02222                         continue;
02223                 }
02224 
02225                 //if set, the game will use this shader for marks on enemies instead of the default "gfx/damage/saberglowmark"
02226                 if ( !Q_stricmp( token, "g2WeaponMarkShader2" ) ) 
02227                 {
02228                         if ( COM_ParseString( &p, &value ) ) 
02229                         {
02230                                 SkipRestOfLine( &p );
02231                                 continue;
02232                         }
02233 #ifdef QAGAME//cgame-only cares about this
02234                         SkipRestOfLine(&p);
02235 #elif defined CGAME
02236                         saber->g2WeaponMarkShader2 = trap_R_RegisterShader( value );
02237 #else
02238                         SkipRestOfLine(&p);
02239 #endif
02240                         continue;
02241                 }
02242 
02243                 //if non-zero, uses damage done to calculate an appropriate amount of knockback
02244                 if ( !Q_stricmp( token, "knockbackScale2" ) ) 
02245                 {
02246                         if ( COM_ParseFloat( &p, &f ) ) 
02247                         {
02248                                 SkipRestOfLine( &p );
02249                                 continue;
02250                         }
02251                         saber->knockbackScale2 = f;
02252                         continue;
02253                 }
02254 
02255                 //scale up or down the damage done by the saber
02256                 if ( !Q_stricmp( token, "damageScale2" ) ) 
02257                 {
02258                         if ( COM_ParseFloat( &p, &f ) ) 
02259                         {
02260                                 SkipRestOfLine( &p );
02261                                 continue;
02262                         }
02263                         saber->damageScale2 = f;
02264                         continue;
02265                 }
02266 
02267                 //if non-zero, the saber never does dismemberment (good for pointed/blunt melee weapons)
02268                 if ( !Q_stricmp( token, "noDismemberment2" ) ) 
02269                 {
02270                         if ( COM_ParseInt( &p, &n ) ) 
02271                         {
02272                                 SkipRestOfLine( &p );
02273                                 continue;
02274                         }
02275                         if ( n )
02276                         {
02277                                 saber->saberFlags2 |= SFL2_NO_DISMEMBERMENT2;
02278                         }
02279                         continue;
02280                 }
02281 
02282                 //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)
02283                 if ( !Q_stricmp( token, "noIdleEffect2" ) ) 
02284                 {
02285                         if ( COM_ParseInt( &p, &n ) ) 
02286                         {
02287                                 SkipRestOfLine( &p );
02288                                 continue;
02289                         }
02290                         if ( n )
02291                         {
02292                                 saber->saberFlags2 |= SFL2_NO_IDLE_EFFECT2;
02293                         }
02294                         continue;
02295                 }
02296 
02297                 //if set, the blades will always be blocking (good for things like shields that should always block)
02298                 if ( !Q_stricmp( token, "alwaysBlock2" ) ) 
02299                 {
02300                         if ( COM_ParseInt( &p, &n ) ) 
02301                         {
02302                                 SkipRestOfLine( &p );
02303                                 continue;
02304                         }
02305                         if ( n )
02306                         {
02307                                 saber->saberFlags2 |= SFL2_ALWAYS_BLOCK2;
02308                         }
02309                         continue;
02310                 }
02311 
02312                 //if set, the blades cannot manually be toggled on and off
02313                 if ( !Q_stricmp( token, "noManualDeactivate2" ) ) 
02314                 {
02315                         if ( COM_ParseInt( &p, &n ) ) 
02316                         {
02317                                 SkipRestOfLine( &p );
02318                                 continue;
02319                         }
02320                         if ( n )
02321                         {
02322                                 saber->saberFlags2 |= SFL2_NO_MANUAL_DEACTIVATE2;
02323                         }
02324                         continue;
02325                 }
02326 
02327                 //if set, the blade does damage in start, transition and return anims (like strong style does)
02328                 if ( !Q_stricmp( token, "transitionDamage2" ) ) 
02329                 {
02330                         if ( COM_ParseInt( &p, &n ) ) 
02331                         {
02332                                 SkipRestOfLine( &p );
02333                                 continue;
02334                         }
02335                         if ( n )
02336                         {
02337                                 saber->saberFlags2 |= SFL2_TRANSITION_DAMAGE2;
02338                         }
02339                         continue;
02340                 }
02341 
02342                 //splashRadius - radius of splashDamage
02343                 if ( !Q_stricmp( token, "splashRadius2" ) ) 
02344                 {
02345                         if ( COM_ParseFloat( &p, &f ) ) 
02346                         {
02347                                 SkipRestOfLine( &p );
02348                                 continue;
02349                         }
02350                         saber->splashRadius2 = f;
02351                         continue;
02352                 }
02353                 
02354                 //splashDamage - amount of splashDamage, 100% at a distance of 0, 0% at a distance = splashRadius
02355                 if ( !Q_stricmp( token, "splashDamage2" ) ) 
02356                 {
02357                         if ( COM_ParseInt( &p, &n ) ) 
02358                         {
02359                                 SkipRestOfLine( &p );
02360                                 continue;
02361                         }
02362                         saber->splashDamage2 = n;
02363                         continue;
02364                 }
02365 
02366                 //splashKnockback - amount of splashKnockback, 100% at a distance of 0, 0% at a distance = splashRadius
02367                 if ( !Q_stricmp( token, "splashKnockback2" ) ) 
02368                 {
02369                         if ( COM_ParseFloat( &p, &f ) ) 
02370                         {
02371                                 SkipRestOfLine( &p );
02372                                 continue;
02373                         }
02374                         saber->splashKnockback2 = f;
02375                         continue;
02376                 }
02377 
02378                 //hit sound - NOTE: must provide all 3!!!
02379                 if ( !Q_stricmp( token, "hit2Sound1" ) ) 
02380                 {
02381                         if ( COM_ParseString( &p, &value ) ) 
02382                         {
02383                                 continue;
02384                         }
02385                         saber->hit2Sound[0] = BG_SoundIndex( (char *)value );
02386                         continue;
02387                 }
02388 
02389                 //hit sound - NOTE: must provide all 3!!!
02390                 if ( !Q_stricmp( token, "hit2Sound2" ) ) 
02391                 {
02392                         if ( COM_ParseString( &p, &value ) ) 
02393                         {
02394                                 continue;
02395                         }
02396                         saber->hit2Sound[1] = BG_SoundIndex( (char *)value );
02397                         continue;
02398                 }
02399 
02400                 //hit sound - NOTE: must provide all 3!!!
02401                 if ( !Q_stricmp( token, "hit2Sound3" ) ) 
02402                 {
02403                         if ( COM_ParseString( &p, &value ) ) 
02404                         {
02405                                 continue;
02406                         }
02407                         saber->hit2Sound[2] = BG_SoundIndex( (char *)value );
02408                         continue;
02409                 }
02410 
02411                 //block sound - NOTE: must provide all 3!!!
02412                 if ( !Q_stricmp( token, "block2Sound1" ) ) 
02413                 {
02414                         if ( COM_ParseString( &p, &value ) ) 
02415                         {
02416                                 continue;
02417                         }
02418                         saber->block2Sound[0] = BG_SoundIndex( (char *)value );
02419                         continue;
02420                 }
02421 
02422                 //block sound - NOTE: must provide all 3!!!
02423                 if ( !Q_stricmp( token, "block2Sound2" ) ) 
02424                 {
02425                         if ( COM_ParseString( &p, &value ) ) 
02426                         {
02427                                 continue;
02428                         }
02429                         saber->block2Sound[1] = BG_SoundIndex( (char *)value );
02430                         continue;
02431                 }
02432 
02433                 //block sound - NOTE: must provide all 3!!!
02434                 if ( !Q_stricmp( token, "block2Sound3" ) ) 
02435                 {
02436                         if ( COM_ParseString( &p, &value ) ) 
02437                         {
02438                                 continue;
02439                         }
02440                         saber->block2Sound[2] = BG_SoundIndex( (char *)value );
02441                         continue;
02442                 }
02443 
02444                 //bounce sound - NOTE: must provide all 3!!!
02445                 if ( !Q_stricmp( token, "bounce2Sound1" ) ) 
02446                 {
02447                         if ( COM_ParseString( &p, &value ) ) 
02448                         {
02449                                 continue;
02450                         }
02451                         saber->bounce2Sound[0] = BG_SoundIndex( (char *)value );
02452                         continue;
02453                 }
02454 
02455                 //bounce sound - NOTE: must provide all 3!!!
02456                 if ( !Q_stricmp( token, "bounce2Sound2" ) ) 
02457                 {
02458                         if ( COM_ParseString( &p, &value ) ) 
02459                         {
02460                                 continue;
02461                         }
02462                         saber->bounce2Sound[1] = BG_SoundIndex( (char *)value );
02463                         continue;
02464                 }
02465 
02466                 //bounce sound - NOTE: must provide all 3!!!
02467                 if ( !Q_stricmp( token, "bounce2Sound3" ) ) 
02468                 {
02469                         if ( COM_ParseString( &p, &value ) ) 
02470                         {
02471                                 continue;
02472                         }
02473                         saber->bounce2Sound[2] = BG_SoundIndex( (char *)value );
02474                         continue;
02475                 }
02476 
02477                 //block effect - when saber/sword hits another saber/sword
02478                 if ( !Q_stricmp( token, "blockEffect2" ) ) 
02479                 {
02480                         if ( COM_ParseString( &p, &value ) ) 
02481                         {
02482                                 continue;
02483                         }
02484 #ifdef QAGAME//cgame-only cares about this
02485                         SkipRestOfLine(&p);
02486 #elif defined CGAME
02487                         saber->blockEffect2 = trap_FX_RegisterEffect( (char *)value );
02488 #else
02489                         SkipRestOfLine(&p);
02490 #endif
02491                         continue;
02492                 }
02493 
02494                 //hit person effect - when saber/sword hits a person
02495                 if ( !Q_stricmp( token, "hitPersonEffect2" ) ) 
02496                 {
02497                         if ( COM_ParseString( &p, &value ) ) 
02498                         {
02499                                 continue;
02500                         }
02501 #ifdef QAGAME//cgame-only cares about this
02502                         SkipRestOfLine(&p);
02503 #elif defined CGAME
02504                         saber->hitPersonEffect2 = trap_FX_RegisterEffect( (char *)value );
02505 #else
02506                         SkipRestOfLine(&p);
02507 #endif
02508                         continue;
02509                 }
02510 
02511                 //hit other effect - when saber/sword hits sopmething else damagable
02512                 if ( !Q_stricmp( token, "hitOtherEffect2" ) ) 
02513                 {
02514                         if ( COM_ParseString( &p, &value ) ) 
02515                         {
02516                                 continue;
02517                         }
02518 #ifdef QAGAME//cgame-only cares about this
02519                         SkipRestOfLine(&p);
02520 #elif defined CGAME
02521                         saber->hitOtherEffect2 = trap_FX_RegisterEffect( (char *)value );
02522 #else
02523                         SkipRestOfLine(&p);
02524 #endif
02525                         continue;
02526                 }
02527 
02528                 //blade effect
02529                 if ( !Q_stricmp( token, "bladeEffect2" ) ) 
02530                 {
02531                         if ( COM_ParseString( &p, &value ) ) 
02532                         {
02533                                 continue;
02534                         }
02535 #ifdef QAGAME//cgame-only cares about this
02536                         SkipRestOfLine(&p);
02537 #elif defined CGAME
02538                         saber->bladeEffect2 = trap_FX_RegisterEffect( (char *)value );
02539 #else
02540                         SkipRestOfLine(&p);
02541 #endif
02542                         continue;
02543                 }
02544 
02545                 //if non-zero, the saber will not do the big, white clash flare with other sabers
02546                 if ( !Q_stricmp( token, "noClashFlare2" ) ) 
02547                 {
02548                         if ( COM_ParseInt( &p, &n ) ) 
02549                         {
02550                                 SkipRestOfLine( &p );
02551                                 continue;
02552                         }
02553                         if ( n )
02554                         {
02555                                 saber->saberFlags2 |= SFL2_NO_CLASH_FLARE2;
02556                         }
02557                         continue;
02558                 }
02559 //===END BLADE-SPECIFIC FIELDS=============================================================================
02560 
02561                 //FIXME: saber sounds (on, off, loop)
02562 
02563 #ifdef _DEBUG
02564                 Com_Printf( "WARNING: unknown keyword '%s' while parsing '%s'\n", token, useSaber );
02565 #endif
02566                 SkipRestOfLine( &p );
02567         }
02568 
02569         //FIXME: precache the saberModel(s)?
02570 
02571         return qtrue;
02572 }


Variable Documentation

stringID_table_t BSETTable[]
 

Initial value:

{
        ENUM2STRING(BSET_SPAWN),
        ENUM2STRING(BSET_USE),
        ENUM2STRING(BSET_AWAKE),
        ENUM2STRING(BSET_ANGER),
        ENUM2STRING(BSET_ATTACK),
        ENUM2STRING(BSET_VICTORY),
        ENUM2STRING(BSET_LOSTENEMY),
        ENUM2STRING(BSET_PAIN),
        ENUM2STRING(BSET_FLEE),
        ENUM2STRING(BSET_DEATH),
        ENUM2STRING(BSET_DELAYED),
        ENUM2STRING(BSET_BLOCKED),
        ENUM2STRING(BSET_BUMPED),
        ENUM2STRING(BSET_STUCK),
        ENUM2STRING(BSET_FFIRE),
        ENUM2STRING(BSET_FFDEATH),
        stringIDExpand("", BSET_INVALID),
        "",                             -1,
}

Definition at line 106 of file NPC_stats.c.

Referenced by G_ActivateBehavior().

stringID_table_t BSTable[]
 

Initial value:

{
        ENUM2STRING(BS_DEFAULT),
        ENUM2STRING(BS_ADVANCE_FIGHT),
        ENUM2STRING(BS_SLEEP),
        ENUM2STRING(BS_FOLLOW_LEADER),
        ENUM2STRING(BS_JUMP),
        ENUM2STRING(BS_SEARCH),
        ENUM2STRING(BS_WANDER),
        ENUM2STRING(BS_NOCLIP),
        ENUM2STRING(BS_REMOVE),
        ENUM2STRING(BS_CINEMATIC),
        
        "",                             -1,
}

Definition at line 88 of file NPC_stats.c.

char* ClassNames[CLASS_NUM_CLASSES]
 

Definition at line 156 of file NPC_stats.c.

stringID_table_t ClassTable[]
 

Definition at line 24 of file NPC_stats.c.

Referenced by NPC_ParseParms().

stringID_table_t FPTable[]
 

Definition at line 130 of file NPC_stats.c.

char NPCFile[MAX_QPATH]
 

Definition at line 238 of file NPC_stats.c.

Referenced by NPC_ParseParms(), NPC_Precache(), and NPC_PrecacheAnimationCFG().

char NPCParms[MAX_NPC_DATA_SIZE]
 

Definition at line 237 of file NPC_stats.c.

Referenced by NPC_LoadParms(), NPC_ParseParms(), NPC_Precache(), and NPC_PrecacheAnimationCFG().

char npcParseBuffer[MAX_NPC_DATA_SIZE]
 

Definition at line 3238 of file NPC_stats.c.

Referenced by NPC_LoadParms().

qboolean NPCsPrecached
 

Definition at line 7 of file NPC_stats.c.

char* TeamNames[TEAM_NUM_TEAMS]
 

Initial value:

 
{
        "",














        "player",
        "enemy",
        "neutral"
}

Definition at line 133 of file NPC_stats.c.

Referenced by NPC_Kill_f().

stringID_table_t TeamTable[]
 

Initial value:

{
        ENUM2STRING(NPCTEAM_FREE),                      
        ENUM2STRING(NPCTEAM_PLAYER),
        ENUM2STRING(NPCTEAM_ENEMY),
        ENUM2STRING(NPCTEAM_NEUTRAL),   
        "",     -1
}

Definition at line 14 of file NPC_stats.c.

Referenced by NPC_Kill_f(), NPC_ParseParms(), and NPC_Precache().

stringID_table_t WPTable[]
 

Definition at line 129 of file NPC_stats.c.

Referenced by BG_SiegeParseClassFile(), NPC_ParseParms(), NPC_Precache(), and SP_misc_weapon_shooter().