00001
00002
00003
00004 #include "b_local.h"
00005 #include "anims.h"
00006 #include "say.h"
00007 #include "../icarus/Q3_Interface.h"
00008
00009 extern vec3_t playerMins;
00010 extern vec3_t playerMaxs;
00011
00012 extern void G_SoundOnEnt( gentity_t *ent, soundChannel_t channel, const char *soundPath );
00013 extern void PM_SetTorsoAnimTimer( gentity_t *ent, int *torsoAnimTimer, int time );
00014 extern void PM_SetLegsAnimTimer( gentity_t *ent, int *legsAnimTimer, int time );
00015 extern void NPC_BSNoClip ( void );
00016 extern void G_AddVoiceEvent( gentity_t *self, int event, int speakDebounceTime );
00017 extern void NPC_ApplyRoff (void);
00018 extern void NPC_TempLookTarget ( gentity_t *self, int lookEntNum, int minLookTime, int maxLookTime );
00019 extern void NPC_CheckPlayerAim ( void );
00020 extern void NPC_CheckAllClear ( void );
00021 extern void G_AddVoiceEvent( gentity_t *self, int event, int speakDebounceTime );
00022 extern qboolean NPC_CheckLookTarget( gentity_t *self );
00023 extern void NPC_SetLookTarget( gentity_t *self, int entNum, int clearTime );
00024 extern void Mark1_dying( gentity_t *self );
00025 extern void NPC_BSCinematic( void );
00026 extern int GetTime ( int lastTime );
00027 extern void NPC_BSGM_Default( void );
00028 extern void NPC_CheckCharmed( void );
00029 extern qboolean Boba_Flying( gentity_t *self );
00030
00031 extern vmCvar_t g_saberRealisticCombat;
00032
00033
00034 gentity_t *NPC;
00035 gNPC_t *NPCInfo;
00036 gclient_t *client;
00037 usercmd_t ucmd;
00038 visibility_t enemyVisibility;
00039
00040 void NPC_SetAnim(gentity_t *ent,int type,int anim,int priority);
00041 void pitch_roll_for_slope( gentity_t *forwhom, vec3_t pass_slope );
00042 extern void GM_Dying( gentity_t *self );
00043
00044 extern int eventClearTime;
00045
00046 void CorpsePhysics( gentity_t *self )
00047 {
00048
00049 memset( &ucmd, 0, sizeof( ucmd ) );
00050 ClientThink( self->s.number, &ucmd );
00051
00052
00053
00054 if ( self->client->NPC_class == CLASS_GALAKMECH )
00055 {
00056 GM_Dying( self );
00057 }
00058
00059 if ( self->client->ps.groundEntityNum != ENTITYNUM_NONE && !(self->s.eFlags&EF_DISINTEGRATION) )
00060 {
00061
00062 pitch_roll_for_slope( self, NULL );
00063 }
00064
00065 if ( eventClearTime == level.time + ALERT_CLEAR_TIME )
00066 {
00067 if ( !(self->client->ps.eFlags&EF_NODRAW) )
00068 {
00069 AddSightEvent( self->enemy, self->r.currentOrigin, 384, AEL_DISCOVERED, 0.0f );
00070 }
00071 }
00072
00073 if ( level.time - self->s.time > 3000 )
00074 {
00075 if ( g_dismember.integer < 11381138 && !g_saberRealisticCombat.integer )
00076 {
00077 if ( self->client->NPC_class != CLASS_PROTOCOL )
00078 {
00079
00080 }
00081 }
00082 }
00083
00084
00085 if (self->client->respawnTime < (level.time+500))
00086 {
00087
00088 if (self->client->ps.eFlags & EF_DISINTEGRATION)
00089 {
00090 self->r.contents = 0;
00091 }
00092 else if ((self->client->NPC_class != CLASS_MARK1) && (self->client->NPC_class != CLASS_INTERROGATOR))
00093 {
00094 self->r.contents = CONTENTS_CORPSE;
00095
00096 }
00097
00098 if ( self->message )
00099 {
00100 self->r.contents |= CONTENTS_TRIGGER;
00101 }
00102 }
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112 #define REMOVE_DISTANCE 128
00113 #define REMOVE_DISTANCE_SQR (REMOVE_DISTANCE * REMOVE_DISTANCE)
00114
00115 void NPC_RemoveBody( gentity_t *self )
00116 {
00117 CorpsePhysics( self );
00118
00119 self->nextthink = level.time + FRAMETIME;
00120
00121 if ( self->NPC->nextBStateThink <= level.time )
00122 {
00123 trap_ICARUS_MaintainTaskManager(self->s.number);
00124 }
00125 self->NPC->nextBStateThink = level.time + FRAMETIME;
00126
00127 if ( self->message )
00128 {
00129 return;
00130 }
00131
00132
00133
00134 if (self->client->NPC_class == CLASS_MARK1)
00135 {
00136 Mark1_dying( self );
00137 }
00138
00139
00140 if ( self->client->NPC_class == CLASS_REMOTE
00141 || self->client->NPC_class == CLASS_SENTRY
00142 || self->client->NPC_class == CLASS_PROBE
00143 || self->client->NPC_class == CLASS_INTERROGATOR
00144 || self->client->NPC_class == CLASS_PROBE
00145 || self->client->NPC_class == CLASS_MARK2 )
00146 {
00147
00148 if (!trap_ICARUS_IsRunning(self->s.number))
00149 {
00150 if ( !self->activator || !self->activator->client || !(self->activator->client->ps.eFlags2&EF2_HELD_BY_MONSTER) )
00151 {
00152 G_FreeEntity( self );
00153 }
00154 }
00155 return;
00156 }
00157
00158
00159 self->r.maxs[2] = self->client->renderInfo.eyePoint[2] - self->r.currentOrigin[2] + 4;
00160 if ( self->r.maxs[2] < -8 )
00161 {
00162 self->r.maxs[2] = -8;
00163 }
00164
00165 if ( self->client->NPC_class == CLASS_GALAKMECH )
00166 {
00167 return;
00168 }
00169 if ( self->NPC && self->NPC->timeOfDeath <= level.time )
00170 {
00171 self->NPC->timeOfDeath = level.time + 1000;
00172
00174
00175
00176 if( self->client->playerTeam == NPCTEAM_ENEMY || self->client->NPC_class == CLASS_PROTOCOL )
00177 {
00178 self->nextthink = level.time + FRAMETIME;
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 }
00196
00197
00198
00199
00200
00201
00202
00203 if ( self->enemy )
00204 {
00205
00206 if (!trap_ICARUS_IsRunning(self->s.number))
00207 {
00208 if ( !self->activator || !self->activator->client || !(self->activator->client->ps.eFlags2&EF2_HELD_BY_MONSTER) )
00209 {
00210 if ( self->client && self->client->ps.saberEntityNum > 0 && self->client->ps.saberEntityNum < ENTITYNUM_WORLD )
00211 {
00212 gentity_t *saberent = &g_entities[self->client->ps.saberEntityNum];
00213 if ( saberent )
00214 {
00215 G_FreeEntity( saberent );
00216 }
00217 }
00218 G_FreeEntity( self );
00219 }
00220 }
00221 }
00222 }
00223 }
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233 int BodyRemovalPadTime( gentity_t *ent )
00234 {
00235 int time;
00236
00237 if ( !ent || !ent->client )
00238 return 0;
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 switch( ent->client->NPC_class )
00286 {
00287 case CLASS_MOUSE:
00288 case CLASS_GONK:
00289 case CLASS_R2D2:
00290 case CLASS_R5D2:
00291
00292 case CLASS_MARK1:
00293 case CLASS_MARK2:
00294 case CLASS_PROBE:
00295 case CLASS_SEEKER:
00296 case CLASS_REMOTE:
00297 case CLASS_SENTRY:
00298 case CLASS_INTERROGATOR:
00299 time = 0;
00300 break;
00301 default:
00302
00303
00304
00305 time = 10000;
00306 break;
00307
00308 }
00309
00310
00311 return time;
00312 }
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 static void NPC_RemoveBodyEffect(void)
00324 {
00325
00326
00327
00328 if ( !NPC || !NPC->client || (NPC->s.eFlags & EF_NODRAW) )
00329 return;
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 switch(NPC->client->NPC_class)
00355 {
00356 case CLASS_PROBE:
00357 case CLASS_SEEKER:
00358 case CLASS_REMOTE:
00359 case CLASS_SENTRY:
00360 case CLASS_GONK:
00361 case CLASS_R2D2:
00362 case CLASS_R5D2:
00363
00364 case CLASS_MARK1:
00365 case CLASS_MARK2:
00366 case CLASS_INTERROGATOR:
00367 case CLASS_ATST:
00368
00369
00370
00371
00372 break;
00373 default:
00374 break;
00375 }
00376
00377
00378 }
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 void pitch_roll_for_slope( gentity_t *forwhom, vec3_t pass_slope )
00396 {
00397 vec3_t slope;
00398 vec3_t nvf, ovf, ovr, startspot, endspot, new_angles = { 0, 0, 0 };
00399 float pitch, mod, dot;
00400
00401
00402 if( !pass_slope || VectorCompare( vec3_origin, pass_slope ) )
00403 {
00404 trace_t trace;
00405
00406 VectorCopy( forwhom->r.currentOrigin, startspot );
00407 startspot[2] += forwhom->r.mins[2] + 4;
00408 VectorCopy( startspot, endspot );
00409 endspot[2] -= 300;
00410 trap_Trace( &trace, forwhom->r.currentOrigin, vec3_origin, vec3_origin, endspot, forwhom->s.number, MASK_SOLID );
00411
00412
00413
00414 if ( trace.fraction >= 1.0 )
00415 return;
00416
00417 if( !( &trace.plane ) )
00418 return;
00419
00420 if ( VectorCompare( vec3_origin, trace.plane.normal ) )
00421 return;
00422
00423 VectorCopy( trace.plane.normal, slope );
00424 }
00425 else
00426 {
00427 VectorCopy( pass_slope, slope );
00428 }
00429
00430
00431 AngleVectors( forwhom->r.currentAngles, ovf, ovr, NULL );
00432
00433 vectoangles( slope, new_angles );
00434 pitch = new_angles[PITCH] + 90;
00435 new_angles[ROLL] = new_angles[PITCH] = 0;
00436
00437 AngleVectors( new_angles, nvf, NULL, NULL );
00438
00439 mod = DotProduct( nvf, ovr );
00440
00441 if ( mod<0 )
00442 mod = -1;
00443 else
00444 mod = 1;
00445
00446 dot = DotProduct( nvf, ovf );
00447
00448 if ( forwhom->client )
00449 {
00450 float oldmins2;
00451
00452 forwhom->client->ps.viewangles[PITCH] = dot * pitch;
00453 forwhom->client->ps.viewangles[ROLL] = ((1-Q_fabs(dot)) * pitch * mod);
00454 oldmins2 = forwhom->r.mins[2];
00455 forwhom->r.mins[2] = -24 + 12 * fabs(forwhom->client->ps.viewangles[PITCH])/180.0f;
00456
00457 if ( oldmins2 > forwhom->r.mins[2] )
00458 {
00459
00460 forwhom->client->ps.origin[2] += (oldmins2 - forwhom->r.mins[2]);
00461 forwhom->r.currentOrigin[2] = forwhom->client->ps.origin[2];
00462 trap_LinkEntity( forwhom );
00463 }
00464 }
00465 else
00466 {
00467 forwhom->r.currentAngles[PITCH] = dot * pitch;
00468 forwhom->r.currentAngles[ROLL] = ((1-Q_fabs(dot)) * pitch * mod);
00469 }
00470 }
00471
00472
00473
00474
00475
00476
00477
00478 static void DeadThink ( void )
00479 {
00480 trace_t trace;
00481
00482
00483
00484
00485 NPC->r.maxs[2] = NPC->client->renderInfo.eyePoint[2] - NPC->r.currentOrigin[2] + 4;
00486 if ( NPC->r.maxs[2] < -8 )
00487 {
00488 NPC->r.maxs[2] = -8;
00489 }
00490 if ( VectorCompare( NPC->client->ps.velocity, vec3_origin ) )
00491 {
00492 if ( NPC->r.mins[0] > -32 )
00493 {
00494 NPC->r.mins[0] -= 1;
00495 trap_Trace (&trace, NPC->r.currentOrigin, NPC->r.mins, NPC->r.maxs, NPC->r.currentOrigin, NPC->s.number, NPC->clipmask );
00496 if ( trace.allsolid )
00497 {
00498 NPC->r.mins[0] += 1;
00499 }
00500 }
00501 if ( NPC->r.maxs[0] < 32 )
00502 {
00503 NPC->r.maxs[0] += 1;
00504 trap_Trace (&trace, NPC->r.currentOrigin, NPC->r.mins, NPC->r.maxs, NPC->r.currentOrigin, NPC->s.number, NPC->clipmask );
00505 if ( trace.allsolid )
00506 {
00507 NPC->r.maxs[0] -= 1;
00508 }
00509 }
00510 if ( NPC->r.mins[1] > -32 )
00511 {
00512 NPC->r.mins[1] -= 1;
00513 trap_Trace (&trace, NPC->r.currentOrigin, NPC->r.mins, NPC->r.maxs, NPC->r.currentOrigin, NPC->s.number, NPC->clipmask );
00514 if ( trace.allsolid )
00515 {
00516 NPC->r.mins[1] += 1;
00517 }
00518 }
00519 if ( NPC->r.maxs[1] < 32 )
00520 {
00521 NPC->r.maxs[1] += 1;
00522 trap_Trace (&trace, NPC->r.currentOrigin, NPC->r.mins, NPC->r.maxs, NPC->r.currentOrigin, NPC->s.number, NPC->clipmask );
00523 if ( trace.allsolid )
00524 {
00525 NPC->r.maxs[1] -= 1;
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 if ( level.time >= NPCInfo->timeOfDeath + BodyRemovalPadTime( NPC ) )
00555 {
00556 if ( NPC->client->ps.eFlags & EF_NODRAW )
00557 {
00558 if (!trap_ICARUS_IsRunning(NPC->s.number))
00559
00560 {
00561 NPC->think = G_FreeEntity;
00562 NPC->nextthink = level.time + FRAMETIME;
00563 }
00564 }
00565 else
00566 {
00567 class_t npc_class;
00568
00569
00570 NPC_RemoveBodyEffect();
00571
00572
00573 NPC->think = NPC_RemoveBody;
00574 NPC->nextthink = level.time + FRAMETIME;
00575
00576
00577
00578 npc_class = NPC->client->NPC_class;
00579
00580 if ( npc_class == CLASS_SEEKER || npc_class == CLASS_REMOTE || npc_class == CLASS_PROBE || npc_class == CLASS_MOUSE ||
00581 npc_class == CLASS_GONK || npc_class == CLASS_R2D2 || npc_class == CLASS_R5D2 ||
00582 npc_class == CLASS_MARK2 || npc_class == CLASS_SENTRY )
00583 {
00584 NPC->client->ps.eFlags |= EF_NODRAW;
00585 NPCInfo->timeOfDeath = level.time + FRAMETIME * 8;
00586 }
00587 else
00588 NPCInfo->timeOfDeath = level.time + FRAMETIME * 4;
00589 }
00590 return;
00591 }
00592 }
00593
00594
00595 if ( NPC->bounceCount < 0 && NPC->s.groundEntityNum >= 0 )
00596 {
00597
00598 int contents = NPC->bounceCount = trap_PointContents( NPC->r.currentOrigin, -1 );
00599
00600 if ( ( contents & CONTENTS_NODROP ) )
00601 {
00602 NPC->client->ps.eFlags |= EF_NODRAW;
00603 }
00604 }
00605
00606 CorpsePhysics( NPC );
00607 }
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617 void SetNPCGlobals( gentity_t *ent )
00618 {
00619 NPC = ent;
00620 NPCInfo = ent->NPC;
00621 client = ent->client;
00622 memset( &ucmd, 0, sizeof( usercmd_t ) );
00623 }
00624
00625 gentity_t *_saved_NPC;
00626 gNPC_t *_saved_NPCInfo;
00627 gclient_t *_saved_client;
00628 usercmd_t _saved_ucmd;
00629
00630 void SaveNPCGlobals(void)
00631 {
00632 _saved_NPC = NPC;
00633 _saved_NPCInfo = NPCInfo;
00634 _saved_client = client;
00635 memcpy( &_saved_ucmd, &ucmd, sizeof( usercmd_t ) );
00636 }
00637
00638 void RestoreNPCGlobals(void)
00639 {
00640 NPC = _saved_NPC;
00641 NPCInfo = _saved_NPCInfo;
00642 client = _saved_client;
00643 memcpy( &ucmd, &_saved_ucmd, sizeof( usercmd_t ) );
00644 }
00645
00646
00647 void ClearNPCGlobals( void )
00648 {
00649 NPC = NULL;
00650 NPCInfo = NULL;
00651 client = NULL;
00652 }
00653
00654
00655 extern qboolean showBBoxes;
00656 vec3_t NPCDEBUG_RED = {1.0, 0.0, 0.0};
00657 vec3_t NPCDEBUG_GREEN = {0.0, 1.0, 0.0};
00658 vec3_t NPCDEBUG_BLUE = {0.0, 0.0, 1.0};
00659 vec3_t NPCDEBUG_LIGHT_BLUE = {0.3f, 0.7f, 1.0};
00660 extern void G_Cube( vec3_t mins, vec3_t maxs, vec3_t color, float alpha );
00661 extern void G_Line( vec3_t start, vec3_t end, vec3_t color, float alpha );
00662 extern void G_Cylinder( vec3_t start, vec3_t end, float radius, vec3_t color );
00663
00664 void NPC_ShowDebugInfo (void)
00665 {
00666 if ( showBBoxes )
00667 {
00668 gentity_t *found = NULL;
00669 vec3_t mins, maxs;
00670
00671 while( (found = G_Find( found, FOFS(classname), "NPC" ) ) != NULL )
00672 {
00673 if ( trap_InPVS( found->r.currentOrigin, g_entities[0].r.currentOrigin ) )
00674 {
00675 VectorAdd( found->r.currentOrigin, found->r.mins, mins );
00676 VectorAdd( found->r.currentOrigin, found->r.maxs, maxs );
00677 G_Cube( mins, maxs, NPCDEBUG_RED, 0.25 );
00678 }
00679 }
00680 }
00681 }
00682
00683 void NPC_ApplyScriptFlags (void)
00684 {
00685 if ( NPCInfo->scriptFlags & SCF_CROUCHED )
00686 {
00687 if ( NPCInfo->charmedTime > level.time && (ucmd.forwardmove || ucmd.rightmove) )
00688 {
00689 }
00690 else
00691 {
00692 ucmd.upmove = -127;
00693 }
00694 }
00695
00696 if(NPCInfo->scriptFlags & SCF_RUNNING)
00697 {
00698 ucmd.buttons &= ~BUTTON_WALKING;
00699 }
00700 else if(NPCInfo->scriptFlags & SCF_WALKING)
00701 {
00702 if ( NPCInfo->charmedTime > level.time && (ucmd.forwardmove || ucmd.rightmove) )
00703 {
00704 }
00705 else
00706 {
00707 ucmd.buttons |= BUTTON_WALKING;
00708 }
00709 }
00710
00711
00712
00713
00714
00715
00716 if(NPCInfo->scriptFlags & SCF_LEAN_RIGHT)
00717 {
00718 ucmd.buttons |= BUTTON_USE;
00719 ucmd.rightmove = 127;
00720 ucmd.forwardmove = 0;
00721 ucmd.upmove = 0;
00722 }
00723 else if(NPCInfo->scriptFlags & SCF_LEAN_LEFT)
00724 {
00725 ucmd.buttons |= BUTTON_USE;
00726 ucmd.rightmove = -127;
00727 ucmd.forwardmove = 0;
00728 ucmd.upmove = 0;
00729 }
00730
00731 if ( (NPCInfo->scriptFlags & SCF_ALT_FIRE) && (ucmd.buttons & BUTTON_ATTACK) )
00732 {
00733 ucmd.buttons |= BUTTON_ALT_ATTACK;
00734 }
00735 }
00736
00737 void Q3_DebugPrint( int level, const char *format, ... );
00738 void NPC_HandleAIFlags (void)
00739 {
00740
00741 if ( NPCInfo->aiFlags & NPCAI_LOST )
00742 {
00743
00744 NPCInfo->aiFlags &= ~NPCAI_LOST;
00745
00746
00747
00748
00749
00750
00751
00752
00753 if ( NPCInfo->goalEntity && NPCInfo->goalEntity == NPC->enemy )
00754 {
00755
00756 NPC_LostEnemyDecideChase();
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
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811 if ( NPCInfo->greetingDebounceTime && NPCInfo->greetingDebounceTime < level.time )
00812 {
00813 G_AddVoiceEvent( NPC, Q_irand(EV_VICTORY1, EV_VICTORY3), Q_irand( 2000, 4000 ) );
00814 NPCInfo->greetingDebounceTime = 0;
00815 }
00816
00817 if ( NPCInfo->ffireCount > 0 )
00818 {
00819 if ( NPCInfo->ffireFadeDebounce < level.time )
00820 {
00821 NPCInfo->ffireCount--;
00822
00823 NPCInfo->ffireFadeDebounce = level.time + 3000;
00824 }
00825 }
00826 if ( d_patched.integer )
00827 {
00828 if ( NPCInfo->consecutiveBlockedMoves > 20 )
00829 {
00830 NPCInfo->consecutiveBlockedMoves = 0;
00831 }
00832 }
00833 }
00834
00835 void NPC_AvoidWallsAndCliffs (void)
00836 {
00837
00838 }
00839
00840 void NPC_CheckAttackScript(void)
00841 {
00842 if(!(ucmd.buttons & BUTTON_ATTACK))
00843 {
00844 return;
00845 }
00846
00847 G_ActivateBehavior(NPC, BSET_ATTACK);
00848 }
00849
00850 float NPC_MaxDistSquaredForWeapon (void);
00851 void NPC_CheckAttackHold(void)
00852 {
00853 vec3_t vec;
00854
00855
00856 if ( !NPC->enemy )
00857 {
00858 NPCInfo->attackHoldTime = 0;
00859 return;
00860 }
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894 {
00895 VectorSubtract(NPC->enemy->r.currentOrigin, NPC->r.currentOrigin, vec);
00896 if( VectorLengthSquared(vec) > NPC_MaxDistSquaredForWeapon() )
00897 {
00898 NPCInfo->attackHoldTime = 0;
00899 }
00900 else if( NPCInfo->attackHoldTime && NPCInfo->attackHoldTime > level.time )
00901 {
00902 ucmd.buttons |= BUTTON_ATTACK;
00903 }
00904 else if ( ( NPCInfo->attackHold ) && ( ucmd.buttons & BUTTON_ATTACK ) )
00905 {
00906 NPCInfo->attackHoldTime = level.time + NPCInfo->attackHold;
00907 }
00908 else
00909 {
00910 NPCInfo->attackHoldTime = 0;
00911 }
00912 }
00913 }
00914
00915
00916
00917
00918
00919
00920 void NPC_KeepCurrentFacing(void)
00921 {
00922 if(!ucmd.angles[YAW])
00923 {
00924 ucmd.angles[YAW] = ANGLE2SHORT( client->ps.viewangles[YAW] ) - client->ps.delta_angles[YAW];
00925 }
00926
00927 if(!ucmd.angles[PITCH])
00928 {
00929 ucmd.angles[PITCH] = ANGLE2SHORT( client->ps.viewangles[PITCH] ) - client->ps.delta_angles[PITCH];
00930 }
00931 }
00932
00933
00934
00935
00936
00937
00938
00939 void NPC_BehaviorSet_Charmed( int bState )
00940 {
00941 switch( bState )
00942 {
00943 case BS_FOLLOW_LEADER:
00944 NPC_BSFollowLeader();
00945 break;
00946 case BS_REMOVE:
00947 NPC_BSRemove();
00948 break;
00949 case BS_SEARCH:
00950 NPC_BSSearch();
00951 break;
00952 case BS_WANDER:
00953 NPC_BSWander();
00954 break;
00955 case BS_FLEE:
00956 NPC_BSFlee();
00957 break;
00958 default:
00959 case BS_DEFAULT:
00960 NPC_BSDefault();
00961 break;
00962 }
00963 }
00964
00965
00966
00967
00968
00969
00970 void NPC_BehaviorSet_Default( int bState )
00971 {
00972 switch( bState )
00973 {
00974 case BS_ADVANCE_FIGHT:
00975 NPC_BSAdvanceFight ();
00976 break;
00977 case BS_SLEEP:
00978 NPC_BSSleep ();
00979 break;
00980 case BS_FOLLOW_LEADER:
00981 NPC_BSFollowLeader();
00982 break;
00983 case BS_JUMP:
00984 NPC_BSJump();
00985 break;
00986 case BS_REMOVE:
00987 NPC_BSRemove();
00988 break;
00989 case BS_SEARCH:
00990 NPC_BSSearch();
00991 break;
00992 case BS_NOCLIP:
00993 NPC_BSNoClip();
00994 break;
00995 case BS_WANDER:
00996 NPC_BSWander();
00997 break;
00998 case BS_FLEE:
00999 NPC_BSFlee();
01000 break;
01001 case BS_WAIT:
01002 NPC_BSWait();
01003 break;
01004 case BS_CINEMATIC:
01005 NPC_BSCinematic();
01006 break;
01007 default:
01008 case BS_DEFAULT:
01009 NPC_BSDefault();
01010 break;
01011 }
01012 }
01013
01014
01015
01016
01017
01018
01019 void NPC_BehaviorSet_Interrogator( int bState )
01020 {
01021 switch( bState )
01022 {
01023 case BS_STAND_GUARD:
01024 case BS_PATROL:
01025 case BS_STAND_AND_SHOOT:
01026 case BS_HUNT_AND_KILL:
01027 case BS_DEFAULT:
01028 NPC_BSInterrogator_Default();
01029 break;
01030 default:
01031 NPC_BehaviorSet_Default( bState );
01032 break;
01033 }
01034 }
01035
01036 void NPC_BSImperialProbe_Attack( void );
01037 void NPC_BSImperialProbe_Patrol( void );
01038 void NPC_BSImperialProbe_Wait(void);
01039
01040
01041
01042
01043
01044
01045 void NPC_BehaviorSet_ImperialProbe( int bState )
01046 {
01047 switch( bState )
01048 {
01049 case BS_STAND_GUARD:
01050 case BS_PATROL:
01051 case BS_STAND_AND_SHOOT:
01052 case BS_HUNT_AND_KILL:
01053 case BS_DEFAULT:
01054 NPC_BSImperialProbe_Default();
01055 break;
01056 default:
01057 NPC_BehaviorSet_Default( bState );
01058 break;
01059 }
01060 }
01061
01062
01063 void NPC_BSSeeker_Default( void );
01064
01065
01066
01067
01068
01069
01070 void NPC_BehaviorSet_Seeker( int bState )
01071 {
01072 switch( bState )
01073 {
01074 case BS_STAND_GUARD:
01075 case BS_PATROL:
01076 case BS_STAND_AND_SHOOT:
01077 case BS_HUNT_AND_KILL:
01078 case BS_DEFAULT:
01079 NPC_BSSeeker_Default();
01080 break;
01081 default:
01082 NPC_BehaviorSet_Default( bState );
01083 break;
01084 }
01085 }
01086
01087 void NPC_BSRemote_Default( void );
01088
01089
01090
01091
01092
01093
01094 void NPC_BehaviorSet_Remote( int bState )
01095 {
01096 NPC_BSRemote_Default();
01097 }
01098
01099 void NPC_BSSentry_Default( void );
01100
01101
01102
01103
01104
01105
01106 void NPC_BehaviorSet_Sentry( int bState )
01107 {
01108 switch( bState )
01109 {
01110 case BS_STAND_GUARD:
01111 case BS_PATROL:
01112 case BS_STAND_AND_SHOOT:
01113 case BS_HUNT_AND_KILL:
01114 case BS_DEFAULT:
01115 NPC_BSSentry_Default();
01116 break;
01117 default:
01118 NPC_BehaviorSet_Default( bState );
01119 break;
01120 }
01121 }
01122
01123
01124
01125
01126
01127
01128 void NPC_BehaviorSet_Grenadier( int bState )
01129 {
01130 switch( bState )
01131 {
01132 case BS_STAND_GUARD:
01133 case BS_PATROL:
01134 case BS_STAND_AND_SHOOT:
01135 case BS_HUNT_AND_KILL:
01136 case BS_DEFAULT:
01137 NPC_BSGrenadier_Default();
01138 break;
01139
01140 default:
01141 NPC_BehaviorSet_Default( bState );
01142 break;
01143 }
01144 }
01145
01146
01147
01148
01149
01150 void NPC_BehaviorSet_Sniper( int bState )
01151 {
01152 switch( bState )
01153 {
01154 case BS_STAND_GUARD:
01155 case BS_PATROL:
01156 case BS_STAND_AND_SHOOT:
01157 case BS_HUNT_AND_KILL:
01158 case BS_DEFAULT:
01159 NPC_BSSniper_Default();
01160 break;
01161
01162 default:
01163 NPC_BehaviorSet_Default( bState );
01164 break;
01165 }
01166 }
01167
01168
01169
01170
01171
01172
01173 void NPC_BehaviorSet_Stormtrooper( int bState )
01174 {
01175 switch( bState )
01176 {
01177 case BS_STAND_GUARD:
01178 case BS_PATROL:
01179 case BS_STAND_AND_SHOOT:
01180 case BS_HUNT_AND_KILL:
01181 case BS_DEFAULT:
01182 NPC_BSST_Default();
01183 break;
01184
01185 case BS_INVESTIGATE:
01186 NPC_BSST_Investigate();
01187 break;
01188
01189 case BS_SLEEP:
01190 NPC_BSST_Sleep();
01191 break;
01192
01193 default:
01194 NPC_BehaviorSet_Default( bState );
01195 break;
01196 }
01197 }
01198
01199
01200
01201
01202
01203
01204
01205 void NPC_BehaviorSet_Jedi( int bState )
01206 {
01207 switch( bState )
01208 {
01209 case BS_STAND_GUARD:
01210 case BS_PATROL:
01211 case BS_STAND_AND_SHOOT:
01212 case BS_HUNT_AND_KILL:
01213 case BS_DEFAULT:
01214 NPC_BSJedi_Default();
01215 break;
01216
01217 case BS_FOLLOW_LEADER:
01218 NPC_BSJedi_FollowLeader();
01219 break;
01220
01221 default:
01222 NPC_BehaviorSet_Default( bState );
01223 break;
01224 }
01225 }
01226
01227
01228
01229
01230
01231
01232 void NPC_BehaviorSet_Droid( int bState )
01233 {
01234 switch( bState )
01235 {
01236 case BS_DEFAULT:
01237 case BS_STAND_GUARD:
01238 case BS_PATROL:
01239 NPC_BSDroid_Default();
01240 break;
01241 default:
01242 NPC_BehaviorSet_Default( bState );
01243 break;
01244 }
01245 }
01246
01247
01248
01249
01250
01251
01252 void NPC_BehaviorSet_Mark1( int bState )
01253 {
01254 switch( bState )
01255 {
01256 case BS_DEFAULT:
01257 case BS_STAND_GUARD:
01258 case BS_PATROL:
01259 NPC_BSMark1_Default();
01260 break;
01261 default:
01262 NPC_BehaviorSet_Default( bState );
01263 break;
01264 }
01265 }
01266
01267 <