00001
00002
00003 #ifdef _JK2 //SP does not have this preprocessor for game like MP does
00004 #ifndef _JK2MP
00005 #define _JK2MP
00006 #endif
00007 #endif
00008
00009 #ifdef _JK2MP
00010 #include "q_shared.h"
00011 #include "bg_public.h"
00012 #include "bg_vehicles.h"
00013 #include "bg_weapons.h"
00014
00015
00016 #include "../namespace_begin.h"
00017 extern int trap_FS_FOpenFile( const char *qpath, fileHandle_t *f, fsMode_t mode );
00018 extern void trap_FS_Read( void *buffer, int len, fileHandle_t f );
00019 extern void trap_FS_Write( const void *buffer, int len, fileHandle_t f );
00020 extern void trap_FS_FCloseFile( fileHandle_t f );
00021 extern int trap_FS_GetFileList( const char *path, const char *extension, char *listbuf, int bufsize );
00022 #include "../namespace_end.h"
00023 #else
00024 #include "g_local.h"
00025 #define QAGAME
00026 #endif
00027
00028
00029 #ifdef _JK2MP
00030 #ifndef QAGAME
00031 #ifndef CGAME
00032 #define WE_ARE_IN_THE_UI
00033 #include "../ui/ui_local.h"
00034 #endif
00035 #endif
00036 #endif
00037
00038 #ifndef _JK2MP
00039 #include "..\Ratl\string_vs.h"
00040 #endif
00041
00042 #ifdef QAGAME
00043 extern void G_SetSharedVehicleFunctions( vehicleInfo_t *pVehInfo );
00044 extern int G_ModelIndex( const char *name );
00045 extern int G_SoundIndex( const char *name );
00046 #ifdef _JK2MP
00047 extern int G_EffectIndex( const char *name );
00048 #endif
00049 #elif CGAME
00050 #include "../namespace_begin.h"
00051 extern qhandle_t trap_R_RegisterModel( const char *name );
00052 extern qhandle_t trap_R_RegisterSkin( const char *name );
00053 extern qhandle_t trap_R_RegisterShader( const char *name );
00054 extern qhandle_t trap_R_RegisterShaderNoMip( const char *name );
00055 extern int trap_FX_RegisterEffect(const char *file);
00056 extern sfxHandle_t trap_S_RegisterSound( const char *sample);
00057 #include "../namespace_end.h"
00058 #else//UI
00059 #include "../namespace_begin.h"
00060 extern qhandle_t trap_R_RegisterModel( const char *name );
00061 extern qhandle_t trap_R_RegisterSkin( const char *name );
00062 extern qhandle_t trap_R_RegisterShader( const char *name );
00063 extern qhandle_t trap_R_RegisterShaderNoMip( const char *name );
00064 extern sfxHandle_t trap_S_RegisterSound( const char *sample);
00065 #include "../namespace_end.h"
00066 #endif
00067
00068 extern stringID_table_t animTable [MAX_ANIMATIONS+1];
00069
00070
00071
00072 #define MAX_VEH_WEAPON_DATA_SIZE 0x4000
00073 #define MAX_VEHICLE_DATA_SIZE 0x10000
00074
00075 #if !defined(_XBOX) || defined(QAGAME)
00076 char VehWeaponParms[MAX_VEH_WEAPON_DATA_SIZE];
00077 char VehicleParms[MAX_VEHICLE_DATA_SIZE];
00078
00079 void BG_ClearVehicleParseParms(void)
00080 {
00081
00082 VehWeaponParms[0] = 0;
00083 VehicleParms[0] = 0;
00084 }
00085
00086 #else
00087 extern char VehWeaponParms[MAX_VEH_WEAPON_DATA_SIZE];
00088 extern char VehicleParms[MAX_VEHICLE_DATA_SIZE];
00089 #endif
00090
00091 #ifdef _JK2MP
00092 #include "../namespace_begin.h"
00093 #endif
00094
00095 #ifndef WE_ARE_IN_THE_UI
00096
00097 extern void G_SetAnimalVehicleFunctions( vehicleInfo_t *pVehInfo );
00098 extern void G_SetSpeederVehicleFunctions( vehicleInfo_t *pVehInfo );
00099 extern void G_SetWalkerVehicleFunctions( vehicleInfo_t *pVehInfo );
00100 extern void G_SetFighterVehicleFunctions( vehicleInfo_t *pVehInfo );
00101 #endif
00102
00103 vehWeaponInfo_t g_vehWeaponInfo[MAX_VEH_WEAPONS];
00104 int numVehicleWeapons = 1;
00105
00106 vehicleInfo_t g_vehicleInfo[MAX_VEHICLES];
00107 int numVehicles = 0;
00108
00109 void BG_VehicleLoadParms( void );
00110
00111 typedef enum {
00112 VF_IGNORE,
00113 VF_INT,
00114 VF_FLOAT,
00115 VF_LSTRING,
00116 VF_VECTOR,
00117 VF_BOOL,
00118 VF_VEHTYPE,
00119 VF_ANIM,
00120 VF_WEAPON,
00121 VF_MODEL,
00122 VF_MODEL_CLIENT,
00123 VF_EFFECT,
00124 VF_EFFECT_CLIENT,
00125 VF_SHADER,
00126 VF_SHADER_NOMIP,
00127 VF_SOUND,
00128 VF_SOUND_CLIENT
00129 } vehFieldType_t;
00130
00131 typedef struct
00132 {
00133 char *name;
00134 int ofs;
00135 vehFieldType_t type;
00136 } vehField_t;
00137
00138 vehField_t vehWeaponFields[NUM_VWEAP_PARMS] =
00139 {
00140 {"name", VWFOFS(name), VF_LSTRING},
00141 {"projectile", VWFOFS(bIsProjectile), VF_BOOL},
00142 {"hasGravity", VWFOFS(bHasGravity), VF_BOOL},
00143 {"ionWeapon", VWFOFS(bIonWeapon), VF_BOOL},
00144 {"saberBlockable", VWFOFS(bSaberBlockable), VF_BOOL},
00145 {"muzzleFX", VWFOFS(iMuzzleFX), VF_EFFECT_CLIENT},
00146 {"model", VWFOFS(iModel), VF_MODEL_CLIENT},
00147 {"shotFX", VWFOFS(iShotFX), VF_EFFECT_CLIENT},
00148 {"impactFX", VWFOFS(iImpactFX), VF_EFFECT_CLIENT},
00149 {"g2MarkShader", VWFOFS(iG2MarkShaderHandle), VF_SHADER},
00150 {"g2MarkSize", VWFOFS(fG2MarkSize), VF_FLOAT},
00151 {"loopSound", VWFOFS(iLoopSound), VF_SOUND_CLIENT},
00152 {"speed", VWFOFS(fSpeed), VF_FLOAT},
00153 {"homing", VWFOFS(fHoming), VF_FLOAT},
00154 {"homingFOV", VWFOFS(fHomingFOV), VF_FLOAT},
00155 {"lockOnTime", VWFOFS(iLockOnTime), VF_INT},
00156 {"damage", VWFOFS(iDamage), VF_INT},
00157 {"splashDamage", VWFOFS(iSplashDamage), VF_INT},
00158 {"splashRadius", VWFOFS(fSplashRadius), VF_FLOAT},
00159 {"ammoPerShot", VWFOFS(iAmmoPerShot), VF_INT},
00160 {"health", VWFOFS(iHealth), VF_INT},
00161 {"width", VWFOFS(fWidth), VF_FLOAT},
00162 {"height", VWFOFS(fHeight), VF_FLOAT},
00163 {"lifetime", VWFOFS(iLifeTime), VF_INT},
00164 {"explodeOnExpire", VWFOFS(bExplodeOnExpire), VF_BOOL},
00165 };
00166
00167 static qboolean BG_ParseVehWeaponParm( vehWeaponInfo_t *vehWeapon, char *parmName, char *pValue )
00168 {
00169 int i;
00170 vec3_t vec;
00171 byte *b = (byte *)vehWeapon;
00172 int _iFieldsRead = 0;
00173 vehicleType_t vehType;
00174 char value[1024];
00175
00176 Q_strncpyz( value, pValue, sizeof(value) );
00177
00178
00179 for ( i = 0; i < NUM_VWEAP_PARMS; i++ )
00180 {
00181 if ( vehWeaponFields[i].name && !Q_stricmp( vehWeaponFields[i].name, parmName ) )
00182 {
00183
00184 switch( vehWeaponFields[i].type )
00185 {
00186 case VF_INT:
00187 *(int *)(b+vehWeaponFields[i].ofs) = atoi(value);
00188 break;
00189 case VF_FLOAT:
00190 *(float *)(b+vehWeaponFields[i].ofs) = atof(value);
00191 break;
00192 case VF_LSTRING:
00193 if (!*(char **)(b+vehWeaponFields[i].ofs))
00194 {
00195 #ifdef _JK2MP
00196 *(char **)(b+vehWeaponFields[i].ofs) = (char *)BG_Alloc(1024);
00197 strcpy(*(char **)(b+vehWeaponFields[i].ofs), value);
00198 #else
00199 (*(char **)(b+vehWeaponFields[i].ofs)) = G_NewString( value );
00200 #endif
00201 }
00202
00203 break;
00204 case VF_VECTOR:
00205 _iFieldsRead = sscanf (value, "%f %f %f", &vec[0], &vec[1], &vec[2]);
00206 assert(_iFieldsRead==3 );
00207 if (_iFieldsRead!=3)
00208 {
00209 Com_Printf (S_COLOR_YELLOW"BG_ParseVehWeaponParm: VEC3 sscanf() failed to read 3 floats ('angle' key bug?)\n");
00210 }
00211 ((float *)(b+vehWeaponFields[i].ofs))[0] = vec[0];
00212 ((float *)(b+vehWeaponFields[i].ofs))[1] = vec[1];
00213 ((float *)(b+vehWeaponFields[i].ofs))[2] = vec[2];
00214 break;
00215 case VF_BOOL:
00216 *(qboolean *)(b+vehWeaponFields[i].ofs) = (qboolean)(atof(value)!=0);
00217 break;
00218 case VF_VEHTYPE:
00219 vehType = (vehicleType_t)GetIDForString( VehicleTable, value );
00220 *(vehicleType_t *)(b+vehWeaponFields[i].ofs) = vehType;
00221 break;
00222 case VF_ANIM:
00223 {
00224 int anim = GetIDForString( animTable, value );
00225 *(int *)(b+vehWeaponFields[i].ofs) = anim;
00226 }
00227 break;
00228 case VF_WEAPON:
00229
00230 break;
00231 case VF_MODEL:
00232 #ifdef QAGAME
00233 *(int *)(b+vehWeaponFields[i].ofs) = G_ModelIndex( value );
00234 #else
00235 *(int *)(b+vehWeaponFields[i].ofs) = trap_R_RegisterModel( value );
00236 #endif
00237 break;
00238 case VF_MODEL_CLIENT:
00239 #ifndef _JK2MP
00240 *(int *)(b+vehWeaponFields[i].ofs) = G_ModelIndex( value );
00241 #elif QAGAME
00242
00243 #else
00244 *(int *)(b+vehWeaponFields[i].ofs) = trap_R_RegisterModel( value );
00245 #endif
00246 break;
00247 case VF_EFFECT:
00248 #ifdef QAGAME
00249 *(int *)(b+vehWeaponFields[i].ofs) = G_EffectIndex( value );
00250 #elif CGAME
00251 *(int *)(b+vehWeaponFields[i].ofs) = trap_FX_RegisterEffect( value );
00252 #endif
00253 break;
00254 case VF_EFFECT_CLIENT:
00255 #ifndef _JK2MP
00256 *(int *)(b+vehWeaponFields[i].ofs) = G_EffectIndex( value );
00257 #elif QAGAME
00258
00259 #elif CGAME
00260 *(int *)(b+vehWeaponFields[i].ofs) = trap_FX_RegisterEffect( value );
00261 #endif
00262 break;
00263 case VF_SHADER:
00264 #ifdef WE_ARE_IN_THE_UI
00265 *(int *)(b+vehWeaponFields[i].ofs) = trap_R_RegisterShaderNoMip( value );
00266 #elif CGAME
00267 *(int *)(b+vehWeaponFields[i].ofs) = trap_R_RegisterShader( value );
00268 #endif
00269 break;
00270 case VF_SHADER_NOMIP:
00271 #ifndef QAGAME
00272 *(int *)(b+vehWeaponFields[i].ofs) = trap_R_RegisterShaderNoMip( value );
00273 #endif
00274 break;
00275 case VF_SOUND:
00276 #ifdef QAGAME
00277 *(int *)(b+vehWeaponFields[i].ofs) = G_SoundIndex( value );
00278 #else
00279 *(int *)(b+vehWeaponFields[i].ofs) = trap_S_RegisterSound( value );
00280 #endif
00281 break;
00282 case VF_SOUND_CLIENT:
00283 #ifndef _JK2MP
00284 *(int *)(b+vehWeaponFields[i].ofs) = G_SoundIndex( value );
00285 #elif QAGAME
00286
00287 #else
00288 *(int *)(b+vehWeaponFields[i].ofs) = trap_S_RegisterSound( value );
00289 #endif
00290 break;
00291 default:
00292
00293 return qfalse;
00294 break;
00295 }
00296 break;
00297 }
00298 }
00299 if ( i == NUM_VWEAP_PARMS )
00300 {
00301 return qfalse;
00302 }
00303 else
00304 {
00305 return qtrue;
00306 }
00307 }
00308
00309 int VEH_LoadVehWeapon( const char *vehWeaponName )
00310 {
00311 const char *token;
00312 char parmName[128];
00313 char *value;
00314 const char *p;
00315 vehWeaponInfo_t *vehWeapon = NULL;
00316
00317
00318
00319
00320 p = VehWeaponParms;
00321
00322 #ifdef _JK2MP
00323 COM_BeginParseSession("vehWeapons");
00324 #else
00325 COM_BeginParseSession();
00326 #endif
00327
00328 vehWeapon = &g_vehWeaponInfo[numVehicleWeapons];
00329
00330 while ( p )
00331 {
00332 token = COM_ParseExt( &p, qtrue );
00333 if ( token[0] == 0 )
00334 {
00335 return qfalse;
00336 }
00337
00338 if ( !Q_stricmp( token, vehWeaponName ) )
00339 {
00340 break;
00341 }
00342
00343 SkipBracedSection( &p );
00344 }
00345 if ( !p )
00346 {
00347 return qfalse;
00348 }
00349
00350 token = COM_ParseExt( &p, qtrue );
00351 if ( token[0] == 0 )
00352 {
00353 return VEH_WEAPON_NONE;
00354 }
00355
00356 if ( Q_stricmp( token, "{" ) != 0 )
00357 {
00358 return VEH_WEAPON_NONE;
00359 }
00360
00361
00362 while ( 1 )
00363 {
00364 SkipRestOfLine( &p );
00365 token = COM_ParseExt( &p, qtrue );
00366 if ( !token[0] )
00367 {
00368 Com_Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing Vehicle Weapon '%s'\n", vehWeaponName );
00369 return VEH_WEAPON_NONE;
00370 }
00371
00372 if ( !Q_stricmp( token, "}" ) )
00373 {
00374 break;
00375 }
00376 Q_strncpyz( parmName, token, sizeof(parmName) );
00377 value = COM_ParseExt( &p, qtrue );
00378 if ( !value || !value[0] )
00379 {
00380 Com_Printf( S_COLOR_RED"ERROR: Vehicle Weapon token '%s' has no value!\n", parmName );
00381 }
00382 else
00383 {
00384 if ( !BG_ParseVehWeaponParm( vehWeapon, parmName, value ) )
00385 {
00386 Com_Printf( S_COLOR_RED"ERROR: Unknown Vehicle Weapon key/value pair '%s','%s'!\n", parmName, value );
00387 }
00388 }
00389 }
00390 if ( vehWeapon->fHoming )
00391 {
00392 #ifdef QAGAME
00393
00394
00395
00396 #elif CGAME
00397 trap_S_RegisterSound( "sound/vehicles/weapons/common/tick.wav" );
00398 trap_S_RegisterSound( "sound/vehicles/weapons/common/lock.wav" );
00399 trap_S_RegisterSound( "sound/vehicles/common/lockalarm1.wav" );
00400 trap_S_RegisterSound( "sound/vehicles/common/lockalarm2.wav" );
00401 trap_S_RegisterSound( "sound/vehicles/common/lockalarm3.wav" );
00402 #else
00403 trap_S_RegisterSound( "sound/vehicles/weapons/common/tick.wav" );
00404 trap_S_RegisterSound( "sound/vehicles/weapons/common/lock.wav" );
00405 trap_S_RegisterSound( "sound/vehicles/common/lockalarm1.wav" );
00406 trap_S_RegisterSound( "sound/vehicles/common/lockalarm2.wav" );
00407 trap_S_RegisterSound( "sound/vehicles/common/lockalarm3.wav" );
00408 #endif
00409 }
00410 return (numVehicleWeapons++);
00411 }
00412
00413 int VEH_VehWeaponIndexForName( const char *vehWeaponName )
00414 {
00415 int vw;
00416 if ( !vehWeaponName || !vehWeaponName[0] )
00417 {
00418 Com_Printf( S_COLOR_RED"ERROR: Trying to read Vehicle Weapon with no name!\n" );
00419 return VEH_WEAPON_NONE;
00420 }
00421 for ( vw = VEH_WEAPON_BASE; vw < numVehicleWeapons; vw++ )
00422 {
00423 if ( g_vehWeaponInfo[vw].name
00424 && Q_stricmp( g_vehWeaponInfo[vw].name, vehWeaponName ) == 0 )
00425 {
00426 return vw;
00427 }
00428 }
00429
00430 if ( vw >= MAX_VEH_WEAPONS )
00431 {
00432 Com_Printf( S_COLOR_RED"ERROR: Too many Vehicle Weapons (max 16), aborting load on %s!\n", vehWeaponName );
00433 return VEH_WEAPON_NONE;
00434 }
00435
00436
00437 vw = VEH_LoadVehWeapon( vehWeaponName );
00438 if ( vw == VEH_WEAPON_NONE )
00439 {
00440 Com_Printf( S_COLOR_RED"ERROR: Could not find Vehicle Weapon %s!\n", vehWeaponName );
00441 }
00442 return vw;
00443 }
00444
00445 vehField_t vehicleFields[] =
00446 {
00447 {"name", VFOFS(name), VF_LSTRING},
00448
00449
00450 {"type", VFOFS(type), VF_VEHTYPE},
00451 {"numHands", VFOFS(numHands), VF_INT},
00452 {"lookPitch", VFOFS(lookPitch), VF_FLOAT},
00453 {"lookYaw", VFOFS(lookYaw), VF_FLOAT},
00454 {"length", VFOFS(length), VF_FLOAT},
00455 {"width", VFOFS(width), VF_FLOAT},
00456 {"height", VFOFS(height), VF_FLOAT},
00457 {"centerOfGravity", VFOFS(centerOfGravity), VF_VECTOR},
00458
00459
00460 {"speedMax", VFOFS(speedMax), VF_FLOAT},
00461 {"turboSpeed", VFOFS(turboSpeed), VF_FLOAT},
00462 {"speedMin", VFOFS(speedMin), VF_FLOAT},
00463 {"speedIdle", VFOFS(speedIdle), VF_FLOAT},
00464 {"accelIdle", VFOFS(accelIdle), VF_FLOAT},
00465 {"acceleration", VFOFS(acceleration), VF_FLOAT},
00466 {"decelIdle", VFOFS(decelIdle), VF_FLOAT},
00467 {"throttleSticks", VFOFS(throttleSticks), VF_BOOL},
00468 {"strafePerc", VFOFS(strafePerc), VF_FLOAT},
00469
00470
00471 {"bankingSpeed", VFOFS(bankingSpeed), VF_FLOAT},
00472 {"pitchLimit", VFOFS(pitchLimit), VF_FLOAT},
00473 {"rollLimit", VFOFS(rollLimit), VF_FLOAT},
00474 {"braking", VFOFS(braking), VF_FLOAT},
00475 {"mouseYaw", VFOFS(mouseYaw), VF_FLOAT},
00476 {"mousePitch", VFOFS(mousePitch), VF_FLOAT},
00477 {"turningSpeed", VFOFS(turningSpeed), VF_FLOAT},
00478 {"turnWhenStopped", VFOFS(turnWhenStopped), VF_BOOL},
00479 {"traction", VFOFS(traction), VF_FLOAT},
00480 {"friction", VFOFS(friction), VF_FLOAT},
00481 {"maxSlope", VFOFS(maxSlope), VF_FLOAT},
00482 {"speedDependantTurning", VFOFS(speedDependantTurning), VF_BOOL},
00483
00484
00485 {"mass", VFOFS(mass), VF_INT},
00486 {"armor", VFOFS(armor), VF_INT},
00487 {"shields", VFOFS(shields), VF_INT},
00488 {"shieldRechargeMS", VFOFS(shieldRechargeMS), VF_INT},
00489 {"toughness", VFOFS(toughness), VF_FLOAT},
00490 {"malfunctionArmorLevel", VFOFS(malfunctionArmorLevel), VF_INT},
00491 {"surfDestruction", VFOFS(surfDestruction), VF_INT},
00492
00493
00494 {"model", VFOFS(model), VF_LSTRING},
00495 {"skin", VFOFS(skin), VF_LSTRING},
00496 {"g2radius", VFOFS(g2radius), VF_INT},
00497 {"riderAnim", VFOFS(riderAnim), VF_ANIM},
00498 {"droidNPC", VFOFS(droidNPC), VF_LSTRING},
00499
00500 #ifdef _JK2MP
00501 {"radarIcon", VFOFS(radarIconHandle), VF_SHADER_NOMIP},
00502 {"dmgIndicFrame", VFOFS(dmgIndicFrameHandle), VF_SHADER_NOMIP},
00503 {"dmgIndicShield", VFOFS(dmgIndicShieldHandle), VF_SHADER_NOMIP},
00504 {"dmgIndicBackground", VFOFS(dmgIndicBackgroundHandle), VF_SHADER_NOMIP},
00505 {"icon_front", VFOFS(iconFrontHandle), VF_SHADER_NOMIP},
00506 {"icon_back", VFOFS(iconBackHandle), VF_SHADER_NOMIP},
00507 {"icon_right", VFOFS(iconRightHandle), VF_SHADER_NOMIP},
00508 {"icon_left", VFOFS(iconLeftHandle), VF_SHADER_NOMIP},
00509 {"crosshairShader", VFOFS(crosshairShaderHandle), VF_SHADER_NOMIP},
00510 {"shieldShader", VFOFS(shieldShaderHandle), VF_SHADER},
00511
00512
00513 {"health_front", VFOFS(health_front), VF_INT},
00514 {"health_back", VFOFS(health_back), VF_INT},
00515 {"health_right", VFOFS(health_right), VF_INT},
00516 {"health_left", VFOFS(health_left), VF_INT},
00517 #else
00518 {"radarIcon", 0, VF_IGNORE},
00519 #endif
00520
00521 {"soundOn", VFOFS(soundOn), VF_SOUND},
00522 {"soundOff", VFOFS(soundOff), VF_SOUND},
00523 {"soundLoop", VFOFS(soundLoop), VF_SOUND},
00524 {"soundTakeOff", VFOFS(soundTakeOff), VF_SOUND},
00525 {"soundEngineStart",VFOFS(soundEngineStart),VF_SOUND_CLIENT},
00526 {"soundSpin", VFOFS(soundSpin), VF_SOUND},
00527 {"soundTurbo", VFOFS(soundTurbo), VF_SOUND},
00528 {"soundHyper", VFOFS(soundHyper), VF_SOUND_CLIENT},
00529 {"soundLand", VFOFS(soundLand), VF_SOUND},
00530 {"soundFlyBy", VFOFS(soundFlyBy), VF_SOUND_CLIENT},
00531 {"soundFlyBy2", VFOFS(soundFlyBy2), VF_SOUND_CLIENT},
00532 {"soundShift1", VFOFS(soundShift1), VF_SOUND},
00533 {"soundShift2", VFOFS(soundShift2), VF_SOUND},
00534 {"soundShift3", VFOFS(soundShift3), VF_SOUND},
00535 {"soundShift4", VFOFS(soundShift4), VF_SOUND},
00536
00537 {"exhaustFX", VFOFS(iExhaustFX), VF_EFFECT_CLIENT},
00538 {"turboFX", VFOFS(iTurboFX), VF_EFFECT_CLIENT},
00539 {"turboStartFX", VFOFS(iTurboStartFX), VF_EFFECT},
00540 {"trailFX", VFOFS(iTrailFX), VF_EFFECT_CLIENT},
00541 {"impactFX", VFOFS(iImpactFX), VF_EFFECT_CLIENT},
00542 {"explodeFX", VFOFS(iExplodeFX), VF_EFFECT},
00543 {"wakeFX", VFOFS(iWakeFX), VF_EFFECT_CLIENT},
00544 {"dmgFX", VFOFS(iDmgFX), VF_EFFECT_CLIENT},
00545 #ifdef _JK2MP
00546 {"injureFX", VFOFS(iInjureFX), VF_EFFECT_CLIENT},
00547 {"noseFX", VFOFS(iNoseFX), VF_EFFECT_CLIENT},
00548 {"lwingFX", VFOFS(iLWingFX), VF_EFFECT_CLIENT},
00549 {"rwingFX", VFOFS(iRWingFX), VF_EFFECT_CLIENT},
00550 #else
00551 {"armorLowFX", VFOFS(iArmorLowFX), VF_EFFECT_CLIENT},
00552 {"armorGoneFX", VFOFS(iArmorGoneFX), VF_EFFECT_CLIENT},
00553 #endif
00554
00555
00556 {"weap1", VFOFS(weapon[0].ID), VF_WEAPON},
00557 {"weap2", VFOFS(weapon[1].ID), VF_WEAPON},
00558
00559 {"weap1Delay", VFOFS(weapon[0].delay), VF_INT},
00560 {"weap2Delay", VFOFS(weapon[1].delay), VF_INT},
00561
00562 {"weap1Link", VFOFS(weapon[0].linkable), VF_INT},
00563 {"weap2Link", VFOFS(weapon[1].linkable), VF_INT},
00564
00565 {"weap1Aim", VFOFS(weapon[0].aimCorrect), VF_BOOL},
00566 {"weap2Aim", VFOFS(weapon[1].aimCorrect), VF_BOOL},
00567
00568 {"weap1AmmoMax", VFOFS(weapon[0].ammoMax), VF_INT},
00569 {"weap2AmmoMax", VFOFS(weapon[1].ammoMax), VF_INT},
00570
00571 {"weap1AmmoRechargeMS", VFOFS(weapon[0].ammoRechargeMS), VF_INT},
00572 {"weap2AmmoRechargeMS", VFOFS(weapon[1].ammoRechargeMS), VF_INT},
00573
00574 {"weap1SoundNoAmmo", VFOFS(weapon[0].soundNoAmmo), VF_SOUND_CLIENT},
00575 {"weap2SoundNoAmmo", VFOFS(weapon[1].soundNoAmmo), VF_SOUND_CLIENT},
00576
00577
00578 {"weapMuzzle1", VFOFS(weapMuzzle[0]), VF_WEAPON},
00579 {"weapMuzzle2", VFOFS(weapMuzzle[1]), VF_WEAPON},
00580 {"weapMuzzle3", VFOFS(weapMuzzle[2]), VF_WEAPON},
00581 {"weapMuzzle4", VFOFS(weapMuzzle[3]), VF_WEAPON},
00582 {"weapMuzzle5", VFOFS(weapMuzzle[4]), VF_WEAPON},
00583 {"weapMuzzle6", VFOFS(weapMuzzle[5]), VF_WEAPON},
00584 {"weapMuzzle7", VFOFS(weapMuzzle[6]), VF_WEAPON},
00585 {"weapMuzzle8", VFOFS(weapMuzzle[7]), VF_WEAPON},
00586 {"weapMuzzle9", VFOFS(weapMuzzle[8]), VF_WEAPON},
00587 {"weapMuzzle10", VFOFS(weapMuzzle[9]), VF_WEAPON},
00588
00589
00590 {"landingHeight", VFOFS(landingHeight), VF_FLOAT},
00591
00592
00593 {"gravity", VFOFS(gravity), VF_INT},
00594 {"hoverHeight", VFOFS(hoverHeight), VF_FLOAT},
00595 {"hoverStrength", VFOFS(hoverStrength), VF_FLOAT},
00596 {"waterProof", VFOFS(waterProof), VF_BOOL},
00597 {"bouyancy", VFOFS(bouyancy), VF_FLOAT},
00598 {"fuelMax", VFOFS(fuelMax), VF_INT},
00599 {"fuelRate", VFOFS(fuelRate), VF_INT},
00600 {"turboDuration", VFOFS(turboDuration), VF_INT},
00601 {"turboRecharge", VFOFS(turboRecharge), VF_INT},
00602 {"visibility", VFOFS(visibility), VF_INT},
00603 {"loudness", VFOFS(loudness), VF_INT},
00604 {"explosionRadius", VFOFS(explosionRadius), VF_FLOAT},
00605 {"explosionDamage", VFOFS(explosionDamage), VF_INT},
00606
00607
00608 {"maxPassengers", VFOFS(maxPassengers), VF_INT},
00609 {"hideRider", VFOFS(hideRider), VF_BOOL},
00610 {"killRiderOnDeath", VFOFS(killRiderOnDeath), VF_BOOL},
00611 {"flammable", VFOFS(flammable), VF_BOOL},
00612 {"explosionDelay", VFOFS(explosionDelay), VF_INT},
00613
00614 {"cameraOverride", VFOFS(cameraOverride), VF_BOOL},
00615 {"cameraRange", VFOFS(cameraRange), VF_FLOAT},
00616 {"cameraVertOffset", VFOFS(cameraVertOffset), VF_FLOAT},
00617 {"cameraHorzOffset", VFOFS(cameraHorzOffset), VF_FLOAT},
00618 {"cameraPitchOffset", VFOFS(cameraPitchOffset), VF_FLOAT},
00619 {"cameraFOV", VFOFS(cameraFOV), VF_FLOAT},
00620 {"cameraAlpha", VFOFS(cameraAlpha), VF_FLOAT},
00621 {"cameraPitchDependantVertOffset", VFOFS(cameraPitchDependantVertOffset), VF_BOOL},
00622
00623
00624 {"turret1Weap", VFOFS(turret[0].iWeapon), VF_WEAPON},
00625 {"turret1Delay", VFOFS(turret[0].iDelay), VF_INT},
00626 {"turret1AmmoMax", VFOFS(turret[0].iAmmoMax), VF_INT},
00627 {"turret1AmmoRechargeMS", VFOFS(turret[0].iAmmoRechargeMS), VF_INT},
00628 {"turret1YawBone", VFOFS(turret[0].yawBone), VF_LSTRING},
00629 {"turret1PitchBone", VFOFS(turret[0].pitchBone), VF_LSTRING},
00630 {"turret1YawAxis", VFOFS(turret[0].yawAxis), VF_INT},
00631 {"turret1PitchAxis", VFOFS(turret[0].pitchAxis), VF_INT},
00632 {"turret1ClampYawL", VFOFS(turret[0].yawClampLeft), VF_FLOAT},
00633 {"turret1ClampYawR", VFOFS(turret[0].yawClampRight), VF_FLOAT},
00634 {"turret1ClampPitchU", VFOFS(turret[0].pitchClampUp), VF_FLOAT},
00635 {"turret1ClampPitchD", VFOFS(turret[0].pitchClampDown), VF_FLOAT},
00636 {"turret1Muzzle1", VFOFS(turret[0].iMuzzle[0]), VF_INT},
00637 {"turret1Muzzle2", VFOFS(turret[0].iMuzzle[1]), VF_INT},
00638 {"turret1TurnSpeed", VFOFS(turret[0].fTurnSpeed), VF_FLOAT},
00639 {"turret1AI", VFOFS(turret[0].bAI), VF_BOOL},
00640 {"turret1AILead", VFOFS(turret[0].bAILead), VF_BOOL},
00641 {"turret1AIRange", VFOFS(turret[0].fAIRange), VF_FLOAT},
00642 {"turret1PassengerNum", VFOFS(turret[0].passengerNum), VF_INT},
00643 {"turret1GunnerViewTag", VFOFS(turret[0].gunnerViewTag), VF_LSTRING},
00644
00645
00646 {"turret2Weap", VFOFS(turret[1].iWeapon), VF_WEAPON},
00647 {"turret2Delay", VFOFS(turret[1].iDelay), VF_INT},
00648 {"turret2AmmoMax", VFOFS(turret[1].iAmmoMax), VF_INT},
00649 {"turret2AmmoRechargeMS", VFOFS(turret[1].iAmmoRechargeMS), VF_INT},
00650 {"turret2YawBone", VFOFS(turret[1].yawBone), VF_LSTRING},
00651 {"turret2PitchBone", VFOFS(turret[1].pitchBone), VF_LSTRING},
00652 {"turret2YawAxis", VFOFS(turret[1].yawAxis), VF_INT},
00653 {"turret2PitchAxis", VFOFS(turret[1].pitchAxis), VF_INT},
00654 {"turret2ClampYawL", VFOFS(turret[1].yawClampLeft), VF_FLOAT},
00655 {"turret2ClampYawR", VFOFS(turret[1].yawClampRight), VF_FLOAT},
00656 {"turret2ClampPitchU", VFOFS(turret[1].pitchClampUp), VF_FLOAT},
00657 {"turret2ClampPitchD", VFOFS(turret[1].pitchClampDown), VF_FLOAT},
00658 {"turret2Muzzle1", VFOFS(turret[1].iMuzzle[0]), VF_INT},
00659 {"turret2Muzzle2", VFOFS(turret[1].iMuzzle[1]), VF_INT},
00660 {"turret2TurnSpeed", VFOFS(turret[1].fTurnSpeed), VF_FLOAT},
00661 {"turret2AI", VFOFS(turret[1].bAI), VF_BOOL},
00662 {"turret2AILead", VFOFS(turret[1].bAILead), VF_BOOL},
00663 {"turret2AIRange", VFOFS(turret[1].fAIRange), VF_FLOAT},
00664 {"turret2PassengerNum", VFOFS(turret[1].passengerNum), VF_INT},
00665 {"turret2GunnerViewTag", VFOFS(turret[1].gunnerViewTag), VF_LSTRING},
00666
00667
00668 {0, -1, VF_INT}
00669 };
00670
00671 stringID_table_t VehicleTable[VH_NUM_VEHICLES+1] =
00672 {
00673 ENUM2STRING(VH_NONE),
00674 ENUM2STRING(VH_WALKER),
00675 ENUM2STRING(VH_FIGHTER),
00676 ENUM2STRING(VH_SPEEDER),
00677 ENUM2STRING(VH_ANIMAL),
00678 ENUM2STRING(VH_FLIER),
00679 0, -1
00680 };
00681
00682
00683 void BG_SetSharedVehicleFunctions( vehicleInfo_t *pVehInfo )
00684 {
00685 #ifdef QAGAME
00686
00687 G_SetSharedVehicleFunctions(pVehInfo);
00688 #endif
00689
00690 #ifndef WE_ARE_IN_THE_UI
00691 switch( pVehInfo->type )
00692 {
00693 case VH_SPEEDER:
00694 G_SetSpeederVehicleFunctions( pVehInfo );
00695 break;
00696 case VH_ANIMAL:
00697 G_SetAnimalVehicleFunctions( pVehInfo );
00698 break;
00699 case VH_FIGHTER:
00700 G_SetFighterVehicleFunctions( pVehInfo );
00701 break;
00702 case VH_WALKER:
00703 G_SetWalkerVehicleFunctions( pVehInfo );
00704 break;
00705 }
00706 #endif
00707 }
00708
00709 void BG_VehicleSetDefaults( vehicleInfo_t *vehicle )
00710 {
00711 memset(vehicle, 0, sizeof(vehicleInfo_t));
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810 }
00811
00812 void BG_VehicleClampData( vehicleInfo_t *vehicle )
00813 {
00814 int i;
00815
00816 for ( i = 0; i < 3; i++ )
00817 {
00818 if ( vehicle->centerOfGravity[i] > 1.0f )
00819 {
00820 vehicle->centerOfGravity[i] = 1.0f;
00821 }
00822 else if ( vehicle->centerOfGravity[i] < -1.0f )
00823 {
00824 vehicle->centerOfGravity[i] = -1.0f;
00825 }
00826 }
00827
00828
00829 if ( vehicle->maxPassengers > VEH_MAX_PASSENGERS )
00830 {
00831 vehicle->maxPassengers = VEH_MAX_PASSENGERS;
00832 }
00833 else if ( vehicle->maxPassengers < 0 )
00834 {
00835 vehicle->maxPassengers = 0;
00836 }
00837 }
00838
00839 static qboolean BG_ParseVehicleParm( vehicleInfo_t *vehicle, char *parmName, char *pValue )
00840 {
00841 int i;
00842 vec3_t vec;
00843 byte *b = (byte *)vehicle;
00844 int _iFieldsRead = 0;
00845 vehicleType_t vehType;
00846 char value[1024];
00847
00848 Q_strncpyz( value, pValue, sizeof(value) );
00849
00850
00851 for ( i = 0; vehicleFields[i].ofs != -1; i++ )
00852 {
00853 if ( !Q_stricmp( vehicleFields[i].name, parmName ) )
00854 {
00855
00856 switch( vehicleFields[i].type )
00857 {
00858 case VF_IGNORE:
00859 break;
00860 case VF_INT:
00861 *(int *)(b+vehicleFields[i].ofs) = atoi(value);
00862 break;
00863 case VF_FLOAT:
00864 *(float *)(b+vehicleFields[i].ofs) = atof(value);
00865 break;
00866 case VF_LSTRING:
00867 if (!*(char **)(b+vehicleFields[i].ofs))
00868 {
00869 #ifdef _JK2MP
00870 *(char **)(b+vehicleFields[i].ofs) = (char *)BG_Alloc(128);
00871 strcpy(*(char **)(b+vehicleFields[i].ofs), value);
00872 #else
00873 (*(char **)(b+vehicleFields[i].ofs)) = G_NewString( value );
00874 #endif
00875 }
00876
00877 break;
00878 case VF_VECTOR:
00879 _iFieldsRead = sscanf (value, "%f %f %f", &vec[0], &vec[1], &vec[2]);
00880 assert(_iFieldsRead==3 );
00881 if (_iFieldsRead!=3)
00882 {
00883 Com_Printf (S_COLOR_YELLOW"BG_ParseVehicleParm: VEC3 sscanf() failed to read 3 floats ('angle' key bug?)\n");
00884 }
00885 ((float *)(b+vehWeaponFields[i].ofs))[0] = vec[0];
00886 ((float *)(b+vehWeaponFields[i].ofs))[1] = vec[1];
00887 ((float *)(b+vehWeaponFields[i].ofs))[2] = vec[2];
00888 break;
00889 case VF_BOOL:
00890 *(qboolean *)(b+vehicleFields[i].ofs) = (qboolean)(atof(value)!=0);
00891 break;
00892 case VF_VEHTYPE:
00893 vehType = (vehicleType_t)GetIDForString( VehicleTable, value );
00894 *(vehicleType_t *)(b+vehicleFields[i].ofs) = vehType;
00895 break;
00896 case VF_ANIM:
00897 {
00898 int anim = GetIDForString( animTable, value );
00899 *(int *)(b+vehicleFields[i].ofs) = anim;
00900 }
00901 break;
00902 case VF_WEAPON:
00903 *(int *)(b+vehicleFields[i].ofs) = VEH_VehWeaponIndexForName( value );
00904 break;
00905 case VF_MODEL:
00906 #ifdef QAGAME
00907 *(int *)(b+vehicleFields[i].ofs) = G_ModelIndex( value );
00908 #else
00909 *(int *)(b+vehicleFields[i].ofs) = trap_R_RegisterModel( value );
00910 #endif
00911 break;
00912 case VF_MODEL_CLIENT:
00913 #ifndef _JK2MP
00914 *(int *)(b+vehicleFields[i].ofs) = G_ModelIndex( value );
00915 #elif QAGAME
00916
00917 #else
00918 *(int *)(b+vehicleFields[i].ofs) = trap_R_RegisterModel( value );
00919 #endif
00920 break;
00921 case VF_EFFECT:
00922 #ifdef QAGAME
00923 *(int *)(b+vehicleFields[i].ofs) = G_EffectIndex( value );
00924 #elif CGAME
00925 *(int *)(b+vehicleFields[i].ofs) = trap_FX_RegisterEffect( value );
00926 #endif
00927 break;
00928 case VF_EFFECT_CLIENT:
00929 #ifndef _JK2MP
00930 *(int *)(b+vehicleFields[i].ofs) = G_EffectIndex( value );
00931 #elif QAGAME
00932
00933 #elif CGAME
00934 *(int *)(b+vehicleFields[i].ofs) = trap_FX_RegisterEffect( value );
00935 #endif
00936 break;
00937 case VF_SHADER:
00938 #ifdef WE_ARE_IN_THE_UI
00939 *(int *)(b+vehicleFields[i].ofs) = trap_R_RegisterShaderNoMip( value );
00940 #elif CGAME
00941 *(int *)(b+vehicleFields[i].ofs) = trap_R_RegisterShader( value );
00942 #endif
00943 break;
00944 case VF_SHADER_NOMIP:
00945 #ifndef QAGAME
00946 *(int *)(b+vehicleFields[i].ofs) = trap_R_RegisterShaderNoMip( value );
00947 #endif
00948 break;
00949 case VF_SOUND:
00950 #ifdef QAGAME
00951 *(int *)(b+vehicleFields[i].ofs) = G_SoundIndex( value );
00952 #else
00953 *(int *)(b+vehicleFields[i].ofs) = trap_S_RegisterSound( value );
00954 #endif
00955 break;
00956 case VF_SOUND_CLIENT:
00957 #ifndef _JK2MP
00958 *(int *)(b+vehicleFields[i].ofs) = G_SoundIndex( value );
00959 #elif QAGAME
00960
00961 #else
00962 *(int *)(b+vehicleFields[i].ofs) = trap_S_RegisterSound( value );
00963 #endif
00964 break;
00965 default:
00966
00967 return qfalse;
00968 break;
00969 }
00970 break;
00971 }
00972 }
00973 if ( vehicleFields[i].ofs == -1 )
00974 {
00975 return qfalse;
00976 }
00977 else
00978 {
00979 return qtrue;
00980 }
00981 }
00982
00983 int VEH_LoadVehicle( const char *vehicleName )
00984 {
00985 const char *token;
00986
00987 char parmName[128] = { 0 };
00988 char weap1[128] = { 0 }, weap2[128] = { 0 };
00989 char weapMuzzle1[128] = { 0 };
00990 char weapMuzzle2[128] = { 0 };
00991 char weapMuzzle3[128] = { 0 };
00992 char weapMuzzle4[128] = { 0 };
00993 char weapMuzzle5[128] = { 0 };
00994 char weapMuzzle6[128] = { 0 };
00995 char weapMuzzle7[128] = { 0 };
00996 char weapMuzzle8[128] = { 0 };
00997 char weapMuzzle9[128] = { 0 };
00998 char weapMuzzle10[128] = { 0 };
00999 char *value = NULL;
01000 const char *p = NULL;
01001 vehicleInfo_t *vehicle = NULL;
01002
01003
01004 if ( numVehicles == 0 )
01005 {
01006 BG_VehicleLoadParms();
01007 }
01008
01009
01010 p = VehicleParms;
01011
01012 #ifdef _JK2MP
01013 COM_BeginParseSession("vehicles");
01014 #else
01015 COM_BeginParseSession();
01016 #endif
01017
01018 vehicle = &g_vehicleInfo[numVehicles];
01019
01020 while ( p )
01021 {
01022 token = COM_ParseExt( &p, qtrue );
01023 if ( token[0] == 0 )
01024 {
01025 return VEHICLE_NONE;
01026 }
01027
01028 if ( !Q_stricmp( token, vehicleName ) )
01029 {
01030 break;
01031 }
01032
01033 SkipBracedSection( &p );
01034 }
01035
01036 if ( !p )
01037 {
01038 return VEHICLE_NONE;
01039 }
01040
01041 token = COM_ParseExt( &p, qtrue );
01042 if ( token[0] == 0 )
01043 {
01044 return VEHICLE_NONE;
01045 }
01046
01047 if ( Q_stricmp( token, "{" ) != 0 )
01048 {
01049 return VEHICLE_NONE;
01050 }
01051
01052 BG_VehicleSetDefaults( vehicle );
01053
01054 while ( 1 )
01055 {
01056 SkipRestOfLine( &p );
01057 token = COM_ParseExt( &p, qtrue );
01058 if ( !token[0] )
01059 {
01060 Com_Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing Vehicle '%s'\n", vehicleName );
01061 return VEHICLE_NONE;
01062 }
01063
01064 if ( !Q_stricmp( token, "}" ) )
01065 {
01066 break;
01067 }
01068 Q_strncpyz( parmName, token, sizeof(parmName) );
01069 value = COM_ParseExt( &p, qtrue );
01070 if ( !value || !value[0] )
01071 {
01072 Com_Printf( S_COLOR_RED"ERROR: Vehicle token '%s' has no value!\n", parmName );
01073 }
01074 else if ( Q_stricmp( "weap1", parmName ) == 0 )
01075 {
01076 Q_strncpyz( weap1, value, sizeof(weap1) );
01077 }
01078 else if ( Q_stricmp( "weap2", parmName ) == 0 )
01079 {
01080 Q_strncpyz( weap2, value, sizeof(weap2) );
01081 }
01082 else if ( Q_stricmp( "weapMuzzle1", parmName ) == 0 )
01083 {
01084 Q_strncpyz( weapMuzzle1, value, sizeof(weapMuzzle1) );
01085 }
01086 else if ( Q_stricmp( "weapMuzzle2", parmName ) == 0 )
01087 {
01088 Q_strncpyz( weapMuzzle2, value, sizeof(weapMuzzle2) );
01089 }
01090 else if ( Q_stricmp( "weapMuzzle3", parmName ) == 0 )
01091 {
01092 Q_strncpyz( weapMuzzle3, value, sizeof(weapMuzzle3) );
01093 }
01094 else if ( Q_stricmp( "weapMuzzle4", parmName ) == 0 )
01095 {
01096 Q_strncpyz( weapMuzzle4, value, sizeof(weapMuzzle4) );
01097 }
01098 else if ( Q_stricmp( "weapMuzzle5", parmName ) == 0 )
01099 {
01100 Q_strncpyz( weapMuzzle5, value, sizeof(weapMuzzle5) );
01101 }
01102 else if ( Q_stricmp( "weapMuzzle6", parmName ) == 0 )
01103 {
01104 Q_strncpyz( weapMuzzle6, value, sizeof(weapMuzzle6) );
01105 }
01106 else if ( Q_stricmp( "weapMuzzle7", parmName ) == 0 )
01107 {
01108 Q_strncpyz( weapMuzzle7, value, sizeof(weapMuzzle7) );
01109 }
01110 else if ( Q_stricmp( "weapMuzzle8", parmName ) == 0 )
01111 {
01112 Q_strncpyz( weapMuzzle8, value, sizeof(weapMuzzle8) );
01113 }
01114 else if ( Q_stricmp( "weapMuzzle9", parmName ) == 0 )
01115 {
01116 Q_strncpyz( weapMuzzle9, value, sizeof(weapMuzzle9) );
01117 }
01118 else if ( Q_stricmp( "weapMuzzle10", parmName ) == 0 )
01119 {
01120 Q_strncpyz( weapMuzzle10, value, sizeof(weapMuzzle10) );
01121 }
01122 else
01123 {
01124 if ( !BG_ParseVehicleParm( vehicle, parmName, value ) )
01125 {
01126 #ifndef FINAL_BUILD
01127 Com_Printf( S_COLOR_RED"ERROR: Unknown Vehicle key/value pair '%s', '%s'!\n", parmName, value );
01128 #endif
01129 }
01130 }
01131 }
01132
01133 if ( weap1[0] )
01134 {
01135 if ( !BG_ParseVehicleParm( vehicle, "weap1", weap1 ) )
01136 {
01137 #ifndef FINAL_BUILD
01138 Com_Printf( S_COLOR_RED"ERROR: Unknown Vehicle key/value pair 'weap1', '%s'!\n", weap1 );
01139 #endif
01140 }
01141 }
01142 if ( weap2[0] )
01143 {
01144 if ( !BG_ParseVehicleParm( vehicle, "weap2", weap2 ) )
01145 {
01146 #ifndef FINAL_BUILD
01147 Com_Printf( S_COLOR_RED"ERROR: Unknown Vehicle key/value pair 'weap2', '%s'!\n", weap2 );
01148 #endif
01149 }
01150 }
01151 if ( weapMuzzle1[0] )
01152 {
01153 if ( !BG_ParseVehicleParm( vehicle, "weapMuzzle1", weapMuzzle1 ) )
01154 {
01155 #ifndef FINAL_BUILD
01156 Com_Printf( S_COLOR_RED"ERROR: Unknown Vehicle key/value pair 'weapMuzzle1', '%s'!\n", weapMuzzle1 );
01157 #endif
01158 }
01159 }
01160 if ( weapMuzzle2[0] )
01161 {
01162 if ( !BG_ParseVehicleParm( vehicle, "weapMuzzle2", weapMuzzle2 ) )
01163 {
01164 #ifndef FINAL_BUILD
01165 Com_Printf( S_COLOR_RED"ERROR: Unknown Vehicle key/value pair 'weapMuzzle2', '%s'!\n", weapMuzzle2 );
01166 #endif
01167 }
01168 }
01169 if ( weapMuzzle3[0] )
01170 {
01171 if ( !BG_ParseVehicleParm( vehicle, "weapMuzzle3", weapMuzzle3 ) )
01172 {
01173 #ifndef FINAL_BUILD
01174 Com_Printf( S_COLOR_RED"ERROR: Unknown Vehicle key/value pair 'weapMuzzle3', '%s'!\n", weapMuzzle3 );
01175 #endif
01176 }
01177 }
01178 if ( weapMuzzle4[0] )
01179 {
01180 if ( !BG_ParseVehicleParm( vehicle, "weapMuzzle4", weapMuzzle4 ) )
01181 {
01182 #ifndef FINAL_BUILD
01183 Com_Printf( S_COLOR_RED"ERROR: Unknown Vehicle key/value pair 'weapMuzzle4', '%s'!\n", weapMuzzle4 );
01184 #endif
01185 }
01186 }
01187 if ( weapMuzzle5[0] )
01188 {
01189 if ( !BG_ParseVehicleParm( vehicle, "weapMuzzle5", weapMuzzle5 ) )
01190 {
01191 #ifndef FINAL_BUILD
01192 Com_Printf( S_COLOR_RED"ERROR: Unknown Vehicle key/value pair 'weapMuzzle5', '%s'!\n", weapMuzzle5 );
01193 #endif
01194 }
01195 }
01196 if ( weapMuzzle6[0] )
01197 {
01198 if ( !BG_ParseVehicleParm( vehicle, "weapMuzzle6", weapMuzzle6 ) )
01199 {
01200 #ifndef FINAL_BUILD
01201 Com_Printf( S_COLOR_RED"ERROR: Unknown Vehicle key/value pair 'weapMuzzle6', '%s'!\n", weapMuzzle6 );
01202 #endif
01203 }
01204 }
01205 if ( weapMuzzle7[0] )
01206 {
01207 if ( !BG_ParseVehicleParm( vehicle, "weapMuzzle7", weapMuzzle7 ) )
01208 {
01209 #ifndef FINAL_BUILD
01210 Com_Printf( S_COLOR_RED"ERROR: Unknown Vehicle key/value pair 'weapMuzzle7', '%s'!\n", weapMuzzle7 );
01211 #endif
01212 }
01213 }
01214 if ( weapMuzzle8[0] )
01215 {
01216 if ( !BG_ParseVehicleParm( vehicle, "weapMuzzle8", weapMuzzle8 ) )
01217 {
01218 #ifndef FINAL_BUILD
01219 Com_Printf( S_COLOR_RED"ERROR: Unknown Vehicle key/value pair 'weapMuzzle8', '%s'!\n", weapMuzzle8 );
01220 #endif
01221 }
01222 }
01223 if ( weapMuzzle9[0] )
01224 {
01225 if ( !BG_ParseVehicleParm( vehicle, "weapMuzzle9", weapMuzzle9 ) )
01226 {
01227 #ifndef FINAL_BUILD
01228 Com_Printf( S_COLOR_RED"ERROR: Unknown Vehicle key/value pair 'weapMuzzle9', '%s'!\n", weapMuzzle9 );
01229 #endif
01230 }
01231 }
01232 if ( weapMuzzle10[0] )
01233 {
01234 if ( !BG_ParseVehicleParm( vehicle, "weapMuzzle10", weapMuzzle10 ) )
01235 {
01236 #ifndef FINAL_BUILD
01237 Com_Printf( S_COLOR_RED"ERROR: Unknown Vehicle key/value pair 'weapMuzzle10', '%s'!\n", weapMuzzle10 );
01238 #endif
01239 }
01240 }
01241
01242 #ifdef _JK2MP
01243
01244 if (!vehicle->health_front)
01245 {
01246 vehicle->health_front = vehicle->armor/4;
01247 }
01248 if (!vehicle->health_back)
01249 {
01250 vehicle->health_back = vehicle->armor/4;
01251 }
01252 if (!vehicle->health_right)
01253 {
01254 vehicle->health_right = vehicle->armor/4;
01255 }
01256 if (!vehicle->health_left)
01257 {
01258 vehicle->health_left = vehicle->armor/4;
01259 }
01260 #endif
01261
01262 if ( vehicle->model )
01263 {
01264 #ifdef QAGAME
01265 vehicle->modelIndex = G_ModelIndex( va( "models/players/%s/model.glm", vehicle->model ) );
01266 #else
01267 vehicle->modelIndex = trap_R_RegisterModel( va( "models/players/%s/model.glm", vehicle->model ) );
01268 #endif
01269 }
01270
01271 #ifndef _JK2MP
01272
01273 if ( vehicle->skin
01274 && vehicle->skin[0] )
01275 {
01276 ratl::string_vs<256> skins(vehicle->skin);
01277 for (ratl::string_vs<256>::tokenizer i = skins.begin("|"); i!=skins.end(); i++)
01278 {
01279
01280 gi.RE_RegisterSkin( va( "models/players/%s/model_%s.skin", vehicle->model, *i) );
01281
01282 G_SkinIndex( va( "models/players/%s/model_%s.skin", vehicle->model, *i) );
01283 }
01284 }
01285 else
01286 {
01287
01288 gi.RE_RegisterSkin( va( "models/players/%s/model_default.skin", vehicle->model) );
01289
01290 G_SkinIndex( va( "models/players/%s/model_default.skin", vehicle->model) );
01291 }
01292 #else
01293 #ifndef QAGAME
01294 if ( vehicle->skin
01295 && vehicle->skin[0] )
01296 {
01297 trap_R_RegisterSkin( va( "models/players/%s/model_%s.skin", vehicle->model, vehicle->skin) );
01298 }
01299 #endif
01300 #endif
01301
01302 BG_VehicleClampData( vehicle );
01303
01304 BG_SetSharedVehicleFunctions( vehicle );
01305
01306 if ( vehicle->explosionDamage )
01307 {
01308 #ifdef QAGAME
01309 G_EffectIndex( "ships/ship_explosion_mark" );
01310 #elif CGAME
01311 trap_FX_RegisterEffect( "ships/ship_explosion_mark" );
01312 #endif
01313 }
01314 if ( vehicle->flammable )
01315 {
01316 #ifdef QAGAME
01317 G_SoundIndex( "sound/vehicles/common/fire_lp.wav" );
01318 #elif CGAME
01319 trap_S_RegisterSound( "sound/vehicles/common/fire_lp.wav" );
01320 #else
01321 trap_S_RegisterSound( "sound/vehicles/common/fire_lp.wav" );
01322 #endif
01323 }
01324
01325 if ( vehicle->hoverHeight > 0 )
01326 {
01327 #ifndef _JK2MP
01328 G_EffectIndex( "ships/swoop_dust" );
01329 #elif QAGAME
01330 G_EffectIndex( "ships/swoop_dust" );
01331 #elif CGAME
01332 trap_FX_RegisterEffect( "ships/swoop_dust" );
01333 #endif
01334 }
01335
01336 #ifdef QAGAME
01337 G_EffectIndex( "volumetric/black_smoke" );
01338 G_EffectIndex( "ships/fire" );
01339 G_SoundIndex( "sound/vehicles/common/release.wav" );
01340 #elif CGAME
01341 trap_R_RegisterShader( "gfx/menus/radar/bracket" );
01342 trap_R_RegisterShader( "gfx/menus/radar/lead" );
01343 trap_R_RegisterShaderNoMip( "gfx/menus/radar/asteroid" );
01344 trap_S_RegisterSound( "sound/vehicles/common/impactalarm.wav" );
01345 trap_S_RegisterSound( "sound/vehicles/common/linkweaps.wav" );
01346 trap_S_RegisterSound( "sound/vehicles/common/release.wav" );
01347 trap_FX_RegisterEffect("effects/ships/dest_burning.efx");
01348 trap_FX_RegisterEffect("effects/ships/dest_destroyed.efx");
01349 trap_FX_RegisterEffect( "volumetric/black_smoke" );
01350 trap_FX_RegisterEffect( "ships/fire" );
01351 trap_FX_RegisterEffect("ships/hyperspace_stars");
01352
01353 if ( vehicle->hideRider )
01354 {
01355 trap_R_RegisterShaderNoMip( "gfx/menus/radar/circle_base" );
01356 trap_R_RegisterShaderNoMip( "gfx/menus/radar/circle_base_frame" );
01357 trap_R_RegisterShaderNoMip( "gfx/menus/radar/circle_base_shield" );
01358 }
01359 #endif
01360
01361 return (numVehicles++);
01362 }
01363
01364 int VEH_VehicleIndexForName( const char *vehicleName )
01365 {
01366 int v;
01367 if ( !vehicleName || !vehicleName[0] )
01368 {
01369 Com_Printf( S_COLOR_RED"ERROR: Trying to read Vehicle with no name!\n" );
01370 return VEHICLE_NONE;
01371 }
01372 for ( v = VEHICLE_BASE; v < numVehicles; v++ )
01373 {
01374 if ( g_vehicleInfo[v].name
01375 && Q_stricmp( g_vehicleInfo[v].name, vehicleName ) == 0 )
01376 {
01377 return v;
01378 }
01379 }
01380
01381 if ( v >= MAX_VEHICLES )
01382 {
01383 Com_Printf( S_COLOR_RED"ERROR: Too many Vehicles (max 64), aborting load on %s!\n", vehicleName );
01384 return VEHICLE_NONE;
01385 }
01386
01387
01388 v = VEH_LoadVehicle( vehicleName );
01389 if ( v == VEHICLE_NONE )
01390 {
01391 Com_Printf( S_COLOR_RED"ERROR: Could not find Vehicle %s!\n", vehicleName );
01392 }
01393 return v;
01394 }
01395
01396 void BG_VehWeaponLoadParms( void )
01397 {
01398 int len, totallen, vehExtFNLen, mainBlockLen, fileCnt, i;
01399 char *holdChar, *marker;
01400 char vehWeaponExtensionListBuf[2048];
01401 fileHandle_t f;
01402 char *tempReadBuffer;
01403
01404 len = 0;
01405
01406
01407 totallen = mainBlockLen = len;
01408 marker = VehWeaponParms+totallen;
01409 *marker = 0;
01410
01411
01412 #ifdef _JK2MP
01413 fileCnt = trap_FS_GetFileList("ext_data/vehicles/weapons", ".vwp", vehWeaponExtensionListBuf, sizeof(vehWeaponExtensionListBuf) );
01414 #else
01415 fileCnt = gi.FS_GetFileList("ext_data/vehicles/weapons", ".vwp", vehWeaponExtensionListBuf, sizeof(vehWeaponExtensionListBuf) );
01416 #endif
01417
01418 holdChar = vehWeaponExtensionListBuf;
01419
01420 #ifdef _JK2MP
01421 tempReadBuffer = (char *)BG_TempAlloc(MAX_VEH_WEAPON_DATA_SIZE);
01422 #else
01423 tempReadBuffer = (char *)gi.Malloc( MAX_VEH_WEAPON_DATA_SIZE, TAG_G_ALLOC, qtrue );
01424 #endif
01425
01426
01427
01428
01429
01430 for ( i = 0; i < fileCnt; i++, holdChar += vehExtFNLen + 1 )
01431 {
01432 vehExtFNLen = strlen( holdChar );
01433
01434
01435
01436 #ifdef _JK2MP
01437 len = trap_FS_FOpenFile(va( "ext_data/vehicles/weapons/%s", holdChar), &f, FS_READ);
01438 #else
01439
01440 len = gi.FS_FOpenFile(va( "ext_data/vehicles/weapons/%s", holdChar), &f, FS_READ);
01441 #endif
01442
01443 if ( len == -1 )
01444 {
01445 Com_Printf( "error reading file\n" );
01446 }
01447 else
01448 {
01449 #ifdef _JK2MP
01450 trap_FS_Read(tempReadBuffer, len, f);
01451 tempReadBuffer[len] = 0;
01452 #else
01453 gi.FS_Read(tempReadBuffer, len, f);
01454 tempReadBuffer[len] = 0;
01455 #endif
01456
01457
01458 if ( totallen && *(marker-1) == '}' )
01459 {
01460 strcat( marker, " " );
01461 totallen++;
01462 marker++;
01463 }
01464
01465 if ( totallen + len >= MAX_VEH_WEAPON_DATA_SIZE ) {
01466 Com_Error(ERR_DROP, "Vehicle Weapon extensions (*.vwp) are too large" );
01467 }
01468 strcat( marker, tempReadBuffer );
01469 #ifdef _JK2MP
01470 trap_FS_FCloseFile( f );
01471 #else
01472 gi.FS_FCloseFile( f );
01473 #endif
01474
01475 totallen += len;
01476 marker = VehWeaponParms+totallen;
01477 }
01478 }
01479
01480 #ifdef _JK2MP
01481 BG_TempFree(MAX_VEH_WEAPON_DATA_SIZE);
01482 #else
01483 gi.Free(tempReadBuffer); tempReadBuffer = NULL;
01484 #endif
01485 }
01486
01487 void BG_VehicleLoadParms( void )
01488 {
01489 int len, totallen, vehExtFNLen, mainBlockLen, fileCnt, i;
01490
01491 char *holdChar, *marker;
01492 char vehExtensionListBuf[2048];
01493 fileHandle_t f;
01494 char *tempReadBuffer;
01495
01496 len = 0;
01497
01498
01499 totallen = mainBlockLen = len;
01500 marker = VehicleParms+totallen;
01501 *marker = 0;
01502
01503
01504 #ifdef _JK2MP
01505 fileCnt = trap_FS_GetFileList("ext_data/vehicles", ".veh", vehExtensionListBuf, sizeof(vehExtensionListBuf) );
01506 #else
01507 fileCnt = gi.FS_GetFileList("ext_data/vehicles", ".veh", vehExtensionListBuf, sizeof(vehExtensionListBuf) );
01508 #endif
01509
01510 holdChar = vehExtensionListBuf;
01511
01512 #ifdef _JK2MP
01513 tempReadBuffer = (char *)BG_TempAlloc(MAX_VEHICLE_DATA_SIZE);
01514 #else
01515 tempReadBuffer = (char *)gi.Malloc( MAX_VEHICLE_DATA_SIZE, TAG_G_ALLOC, qtrue );
01516 #endif
01517
01518
01519
01520
01521
01522 for ( i = 0; i < fileCnt; i++, holdChar += vehExtFNLen + 1 )
01523 {
01524 vehExtFNLen = strlen( holdChar );
01525
01526
01527
01528 #ifdef _JK2MP
01529 len = trap_FS_FOpenFile(va( "ext_data/vehicles/%s", holdChar), &f, FS_READ);
01530 #else
01531
01532 len = gi.FS_FOpenFile(va( "ext_data/vehicles/%s", holdChar), &f, FS_READ);
01533 #endif
01534
01535 if ( len == -1 )
01536 {
01537 Com_Printf( "error reading file\n" );
01538 }
01539 else
01540 {
01541 #ifdef _JK2MP
01542 trap_FS_Read(tempReadBuffer, len, f);
01543 tempReadBuffer[len] = 0;
01544 #else
01545 gi.FS_Read(tempReadBuffer, len, f);
01546 tempReadBuffer[len] = 0;
01547 #endif
01548
01549
01550 if ( totallen && *(marker-1) == '}' )
01551 {
01552 strcat( marker, " " );
01553 totallen++;
01554 marker++;
01555 }
01556
01557 if ( totallen + len >= MAX_VEHICLE_DATA_SIZE ) {
01558 Com_Error(ERR_DROP, "Vehicle extensions (*.veh) are too large" );
01559 }
01560 strcat( marker, tempReadBuffer );
01561 #ifdef _JK2MP
01562 trap_FS_FCloseFile( f );
01563 #else
01564 gi.FS_FCloseFile( f );
01565 #endif
01566
01567 totallen += len;
01568 marker = VehicleParms+totallen;
01569 }
01570 }
01571
01572 #ifdef _JK2MP
01573 BG_TempFree(MAX_VEHICLE_DATA_SIZE);
01574 #else
01575 gi.Free(tempReadBuffer); tempReadBuffer = NULL;
01576 #endif
01577
01578 numVehicles = 1;
01579
01580 BG_VehicleSetDefaults( &g_vehicleInfo[VEHICLE_BASE] );
01581
01582 BG_VehicleClampData( &g_vehicleInfo[VEHICLE_BASE] );
01583
01584 BG_SetSharedVehicleFunctions( &g_vehicleInfo[VEHICLE_BASE] );
01585
01586
01587 BG_VehWeaponLoadParms();
01588 }
01589
01590 int BG_VehicleGetIndex( const char *vehicleName )
01591 {
01592 return (VEH_VehicleIndexForName( vehicleName ));
01593 }
01594
01595
01596
01597
01598
01599 void BG_GetVehicleModelName(char *modelname)
01600 {
01601 char *vehName = &modelname[1];
01602 int vIndex = BG_VehicleGetIndex(vehName);
01603 assert(modelname[0] == '$');
01604
01605 if (vIndex == VEHICLE_NONE)
01606 {
01607 Com_Error(ERR_DROP, "BG_GetVehicleModelName: couldn't find vehicle %s", vehName);
01608 }
01609
01610 strcpy(modelname, g_vehicleInfo[vIndex].model);
01611 }
01612
01613 void BG_GetVehicleSkinName(char *skinname)
01614 {
01615 char *vehName = &skinname[1];
01616 int vIndex = BG_VehicleGetIndex(vehName);
01617 assert(skinname[0] == '$');
01618
01619 if (vIndex == VEHICLE_NONE)
01620 {
01621 Com_Error(ERR_DROP, "BG_GetVehicleSkinName: couldn't find vehicle %s", vehName);
01622 }
01623
01624 if ( !g_vehicleInfo[vIndex].skin
01625 || !g_vehicleInfo[vIndex].skin[0] )
01626 {
01627 skinname[0] = 0;
01628 }
01629 else
01630 {
01631 strcpy(skinname, g_vehicleInfo[vIndex].skin);
01632 }
01633 }
01634
01635 #ifdef _JK2MP
01636 #ifndef WE_ARE_IN_THE_UI
01637
01638
01639 extern int BG_GetTime(void);
01640 extern int trap_G2API_AddBolt(void *ghoul2, int modelIndex, const char *boneName);
01641 extern qboolean trap_G2API_GetBoltMatrix(void *ghoul2, const int modelIndex, const int boltIndex, mdxaBone_t *matrix,
01642 const vec3_t angles, const vec3_t position, const int frameNum, qhandle_t *modelList, vec3_t scale);
01643 void AttachRidersGeneric( Vehicle_t *pVeh )
01644 {
01645
01646 if ( pVeh->m_pPilot )
01647 {
01648 mdxaBone_t boltMatrix;
01649 vec3_t yawOnlyAngles;
01650 bgEntity_t *parent = pVeh->m_pParentEntity;
01651 bgEntity_t *pilot = pVeh->m_pPilot;
01652 int crotchBolt = trap_G2API_AddBolt(parent->ghoul2, 0, "*driver");
01653
01654 assert(parent->playerState);
01655
01656 VectorSet(yawOnlyAngles, 0, parent->playerState->viewangles[YAW], 0);
01657
01658
01659 trap_G2API_GetBoltMatrix( parent->ghoul2, 0, crotchBolt, &boltMatrix,
01660 yawOnlyAngles, parent->playerState->origin,
01661 BG_GetTime(), NULL, parent->modelScale );
01662 BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, pilot->playerState->origin );
01663 }
01664 }
01665 #endif
01666
01667 #include "../namespace_end.h"
01668
01669 #endif // _JK2MP
01670