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 #ifdef QAGAME //we only want a few of these functions for BG
00072
00073 extern float DotToSpot( vec3_t spot, vec3_t from, vec3_t fromAngles );
00074 extern vmCvar_t cg_thirdPersonAlpha;
00075 extern vec3_t playerMins;
00076 extern vec3_t playerMaxs;
00077 extern cvar_t *g_speederControlScheme;
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 Vehicle_SetAnim(gentity_t *ent,int setAnimParts,int anim,int setAnimFlags, int iBlend);
00081 extern void G_Knockdown( gentity_t *self, gentity_t *attacker, const vec3_t pushDir, float strength, qboolean breakSaberLock );
00082 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 );
00083
00084 static void RegisterAssets( Vehicle_t *pVeh )
00085 {
00086
00087 #ifdef _JK2MP
00088 RegisterItem(BG_FindItemForWeapon(WP_TURRET));
00089 #else
00090
00091 #endif
00092
00093
00094 g_vehicleInfo[VEHICLE_BASE].RegisterAssets( pVeh );
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 static bool Board( Vehicle_t *pVeh, bgEntity_t *pEnt )
00107 {
00108 if ( !g_vehicleInfo[VEHICLE_BASE].Board( pVeh, pEnt ) )
00109 return false;
00110
00111
00112 pVeh->m_iBoarding = level.time + 1500;
00113
00114 return true;
00115 }
00116 #endif //QAGAME
00117
00118 #ifdef _JK2MP
00119 #include "../namespace_begin.h"
00120 #endif
00121
00122
00123
00124
00125
00126
00127
00128
00129 static void ProcessMoveCommands( Vehicle_t *pVeh )
00130 {
00131
00132
00133
00134
00135
00136 float speedInc, speedIdleDec, speedIdle, speedIdleAccel, speedMin, speedMax;
00137 float fWalkSpeedMax;
00138 bgEntity_t *parent = pVeh->m_pParentEntity;
00139 #ifdef _JK2MP
00140 playerState_t *parentPS = parent->playerState;
00141 #else
00142 playerState_t *parentPS = &parent->client->ps;
00143 #endif
00144
00145 speedIdleDec = pVeh->m_pVehicleInfo->decelIdle * pVeh->m_fTimeModifier;
00146 speedMax = pVeh->m_pVehicleInfo->speedMax;
00147
00148 speedIdle = pVeh->m_pVehicleInfo->speedIdle;
00149 speedIdleAccel = pVeh->m_pVehicleInfo->accelIdle * pVeh->m_fTimeModifier;
00150 speedMin = pVeh->m_pVehicleInfo->speedMin;
00151
00152 #ifdef _JK2MP
00153 if ( !parentPS->m_iVehicleNum )
00154 #else
00155 if ( !pVeh->m_pVehicleInfo->Inhabited( pVeh ) )
00156 #endif
00157 {
00158 speedInc = speedIdle * pVeh->m_fTimeModifier;
00159 VectorClear( parentPS->moveDir );
00160
00161 parentPS->speed = 0;
00162 }
00163 else
00164 {
00165 speedInc = pVeh->m_pVehicleInfo->acceleration * pVeh->m_fTimeModifier;
00166 }
00167
00168 if ( parentPS->speed || parentPS->groundEntityNum == ENTITYNUM_NONE ||
00169 pVeh->m_ucmd.forwardmove || pVeh->m_ucmd.upmove > 0 )
00170 {
00171 if ( pVeh->m_ucmd.forwardmove > 0 && speedInc )
00172 {
00173 parentPS->speed += speedInc;
00174 }
00175 else if ( pVeh->m_ucmd.forwardmove < 0 )
00176 {
00177 if ( parentPS->speed > speedIdle )
00178 {
00179 parentPS->speed -= speedInc;
00180 }
00181 else if ( parentPS->speed > speedMin )
00182 {
00183 parentPS->speed -= speedIdleDec;
00184 }
00185 }
00186
00187 else if ( parentPS->speed > 0.0f )
00188 {
00189 parentPS->speed -= speedIdleDec;
00190 if ( parentPS->speed < 0.0f )
00191 {
00192 parentPS->speed = 0.0f;
00193 }
00194 }
00195 else if ( parentPS->speed < 0.0f )
00196 {
00197 parentPS->speed += speedIdleDec;
00198 if ( parentPS->speed > 0.0f )
00199 {
00200 parentPS->speed = 0.0f;
00201 }
00202 }
00203 }
00204 else
00205 {
00206 if ( pVeh->m_ucmd.forwardmove < 0 )
00207 {
00208 pVeh->m_ucmd.forwardmove = 0;
00209 }
00210 if ( pVeh->m_ucmd.upmove < 0 )
00211 {
00212 pVeh->m_ucmd.upmove = 0;
00213 }
00214
00215 pVeh->m_ucmd.rightmove = 0;
00216
00217
00218
00219
00220
00221
00222 }
00223
00224 if (parentPS && parentPS->electrifyTime > pm->cmd.serverTime)
00225 {
00226 speedMax *= 0.5f;
00227 }
00228
00229 fWalkSpeedMax = speedMax * 0.275f;
00230 if ( pVeh->m_ucmd.buttons & BUTTON_WALKING && parentPS->speed > fWalkSpeedMax )
00231 {
00232 parentPS->speed = fWalkSpeedMax;
00233 }
00234 else if ( parentPS->speed > speedMax )
00235 {
00236 parentPS->speed = speedMax;
00237 }
00238 else if ( parentPS->speed < speedMin )
00239 {
00240 parentPS->speed = speedMin;
00241 }
00242
00243 if (parentPS->stats[STAT_HEALTH] <= 0)
00244 {
00245 parentPS->speed = 0;
00246 }
00247
00248
00249
00250
00251 }
00252
00253 #ifdef _JK2MP
00254 void WalkerYawAdjust(Vehicle_t *pVeh, playerState_t *riderPS, playerState_t *parentPS)
00255 {
00256 float angDif = AngleSubtract(pVeh->m_vOrientation[YAW], riderPS->viewangles[YAW]);
00257
00258 if (parentPS && parentPS->speed)
00259 {
00260 float s = parentPS->speed;
00261 float maxDif = pVeh->m_pVehicleInfo->turningSpeed*1.5f;
00262
00263 if (s < 0.0f)
00264 {
00265 s = -s;
00266 }
00267 angDif *= s/pVeh->m_pVehicleInfo->speedMax;
00268 if (angDif > maxDif)
00269 {
00270 angDif = maxDif;
00271 }
00272 else if (angDif < -maxDif)
00273 {
00274 angDif = -maxDif;
00275 }
00276 pVeh->m_vOrientation[YAW] = AngleNormalize180(pVeh->m_vOrientation[YAW] - angDif*(pVeh->m_fTimeModifier*0.2f));
00277 }
00278 }
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 #endif
00308
00309
00310
00311
00312
00313
00314
00315
00316 static void ProcessOrientCommands( Vehicle_t *pVeh )
00317 {
00318
00319
00320
00321 float speed;
00322 bgEntity_t *parent = pVeh->m_pParentEntity;
00323 playerState_t *parentPS, *riderPS;
00324
00325 #ifdef _JK2MP
00326 bgEntity_t *rider = NULL;
00327 if (parent->s.owner != ENTITYNUM_NONE)
00328 {
00329 rider = PM_BGEntForNum(parent->s.owner);
00330 }
00331 #else
00332 gentity_t *rider = parent->owner;
00333 #endif
00334
00335 #ifdef _JK2MP
00336 if ( !rider )
00337 #else
00338 if ( !rider || !rider->client )
00339 #endif
00340 {
00341 rider = parent;
00342 }
00343
00344 #ifdef _JK2MP
00345 parentPS = parent->playerState;
00346 riderPS = rider->playerState;
00347 #else
00348 parentPS = &parent->client->ps;
00349 riderPS = &rider->client->ps;
00350 #endif
00351
00352 speed = VectorLength( parentPS->velocity );
00353
00354
00355 if ( rider->s.number < MAX_CLIENTS )
00356 {
00357 #ifdef _JK2MP
00358 WalkerYawAdjust(pVeh, riderPS, parentPS);
00359
00360 pVeh->m_vOrientation[PITCH] = riderPS->viewangles[PITCH];
00361 #else
00362 pVeh->m_vOrientation[YAW] = riderPS->viewangles[YAW];
00363 pVeh->m_vOrientation[PITCH] = riderPS->viewangles[PITCH];
00364 #endif
00365 }
00366 else
00367 {
00368 float turnSpeed = pVeh->m_pVehicleInfo->turningSpeed;
00369 if ( !pVeh->m_pVehicleInfo->turnWhenStopped
00370 && !parentPS->speed )
00371 {
00372
00373 turnSpeed = 0.0f;
00374 }
00375 #ifdef _JK2MP
00376 if (rider->s.eType == ET_NPC)
00377 #else
00378 if ( !rider || rider->NPC )
00379 #endif
00380 {
00381 turnSpeed *= 2.0f;
00382 #ifdef _JK2MP
00383 if (parentPS->speed > 200.0f)
00384 #else
00385 if ( parent->client->ps.speed > 200.0f )
00386 #endif
00387 {
00388 turnSpeed += turnSpeed * parentPS->speed/200.0f*0.05f;
00389 }
00390 }
00391 turnSpeed *= pVeh->m_fTimeModifier;
00392
00393
00394 if ( pVeh->m_ucmd.rightmove < 0 )
00395 {
00396 pVeh->m_vOrientation[YAW] += turnSpeed;
00397 }
00398 else if ( pVeh->m_ucmd.rightmove > 0 )
00399 {
00400 pVeh->m_vOrientation[YAW] -= turnSpeed;
00401 }
00402
00403 if ( pVeh->m_pVehicleInfo->malfunctionArmorLevel && pVeh->m_iArmor <= pVeh->m_pVehicleInfo->malfunctionArmorLevel )
00404 {
00405 }
00406 }
00407
00408
00409
00410
00411 }
00412
00413 #ifdef QAGAME //back to our game-only functions
00414
00415 static void AnimateVehicle( Vehicle_t *pVeh )
00416 {
00417 animNumber_t Anim = BOTH_STAND1;
00418 int iFlags = SETANIM_FLAG_NORMAL, iBlend = 300;
00419 gentity_t *parent = (gentity_t *)pVeh->m_pParentEntity;
00420 float fSpeedPercToMax;
00421
00422
00423 if ( parent->health <= 0 )
00424 {
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 return;
00436 }
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454 fSpeedPercToMax = parent->client->ps.speed / pVeh->m_pVehicleInfo->speedMax;
00455
00456
00457 if ( fSpeedPercToMax > 0.0f )
00458 {
00459 float fYawDelta;
00460
00461 iBlend = 300;
00462 iFlags = SETANIM_FLAG_OVERRIDE;
00463 fYawDelta = pVeh->m_vPrevOrientation[YAW] - pVeh->m_vOrientation[YAW];
00464
00465
00466
00467
00468
00469
00470 if ( ( pVeh->m_ucmd.buttons & BUTTON_WALKING ) || fSpeedPercToMax < 0.275f )
00471 {
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 {
00483 Anim = BOTH_WALK1;
00484 }
00485 }
00486
00487 else
00488 {
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499 {
00500 Anim = BOTH_RUN1;
00501 }
00502 }
00503 }
00504 else
00505 {
00506
00507 if ( fSpeedPercToMax < -0.018f )
00508 {
00509 iFlags = SETANIM_FLAG_NORMAL;
00510 Anim = BOTH_WALKBACK1;
00511 iBlend = 500;
00512 }
00513 else
00514 {
00515
00516
00517
00518 iFlags = SETANIM_FLAG_NORMAL | SETANIM_FLAG_RESTART | SETANIM_FLAG_HOLD;
00519 iBlend = 600;
00520 #ifdef _JK2MP
00521 if (parent->client->ps.m_iVehicleNum)
00522 #else
00523 if ( pVeh->m_pVehicleInfo->Inhabited( pVeh ) )
00524 #endif
00525 {
00526 Anim = BOTH_STAND1;
00527 }
00528 else
00529 {
00530 Anim = BOTH_STAND2;
00531 }
00532 }
00533 }
00534
00535 Vehicle_SetAnim( parent, SETANIM_LEGS, Anim, iFlags, iBlend );
00536 }
00537
00538
00539
00540 #endif //QAGAME
00541
00542 #ifndef QAGAME
00543 void AttachRidersGeneric( Vehicle_t *pVeh );
00544 #endif
00545
00546
00547 void G_SetWalkerVehicleFunctions( vehicleInfo_t *pVehInfo )
00548 {
00549 #ifdef QAGAME
00550 pVehInfo->AnimateVehicle = AnimateVehicle;
00551
00552
00553
00554
00555
00556
00557 pVehInfo->Board = Board;
00558
00559
00560
00561
00562 pVehInfo->RegisterAssets = RegisterAssets;
00563
00564
00565
00566 #endif //QAGAME
00567 pVehInfo->ProcessMoveCommands = ProcessMoveCommands;
00568 pVehInfo->ProcessOrientCommands = ProcessOrientCommands;
00569
00570 #ifndef QAGAME //cgame prediction attachment func
00571 pVehInfo->AttachRiders = AttachRidersGeneric;
00572 #endif
00573
00574
00575
00576
00577 }
00578
00579
00580 #ifdef _JK2MP
00581 #include "../namespace_end.h"
00582 #endif
00583
00584 #ifdef QAGAME
00585 extern void G_AllocateVehicleObject(Vehicle_t **pVeh);
00586 #endif
00587
00588 #ifdef _JK2MP
00589 #include "../namespace_begin.h"
00590 #endif
00591
00592
00593
00594 void G_CreateWalkerNPC( Vehicle_t **pVeh, const char *strAnimalType )
00595 {
00596
00597 #ifdef _JK2MP
00598 #ifdef QAGAME
00599
00600
00601
00602 G_AllocateVehicleObject(pVeh);
00603 #else
00604 if (!*pVeh)
00605 {
00606 (*pVeh) = (Vehicle_t *) BG_Alloc( sizeof(Vehicle_t) );
00607 }
00608 #endif
00609 memset(*pVeh, 0, sizeof(Vehicle_t));
00610 (*pVeh)->m_pVehicleInfo = &g_vehicleInfo[BG_VehicleGetIndex( strAnimalType )];
00611 #else
00612 (*pVeh) = (Vehicle_t *) gi.Malloc( sizeof(Vehicle_t), TAG_G_ALLOC, qtrue );
00613 (*pVeh)->m_pVehicleInfo = &g_vehicleInfo[BG_VehicleGetIndex( strAnimalType )];
00614 #endif
00615 }
00616
00617 #ifdef _JK2MP
00618
00619 #include "../namespace_end.h"
00620
00621
00622 #undef currentAngles
00623 #undef currentOrigin
00624 #undef mins
00625 #undef maxs
00626 #undef legsAnimTimer
00627 #undef torsoAnimTimer
00628 #undef bool
00629 #undef false
00630 #undef true
00631
00632 #undef sqrtf
00633 #undef Q_flrand
00634
00635 #undef MOD_EXPLOSIVE
00636 #endif