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, bol