00001
00002
00003
00004
00005 #include "cg_local.h"
00006
00007
00008
00009 #include "..\game\q_shared.h"
00010 #include "..\ghoul2\g2.h"
00011
00012
00013
00014
00015 extern qboolean CG_InFighter( void );
00016 static void CG_Missile( centity_t *cent );
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 void CG_PositionEntityOnTag( refEntity_t *entity, const refEntity_t *parent,
00027 qhandle_t parentModel, char *tagName ) {
00028 int i;
00029 orientation_t lerped;
00030
00031
00032 trap_R_LerpTag( &lerped, parentModel, parent->oldframe, parent->frame,
00033 1.0 - parent->backlerp, tagName );
00034
00035
00036 VectorCopy( parent->origin, entity->origin );
00037 for ( i = 0 ; i < 3 ; i++ ) {
00038 VectorMA( entity->origin, lerped.origin[i], parent->axis[i], entity->origin );
00039 }
00040
00041
00042 MatrixMultiply( lerped.axis, ((refEntity_t *)parent)->axis, entity->axis );
00043 entity->backlerp = parent->backlerp;
00044 }
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 void CG_PositionRotatedEntityOnTag( refEntity_t *entity, const refEntity_t *parent,
00056 qhandle_t parentModel, char *tagName ) {
00057 int i;
00058 orientation_t lerped;
00059 vec3_t tempAxis[3];
00060
00061
00062
00063 trap_R_LerpTag( &lerped, parentModel, parent->oldframe, parent->frame,
00064 1.0 - parent->backlerp, tagName );
00065
00066
00067 VectorCopy( parent->origin, entity->origin );
00068 for ( i = 0 ; i < 3 ; i++ ) {
00069 VectorMA( entity->origin, lerped.origin[i], parent->axis[i], entity->origin );
00070 }
00071
00072
00073 MatrixMultiply( entity->axis, lerped.axis, tempAxis );
00074 MatrixMultiply( tempAxis, ((refEntity_t *)parent)->axis, entity->axis );
00075 }
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 void CG_SetEntitySoundPosition( centity_t *cent ) {
00097 if ( cent->currentState.solid == SOLID_BMODEL )
00098 {
00099 vec3_t origin;
00100 float *v;
00101
00102 v = cgs.inlineModelMidpoints[ cent->currentState.modelindex ];
00103 VectorAdd( cent->lerpOrigin, v, origin );
00104 trap_S_UpdateEntityPosition( cent->currentState.number, origin );
00105 }
00106 else
00107 {
00108 trap_S_UpdateEntityPosition( cent->currentState.number, cent->lerpOrigin );
00109 }
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119 void CG_S_AddLoopingSound(int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx)
00120 {
00121 centity_t *cent = &cg_entities[entityNum];
00122 cgLoopSound_t *cSound = NULL;
00123 int i = 0;
00124 qboolean alreadyPlaying = qfalse;
00125
00126
00127 while (i < cent->numLoopingSounds)
00128 {
00129 cSound = ¢->loopingSound[i];
00130
00131 if (cSound->sfx == sfx)
00132 {
00133 alreadyPlaying = qtrue;
00134 break;
00135 }
00136 }
00137
00138 if (alreadyPlaying && cSound)
00139 {
00140 VectorCopy(origin, cSound->origin);
00141 VectorCopy(velocity, cSound->velocity);
00142 }
00143 else if (cent->numLoopingSounds >= MAX_CG_LOOPSOUNDS)
00144 {
00145 #ifdef _XBOX // We decreased this number, so I'd like to know if it gets overflowed
00146 Com_Printf( S_COLOR_YELLOW "Warning: MAX_CG_LOOPSOUNDS exceeded!!\n" );
00147 #endif
00148 return;
00149 }
00150
00151
00152 cSound = ¢->loopingSound[cent->numLoopingSounds];
00153
00154 cSound->entityNum = entityNum;
00155 VectorCopy(origin, cSound->origin);
00156 VectorCopy(velocity, cSound->velocity);
00157 cSound->sfx = sfx;
00158
00159 cent->numLoopingSounds++;
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169 void CG_S_AddRealLoopingSound(int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx)
00170 {
00171 CG_S_AddLoopingSound(entityNum, origin, velocity, sfx);
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181 void CG_S_StopLoopingSound(int entityNum, sfxHandle_t sfx)
00182 {
00183 centity_t *cent = &cg_entities[entityNum];
00184 cgLoopSound_t *cSound;
00185
00186 if (sfx == -1)
00187 {
00188 cent->numLoopingSounds = 0;
00189 }
00190 else
00191 {
00192 int i = 0;
00193
00194 while (i < cent->numLoopingSounds)
00195 {
00196 cSound = ¢->loopingSound[i];
00197
00198 if (cSound->sfx == sfx)
00199 {
00200 int x = i+1;
00201
00202 while (x < cent->numLoopingSounds)
00203 {
00204 memcpy(¢->loopingSound[x-1], ¢->loopingSound[x], sizeof(cent->loopingSound[x]));
00205 x++;
00206 }
00207 cent->numLoopingSounds--;
00208 }
00209
00210 i++;
00211 }
00212 }
00213
00214 }
00215
00216
00217
00218
00219
00220
00221
00222
00223 void CG_S_UpdateLoopingSounds(int entityNum)
00224 {
00225 centity_t *cent = &cg_entities[entityNum];
00226 cgLoopSound_t *cSound;
00227 vec3_t lerpOrg;
00228 float *v;
00229 int i = 0;
00230
00231 if (!cent->numLoopingSounds)
00232 {
00233 return;
00234 }
00235
00236 if (cent->currentState.eType == ET_MOVER)
00237 {
00238 v = cgs.inlineModelMidpoints[ cent->currentState.modelindex ];
00239 VectorAdd( cent->lerpOrigin, v, lerpOrg );
00240 }
00241 else
00242 {
00243 VectorCopy(cent->lerpOrigin, lerpOrg);
00244 }
00245
00246 while (i < cent->numLoopingSounds)
00247 {
00248 cSound = ¢->loopingSound[i];
00249
00250
00251
00252 trap_S_AddLoopingSound(entityNum, lerpOrg, cSound->velocity, cSound->sfx);
00253 i++;
00254 }
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264 static void CG_EntityEffects( centity_t *cent ) {
00265
00266
00267 CG_SetEntitySoundPosition( cent );
00268
00269
00270 if ( cent->currentState.loopSound || (cent->currentState.loopIsSoundset && cent->currentState.number >= MAX_CLIENTS) ) {
00271 sfxHandle_t realSoundIndex = -1;
00272
00273 if (cent->currentState.loopIsSoundset && cent->currentState.number >= MAX_CLIENTS)
00274 {
00275
00276 const char *soundSet;
00277
00278 soundSet = CG_ConfigString( CS_AMBIENT_SET + cent->currentState.soundSetIndex );
00279
00280 if (soundSet && soundSet[0])
00281 {
00282 realSoundIndex = trap_AS_GetBModelSound(soundSet, cent->currentState.loopSound);
00283 }
00284 }
00285 else
00286 {
00287 realSoundIndex = cgs.gameSounds[ cent->currentState.loopSound ];
00288 }
00289
00290
00291 if (realSoundIndex != -1)
00292 {
00293 if ( cent->currentState.solid == SOLID_BMODEL )
00294 {
00295 vec3_t origin;
00296 float *v;
00297
00298 v = cgs.inlineModelMidpoints[ cent->currentState.modelindex ];
00299 VectorAdd( cent->lerpOrigin, v, origin );
00300 trap_S_AddLoopingSound( cent->currentState.number, origin, vec3_origin,
00301 realSoundIndex );
00302 }
00303 else if (cent->currentState.eType != ET_SPEAKER) {
00304 trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin,
00305 realSoundIndex );
00306 } else {
00307 trap_S_AddRealLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin,
00308 realSoundIndex );
00309 }
00310 }
00311 }
00312
00313
00314
00315 if ( cent->currentState.constantLight ) {
00316 int cl;
00317 int i, r, g, b;
00318
00319 cl = cent->currentState.constantLight;
00320 r = cl & 255;
00321 g = ( cl >> 8 ) & 255;
00322 b = ( cl >> 16 ) & 255;
00323 i = ( ( cl >> 24 ) & 255 ) * 4;
00324 trap_R_AddLightToScene( cent->lerpOrigin, i, r, g, b );
00325 }
00326
00327 }
00328
00329 localEntity_t *FX_AddOrientedLine(vec3_t start, vec3_t end, vec3_t normal, float stScale, float scale,
00330 float dscale, float startalpha, float endalpha, float killTime, qhandle_t shader)
00331 {
00332 localEntity_t *le;
00333
00334 #ifdef _DEBUG
00335 if (!shader)
00336 {
00337 Com_Printf("FX_AddLine: NULL shader\n");
00338 }
00339 #endif
00340
00341 le = CG_AllocLocalEntity();
00342 le->leType = LE_OLINE;
00343
00344 le->startTime = cg.time;
00345 le->endTime = le->startTime + killTime;
00346 le->data.line.width = scale;
00347 le->data.line.dwidth = dscale;
00348
00349 le->alpha = startalpha;
00350 le->dalpha = endalpha - startalpha;
00351
00352 le->refEntity.data.line.stscale = stScale;
00353 le->refEntity.data.line.width = scale;
00354
00355 le->refEntity.customShader = shader;
00356
00357
00358 VectorCopy ( start, le->refEntity.origin);
00359 VectorCopy ( end, le->refEntity.oldorigin );
00360
00361 AxisClear(le->refEntity.axis);
00362 VectorCopy( normal, le->refEntity.axis[0] );
00363 RotateAroundDirection( le->refEntity.axis, 0);
00364
00365 le->refEntity.shaderRGBA[0] = 0xff;
00366 le->refEntity.shaderRGBA[1] = 0xff;
00367 le->refEntity.shaderRGBA[2] = 0xff;
00368 le->refEntity.shaderRGBA[3] = 0xff;
00369
00370 le->color[0] = 1.0;
00371 le->color[1] = 1.0;
00372 le->color[2] = 1.0;
00373 le->color[3] = 1.0;
00374 le->lifeRate = 1.0 / ( le->endTime - le->startTime );
00375
00376 return(le);
00377 }
00378
00379 void FX_DrawPortableShield(centity_t *cent)
00380 {
00381
00382
00383
00384 int xaxis, height, posWidth, negWidth, team;
00385 vec3_t start, end, normal;
00386 localEntity_t *le;
00387 qhandle_t shader;
00388 char buf[1024];
00389
00390 trap_Cvar_VariableStringBuffer("cl_paused", buf, sizeof(buf));
00391
00392 if (atoi(buf))
00393 {
00394 return;
00395 }
00396
00397 if (cent->currentState.eFlags & EF_NODRAW)
00398 {
00399 return;
00400 }
00401
00402
00403 xaxis = ((cent->currentState.time2 >> 24) & 1);
00404 height = ((cent->currentState.time2 >> 16) & 255);
00405 posWidth = ((cent->currentState.time2 >> 8) & 255);
00406 negWidth = (cent->currentState.time2 & 255);
00407
00408 team = (cent->currentState.otherEntityNum2);
00409
00410 VectorClear(normal);
00411
00412 VectorCopy(cent->lerpOrigin, start);
00413 VectorCopy(cent->lerpOrigin, end);
00414
00415 if (xaxis)
00416 {
00417 start[0] -= negWidth;
00418 end[0] += posWidth;
00419 }
00420 else
00421 {
00422 start[1] -= negWidth;
00423 end[1] += posWidth;
00424 }
00425
00426 normal[0] = 1;
00427 normal[1] = 1;
00428
00429 start[2] += height/2;
00430 end[2] += height/2;
00431
00432 if (team == TEAM_RED)
00433 {
00434 if (cent->currentState.trickedentindex)
00435 {
00436 shader = trap_R_RegisterShader( "gfx/misc/red_dmgshield" );
00437 }
00438 else
00439 {
00440 shader = trap_R_RegisterShader( "gfx/misc/red_portashield" );
00441 }
00442 }
00443 else
00444 {
00445 if (cent->currentState.trickedentindex)
00446 {
00447 shader = trap_R_RegisterShader( "gfx/misc/blue_dmgshield" );
00448 }
00449 else
00450 {
00451 shader = trap_R_RegisterShader( "gfx/misc/blue_portashield" );
00452 }
00453 }
00454
00455 le = FX_AddOrientedLine(start, end, normal, 1.0f, height, 0.0f, 1.0f, 1.0f, 50.0, shader);
00456 }
00457
00458
00459
00460
00461
00462
00463 void CG_Special( centity_t *cent ) {
00464 entityState_t *s1;
00465
00466 s1 = ¢->currentState;
00467
00468 if (!s1)
00469 {
00470 return;
00471 }
00472
00473
00474 if (!s1->modelindex) {
00475 return;
00476 }
00477
00478 if (s1->modelindex == HI_SHIELD)
00479 {
00480 FX_DrawPortableShield(cent);
00481 return;
00482 }
00483 }
00484
00485
00486
00487
00488
00489
00490 void CG_SetGhoul2Info( refEntity_t *ent, centity_t *cent)
00491 {
00492
00493 ent->ghoul2 = cent->ghoul2;
00494 VectorCopy( cent->modelScale, ent->modelScale);
00495 ent->radius = cent->radius;
00496 VectorCopy (cent->lerpAngles, ent->angles);
00497 }
00498
00499
00500
00501
00502 void CG_CreateBBRefEnts(entityState_t *s1, vec3_t origin )
00503 {
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568 }
00569
00570
00571 void G2_BoltToGhoul2Model(centity_t *cent, refEntity_t *ent)
00572 {
00573
00574 int modelNum = cent->boltInfo >> MODEL_SHIFT;
00575 int boltNum = cent->boltInfo >> BOLT_SHIFT;
00576 int entNum = cent->boltInfo >> ENTITY_SHIFT;
00577 mdxaBone_t boltMatrix;
00578
00579 modelNum &= MODEL_AND;
00580 boltNum &= BOLT_AND;
00581 entNum &= ENTITY_AND;
00582
00583
00584
00585 assert(0);
00586
00587
00588
00589 trap_G2API_GetBoltMatrix(cent->ghoul2, modelNum, boltNum, &boltMatrix, cg_entities[entNum].currentState.angles, cg_entities[entNum].currentState.origin, cg.time, cgs.gameModels, cent->modelScale);
00590
00591
00592 ent->origin[0] = boltMatrix.matrix[0][3];
00593 ent->origin[1] = boltMatrix.matrix[1][3];
00594 ent->origin[2] = boltMatrix.matrix[2][3];
00595
00596 ent->axis[0][0] = boltMatrix.matrix[0][0];
00597 ent->axis[0][1] = boltMatrix.matrix[1][0];
00598 ent->axis[0][2] = boltMatrix.matrix[2][0];
00599
00600 ent->axis[1][0] = boltMatrix.matrix[0][1];
00601 ent->axis[1][1] = boltMatrix.matrix[1][1];
00602 ent->axis[1][2] = boltMatrix.matrix[2][1];
00603
00604 ent->axis[2][0] = boltMatrix.matrix[0][2];
00605 ent->axis[2][1] = boltMatrix.matrix[1][2];
00606 ent->axis[2][2] = boltMatrix.matrix[2][2];
00607 }
00608
00609 void ScaleModelAxis(refEntity_t *ent)
00610
00611 {
00612 if (ent->modelScale[0] && ent->modelScale[0] != 1.0f)
00613 {
00614 VectorScale( ent->axis[0], ent->modelScale[0] , ent->axis[0] );
00615 ent->nonNormalizedAxes = qtrue;
00616 }
00617 if (ent->modelScale[1] && ent->modelScale[1] != 1.0f)
00618 {
00619 VectorScale( ent->axis[1], ent->modelScale[1] , ent->axis[1] );
00620 ent->nonNormalizedAxes = qtrue;
00621 }
00622 if (ent->modelScale[2] && ent->modelScale[2] != 1.0f)
00623 {
00624 VectorScale( ent->axis[2], ent->modelScale[2] , ent->axis[2] );
00625 ent->nonNormalizedAxes = qtrue;
00626 }
00627 }
00628
00629
00630
00631
00632 char *forceHolocronModels[] = {
00633 "models/map_objects/mp/lt_heal.md3",
00634 "models/map_objects/mp/force_jump.md3",
00635 "models/map_objects/mp/force_speed.md3",
00636 "models/map_objects/mp/force_push.md3",
00637 "models/map_objects/mp/force_pull.md3",
00638 "models/map_objects/mp/lt_telepathy.md3",
00639 "models/map_objects/mp/dk_grip.md3",
00640 "models/map_objects/mp/dk_lightning.md3",
00641 "models/map_objects/mp/dk_rage.md3",
00642 "models/map_objects/mp/lt_protect.md3",
00643 "models/map_objects/mp/lt_absorb.md3",
00644 "models/map_objects/mp/lt_healother.md3",
00645 "models/map_objects/mp/dk_powerother.md3",
00646 "models/map_objects/mp/dk_drain.md3",
00647 "models/map_objects/mp/force_sight.md3",
00648 "models/map_objects/mp/saber_attack.md3",
00649 "models/map_objects/mp/saber_defend.md3",
00650 "models/map_objects/mp/saber_throw.md3"
00651 };
00652
00653 void CG_Disintegration(centity_t *cent, refEntity_t *ent)
00654 {
00655 vec3_t tempAng, hitLoc;
00656 float tempLength;
00657
00658 VectorCopy(cent->currentState.origin2, hitLoc);
00659
00660 VectorSubtract( hitLoc, ent->origin, ent->oldorigin );
00661
00662 tempLength = VectorNormalize( ent->oldorigin );
00663 vectoangles( ent->oldorigin, tempAng );
00664 tempAng[YAW] -= cent->lerpAngles[YAW];
00665 AngleVectors( tempAng, ent->oldorigin, NULL, NULL );
00666 VectorScale( ent->oldorigin, tempLength, ent->oldorigin );
00667
00668 ent->endTime = cent->dustTrailTime;
00669
00670 ent->renderfx |= RF_DISINTEGRATE2;
00671 ent->customShader = cgs.media.disruptorShader;
00672 trap_R_AddRefEntityToScene( ent );
00673
00674 ent->renderfx &= ~(RF_DISINTEGRATE2);
00675 ent->renderfx |= (RF_DISINTEGRATE1);
00676 ent->customShader = 0;
00677 trap_R_AddRefEntityToScene( ent );
00678
00679 if ( cg.time - ent->endTime < 1000 && (cg_timescale.value * cg_timescale.value * random()) > 0.05f )
00680 {
00681 vec3_t fxOrg, fxDir;
00682 mdxaBone_t boltMatrix;
00683 int torsoBolt = trap_G2API_AddBolt(cent->ghoul2, 0, "lower_lumbar");
00684
00685 VectorSet(fxDir, 0, 1, 0);
00686
00687 trap_G2API_GetBoltMatrix( cent->ghoul2, 0, torsoBolt, &boltMatrix, cent->lerpAngles, cent->lerpOrigin, cg.time,
00688 cgs.gameModels, cent->modelScale);
00689 BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, fxOrg );
00690
00691 VectorMA( fxOrg, -18, cg.refdef.viewaxis[0], fxOrg );
00692 fxOrg[2] += crandom() * 20;
00693 trap_FX_PlayEffectID( cgs.effects.mDisruptorDeathSmoke, fxOrg, fxDir, -1, -1 );
00694
00695 if ( random() > 0.5f )
00696 {
00697 trap_FX_PlayEffectID( cgs.effects.mDisruptorDeathSmoke, fxOrg, fxDir, -1, -1 );
00698 }
00699 }
00700 }
00701
00702 extern int cgSiegeEntityRender;
00703 static qboolean CG_RenderTimeEntBolt(centity_t *cent)
00704 {
00705 int clientNum = cent->currentState.boltToPlayer-1;
00706 centity_t *cl;
00707 mdxaBone_t matrix;
00708 vec3_t boltOrg, boltAng;
00709 int getBolt = -1;
00710
00711 if (clientNum >= MAX_CLIENTS || clientNum < 0)
00712 {
00713 assert(0);
00714 return qfalse;
00715 }
00716
00717 cl = &cg_entities[clientNum];
00718
00719 if (!cl->ghoul2)
00720 {
00721 assert(0);
00722 return qfalse;
00723 }
00724
00725 if (clientNum == cg.predictedPlayerState.clientNum &&
00726 !cg.renderingThirdPerson)
00727 {
00728 cgSiegeEntityRender = cent->currentState.number;
00729 return qfalse;
00730 }
00731
00732 getBolt = trap_G2API_AddBolt(cl->ghoul2, 0, "lhand");
00733
00734 trap_G2API_GetBoltMatrix(cl->ghoul2, 0, getBolt, &matrix, cl->turAngles, cl->lerpOrigin, cg.time, cgs.gameModels, cl->modelScale);
00735
00736 BG_GiveMeVectorFromMatrix(&matrix, ORIGIN, boltOrg);
00737 BG_GiveMeVectorFromMatrix(&matrix, NEGATIVE_Y, boltAng);
00738 vectoangles(boltAng, boltAng);
00739 boltAng[PITCH] = boltAng[ROLL] = 0;
00740
00741 VectorCopy(boltOrg, cent->lerpOrigin);
00742 VectorCopy(boltAng, cent->lerpAngles);
00743
00744 return qtrue;
00745 }
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799 void CG_AddRadarEnt(centity_t *cent)
00800 {
00801 if (cg.radarEntityCount == sizeof(cg.radarEntities)/sizeof(cg.radarEntities[0]))
00802 {
00803 #ifdef _DEBUG
00804 Com_Printf("^3Warning: CG_AddRadarEnt full. (%d max)\n", sizeof(cg.radarEntities)/sizeof(cg.radarEntities[0]));
00805 #endif
00806 return;
00807 }
00808 cg.radarEntities[cg.radarEntityCount++] = cent->currentState.number;
00809 }
00810
00811 void CG_AddBracketedEnt(centity_t *cent)
00812 {
00813 if (cg.bracketedEntityCount == sizeof(cg.bracketedEntities)/sizeof(cg.bracketedEntities[0]))
00814 {
00815 #ifdef _DEBUG
00816 Com_Printf("^3Warning: CG_AddBracketedEnt full. (%d max)\n", sizeof(cg.radarEntities)/sizeof(cg.bracketedEntities[0]));
00817 #endif
00818 return;
00819 }
00820 cg.bracketedEntities[cg.bracketedEntityCount++] = cent->currentState.number;
00821 }
00822
00823
00824
00825
00826
00827 void CG_G2ServerBoneAngles(centity_t *cent);
00828
00829 #include "../namespace_begin.h"
00830 extern qboolean BG_GetRootSurfNameWithVariant( void *ghoul2, const char *rootSurfName, char *returnSurfName, int returnSize );
00831 #include "../namespace_end.h"
00832
00833 static void CG_General( centity_t *cent ) {
00834 refEntity_t ent;
00835 entityState_t *s1;
00836 float val;
00837 int beamID;
00838 vec3_t beamOrg;
00839 mdxaBone_t matrix;
00840 qboolean doNotSetModel = qfalse;
00841
00842 if (cent->currentState.modelGhoul2 == 127)
00843 {
00844 return;
00845 }
00846
00847 if (cent->ghoul2 && !cent->currentState.modelGhoul2 && cent->currentState.eType != ET_BODY &&
00848 cent->currentState.number >= MAX_CLIENTS)
00849 {
00850 if (trap_G2_HaveWeGhoul2Models(cent->ghoul2))
00851 {
00852 trap_G2API_CleanGhoul2Models(&(cent->ghoul2));
00853 }
00854 }
00855
00856 if (cent->currentState.eFlags & EF_RADAROBJECT)
00857 {
00858 CG_AddRadarEnt(cent);
00859 }
00860 if (cent->currentState.eFlags2 & EF2_BRACKET_ENTITY)
00861 {
00862 if ( CG_InFighter() )
00863 {
00864 CG_AddBracketedEnt(cent);
00865 }
00866 }
00867
00868 if (cent->currentState.boltToPlayer)
00869 {
00870 centity_t *pl = &cg_entities[cent->currentState.boltToPlayer-1];
00871 if (CG_IsMindTricked(pl->currentState.trickedentindex,
00872 pl->currentState.trickedentindex2,
00873 pl->currentState.trickedentindex3,
00874 pl->currentState.trickedentindex4,
00875 cg.predictedPlayerState.clientNum))
00876 {
00877 return;
00878 }
00879 if (!CG_RenderTimeEntBolt(cent))
00880 {
00881 if (cent->currentState.boltToPlayer > 0 &&
00882 cent->currentState.boltToPlayer <= MAX_CLIENTS)
00883 {
00884 VectorCopy(pl->lerpOrigin, cent->lerpOrigin);
00885
00886 if (cent->currentState.eFlags & EF_CLIENTSMOOTH)
00887 {
00888 VectorCopy(cent->lerpOrigin, cent->turAngles);
00889 }
00890 }
00891 return;
00892 }
00893
00894 if (cent->currentState.eFlags & EF_CLIENTSMOOTH)
00895 {
00896 VectorCopy(cent->lerpOrigin, cent->turAngles);
00897 }
00898
00899
00900
00901
00902
00903
00904
00905 }
00906 else if (cent->currentState.eFlags & EF_CLIENTSMOOTH)
00907 {
00908 if (cent->currentState.groundEntityNum >= ENTITYNUM_WORLD)
00909 {
00910 float smoothFactor = 0.5f*cg_timescale.value;
00911 int k = 0;
00912 vec3_t posDif;
00913
00914
00915 if (DistanceSquared(cent->turAngles,cent->lerpOrigin)>18000.0f)
00916 {
00917 VectorCopy(cent->lerpOrigin, cent->turAngles);
00918 }
00919
00920 VectorSubtract(cent->lerpOrigin, cent->turAngles, posDif);
00921
00922 for (k=0;k<3;k++)
00923 {
00924 cent->turAngles[k]=(cent->turAngles[k]+posDif[k]*smoothFactor);
00925 cent->lerpOrigin[k]=cent->turAngles[k];
00926 }
00927 }
00928 else
00929 {
00930 VectorCopy(cent->lerpOrigin, cent->turAngles);
00931 }
00932 }
00933
00934
00935 if (cent->ghoul2 &&
00936 (cent->currentState.eType == ET_BODY || (cent->currentState.eFlags & EF_RAG)))
00937 {
00938 if (!(cent->currentState.eFlags & EF_NODRAW) &&
00939 !(cent->currentState.eFlags & EF_DISINTEGRATION) &&
00940 cent->bodyFadeTime <= cg.time)
00941 {
00942 vec3_t forcedAngles;
00943
00944 VectorClear(forcedAngles);
00945 forcedAngles[YAW] = cent->lerpAngles[YAW];
00946
00947 CG_RagDoll(cent, forcedAngles);
00948 }
00949 }
00950 else if (cent->isRagging)
00951 {
00952 cent->isRagging = qfalse;
00953
00954 if (cent->ghoul2 && trap_G2_HaveWeGhoul2Models(cent->ghoul2))
00955 {
00956 trap_G2API_SetRagDoll(cent->ghoul2, NULL);
00957 }
00958 }
00959
00960 if (cent->currentState.boneOrient && cent->ghoul2)
00961 {
00962 CG_G2ServerBoneAngles(cent);
00963 }
00964
00965 if ((cent->currentState.eFlags & EF_G2ANIMATING) && cent->ghoul2)
00966 {
00967
00968
00969
00970 if (cent->currentState.torsoAnim != cent->pe.torso.animationNumber ||
00971 cent->currentState.legsAnim != cent->pe.legs.animationNumber ||
00972 cent->currentState.torsoFlip != cent->pe.torso.lastFlip)
00973 {
00974 trap_G2API_SetBoneAnim(cent->ghoul2, 0, "model_root", cent->currentState.torsoAnim,
00975 cent->currentState.legsAnim, (BONE_ANIM_OVERRIDE_FREEZE|BONE_ANIM_BLEND), 1.0f, cg.time, -1, 100);
00976
00977 cent->pe.torso.animationNumber = cent->currentState.torsoAnim;
00978 cent->pe.legs.animationNumber = cent->currentState.legsAnim;
00979 cent->pe.torso.lastFlip = cent->currentState.torsoFlip;
00980 }
00981 }
00982
00983 memset (&ent, 0, sizeof(ent));
00984
00985 ent.shaderRGBA[0] = cent->currentState.customRGBA[0];
00986 ent.shaderRGBA[1] = cent->currentState.customRGBA[1];
00987 ent.shaderRGBA[2] = cent->currentState.customRGBA[2];
00988 ent.shaderRGBA[3] = cent->currentState.customRGBA[3];
00989
00990 if (cent->currentState.modelGhoul2 >= G2_MODELPART_HEAD &&
00991 cent->currentState.modelGhoul2 <= G2_MODELPART_RLEG &&
00992
00993 cent->currentState.weapon == G2_MODEL_PART)
00994 {
00995 centity_t *clEnt;
00996 int dismember_settings = cg_dismember.integer;
00997 float smoothFactor = 0.5f*cg_timescale.value;
00998 int k = 0;
00999 vec3_t posDif;
01000
01001 doNotSetModel = qtrue;
01002
01003 if (cent->currentState.modelindex >= 0)
01004 {
01005 clEnt = &cg_entities[cent->currentState.modelindex];
01006 }
01007 else
01008 {
01009 clEnt = &cg_entities[cent->currentState.otherEntityNum2];
01010 }
01011
01012 if (!dismember_settings)
01013 {
01014 return;
01015 }
01016
01017 if (dismember_settings < 2 && (cent->currentState.modelGhoul2 == G2_MODELPART_HEAD || cent->currentState.modelGhoul2 == G2_MODELPART_WAIST))
01018 {
01019 return;
01020 }
01021
01022 if (!cent->ghoul2)
01023 {
01024 const char *limbBone;
01025 const char *rotateBone;
01026 char limbName[MAX_QPATH];
01027 char stubName[MAX_QPATH];
01028 char limbCapName[MAX_QPATH];
01029 char stubCapName[MAX_QPATH];
01030 char *limbTagName;
01031 char *stubTagName;
01032 int limb_anim;
01033 int newBolt;
01034 int limbBit = (1 << (cent->currentState.modelGhoul2-10));
01035
01036 if (clEnt && (clEnt->torsoBolt & limbBit))
01037 {
01038 return;
01039 }
01040
01041
01042 if (clEnt && !(clEnt->currentState.eFlags & EF_DEAD))
01043 {
01044 return;
01045 }
01046
01047 if (clEnt && (!BG_InDeathAnim(clEnt->currentState.torsoAnim) || !BG_InDeathAnim(clEnt->pe.torso.animationNumber)))
01048 {
01049 if (clEnt->currentState.torsoAnim != BOTH_RIGHTHANDCHOPPEDOFF)
01050 {
01051 return;
01052 }
01053 }
01054
01055 cent->bolt4 = -1;
01056 cent->trailTime = 0;
01057
01058 if (cent->currentState.modelGhoul2 == G2_MODELPART_HEAD)
01059 {
01060 limbBone = "cervical";
01061 rotateBone = "cranium";
01062 Q_strncpyz( limbName , "head", sizeof( limbName ) );
01063 Q_strncpyz( limbCapName, "head_cap_torso", sizeof( limbCapName ) );
01064 Q_strncpyz( stubCapName, "torso_cap_head", sizeof( stubCapName ) );
01065 limbTagName = "*head_cap_torso";
01066 stubTagName = "*torso_cap_head";
01067 limb_anim = BOTH_DISMEMBER_HEAD1;
01068 }
01069 else if (cent->currentState.modelGhoul2 == G2_MODELPART_WAIST)
01070 {
01071 limbBone = "pelvis";
01072
01073 if (clEnt->localAnimIndex <= 1)
01074 {
01075 rotateBone = "thoracic";
01076 }
01077 else
01078 {
01079 rotateBone = "pelvis";
01080 }
01081 Q_strncpyz( limbName, "torso", sizeof( limbName ) );
01082 Q_strncpyz( limbCapName, "torso_cap_hips", sizeof( limbCapName ) );
01083 Q_strncpyz( stubCapName, "hips_cap_torso", sizeof( stubCapName ) );
01084 limbTagName = "*torso_cap_hips";
01085 stubTagName = "*hips_cap_torso";
01086 limb_anim = BOTH_DISMEMBER_TORSO1;
01087 }
01088 else if (cent->currentState.modelGhoul2 == G2_MODELPART_LARM)
01089 {
01090 limbBone = "lhumerus";
01091 rotateBone = "lradius";
01092 BG_GetRootSurfNameWithVariant( clEnt->ghoul2, "l_arm", limbName, sizeof(limbName) );
01093 BG_GetRootSurfNameWithVariant( clEnt->ghoul2, "torso", stubName, sizeof(stubName) );
01094 Com_sprintf( limbCapName, sizeof( limbCapName ), "%s_cap_torso", limbName );
01095 Com_sprintf( stubCapName, sizeof( stubCapName), "%s_cap_l_arm", stubName );
01096 limbTagName = "*l_arm_cap_torso";
01097 stubTagName = "*torso_cap_l_arm";
01098 limb_anim = BOTH_DISMEMBER_LARM;
01099 }
01100 else if (cent->currentState.modelGhoul2 == G2_MODELPART_RARM)
01101 {
01102 limbBone = "rhumerus";
01103 rotateBone = "rradius";
01104 BG_GetRootSurfNameWithVariant( clEnt->ghoul2, "r_arm", limbName, sizeof(limbName) );
01105 BG_GetRootSurfNameWithVariant( clEnt->ghoul2, "torso", stubName, sizeof(stubName) );
01106 Com_sprintf( limbCapName, sizeof( limbCapName ), "%s_cap_torso", limbName );
01107 Com_sprintf( stubCapName, sizeof( stubCapName), "%s_cap_r_arm", stubName );
01108 limbTagName = "*r_arm_cap_torso";
01109 stubTagName = "*torso_cap_r_arm";
01110 limb_anim = BOTH_DISMEMBER_RARM;
01111 }
01112 else if (cent->currentState.modelGhoul2 == G2_MODELPART_RHAND)
01113 {
01114 limbBone = "rradiusX";
01115 rotateBone = "rhand";
01116 BG_GetRootSurfNameWithVariant( clEnt->ghoul2, "r_hand", limbName, sizeof(limbName) );
01117 BG_GetRootSurfNameWithVariant( clEnt->ghoul2, "r_arm", stubName, sizeof(stubName) );
01118 Com_sprintf( limbCapName, sizeof( limbCapName ), "%s_cap_r_arm", limbName );
01119 Com_sprintf( stubCapName, sizeof( stubCapName), "%s_cap_r_hand", stubName );
01120 limbTagName = "*r_hand_cap_r_arm";
01121 stubTagName = "*r_arm_cap_r_hand";
01122 limb_anim = BOTH_DISMEMBER_RARM;
01123 }
01124 else if (cent->currentState.modelGhoul2 == G2_MODELPART_LLEG)
01125 {
01126 limbBone = "lfemurYZ";
01127 rotateBone = "ltibia";
01128 BG_GetRootSurfNameWithVariant( clEnt->ghoul2, "l_leg", limbName, sizeof(limbName) );
01129 BG_GetRootSurfNameWithVariant( clEnt->ghoul2, "hips", stubName, sizeof(stubName) );
01130 Com_sprintf( limbCapName, sizeof( limbCapName ), "%s_cap_hips", limbName );
01131 Com_sprintf( stubCapName, sizeof( stubCapName), "%s_cap_l_leg", stubName );
01132 limbTagName = "*l_leg_cap_hips";
01133 stubTagName = "*hips_cap_l_leg";
01134 limb_anim = BOTH_DISMEMBER_LLEG;
01135 }
01136 else if (cent->currentState.modelGhoul2 == G2_MODELPART_RLEG)
01137 {
01138 limbBone = "rfemurYZ";
01139 rotateBone = "rtibia";
01140 BG_GetRootSurfNameWithVariant( clEnt->ghoul2, "r_leg", limbName, sizeof(limbName) );
01141 BG_GetRootSurfNameWithVariant( clEnt->ghoul2, "hips", stubName, sizeof(stubName) );
01142 Com_sprintf( limbCapName, sizeof( limbCapName ), "%s_cap_hips", limbName );
01143 Com_sprintf( stubCapName, sizeof( stubCapName), "%s_cap_r_leg", stubName );
01144 limbTagName = "*r_leg_cap_hips";
01145 stubTagName = "*hips_cap_r_leg";
01146 limb_anim = BOTH_DISMEMBER_RLEG;
01147 }
01148 else
01149 {
01150 limbBone = "rfemurYZ";
01151 rotateBone = "rtibia";
01152 BG_GetRootSurfNameWithVariant( clEnt->ghoul2, "r_leg", limbName, sizeof(limbName) );
01153 BG_GetRootSurfNameWithVariant( clEnt->ghoul2, "hips", stubName, sizeof(stubName) );
01154 Com_sprintf( limbCapName, sizeof( limbCapName ), "%s_cap_hips", limbName );
01155 Com_sprintf( stubCapName, sizeof( stubCapName), "%s_cap_r_leg", stubName );
01156 limbTagName = "*r_leg_cap_hips";
01157 stubTagName = "*hips_cap_r_leg";
01158 limb_anim = BOTH_DISMEMBER_RLEG;
01159 }
01160
01161 if (clEnt && clEnt->ghoul2)
01162 {
01163 if (trap_G2API_HasGhoul2ModelOnIndex(&(clEnt->ghoul2), 2))
01164 {
01165 trap_G2API_RemoveGhoul2Model(&(clEnt->ghoul2), 2);
01166 }
01167
01168 if (trap_G2API_HasGhoul2ModelOnIndex(&(clEnt->ghoul2), 3))
01169 {
01170 trap_G2API_RemoveGhoul2Model(&(clEnt->ghoul2), 3);
01171 }
01172
01173 if (clEnt->localAnimIndex <= 0)
01174 {
01175 trap_G2API_SetBoneAngles(clEnt->ghoul2, 0, "model_root", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, cgs.gameModels, 100, cg.time);
01176 trap_G2API_SetBoneAngles(clEnt->ghoul2, 0, "pelvis", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, cgs.gameModels, 0, cg.time);
01177 trap_G2API_SetBoneAngles(clEnt->ghoul2, 0, "thoracic", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, cgs.gameModels, 0, cg.time);
01178 trap_G2API_SetBoneAngles(clEnt->ghoul2, 0, "upper_lumbar", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, cgs.gameModels, 100, cg.time);
01179 trap_G2API_SetBoneAngles(clEnt->ghoul2, 0, "lower_lumbar", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, cgs.gameModels, 100, cg.time);
01180 trap_G2API_SetBoneAngles(clEnt->ghoul2, 0, "cranium", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_Z, NEGATIVE_Y, POSITIVE_X, cgs.gameModels, 100, cg.time);
01181 }
01182 else
01183 {
01184 trap_G2API_SetBoneAngles(clEnt->ghoul2, 0, "model_root", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, cgs.gameModels, 100, cg.time);
01185 trap_G2API_SetBoneAngles(clEnt->ghoul2, 0, "pelvis", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, cgs.gameModels, 0, cg.time);
01186 trap_G2API_SetBoneAngles(clEnt->ghoul2, 0, "upper_lumbar", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, cgs.gameModels, 100, cg.time);
01187 trap_G2API_SetBoneAngles(clEnt->ghoul2, 0, "lower_lumbar", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, cgs.gameModels, 100, cg.time);
01188 }
01189
01190 trap_G2API_DuplicateGhoul2Instance(clEnt->ghoul2, ¢->ghoul2);
01191 }
01192
01193 if (!cent->ghoul2)
01194 {
01195 return;
01196 }
01197
01198 newBolt = trap_G2API_AddBolt( cent->ghoul2, 0, limbTagName );
01199 if ( newBolt != -1 )
01200 {
01201 vec3_t boltOrg, boltAng;
01202
01203 trap_G2API_GetBoltMatrix(cent->ghoul2, 0, newBolt, &matrix, cent->lerpAngles, cent->lerpOrigin, cg.time, cgs.gameModels, cent->modelScale);
01204
01205 BG_GiveMeVectorFromMatrix(&matrix, ORIGIN, boltOrg);
01206 BG_GiveMeVectorFromMatrix(&matrix, NEGATIVE_Y, boltAng);
01207
01208 trap_FX_PlayEffectID(cgs.effects.mBlasterSmoke, boltOrg, boltAng, -1, -1);
01209 }
01210
01211 cent->bolt4 = newBolt;
01212
01213 trap_G2API_SetRootSurface(cent->ghoul2, 0, limbName);
01214
01215 trap_G2API_SetNewOrigin(cent->ghoul2, trap_G2API_AddBolt(cent->ghoul2, 0, rotateBone));
01216
01217 trap_G2API_SetSurfaceOnOff(cent->ghoul2, limbCapName, 0);
01218
01219 trap_G2API_SetSurfaceOnOff(clEnt->ghoul2, limbName, 0x00000100);
01220 trap_G2API_SetSurfaceOnOff(clEnt->ghoul2, stubCapName, 0);
01221
01222 newBolt = trap_G2API_AddBolt( clEnt->ghoul2, 0, stubTagName );
01223 if ( newBolt != -1 )
01224 {
01225 vec3_t boltOrg, boltAng;
01226
01227 trap_G2API_GetBoltMatrix(clEnt->ghoul2, 0, newBolt, &matrix, clEnt->lerpAngles, clEnt->lerpOrigin, cg.time, cgs.gameModels, clEnt->modelScale);
01228
01229 BG_GiveMeVectorFromMatrix(&matrix, ORIGIN, boltOrg);
01230 BG_GiveMeVectorFromMatrix(&matrix, NEGATIVE_Y, boltAng);
01231
01232 trap_FX_PlayEffectID(cgs.effects.mBlasterSmoke, boltOrg, boltAng, -1, -1);
01233 }
01234
01235 if (cent->currentState.modelGhoul2 == G2_MODELPART_RARM || cent->currentState.modelGhoul2 == G2_MODELPART_RHAND || cent->currentState.modelGhoul2 == G2_MODELPART_WAIST)
01236 {
01237 if (trap_G2API_HasGhoul2ModelOnIndex(&(clEnt->ghoul2), 1))
01238 {
01239 trap_G2API_RemoveGhoul2Model(&(clEnt->ghoul2), 1);
01240 }
01241 }
01242
01243 clEnt->torsoBolt |= limbBit;
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259 VectorCopy(cent->lerpOrigin, cent->turAngles);
01260
01261 }
01262
01263
01264 if (DistanceSquared(cent->turAngles,cent->lerpOrigin)>18000.0f)
01265 {
01266 VectorCopy(cent->lerpOrigin, cent->turAngles);
01267 }
01268
01269 VectorSubtract(cent->lerpOrigin, cent->turAngles, posDif);
01270
01271 for (k=0;k<3;k++)
01272 {
01273 cent->turAngles[k]=(cent->turAngles[k]+posDif[k]*smoothFactor);
01274 cent->lerpOrigin[k]=cent->turAngles[k];
01275 }
01276
01277 if (cent->ghoul2 && cent->bolt4 != -1 && cent->trailTime < cg.time)
01278 {
01279 if ( cent->bolt4 != -1 &&
01280 (cent->currentState.pos.trDelta[0] || cent->currentState.pos.trDelta[1] || cent->currentState.pos.trDelta[2]) )
01281 {
01282 vec3_t boltOrg, boltAng;
01283
01284 trap_G2API_GetBoltMatrix(cent->ghoul2, 0, cent->bolt4, &matrix, cent->lerpAngles, cent->lerpOrigin, cg.time, cgs.gameModels, cent->modelScale);
01285
01286 BG_GiveMeVectorFromMatrix(&matrix, ORIGIN, boltOrg);
01287 BG_GiveMeVectorFromMatrix(&matrix, NEGATIVE_Y, boltAng);
01288
01289 if (!boltAng[0] && !boltAng[1] && !boltAng[2])
01290 {
01291 boltAng[1] = 1;
01292 }
01293 trap_FX_PlayEffectID(cgs.effects.mBlasterSmoke, boltOrg, boltAng, -1, -1);
01294
01295 cent->trailTime = cg.time + 400;
01296 }
01297 }
01298
01299 ent.radius = cent->currentState.g2radius;
01300 ent.hModel = 0;
01301 }
01302
01303 if (cent->currentState.number >= MAX_CLIENTS &&
01304 cent->currentState.activeForcePass == NUM_FORCE_POWERS+1&&
01305 cent->currentState.NPC_class != CLASS_VEHICLE )
01306 {
01307 vec3_t empAngles;
01308 centity_t *empOwn;
01309
01310 empOwn = &cg_entities[cent->currentState.emplacedOwner];
01311
01312 if (cg.snap->ps.clientNum == empOwn->currentState.number &&
01313 !cg.renderingThirdPerson)
01314 {
01315 VectorCopy(cg.refdef.viewangles, empAngles);
01316 }
01317 else
01318 {
01319 VectorCopy(empOwn->lerpAngles, empAngles);
01320 }
01321
01322 if (empAngles[PITCH] > 40)
01323 {
01324 empAngles[PITCH] = 40;
01325 }
01326 empAngles[YAW] -= cent->currentState.angles[YAW];
01327
01328 trap_G2API_SetBoneAngles( cent->ghoul2, 0, "Bone02", empAngles, BONE_ANGLES_REPLACE, NEGATIVE_Y, NEGATIVE_X, POSITIVE_Z, NULL, 0, cg.time);
01329 }
01330
01331 s1 = ¢->currentState;
01332
01333
01334 if ((!s1->modelindex) && !(trap_G2_HaveWeGhoul2Models(cent->ghoul2)))
01335 {
01336 return;
01337 }
01338
01339 if ( ( s1->eFlags & EF_NODRAW ) )
01340 {
01341 return;
01342 }
01343
01344
01345 if ( s1->eFlags & EF_SHADER_ANIM )
01346 {
01347
01348 ent.renderfx|=RF_SETANIMINDEX;
01349 ent.skinNum = s1->frame;
01350 }
01351 else
01352 {
01353 ent.frame = s1->frame;
01354 }
01355 ent.oldframe = ent.frame;
01356 ent.backlerp = 0;
01357
01358
01359
01360
01361 CG_SetGhoul2Info(&ent, cent);
01362
01363
01364
01365
01366 VectorCopy( cent->lerpOrigin, ent.origin);
01367 VectorCopy( cent->lerpOrigin, ent.oldorigin);
01368
01369 if (cent->currentState.modelGhoul2)
01370 {
01371 if (!cent->ghoul2 && !cent->currentState.bolt1)
01372 {
01373 char skinName[MAX_QPATH];
01374 const char *modelName = CG_ConfigString( CS_MODELS+cent->currentState.modelindex );
01375 int l;
01376 int skin = 0;
01377
01378 trap_G2API_InitGhoul2Model(¢->ghoul2, modelName, 0, 0, 0, 0, 0);
01379 if (cent->ghoul2 && trap_G2API_SkinlessModel(cent->ghoul2, 0))
01380 {
01381 Q_strncpyz(skinName, modelName, MAX_QPATH);
01382 l = strlen(skinName);
01383 while (l > 0 && skinName[l] != '/')
01384 {
01385 l--;
01386 }
01387 if (skinName[l] == '/')
01388 {
01389 l++;
01390 skinName[l] = 0;
01391 Q_strcat(skinName, MAX_QPATH, "model_default.skin");
01392
01393 skin = trap_R_RegisterSkin(skinName);
01394 }
01395 trap_G2API_SetSkin(cent->ghoul2, 0, skin, skin);
01396 }
01397 }
01398 else if (cent->currentState.bolt1)
01399 {
01400 TurretClientRun(cent);
01401 }
01402
01403 if (cent->ghoul2)
01404 {
01405 ent.radius = cent->currentState.g2radius;
01406 }
01407 }
01408
01409 if (s1->eType == ET_BODY)
01410 {
01411 ent.radius = cent->currentState.g2radius;
01412
01413 if (cent->ghoul2)
01414 {
01415 cent->lerpAngles[PITCH] = 0;
01416 cent->lerpAngles[ROLL] = 0;
01417 trap_G2API_SetBoneAngles(cent->ghoul2, 0, "pelvis", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, cgs.gameModels, 0, cg.time);
01418 trap_G2API_SetBoneAngles(cent->ghoul2, 0, "thoracic", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, cgs.gameModels, 0, cg.time);
01419 trap_G2API_SetBoneAngles(cent->ghoul2, 0, "upper_lumbar", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, cgs.gameModels, 100, cg.time);
01420 trap_G2API_SetBoneAngles(cent->ghoul2, 0, "lower_lumbar", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, cgs.gameModels, 100, cg.time);
01421 trap_G2API_SetBoneAngles(cent->ghoul2, 0, "cranium", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_Z, NEGATIVE_Y, POSITIVE_X, cgs.gameModels, 100, cg.time);
01422 }
01423 }
01424
01425 if (s1->eType == ET_HOLOCRON && s1->modelindex < -100)
01426 {
01427
01428 ent.hModel = trap_R_RegisterModel(forceHolocronModels[s1->modelindex+128]);
01429
01430
01431 VectorCopy( cg.autoAngles, cent->lerpAngles );
01432 AxisCopy( cg.autoAxis, ent.axis );
01433 }
01434 else if (!doNotSetModel)
01435 {
01436 ent.hModel = cgs.gameModels[s1->modelindex];
01437 }
01438
01439
01440 if (s1->number == cg.snap->ps.clientNum) {
01441 ent.renderfx |= RF_THIRD_PERSON;
01442 }
01443
01444
01445 AnglesToAxis( cent->lerpAngles, ent.axis );
01446
01447 if (cent->currentState.iModelScale)
01448 {
01449 cent->modelScale[0] = cent->modelScale[1] = cent->modelScale[2] = cent->currentState.iModelScale/100.0f;
01450 VectorCopy(cent->modelScale, ent.modelScale);
01451 ScaleModelAxis(&ent);
01452 }
01453 else
01454 {
01455 VectorClear(cent->modelScale);
01456 }
01457
01458 if ( cent->currentState.time > cg.time && cent->currentState.weapon == WP_EMPLACED_GUN )
01459 {
01460
01461 val = (1.0f - (float)(cent->currentState.time - cg.time) / 3200.0f ) * 0.3f;
01462
01463 ent.customShader = trap_R_RegisterShader( "gfx/effects/turretflashdie" );
01464 ent.shaderRGBA[0] = (sin( cg.time * 0.04f ) * val * 0.4f + val) * 255;
01465 ent.shaderRGBA[1] = ent.shaderRGBA[2] = 0;
01466
01467 ent.shaderRGBA[3] = 100;
01468 trap_R_AddRefEntityToScene( &ent );
01469 ent.customShader = 0;
01470 }
01471 else if ( cent->currentState.time == -1 && cent->currentState.weapon == WP_EMPLACED_GUN)
01472 {
01473 ent.customShader = trap_R_RegisterShader( "models/map_objects/imp_mine/turret_chair_dmg.tga" );
01474
01475 }
01476
01477 if ((cent->currentState.eFlags & EF_DISINTEGRATION) && cent->currentState.eType == ET_BODY)
01478 {
01479 if (!cent->dustTrailTime)
01480 {
01481 cent->dustTrailTime = cg.time;
01482 }
01483
01484 CG_Disintegration(cent, &ent);
01485 return;
01486 }
01487 else if (cent->currentState.eType == ET_BODY)
01488 {
01489 if (cent->bodyFadeTime > cg.time)
01490 {
01491 qboolean lightSide = cent->teamPowerType;
01492 vec3_t hitLoc, tempAng;
01493 float tempLength;
01494 int curTimeDif = ((cg.time + 60000) - cent->bodyFadeTime);
01495 int tMult = curTimeDif*0.08;
01496
01497 ent.renderfx |= RF_FORCE_ENT_ALPHA;
01498
01499
01500
01501
01502
01503
01504
01505
01506 if (curTimeDif*0.1 > 254)
01507 {
01508 ent.shaderRGBA[3] = 0;
01509 }
01510 else
01511 {
01512 ent.shaderRGBA[3] = (254 - tMult);
01513 }
01514
01515 if (ent.shaderRGBA[3] >= 1)
01516 {
01517 trap_R_AddRefEntityToScene (&ent);
01518 }
01519
01520 ent.renderfx &= ~RF_FORCE_ENT_ALPHA;
01521 ent.renderfx |= RF_RGB_TINT;
01522
01523 if (tMult > 200)
01524 {
01525 ent.shaderRGBA[3] = 200;
01526 if (!cent->dustTrailTime)
01527 {
01528 cent->dustTrailTime = cg.time;
01529 if (lightSide)
01530 {
01531 trap_S_StartSound ( NULL, cent->currentState.number, CHAN_AUTO, trap_S_RegisterSound("sound/weapons/force/see.wav") );
01532 }
01533 else
01534 {
01535 trap_S_StartSound ( NULL, cent->currentState.number, CHAN_AUTO, trap_S_RegisterSound("sound/weapons/force/lightning") );
01536 }
01537 }
01538 ent.endTime = cent->dustTrailTime;
01539 ent.renderfx |= RF_DISINTEGRATE2;
01540 }
01541 else
01542 {
01543 ent.shaderRGBA[3] = tMult;
01544 if (ent.shaderRGBA[3] < 1)
01545 {
01546 ent.shaderRGBA[3] = 1;
01547 }
01548 }
01549
01550 ent.shaderRGBA[0] = ent.shaderRGBA[1] = ent.shaderRGBA[2] = ent.shaderRGBA[3];
01551 VectorCopy(cent->lerpOrigin, hitLoc);
01552
01553 VectorSubtract( hitLoc, ent.origin, ent.oldorigin );
01554
01555 tempLength = VectorNormalize( ent.oldorigin );
01556 vectoangles( ent.oldorigin, tempAng );
01557 tempAng[YAW] -= cent->lerpAngles[YAW];
01558 AngleVectors( tempAng, ent.oldorigin, NULL, NULL );
01559 VectorScale( ent.oldorigin, tempLength, ent.oldorigin );
01560
01561 if (lightSide)
01562 {
01563 ent.customShader = cgs.media.playerShieldDamage;
01564 }
01565 else
01566 {
01567 ent.customShader = cgs.media.redSaberGlowShader;
01568 }
01569
01570
01571
01572
01573
01574
01575
01576 trap_R_AddRefEntityToScene( &ent );
01577 ent.renderfx &= ~RF_DISINTEGRATE2;
01578 ent.customShader = 0;
01579
01580 if (curTimeDif < 3400)
01581 {
01582 if (lightSide)
01583 {
01584 if (curTimeDif < 2200)
01585 {
01586 trap_S_StartSound ( NULL, cent->currentState.number, CHAN_AUTO, trap_S_RegisterSound( "sound/weapons/saber/saberhum1.wav" ) );
01587 }
01588 }
01589 else
01590 {
01591 ent.renderfx |= RF_RGB_TINT;
01592 ent.shaderRGBA[0] = 255;
01593 ent.shaderRGBA[1] = ent.shaderRGBA[2] = 0;
01594 ent.shaderRGBA[3] = 255;
01595 if ( rand() & 1 )
01596 {
01597 ent.customShader = cgs.media.electricBodyShader;
01598 }
01599 else
01600 {
01601 ent.customShader = cgs.media.electricBody2Shader;
01602 }
01603 if ( random() > 0.9f )
01604 {
01605 trap_S_StartSound ( NULL, cent->currentState.number, CHAN_AUTO, cgs.media.crackleSound );
01606 }
01607 trap_R_AddRefEntityToScene( &ent );
01608 }
01609 }
01610
01611 return;
01612 }
01613 else
01614 {
01615 cent->dustTrailTime = 0;
01616 }
01617 }
01618
01619 if (cent->currentState.modelGhoul2 &&
01620 !ent.ghoul2 &&
01621 !ent.hModel)
01622 {
01623 return;
01624 }
01625
01626
01627 trap_R_AddRefEntityToScene (&ent);
01628
01629 if (cent->bolt3 == 999)
01630 {
01631 vec3_t org;
01632 float wv;
01633 int i;
01634 addspriteArgStruct_t fxSArgs;
01635
01636
01637
01638 ent.customShader = cgs.media.solidWhite;
01639 ent.renderfx = RF_RGB_TINT;
01640 wv = sin( cg.time * 0.003f ) * 0.08f + 0.1f;
01641 ent.shaderRGBA[0] = wv * 255;
01642 ent.shaderRGBA[1] = wv * 255;
01643 ent.shaderRGBA[2] = wv * 0;
01644 trap_R_AddRefEntityToScene (&ent);
01645
01646 for ( i = -4; i < 10; i += 1 )
01647 {
01648 VectorMA( ent.origin, -i, ent.axis[2], org );
01649
01650 VectorCopy(org, fxSArgs.origin);
01651 VectorClear(fxSArgs.vel);
01652 VectorClear(fxSArgs.accel);
01653 fxSArgs.scale = 5.5f;
01654 fxSArgs.dscale = 5.5f;
01655 fxSArgs.sAlpha = wv;
01656 fxSArgs.eAlpha = wv;
01657 fxSArgs.rotation = 0.0f;
01658 fxSArgs.bounce = 0.0f;
01659 fxSArgs.life = 1.0f;
01660 fxSArgs.shader = cgs.media.yellowDroppedSaberShader;
01661 fxSArgs.flags = 0x08000000;
01662
01663
01664 trap_FX_AddSprite(&fxSArgs);
01665 }
01666 }
01667 else if (cent->currentState.trickedentindex3)
01668 {
01669 vec3_t org;
01670 float wv;
01671 addspriteArgStruct_t fxSArgs;
01672
01673
01674
01675 ent.customShader = cgs.media.solidWhite;
01676 ent.renderfx = RF_RGB_TINT;
01677 wv = sin( cg.time * 0.005f ) * 0.08f + 0.1f;
01678
01679 if (cent->currentState.trickedentindex3 == 1)
01680 {
01681 ent.shaderRGBA[0] = wv*255;
01682 ent.shaderRGBA[1] = 0;
01683 ent.shaderRGBA[2] = 0;
01684 }
01685 else if (cent->currentState.trickedentindex3 == 2)
01686 {
01687 ent.shaderRGBA[0] = wv*255;
01688 ent.shaderRGBA[1] = wv*255;
01689 ent.shaderRGBA[2] = wv*255;
01690 }
01691 else
01692 {
01693 if ((s1->modelindex+128) == FP_SABER_OFFENSE ||
01694 (s1->modelindex+128) == FP_SABER_DEFENSE ||
01695 (s1->modelindex+128) == FP_SABERTHROW)
01696 {
01697 ent.shaderRGBA[0] = 0;
01698 ent.shaderRGBA[1] = wv*255;
01699 ent.shaderRGBA[2] = 0;
01700 }
01701 else
01702 {
01703 ent.shaderRGBA[0] = 0;
01704 ent.shaderRGBA[1] = wv*255;
01705 ent.shaderRGBA[2] = wv*255;
01706 }
01707 }
01708
01709 ent.modelScale[0] = 1.1;
01710 ent.modelScale[1] = 1.1;
01711 ent.modelScale[2] = 1.1;
01712
01713 ent.origin[2] -= 2;
01714 ScaleModelAxis(&ent);
01715
01716 trap_R_AddRefEntityToScene (&ent);
01717
01718 VectorMA( ent.origin, 1, ent.axis[2], org );
01719
01720 org[2] += 18;
01721
01722 wv = sin( cg.time * 0.002f ) * 0.08f + 0.1f;
01723
01724 VectorCopy(org, fxSArgs.origin);
01725 VectorClear(fxSArgs.vel);
01726 VectorClear(fxSArgs.accel);
01727 fxSArgs.scale = wv*120;
01728 fxSArgs.dscale = wv*120;
01729 fxSArgs.sAlpha = wv*12;
01730 fxSArgs.eAlpha = wv*12;
01731 fxSArgs.rotation = 0.0f;
01732 fxSArgs.bounce = 0.0f;
01733 fxSArgs.life = 1.0f;
01734
01735 fxSArgs.flags = 0x08000000|0x00000001;
01736
01737 if (cent->currentState.trickedentindex3 == 1)
01738 {
01739 fxSArgs.sAlpha *= 3;
01740 fxSArgs.eAlpha *= 3;
01741 fxSArgs.shader = cgs.media.redSaberGlowShader;
01742 trap_FX_AddSprite(&fxSArgs);
01743 }
01744 else if (cent->currentState.trickedentindex3 == 2)
01745 {
01746 fxSArgs.sAlpha *= 1.5;
01747 fxSArgs.eAlpha *= 1.5;
01748 fxSArgs.shader = cgs.media.redSaberGlowShader;
01749 trap_FX_AddSprite(&fxSArgs);
01750 fxSArgs.shader = cgs.media.greenSaberGlowShader;
01751 trap_FX_AddSprite(&fxSArgs);
01752 fxSArgs.shader = cgs.media.blueSaberGlowShader;
01753 trap_FX_AddSprite(&fxSArgs);
01754 }
01755 else
01756 {
01757 if ((s1->modelindex+128) == FP_SABER_OFFENSE ||
01758 (s1->modelindex+128) == FP_SABER_DEFENSE ||
01759 (s1->modelindex+128) == FP_SABERTHROW)
01760 {
01761 fxSArgs.sAlpha *= 1.5;
01762 fxSArgs.eAlpha *= 1.5;
01763 fxSArgs.shader = cgs.media.greenSaberGlowShader;
01764 trap_FX_AddSprite(&fxSArgs);
01765 }
01766 else
01767 {
01768 fxSArgs.sAlpha *= 0.5;
01769 fxSArgs.eAlpha *= 0.5;
01770 fxSArgs.shader = cgs.media.greenSaberGlowShader;
01771 trap_FX_AddSprite(&fxSArgs);
01772 fxSArgs.shader = cgs.media.blueSaberGlowShader;
01773 trap_FX_AddSprite(&fxSArgs);
01774 }
01775 }
01776 }
01777
01778 if ( cent->currentState.time == -1 && cent->currentState.weapon == WP_TRIP_MINE && (cent->currentState.eFlags & EF_FIRING) )
01779 {
01780 if (cent->currentState.bolt2 == 1)
01781 {
01782 VectorMA( ent.origin, 6.6f, ent.axis[0], beamOrg );
01783 beamID = cgs.effects.tripmineGlowFX;
01784 trap_FX_PlayEffectID( beamID, beamOrg, cent->currentState.pos.trDelta, -1, -1 );
01785 }
01786 else
01787 {
01788 int i = 0;
01789
01790 VectorMA( ent.origin, 6.6f, ent.axis[0], beamOrg );
01791 beamID = cgs.effects.tripmineLaserFX;
01792
01793 if (cg.snap->ps.fd.forcePowersActive & (1 << FP_SEE))
01794 {
01795 i = cg.snap->ps.fd.forcePowerLevel[FP_SEE];
01796
01797 while (i > 0)
01798 {
01799 trap_FX_PlayEffectID( beamID, beamOrg, cent->currentState.pos.trDelta, -1, -1 );
01800 trap_FX_PlayEffectID( beamID, beamOrg, cent->currentState.pos.trDelta, -1, -1 );
01801 i--;
01802 }
01803 }
01804
01805 trap_FX_PlayEffectID( beamID, beamOrg, cent->currentState.pos.trDelta, -1, -1 );
01806 }
01807 }
01808
01809
01810
01811
01812 if (cg_debugBB.integer)
01813 {
01814 CG_CreateBBRefEnts(s1, cent->lerpOrigin);
01815 }
01816
01817
01818
01819 }
01820
01821
01822
01823
01824
01825
01826
01827
01828 static void CG_Speaker( centity_t *cent ) {
01829 if (cent->currentState.trickedentindex)
01830 {
01831 CG_S_StopLoopingSound(cent->currentState.number, -1);
01832 }
01833
01834 if ( ! cent->currentState.clientNum ) {
01835 return;
01836 }
01837
01838 if ( cg.time < cent->miscTime ) {
01839 return;
01840 }
01841
01842 trap_S_StartSound (NULL, cent->currentState.number, CHAN_ITEM, cgs.gameSounds[cent->currentState.eventParm] );
01843
01844
01845
01846 cent->miscTime = cg.time + cent->currentState.frame * 100 + cent->currentState.clientNum * 100 * crandom();
01847 }
01848
01849 qboolean CG_GreyItem(int type, int tag, int plSide)
01850 {
01851 if (type == IT_POWERUP &&
01852 (tag == PW_FORCE_ENLIGHTENED_LIGHT || tag == PW_FORCE_ENLIGHTENED_DARK))
01853 {
01854 if (plSide == FORCE_LIGHTSIDE)
01855 {
01856 if (tag == PW_FORCE_ENLIGHTENED_DARK)
01857 {
01858 return qtrue;
01859 }
01860 }
01861 else if (plSide == FORCE_DARKSIDE)
01862 {
01863 if (tag == PW_FORCE_ENLIGHTENED_LIGHT)
01864 {
01865 return qtrue;
01866 }
01867 }
01868 }
01869
01870 return qfalse;
01871 }
01872
01873
01874
01875
01876
01877
01878 static void CG_Item( centity_t *cent ) {
01879 refEntity_t ent;
01880 entityState_t *es;
01881 gitem_t *item;
01882 int msec;
01883 float scale;
01884 weaponInfo_t *wi;
01885
01886 es = ¢->currentState;
01887 if ( es->modelindex >= bg_numItems ) {
01888 CG_Error( "Bad item index %i on entity", es->modelindex );
01889 }
01890
01891
01892
01893
01894
01895 if ((es->eFlags & EF_NODRAW) && (es->eFlags & EF_ITEMPLACEHOLDER))
01896 {
01897 es->eFlags &= ~EF_NODRAW;
01898 }
01899
01900 if ( !es->modelindex )
01901 {
01902 return;
01903 }
01904
01905 item = &bg_itemlist[ es->modelindex ];
01906
01907 if ((item->giType == IT_WEAPON || item->giType == IT_POWERUP) &&
01908 !(cent->currentState.eFlags & EF_DROPPEDWEAPON) &&
01909 !cg_simpleItems.integer)
01910 {
01911 vec3_t uNorm;
01912 qboolean doGrey;
01913
01914 VectorClear(uNorm);
01915
01916 uNorm[2] = 1;
01917
01918 memset( &ent, 0, sizeof( ent ) );
01919
01920 ent.customShader = 0;
01921 VectorCopy(cent->lerpOrigin, ent.origin);
01922 VectorCopy( cent->currentState.angles, cent->lerpAngles );
01923 AnglesToAxis(cent->lerpAngles, ent.axis);
01924 ent.hModel = cgs.media.itemHoloModel;
01925
01926 doGrey = CG_GreyItem(item->giType, item->giTag, cg.snap->ps.fd.forceSide);
01927
01928 if (doGrey)
01929 {
01930 ent.renderfx |= RF_RGB_TINT;
01931
01932 ent.shaderRGBA[0] = 150;
01933 ent.shaderRGBA[1] = 150;
01934 ent.shaderRGBA[2] = 150;
01935 }
01936
01937 trap_R_AddRefEntityToScene(&ent);
01938
01939 if (!doGrey)
01940 {
01941 trap_FX_PlayEffectID(cgs.effects.itemCone, ent.origin, uNorm, -1, -1);
01942 }
01943 }
01944
01945
01946 if ( ( es->eFlags & EF_NODRAW ) )
01947 {
01948 return;
01949 }
01950
01951
01952
01953
01954 if ( cg_simpleItems.integer && item->giType != IT_TEAM ) {
01955 memset( &ent, 0, sizeof( ent ) );
01956 ent.reType = RT_SPRITE;
01957 VectorCopy( cent->lerpOrigin, ent.origin );
01958 ent.radius = 14;
01959 ent.customShader = cg_items[es->modelindex].icon;
01960 ent.shaderRGBA[0] = 255;
01961 ent.shaderRGBA[1] = 255;
01962 ent.shaderRGBA[2] = 255;
01963
01964 ent.origin[2] += 16;
01965
01966 if (item->giType != IT_POWERUP || item->giTag != PW_FORCE_BOON)
01967 {
01968 ent.renderfx |= RF_FORCE_ENT_ALPHA;
01969 }
01970
01971 if ( es->eFlags & EF_ITEMPLACEHOLDER )
01972 {
01973 if (item->giType == IT_POWERUP && item->giTag == PW_FORCE_BOON)
01974 {
01975 return;
01976 }
01977 ent.shaderRGBA[0] = 200;
01978 ent.shaderRGBA[1] = 200;
01979 ent.shaderRGBA[2] = 200;
01980 ent.shaderRGBA[3] = 150 + sin(cg.time*0.01)*30;
01981 }
01982 else
01983 {
01984 ent.shaderRGBA[3] = 255;
01985 }
01986
01987 if (CG_GreyItem(item->giType, item->giTag, cg.snap->ps.fd.forceSide))
01988 {
01989 ent.shaderRGBA[0] = 100;
01990 ent.shaderRGBA[1] = 100;
01991 ent.shaderRGBA[2] = 100;
01992
01993 ent.shaderRGBA[3] = 200;
01994
01995 if (item->giTag == PW_FORCE_ENLIGHTENED_LIGHT)
01996 {
01997 ent.customShader = trap_R_RegisterShader("gfx/misc/mp_light_enlight_disable");
01998 }
01999 else
02000 {
02001 ent.customShader = trap_R_RegisterShader("gfx/misc/mp_dark_enlight_disable");
02002 }
02003 }
02004 trap_R_AddRefEntityToScene(&ent);
02005 return;
02006 }
02007
02008 if ((item->giType == IT_WEAPON || item->giType == IT_POWERUP) &&
02009 !(cent->currentState.eFlags & EF_DROPPEDWEAPON))
02010 {
02011 cent->lerpOrigin[2] += 16;
02012 }
02013
02014 if ((!(cent->currentState.eFlags & EF_DROPPEDWEAPON) || item->giType == IT_POWERUP) &&
02015 (item->giType == IT_WEAPON || item->giType == IT_POWERUP))
02016 {
02017
02018 scale = 0.005 + cent->currentState.number * 0.00001;
02019 cent->lerpOrigin[2] += 4 + cos( ( cg.time + 1000 ) * scale ) * 4;
02020 }
02021 else
02022 {
02023 if (item->giType == IT_HOLDABLE)
02024 {
02025 if (item->giTag == HI_SEEKER)
02026 {
02027 cent->lerpOrigin[2] += 5;
02028 }
02029 if (item->giTag == HI_SHIELD)
02030 {
02031 cent->lerpOrigin[2] += 2;
02032 }
02033 if (item->giTag == HI_BINOCULARS)
02034 {
02035 cent->lerpOrigin[2] += 2;
02036 }
02037 }
02038 if (item->giType == IT_HEALTH)
02039 {
02040 cent->lerpOrigin[2] += 2;
02041 }
02042 if (item->giType == IT_ARMOR)
02043 {
02044 if (item->quantity == 100)
02045 {
02046 cent->lerpOrigin[2] += 7;
02047 }
02048 }
02049 }
02050
02051 memset (&ent, 0, sizeof(ent));
02052
02053 if ( (!(cent->currentState.eFlags & EF_DROPPEDWEAPON) || item->giType == IT_POWERUP) &&
02054 (item->giType == IT_WEAPON || item->giType == IT_POWERUP) )
02055 {
02056
02057 VectorCopy( cg.autoAngles, cent->lerpAngles );
02058 AxisCopy( cg.autoAxis, ent.axis );
02059 }
02060 else
02061 {
02062 VectorCopy( cent->currentState.angles, cent->lerpAngles );
02063 AnglesToAxis(cent->lerpAngles, ent.axis);
02064 }
02065
02066 wi = NULL;
02067
02068
02069
02070 if (!(cent->currentState.eFlags & EF_DROPPEDWEAPON))
02071 {
02072 if ( item->giType == IT_WEAPON ) {
02073 wi = &cg_weapons[item->giTag];
02074 cent->lerpOrigin[0] -=
02075 wi->weaponMidpoint[0] * ent.axis[0][0] +
02076 wi->weaponMidpoint[1] * ent.axis[1][0] +
02077 wi->weaponMidpoint[2] * ent.axis[2][0];
02078 cent->lerpOrigin[1] -=
02079 wi->weaponMidpoint[0] * ent.axis[0][1] +
02080 wi->weaponMidpoint[1] * ent.axis[1][1] +
02081 wi->weaponMidpoint[2] * ent.axis[2][1];
02082 cent->lerpOrigin[2] -=
02083 wi->weaponMidpoint[0] * ent.axis[0][2] +
02084 wi->weaponMidpoint[1] * ent.axis[1][2] +
02085 wi->weaponMidpoint[2] * ent.axis[2][2];
02086
02087 cent->lerpOrigin[2] += 8;
02088 }
02089 }
02090 else
02091 {
02092 wi = &cg_weapons[item->giTag];
02093
02094 switch(item->giTag)
02095 {
02096 case WP_BLASTER:
02097 cent->lerpOrigin[2] -= 12;
02098 break;
02099 case WP_DISRUPTOR:
02100 cent->lerpOrigin[2] -= 13;
02101 break;
02102 case WP_BOWCASTER:
02103 cent->lerpOrigin[2] -= 16;
02104 break;
02105 case WP_REPEATER:
02106 cent->lerpOrigin[2] -= 12;
02107 break;
02108 case WP_DEMP2:
02109 cent->lerpOrigin[2] -= 10;
02110 break;
02111 case WP_FLECHETTE:
02112 cent->lerpOrigin[2] -= 6;
02113 break;
02114 case WP_ROCKET_LAUNCHER:
02115 cent->lerpOrigin[2] -= 11;
02116 break;
02117 case WP_THERMAL:
02118 cent->lerpOrigin[2] -= 12;
02119 break;
02120 case WP_TRIP_MINE:
02121 cent->lerpOrigin[2] -= 16;
02122 break;
02123 case WP_DET_PACK:
02124 cent->lerpOrigin[2] -= 16;
02125 break;
02126 default:
02127 cent->lerpOrigin[2] -= 8;
02128 break;
02129 }
02130 }
02131
02132 ent.hModel = cg_items[es->modelindex].models[0];
02133
02134
02135
02136 ent.ghoul2 = cg_items[es->modelindex].g2Models[0];
02137 ent.radius = cg_items[es->modelindex].radius[0];
02138 VectorCopy (cent->lerpAngles, ent.angles);
02139
02140
02141
02142 VectorCopy( cent->lerpOrigin, ent.origin);
02143 VectorCopy( cent->lerpOrigin, ent.oldorigin);
02144
02145 ent.nonNormalizedAxes = qfalse;
02146
02147
02148
02149 msec = cg.time - cent->miscTime;
02150
02151 if (CG_GreyItem(item->giType, item->giTag, cg.snap->ps.fd.forceSide))
02152 {
02153 ent.renderfx |= RF_RGB_TINT;
02154
02155 ent.shaderRGBA[0] = 150;
02156 ent.shaderRGBA[1] = 150;
02157 ent.shaderRGBA[2] = 150;
02158
02159 ent.renderfx |= RF_FORCE_ENT_ALPHA;
02160
02161 ent.shaderRGBA[3] = 200;
02162
02163 if (item->giTag == PW_FORCE_ENLIGHTENED_LIGHT)
02164 {
02165 ent.customShader = trap_R_RegisterShader("gfx/misc/mp_light_enlight_disable");
02166 }
02167 else
02168 {
02169 ent.customShader = trap_R_RegisterShader("gfx/misc/mp_dark_enlight_disable");
02170 }
02171
02172 trap_R_AddRefEntityToScene( &ent );
02173 return;
02174 }
02175
02176 if ( es->eFlags & EF_ITEMPLACEHOLDER )
02177 {
02178 if ( es->eFlags & EF_DEAD )
02179 return;
02180
02181 ent.renderfx |= RF_RGB_TINT;
02182 ent.shaderRGBA[0] = 0;
02183 ent.shaderRGBA[1] = 200;
02184 ent.shaderRGBA[2] = 85;
02185 ent.customShader = cgs.media.itemRespawningPlaceholder;
02186 }
02187
02188
02189 if ( item->giType == IT_WEAPON ) {
02190 VectorScale( ent.axis[0], 1.5, ent.axis[0] );
02191 VectorScale( ent.axis[1], 1.5, ent.axis[1] );
02192 VectorScale( ent.axis[2], 1.5, ent.axis[2] );
02193 ent.nonNormalizedAxes = qtrue;
02194
02195 }
02196
02197 if (!(cent->currentState.eFlags & EF_DROPPEDWEAPON) &&
02198 (item->giType == IT_WEAPON || item->giType == IT_POWERUP))
02199 {
02200 ent.renderfx |= RF_MINLIGHT;
02201 }
02202
02203 if (item->giType != IT_TEAM && msec >= 0 && msec < ITEM_SCALEUP_TIME && !(es->eFlags & EF_ITEMPLACEHOLDER) && !(es->eFlags & EF_DROPPEDWEAPON))
02204 {
02205 float alpha;
02206 int a;
02207
02208 alpha = (float)msec / ITEM_SCALEUP_TIME;
02209 a = alpha * 255.0;
02210 if (a <= 0)
02211 a=1;
02212
02213 ent.shaderRGBA[3] = a;
02214 if (item->giType != IT_POWERUP || item->giTag != PW_FORCE_BOON)
02215 {
02216 ent.renderfx |= RF_FORCE_ENT_ALPHA;
02217 }
02218 trap_R_AddRefEntityToScene(&ent);
02219
02220 ent.renderfx &= ~RF_FORCE_ENT_ALPHA;
02221
02222
02223
02224
02225
02226 a = alpha * 255.0;
02227
02228 a = 255 - a;
02229
02230 if (a <= 0)
02231 a=1;
02232 if (a > 255)
02233 a=255;
02234
02235 ent.customShader = cgs.media.itemRespawningRezOut;
02236
02237
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252
02253
02254 ent.renderfx |= RF_RGB_TINT;
02255 ent.shaderRGBA[0] = 0;
02256 ent.shaderRGBA[1] = 200;
02257 ent.shaderRGBA[2] = 85;
02258
02259 trap_R_AddRefEntityToScene( &ent );
02260 }
02261 else
02262 {
02263 if (item->giType == IT_TEAM &&
02264 (item->giTag == PW_REDFLAG || item->giTag == PW_BLUEFLAG))
02265 {
02266 ent.modelScale[0] = 0.7;
02267 ent.modelScale[1] = 0.7;
02268 ent.modelScale[2] = 0.7;
02269 ScaleModelAxis(&ent);
02270 }
02271 trap_R_AddRefEntityToScene(&ent);
02272 }
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299 if ( !cg_simpleItems.integer )
02300 {
02301 vec3_t spinAngles;
02302
02303 VectorClear( spinAngles );
02304
02305 if ( item->giType == IT_HEALTH || item->giType == IT_POWERUP )
02306 {
02307 if ( ( ent.hModel = cg_items[es->modelindex].models[1] ) != 0 )
02308 {
02309 if ( item->giType == IT_POWERUP )
02310 {
02311 ent.origin[2] += 12;
02312 spinAngles[1] = ( cg.time & 1023 ) * 360 / -1024.0f;
02313 }
02314 AnglesToAxis( spinAngles, ent.axis );
02315
02316 trap_R_AddRefEntityToScene( &ent );
02317 }
02318 }
02319 }
02320 }
02321
02322
02323
02324 void CG_CreateDistortionTrailPart(centity_t *cent, float scale, vec3_t pos)
02325 {
02326 refEntity_t ent;
02327 vec3_t ang;
02328 float vLen;
02329
02330 if (!cg_renderToTextureFX.integer)
02331 {
02332 return;
02333 }
02334 memset( &ent, 0, sizeof( ent ) );
02335
02336 VectorCopy( pos, ent.origin );
02337
02338 VectorSubtract(ent.origin, cg.refdef.vieworg, ent.axis[0]);
02339 vLen = VectorLength(ent.axis[0]);
02340 if (VectorNormalize(ent.axis[0]) <= 0.1f)
02341 {
02342 return;
02343 }
02344
02345 VectorCopy(cent->lerpAngles, ang);
02346 ang[PITCH] += 90.0f;
02347 AnglesToAxis(ang, ent.axis);
02348
02349
02350 if (vLen < 512)
02351 {
02352 ent.radius = 256;
02353 }
02354 else if (vLen < 1024)
02355 {
02356 ent.radius = 128;
02357 }
02358 else if (vLen < 2048)
02359 {
02360 ent.radius = 64;
02361 }
02362 else
02363 {
02364 ent.radius = 32;
02365 }
02366
02367 ent.modelScale[0] = scale;
02368 ent.modelScale[1] = scale;
02369 ent.modelScale[2] = scale*16.0f;
02370 ScaleModelAxis(&ent);
02371
02372 ent.hModel = trap_R_RegisterModel("models/weapons2/merr_sonn/trailmodel.md3");
02373 ent.customShader = cgs.media.itemRespawningRezOut;
02374
02375 #if 1
02376 ent.renderfx = (RF_DISTORTION|RF_FORCE_ENT_ALPHA);
02377 ent.shaderRGBA[0] = 255.0f;
02378 ent.shaderRGBA[1] = 255.0f;
02379 ent.shaderRGBA[2] = 255.0f;
02380 ent.shaderRGBA[3] = 100.0f;
02381 #else //no alpha
02382 ent.renderfx = RF_DISTORTION;
02383 #endif
02384
02385 trap_R_AddRefEntityToScene( &ent );
02386 }
02387
02388
02389
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419 static void CG_Missile( centity_t *cent ) {
02420 refEntity_t ent;
02421 entityState_t *s1;
02422 const weaponInfo_t *weapon;
02423
02424
02425 s1 = ¢->currentState;
02426 if ( s1->weapon > WP_NUM_WEAPONS && s1->weapon != G2_MODEL_PART ) {
02427 s1->weapon = 0;
02428 }
02429
02430 if (cent->ghoul2 && s1->weapon == G2_MODEL_PART)
02431 {
02432 weapon = &cg_weapons[WP_SABER];
02433 }
02434 else
02435 {
02436 weapon = &cg_weapons[s1->weapon];
02437 }
02438
02439 if (cent->currentState.eFlags & EF_RADAROBJECT)
02440 {
02441 CG_AddRadarEnt(cent);
02442 }
02443
02444 if (s1->weapon == WP_SABER)
02445 {
02446 if ((cent->currentState.modelindex != cent->serverSaberHitIndex || !cent->ghoul2) && !(s1->eFlags & EF_NODRAW))
02447 {
02448 const char *saberModel = CG_ConfigString( CS_MODELS+cent->currentState.modelindex );
02449
02450 cent->serverSaberHitIndex = cent->currentState.modelindex;
02451
02452 if (cent->ghoul2)
02453 {
02454 trap_G2API_CleanGhoul2Models(&(cent->ghoul2));
02455 cent->ghoul2 = 0;
02456 }
02457
02458 if (saberModel && saberModel[0])
02459 {
02460 trap_G2API_InitGhoul2Model(¢->ghoul2, saberModel, 0, 0, 0, 0, 0);
02461 }
02462 else
02463 {
02464 trap_G2API_InitGhoul2Model(¢->ghoul2, "models/weapons2/saber/saber_w.glm", 0, 0, 0, 0, 0);
02465 }
02466 return;
02467 }
02468 else if (s1->eFlags & EF_NODRAW)
02469 {
02470 return;
02471 }
02472 }
02473
02474 if (cent->ghoul2)
02475 {
02476 ent.radius = cent->currentState.g2radius;
02477 }
02478
02479
02480 VectorCopy( s1->angles, cent->lerpAngles);
02481
02482 if ( s1->otherEntityNum2 && s1->weapon != WP_SABER )
02483 {
02484 vec3_t forward;
02485
02486 if ( VectorNormalize2( cent->currentState.pos.trDelta, forward ) == 0.0f )
02487 {
02488 forward[2] = 1.0f;
02489 }
02490 if ((s1->eFlags&EF_JETPACK_ACTIVE)
02491 && (g_vehWeaponInfo[s1->otherEntityNum2].iShotFX
02492 || g_vehWeaponInfo[s1->otherEntityNum2].iModel != NULL_HANDLE) )
02493 {
02494 trap_FX_PlayEffectID( g_vehWeaponInfo[s1->otherEntityNum2].iShotFX, cent->lerpOrigin, forward, -1, -1 );
02495 if ( g_vehWeaponInfo[s1->otherEntityNum2].iLoopSound )
02496 {
02497 vec3_t velocity;
02498 BG_EvaluateTrajectoryDelta( ¢->currentState.pos, cg.time, velocity );
02499 trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, velocity, g_vehWeaponInfo[s1->otherEntityNum2].iLoopSound );
02500 }
02501
02502 if ( g_vehWeaponInfo[s1->otherEntityNum2].iModel == NULL_HANDLE )
02503 {
02504 return;
02505 }
02506 }
02507 else
02508 {
02509 trap_FX_PlayEffectID( cgs.gameEffects[s1->otherEntityNum2], cent->lerpOrigin, forward, -1, -1 );
02510 if ( s1->loopSound )
02511 {
02512 vec3_t velocity;
02513 BG_EvaluateTrajectoryDelta( ¢->currentState.pos, cg.time, velocity );
02514 trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, velocity, s1->loopSound );
02515 }
02516
02517 return;
02518 }
02519 }
02520 else if ( cent->currentState.eFlags & EF_ALT_FIRING )
02521 {
02522
02523 if ( weapon->altMissileTrailFunc )
02524 {
02525 weapon->altMissileTrailFunc( cent, weapon );
02526 }
02527
02528
02529 if ( weapon->altMissileDlight )
02530 {
02531 trap_R_AddLightToScene(cent->lerpOrigin, weapon->altMissileDlight,
02532 weapon->altMissileDlightColor[0], weapon->altMissileDlightColor[1], weapon->altMissileDlightColor[2] );
02533 }
02534
02535
02536 if ( weapon->altMissileSound ) {
02537 vec3_t velocity;
02538
02539 BG_EvaluateTrajectoryDelta( ¢->currentState.pos, cg.time, velocity );
02540
02541 trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, velocity, weapon->altMissileSound );
02542 }
02543
02544
02545 if ( weapon->altMissileModel == NULL_HANDLE )
02546 return;
02547 }
02548 else
02549 {
02550
02551 if ( weapon->missileTrailFunc )
02552 {
02553 weapon->missileTrailFunc( cent, weapon );
02554 }
02555
02556
02557 if ( weapon->missileDlight )
02558 {
02559 trap_R_AddLightToScene(cent->lerpOrigin, weapon->missileDlight,
02560 weapon->missileDlightColor[0], weapon->missileDlightColor[1], weapon->missileDlightColor[2] );
02561 }
02562
02563
02564 if ( weapon->missileSound )
02565 {
02566 vec3_t velocity;
02567
02568 BG_EvaluateTrajectoryDelta( ¢->currentState.pos, cg.time, velocity );
02569
02570 trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, velocity, weapon->missileSound );
02571 }
02572
02573
02574 if ( weapon->missileModel == NULL_HANDLE && s1->weapon != WP_SABER && s1->weapon != G2_MODEL_PART )
02575 return;
02576 }
02577
02578
02579 memset (&ent, 0, sizeof(ent));
02580 VectorCopy( cent->lerpOrigin, ent.origin);
02581 VectorCopy( cent->lerpOrigin, ent.oldorigin);
02582
02583
02584
02585 CG_SetGhoul2Info(&ent, cent);
02586
02587
02588
02589
02590
02591
02592 ent.skinNum = cg.clientFrame & 1;
02593 ent.renderfx = RF_NOSHADOW;
02594
02595 if ( !(s1->eFlags&EF_JETPACK_ACTIVE) )
02596 {
02597 if (s1->weapon != WP_SABER && s1->weapon != G2_MODEL_PART)
02598 {
02599
02600
02601 if ( cent->currentState.eFlags & EF_ALT_FIRING )
02602 {
02603 ent.hModel = weapon->altMissileModel;
02604 }
02605 else
02606 {
02607 ent.hModel = weapon->missileModel;
02608 }
02609 }
02610 }
02611
02612 else
02613 {
02614 if ( g_vehWeaponInfo[s1->otherEntityNum2].iModel != NULL_HANDLE )
02615 {
02616 ent.hModel = g_vehWeaponInfo[s1->otherEntityNum2].iModel;
02617 }
02618 else
02619 {
02620 return;
02621 }
02622 }
02623
02624
02625 if ( s1->apos.trType != TR_INTERPOLATE )
02626 {
02627
02628 if ( VectorNormalize2( s1->pos.trDelta, ent.axis[0] ) == 0 ) {
02629 ent.axis[0][2] = 1;
02630 }
02631
02632
02633 if ( s1->pos.trType != TR_STATIONARY )
02634 {
02635 if ( s1->eFlags & EF_MISSILE_STICK )
02636 {
02637 RotateAroundDirection( ent.axis, cg.time * 0.5f );
02638 }
02639 else
02640 {
02641 RotateAroundDirection( ent.axis, cg.time * 0.25f );
02642 }
02643 }
02644 else
02645 {
02646 if ( s1->eFlags & EF_MISSILE_STICK )
02647 {
02648 RotateAroundDirection( ent.axis, (float)s1->pos.trTime * 0.5f );
02649 }
02650 else
02651 {
02652 RotateAroundDirection( ent.axis, (float)s1->time );
02653 }
02654 }
02655 }
02656 else
02657 {
02658 AnglesToAxis( cent->lerpAngles, ent.axis );
02659 }
02660
02661 if (s1->weapon == WP_SABER)
02662 {
02663 ent.radius = s1->g2radius;
02664 }
02665
02666
02667 CG_AddRefEntityWithPowerups( &ent, s1, TEAM_FREE );
02668
02669 if (s1->weapon == WP_SABER && cgs.gametype == GT_JEDIMASTER)
02670 {
02671 vec3_t org;
02672 float wv;
02673 int i;
02674 addspriteArgStruct_t fxSArgs;
02675
02676
02677
02678 ent.customShader = cgs.media.solidWhite;
02679 ent.renderfx = RF_RGB_TINT;
02680 wv = sin( cg.time * 0.003f ) * 0.08f + 0.1f;
02681 ent.shaderRGBA[0] = wv * 255;
02682 ent.shaderRGBA[1] = wv * 255;
02683 ent.shaderRGBA[2] = wv * 0;
02684 trap_R_AddRefEntityToScene (&ent);
02685
02686 for ( i = -4; i < 10; i += 1 )
02687 {
02688 VectorMA( ent.origin, -i, ent.axis[2], org );
02689
02690 VectorCopy(org, fxSArgs.origin);
02691 VectorClear(fxSArgs.vel);
02692 VectorClear(fxSArgs.accel);
02693 fxSArgs.scale = 5.5f;
02694 fxSArgs.dscale = 5.5f;
02695 fxSArgs.sAlpha = wv;
02696 fxSArgs.eAlpha = wv;
02697 fxSArgs.rotation = 0.0f;
02698 fxSArgs.bounce = 0.0f;
02699 fxSArgs.life = 1.0f;
02700 fxSArgs.shader = cgs.media.yellowDroppedSaberShader;
02701 fxSArgs.flags = 0x08000000;
02702
02703
02704 trap_FX_AddSprite(&fxSArgs);
02705 }
02706
02707 if (cgs.gametype == GT_JEDIMASTER)
02708 {
02709 ent.shaderRGBA[0] = 255;
02710 ent.shaderRGBA[1] = 255;
02711 ent.shaderRGBA[2] = 0;
02712
02713 ent.renderfx |= RF_DEPTHHACK;
02714 ent.customShader = cgs.media.forceSightBubble;
02715
02716 trap_R_AddRefEntityToScene( &ent );
02717 }
02718 }
02719
02720 if ( s1->eFlags & EF_FIRING )
02721 {
02722 vec3_t beamOrg;
02723
02724 VectorMA( ent.origin, 8, ent.axis[0], beamOrg );
02725 trap_FX_PlayEffectID( cgs.effects.mTripMineLaster, beamOrg, ent.axis[0], -1, -1 );
02726 }
02727 }
02728
02729 int CG_BMS_START = 0;
02730 int CG_BMS_MID = 1;
02731 int CG_BMS_END = 2;
02732
02733
02734
02735
02736
02737
02738
02739 void CG_PlayDoorLoopSound( centity_t *cent )
02740 {
02741 sfxHandle_t sfx;
02742 const char *soundSet;
02743 vec3_t origin;
02744 float *v;
02745
02746 if ( !cent->currentState.soundSetIndex )
02747 {
02748 return;
02749 }
02750
02751 soundSet = CG_ConfigString( CS_AMBIENT_SET + cent->currentState.soundSetIndex );
02752
02753 if (!soundSet || !soundSet[0])
02754 {
02755 return;
02756 }
02757
02758 sfx = trap_AS_GetBModelSound( soundSet, CG_BMS_MID );
02759
02760 if ( sfx == -1 )
02761 {
02762 return;
02763 }
02764
02765 if (cent->currentState.eType == ET_MOVER)
02766 {
02767 v = cgs.inlineModelMidpoints[ cent->currentState.modelindex ];
02768 VectorAdd( cent->lerpOrigin, v, origin );
02769 }
02770 else
02771 {
02772 VectorCopy(cent->lerpOrigin, origin);
02773 }
02774
02775
02776 CG_S_AddRealLoopingSound(cent->currentState.number, origin, vec3_origin, sfx);
02777 }
02778
02779
02780
02781
02782
02783
02784
02785 void CG_PlayDoorSound( centity_t *cent, int type )
02786 {
02787 sfxHandle_t sfx;
02788 const char *soundSet;
02789
02790 if ( !cent->currentState.soundSetIndex )
02791 {
02792 return;
02793 }
02794
02795 soundSet = CG_ConfigString( CS_AMBIENT_SET + cent->currentState.soundSetIndex );
02796
02797 if (!soundSet || !soundSet[0])
02798 {
02799 return;
02800 }
02801
02802 sfx = trap_AS_GetBModelSound( soundSet, type );
02803
02804 if ( sfx == -1 )
02805 {
02806 return;
02807 }
02808
02809 trap_S_StartSound( NULL, cent->currentState.number, CHAN_AUTO, sfx );
02810 }
02811
02812
02813
02814
02815
02816
02817 static void CG_Mover( centity_t *cent ) {
02818 refEntity_t ent;
02819 entityState_t *s1;
02820
02821 s1 = ¢->currentState;
02822
02823
02824 memset (&ent, 0, sizeof(ent));
02825
02826 if ( (cent->currentState.eFlags2&EF2_HYPERSPACE) )
02827 {
02828 qboolean drawMe = qfalse;
02829 if ( cg.predictedPlayerState.m_iVehicleNum
02830 && cg.predictedVehicleState.hyperSpaceTime
02831 && (cg.time-cg.predictedVehicleState.hyperSpaceTime) < HYPERSPACE_TIME
02832 && (cg.time-cg.predictedVehicleState.hyperSpaceTime) > 1000 )
02833 {
02834 if ( cg.snap
02835 && cg.snap->ps.pm_type == PM_INTERMISSION )
02836 {
02837 }
02838 else if ( (cg.predictedVehicleState.eFlags2&EF2_HYPERSPACE) )
02839 {
02840 float timeFrac = ((float)(cg.time-cg.predictedVehicleState.hyperSpaceTime-1000))/(HYPERSPACE_TIME-1000);
02841 if ( timeFrac < (HYPERSPACE_TELEPORT_FRAC+0.1f) )
02842 {
02843 const float alpha = timeFrac<0.5f?timeFrac/0.5f:1.0f;
02844 drawMe = qtrue;
02845 VectorMA( cg.refdef.vieworg, 1000.0f+((1.0f-timeFrac)*1000.0f), cg.refdef.viewaxis[0], cent->lerpOrigin );
02846 VectorSet( cent->lerpAngles, cg.refdef.viewangles[PITCH], cg.refdef.viewangles[YAW]-90.0f, 0 );
02847 ent.shaderRGBA[0] = ent.shaderRGBA[1] = ent.shaderRGBA[2] = 255;
02848 ent.shaderRGBA[3] = alpha*255;
02849 }
02850 }
02851 }
02852 if ( !drawMe )
02853 {
02854 return;
02855 }
02856 }
02857
02858 if (cent->currentState.eFlags & EF_RADAROBJECT)
02859 {
02860 CG_AddRadarEnt(cent);
02861 }
02862
02863 VectorCopy( cent->lerpOrigin, ent.origin);
02864 VectorCopy( cent->lerpOrigin, ent.oldorigin);
02865 AnglesToAxis( cent->lerpAngles, ent.axis );
02866
02867 ent.renderfx = RF_NOSHADOW;
02868
02869
02870
02871
02872 CG_SetGhoul2Info(&ent, cent);
02873
02874
02875
02876
02877 ent.skinNum = ( cg.time >> 6 ) & 1;
02878
02879
02880 if ( s1->solid == SOLID_BMODEL )
02881 {
02882 ent.hModel = cgs.inlineDrawModel[s1->modelindex];
02883 }
02884 else
02885 {
02886 ent.hModel = cgs.gameModels[s1->modelindex];
02887 }
02888
02889 if ( s1->eFlags & EF_SHADER_ANIM )
02890 {
02891 ent.renderfx|=RF_SETANIMINDEX;
02892 ent.skinNum = s1->frame;
02893
02894 }
02895
02896
02897 trap_R_AddRefEntityToScene(&ent);
02898
02899
02900 if ( s1->modelindex2 )
02901 {
02902 ent.skinNum = 0;
02903 ent.hModel = cgs.gameModels[s1->modelindex2];
02904 if (s1->iModelScale)
02905 {
02906 ent.modelScale[0] = ent.modelScale[1] = ent.modelScale[2] = s1->iModelScale/100.0f;
02907 ScaleModelAxis(&ent);
02908 }
02909 trap_R_AddRefEntityToScene(&ent);
02910 }
02911
02912 }
02913
02914
02915
02916
02917
02918
02919
02920
02921 void CG_Beam( centity_t *cent ) {
02922 refEntity_t ent;
02923 entityState_t *s1;
02924
02925 s1 = ¢->currentState;
02926
02927
02928 memset (&ent, 0, sizeof(ent));
02929 VectorCopy( s1->pos.trBase, ent.origin );
02930 VectorCopy( s1->origin2, ent.oldorigin );
02931 AxisClear( ent.axis );
02932 ent.reType = RT_BEAM;
02933
02934 ent.renderfx = RF_NOSHADOW;
02935
02936
02937
02938 CG_SetGhoul2Info(&ent, cent);
02939
02940
02941
02942
02943
02944 trap_R_AddRefEntityToScene(&ent);
02945 }
02946
02947
02948
02949
02950
02951
02952
02953 static void CG_Portal( centity_t *cent ) {
02954 refEntity_t ent;
02955 entityState_t *s1;
02956
02957 s1 = ¢->currentState;
02958
02959
02960 memset (&ent, 0, sizeof(ent));
02961 VectorCopy( cent->lerpOrigin, ent.origin );
02962 VectorCopy( s1->origin2, ent.oldorigin );
02963 ByteToDir( s1->eventParm, ent.axis[0] );
02964 PerpendicularVector( ent.axis[1], ent.axis[0] );
02965
02966
02967
02968 VectorSubtract( vec3_origin, ent.axis[1], ent.axis[1] );
02969
02970 CrossProduct( ent.axis[0], ent.axis[1], ent.axis[2] );
02971 ent.reType = RT_PORTALSURFACE;
02972 ent.oldframe = s1->powerups;
02973 ent.frame = s1->frame;
02974 ent.skinNum = s1->clientNum/256.0 * 360;
02975
02976
02977
02978 CG_SetGhoul2Info(&ent, cent);
02979
02980
02981
02982
02983 trap_R_AddRefEntityToScene(&ent);
02984 }
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994 void CG_AdjustPositionForMover( const vec3_t in, int moverNum, int fromTime, int toTime, vec3_t out ) {
02995 centity_t *cent;
02996 vec3_t oldOrigin, origin, deltaOrigin;
02997 vec3_t oldAngles, angles, deltaAngles;
02998
02999 if ( moverNum <= 0 || moverNum >= ENTITYNUM_MAX_NORMAL ) {
03000 VectorCopy( in, out );
03001 return;
03002 }
03003
03004 cent = &cg_entities[ moverNum ];
03005 if ( cent->currentState.eType != ET_MOVER ) {
03006 VectorCopy( in, out );
03007 return;
03008 }
03009
03010 BG_EvaluateTrajectory( ¢->currentState.pos, fromTime, oldOrigin );
03011 BG_EvaluateTrajectory( ¢->currentState.apos, fromTime, oldAngles );
03012
03013 BG_EvaluateTrajectory( ¢->currentState.pos, toTime, origin );
03014 BG_EvaluateTrajectory( ¢->currentState.apos, toTime, angles );
03015
03016 VectorSubtract( origin, oldOrigin, deltaOrigin );
03017 VectorSubtract( angles, oldAngles, deltaAngles );
03018
03019 VectorAdd( in, deltaOrigin, out );
03020
03021
03022 }
03023
03024
03025
03026
03027
03028
03029 static void CG_InterpolateEntityPosition( centity_t *cent ) {
03030 vec3_t current, next;
03031 float f;
03032
03033
03034
03035 if ( cg.nextSnap == NULL ) {
03036 CG_Error( "CG_InterpoateEntityPosition: cg.nextSnap == NULL" );
03037 }
03038
03039 f = cg.frameInterpolation;
03040
03041
03042
03043 BG_EvaluateTrajectory( ¢->currentState.pos, cg.snap->serverTime, current );
03044 BG_EvaluateTrajectory( ¢->nextState.pos, cg.nextSnap->serverTime, next );
03045
03046 cent->lerpOrigin[0] = current[0] + f * ( next[0] - current[0] );
03047 cent->lerpOrigin[1] = current[1] + f * ( next[1] - current[1] );
03048 cent->lerpOrigin[2] = current[2] + f * ( next[2] - current[2] );
03049
03050 BG_EvaluateTrajectory( ¢->currentState.apos, cg.snap->serverTime, current );
03051 BG_EvaluateTrajectory( ¢->nextState.apos, cg.nextSnap->serverTime, next );
03052
03053 cent->lerpAngles[0] = LerpAngle( current[0], next[0], f );
03054 cent->lerpAngles[1] = LerpAngle( current[1], next[1], f );
03055 cent->lerpAngles[2] = LerpAngle( current[2], next[2], f );
03056 }
03057
03058
03059
03060
03061
03062
03063
03064 void CG_CalcEntityLerpPositions( centity_t *cent ) {
03065 qboolean goAway = qfalse;
03066
03067
03068 if ( !cg_smoothClients.integer ) {
03069
03070 if ( cent->currentState.number < MAX_CLIENTS ) {
03071 cent->currentState.pos.trType = TR_INTERPOLATE;
03072 cent->nextState.pos.trType = TR_INTERPOLATE;
03073 }
03074 }
03075
03076 if (cg.predictedPlayerState.m_iVehicleNum &&
03077 cg.predictedPlayerState.m_iVehicleNum == cent->currentState.number &&
03078 cent->currentState.eType == ET_NPC && cent->currentState.NPC_class == CLASS_VEHICLE)
03079 {
03080 centity_t *veh = &cg_entities[cg.predictedPlayerState.m_iVehicleNum];
03081
03082 if (veh->currentState.owner == cg.predictedPlayerState.clientNum)
03083 {
03084 BG_EvaluateTrajectory( ¢->currentState.pos, cg.time, cent->lerpOrigin );
03085 BG_EvaluateTrajectory( ¢->currentState.apos, cg.time, cent->lerpAngles );
03086 return;
03087 }
03088 }
03089
03090 if ( cent->interpolate && cent->currentState.pos.trType == TR_INTERPOLATE ) {
03091 CG_InterpolateEntityPosition( cent );
03092 return;
03093 }
03094
03095
03096
03097 if ( cent->interpolate && cent->currentState.pos.trType == TR_LINEAR_STOP &&
03098 cent->currentState.number < MAX_CLIENTS) {
03099 CG_InterpolateEntityPosition( cent );
03100 goAway = qtrue;
03101 }
03102 else if (cent->interpolate &&
03103 cent->currentState.eType == ET_NPC && cent->currentState.NPC_class == CLASS_VEHICLE)
03104 {
03105 CG_InterpolateEntityPosition( cent );
03106 goAway = qtrue;
03107 }
03108 else
03109 {
03110
03111 BG_EvaluateTrajectory( ¢->currentState.pos, cg.time, cent->lerpOrigin );
03112 BG_EvaluateTrajectory( ¢->currentState.apos, cg.time, cent->lerpAngles );
03113 }
03114
03115 #if 0
03116 if (cent->hasRagOffset && cent->ragOffsetTime < cg.time)
03117 {
03118 vec3_t slideDir;
03119 vec3_t preOffset;
03120 vec3_t addedOffset;
03121 vec3_t playerMins = {-15, -15, DEFAULT_MINS_2};
03122 vec3_t playerMaxs = {15, 15, DEFAULT_MAXS_2};
03123 trace_t tr;
03124
03125
03126 VectorCopy(cent->ragOffsets, slideDir);
03127 VectorNormalize(slideDir);
03128
03129
03130 VectorCopy(cent->lerpOriginOffset, preOffset);
03131
03132
03133 VectorMA(cent->lerpOriginOffset, 0.4f, slideDir, cent->lerpOriginOffset);
03134
03135 if (VectorLength(cent->lerpOriginOffset) > 10.0f)
03136 {
03137 VectorCopy(preOffset, cent->lerpOriginOffset);
03138 }
03139 else
03140 {
03141
03142 VectorAdd(cent->lerpOrigin, cent->lerpOriginOffset, addedOffset);
03143 CG_Trace(&tr, cent->lerpOrigin, playerMins, playerMaxs, addedOffset, cent->currentState.number, MASK_PLAYERSOLID);
03144
03145 if (tr.startsolid || tr.allsolid || tr.fraction != 1.0f)
03146 {
03147 VectorCopy(preOffset, cent->lerpOriginOffset);
03148 }
03149 else
03150 {
03151
03152
03153
03154
03155
03156
03157
03158 cent->lerpOriginOffset[2] = 0.0f;
03159 }
03160 }
03161
03162
03163 cent->hasRagOffset = qfalse;
03164 VectorClear(cent->ragOffsets);
03165 cent->ragOffsetTime = cg.time + 50;
03166 }
03167
03168
03169 if (cent->isRagging && ((cent->currentState.eFlags & EF_DEAD) || (cent->currentState.eFlags & EF_RAG)))
03170 {
03171 VectorAdd(cent->lerpOrigin, cent->lerpOriginOffset, cent->lerpOrigin);
03172 }
03173 #endif
03174
03175 if (goAway)
03176 {
03177 return;
03178 }
03179
03180
03181
03182 if ( cent->currentState.number != cg.predictedPlayerState.clientNum ) {
03183 CG_AdjustPositionForMover( cent->lerpOrigin, cent->currentState.groundEntityNum,
03184 cg.snap->serverTime, cg.time, cent->lerpOrigin );
03185 }
03186 }
03187
03188
03189
03190
03191
03192
03193 static void CG_TeamBase( centity_t *cent ) {
03194 refEntity_t model;
03195 if ( cgs.gametype == GT_CTF || cgs.gametype == GT_CTY ) {
03196
03197 memset(&model, 0, sizeof(model));
03198 model.reType = RT_MODEL;
03199 VectorCopy( cent->lerpOrigin, model.lightingOrigin );
03200 VectorCopy( cent->lerpOrigin, model.origin );
03201 AnglesToAxis( cent->currentState.angles, model.axis );
03202 if ( cent->currentState.modelindex == TEAM_RED ) {
03203 model.hModel = cgs.media.redFlagBaseModel;
03204 }
03205 else if ( cent->currentState.modelindex == TEAM_BLUE ) {
03206 model.hModel = cgs.media.blueFlagBaseModel;
03207 }
03208 else {
03209 model.hModel = cgs.media.neutralFlagBaseModel;
03210 }
03211
03212 if (cent->currentState.eType != ET_NPC)
03213 {
03214 trap_R_AddRefEntityToScene( &model );
03215 }
03216 }
03217 }
03218
03219 void CG_G2Animated( centity_t *cent );
03220
03221 static void CG_FX( centity_t *cent )
03222 {
03223 vec3_t fxDir;
03224 int efxIndex = 0;
03225 entityState_t *s1;
03226 const char *s;
03227
03228 if (cent->miscTime > cg.time)
03229 {
03230 return;
03231 }
03232
03233 s1 = ¢->currentState;
03234
03235 if (!s1)
03236 {
03237 return;
03238 }
03239
03240 if (s1->modelindex2 == FX_STATE_OFF)
03241 {
03242 return;
03243 }
03244
03245 if (s1->modelindex2 < FX_STATE_ONE_SHOT_LIMIT)
03246 {
03247 if (cent->muzzleFlashTime == s1->modelindex2)
03248 {
03249 return;
03250 }
03251
03252 cent->muzzleFlashTime = s1->modelindex2;
03253 }
03254
03255 cent->miscTime = cg.time + s1->speed + random() * s1->time;
03256
03257 AngleVectors(s1->angles, fxDir, 0, 0);
03258
03259 if (!fxDir[0] && !fxDir[1] && !fxDir[2])
03260 {
03261 fxDir[1] = 1;
03262 }
03263
03264 if ( cgs.gameEffects[ s1->modelindex ] )
03265 {
03266 efxIndex = cgs.gameEffects[s1->modelindex];
03267 }
03268 else
03269 {
03270 s = CG_ConfigString( CS_EFFECTS + s1->modelindex );
03271 if (s && s[0])
03272 {
03273 efxIndex = trap_FX_RegisterEffect(s);
03274 cgs.gameEffects[s1->modelindex] = efxIndex;
03275 }
03276 }
03277
03278 if (efxIndex)
03279 {
03280 if (s1->isPortalEnt)
03281 {
03282 trap_FX_PlayPortalEffectID(efxIndex, cent->lerpOrigin, fxDir, -1, -1 );
03283 }
03284 else
03285 {
03286 trap_FX_PlayEffectID(efxIndex, cent->lerpOrigin, fxDir, -1, -1 );
03287 }
03288 }
03289
03290
03291 }
03292
03293
03294
03295
03296
03297
03298
03299
03300 static void CG_AddCEntity( centity_t *cent ) {
03301
03302 if ( cent->currentState.eType >= ET_EVENTS ) {
03303 return;
03304 }
03305
03306 if (cg.predictedPlayerState.pm_type == PM_INTERMISSION)
03307 {
03308 if (cent->currentState.eType == ET_GENERAL ||
03309 cent->currentState.eType == ET_PLAYER ||
03310 cent->currentState.eType == ET_INVISIBLE)
03311 {
03312 return;
03313 }
03314 if ( cent->currentState.eType == ET_NPC )
03315 {
03316 if ( cent->currentState.NPC_class == CLASS_VEHICLE )
03317 {
03318 return;
03319 }
03320 }
03321 }
03322
03323
03324 CG_CalcEntityLerpPositions( cent );
03325
03326
03327 CG_EntityEffects( cent );
03328
03329
03330
03331
03332
03333 if ( cent->currentState.soundSetIndex && cent->currentState.eType != ET_MOVER )
03334 {
03335 const char *soundSet = CG_ConfigString( CS_AMBIENT_SET + cent->currentState.soundSetIndex );
03336
03337 if (soundSet && soundSet[0])
03338 {
03339 trap_S_AddLocalSet(soundSet, cg.refdef.vieworg, cent->lerpOrigin, cent->currentState.number, cg.time);
03340 }
03341 }
03342
03343
03344
03345 switch ( cent->currentState.eType ) {
03346 default:
03347 CG_Error( "Bad entity type: %i\n", cent->currentState.eType );
03348 break;
03349
03350 case ET_FX:
03351 CG_FX( cent );
03352 break;
03353
03354 case ET_INVISIBLE:
03355 case ET_PUSH_TRIGGER:
03356 case ET_TELEPORT_TRIGGER:
03357 case ET_TERRAIN:
03358 break;
03359 case ET_GENERAL:
03360 CG_General( cent );
03361 break;
03362 case ET_PLAYER:
03363 CG_Player( cent );
03364 break;
03365 case ET_ITEM:
03366 CG_Item( cent );
03367 break;
03368 case ET_MISSILE:
03369 CG_Missile( cent );
03370 break;
03371 case ET_SPECIAL:
03372 CG_Special( cent );
03373 break;
03374 case ET_HOLOCRON:
03375 CG_General( cent );
03376 break;
03377 case ET_MOVER:
03378 CG_Mover( cent );
03379 break;
03380 case ET_BEAM:
03381 CG_Beam( cent );
03382 break;
03383 case ET_PORTAL:
03384 CG_Portal( cent );
03385 break;
03386 case ET_SPEAKER:
03387 CG_Speaker( cent );
03388 break;
03389 case ET_NPC:
03390 CG_G2Animated( cent );
03391 break;
03392 case ET_TEAM:
03393 CG_TeamBase( cent );
03394 break;
03395 case ET_BODY:
03396 CG_General( cent );
03397 break;
03398 }
03399 }
03400
03401 void CG_ManualEntityRender(centity_t *cent)
03402 {
03403 CG_AddCEntity(cent);
03404 }
03405
03406
03407
03408
03409
03410
03411
03412 void CG_AddPacketEntities( qboolean isPortal ) {
03413 int num;
03414 centity_t *cent;
03415 playerState_t *ps;
03416
03417 if (isPortal)
03418 {
03419 for ( num = 0 ; num < cg.snap->numEntities ; num++ )
03420 {
03421 cent = &cg_entities[ cg.snap->entities[ num ].number ];
03422
03423 if (cent->currentState.isPortalEnt)
03424 {
03425 CG_AddCEntity( cent );
03426 }
03427 }
03428 return;
03429 }
03430
03431
03432 if ( cg.nextSnap ) {
03433 int delta;
03434
03435 delta = (cg.nextSnap->serverTime - cg.snap->serverTime);
03436 if ( delta == 0 ) {
03437 cg.frameInterpolation = 0;
03438 } else {
03439 cg.frameInterpolation = (float)( cg.time - cg.snap->serverTime ) / delta;
03440 }
03441 } else {
03442 cg.frameInterpolation = 0;
03443
03444 }
03445
03446
03447 cg.autoAngles[0] = 0;
03448 cg.autoAngles[1] = ( cg.time & 2047 ) * 360 / 2048.0;
03449 cg.autoAngles[2] = 0;
03450
03451 cg.autoAnglesFast[0] = 0;
03452 cg.autoAnglesFast[1] = ( cg.time & 1023 ) * 360 / 1024.0f;
03453 cg.autoAnglesFast[2] = 0;
03454
03455 AnglesToAxis( cg.autoAngles, cg.autoAxis );
03456 AnglesToAxis( cg.autoAnglesFast, cg.autoAxisFast );
03457
03458
03459 cg.radarEntityCount = 0;
03460 cg.bracketedEntityCount = 0;
03461
03462
03463 ps = &cg.predictedPlayerState;
03464
03465 CG_CheckPlayerG2Weapons(ps, &cg_entities[cg.predictedPlayerState.clientNum]);
03466 BG_PlayerStateToEntityState( ps, &cg_entities[cg.predictedPlayerState.clientNum].currentState, qfalse );
03467
03468 if (cg.predictedPlayerState.m_iVehicleNum)
03469 {
03470
03471
03472 centity_t *veh = &cg_entities[cg.predictedPlayerState.m_iVehicleNum];
03473
03474 if (veh->currentState.owner == cg.predictedPlayerState.clientNum)
03475 {
03476 BG_PlayerStateToEntityState( &cg.predictedVehicleState, &veh->currentState, qfalse );
03477 veh->currentState.eType = ET_NPC;
03478
03479 veh->currentState.pos.trType = TR_INTERPOLATE;
03480 }
03481 CG_AddCEntity(veh);
03482 veh->bodyHeight = cg.time;
03483 }
03484
03485 CG_AddCEntity( &cg_entities[cg.predictedPlayerState.clientNum] );
03486
03487
03488
03489
03490
03491
03492
03493
03494 for ( num = 0 ; num < cg.snap->numEntities ; num++ ) {
03495
03496 if (cg.snap->entities[ num ].number != cg.snap->ps.clientNum)
03497 {
03498 cent = &cg_entities[ cg.snap->entities[ num ].number ];
03499 if (cent->currentState.eType == ET_PLAYER &&
03500 cent->currentState.m_iVehicleNum)
03501 {
03502 int j = 0;
03503
03504 while (j < cg.snap->numEntities)
03505 {
03506 if (cg.snap->entities[j].number == cent->currentState.m_iVehicleNum)
03507 {
03508 centity_t *veh = &cg_entities[cg.snap->entities[j].number];
03509
03510 CG_AddCEntity(veh);
03511 veh->bodyHeight = cg.time;
03512 break;
03513 }
03514
03515 j++;
03516 }
03517 }
03518 else if (cent->currentState.eType == ET_NPC &&
03519 cent->currentState.m_iVehicleNum &&
03520 cent->bodyHeight == cg.time)
03521 {
03522
03523 continue;
03524 }
03525 CG_AddCEntity( cent );
03526 }
03527 }
03528
03529 for(num=0;num<cg_numpermanents;num++)
03530 {
03531 cent = cg_permanents[num];
03532 if (cent->currentValid)
03533 {
03534 CG_AddCEntity( cent );
03535 }
03536 }
03537 }
03538
03539 void CG_ROFF_NotetrackCallback( centity_t *cent, const char *notetrack)
03540 {
03541 int i = 0, r = 0, objectID = 0, anglesGathered = 0, posoffsetGathered = 0;
03542 char type[256];
03543 char argument[512];
03544 char addlArg[512];
03545 char errMsg[256];
03546 char t[64];
03547 int addlArgs = 0;
03548 vec3_t parsedAngles, parsedOffset, useAngles, useOrigin, forward, right, up;
03549
03550 if (!cent || !notetrack)
03551 {
03552 return;
03553 }
03554
03555
03556
03557 while (notetrack[i] && notetrack[i] != ' ')
03558 {
03559 type[i] = notetrack[i];
03560 i++;
03561 }
03562
03563 type[i] = '\0';
03564
03565 if (notetrack[i] != ' ')
03566 {
03567 return;
03568 }
03569
03570 i++;
03571
03572 while (notetrack[i] && notetrack[i] != ' ')
03573 {
03574 argument[r] = notetrack[i];
03575 r++;
03576 i++;
03577 }
03578 argument[r] = '\0';
03579
03580 if (!r)
03581 {
03582 return;
03583 }
03584
03585 if (notetrack[i] == ' ')
03586 {
03587 addlArgs = 1;
03588
03589 i++;
03590 r = 0;
03591 while (notetrack[i])
03592 {
03593 addlArg[r] = notetrack[i];
03594 r++;
03595 i++;
03596 }
03597 addlArg[r] = '\0';
03598 }
03599
03600 if (strcmp(type, "effect") == 0)
03601 {
03602 if (!addlArgs)
03603 {
03604
03605
03606 VectorClear(parsedOffset);
03607 goto defaultoffsetposition;
03608 }
03609
03610 i = 0;
03611
03612 while (posoffsetGathered < 3)
03613 {
03614 r = 0;
03615 while (addlArg[i] && addlArg[i] != '+' && addlArg[i] != ' ')
03616 {
03617 t[r] = addlArg[i];
03618 r++;
03619 i++;
03620 }
03621 t[r] = '\0';
03622 i++;
03623 if (!r)
03624 {
03625
03626
03627 VectorClear(parsedOffset);
03628 i = 0;
03629 goto defaultoffsetposition;
03630 }
03631 parsedOffset[posoffsetGathered] = atof(t);
03632 posoffsetGathered++;
03633 }
03634
03635 if (posoffsetGathered < 3)
03636 {
03637 Com_sprintf(errMsg, sizeof(errMsg), "Offset position argument for 'effect' type is invalid.");
03638 goto functionend;
03639 }
03640
03641 i--;
03642
03643 if (addlArg[i] != ' ')
03644 {
03645 addlArgs = 0;
03646 }
03647
03648 defaultoffsetposition:
03649
03650 objectID = trap_FX_RegisterEffect(argument);
03651
03652 if (objectID)
03653 {
03654 if (addlArgs)
03655 {
03656 i++;
03657 while (anglesGathered < 3)
03658 {
03659 r = 0;
03660 while (addlArg[i] && addlArg[i] != '-')
03661 {
03662 t[r] = addlArg[i];
03663 r++;
03664 i++;
03665 }
03666 t[r] = '\0';
03667 i++;
03668
03669 if (!r)
03670 {
03671 anglesGathered = 0;
03672 break;
03673 }
03674
03675 parsedAngles[anglesGathered] = atof(t);
03676 anglesGathered++;
03677 }
03678
03679 if (anglesGathered)
03680 {
03681 VectorCopy(parsedAngles, useAngles);
03682 }
03683 else
03684 {
03685 VectorCopy(cent->lerpAngles, useAngles);
03686 }
03687 }
03688 else
03689 {
03690 VectorCopy(cent->lerpAngles, useAngles);
03691 }
03692
03693 AngleVectors(useAngles, forward, right, up);
03694
03695 VectorCopy(cent->lerpOrigin, useOrigin);
03696
03697
03698 useOrigin[0] += forward[0]*parsedOffset[0];
03699 useOrigin[1] += forward[1]*parsedOffset[0];
03700 useOrigin[2] += forward[2]*parsedOffset[0];
03701
03702
03703 useOrigin[0] += right[0]*parsedOffset[1];
03704 useOrigin[1] += right[1]*parsedOffset[1];
03705 useOrigin[2] += right[2]*parsedOffset[1];
03706
03707
03708 useOrigin[0] += up[0]*parsedOffset[2];
03709 useOrigin[1] += up[1]*parsedOffset[2];
03710 useOrigin[2] += up[2]*parsedOffset[2];
03711
03712 trap_FX_PlayEffectID(objectID, useOrigin, useAngles, -1, -1);
03713 }
03714 }
03715 else if (strcmp(type, "sound") == 0)
03716 {
03717 objectID = trap_S_RegisterSound(argument);
03718 trap_S_StartSound(cent->lerpOrigin, cent->currentState.number, CHAN_BODY, objectID);
03719 }
03720 else if (strcmp(type, "loop") == 0)
03721 {
03722 return;
03723 }
03724
03725 else
03726 {
03727 if (type[0])
03728 {
03729 Com_Printf("^3Warning: \"%s\" is an invalid ROFF notetrack function\n", type);
03730 }
03731 else
03732 {
03733 Com_Printf("^3Warning: Notetrack is missing function and/or arguments\n");
03734 }
03735 }
03736
03737 return;
03738
03739 functionend:
03740 Com_Printf("^3Type-specific notetrack error: %s\n", errMsg);
03741 return;
03742 }
03743
03744 void CG_Cube( vec3_t mins, vec3_t maxs, vec3_t color, float alpha )
03745 {
03746 vec3_t rot={0,0,0};
03747 int vec[3];
03748 int axis, i;
03749 addpolyArgStruct_t apArgs;
03750
03751 memset (&apArgs, 0, sizeof(apArgs));
03752
03753 for ( axis = 0, vec[0] = 0, vec[1] = 1, vec[2] = 2; axis < 3; axis++, vec[0]++, vec[1]++, vec[2]++ )
03754 {
03755 for ( i = 0; i < 3; i++ )
03756 {
03757 if ( vec[i] > 2 )
03758 {
03759 vec[i] = 0;
03760 }
03761 }
03762
03763 apArgs.p[0][vec[1]] = mins[vec[1]];
03764 apArgs.p[0][vec[2]] = mins[vec[2]];
03765
03766 apArgs.p[1][vec[1]] = mins[vec[1]];
03767 apArgs.p[1][vec[2]] = maxs[vec[2]];
03768
03769 apArgs.p[2][vec[1]] = maxs[vec[1]];
03770 apArgs.p[2][vec[2]] = maxs[vec[2]];
03771
03772 apArgs.p[3][vec[1]] = maxs[vec[1]];
03773 apArgs.p[3][vec[2]] = mins[vec[2]];
03774
03775
03776 apArgs.p[0][vec[0]] = apArgs.p[1][vec[0]] = apArgs.p[2][vec[0]] = apArgs.p[3][vec[0]] = mins[vec[0]];
03777
03778 apArgs.numVerts = 4;
03779 apArgs.alpha1 = apArgs.alpha2 = alpha;
03780 VectorCopy( color, apArgs.rgb1 );
03781 VectorCopy( color, apArgs.rgb2 );
03782 VectorCopy( rot, apArgs.rotationDelta );
03783 apArgs.killTime = cg.frametime;
03784 apArgs.shader = cgs.media.solidWhite;
03785
03786 trap_FX_AddPoly( &apArgs );
03787
03788
03789 apArgs.p[0][vec[0]] = apArgs.p[1][vec[0]] = apArgs.p[2][vec[0]] = apArgs.p[3][vec[0]] = maxs[vec[0]];
03790
03791 trap_FX_AddPoly( &apArgs );
03792 }
03793 }