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 #include "..\game\wp_saber.h"
00047 #else
00048 #include "bg_vehicles.h"
00049 #endif
00050
00051 #ifdef _JK2MP
00052
00053
00054 #define currentAngles r.currentAngles
00055 #define currentOrigin r.currentOrigin
00056 #define mins r.mins
00057 #define maxs r.maxs
00058 #define legsAnimTimer legsTimer
00059 #define torsoAnimTimer torsoTimer
00060 #define bool qboolean
00061 #define false qfalse
00062 #define true qtrue
00063
00064 #define sqrtf sqrt
00065 #define Q_flrand flrand
00066
00067 #define MOD_EXPLOSIVE MOD_SUICIDE
00068 #else
00069 #define bgEntity_t gentity_t
00070 extern void NPC_SetAnim(gentity_t *ent,int setAnimParts,int anim,int setAnimFlags, int iBlend);
00071 #endif
00072
00073 extern float DotToSpot( vec3_t spot, vec3_t from, vec3_t fromAngles );
00074 #ifdef QAGAME //SP or gameside MP
00075 extern vmCvar_t cg_thirdPersonAlpha;
00076 extern vec3_t playerMins;
00077 extern vec3_t playerMaxs;
00078 extern cvar_t *g_speederControlScheme;
00079 extern void ChangeWeapon( gentity_t *ent, int newWeapon );
00080 extern void PM_SetAnim(pmove_t *pm,int setAnimParts,int anim,int setAnimFlags, int blendTime);
00081 extern int PM_AnimLength( int index, animNumber_t anim );
00082 #endif
00083
00084 #ifdef _JK2MP
00085
00086 #include "../namespace_begin.h"
00087
00088 extern void BG_SetAnim(playerState_t *ps, animation_t *animations, int setAnimParts,int anim,int setAnimFlags, int blendTime);
00089 extern int BG_GetTime(void);
00090 extern qboolean BG_SabersOff( playerState_t *ps );
00091 #endif
00092
00093
00094
00095
00096
00097 #define STRAFERAM_DURATION 8
00098 #define STRAFERAM_ANGLE 8
00099
00100
00101 #ifndef _JK2MP
00102 bool VEH_StartStrafeRam(Vehicle_t *pVeh, bool Right)
00103 {
00104 if (!(pVeh->m_ulFlags&VEH_STRAFERAM))
00105 {
00106 float speed = VectorLength(pVeh->m_pParentEntity->client->ps.velocity);
00107 if (speed>400.0f)
00108 {
00109
00110
00111 vec3_t right;
00112 AngleVectors(pVeh->m_vOrientation, 0, right, 0);
00113 VectorMA(pVeh->m_pParentEntity->client->ps.velocity, (Right)?( speed):(-speed), right, pVeh->m_pParentEntity->pos3);
00114
00115 pVeh->m_ulFlags |= VEH_STRAFERAM;
00116 parentPS->hackingTime = (Right)?(STRAFERAM_DURATION):(-STRAFERAM_DURATION);
00117
00118 if (pVeh->m_iSoundDebounceTimer<level.time && Q_irand(0,1)==0)
00119 {
00120 int shiftSound = Q_irand(1,4);
00121 switch (shiftSound)
00122 {
00123 case 1: shiftSound=pVeh->m_pVehicleInfo->soundShift1; break;
00124 case 2: shiftSound=pVeh->m_pVehicleInfo->soundShift2; break;
00125 case 3: shiftSound=pVeh->m_pVehicleInfo->soundShift3; break;
00126 case 4: shiftSound=pVeh->m_pVehicleInfo->soundShift4; break;
00127 }
00128 if (shiftSound)
00129 {
00130 pVeh->m_iSoundDebounceTimer = level.time + Q_irand(1000, 4000);
00131 G_SoundIndexOnEnt( pVeh->m_pParentEntity, CHAN_AUTO, shiftSound);
00132 }
00133 }
00134 return true;
00135 }
00136 }
00137 return false;
00138 }
00139 #else
00140 bool VEH_StartStrafeRam(Vehicle_t *pVeh, bool Right, int Duration)
00141 {
00142 return false;
00143 }
00144 #endif
00145
00146
00147 #ifdef QAGAME //game-only.. for now
00148
00149 bool Update( Vehicle_t *pVeh, const usercmd_t *pUcmd )
00150 {
00151 if ( !g_vehicleInfo[VEHICLE_BASE].Update( pVeh, pUcmd ) )
00152 {
00153 return false;
00154 }
00155
00156
00157 if ( pVeh->m_iDieTime != 0 )
00158 {
00159 pVeh->m_pVehicleInfo->DeathUpdate( pVeh );
00160 }
00161
00162
00163 #ifndef _JK2MP //this makes prediction unhappy, and rightfully so.
00164 gentity_t *parent = (gentity_t *)pVeh->m_pParentEntity;
00165
00166 if ( pVeh->m_ulFlags & VEH_FLYING )
00167 {
00168 vec3_t vVehAngles;
00169 VectorSet(vVehAngles, 0, pVeh->m_vOrientation[YAW], 0 );
00170 AngleVectors( vVehAngles, parent->client->ps.moveDir, NULL, NULL );
00171 }
00172 else
00173 {
00174 vec3_t vVehAngles;
00175 VectorSet(vVehAngles, pVeh->m_vOrientation[PITCH], pVeh->m_vOrientation[YAW], 0 );
00176 AngleVectors( vVehAngles, parent->client->ps.moveDir, NULL, NULL );
00177 }
00178
00179
00180
00181 if (!(pVeh->m_ulFlags&VEH_STRAFERAM) && !(pVeh->m_ulFlags&VEH_FLYING))
00182 {
00183
00184
00185 if (pVeh->m_ucmd.rightmove && !parentPS->hackingTime)
00186 {
00187 parentPS->hackingTime = (pVeh->m_ucmd.rightmove>0)?(level.time):(-1*level.time);
00188 }
00189
00190
00191
00192 else if (!pVeh->m_ucmd.rightmove && parentPS->hackingTime)
00193 {
00194
00195
00196 if ((level.time - abs(parentPS->hackingTime))<300)
00197 {
00198 if (!VEH_StartStrafeRam(pVeh, (parentPS->hackingTime>0)))
00199 {
00200 parentPS->hackingTime = 0;
00201 }
00202 }
00203
00204
00205
00206 else
00207 {
00208 parentPS->hackingTime = 0;
00209 }
00210 }
00211 }
00212
00213
00214
00215 else if (!parentPS->hackingTime)
00216 {
00217 pVeh->m_ulFlags &=~VEH_STRAFERAM;
00218 }
00219
00220
00221
00222
00223 if (pVeh->m_pVehicleInfo->iExhaustFX)
00224 {
00225
00226
00227 if (pVeh->m_ucmd.forwardmove && !(pVeh->m_ulFlags&VEH_ACCELERATORON))
00228 {
00229 pVeh->m_ulFlags |= VEH_ACCELERATORON;
00230 for (int i=0; (i<MAX_VEHICLE_EXHAUSTS && pVeh->m_iExhaustTag[i]!=-1); i++)
00231 {
00232 G_PlayEffect(pVeh->m_pVehicleInfo->iExhaustFX, parent->playerModel, pVeh->m_iExhaustTag[i], parent->s.number, parent->currentOrigin, 1, qtrue);
00233 }
00234 }
00235
00236
00237
00238 else if (!pVeh->m_ucmd.forwardmove && (pVeh->m_ulFlags&VEH_ACCELERATORON))
00239 {
00240 pVeh->m_ulFlags &=~VEH_ACCELERATORON;
00241 for (int i=0; (i<MAX_VEHICLE_EXHAUSTS && pVeh->m_iExhaustTag[i]!=-1); i++)
00242 {
00243 G_StopEffect(pVeh->m_pVehicleInfo->iExhaustFX, parent->playerModel, pVeh->m_iExhaustTag[i], parent->s.number);
00244 }
00245 }
00246 }
00247
00248 if (!(pVeh->m_ulFlags&VEH_ARMORLOW) && (pVeh->m_iArmor <= pVeh->m_pVehicleInfo->armor/3))
00249 {
00250 pVeh->m_ulFlags |= VEH_ARMORLOW;
00251
00252 }
00253
00254
00255
00256 if (pVeh->m_pVehicleInfo->iArmorGoneFX)
00257 {
00258 if (!(pVeh->m_ulFlags&VEH_ARMORGONE) && (pVeh->m_iArmor <= 0))
00259 {
00260 pVeh->m_ulFlags |= VEH_ARMORGONE;
00261 G_PlayEffect(pVeh->m_pVehicleInfo->iArmorGoneFX, parent->playerModel, parent->crotchBolt, parent->s.number, parent->currentOrigin, 1, qtrue);
00262 parent->s.loopSound = G_SoundIndex( "sound/vehicles/common/fire_lp.wav" );
00263 }
00264 }
00265 #endif
00266
00267 return true;
00268 }
00269 #endif //QAGAME
00270
00271
00272
00273
00274
00275
00276
00277
00278 static void ProcessMoveCommands( Vehicle_t *pVeh )
00279 {
00280
00281
00282
00283
00284 float speedInc, speedIdleDec, speedIdle, speedIdleAccel, speedMin, speedMax;
00285 playerState_t *parentPS;
00286 playerState_t *pilotPS = NULL;
00287 int curTime;
00288
00289 #ifdef _JK2MP
00290 parentPS = pVeh->m_pParentEntity->playerState;
00291 if (pVeh->m_pPilot)
00292 {
00293 pilotPS = pVeh->m_pPilot->playerState;
00294 }
00295 #else
00296 parentPS = &pVeh->m_pParentEntity->client->ps;
00297 if (pVeh->m_pPilot)
00298 {
00299 pilotPS = &pVeh->m_pPilot->client->ps;
00300 }
00301 #endif
00302
00303
00304
00305
00306 if ( pVeh->m_ulFlags & VEH_FLYING )
00307 {
00308 speedInc = pVeh->m_pVehicleInfo->acceleration * pVeh->m_fTimeModifier * 0.4f;
00309 }
00310 #ifdef _JK2MP
00311 else if ( !parentPS->m_iVehicleNum )
00312 #else
00313 else if ( !pVeh->m_pVehicleInfo->Inhabited( pVeh ) )
00314 #endif
00315 {
00316 speedInc = 0;
00317
00318 }
00319 else
00320 {
00321 speedInc = pVeh->m_pVehicleInfo->acceleration * pVeh->m_fTimeModifier;
00322 }
00323 speedIdleDec = pVeh->m_pVehicleInfo->decelIdle * pVeh->m_fTimeModifier;
00324
00325 #ifndef _JK2MP//SP
00326 curTime = level.time;
00327 #elif QAGAME//MP GAME
00328 curTime = level.time;
00329 #elif CGAME//MP CGAME
00330
00331 curTime = pm->cmd.serverTime;
00332 #endif
00333
00334
00335
00336 if ( (pVeh->m_pPilot &&
00337 (pVeh->m_ucmd.buttons & BUTTON_ALT_ATTACK) && pVeh->m_pVehicleInfo->turboSpeed)
00338
00339
00340 )
00341 {
00342 if ( (parentPS && parentPS->electrifyTime > curTime) ||
00343 (pVeh->m_pPilot->playerState &&
00344 (pVeh->m_pPilot->playerState->weapon == WP_MELEE ||
00345 (pVeh->m_pPilot->playerState->weapon == WP_SABER && BG_SabersOff( pVeh->m_pPilot->playerState ) ))) )
00346 {
00347 if ((curTime - pVeh->m_iTurboTime)>pVeh->m_pVehicleInfo->turboRecharge)
00348 {
00349 pVeh->m_iTurboTime = (curTime + pVeh->m_pVehicleInfo->turboDuration);
00350 if (pVeh->m_pVehicleInfo->iTurboStartFX)
00351 {
00352 int i;
00353 for (i=0; (i<MAX_VEHICLE_EXHAUSTS && pVeh->m_iExhaustTag[i]!=-1); i++)
00354 {
00355 #ifdef QAGAME
00356 if (pVeh->m_pParentEntity &&
00357 pVeh->m_pParentEntity->ghoul2 &&
00358 pVeh->m_pParentEntity->playerState)
00359 {
00360 vec3_t boltOrg, boltDir;
00361 mdxaBone_t boltMatrix;
00362
00363 VectorSet(boltDir, 0.0f, pVeh->m_pParentEntity->playerState->viewangles[YAW], 0.0f);
00364
00365 trap_G2API_GetBoltMatrix(pVeh->m_pParentEntity->ghoul2, 0, pVeh->m_iExhaustTag[i], &boltMatrix, boltDir, pVeh->m_pParentEntity->playerState->origin, level.time, NULL, pVeh->m_pParentEntity->modelScale);
00366 BG_GiveMeVectorFromMatrix(&boltMatrix, ORIGIN, boltOrg);
00367 BG_GiveMeVectorFromMatrix(&boltMatrix, ORIGIN, boltDir);
00368 G_PlayEffectID(pVeh->m_pVehicleInfo->iTurboStartFX, boltOrg, boltDir);
00369 }
00370 #endif
00371 }
00372 }
00373 parentPS->speed = pVeh->m_pVehicleInfo->turboSpeed;
00374 }
00375 }
00376 }
00377
00378
00379 if (pVeh->m_ulFlags&VEH_SLIDEBREAKING)
00380 {
00381 if (pVeh->m_ucmd.forwardmove>=0
00382 #ifndef _JK2MP
00383 || ((level.time - pVeh->m_pParentEntity->lastMoveTime)>500)
00384 #endif
00385 )
00386 {
00387 pVeh->m_ulFlags &= ~VEH_SLIDEBREAKING;
00388 }
00389 parentPS->speed = 0;
00390 }
00391 else if (
00392 (curTime > pVeh->m_iTurboTime) &&
00393 !(pVeh->m_ulFlags&VEH_FLYING) &&
00394 pVeh->m_ucmd.forwardmove<0 &&
00395 fabs(pVeh->m_vOrientation[ROLL])>25.0f)
00396 {
00397 pVeh->m_ulFlags |= VEH_SLIDEBREAKING;
00398 }
00399
00400
00401 if ( curTime < pVeh->m_iTurboTime )
00402 {
00403 speedMax = pVeh->m_pVehicleInfo->turboSpeed;
00404 if (parentPS)
00405 {
00406 parentPS->eFlags |= EF_JETPACK_ACTIVE;
00407 }
00408 }
00409 else
00410 {
00411 speedMax = pVeh->m_pVehicleInfo->speedMax;
00412 if (parentPS)
00413 {
00414 parentPS->eFlags &= ~EF_JETPACK_ACTIVE;
00415 }
00416 }
00417
00418
00419 speedIdle = pVeh->m_pVehicleInfo->speedIdle;
00420 speedIdleAccel = pVeh->m_pVehicleInfo->accelIdle * pVeh->m_fTimeModifier;
00421 speedMin = pVeh->m_pVehicleInfo->speedMin;
00422
00423 if ( parentPS->speed || parentPS->groundEntityNum == ENTITYNUM_NONE ||
00424 pVeh->m_ucmd.forwardmove || pVeh->m_ucmd.upmove > 0 )
00425 {
00426 if ( pVeh->m_ucmd.forwardmove > 0 && speedInc )
00427 {
00428 parentPS->speed += speedInc;
00429 }
00430 else if ( pVeh->m_ucmd.forwardmove < 0 )
00431 {
00432 if ( parentPS->speed > speedIdle )
00433 {
00434 parentPS->speed -= speedInc;
00435 }
00436 else if ( parentPS->speed > speedMin )
00437 {
00438 parentPS->speed -= speedIdleDec;
00439 }
00440 }
00441
00442 else if ( parentPS->speed > 0.0f )
00443 {
00444 parentPS->speed -= speedIdleDec;
00445 if ( parentPS->speed < 0.0f )
00446 {
00447 parentPS->speed = 0.0f;
00448 }
00449 }
00450 else if ( parentPS->speed < 0.0f )
00451 {
00452 parentPS->speed += speedIdleDec;
00453 if ( parentPS->speed > 0.0f )
00454 {
00455 parentPS->speed = 0.0f;
00456 }
00457 }
00458 }
00459 else
00460 {
00461 if ( !pVeh->m_pVehicleInfo->strafePerc
00462 #ifdef _JK2MP
00463 || (0 && pVeh->m_pParentEntity->s.number < MAX_CLIENTS) )
00464 #else
00465 || (!g_speederControlScheme->value && !pVeh->m_pParentEntity->s.number) )
00466 #endif
00467 {
00468
00469 }
00470 }
00471
00472 if ( parentPS->speed > speedMax )
00473 {
00474 parentPS->speed = speedMax;
00475 }
00476 else if ( parentPS->speed < speedMin )
00477 {
00478 parentPS->speed = speedMin;
00479 }
00480
00481 if (parentPS && parentPS->electrifyTime > curTime)
00482 {
00483 parentPS->speed *= (pVeh->m_fTimeModifier/60.0f);
00484 }
00485
00486
00487
00488
00489
00490 }
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502 #ifdef _JK2MP //temp hack til mp speeder controls are sorted -rww
00503 extern void AnimalProcessOri(Vehicle_t *pVeh);
00504 #endif
00505 void ProcessOrientCommands( Vehicle_t *pVeh )
00506 {
00507
00508
00509
00510 playerState_t *riderPS;
00511 playerState_t *parentPS;
00512
00513 #ifdef _JK2MP
00514 float angDif;
00515
00516 if (pVeh->m_pPilot)
00517 {
00518 riderPS = pVeh->m_pPilot->playerState;
00519 }
00520 else
00521 {
00522 riderPS = pVeh->m_pParentEntity->playerState;
00523 }
00524 parentPS = pVeh->m_pParentEntity->playerState;
00525
00526
00527 angDif = AngleSubtract(pVeh->m_vOrientation[YAW], riderPS->viewangles[YAW]);
00528 if (parentPS && parentPS->speed)
00529 {
00530 float s = parentPS->speed;
00531 float maxDif = pVeh->m_pVehicleInfo->turningSpeed*4.0f;
00532 if (s < 0.0f)
00533 {
00534 s = -s;
00535 }
00536 angDif *= s/pVeh->m_pVehicleInfo->speedMax;
00537 if (angDif > maxDif)
00538 {
00539 angDif = maxDif;
00540 }
00541 else if (angDif < -maxDif)
00542 {
00543 angDif = -maxDif;
00544 }
00545 pVeh->m_vOrientation[YAW] = AngleNormalize180(pVeh->m_vOrientation[YAW] - angDif*(pVeh->m_fTimeModifier*0.2f));
00546
00547 if (parentPS->electrifyTime > pm->cmd.serverTime)
00548 {
00549 pVeh->m_vOrientation[YAW] += (sin(pm->cmd.serverTime/1000.0f)*3.0f)*pVeh->m_fTimeModifier;
00550 }
00551 }
00552
00553 #else
00554 gentity_t *rider = pVeh->m_pParentEntity->owner;
00555 if ( !rider || !rider->client )
00556 {
00557 riderPS = &pVeh->m_pParentEntity->client->ps;
00558 }
00559 else
00560 {
00561 riderPS = &rider->client->ps;
00562 }
00563 parentPS = &pVeh->m_pParentEntity->client->ps;
00564
00565 if (pVeh->m_ulFlags & VEH_FLYING)
00566 {
00567 pVeh->m_vOrientation[YAW] += pVeh->m_vAngularVelocity;
00568 }
00569 else if (
00570 (pVeh->m_ulFlags & VEH_SLIDEBREAKING) ||
00571 (pVeh->m_ulFlags & VEH_OUTOFCONTROL)
00572 )
00573 {
00574
00575 }
00576 else if (
00577 (pVeh->m_ulFlags & VEH_STRAFERAM)
00578 )
00579 {
00580 if (parentPS->hackingTime>0)
00581 {
00582 parentPS->hackingTime--;
00583 pVeh->m_vOrientation[ROLL] += (parentPS->hackingTime<( STRAFERAM_DURATION/2))?(-STRAFERAM_ANGLE):( STRAFERAM_ANGLE);
00584 }
00585 else if (pVeh->hackingTime<0)
00586 {
00587 parentPS->hackingTime++;
00588 pVeh->m_vOrientation[ROLL] += (parentPS->hackingTime>(-STRAFERAM_DURATION/2))?( STRAFERAM_ANGLE):(-STRAFERAM_ANGLE);
00589 }
00590 }
00591 else
00592 {
00593 pVeh->m_vOrientation[YAW] = riderPS->viewangles[YAW];
00594 }
00595 #endif
00596
00597
00598
00599
00600 }
00601
00602 #ifdef QAGAME
00603
00604 extern void PM_SetAnim(pmove_t *pm,int setAnimParts,int anim,int setAnimFlags, int blendTime);
00605 extern int PM_AnimLength( int index, animNumber_t anim );
00606
00607
00608 void AnimateVehicle( Vehicle_t *pVeh )
00609 {
00610 }
00611
00612 #endif //QAGAME
00613
00614
00615
00616 #ifndef _JK2MP
00617 extern void CG_ChangeWeapon( int num );
00618 #endif
00619
00620
00621 #ifndef _JK2MP
00622 extern void G_StartMatrixEffect( gentity_t *ent, int meFlags = 0, int length = 1000, float timeScale = 0.0f, int spinTime = 0 );
00623 #endif
00624
00625
00626
00627
00628
00629
00630 void AnimateRiders( Vehicle_t *pVeh )
00631 {
00632 animNumber_t Anim = BOTH_VS_IDLE;
00633 float fSpeedPercToMax;
00634 int iFlags = SETANIM_FLAG_NORMAL, iBlend = 300;
00635 playerState_t *pilotPS;
00636 playerState_t *parentPS;
00637 int curTime;
00638
00639
00640
00641 if ( pVeh->m_iBoarding != 0 )
00642 {
00643
00644 if ( pVeh->m_iBoarding < 0 )
00645 {
00646 int iAnimLen;
00647
00648
00649 if ( pVeh->m_iBoarding == -1 )
00650 {
00651 Anim = BOTH_VS_MOUNT_L;
00652 }
00653 else if ( pVeh->m_iBoarding == -2 )
00654 {
00655 Anim = BOTH_VS_MOUNT_R;
00656 }
00657 else if ( pVeh->m_iBoarding == -3 )
00658 {
00659 Anim = BOTH_VS_MOUNTJUMP_L;
00660 }
00661 else if ( pVeh->m_iBoarding == VEH_MOUNT_THROW_LEFT)
00662 {
00663 iBlend = 0;
00664 Anim = BOTH_VS_MOUNTTHROW_R;
00665 }
00666 else if ( pVeh->m_iBoarding == VEH_MOUNT_THROW_RIGHT)
00667 {
00668 iBlend = 0;
00669 Anim = BOTH_VS_MOUNTTHROW_L;
00670 }
00671
00672
00673
00674 #ifdef _JK2MP
00675 iAnimLen = BG_AnimLength( pVeh->m_pPilot->localAnimIndex, Anim ) * 0.4f;
00676 pVeh->m_iBoarding = BG_GetTime() + iAnimLen;
00677 #else
00678 iAnimLen = PM_AnimLength( pVeh->m_pPilot->client->clientInfo.animFileIndex, Anim );
00679 if (pVeh->m_iBoarding!=VEH_MOUNT_THROW_LEFT && pVeh->m_iBoarding!=VEH_MOUNT_THROW_RIGHT)
00680 {
00681 pVeh->m_iBoarding = level.time + (iAnimLen*0.4f);
00682 }
00683 else
00684 {
00685 pVeh->m_iBoarding = level.time + iAnimLen;
00686 }
00687 #endif
00688
00689
00690 iFlags = SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD;
00691
00692 #ifdef _JK2MP
00693 BG_SetAnim(pVeh->m_pPilot->playerState, bgAllAnims[pVeh->m_pPilot->localAnimIndex].anims,
00694 SETANIM_BOTH, Anim, iFlags, iBlend);
00695 #else
00696 NPC_SetAnim( pVeh->m_pPilot, SETANIM_BOTH, Anim, iFlags, iBlend );
00697 if (pVeh->m_pOldPilot)
00698 {
00699 iAnimLen = PM_AnimLength( pVeh->m_pPilot->client->clientInfo.animFileIndex, BOTH_VS_MOUNTTHROWEE);
00700 NPC_SetAnim( pVeh->m_pOldPilot, SETANIM_BOTH, BOTH_VS_MOUNTTHROWEE, iFlags, iBlend );
00701 }
00702 #endif
00703 }
00704
00705 #ifndef _JK2MP
00706 if (pVeh->m_pOldPilot && pVeh->m_pOldPilot->client->ps.torsoAnimTimer<=0)
00707 {
00708 if (Q_irand(0, player->count)==0)
00709 {
00710 player->count++;
00711 player->lastEnemy = pVeh->m_pOldPilot;
00712 G_StartMatrixEffect(player, MEF_LOOK_AT_ENEMY|MEF_NO_RANGEVAR|MEF_NO_VERTBOB|MEF_NO_SPIN, 1000);
00713 }
00714
00715 gentity_t* oldPilot = pVeh->m_pOldPilot;
00716 pVeh->m_pVehicleInfo->Eject(pVeh, pVeh->m_pOldPilot, qtrue);
00717
00718
00719
00720 oldPilot->client->noRagTime = -1;
00721 G_Damage(oldPilot, pVeh->m_pPilot, pVeh->m_pPilot, pVeh->m_pPilot->currentAngles, pVeh->m_pPilot->currentOrigin, 1000, 0, MOD_CRUSH);
00722
00723
00724
00725 vec3_t throwDir;
00726 VectorScale(pVeh->m_pParentEntity->client->ps.velocity, -1.0f, throwDir);
00727 VectorNormalize(throwDir);
00728 throwDir[2] += 0.3f;
00729
00730
00731
00732 G_Throw(oldPilot, throwDir, VectorLength(pVeh->m_pParentEntity->client->ps.velocity)/10.0f);
00733 NPC_SetAnim(oldPilot, SETANIM_BOTH, BOTH_DEATHBACKWARD1, SETANIM_FLAG_OVERRIDE, iBlend );
00734 }
00735 #endif
00736
00737 return;
00738 }
00739
00740 #ifdef _JK2MP //fixme
00741 if (1) return;
00742 #endif
00743
00744 #ifdef _JK2MP
00745 pilotPS = pVeh->m_pPilot->playerState;
00746 parentPS = pVeh->m_pPilot->playerState;
00747 #else
00748 pilotPS = &pVeh->m_pPilot->client->ps;
00749 parentPS = &pVeh->m_pParentEntity->client->ps;
00750 #endif
00751
00752 #ifndef _JK2MP//SP
00753 curTime = level.time;
00754 #elif QAGAME//MP GAME
00755 curTime = level.time;
00756 #elif CGAME//MP CGAME
00757
00758 curTime = pm->cmd.serverTime;
00759 #endif
00760
00761
00762 fSpeedPercToMax = parentPS->speed / pVeh->m_pVehicleInfo->speedMax;
00763
00764
00765 #ifdef _JK2MP
00766 if ( pVeh->m_ucmd.forwardmove < 0 && !(pVeh->m_ulFlags & VEH_SLIDEBREAKING))
00767 #else
00768 if ( fSpeedPercToMax < -0.018f && !(pVeh->m_ulFlags & VEH_SLIDEBREAKING))
00769 #endif
00770 {
00771 Anim = BOTH_VS_REV;
00772 iBlend = 500;
00773 }
00774 else
00775 {
00776 bool HasWeapon = ((pilotPS->weapon != WP_NONE) && (pilotPS->weapon != WP_MELEE));
00777 bool Attacking = (HasWeapon && !!(pVeh->m_ucmd.buttons&BUTTON_ATTACK));
00778 #ifdef _JK2MP //fixme: flying tends to spaz out a lot
00779 bool Flying = false;
00780 bool Crashing = false;
00781 #else
00782 bool Flying = !!(pVeh->m_ulFlags & VEH_FLYING);
00783 bool Crashing = !!(pVeh->m_ulFlags & VEH_CRASHING);
00784 #endif
00785 bool Right = (pVeh->m_ucmd.rightmove>0);
00786 bool Left = (pVeh->m_ucmd.rightmove<0);
00787 bool Turbo = (curTime<pVeh->m_iTurboTime);
00788 EWeaponPose WeaponPose = WPOSE_NONE;
00789
00790
00791
00792
00793 pVeh->m_ulFlags &= ~VEH_CRASHING;
00794
00795
00796
00797
00798 #ifndef _JK2MP
00799 if (HasWeapon && (Turbo || (pilotPS->weapon==WP_SABER && !pilotPS->SaberActive())))
00800 {
00801 if (pVeh->m_pPilot->s.number<MAX_CLIENTS)
00802 {
00803 CG_ChangeWeapon(WP_NONE);
00804 }
00805
00806 pVeh->m_pPilot->client->ps.weapon = WP_NONE;
00807 G_RemoveWeaponModels(pVeh->m_pPilot);
00808 }
00809 #endif
00810
00811
00812
00813 #ifdef _JK2MP
00814 if (pilotPS->weaponTime>0)
00815 {
00816 return;
00817 }
00818 #else
00819 if (pilotPS->torsoAnim>=BOTH_VS_ATL_S && pilotPS->torsoAnim<=BOTH_VS_ATF_G)
00820 {
00821 float bodyCurrent = 0.0f;
00822 int bodyEnd = 0;
00823 if (!!gi.G2API_GetBoneAnimIndex(&pVeh->m_pPilot->ghoul2[pVeh->m_pPilot->playerModel], pVeh->m_pPilot->rootBone, level.time, &bodyCurrent, NULL, &bodyEnd, NULL, NULL, NULL))
00824 {
00825 if (bodyCurrent<=((float)(bodyEnd)-1.5f))
00826 {
00827 return;
00828 }
00829 }
00830 }
00831 #endif
00832
00833
00834
00835 if (pilotPS->weapon==WP_BLASTER)
00836 {
00837 WeaponPose = WPOSE_BLASTER;
00838 }
00839 else if (pilotPS->weapon==WP_SABER)
00840 {
00841 if ( (pVeh->m_ulFlags&VEH_SABERINLEFTHAND) && pilotPS->torsoAnim==BOTH_VS_ATL_TO_R_S)
00842 {
00843 pVeh->m_ulFlags &= ~VEH_SABERINLEFTHAND;
00844 }
00845 if (!(pVeh->m_ulFlags&VEH_SABERINLEFTHAND) && pilotPS->torsoAnim==BOTH_VS_ATR_TO_L_S)
00846 {
00847 pVeh->m_ulFlags |= VEH_SABERINLEFTHAND;
00848 }
00849 WeaponPose = (pVeh->m_ulFlags&VEH_SABERINLEFTHAND)?(WPOSE_SABERLEFT):(WPOSE_SABERRIGHT);
00850 }
00851
00852
00853 if (Attacking && WeaponPose)
00854 {
00855 iBlend = 100;
00856 iFlags = SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD|SETANIM_FLAG_RESTART;
00857
00858
00859
00860 if (!Left && !Right)
00861 {
00862 #ifndef _JK2MP
00863 if (pVeh->m_pPilot->enemy)
00864 {
00865 vec3_t toEnemy;
00866 float toEnemyDistance;
00867 vec3_t actorRight;
00868 float actorRightDot;
00869
00870 VectorSubtract(pVeh->m_pPilot->currentOrigin, pVeh->m_pPilot->enemy->currentOrigin, toEnemy);
00871 toEnemyDistance = VectorNormalize(toEnemy);
00872
00873 AngleVectors(pVeh->m_pParentEntity->currentAngles, 0, actorRight, 0);
00874 actorRightDot = DotProduct(toEnemy, actorRight);
00875
00876 if (fabsf(actorRightDot)>0.5f || pilotPS->weapon==WP_SABER)
00877 {
00878 Left = (actorRightDot>0.0f);
00879 Right = !Left;
00880 }
00881 else
00882 {
00883 Right = Left = false;
00884 }
00885 }
00886 else
00887 #endif
00888 if (pilotPS->weapon==WP_SABER && !Left && !Right)
00889 {
00890 Left = (WeaponPose==WPOSE_SABERLEFT);
00891 Right = !Left;
00892 }
00893 }
00894
00895
00896 if (Left)
00897 {
00898 switch(WeaponPose)
00899 {
00900 case WPOSE_BLASTER: Anim = BOTH_VS_ATL_G; break;
00901 case WPOSE_SABERLEFT: Anim = BOTH_VS_ATL_S; break;
00902 case WPOSE_SABERRIGHT: Anim = BOTH_VS_ATR_TO_L_S; break;
00903 default: assert(0);
00904 }
00905 }
00906 else if (Right)
00907 {
00908 switch(WeaponPose)
00909 {
00910 case WPOSE_BLASTER: Anim = BOTH_VS_ATR_G; break;
00911 case WPOSE_SABERLEFT: Anim = BOTH_VS_ATL_TO_R_S; break;
00912 case WPOSE_SABERRIGHT: Anim = BOTH_VS_ATR_S; break;
00913 default: assert(0);
00914 }
00915 }
00916 else
00917 {
00918 switch(WeaponPose)
00919 {
00920 case WPOSE_BLASTER: Anim = BOTH_VS_ATF_G; break;
00921 default: assert(0);
00922 }
00923 }
00924
00925 }
00926 else if (Left && pVeh->m_ucmd.buttons&BUTTON_USE)
00927 {
00928 iBlend = 400;
00929 iFlags = SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD;
00930 switch(WeaponPose)
00931 {
00932 case WPOSE_SABERLEFT: Anim = BOTH_VS_IDLE_SL; break;
00933 case WPOSE_SABERRIGHT: Anim = BOTH_VS_IDLE_SR; break;
00934 default: Anim = BOTH_VS_LOOKLEFT;
00935 }
00936 }
00937 else if (Right && pVeh->m_ucmd.buttons&BUTTON_USE)
00938 {
00939 iBlend = 400;
00940 iFlags = SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD;
00941 switch(WeaponPose)
00942 {
00943 case WPOSE_SABERLEFT: Anim = BOTH_VS_IDLE_SL; break;
00944 case WPOSE_SABERRIGHT: Anim = BOTH_VS_IDLE_SR; break;
00945 default: Anim = BOTH_VS_LOOKRIGHT;
00946 }
00947 }
00948 else if (Turbo)
00949 {
00950 iBlend = 50;
00951 iFlags = SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLDLESS;
00952 Anim = BOTH_VS_TURBO;
00953 }
00954 else if (Flying)
00955 {
00956 iBlend = 800;
00957 iFlags = SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD;
00958
00959 switch(WeaponPose)
00960 {
00961 case WPOSE_NONE: Anim = BOTH_VS_AIR; break;
00962 case WPOSE_BLASTER: Anim = BOTH_VS_AIR_G; break;
00963 case WPOSE_SABERLEFT: Anim = BOTH_VS_AIR_SL; break;
00964 case WPOSE_SABERRIGHT: Anim = BOTH_VS_AIR_SR; break;
00965 default: assert(0);
00966 }
00967 }
00968 else if (Crashing)
00969 {
00970 iBlend = 100;
00971 iFlags = SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLDLESS;
00972
00973 switch(WeaponPose)
00974 {
00975 case WPOSE_NONE: Anim = BOTH_VS_LAND; break;
00976 case WPOSE_BLASTER: Anim = BOTH_VS_LAND_G; break;
00977 case WPOSE_SABERLEFT: Anim = BOTH_VS_LAND_SL; break;
00978 case WPOSE_SABERRIGHT: Anim = BOTH_VS_LAND_SR; break;
00979 default: assert(0);
00980 }
00981 }
00982 else
00983 {
00984 iBlend = 300;
00985 iFlags = SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLDLESS;
00986
00987 if (pVeh->m_vOrientation[ROLL] <= -20)
00988 {
00989 switch(WeaponPose)
00990 {
00991 case WPOSE_NONE: Anim = BOTH_VS_LEANL; break;
00992 case WPOSE_BLASTER: Anim = BOTH_VS_LEANL_G; break;
00993 case WPOSE_SABERLEFT: Anim = BOTH_VS_LEANL_SL; break;
00994 case WPOSE_SABERRIGHT: Anim = BOTH_VS_LEANL_SR; break;
00995 default: assert(0);
00996 }
00997 }
00998 else if (pVeh->m_vOrientation[ROLL] >= 20)
00999 {
01000 switch(WeaponPose)
01001 {
01002 case WPOSE_NONE: Anim = BOTH_VS_LEANR; break;
01003 case WPOSE_BLASTER: Anim = BOTH_VS_LEANR_G; break;
01004 case WPOSE_SABERLEFT: Anim = BOTH_VS_LEANR_SL; break;
01005 case WPOSE_SABERRIGHT: Anim = BOTH_VS_LEANR_SR; break;
01006 default: assert(0);
01007 }
01008 }
01009 else
01010 {
01011 switch(WeaponPose)
01012 {
01013 case WPOSE_NONE: Anim = BOTH_VS_IDLE; break;
01014 case WPOSE_BLASTER: Anim = BOTH_VS_IDLE_G; break;
01015 case WPOSE_SABERLEFT: Anim = BOTH_VS_IDLE_SL; break;
01016 case WPOSE_SABERRIGHT: Anim = BOTH_VS_IDLE_SR; break;
01017 default: assert(0);
01018 }
01019 }
01020 }
01021 }
01022
01023 #ifdef _JK2MP
01024 iFlags &= ~SETANIM_FLAG_OVERRIDE;
01025 if (pVeh->m_pPilot->playerState->torsoAnim == Anim)
01026 {
01027 pVeh->m_pPilot->playerState->torsoTimer = BG_AnimLength(pVeh->m_pPilot->localAnimIndex, Anim);
01028 }
01029 if (pVeh->m_pPilot->playerState->legsAnim == Anim)
01030 {
01031 pVeh->m_pPilot->playerState->legsTimer = BG_AnimLength(pVeh->m_pPilot->localAnimIndex, Anim);
01032 }
01033 BG_SetAnim(pVeh->m_pPilot->playerState, bgAllAnims[pVeh->m_pPilot->localAnimIndex].anims,
01034 SETANIM_BOTH, Anim, iFlags|SETANIM_FLAG_HOLD, iBlend);
01035 #else
01036 NPC_SetAnim( pVeh->m_pPilot, SETANIM_BOTH, Anim, iFlags, iBlend );
01037 #endif
01038 }
01039
01040 #ifndef QAGAME
01041 void AttachRidersGeneric( Vehicle_t *pVeh );
01042 #endif
01043
01044 void G_SetSpeederVehicleFunctions( vehicleInfo_t *pVehInfo )
01045 {
01046 #ifdef QAGAME
01047 pVehInfo->AnimateVehicle = AnimateVehicle;
01048 pVehInfo->AnimateRiders = AnimateRiders;
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061 pVehInfo->Update = Update;
01062
01063 #endif
01064
01065
01066 pVehInfo->ProcessMoveCommands = ProcessMoveCommands;
01067 pVehInfo->ProcessOrientCommands = ProcessOrientCommands;
01068
01069 #ifndef QAGAME //cgame prediction attachment func
01070 pVehInfo->AttachRiders = AttachRidersGeneric;
01071 #endif
01072
01073
01074
01075
01076 }
01077
01078
01079 #ifdef _JK2MP
01080 #include "../namespace_end.h"
01081 #endif
01082
01083 #ifdef QAGAME
01084 extern void G_AllocateVehicleObject(Vehicle_t **pVeh);
01085 #endif
01086
01087 #ifdef _JK2MP
01088 #include "../namespace_begin.h"
01089 #endif
01090
01091
01092 void G_CreateSpeederNPC( Vehicle_t **pVeh, const char *strType )
01093 {
01094 #ifdef _JK2MP
01095 #ifdef QAGAME
01096
01097
01098
01099 G_AllocateVehicleObject(pVeh);
01100 #else
01101 if (!*pVeh)
01102 {
01103 (*pVeh) = (Vehicle_t *) BG_Alloc( sizeof(Vehicle_t) );
01104 }
01105 #endif
01106 memset(*pVeh, 0, sizeof(Vehicle_t));
01107 (*pVeh)->m_pVehicleInfo = &g_vehicleInfo[BG_VehicleGetIndex( strType )];
01108 #else
01109
01110 (*pVeh) = (Vehicle_t *) gi.Malloc( sizeof(Vehicle_t), TAG_G_ALLOC, qtrue );
01111 (*pVeh)->m_pVehicleInfo = &g_vehicleInfo[BG_VehicleGetIndex( strType )];
01112 #endif
01113 }
01114
01115 #ifdef _JK2MP
01116
01117 #include "../namespace_end.h"
01118
01119
01120 #undef currentAngles
01121 #undef currentOrigin
01122 #undef mins
01123 #undef maxs
01124 #undef legsAnimTimer
01125 #undef torsoAnimTimer
01126 #undef bool
01127 #undef false
01128 #undef true
01129
01130 #undef sqrtf
01131 #undef Q_flrand
01132
01133 #undef MOD_EXPLOSIVE
01134 #endif