00001
00002 #include "g_headers.h"
00003
00004
00005
00006
00007 #ifdef _JK2MP
00008
00009 #undef currentAngles
00010 #undef currentOrigin
00011 #undef mins
00012 #undef maxs
00013 #undef legsAnimTimer
00014 #undef torsoAnimTimer
00015 #undef bool
00016 #undef false
00017 #undef true
00018
00019 #undef sqrtf
00020 #undef Q_flrand
00021
00022 #undef MOD_EXPLOSIVE
00023 #endif
00024
00025 #ifdef _JK2 //SP does not have this preprocessor for game like MP does
00026 #ifndef _JK2MP
00027 #define _JK2MP
00028 #endif
00029 #endif
00030
00031 #ifndef _JK2MP //if single player
00032 #ifndef QAGAME //I don't think we have a QAGAME define
00033 #define QAGAME //but define it cause in sp we're always in the game
00034 #endif
00035 #endif
00036
00037 #ifdef QAGAME //including game headers on cgame is FORBIDDEN ^_^
00038 #include "g_local.h"
00039 #elif defined _JK2MP
00040 #include "bg_public.h"
00041 #endif
00042
00043 #ifndef _JK2MP
00044 #include "g_functions.h"
00045 #include "g_vehicles.h"
00046 #else
00047 #include "bg_vehicles.h"
00048 #endif
00049
00050 #ifdef _JK2MP
00051
00052
00053 #define currentAngles r.currentAngles
00054 #define currentOrigin r.currentOrigin
00055 #define mins r.mins
00056 #define maxs r.maxs
00057 #define legsAnimTimer legsTimer
00058 #define torsoAnimTimer torsoTimer
00059 #define bool qboolean
00060 #define false qfalse
00061 #define true qtrue
00062
00063 #define sqrtf sqrt
00064 #define Q_flrand flrand
00065
00066 #define MOD_EXPLOSIVE MOD_SUICIDE
00067 #else
00068 #define bgEntity_t gentity_t
00069 #endif
00070
00071 extern float DotToSpot( vec3_t spot, vec3_t from, vec3_t fromAngles );
00072 #ifdef QAGAME //SP or gameside MP
00073 extern vmCvar_t cg_thirdPersonAlpha;
00074 extern vec3_t playerMins;
00075 extern vec3_t playerMaxs;
00076 extern cvar_t *g_speederControlScheme;
00077 extern void ChangeWeapon( gentity_t *ent, int newWeapon );
00078 extern void PM_SetAnim(pmove_t *pm,int setAnimParts,int anim,int setAnimFlags, int blendTime);
00079 extern int PM_AnimLength( int index, animNumber_t anim );
00080 extern void G_VehicleTrace( trace_t *results, const vec3_t start, const vec3_t tMins, const vec3_t tMaxs, const vec3_t end, int passEntityNum, int contentmask );
00081 #endif
00082
00083 extern qboolean BG_UnrestrainedPitchRoll( playerState_t *ps, Vehicle_t *pVeh );
00084
00085 #ifdef _JK2MP
00086
00087 #include "../namespace_begin.h"
00088
00089 extern void BG_SetAnim(playerState_t *ps, animation_t *animations, int setAnimParts,int anim,int setAnimFlags, int blendTime);
00090 extern int BG_GetTime(void);
00091 #endif
00092
00093 extern void BG_ExternThisSoICanRecompileInDebug( Vehicle_t *pVeh, playerState_t *riderPS );
00094
00095
00096 bool BG_FighterUpdate(Vehicle_t *pVeh, const usercmd_t *pUcmd, vec3_t trMins, vec3_t trMaxs, float gravity,
00097 void (*traceFunc)( trace_t *results, const vec3_t start, const vec3_t lmins, const vec3_t lmaxs, const vec3_t end, int passEntityNum, int contentMask ))
00098 {
00099 vec3_t bottom;
00100 playerState_t *parentPS;
00101 qboolean isDead = qfalse;
00102 #ifdef QAGAME //don't do this on client
00103 int i;
00104
00105
00106 pVeh->m_pVehicleInfo->Ghost( pVeh, pVeh->m_pPilot );
00107 for ( i = 0; i < pVeh->m_pVehicleInfo->maxPassengers; i++ )
00108 {
00109 pVeh->m_pVehicleInfo->Ghost( pVeh, pVeh->m_ppPassengers[i] );
00110 }
00111 #endif
00112
00113
00114 #ifdef _JK2MP
00115 parentPS = pVeh->m_pParentEntity->playerState;
00116 #else
00117 parentPS = &pVeh->m_pParentEntity->client->ps;
00118 #endif
00119
00120 if (!parentPS)
00121 {
00122 Com_Error(ERR_DROP, "NULL PS in BG_FighterUpdate (%s)", pVeh->m_pVehicleInfo->name);
00123 return false;
00124 }
00125
00126
00127 if ( pVeh->m_pPilot )
00128 {
00129 parentPS->gravity = 0;
00130 #ifndef _JK2MP //don't need this flag in mp, I.. guess
00131 pVeh->m_pParentEntity->svFlags |= SVF_CUSTOM_GRAVITY;
00132 #endif
00133 }
00134 else
00135 {
00136 #ifndef _JK2MP //don't need this flag in mp, I.. guess
00137 pVeh->m_pParentEntity->svFlags &= ~SVF_CUSTOM_GRAVITY;
00138 #else //in MP set grav back to normal gravity
00139 if (pVeh->m_pVehicleInfo->gravity)
00140 {
00141 parentPS->gravity = pVeh->m_pVehicleInfo->gravity;
00142 }
00143 else
00144 {
00145 parentPS->gravity = gravity;
00146 }
00147 #endif
00148 }
00149
00150 #ifdef _JK2MP
00151 isDead = (qboolean)((parentPS->eFlags&EF_DEAD)!=0);
00152 #else
00153 isDead = (parentPS->stats[STAT_HEALTH] <= 0 );
00154 #endif
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 VectorCopy( parentPS->origin, bottom );
00174 bottom[2] -= pVeh->m_pVehicleInfo->landingHeight;
00175
00176 traceFunc( &pVeh->m_LandTrace, parentPS->origin, trMins, trMaxs, bottom, pVeh->m_pParentEntity->s.number, (MASK_NPCSOLID&~CONTENTS_BODY) );
00177
00178
00179 return true;
00180 }
00181
00182 #ifdef QAGAME //ONLY in SP or on server, not cgame
00183
00184
00185 static bool Update( Vehicle_t *pVeh, const usercmd_t *pUcmd )
00186 {
00187 assert(pVeh->m_pParentEntity);
00188 if (!BG_FighterUpdate(pVeh, pUcmd, ((gentity_t *)pVeh->m_pParentEntity)->mins,
00189 ((gentity_t *)pVeh->m_pParentEntity)->maxs,
00190 #ifdef _JK2MP
00191 g_gravity.value,
00192 #else
00193 g_gravity->value,
00194 #endif
00195 G_VehicleTrace))
00196 {
00197 return false;
00198 }
00199
00200 if ( !g_vehicleInfo[VEHICLE_BASE].Update( pVeh, pUcmd ) )
00201 {
00202 return false;
00203 }
00204
00205 return true;
00206 }
00207
00208
00209 static bool Board( Vehicle_t *pVeh, bgEntity_t *pEnt )
00210 {
00211 if ( !g_vehicleInfo[VEHICLE_BASE].Board( pVeh, pEnt ) )
00212 return false;
00213
00214
00215 pVeh->m_iBoarding = level.time + 1500;
00216
00217 return true;
00218 }
00219
00220
00221 static bool Eject( Vehicle_t *pVeh, bgEntity_t *pEnt, qboolean forceEject )
00222 {
00223 if ( g_vehicleInfo[VEHICLE_BASE].Eject( pVeh, pEnt, forceEject ) )
00224 {
00225 return true;
00226 }
00227
00228 return false;
00229 }
00230
00231 #endif //end game-side only
00232
00233
00234 static float PredictedAngularDecrement(float scale, float timeMod, float originalAngle)
00235 {
00236 float fixedBaseDec = originalAngle*0.05f;
00237 float r = 0.0f;
00238
00239 if (fixedBaseDec < 0.0f)
00240 {
00241 fixedBaseDec = -fixedBaseDec;
00242 }
00243
00244 fixedBaseDec *= (1.0f+(1.0f-scale));
00245
00246 if (fixedBaseDec < 0.1f)
00247 {
00248 fixedBaseDec = 0.1f;
00249 }
00250
00251 fixedBaseDec *= (timeMod*0.1f);
00252 if (originalAngle > 0.0f)
00253 {
00254 r = (originalAngle-fixedBaseDec);
00255 if (r < 0.0f)
00256 {
00257 r = 0.0f;
00258 }
00259 }
00260 else if (originalAngle < 0.0f)
00261 {
00262 r = (originalAngle+fixedBaseDec);
00263 if (r > 0.0f)
00264 {
00265 r = 0.0f;
00266 }
00267 }
00268
00269 return r;
00270 }
00271
00272 #ifdef QAGAME//only do this check on GAME side, because if it's CGAME, it's being predicted, and it's only predicted if the local client is the driver
00273 qboolean FighterIsInSpace( gentity_t *gParent )
00274 {
00275 if ( gParent
00276 && gParent->client
00277 && gParent->client->inSpaceIndex
00278 && gParent->client->inSpaceIndex < ENTITYNUM_WORLD )
00279 {
00280 return qtrue;
00281 }
00282 return qfalse;
00283 }
00284 #endif
00285
00286 qboolean FighterOverValidLandingSurface( Vehicle_t *pVeh )
00287 {
00288 if ( pVeh->m_LandTrace.fraction < 1.0f
00289 && pVeh->m_LandTrace.plane.normal[2] >= MIN_LANDING_SLOPE )
00290
00291 {
00292 return qtrue;
00293 }
00294 return qfalse;
00295 }
00296
00297 qboolean FighterIsLanded( Vehicle_t *pVeh, playerState_t *parentPS )
00298 {
00299 if ( FighterOverValidLandingSurface( pVeh )
00300 && !parentPS->speed )
00301 {
00302 return qtrue;
00303 }
00304 return qfalse;
00305 }
00306
00307 qboolean FighterIsLanding( Vehicle_t *pVeh, playerState_t *parentPS )
00308 {
00309
00310 if ( FighterOverValidLandingSurface( pVeh )
00311 #ifdef QAGAME
00312 && pVeh->m_pVehicleInfo->Inhabited( pVeh )
00313 #endif
00314 && (pVeh->m_ucmd.forwardmove < 0||pVeh->m_ucmd.upmove<0)
00315 && parentPS->speed <= MIN_LANDING_SPEED )
00316 {
00317 return qtrue;
00318 }
00319 return qfalse;
00320 }
00321
00322 qboolean FighterIsLaunching( Vehicle_t *pVeh, playerState_t *parentPS )
00323 {
00324
00325 if ( FighterOverValidLandingSurface( pVeh )
00326 #ifdef QAGAME
00327 && pVeh->m_pVehicleInfo->Inhabited( pVeh )
00328 #endif
00329 && pVeh->m_ucmd.upmove > 0
00330 && parentPS->speed <= 200.0f )
00331 {
00332 return qtrue;
00333 }
00334 return qfalse;
00335 }
00336
00337 qboolean FighterSuspended( Vehicle_t *pVeh, playerState_t *parentPS )
00338 {
00339 #ifdef QAGAME//only do this check on GAME side, because if it's CGAME, it's being predicted, and it's only predicted if the local client is the driver
00340 if (!pVeh->m_pPilot
00341 && !parentPS->speed
00342 && pVeh->m_ucmd.forwardmove <= 0
00343 && pVeh->m_pParentEntity != NULL
00344 && (((gentity_t *)pVeh->m_pParentEntity)->spawnflags&2) )
00345 {
00346 return qtrue;
00347 }
00348 return qfalse;
00349 #elif CGAME
00350 return qfalse;
00351 #endif
00352 }
00353
00354 #ifdef CGAME
00355 extern void trap_S_StartSound( vec3_t origin, int entityNum, int entchannel, sfxHandle_t sfx );
00356 extern sfxHandle_t trap_S_RegisterSound( const char *sample);
00357 #endif
00358
00359
00360
00361
00362
00363
00364
00365
00366 #define FIGHTER_MIN_TAKEOFF_FRACTION 0.7f
00367 static void ProcessMoveCommands( Vehicle_t *pVeh )
00368 {
00369
00370
00371
00372
00373
00374 float speedInc, speedIdleDec, speedIdle, speedIdleAccel, speedMin, speedMax;
00375 bgEntity_t *parent = pVeh->m_pParentEntity;
00376 qboolean isLandingOrLaunching = qfalse;
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389 int curTime = pm->cmd.serverTime;
00390
00391 #ifdef _JK2MP
00392 playerState_t *parentPS = parent->playerState;
00393 #else
00394 playerState_t *parentPS = &parent->client->ps;
00395 #endif
00396
00397 #ifdef _JK2MP
00398 if ( parentPS->hyperSpaceTime
00399 && curTime - parentPS->hyperSpaceTime < HYPERSPACE_TIME )
00400 {
00401
00402 float timeFrac = ((float)(curTime-parentPS->hyperSpaceTime))/HYPERSPACE_TIME;
00403 if ( timeFrac < HYPERSPACE_TELEPORT_FRAC )
00404 {
00405 if ( !(parentPS->eFlags2&EF2_HYPERSPACE) )
00406 {
00407 parentPS->speed = 0.0f;
00408 }
00409 else
00410 {
00411 if ( parentPS->speed < HYPERSPACE_SPEED )
00412 {
00413
00414
00415 #ifdef QAGAME//MP GAME-side
00416
00417 #elif CGAME//MP CGAME-side
00418 trap_S_StartSound( NULL, pm->ps->clientNum, CHAN_LOCAL, pVeh->m_pVehicleInfo->soundHyper );
00419 #endif
00420 }
00421
00422 parentPS->speed = HYPERSPACE_SPEED;
00423 }
00424 }
00425 else
00426 {
00427 parentPS->speed = 200.0f + ((1.0f-timeFrac)*(1.0f/HYPERSPACE_TELEPORT_FRAC)*(HYPERSPACE_SPEED-200.0f));
00428
00429 if ( VectorLength( parentPS->velocity ) < parentPS->speed )
00430 {
00431 VectorScale( parentPS->moveDir, parentPS->speed, parentPS->velocity );
00432 }
00433 }
00434 return;
00435 }
00436 #endif
00437
00438 if ( pVeh->m_iDropTime >= curTime )
00439 {
00440 parentPS->speed = 0.0f;
00441 parentPS->gravity = 800;
00442 return;
00443 }
00444
00445 isLandingOrLaunching = (FighterIsLanding( pVeh, parentPS )||FighterIsLaunching( pVeh, parentPS ));
00446
00447
00448 if ( isLandingOrLaunching
00449 && (pVeh->m_ucmd.forwardmove<=0||pVeh->m_LandTrace.fraction<=FIGHTER_MIN_TAKEOFF_FRACTION) )
00450 {
00451
00452
00453 if ( pVeh->m_ucmd.upmove > 0 )
00454 {
00455 #ifdef _JK2MP
00456 if ( parentPS->velocity[2] <= 0
00457 && pVeh->m_pVehicleInfo->soundTakeOff )
00458 {
00459 #ifdef QAGAME//MP GAME-side
00460 G_EntitySound( ((gentity_t *)(pVeh->m_pParentEntity)), CHAN_AUTO, pVeh->m_pVehicleInfo->soundTakeOff );
00461 #endif
00462 }
00463 #endif
00464 parentPS->velocity[2] += pVeh->m_pVehicleInfo->acceleration * pVeh->m_fTimeModifier;
00465 }
00466 else if ( pVeh->m_ucmd.upmove < 0 )
00467 {
00468 parentPS->velocity[2] -= pVeh->m_pVehicleInfo->acceleration * pVeh->m_fTimeModifier;
00469 }
00470 else if ( pVeh->m_ucmd.forwardmove < 0 )
00471 {
00472 if ( pVeh->m_LandTrace.fraction != 0.0f )
00473 {
00474 parentPS->velocity[2] -= pVeh->m_pVehicleInfo->acceleration * pVeh->m_fTimeModifier;
00475 }
00476
00477 if ( pVeh->m_LandTrace.fraction <= FIGHTER_MIN_TAKEOFF_FRACTION )
00478 {
00479
00480
00481
00482
00483
00484
00485
00486 parentPS->velocity[2] = PredictedAngularDecrement(pVeh->m_LandTrace.fraction, pVeh->m_fTimeModifier*5.0f, parentPS->velocity[2]);
00487
00488 parentPS->speed = 0;
00489 }
00490 }
00491
00492
00493
00494 pVeh->m_vOrientation[PITCH] = PredictedAngularDecrement(0.7f, pVeh->m_fTimeModifier*10.0f, pVeh->m_vOrientation[PITCH]);
00495
00496 return;
00497 }
00498
00499 if ( (pVeh->m_ucmd.upmove > 0) && pVeh->m_pVehicleInfo->turboSpeed )
00500 {
00501 if ((curTime - pVeh->m_iTurboTime)>pVeh->m_pVehicleInfo->turboRecharge)
00502 {
00503 pVeh->m_iTurboTime = (curTime + pVeh->m_pVehicleInfo->turboDuration);
00504
00505 #ifdef QAGAME//MP GAME-side
00506
00507 if ( pVeh->m_pVehicleInfo->soundTurbo )
00508 {
00509 G_EntitySound( ((gentity_t *)(pVeh->m_pParentEntity)), CHAN_AUTO, pVeh->m_pVehicleInfo->soundTurbo );
00510 }
00511 #endif
00512 }
00513 }
00514 speedInc = pVeh->m_pVehicleInfo->acceleration * pVeh->m_fTimeModifier;
00515 if ( curTime < pVeh->m_iTurboTime )
00516 {
00517 speedMax = pVeh->m_pVehicleInfo->turboSpeed;
00518
00519
00520
00521 speedInc = (pVeh->m_pVehicleInfo->acceleration*2.0f) * pVeh->m_fTimeModifier;
00522
00523
00524 pVeh->m_ucmd.forwardmove = 127;
00525 #ifdef _JK2MP//SP can cheat and just check m_iTurboTime directly... :)
00526
00527 parentPS->eFlags |= EF_JETPACK_ACTIVE;
00528 #endif
00529 }
00530
00531
00532
00533
00534
00535
00536
00537 else
00538 {
00539 speedMax = pVeh->m_pVehicleInfo->speedMax;
00540 #ifdef _JK2MP//SP can cheat and just check m_iTurboTime directly... :)
00541 if ( (parentPS->eFlags&EF_JETPACK_ACTIVE) )
00542 {
00543 parentPS->eFlags &= ~EF_JETPACK_ACTIVE;
00544 }
00545 #endif
00546 }
00547 speedIdleDec = pVeh->m_pVehicleInfo->decelIdle * pVeh->m_fTimeModifier;
00548 speedIdle = pVeh->m_pVehicleInfo->speedIdle;
00549 speedIdleAccel = pVeh->m_pVehicleInfo->accelIdle * pVeh->m_fTimeModifier;
00550 speedMin = pVeh->m_pVehicleInfo->speedMin;
00551
00552 if ( (parentPS->brokenLimbs&(1<<SHIPSURF_DAMAGE_BACK_HEAVY)) )
00553 {
00554 speedMax *= 0.8f;
00555 }
00556 else if ( (parentPS->brokenLimbs&(1<<SHIPSURF_DAMAGE_BACK_LIGHT)) )
00557 {
00558 speedMax *= 0.6f;
00559 }
00560
00561 if (pVeh->m_iRemovedSurfaces
00562 || parentPS->electrifyTime>=curTime)
00563 {
00564 parentPS->speed += speedInc;
00565
00566 pVeh->m_ucmd.forwardmove = 127;
00567 }
00568 #ifdef QAGAME //well, the thing is always going to be inhabited if it's being predicted!
00569 else if ( FighterSuspended( pVeh, parentPS ) )
00570 {
00571 parentPS->speed = 0;
00572 pVeh->m_ucmd.forwardmove = 0;
00573 }
00574 else if ( !pVeh->m_pVehicleInfo->Inhabited( pVeh )
00575 && parentPS->speed > 0 )
00576 {
00577
00578 pVeh->m_ucmd.forwardmove = 127;
00579 }
00580 #endif
00581 else if ( ( parentPS->speed || parentPS->groundEntityNum == ENTITYNUM_NONE ||
00582 pVeh->m_ucmd.forwardmove || pVeh->m_ucmd.upmove > 0 ) && pVeh->m_LandTrace.fraction >= 0.05f )
00583 {
00584 if ( pVeh->m_ucmd.forwardmove > 0 && speedInc )
00585 {
00586 parentPS->speed += speedInc;
00587 pVeh->m_ucmd.forwardmove = 127;
00588 }
00589 else if ( pVeh->m_ucmd.forwardmove < 0
00590 || pVeh->m_ucmd.upmove < 0 )
00591 {
00592 if ( pVeh->m_ucmd.upmove < 0 )
00593 {
00594 if ( pVeh->m_ucmd.forwardmove )
00595 {
00596 speedInc += pVeh->m_pVehicleInfo->braking;
00597 speedIdleDec += pVeh->m_pVehicleInfo->braking;
00598 }
00599 else
00600 {
00601 speedInc = speedIdleDec = pVeh->m_pVehicleInfo->braking;
00602 }
00603 }
00604 if ( parentPS->speed > speedIdle )
00605 {
00606 parentPS->speed -= speedInc;
00607 }
00608 else if ( parentPS->speed > speedMin )
00609 {
00610 if ( FighterOverValidLandingSurface( pVeh ) )
00611 {
00612 parentPS->speed -= speedInc;
00613 }
00614 else
00615 {
00616 parentPS->speed -= speedIdleDec;
00617 if ( parentPS->speed < MIN_LANDING_SPEED )
00618 {
00619 parentPS->speed = MIN_LANDING_SPEED;
00620 }
00621 }
00622 }
00623 if ( pVeh->m_pVehicleInfo->type == VH_FIGHTER )
00624 {
00625 pVeh->m_ucmd.forwardmove = 127;
00626 }
00627 else if ( speedMin >= 0 )
00628 {
00629 pVeh->m_ucmd.forwardmove = 0;
00630 }
00631 }
00632
00633 else if ( pVeh->m_pVehicleInfo->throttleSticks )
00634 {
00635 if ( parentPS->speed <= MIN_LANDING_SPEED )
00636 {
00637 if ( FighterOverValidLandingSurface( pVeh ) )
00638 {
00639
00640 if ( parentPS->speed > 0 )
00641 {
00642 parentPS->speed -= speedIdleDec;
00643 }
00644 else if ( parentPS->speed < 0 )
00645 {
00646 parentPS->speed += speedIdleDec;
00647 }
00648 }
00649 else
00650 {
00651
00652 if ( parentPS->speed < speedIdle )
00653 {
00654 parentPS->speed += speedIdleAccel;
00655 if ( parentPS->speed > speedIdle )
00656 {
00657 parentPS->speed = speedIdle;
00658 }
00659 }
00660 }
00661 }
00662 }
00663 else
00664 {
00665
00666
00667 if ( (pVeh->m_LandTrace.fraction >= 1.0f
00668 || pVeh->m_LandTrace.plane.normal[2] < MIN_LANDING_SLOPE )
00669 && speedIdle > 0 )
00670 {
00671
00672 if ( parentPS->speed < speedIdle )
00673 {
00674 parentPS->speed += speedIdleAccel;
00675 if ( parentPS->speed > speedIdle )
00676 {
00677 parentPS->speed = speedIdle;
00678 }
00679 }
00680 else if ( parentPS->speed > 0 )
00681 {
00682 parentPS->speed -= speedIdleDec;
00683
00684 if ( parentPS->speed < speedIdle )
00685 {
00686 parentPS->speed = speedIdle;
00687 }
00688 }
00689 }
00690 else
00691 {
00692 if ( parentPS->speed > 0 )
00693 {
00694 parentPS->speed -= speedIdleDec;
00695 }
00696 else if ( parentPS->speed < 0 )
00697 {
00698 parentPS->speed += speedIdleDec;
00699 }
00700 }
00701 }
00702 }
00703 else
00704 {
00705 if ( pVeh->m_ucmd.forwardmove < 0 )
00706 {
00707 pVeh->m_ucmd.forwardmove = 0;
00708 }
00709 if ( pVeh->m_ucmd.upmove < 0 )
00710 {
00711 pVeh->m_ucmd.upmove = 0;
00712 }
00713
00714 #ifndef _JK2MP
00715 if ( !pVeh->m_pVehicleInfo->strafePerc || (!g_speederControlScheme->value && !pVeh->m_pParentEntity->s.number) )
00716 {
00717 pVeh->m_ucmd.rightmove = 0;
00718 }
00719 #endif
00720 }
00721
00722 #if 1//This is working now, but there are some transitional jitters... Rich?
00723
00724 if ( pVeh->m_pVehicleInfo->strafePerc
00725 #ifdef QAGAME//only do this check on GAME side, because if it's CGAME, it's being predicted, and it's only predicted if the local client is the driver
00726 && pVeh->m_pVehicleInfo->Inhabited( pVeh )
00727 #endif
00728 && !pVeh->m_iRemovedSurfaces
00729 && parentPS->electrifyTime<curTime
00730 && (pVeh->m_LandTrace.fraction >= 1.0f
00731 ||pVeh->m_LandTrace.plane.normal[2] < MIN_LANDING_SLOPE
00732 ||parentPS->speed>MIN_LANDING_SPEED)
00733 && pVeh->m_ucmd.rightmove )
00734 {
00735 vec3_t vAngles, vRight;
00736 float strafeSpeed = (pVeh->m_pVehicleInfo->strafePerc*speedMax)*5.0f;
00737 VectorCopy( pVeh->m_vOrientation, vAngles );
00738 vAngles[PITCH] = vAngles[ROLL] = 0;
00739 AngleVectors( vAngles, NULL, vRight, NULL );
00740
00741 if ( pVeh->m_ucmd.rightmove > 0 )
00742 {
00743
00744
00745 if ( parentPS->hackingTime > -MAX_STRAFE_TIME )
00746 {
00747 float curStrafeSpeed = DotProduct( parentPS->velocity, vRight );
00748 if ( curStrafeSpeed > 0.0f )
00749 {
00750 strafeSpeed -= curStrafeSpeed;
00751 }
00752 if ( strafeSpeed > 0 )
00753 {
00754 VectorMA( parentPS->velocity, strafeSpeed*pVeh->m_fTimeModifier, vRight, parentPS->velocity );
00755 }
00756 parentPS->hackingTime -= 50*pVeh->m_fTimeModifier;
00757 }
00758 }
00759 else
00760 {
00761 if ( parentPS->hackingTime < MAX_STRAFE_TIME )
00762 {
00763 float curStrafeSpeed = DotProduct( parentPS->velocity, vRight );
00764 if ( curStrafeSpeed < 0.0f )
00765 {
00766 strafeSpeed += curStrafeSpeed;
00767 }
00768 if ( strafeSpeed > 0 )
00769 {
00770 VectorMA( parentPS->velocity, -strafeSpeed*pVeh->m_fTimeModifier, vRight, parentPS->velocity );
00771 }
00772 parentPS->hackingTime += 50*pVeh->m_fTimeModifier;
00773 }
00774 }
00775
00776
00777 }
00778 else
00779 {
00780 if ( parentPS->hackingTime > 0 )
00781 {
00782 parentPS->hackingTime -= 50*pVeh->m_fTimeModifier;
00783 if ( parentPS->hackingTime < 0 )
00784 {
00785 parentPS->hackingTime = 0.0f;
00786 }
00787 }
00788 else if ( parentPS->hackingTime < 0 )
00789 {
00790 parentPS->hackingTime += 50*pVeh->m_fTimeModifier;
00791 if ( parentPS->hackingTime > 0 )
00792 {
00793 parentPS->hackingTime = 0.0f;
00794 }
00795 }
00796 }
00797
00798 #endif
00799
00800 if ( parentPS->speed > speedMax )
00801 {
00802 parentPS->speed = speedMax;
00803 }
00804 else if ( parentPS->speed < speedMin )
00805 {
00806 parentPS->speed = speedMin;
00807 }
00808
00809 #ifdef QAGAME//FIXME: get working in GAME and CGAME
00810 if ((pVeh->m_vOrientation[PITCH]*0.1f) > 10.0f)
00811 {
00812 if ( FighterIsInSpace( (gentity_t *)parent ) )
00813 {
00814 }
00815 else
00816 {
00817
00818 float mult = pVeh->m_vOrientation[PITCH]*0.1f;
00819 if (mult < 1.0f)
00820 {
00821 mult = 1.0f;
00822 }
00823 parentPS->speed = PredictedAngularDecrement(mult, pVeh->m_fTimeModifier*10.0f, parentPS->speed);
00824 }
00825 }
00826
00827 if (pVeh->m_iRemovedSurfaces
00828 || parentPS->electrifyTime>=curTime)
00829 {
00830 if ( FighterIsInSpace( (gentity_t *)parent ) )
00831 {
00832
00833 if ( !(parent->s.number&3) )
00834 {
00835 parentPS->gravity = 0;
00836 }
00837 else if ( !(parent->s.number&2) )
00838 {
00839 parentPS->gravity = -500.0f;
00840 parentPS->velocity[2] = 80.0f;
00841 }
00842 else
00843 {
00844 parentPS->gravity = 500.0f;
00845 parentPS->velocity[2] = -80.0f;
00846 }
00847 }
00848 else
00849 {
00850 parentPS->gravity = 500.0f;
00851 parentPS->velocity[2] = -80.0f;
00852 }
00853 }
00854 else if ( FighterSuspended( pVeh, parentPS ) )
00855 {
00856 parentPS->gravity = 0;
00857 }
00858 else if ( (!parentPS->speed||parentPS->speed < speedIdle) && pVeh->m_ucmd.upmove <= 0 )
00859 {
00860 if ( FighterIsInSpace( (gentity_t *)parent ) )
00861 {
00862 if ( FighterOverValidLandingSurface( pVeh ) )
00863 {
00864 parentPS->gravity = (speedIdle - parentPS->speed)/4;
00865 }
00866 }
00867 else
00868 {
00869 parentPS->gravity = (speedIdle - parentPS->speed)/4;
00870 }
00871 }
00872 else
00873 {
00874 parentPS->gravity = 0;
00875 }
00876 #else//FIXME: get above checks working in GAME and CGAME
00877 parentPS->gravity = 0;
00878 #endif
00879
00880
00881
00882
00883 }
00884
00885 extern void BG_VehicleTurnRateForSpeed( Vehicle_t *pVeh, float speed, float *mPitchOverride, float *mYawOverride );
00886 static void FighterWingMalfunctionCheck( Vehicle_t *pVeh, playerState_t *parentPS )
00887 {
00888 float mPitchOverride = 1.0f;
00889 float mYawOverride = 1.0f;
00890 BG_VehicleTurnRateForSpeed( pVeh, parentPS->speed, &mPitchOverride, &mYawOverride );
00891
00892 if ( (parentPS->brokenLimbs&(1<<SHIPSURF_DAMAGE_RIGHT_HEAVY)) )
00893 {
00894 pVeh->m_vOrientation[ROLL] += (sin( pVeh->m_ucmd.serverTime*0.001 )+1.0f)*pVeh->m_fTimeModifier*mYawOverride*50.0f;
00895 }
00896 else if ( (parentPS->brokenLimbs&(1<<SHIPSURF_DAMAGE_RIGHT_LIGHT)) )
00897 {
00898 pVeh->m_vOrientation[ROLL] += (sin( pVeh->m_ucmd.serverTime*0.001 )+1.0f)*pVeh->m_fTimeModifier*mYawOverride*12.5f;
00899 }
00900
00901
00902 if ( (parentPS->brokenLimbs&(1<<SHIPSURF_DAMAGE_LEFT_HEAVY)) )
00903 {
00904 pVeh->m_vOrientation[ROLL] -= (sin( pVeh->m_ucmd.serverTime*0.001 )+1.0f)*pVeh->m_fTimeModifier*mYawOverride*50.0f;
00905 }
00906 else if ( (parentPS->brokenLimbs&(1<<SHIPSURF_DAMAGE_LEFT_LIGHT)) )
00907 {
00908 pVeh->m_vOrientation[ROLL] -= (sin( pVeh->m_ucmd.serverTime*0.001 )+1.0f)*pVeh->m_fTimeModifier*mYawOverride*12.5f;
00909 }
00910
00911 }
00912
00913 static void FighterNoseMalfunctionCheck( Vehicle_t *pVeh, playerState_t *parentPS )
00914 {
00915 float mPitchOverride = 1.0f;
00916 float mYawOverride = 1.0f;
00917 BG_VehicleTurnRateForSpeed( pVeh, parentPS->speed, &mPitchOverride, &mYawOverride );
00918
00919 if ( (parentPS->brokenLimbs&(1<<SHIPSURF_DAMAGE_FRONT_HEAVY)) )
00920 {
00921
00922 pVeh->m_vOrientation[PITCH] += sin( pVeh->m_ucmd.serverTime*0.001 )*pVeh->m_fTimeModifier*mPitchOverride*50.0f;
00923 }
00924 else if ( (parentPS->brokenLimbs&(1<<SHIPSURF_DAMAGE_FRONT_LIGHT)) )
00925 {
00926
00927 pVeh->m_vOrientation[PITCH] += sin( pVeh->m_ucmd.serverTime*0.001 )*pVeh->m_fTimeModifier*mPitchOverride*20.0f;
00928 }
00929 }
00930
00931 static void FighterDamageRoutine( Vehicle_t *pVeh, bgEntity_t *parent, playerState_t *parentPS, playerState_t *riderPS, qboolean isDead )
00932 {
00933 if ( !pVeh->m_iRemovedSurfaces )
00934 {
00935 if ( pVeh->m_pParentEntity && isDead )
00936 {
00937 pVeh->m_ucmd.upmove = 0;
00938
00939
00940
00941
00942
00943
00944
00945 if ( !(pVeh->m_pParentEntity->s.number%3) )
00946 {
00947 pVeh->m_vOrientation[PITCH] += pVeh->m_fTimeModifier;
00948 if ( !BG_UnrestrainedPitchRoll( riderPS, pVeh ) )
00949 {
00950 if ( pVeh->m_vOrientation[PITCH] > 60.0f )
00951 {
00952 pVeh->m_vOrientation[PITCH] = 60.0f;
00953 }
00954 }
00955 }
00956 else if ( !(pVeh->m_pParentEntity->s.number%2) )
00957 {
00958 pVeh->m_vOrientation[PITCH] -= pVeh->m_fTimeModifier;
00959 if ( !BG_UnrestrainedPitchRoll( riderPS, pVeh ) )
00960 {
00961 if ( pVeh->m_vOrientation[PITCH] > -60.0f )
00962 {
00963 pVeh->m_vOrientation[PITCH] = -60.0f;
00964 }
00965 }
00966 }
00967 if ( (pVeh->m_pParentEntity->s.number%2) )
00968 {
00969 pVeh->m_vOrientation[YAW] += pVeh->m_fTimeModifier;
00970 pVeh->m_vOrientation[ROLL] += pVeh->m_fTimeModifier*4.0f;
00971 }
00972 else
00973 {
00974 pVeh->m_vOrientation[YAW] -= pVeh->m_fTimeModifier;
00975 pVeh->m_vOrientation[ROLL] -= pVeh->m_fTimeModifier*4.0f;
00976 }
00977 }
00978 return;
00979 }
00980
00981
00982 pVeh->m_ucmd.upmove = 0;
00983
00984
00985
00986 if ( pVeh->m_LandTrace.fraction >= 0.1f )
00987 {
00988 if ( !FighterSuspended( pVeh, parentPS ) )
00989 {
00990
00991
00992 if ( !(pVeh->m_pParentEntity->s.number%2) )
00993 {
00994 pVeh->m_vOrientation[PITCH] += pVeh->m_fTimeModifier;
00995 if ( !BG_UnrestrainedPitchRoll( riderPS, pVeh ) )
00996 {
00997 if ( pVeh->m_vOrientation[PITCH] > 60.0f )
00998 {
00999 pVeh->m_vOrientation[PITCH] = 60.0f;
01000 }
01001 }
01002 }
01003 else if ( !(pVeh->m_pParentEntity->s.number%3) )
01004 {
01005 pVeh->m_vOrientation[PITCH] -= pVeh->m_fTimeModifier;
01006 if ( !BG_UnrestrainedPitchRoll( riderPS, pVeh ) )
01007 {
01008 if ( pVeh->m_vOrientation[PITCH] > -60.0f )
01009 {
01010 pVeh->m_vOrientation[PITCH] = -60.0f;
01011 }
01012 }
01013 }
01014
01015 }
01016 }
01017 #ifdef QAGAME
01018 if ( pVeh->m_LandTrace.fraction < 1.0f )
01019 {
01020 gentity_t *parent = (gentity_t *)pVeh->m_pParentEntity;
01021 gentity_t *killer = parent;
01022 #ifdef _JK2MP//only have this info in MP...
01023 if (parent->client->ps.otherKiller < ENTITYNUM_WORLD &&
01024 parent->client->ps.otherKillerTime > level.time)
01025 {
01026 gentity_t *potentialKiller = &g_entities[parent->client->ps.otherKiller];
01027
01028 if (potentialKiller->inuse && potentialKiller->client)
01029 {
01030 killer = potentialKiller;
01031 }
01032 }
01033 #endif
01034 G_Damage(parent, killer, killer, vec3_origin, parent->client->ps.origin, 99999, DAMAGE_NO_ARMOR, MOD_SUICIDE);
01035 }
01036 #endif
01037
01038 if ( ((pVeh->m_iRemovedSurfaces & SHIPSURF_BROKEN_C) ||
01039 (pVeh->m_iRemovedSurfaces & SHIPSURF_BROKEN_D)) &&
01040 ((pVeh->m_iRemovedSurfaces & SHIPSURF_BROKEN_E) ||
01041 (pVeh->m_iRemovedSurfaces & SHIPSURF_BROKEN_F)) )
01042 {
01043 float factor = 2.0f;
01044 if ((pVeh->m_iRemovedSurfaces & SHIPSURF_BROKEN_E) &&
01045 (pVeh->m_iRemovedSurfaces & SHIPSURF_BROKEN_F) &&
01046 (pVeh->m_iRemovedSurfaces & SHIPSURF_BROKEN_C) &&
01047 (pVeh->m_iRemovedSurfaces & SHIPSURF_BROKEN_D))
01048 {
01049 factor *= 2.0f;
01050 }
01051
01052 if ( !(pVeh->m_pParentEntity->s.number%4)||!(pVeh->m_pParentEntity->s.number%5) )
01053 {
01054 factor *= 4.0f;
01055 }
01056
01057 pVeh->m_vOrientation[ROLL] += (pVeh->m_fTimeModifier*factor);
01058 }
01059 else if ((pVeh->m_iRemovedSurfaces & SHIPSURF_BROKEN_C) ||
01060 (pVeh->m_iRemovedSurfaces & SHIPSURF_BROKEN_D))
01061 {
01062 float factor = 2.0f;
01063 if ((pVeh->m_iRemovedSurfaces & SHIPSURF_BROKEN_C) &&
01064 (pVeh->m_iRemovedSurfaces & SHIPSURF_BROKEN_D))
01065 {
01066 factor *= 2.0f;
01067 }
01068
01069 if ( !(pVeh->m_pParentEntity->s.number%4)||!(pVeh->m_pParentEntity->s.number%5) )
01070 {
01071 factor *= 4.0f;
01072 }
01073
01074 pVeh->m_vOrientation[ROLL] += factor*pVeh->m_fTimeModifier;
01075 }
01076 else if ((pVeh->m_iRemovedSurfaces & SHIPSURF_BROKEN_E) ||
01077 (pVeh->m_iRemovedSurfaces & SHIPSURF_BROKEN_F))
01078 {
01079 float factor = 2.0f;
01080 if ((pVeh->m_iRemovedSurfaces & SHIPSURF_BROKEN_E) &&
01081 (pVeh->m_iRemovedSurfaces & SHIPSURF_BROKEN_F))
01082 {
01083 factor *= 2.0f;
01084 }
01085
01086 if ( !(pVeh->m_pParentEntity->s.number%4)||!(pVeh->m_pParentEntity->s.number%5) )
01087 {
01088 factor *= 4.0f;
01089 }
01090
01091 pVeh->m_vOrientation[ROLL] -= factor*pVeh->m_fTimeModifier;
01092 }
01093 }
01094
01095 #ifdef _JK2MP
01096
01097 #ifdef VEH_CONTROL_SCHEME_4
01098
01099 #define FIGHTER_TURNING_MULTIPLIER 0.8f//was 1.6f //magic number hackery
01100 #define FIGHTER_TURNING_DEADZONE 0.25f//no turning if offset is this much
01101 void FighterRollAdjust(Vehicle_t *pVeh, playerState_t *riderPS, playerState_t *parentPS)
01102 {
01103
01104
01105
01106 float angDif = AngleSubtract(pVeh->m_vPrevRiderViewAngles[YAW],riderPS->viewangles[YAW]);
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122 angDif *= 0.5f;
01123 if ( angDif > 0.0f )
01124 {
01125 angDif *= angDif;
01126 }
01127 else if ( angDif < 0.0f )
01128 {
01129 angDif *= -angDif;
01130 }
01131
01132 if (parentPS && parentPS->speed)
01133 {
01134 float maxDif = pVeh->m_pVehicleInfo->turningSpeed*FIGHTER_TURNING_MULTIPLIER;
01135
01136 if ( pVeh->m_pVehicleInfo->speedDependantTurning )
01137 {
01138 float speedFrac = 1.0f;
01139 if ( pVeh->m_LandTrace.fraction >= 1.0f
01140 || pVeh->m_LandTrace.plane.normal[2] < MIN_LANDING_SLOPE )
01141 {
01142 float s = parentPS->speed;
01143 if (s < 0.0f)
01144 {
01145 s = -s;
01146 }
01147 speedFrac = (s/(pVeh->m_pVehicleInfo->speedMax*0.75f));
01148 if ( speedFrac < 0.25f )
01149 {
01150 speedFrac = 0.25f;
01151 }
01152 else if ( speedFrac > 1.0f )
01153 {
01154 speedFrac = 1.0f;
01155 }
01156 }
01157 angDif *= speedFrac;
01158 }
01159 if (angDif > maxDif)
01160 {
01161 angDif = maxDif;
01162 }
01163 else if (angDif < -maxDif)
01164 {
01165 angDif = -maxDif;
01166 }
01167 pVeh->m_vOrientation[ROLL] = AngleNormalize180(pVeh->m_vOrientation[ROLL] + angDif*(pVeh->m_fTimeModifier*0.2f));
01168 }
01169 }
01170
01171 void FighterYawAdjust(Vehicle_t *pVeh, playerState_t *riderPS, playerState_t *parentPS)
01172 {
01173 float angDif = AngleSubtract(pVeh->m_vPrevRiderViewAngles[YAW],riderPS->viewangles[YAW]);
01174 if ( fabs( angDif ) < FIGHTER_TURNING_DEADZONE )
01175 {
01176 angDif = 0.0f;
01177 }
01178 else if ( angDif >= FIGHTER_TURNING_DEADZONE )
01179 {
01180 angDif -= FIGHTER_TURNING_DEADZONE;
01181 }
01182 else if ( angDif <= -FIGHTER_TURNING_DEADZONE )
01183 {
01184 angDif += FIGHTER_TURNING_DEADZONE;
01185 }
01186
01187 angDif *= 0.5f;
01188 if ( angDif > 0.0f )
01189 {
01190 angDif *= angDif;
01191 }
01192 else if ( angDif < 0.0f )
01193 {
01194 angDif *= -angDif;
01195 }
01196
01197 if (parentPS && parentPS->speed)
01198 {
01199 float maxDif = pVeh->m_pVehicleInfo->turningSpeed*FIGHTER_TURNING_MULTIPLIER;
01200
01201 if ( pVeh->m_pVehicleInfo->speedDependantTurning )
01202 {
01203 float speedFrac = 1.0f;
01204 if ( pVeh->m_LandTrace.fraction >= 1.0f
01205 || pVeh->m_LandTrace.plane.normal[2] < MIN_LANDING_SLOPE )
01206 {
01207 float s = parentPS->speed;
01208 if (s < 0.0f)
01209 {
01210 s = -s;
01211 }
01212 speedFrac = (s/(pVeh->m_pVehicleInfo->speedMax*0.75f));
01213 if ( speedFrac < 0.25f )
01214 {
01215 speedFrac = 0.25f;
01216 }
01217 else if ( speedFrac > 1.0f )
01218 {
01219 speedFrac = 1.0f;
01220 }
01221 }
01222 angDif *= speedFrac;
01223 }
01224 if (angDif > maxDif)
01225 {
01226 angDif = maxDif;
01227 }
01228 else if (angDif < -maxDif)
01229 {
01230 angDif = -maxDif;
01231 }
01232 pVeh->m_vOrientation[YAW] = AngleNormalize180(pVeh->m_vOrientation[YAW] - (angDif*(pVeh->m_fTimeModifier*0.2f)) );
01233 }
01234 }
01235
01236 void FighterPitchAdjust(Vehicle_t *pVeh, playerState_t *riderPS, playerState_t *parentPS)
01237 {
01238 float angDif = AngleSubtract(0,riderPS->viewangles[PITCH]);
01239 if ( fabs( angDif ) < FIGHTER_TURNING_DEADZONE )
01240 {
01241 angDif = 0.0f;
01242 }
01243 else if ( angDif >= FIGHTER_TURNING_DEADZONE )
01244 {
01245 angDif -= FIGHTER_TURNING_DEADZONE;
01246 }
01247 else if ( angDif <= -FIGHTER_TURNING_DEADZONE )
01248 {
01249 angDif += FIGHTER_TURNING_DEADZONE;
01250 }
01251
01252 angDif *= 0.5f;
01253 if ( angDif > 0.0f )
01254 {
01255 angDif *= angDif;
01256 }
01257 else if ( angDif < 0.0f )
01258 {
01259 angDif *= -angDif;
01260 }
01261
01262 if (parentPS && parentPS->speed)
01263 {
01264 float maxDif = pVeh->m_pVehicleInfo->turningSpeed*FIGHTER_TURNING_MULTIPLIER;
01265
01266 if ( pVeh->m_pVehicleInfo->speedDependantTurning )
01267 {
01268 float speedFrac = 1.0f;
01269 if ( pVeh->m_LandTrace.fraction >= 1.0f
01270 || pVeh->m_LandTrace.plane.normal[2] < MIN_LANDING_SLOPE )
01271 {
01272 float s = parentPS->speed;
01273 if (s < 0.0f)
01274 {
01275 s = -s;
01276 }
01277 speedFrac = (s/(pVeh->m_pVehicleInfo->speedMax*0.75f));
01278 if ( speedFrac < 0.25f )
01279 {
01280 speedFrac = 0.25f;
01281 }
01282 else if ( speedFrac > 1.0f )
01283 {
01284 speedFrac = 1.0f;
01285 }
01286 }
01287 angDif *= speedFrac;
01288 }
01289 if (angDif > maxDif)
01290 {
01291 angDif = maxDif;
01292 }
01293 else if (angDif < -maxDif)
01294 {
01295 angDif = -maxDif;
01296 }
01297 pVeh->m_vOrientation[PITCH] = AngleNormalize180(pVeh->m_vOrientation[PITCH] - (angDif*(pVeh->m_fTimeModifier*0.2f)) );
01298 }
01299 }
01300
01301 #else// VEH_CONTROL_SCHEME_4
01302
01303 void FighterYawAdjust(Vehicle_t *pVeh, playerState_t *riderPS, playerState_t *parentPS)
01304 {
01305 float angDif = AngleSubtract(pVeh->m_vOrientation[YAW], riderPS->viewangles[YAW]);
01306
01307 if (parentPS && parentPS->speed)
01308 {
01309 float s = parentPS->speed;
01310 float maxDif = pVeh->m_pVehicleInfo->turningSpeed*0.8f;
01311
01312 if (s < 0.0f)
01313 {
01314 s = -s;
01315 }
01316 angDif *= s/pVeh->m_pVehicleInfo->speedMax;
01317 if (angDif > maxDif)
01318 {
01319 angDif = maxDif;
01320 }
01321 else if (angDif < -maxDif)
01322 {
01323 angDif = -maxDif;
01324 }
01325 pVeh->m_vOrientation[YAW] = AngleNormalize180(pVeh->m_vOrientation[YAW] - angDif*(pVeh->m_fTimeModifier*0.2f));
01326 }
01327 }
01328
01329 void FighterPitchAdjust(Vehicle_t *pVeh, playerState_t *riderPS, playerState_t *parentPS)
01330 {
01331 float angDif = AngleSubtract(pVeh->m_vOrientation[PITCH], riderPS->viewangles[PITCH]);
01332
01333 if (parentPS && parentPS->speed)
01334 {
01335 float s = parentPS->speed;
01336 float maxDif = pVeh->m_pVehicleInfo->turningSpeed*0.8f;
01337
01338 if (s < 0.0f)
01339 {
01340 s = -s;
01341 }
01342 angDif *= s/pVeh->m_pVehicleInfo->speedMax;
01343 if (angDif > maxDif)
01344 {
01345 angDif = maxDif;
01346 }
01347 else if (angDif < -maxDif)
01348 {
01349 angDif = -maxDif;
01350 }
01351 pVeh->m_vOrientation[PITCH] = AngleNormalize360(pVeh->m_vOrientation[PITCH] - angDif*(pVeh->m_fTimeModifier*0.2f));
01352 }
01353 }
01354 #endif// VEH_CONTROL_SCHEME_4
01355
01356 void FighterPitchClamp(Vehicle_t *pVeh, playerState_t *riderPS, playerState_t *parentPS, int curTime )
01357 {
01358 if ( !BG_UnrestrainedPitchRoll( riderPS, pVeh ) )
01359 {
01360 if ( pVeh->m_pVehicleInfo->pitchLimit != -1
01361 && !pVeh->m_iRemovedSurfaces
01362 && parentPS->electrifyTime < curTime )
01363 {
01364 if (pVeh->m_vOrientation[PITCH] > pVeh->m_pVehicleInfo->pitchLimit )
01365 {
01366 pVeh->m_vOrientation[PITCH] = pVeh->m_pVehicleInfo->pitchLimit;
01367 }
01368 else if (pVeh->m_vOrientation[PITCH] < -pVeh->m_pVehicleInfo->pitchLimit)
01369 {
01370 pVeh->m_vOrientation[PITCH] = -pVeh->m_pVehicleInfo->pitchLimit;
01371 }
01372 }
01373 }
01374 }
01375
01376 #endif// _JK2MP
01377
01378
01379
01380
01381
01382
01383
01384
01385 static void ProcessOrientCommands( Vehicle_t *pVeh )
01386 {
01387
01388
01389
01390
01391 bgEntity_t *parent = pVeh->m_pParentEntity;
01392 playerState_t *parentPS, *riderPS;
01393 float angleTimeMod;
01394 #ifdef QAGAME
01395 const float groundFraction = 0.1f;
01396 #endif
01397 float curRoll = 0.0f;
01398 qboolean isDead = qfalse;
01399 qboolean isLandingOrLanded = qfalse;
01400 #ifndef _JK2MP//SP
01401 int curTime = level.time;
01402 #elif QAGAME//MP GAME
01403 int curTime = level.time;
01404 #elif CGAME//MP CGAME
01405
01406 int curTime = pm->cmd.serverTime;
01407 #endif
01408
01409 #ifdef _JK2MP
01410 bgEntity_t *rider = NULL;
01411 if (parent->s.owner != ENTITYNUM_NONE)
01412 {
01413 rider = PM_BGEntForNum(parent->s.owner);
01414 }
01415 #else
01416 gentity_t *rider = parent->owner;
01417 #endif
01418
01419 #ifdef _JK2MP
01420 if ( !rider )
01421 #else
01422 if ( !rider || !rider->client )
01423 #endif
01424 {
01425 rider = parent;
01426 }
01427
01428 #ifdef _JK2MP
01429 parentPS = parent->playerState;
01430 riderPS = rider->playerState;
01431 isDead = (qboolean)((parentPS->eFlags&EF_DEAD)!=0);
01432 #else
01433 parentPS = &parent->client->ps;
01434 riderPS = &rider->client->ps;
01435 isDead = (parentPS->stats[STAT_HEALTH] <= 0 );
01436 #endif
01437
01438 #ifdef _JK2MP
01439
01440 #ifdef VEH_CONTROL_SCHEME_4
01441 if ( parentPS->hyperSpaceTime
01442 && (curTime - parentPS->hyperSpaceTime) < HYPERSPACE_TIME )
01443 {
01444
01445
01446 VectorCopy( parentPS->viewangles, pVeh->m_vOrientation );
01447 VectorClear( pVeh->m_vPrevRiderViewAngles );
01448 pVeh->m_vPrevRiderViewAngles[YAW] = AngleNormalize180(riderPS->viewangles[YAW]);
01449 FighterPitchClamp( pVeh, riderPS, parentPS, curTime );
01450 return;
01451 }
01452 else if ( parentPS->vehTurnaroundIndex
01453 && parentPS->vehTurnaroundTime > curTime )
01454 {
01455
01456
01457 VectorCopy( parentPS->viewangles, pVeh->m_vOrientation );
01458 VectorClear( pVeh->m_vPrevRiderViewAngles );
01459 pVeh->m_vPrevRiderViewAngles[YAW] = AngleNormalize180(riderPS->viewangles[YAW]);
01460 FighterPitchClamp( pVeh, riderPS, parentPS, curTime );
01461 return;
01462 }
01463
01464 #else// VEH_CONTROL_SCHEME_4
01465
01466 if ( parentPS->hyperSpaceTime
01467 && (curTime - parentPS->hyperSpaceTime) < HYPERSPACE_TIME )
01468 {
01469 VectorCopy( riderPS->viewangles, pVeh->m_vOrientation );
01470 VectorCopy( riderPS->viewangles, parentPS->viewangles );
01471 return;
01472 }
01473 #endif// VEH_CONTROL_SCHEME_4
01474
01475 #endif//_JK2MP
01476
01477 if ( pVeh->m_iDropTime >= curTime )
01478 {
01479 parentPS->viewangles[YAW] = pVeh->m_vOrientation[YAW] = riderPS->viewangles[YAW];
01480 #ifdef VEH_CONTROL_SCHEME_4
01481 VectorClear( pVeh->m_vPrevRiderViewAngles );
01482 pVeh->m_vPrevRiderViewAngles[YAW] = AngleNormalize180(riderPS->viewangles[YAW]);
01483 #endif// VEH_CONTROL_SCHEME_4
01484 return;
01485 }
01486
01487 angleTimeMod = pVeh->m_fTimeModifier;
01488
01489 if ( isDead || parentPS->electrifyTime>=curTime ||
01490 (pVeh->m_pVehicleInfo->surfDestruction &&
01491 pVeh->m_iRemovedSurfaces &&
01492 (pVeh->m_iRemovedSurfaces & SHIPSURF_BROKEN_C) &&
01493 (pVeh->m_iRemovedSurfaces & SHIPSURF_BROKEN_D) &&
01494 (pVeh->m_iRemovedSurfaces & SHIPSURF_BROKEN_E) &&
01495 (pVeh->m_iRemovedSurfaces & SHIPSURF_BROKEN_F)) )
01496 {
01497 FighterDamageRoutine(pVeh, parent, parentPS, riderPS, isDead);
01498 pVeh->m_vOrientation[ROLL] = AngleNormalize180( pVeh->m_vOrientation[ROLL] );
01499 return;
01500 }
01501
01502 if ( !BG_UnrestrainedPitchRoll( riderPS, pVeh ) )
01503 {
01504 pVeh->m_vOrientation[ROLL] = PredictedAngularDecrement(0.95f, angleTimeMod*2.0f, pVeh->m_vOrientation[ROLL]);
01505 }
01506
01507 isLandingOrLanded = (FighterIsLanding( pVeh, parentPS )||FighterIsLanded( pVeh, parentPS ));
01508
01509 if (!isLandingOrLanded)
01510 {
01511 int m = 0;
01512 float aVelDif;
01513 float dForVel;
01514
01515 FighterWingMalfunctionCheck( pVeh, parentPS );
01516
01517 while (m < 3)
01518 {
01519 aVelDif = pVeh->m_vFullAngleVelocity[m];
01520
01521 if (aVelDif != 0.0f)
01522 {
01523 dForVel = (aVelDif*0.1f)*pVeh->m_fTimeModifier;
01524 if (dForVel > 1.0f || dForVel < -1.0f)
01525 {
01526 pVeh->m_vOrientation[m] += dForVel;
01527 pVeh->m_vOrientation[m] = AngleNormalize180(pVeh->m_vOrientation[m]);
01528 if (m == PITCH)
01529 {
01530 if (pVeh->m_vOrientation[m] > 90.0f && (pVeh->m_vOrientation[m]-dForVel) < 90.0f)
01531 {
01532 pVeh->m_vOrientation[m] = 90.0f;
01533 pVeh->m_vFullAngleVelocity[m] = -pVeh->m_vFullAngleVelocity[m];
01534 }
01535 }
01536 pVeh->m_vFullAngleVelocity[m] -= dForVel;
01537 }
01538 else
01539 {
01540 pVeh->m_vFullAngleVelocity[m] = 0.0f;
01541 }
01542 }
01543
01544 m++;
01545 }
01546 }
01547 else
01548 {
01549 VectorClear(pVeh->m_vFullAngleVelocity);
01550 }
01551
01552 curRoll = pVeh->m_vOrientation[ROLL];
01553
01554
01555 if ( isLandingOrLanded
01556 && !pVeh->m_iRemovedSurfaces
01557 && parentPS->electrifyTime<curTime)
01558 {
01559 if ( parentPS->speed > 0.0f )
01560 {
01561 if ( pVeh->m_LandTrace.fraction < 0.3f )
01562 {
01563 pVeh->m_vOrientation[PITCH] = 0.0f;
01564 }
01565 else
01566 {
01567 pVeh->m_vOrientation[PITCH] = PredictedAngularDecrement(0.83f, angleTimeMod*10.0f, pVeh->m_vOrientation[PITCH]);
01568 }
01569 }
01570 if ( pVeh->m_LandTrace.fraction > 0.1f
01571 || pVeh->m_LandTrace.plane.normal[2] < MIN_LANDING_SLOPE )
01572 {
01573
01574 #ifdef _JK2MP
01575 FighterYawAdjust(pVeh, riderPS, parentPS);
01576 #else
01577 pVeh->m_vOrientation[YAW] = riderPS->viewangles[YAW];
01578 #endif
01579 }
01580 #ifdef VEH_CONTROL_SCHEME_4
01581 else
01582 {
01583 VectorClear( pVeh->m_vPrevRiderViewAngles );
01584 pVeh->m_vPrevRiderViewAngles[YAW] = AngleNormalize180(riderPS->viewangles[YAW]);
01585 }
01586 #endif// VEH_CONTROL_SCHEME_4
01587 }
01588 else if ( (pVeh->m_iRemovedSurfaces||parentPS->electrifyTime>=curTime)
01589 && (!(pVeh->m_pParentEntity->s.number%4)||!(pVeh->m_pParentEntity->s.number%5)) )
01590 {
01591 }
01592 else if ( pVeh->m_pPilot && pVeh->m_pPilot->s.number < MAX_CLIENTS && parentPS->speed > 0.0f )
01593 {
01594 #ifdef VEH_CONTROL_SCHEME_4
01595 if ( 0 )
01596 #else// VEH_CONTROL_SCHEME_4
01597 if ( BG_UnrestrainedPitchRoll( riderPS, pVeh ) )
01598 #endif// VEH_CONTROL_SCHEME_4
01599 {
01600 VectorCopy( riderPS->viewangles, pVeh->m_vOrientation );
01601 VectorCopy( riderPS->viewangles, parentPS->viewangles );
01602 #ifdef _JK2MP
01603
01604 #endif
01605
01606 curRoll = pVeh->m_vOrientation[ROLL];
01607
01608 FighterNoseMalfunctionCheck( pVeh, parentPS );
01609
01610
01611 }
01612 else
01613 {
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632 #ifdef _JK2MP
01633
01634
01635
01636
01637
01638 FighterYawAdjust(pVeh, riderPS, parentPS);
01639 #else
01640 pVeh->m_vOrientation[YAW] = riderPS->viewangles[YAW];
01641 #endif
01642
01643
01644 if ( !FighterOverValidLandingSurface( pVeh )
01645 || parentPS->speed > MIN_LANDING_SPEED )
01646
01647 {
01648 float fYawDelta;
01649
01650 #ifdef _JK2MP
01651 FighterPitchAdjust(pVeh, riderPS, parentPS);
01652 #ifdef VEH_CONTROL_SCHEME_4
01653 FighterPitchClamp( pVeh, riderPS, parentPS, curTime );
01654 #endif// VEH_CONTROL_SCHEME_4
01655 #else
01656 pVeh->m_vOrientation[PITCH] = riderPS->viewangles[PITCH];
01657 #endif
01658
01659 FighterNoseMalfunctionCheck( pVeh, parentPS );
01660
01661
01662 fYawDelta = AngleSubtract(pVeh->m_vOrientation[YAW], pVeh->m_vPrevOrientation[YAW]);
01663 if ( fYawDelta > 8.0f )
01664 {
01665 fYawDelta = 8.0f;
01666 }
01667 else if ( fYawDelta < -8.0f )
01668 {
01669 fYawDelta = -8.0f;
01670 }
01671 curRoll -= fYawDelta;
01672 curRoll = PredictedAngularDecrement(0.93f, angleTimeMod*2.0f, curRoll);
01673
01674
01675
01676 #ifdef VEH_CONTROL_SCHEME_4
01677 if ( !BG_UnrestrainedPitchRoll( riderPS, pVeh ) )
01678 {
01679 if ( pVeh->m_pVehicleInfo->rollLimit != -1 )
01680 {
01681 if (curRoll > pVeh->m_pVehicleInfo->rollLimit )
01682 {
01683 curRoll = pVeh->m_pVehicleInfo->rollLimit;
01684 }
01685 else if (curRoll < -pVeh->m_pVehicleInfo->rollLimit)
01686 {
01687 curRoll = -pVeh->m_pVehicleInfo->rollLimit;
01688 }
01689 }
01690 }
01691 #else// VEH_CONTROL_SCHEME_4
01692 if ( pVeh->m_pVehicleInfo->rollLimit != -1 )
01693 {
01694 if (curRoll > pVeh->m_pVehicleInfo->rollLimit )
01695 {
01696 curRoll = pVeh->m_pVehicleInfo->rollLimit;
01697 }
01698 else if (curRoll < -pVeh->m_pVehicleInfo->rollLimit)
01699 {
01700 curRoll = -pVeh->m_pVehicleInfo->rollLimit;
01701 }
01702 }
01703 #endif// VEH_CONTROL_SCHEME_4
01704 }
01705 }
01706 }
01707
01708
01709 if ( isLandingOrLanded )
01710 {
01711 if ( !isDead
01712 && parentPS->electrifyTime<curTime
01713 && (!pVeh->m_pVehicleInfo->surfDestruction || !pVeh->m_iRemovedSurfaces ) )
01714 {
01715 if ( pVeh->m_vOrientation[PITCH] > 0 )
01716 {
01717 pVeh->m_vOrientation[PITCH] = PredictedAngularDecrement(0.2f, angleTimeMod*10.0f, pVeh->m_vOrientation[PITCH]);
01718 }
01719 else
01720 {
01721 pVeh->m_vOrientation[PITCH] = PredictedAngularDecrement(0.75f, angleTimeMod*10.0f, pVeh->m_vOrientation[PITCH]);
01722 }
01723 }
01724 }
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763 #ifdef QAGAME //never gonna happen on client anyway, we can't be getting predicted unless the predicting client is boarded
01764 if ( !pVeh->m_pVehicleInfo->Inhabited( pVeh )
01765 && pVeh->m_LandTrace.fraction >= groundFraction
01766 && !FighterIsInSpace( (gentity_t *)parent )
01767 && !FighterSuspended( pVeh, parentPS ) )
01768 {
01769 pVeh->m_ucmd.upmove = 0;
01770
01771 pVeh->m_vOrientation[PITCH] += pVeh->m_fTimeModifier;
01772 if ( !BG_UnrestrainedPitchRoll( riderPS, pVeh ) )
01773 {
01774 if ( pVeh->m_vOrientation[PITCH] > 60.0f )
01775 {
01776 pVeh->m_vOrientation[PITCH] = 60.0f;
01777 }
01778 }
01779 }
01780 #endif
01781
01782 if ( !parentPS->hackingTime )
01783 {
01784 pVeh->m_vOrientation[ROLL] = curRoll;
01785
01786 if ( pVeh->m_vOrientation[ROLL] )
01787 {
01788 if ( (pVeh->m_iRemovedSurfaces||parentPS->electrifyTime>=curTime)
01789 && (!(pVeh->m_pParentEntity->s.number%4)||!(pVeh->m_pParentEntity->s.number%5)) )
01790 {
01791 }
01792 else
01793 {
01794 if ( !BG_UnrestrainedPitchRoll( riderPS, pVeh ) )
01795 {
01796 pVeh->m_vOrientation[YAW] -= ((pVeh->m_vOrientation[ROLL])*0.05f)*pVeh->m_fTimeModifier;
01797 }
01798 }
01799 }
01800 }
01801 else
01802 {
01803 float strafeRoll = (parentPS->hackingTime/MAX_STRAFE_TIME)*pVeh->m_pVehicleInfo->rollLimit;
01804 float strafeDif = AngleSubtract(strafeRoll, pVeh->m_vOrientation[ROLL]);
01805 pVeh->m_vOrientation[ROLL] += (strafeDif*0.1f)*pVeh->m_fTimeModifier;
01806 if ( !BG_UnrestrainedPitchRoll( riderPS, pVeh ) )
01807 {
01808 if ( pVeh->m_pVehicleInfo->rollLimit != -1
01809 && !pVeh->m_iRemovedSurfaces
01810 && parentPS->electrifyTime<curTime)
01811 {
01812 if (pVeh->m_vOrientation[ROLL] > pVeh->m_pVehicleInfo->rollLimit )
01813 {
01814 pVeh->m_vOrientation[ROLL] = pVeh->m_pVehicleInfo->rollLimit;
01815 }
01816 else if (pVeh->m_vOrientation[ROLL] < -pVeh->m_pVehicleInfo->rollLimit)
01817 {
01818 pVeh->m_vOrientation[ROLL] = -pVeh->m_pVehicleInfo->rollLimit;
01819 }
01820 }
01821 }
01822 }
01823
01824 if (pVeh->m_pVehicleInfo->surfDestruction)
01825 {
01826 FighterDamageRoutine(pVeh, parent, parentPS, riderPS, isDead);
01827 }
01828 pVeh->m_vOrientation[ROLL] = AngleNormalize180( pVeh->m_vOrientation[ROLL] );
01829
01830
01831
01832
01833 }
01834
01835 #ifdef QAGAME //ONLY in SP or on server, not cgame
01836
01837 extern void PM_SetAnim(pmove_t *pm,int setAnimParts,int anim,int setAnimFlags, int blendTime);
01838
01839
01840 static void AnimateVehicle( Vehicle_t *pVeh )
01841 {
01842 int Anim = -1;
01843 int iFlags = SETANIM_FLAG_NORMAL, iBlend = 300;
01844 qboolean isLanding = qfalse, isLanded = qfalse;
01845 #ifdef _JK2MP
01846 playerState_t *parentPS = pVeh->m_pParentEntity->playerState;
01847 #else
01848 playerState_t *parentPS = &pVeh->m_pParentEntity->client->ps;
01849 #endif
01850 #ifndef _JK2MP//SP
01851
01852 #elif QAGAME//MP GAME
01853 int curTime = level.time;
01854 #elif CGAME//MP CGAME
01855
01856 int curTime = pm->cmd.serverTime;
01857 #endif
01858
01859 if ( parentPS->hyperSpaceTime
01860 && curTime - parentPS->hyperSpaceTime < HYPERSPACE_TIME )
01861 {
01862
01863 if ( pVeh->m_ulFlags & VEH_WINGSOPEN )
01864 {
01865 pVeh->m_ulFlags &= ~VEH_WINGSOPEN;
01866 Anim = BOTH_WINGS_CLOSE;
01867 }
01868 }
01869 else
01870 {
01871 isLanding = FighterIsLanding( pVeh, parentPS );
01872 isLanded = FighterIsLanded( pVeh, parentPS );
01873
01874
01875 if ( !isLanding && !isLanded )
01876 {
01877 if ( !( pVeh->m_ulFlags & VEH_WINGSOPEN ) )
01878 {
01879 pVeh->m_ulFlags |= VEH_WINGSOPEN;
01880 pVeh->m_ulFlags &= ~VEH_GEARSOPEN;
01881 Anim = BOTH_WINGS_OPEN;
01882 }
01883 }
01884
01885 else
01886 {
01887 if ( (pVeh->m_ucmd.forwardmove < 0 || pVeh->m_ucmd.upmove < 0||isLanded)
01888 && pVeh->m_LandTrace.fraction <= 0.4f
01889 && pVeh->m_LandTrace.plane.normal[2] >= MIN_LANDING_SLOPE )
01890 {
01891
01892 if ( !( pVeh->m_ulFlags & VEH_GEARSOPEN ) )
01893 {
01894 #ifdef _JK2MP
01895 if ( pVeh->m_pVehicleInfo->soundLand )
01896 {
01897 #ifdef QAGAME//MP GAME-side
01898 G_EntitySound( ((gentity_t *)(pVeh->m_pParentEntity)), CHAN_AUTO, pVeh->m_pVehicleInfo->soundLand );
01899 #elif CGAME//MP CGAME-side
01900
01901 #endif
01902 }
01903 #endif
01904 pVeh->m_ulFlags |= VEH_GEARSOPEN;
01905 Anim = BOTH_GEARS_OPEN;
01906 }
01907 }
01908 else
01909 {
01910
01911 if ( pVeh->m_ulFlags & VEH_GEARSOPEN )
01912 {
01913 pVeh->m_ulFlags &= ~VEH_GEARSOPEN;
01914 Anim = BOTH_GEARS_CLOSE;
01915
01916 }
01917
01918 else
01919 {
01920 if ( pVeh->m_ulFlags & VEH_WINGSOPEN )
01921 {
01922 pVeh->m_ulFlags &= ~VEH_WINGSOPEN;
01923 Anim = BOTH_WINGS_CLOSE;
01924 }
01925 }
01926 }
01927 }
01928 }
01929
01930 if ( Anim != -1 )
01931 {
01932 #ifdef _JK2MP
01933 BG_SetAnim(pVeh->m_pParentEntity->playerState, bgAllAnims[pVeh->m_pParentEntity->localAnimIndex].anims,
01934 SETANIM_BOTH, Anim, iFlags, iBlend);
01935 #else
01936 NPC_SetAnim( pVeh->m_pParentEntity, SETANIM_BOTH, Anim, iFlags, iBlend );
01937 #endif
01938 }
01939 }
01940
01941
01942 static void AnimateRiders( Vehicle_t *pVeh )
01943 {
01944 }
01945
01946 #endif //game-only
01947
01948 #ifndef QAGAME
01949 void AttachRidersGeneric( Vehicle_t *pVeh );
01950 #endif
01951
01952 void G_SetFighterVehicleFunctions( vehicleInfo_t *pVehInfo )
01953 {
01954 #ifdef QAGAME //ONLY in SP or on server, not cgame
01955 pVehInfo->AnimateVehicle = AnimateVehicle;
01956 pVehInfo->AnimateRiders = AnimateRiders;
01957
01958
01959
01960
01961
01962 pVehInfo->Board = Board;
01963 pVehInfo->Eject = Eject;
01964
01965
01966
01967
01968
01969 pVehInfo->Update = Update;
01970
01971 #endif //game-only
01972 pVehInfo->ProcessMoveCommands = ProcessMoveCommands;
01973 pVehInfo->ProcessOrientCommands = ProcessOrientCommands;
01974
01975 #ifndef QAGAME //cgame prediction attachment func
01976 pVehInfo->AttachRiders = AttachRidersGeneric;
01977 #endif
01978
01979
01980
01981
01982 }
01983
01984
01985 #ifdef _JK2MP
01986 #include "../namespace_end.h"
01987 #endif
01988
01989 #ifdef QAGAME
01990 extern void G_AllocateVehicleObject(Vehicle_t **pVeh);
01991 #endif
01992
01993 #ifdef _JK2MP
01994 #include "../namespace_begin.h"
01995 #endif
01996
01997
01998 void G_CreateFighterNPC( Vehicle_t **pVeh, const char *strType )
01999 {
02000
02001 #ifdef _JK2MP
02002 #ifdef QAGAME
02003
02004
02005
02006 G_AllocateVehicleObject(pVeh);
02007 #else
02008 if (!*pVeh)
02009 {
02010 (*pVeh) = (Vehicle_t *) BG_Alloc( sizeof(Vehicle_t) );
02011 }
02012 #endif
02013 memset(*pVeh, 0, sizeof(Vehicle_t));
02014 #else
02015 (*pVeh) = (Vehicle_t *) gi.Malloc( sizeof(Vehicle_t), TAG_G_ALLOC, qtrue );
02016 #endif
02017 (*pVeh)->m_pVehicleInfo = &g_vehicleInfo[BG_VehicleGetIndex( strType )];
02018 }
02019
02020 #ifdef _JK2MP
02021
02022 #include "../namespace_end.h"
02023
02024
02025 #undef currentAngles
02026 #undef currentOrigin
02027 #undef mins
02028 #undef maxs
02029 #undef legsAnimTimer
02030 #undef torsoAnimTimer
02031 #undef bool
02032 #undef false
02033 #undef true
02034
02035 #undef sqrtf
02036 #undef Q_flrand
02037
02038 #undef MOD_EXPLOSIVE
02039 #endif