00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "cg_local.h"
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 void CG_PositionEntityOnTag( refEntity_t *entity, const refEntity_t *parent,
00037 qhandle_t parentModel, char *tagName ) {
00038 int i;
00039 orientation_t lerped;
00040
00041
00042 trap_R_LerpTag( &lerped, parentModel, parent->oldframe, parent->frame,
00043 1.0 - parent->backlerp, tagName );
00044
00045
00046 VectorCopy( parent->origin, entity->origin );
00047 for ( i = 0 ; i < 3 ; i++ ) {
00048 VectorMA( entity->origin, lerped.origin[i], parent->axis[i], entity->origin );
00049 }
00050
00051
00052 MatrixMultiply( lerped.axis, ((refEntity_t *)parent)->axis, entity->axis );
00053 entity->backlerp = parent->backlerp;
00054 }
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 void CG_PositionRotatedEntityOnTag( refEntity_t *entity, const refEntity_t *parent,
00066 qhandle_t parentModel, char *tagName ) {
00067 int i;
00068 orientation_t lerped;
00069 vec3_t tempAxis[3];
00070
00071
00072
00073 trap_R_LerpTag( &lerped, parentModel, parent->oldframe, parent->frame,
00074 1.0 - parent->backlerp, tagName );
00075
00076
00077 VectorCopy( parent->origin, entity->origin );
00078 for ( i = 0 ; i < 3 ; i++ ) {
00079 VectorMA( entity->origin, lerped.origin[i], parent->axis[i], entity->origin );
00080 }
00081
00082
00083 MatrixMultiply( entity->axis, lerped.axis, tempAxis );
00084 MatrixMultiply( tempAxis, ((refEntity_t *)parent)->axis, entity->axis );
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 void CG_SetEntitySoundPosition( centity_t *cent ) {
00105 if ( cent->currentState.solid == SOLID_BMODEL ) {
00106 vec3_t origin;
00107 float *v;
00108
00109 v = cgs.inlineModelMidpoints[ cent->currentState.modelindex ];
00110 VectorAdd( cent->lerpOrigin, v, origin );
00111 trap_S_UpdateEntityPosition( cent->currentState.number, origin );
00112 } else {
00113 trap_S_UpdateEntityPosition( cent->currentState.number, cent->lerpOrigin );
00114 }
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124 static void CG_EntityEffects( centity_t *cent ) {
00125
00126
00127 CG_SetEntitySoundPosition( cent );
00128
00129
00130 if ( cent->currentState.loopSound ) {
00131 if (cent->currentState.eType != ET_SPEAKER) {
00132 trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin,
00133 cgs.gameSounds[ cent->currentState.loopSound ] );
00134 } else {
00135 trap_S_AddRealLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin,
00136 cgs.gameSounds[ cent->currentState.loopSound ] );
00137 }
00138 }
00139
00140
00141
00142 if ( cent->currentState.constantLight ) {
00143 int cl;
00144 int i, r, g, b;
00145
00146 cl = cent->currentState.constantLight;
00147 r = cl & 255;
00148 g = ( cl >> 8 ) & 255;
00149 b = ( cl >> 16 ) & 255;
00150 i = ( ( cl >> 24 ) & 255 ) * 4;
00151 trap_R_AddLightToScene( cent->lerpOrigin, i, r, g, b );
00152 }
00153
00154 }
00155
00156
00157
00158
00159
00160
00161
00162 static void CG_General( centity_t *cent ) {
00163 refEntity_t ent;
00164 entityState_t *s1;
00165
00166 s1 = ¢->currentState;
00167
00168
00169 if (!s1->modelindex) {
00170 return;
00171 }
00172
00173 memset (&ent, 0, sizeof(ent));
00174
00175
00176
00177 ent.frame = s1->frame;
00178 ent.oldframe = ent.frame;
00179 ent.backlerp = 0;
00180
00181 VectorCopy( cent->lerpOrigin, ent.origin);
00182 VectorCopy( cent->lerpOrigin, ent.oldorigin);
00183
00184 ent.hModel = cgs.gameModels[s1->modelindex];
00185
00186
00187 if (s1->number == cg.snap->ps.clientNum) {
00188 ent.renderfx |= RF_THIRD_PERSON;
00189 }
00190
00191
00192 AnglesToAxis( cent->lerpAngles, ent.axis );
00193
00194
00195 trap_R_AddRefEntityToScene (&ent);
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205 static void CG_Speaker( centity_t *cent ) {
00206 if ( ! cent->currentState.clientNum ) {
00207 return;
00208 }
00209
00210 if ( cg.time < cent->miscTime ) {
00211 return;
00212 }
00213
00214 trap_S_StartSound (NULL, cent->currentState.number, CHAN_ITEM, cgs.gameSounds[cent->currentState.eventParm] );
00215
00216
00217
00218 cent->miscTime = cg.time + cent->currentState.frame * 100 + cent->currentState.clientNum * 100 * crandom();
00219 }
00220
00221
00222
00223
00224
00225
00226 static void CG_Item( centity_t *cent ) {
00227 refEntity_t ent;
00228 entityState_t *es;
00229 gitem_t *item;
00230 int msec;
00231 float frac;
00232 float scale;
00233 weaponInfo_t *wi;
00234
00235 es = ¢->currentState;
00236 if ( es->modelindex >= bg_numItems ) {
00237 CG_Error( "Bad item index %i on entity", es->modelindex );
00238 }
00239
00240
00241 if ( !es->modelindex || ( es->eFlags & EF_NODRAW ) ) {
00242 return;
00243 }
00244
00245 item = &bg_itemlist[ es->modelindex ];
00246 if ( cg_simpleItems.integer && item->giType != IT_TEAM ) {
00247 memset( &ent, 0, sizeof( ent ) );
00248 ent.reType = RT_SPRITE;
00249 VectorCopy( cent->lerpOrigin, ent.origin );
00250 ent.radius = 14;
00251 ent.customShader = cg_items[es->modelindex].icon;
00252 ent.shaderRGBA[0] = 255;
00253 ent.shaderRGBA[1] = 255;
00254 ent.shaderRGBA[2] = 255;
00255 ent.shaderRGBA[3] = 255;
00256 trap_R_AddRefEntityToScene(&ent);
00257 return;
00258 }
00259
00260
00261 scale = 0.005 + cent->currentState.number * 0.00001;
00262 cent->lerpOrigin[2] += 4 + cos( ( cg.time + 1000 ) * scale ) * 4;
00263
00264 memset (&ent, 0, sizeof(ent));
00265
00266
00267 if ( item->giType == IT_HEALTH ) {
00268 VectorCopy( cg.autoAnglesFast, cent->lerpAngles );
00269 AxisCopy( cg.autoAxisFast, ent.axis );
00270 } else {
00271 VectorCopy( cg.autoAngles, cent->lerpAngles );
00272 AxisCopy( cg.autoAxis, ent.axis );
00273 }
00274
00275 wi = NULL;
00276
00277
00278
00279 if ( item->giType == IT_WEAPON ) {
00280 wi = &cg_weapons[item->giTag];
00281 cent->lerpOrigin[0] -=
00282 wi->weaponMidpoint[0] * ent.axis[0][0] +
00283 wi->weaponMidpoint[1] * ent.axis[1][0] +
00284 wi->weaponMidpoint[2] * ent.axis[2][0];
00285 cent->lerpOrigin[1] -=
00286 wi->weaponMidpoint[0] * ent.axis[0][1] +
00287 wi->weaponMidpoint[1] * ent.axis[1][1] +
00288 wi->weaponMidpoint[2] * ent.axis[2][1];
00289 cent->lerpOrigin[2] -=
00290 wi->weaponMidpoint[0] * ent.axis[0][2] +
00291 wi->weaponMidpoint[1] * ent.axis[1][2] +
00292 wi->weaponMidpoint[2] * ent.axis[2][2];
00293
00294 cent->lerpOrigin[2] += 8;
00295 }
00296
00297 ent.hModel = cg_items[es->modelindex].models[0];
00298
00299 VectorCopy( cent->lerpOrigin, ent.origin);
00300 VectorCopy( cent->lerpOrigin, ent.oldorigin);
00301
00302 ent.nonNormalizedAxes = qfalse;
00303
00304
00305 msec = cg.time - cent->miscTime;
00306 if ( msec >= 0 && msec < ITEM_SCALEUP_TIME ) {
00307 frac = (float)msec / ITEM_SCALEUP_TIME;
00308 VectorScale( ent.axis[0], frac, ent.axis[0] );
00309 VectorScale( ent.axis[1], frac, ent.axis[1] );
00310 VectorScale( ent.axis[2], frac, ent.axis[2] );
00311 ent.nonNormalizedAxes = qtrue;
00312 } else {
00313 frac = 1.0;
00314 }
00315
00316
00317
00318 if ( ( item->giType == IT_WEAPON ) ||
00319 ( item->giType == IT_ARMOR ) ) {
00320 ent.renderfx |= RF_MINLIGHT;
00321 }
00322
00323
00324 if ( item->giType == IT_WEAPON ) {
00325 VectorScale( ent.axis[0], 1.5, ent.axis[0] );
00326 VectorScale( ent.axis[1], 1.5, ent.axis[1] );
00327 VectorScale( ent.axis[2], 1.5, ent.axis[2] );
00328 ent.nonNormalizedAxes = qtrue;
00329 #ifdef MISSIONPACK
00330 trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, cgs.media.weaponHoverSound );
00331 #endif
00332 }
00333
00334 #ifdef MISSIONPACK
00335 if ( item->giType == IT_HOLDABLE && item->giTag == HI_KAMIKAZE ) {
00336 VectorScale( ent.axis[0], 2, ent.axis[0] );
00337 VectorScale( ent.axis[1], 2, ent.axis[1] );
00338 VectorScale( ent.axis[2], 2, ent.axis[2] );
00339 ent.nonNormalizedAxes = qtrue;
00340 }
00341 #endif
00342
00343
00344 trap_R_AddRefEntityToScene(&ent);
00345
00346 #ifdef MISSIONPACK
00347 if ( item->giType == IT_WEAPON && wi->barrelModel ) {
00348 refEntity_t barrel;
00349
00350 memset( &barrel, 0, sizeof( barrel ) );
00351
00352 barrel.hModel = wi->barrelModel;
00353
00354 VectorCopy( ent.lightingOrigin, barrel.lightingOrigin );
00355 barrel.shadowPlane = ent.shadowPlane;
00356 barrel.renderfx = ent.renderfx;
00357
00358 CG_PositionRotatedEntityOnTag( &barrel, &ent, wi->weaponModel, "tag_barrel" );
00359
00360 AxisCopy( ent.axis, barrel.axis );
00361 barrel.nonNormalizedAxes = ent.nonNormalizedAxes;
00362
00363 trap_R_AddRefEntityToScene( &barrel );
00364 }
00365 #endif
00366
00367
00368 if ( !cg_simpleItems.integer )
00369 {
00370 vec3_t spinAngles;
00371
00372 VectorClear( spinAngles );
00373
00374 if ( item->giType == IT_HEALTH || item->giType == IT_POWERUP )
00375 {
00376 if ( ( ent.hModel = cg_items[es->modelindex].models[1] ) != 0 )
00377 {
00378 if ( item->giType == IT_POWERUP )
00379 {
00380 ent.origin[2] += 12;
00381 spinAngles[1] = ( cg.time & 1023 ) * 360 / -1024.0f;
00382 }
00383 AnglesToAxis( spinAngles, ent.axis );
00384
00385
00386 if ( frac != 1.0 ) {
00387 VectorScale( ent.axis[0], frac, ent.axis[0] );
00388 VectorScale( ent.axis[1], frac, ent.axis[1] );
00389 VectorScale( ent.axis[2], frac, ent.axis[2] );
00390 ent.nonNormalizedAxes = qtrue;
00391 }
00392 trap_R_AddRefEntityToScene( &ent );
00393 }
00394 }
00395 }
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405 static void CG_Missile( centity_t *cent ) {
00406 refEntity_t ent;
00407 entityState_t *s1;
00408 const weaponInfo_t *weapon;
00409
00410
00411 s1 = ¢->currentState;
00412 if ( s1->weapon > WP_NUM_WEAPONS ) {
00413 s1->weapon = 0;
00414 }
00415 weapon = &cg_weapons[s1->weapon];
00416
00417
00418 VectorCopy( s1->angles, cent->lerpAngles);
00419
00420
00421 if ( weapon->missileTrailFunc )
00422 {
00423 weapon->missileTrailFunc( cent, weapon );
00424 }
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443 if ( weapon->missileDlight ) {
00444 trap_R_AddLightToScene(cent->lerpOrigin, weapon->missileDlight,
00445 weapon->missileDlightColor[0], weapon->missileDlightColor[1], weapon->missileDlightColor[2] );
00446 }
00447
00448
00449 if ( weapon->missileSound ) {
00450 vec3_t velocity;
00451
00452 BG_EvaluateTrajectoryDelta( ¢->currentState.pos, cg.time, velocity );
00453
00454 trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, velocity, weapon->missileSound );
00455 }
00456
00457
00458 memset (&ent, 0, sizeof(ent));
00459 VectorCopy( cent->lerpOrigin, ent.origin);
00460 VectorCopy( cent->lerpOrigin, ent.oldorigin);
00461
00462 if ( cent->currentState.weapon == WP_PLASMAGUN ) {
00463 ent.reType = RT_SPRITE;
00464 ent.radius = 16;
00465 ent.rotation = 0;
00466 ent.customShader = cgs.media.plasmaBallShader;
00467 trap_R_AddRefEntityToScene( &ent );
00468 return;
00469 }
00470
00471
00472 ent.skinNum = cg.clientFrame & 1;
00473 ent.hModel = weapon->missileModel;
00474 ent.renderfx = weapon->missileRenderfx | RF_NOSHADOW;
00475
00476 #ifdef MISSIONPACK
00477 if ( cent->currentState.weapon == WP_PROX_LAUNCHER ) {
00478 if (s1->generic1 == TEAM_BLUE) {
00479 ent.hModel = cgs.media.blueProxMine;
00480 }
00481 }
00482 #endif
00483
00484
00485 if ( VectorNormalize2( s1->pos.trDelta, ent.axis[0] ) == 0 ) {
00486 ent.axis[0][2] = 1;
00487 }
00488
00489
00490 if ( s1->pos.trType != TR_STATIONARY ) {
00491 RotateAroundDirection( ent.axis, cg.time / 4 );
00492 } else {
00493 #ifdef MISSIONPACK
00494 if ( s1->weapon == WP_PROX_LAUNCHER ) {
00495 AnglesToAxis( cent->lerpAngles, ent.axis );
00496 }
00497 else
00498 #endif
00499 {
00500 RotateAroundDirection( ent.axis, s1->time );
00501 }
00502 }
00503
00504
00505 CG_AddRefEntityWithPowerups( &ent, s1, TEAM_FREE );
00506 }
00507
00508
00509
00510
00511
00512
00513
00514
00515 static void CG_Grapple( centity_t *cent ) {
00516 refEntity_t ent;
00517 entityState_t *s1;
00518 const weaponInfo_t *weapon;
00519
00520 s1 = ¢->currentState;
00521 if ( s1->weapon > WP_NUM_WEAPONS ) {
00522 s1->weapon = 0;
00523 }
00524 weapon = &cg_weapons[s1->weapon];
00525
00526
00527 VectorCopy( s1->angles, cent->lerpAngles);
00528
00529 #if 0 // FIXME add grapple pull sound here..?
00530
00531 if ( weapon->missileSound ) {
00532 trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, weapon->missileSound );
00533 }
00534 #endif
00535
00536
00537 CG_GrappleTrail ( cent, weapon );
00538
00539
00540 memset (&ent, 0, sizeof(ent));
00541 VectorCopy( cent->lerpOrigin, ent.origin);
00542 VectorCopy( cent->lerpOrigin, ent.oldorigin);
00543
00544
00545 ent.skinNum = cg.clientFrame & 1;
00546 ent.hModel = weapon->missileModel;
00547 ent.renderfx = weapon->missileRenderfx | RF_NOSHADOW;
00548
00549
00550 if ( VectorNormalize2( s1->pos.trDelta, ent.axis[0] ) == 0 ) {
00551 ent.axis[0][2] = 1;
00552 }
00553
00554 trap_R_AddRefEntityToScene( &ent );
00555 }
00556
00557
00558
00559
00560
00561
00562 static void CG_Mover( centity_t *cent ) {
00563 refEntity_t ent;
00564 entityState_t *s1;
00565
00566 s1 = ¢->currentState;
00567
00568
00569 memset (&ent, 0, sizeof(ent));
00570 VectorCopy( cent->lerpOrigin, ent.origin);
00571 VectorCopy( cent->lerpOrigin, ent.oldorigin);
00572 AnglesToAxis( cent->lerpAngles, ent.axis );
00573
00574 ent.renderfx = RF_NOSHADOW;
00575
00576
00577 ent.skinNum = ( cg.time >> 6 ) & 1;
00578
00579
00580 if ( s1->solid == SOLID_BMODEL ) {
00581 ent.hModel = cgs.inlineDrawModel[s1->modelindex];
00582 } else {
00583 ent.hModel = cgs.gameModels[s1->modelindex];
00584 }
00585
00586
00587 trap_R_AddRefEntityToScene(&ent);
00588
00589
00590 if ( s1->modelindex2 ) {
00591 ent.skinNum = 0;
00592 ent.hModel = cgs.gameModels[s1->modelindex2];
00593 trap_R_AddRefEntityToScene(&ent);
00594 }
00595
00596 }
00597
00598
00599
00600
00601
00602
00603
00604
00605 void CG_Beam( centity_t *cent ) {
00606 refEntity_t ent;
00607 entityState_t *s1;
00608
00609 s1 = ¢->currentState;
00610
00611
00612 memset (&ent, 0, sizeof(ent));
00613 VectorCopy( s1->pos.trBase, ent.origin );
00614 VectorCopy( s1->origin2, ent.oldorigin );
00615 AxisClear( ent.axis );
00616 ent.reType = RT_BEAM;
00617
00618 ent.renderfx = RF_NOSHADOW;
00619
00620
00621 trap_R_AddRefEntityToScene(&ent);
00622 }
00623
00624
00625
00626
00627
00628
00629
00630 static void CG_Portal( centity_t *cent ) {
00631 refEntity_t ent;
00632 entityState_t *s1;
00633
00634 s1 = ¢->currentState;
00635
00636
00637 memset (&ent, 0, sizeof(ent));
00638 VectorCopy( cent->lerpOrigin, ent.origin );
00639 VectorCopy( s1->origin2, ent.oldorigin );
00640 ByteToDir( s1->eventParm, ent.axis[0] );
00641 PerpendicularVector( ent.axis[1], ent.axis[0] );
00642
00643
00644
00645 VectorSubtract( vec3_origin, ent.axis[1], ent.axis[1] );
00646
00647 CrossProduct( ent.axis[0], ent.axis[1], ent.axis[2] );
00648 ent.reType = RT_PORTALSURFACE;
00649 ent.oldframe = s1->powerups;
00650 ent.frame = s1->frame;
00651 ent.skinNum = s1->clientNum/256.0 * 360;
00652
00653
00654 trap_R_AddRefEntityToScene(&ent);
00655 }
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665 void CG_AdjustPositionForMover( const vec3_t in, int moverNum, int fromTime, int toTime, vec3_t out ) {
00666 centity_t *cent;
00667 vec3_t oldOrigin, origin, deltaOrigin;
00668 vec3_t oldAngles, angles, deltaAngles;
00669
00670 if ( moverNum <= 0 || moverNum >= ENTITYNUM_MAX_NORMAL ) {
00671 VectorCopy( in, out );
00672 return;
00673 }
00674
00675 cent = &cg_entities[ moverNum ];
00676 if ( cent->currentState.eType != ET_MOVER ) {
00677 VectorCopy( in, out );
00678 return;
00679 }
00680
00681 BG_EvaluateTrajectory( ¢->currentState.pos, fromTime, oldOrigin );
00682 BG_EvaluateTrajectory( ¢->currentState.apos, fromTime, oldAngles );
00683
00684 BG_EvaluateTrajectory( ¢->currentState.pos, toTime, origin );
00685 BG_EvaluateTrajectory( ¢->currentState.apos, toTime, angles );
00686
00687 VectorSubtract( origin, oldOrigin, deltaOrigin );
00688 VectorSubtract( angles, oldAngles, deltaAngles );
00689
00690 VectorAdd( in, deltaOrigin, out );
00691
00692
00693 }
00694
00695
00696
00697
00698
00699
00700
00701 static void CG_InterpolateEntityPosition( centity_t *cent ) {
00702 vec3_t current, next;
00703 float f;
00704
00705
00706
00707 if ( cg.nextSnap == NULL ) {
00708 CG_Error( "CG_InterpoateEntityPosition: cg.nextSnap == NULL" );
00709 }
00710
00711 f = cg.frameInterpolation;
00712
00713
00714
00715 BG_EvaluateTrajectory( ¢->currentState.pos, cg.snap->serverTime, current );
00716 BG_EvaluateTrajectory( ¢->nextState.pos, cg.nextSnap->serverTime, next );
00717
00718 cent->lerpOrigin[0] = current[0] + f * ( next[0] - current[0] );
00719 cent->lerpOrigin[1] = current[1] + f * ( next[1] - current[1] );
00720 cent->lerpOrigin[2] = current[2] + f * ( next[2] - current[2] );
00721
00722 BG_EvaluateTrajectory( ¢->currentState.apos, cg.snap->serverTime, current );
00723 BG_EvaluateTrajectory( ¢->nextState.apos, cg.nextSnap->serverTime, next );
00724
00725 cent->lerpAngles[0] = LerpAngle( current[0], next[0], f );
00726 cent->lerpAngles[1] = LerpAngle( current[1], next[1], f );
00727 cent->lerpAngles[2] = LerpAngle( current[2], next[2], f );
00728
00729 }
00730
00731
00732
00733
00734
00735
00736
00737 static void CG_CalcEntityLerpPositions( centity_t *cent ) {
00738
00739
00740 if ( !cg_smoothClients.integer ) {
00741
00742 if ( cent->currentState.number < MAX_CLIENTS ) {
00743 cent->currentState.pos.trType = TR_INTERPOLATE;
00744 cent->nextState.pos.trType = TR_INTERPOLATE;
00745 }
00746 }
00747
00748 if ( cent->interpolate && cent->currentState.pos.trType == TR_INTERPOLATE ) {
00749 CG_InterpolateEntityPosition( cent );
00750 return;
00751 }
00752
00753
00754
00755 if ( cent->interpolate && cent->currentState.pos.trType == TR_LINEAR_STOP &&
00756 cent->currentState.number < MAX_CLIENTS) {
00757 CG_InterpolateEntityPosition( cent );
00758 return;
00759 }
00760
00761
00762 BG_EvaluateTrajectory( ¢->currentState.pos, cg.time, cent->lerpOrigin );
00763 BG_EvaluateTrajectory( ¢->currentState.apos, cg.time, cent->lerpAngles );
00764
00765
00766
00767 if ( cent != &cg.predictedPlayerEntity ) {
00768 CG_AdjustPositionForMover( cent->lerpOrigin, cent->currentState.groundEntityNum,
00769 cg.snap->serverTime, cg.time, cent->lerpOrigin );
00770 }
00771 }
00772
00773
00774
00775
00776
00777
00778 static void CG_TeamBase( centity_t *cent ) {
00779 refEntity_t model;
00780 #ifdef MISSIONPACK
00781 vec3_t angles;
00782 int t, h;
00783 float c;
00784
00785 if ( cgs.gametype == GT_CTF || cgs.gametype == GT_1FCTF ) {
00786 #else
00787 if ( cgs.gametype == GT_CTF) {
00788 #endif
00789
00790 memset(&model, 0, sizeof(model));
00791 model.reType = RT_MODEL;
00792 VectorCopy( cent->lerpOrigin, model.lightingOrigin );
00793 VectorCopy( cent->lerpOrigin, model.origin );
00794 AnglesToAxis( cent->currentState.angles, model.axis );
00795 if ( cent->currentState.modelindex == TEAM_RED ) {
00796 model.hModel = cgs.media.redFlagBaseModel;
00797 }
00798 else if ( cent->currentState.modelindex == TEAM_BLUE ) {
00799 model.hModel = cgs.media.blueFlagBaseModel;
00800 }
00801 else {
00802 model.hModel = cgs.media.neutralFlagBaseModel;
00803 }
00804 trap_R_AddRefEntityToScene( &model );
00805 }
00806 #ifdef MISSIONPACK
00807 else if ( cgs.gametype == GT_OBELISK ) {
00808
00809 memset(&model, 0, sizeof(model));
00810 model.reType = RT_MODEL;
00811 VectorCopy( cent->lerpOrigin, model.lightingOrigin );
00812 VectorCopy( cent->lerpOrigin, model.origin );
00813 AnglesToAxis( cent->currentState.angles, model.axis );
00814
00815 model.hModel = cgs.media.overloadBaseModel;
00816 trap_R_AddRefEntityToScene( &model );
00817
00818 if ( cent->currentState.frame == 1) {
00819
00820
00821 c = cent->currentState.modelindex2;
00822 model.shaderRGBA[0] = 0xff;
00823 model.shaderRGBA[1] = c;
00824 model.shaderRGBA[2] = c;
00825 model.shaderRGBA[3] = 0xff;
00826
00827 model.hModel = cgs.media.overloadEnergyModel;
00828 trap_R_AddRefEntityToScene( &model );
00829 }
00830
00831 if ( cent->currentState.frame == 2) {
00832 if ( !cent->miscTime ) {
00833 cent->miscTime = cg.time;
00834 }
00835 t = cg.time - cent->miscTime;
00836 h = (cg_obeliskRespawnDelay.integer - 5) * 1000;
00837
00838 if (t > h) {
00839 c = (float) (t - h) / h;
00840 if (c > 1)
00841 c = 1;
00842 }
00843 else {
00844 c = 0;
00845 }
00846
00847 AnglesToAxis( cent->currentState.angles, model.axis );
00848
00849 model.shaderRGBA[0] = c * 0xff;
00850 model.shaderRGBA[1] = c * 0xff;
00851 model.shaderRGBA[2] = c * 0xff;
00852 model.shaderRGBA[3] = c * 0xff;
00853
00854 model.hModel = cgs.media.overloadLightsModel;
00855 trap_R_AddRefEntityToScene( &model );
00856
00857 if (t > h) {
00858 if ( !cent->muzzleFlashTime ) {
00859 trap_S_StartSound (cent->lerpOrigin, ENTITYNUM_NONE, CHAN_BODY, cgs.media.obeliskRespawnSound);
00860 cent->muzzleFlashTime = 1;
00861 }
00862 VectorCopy(cent->currentState.angles, angles);
00863 angles[YAW] += (float) 16 * acos(1-c) * 180 / M_PI;
00864 AnglesToAxis( angles, model.axis );
00865
00866 VectorScale( model.axis[0], c, model.axis[0]);
00867 VectorScale( model.axis[1], c, model.axis[1]);
00868 VectorScale( model.axis[2], c, model.axis[2]);
00869
00870 model.shaderRGBA[0] = 0xff;
00871 model.shaderRGBA[1] = 0xff;
00872 model.shaderRGBA[2] = 0xff;
00873 model.shaderRGBA[3] = 0xff;
00874
00875 model.origin[2] += 56;
00876 model.hModel = cgs.media.overloadTargetModel;
00877 trap_R_AddRefEntityToScene( &model );
00878 }
00879 else {
00880
00881 }
00882 }
00883 else {
00884 cent->miscTime = 0;
00885 cent->muzzleFlashTime = 0;
00886
00887 c = cent->currentState.modelindex2;
00888 model.shaderRGBA[0] = 0xff;
00889 model.shaderRGBA[1] = c;
00890 model.shaderRGBA[2] = c;
00891 model.shaderRGBA[3] = 0xff;
00892
00893 model.hModel = cgs.media.overloadLightsModel;
00894 trap_R_AddRefEntityToScene( &model );
00895
00896 model.origin[2] += 56;
00897 model.hModel = cgs.media.overloadTargetModel;
00898 trap_R_AddRefEntityToScene( &model );
00899 }
00900 }
00901 else if ( cgs.gametype == GT_HARVESTER ) {
00902
00903 memset(&model, 0, sizeof(model));
00904 model.reType = RT_MODEL;
00905 VectorCopy( cent->lerpOrigin, model.lightingOrigin );
00906 VectorCopy( cent->lerpOrigin, model.origin );
00907 AnglesToAxis( cent->currentState.angles, model.axis );
00908
00909 if ( cent->currentState.modelindex == TEAM_RED ) {
00910 model.hModel = cgs.media.harvesterModel;
00911 model.customSkin = cgs.media.harvesterRedSkin;
00912 }
00913 else if ( cent->currentState.modelindex == TEAM_BLUE ) {
00914 model.hModel = cgs.media.harvesterModel;
00915 model.customSkin = cgs.media.harvesterBlueSkin;
00916 }
00917 else {
00918 model.hModel = cgs.media.harvesterNeutralModel;
00919 model.customSkin = 0;
00920 }
00921 trap_R_AddRefEntityToScene( &model );
00922 }
00923 #endif
00924 }
00925
00926
00927
00928
00929
00930
00931
00932 static void CG_AddCEntity( centity_t *cent ) {
00933
00934 if ( cent->currentState.eType >= ET_EVENTS ) {
00935 return;
00936 }
00937
00938
00939 CG_CalcEntityLerpPositions( cent );
00940
00941
00942 CG_EntityEffects( cent );
00943
00944 switch ( cent->currentState.eType ) {
00945 default:
00946 CG_Error( "Bad entity type: %i\n", cent->currentState.eType );
00947 break;
00948 case ET_INVISIBLE:
00949 case ET_PUSH_TRIGGER:
00950 case ET_TELEPORT_TRIGGER:
00951 break;
00952 case ET_GENERAL:
00953 CG_General( cent );
00954 break;
00955 case ET_PLAYER:
00956 CG_Player( cent );
00957 break;
00958 case ET_ITEM:
00959 CG_Item( cent );
00960 break;
00961 case ET_MISSILE:
00962 CG_Missile( cent );
00963 break;
00964 case ET_MOVER:
00965 CG_Mover( cent );
00966 break;
00967 case ET_BEAM:
00968 CG_Beam( cent );
00969 break;
00970 case ET_PORTAL:
00971 CG_Portal( cent );
00972 break;
00973 case ET_SPEAKER:
00974 CG_Speaker( cent );
00975 break;
00976 case ET_GRAPPLE:
00977 CG_Grapple( cent );
00978 break;
00979 case ET_TEAM:
00980 CG_TeamBase( cent );
00981 break;
00982 }
00983 }
00984
00985
00986
00987
00988
00989
00990
00991 void CG_AddPacketEntities( void ) {
00992 int num;
00993 centity_t *cent;
00994 playerState_t *ps;
00995
00996
00997 if ( cg.nextSnap ) {
00998 int delta;
00999
01000 delta = (cg.nextSnap->serverTime - cg.snap->serverTime);
01001 if ( delta == 0 ) {
01002 cg.frameInterpolation = 0;
01003 } else {
01004 cg.frameInterpolation = (float)( cg.time - cg.snap->serverTime ) / delta;
01005 }
01006 } else {
01007 cg.frameInterpolation = 0;
01008
01009 }
01010
01011
01012 cg.autoAngles[0] = 0;
01013 cg.autoAngles[1] = ( cg.time & 2047 ) * 360 / 2048.0;
01014 cg.autoAngles[2] = 0;
01015
01016 cg.autoAnglesFast[0] = 0;
01017 cg.autoAnglesFast[1] = ( cg.time & 1023 ) * 360 / 1024.0f;
01018 cg.autoAnglesFast[2] = 0;
01019
01020 AnglesToAxis( cg.autoAngles, cg.autoAxis );
01021 AnglesToAxis( cg.autoAnglesFast, cg.autoAxisFast );
01022
01023
01024 ps = &cg.predictedPlayerState;
01025 BG_PlayerStateToEntityState( ps, &cg.predictedPlayerEntity.currentState, qfalse );
01026 CG_AddCEntity( &cg.predictedPlayerEntity );
01027
01028
01029 CG_CalcEntityLerpPositions( &cg_entities[ cg.snap->ps.clientNum ] );
01030
01031
01032 for ( num = 0 ; num < cg.snap->numEntities ; num++ ) {
01033 cent = &cg_entities[ cg.snap->entities[ num ].number ];
01034 CG_AddCEntity( cent );
01035 }
01036 }
01037