00001 #include "b_local.h"
00002 #include "g_nav.h"
00003
00004 #define MIN_MELEE_RANGE 320
00005 #define MIN_MELEE_RANGE_SQR ( MIN_MELEE_RANGE * MIN_MELEE_RANGE )
00006
00007 #define MIN_DISTANCE 128
00008 #define MIN_DISTANCE_SQR ( MIN_DISTANCE * MIN_DISTANCE )
00009
00010 #define TURN_OFF 0x00000100
00011
00012 #define LEFT_ARM_HEALTH 40
00013 #define RIGHT_ARM_HEALTH 40
00014 #define AMMO_POD_HEALTH 40
00015
00016 #define BOWCASTER_VELOCITY 1300
00017 #define BOWCASTER_NPC_DAMAGE_EASY 12
00018 #define BOWCASTER_NPC_DAMAGE_NORMAL 24
00019 #define BOWCASTER_NPC_DAMAGE_HARD 36
00020 #define BOWCASTER_SIZE 2
00021 #define BOWCASTER_SPLASH_DAMAGE 0
00022 #define BOWCASTER_SPLASH_RADIUS 0
00023
00024
00025 enum
00026 {
00027 LSTATE_NONE = 0,
00028 LSTATE_ASLEEP,
00029 LSTATE_WAKEUP,
00030 LSTATE_FIRED0,
00031 LSTATE_FIRED1,
00032 LSTATE_FIRED2,
00033 LSTATE_FIRED3,
00034 LSTATE_FIRED4,
00035 };
00036
00037 qboolean NPC_CheckPlayerTeamStealth( void );
00038 void Mark1_BlasterAttack(qboolean advance);
00039 void DeathFX( gentity_t *ent );
00040
00041 #include "../namespace_begin.h"
00042 extern gitem_t *BG_FindItemForAmmo( ammo_t ammo );
00043 #include "../namespace_end.h"
00044
00045
00046
00047
00048
00049
00050 void NPC_Mark1_Precache(void)
00051 {
00052 G_SoundIndex( "sound/chars/mark1/misc/mark1_wakeup");
00053 G_SoundIndex( "sound/chars/mark1/misc/shutdown");
00054 G_SoundIndex( "sound/chars/mark1/misc/walk");
00055 G_SoundIndex( "sound/chars/mark1/misc/run");
00056 G_SoundIndex( "sound/chars/mark1/misc/death1");
00057 G_SoundIndex( "sound/chars/mark1/misc/death2");
00058 G_SoundIndex( "sound/chars/mark1/misc/anger");
00059 G_SoundIndex( "sound/chars/mark1/misc/mark1_fire");
00060 G_SoundIndex( "sound/chars/mark1/misc/mark1_pain");
00061 G_SoundIndex( "sound/chars/mark1/misc/mark1_explo");
00062
00063
00064 G_EffectIndex( "env/med_explode2");
00065 G_EffectIndex( "explosions/probeexplosion1");
00066 G_EffectIndex( "blaster/smoke_bolton");
00067 G_EffectIndex( "bryar/muzzle_flash");
00068 G_EffectIndex( "explosions/droidexplosion1" );
00069
00070 RegisterItem( BG_FindItemForAmmo( AMMO_METAL_BOLTS));
00071 RegisterItem( BG_FindItemForAmmo( AMMO_BLASTER ));
00072 RegisterItem( BG_FindItemForWeapon( WP_BOWCASTER ));
00073 RegisterItem( BG_FindItemForWeapon( WP_BRYAR_PISTOL ));
00074 }
00075
00076
00077
00078
00079
00080
00081 void NPC_Mark1_Part_Explode( gentity_t *self, int bolt )
00082 {
00083 if ( bolt >=0 )
00084 {
00085 mdxaBone_t boltMatrix;
00086 vec3_t org, dir;
00087
00088 trap_G2API_GetBoltMatrix( self->ghoul2, 0,
00089 bolt,
00090 &boltMatrix, self->r.currentAngles, self->r.currentOrigin, level.time,
00091 NULL, self->modelScale );
00092
00093 BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, org );
00094 BG_GiveMeVectorFromMatrix( &boltMatrix, NEGATIVE_Y, dir );
00095
00096 G_PlayEffectID( G_EffectIndex("env/med_explode2"), org, dir );
00097
00098 G_PlayEffectID( G_EffectIndex("blaster/smoke_bolton"), org, dir );
00099 }
00100
00101
00102 }
00103
00104
00105
00106
00107
00108
00109 void Mark1_Idle( void )
00110 {
00111
00112 NPC_BSIdle();
00113
00114 NPC_SetAnim( NPC, SETANIM_BOTH, BOTH_SLEEP1, SETANIM_FLAG_NORMAL );
00115 }
00116
00117
00118
00119
00120
00121
00122
00123 void Mark1Dead_FireRocket (void)
00124 {
00125 mdxaBone_t boltMatrix;
00126 vec3_t muzzle1,muzzle_dir;
00127 gentity_t *missile;
00128
00129 int damage = 50;
00130 int bolt = trap_G2API_AddBolt(NPC->ghoul2, 0, "*flash5");
00131
00132 trap_G2API_GetBoltMatrix( NPC->ghoul2, 0,
00133 bolt,
00134 &boltMatrix, NPC->r.currentAngles, NPC->r.currentOrigin, level.time,
00135 NULL, NPC->modelScale );
00136
00137 BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, muzzle1 );
00138 BG_GiveMeVectorFromMatrix( &boltMatrix, NEGATIVE_Y, muzzle_dir );
00139
00140 G_PlayEffectID( G_EffectIndex("bryar/muzzle_flash"), muzzle1, muzzle_dir );
00141
00142 G_Sound( NPC, CHAN_AUTO, G_SoundIndex("sound/chars/mark1/misc/mark1_fire"));
00143
00144 missile = CreateMissile( muzzle1, muzzle_dir, BOWCASTER_VELOCITY, 10000, NPC, qfalse );
00145
00146 missile->classname = "bowcaster_proj";
00147 missile->s.weapon = WP_BOWCASTER;
00148
00149 VectorSet( missile->r.maxs, BOWCASTER_SIZE, BOWCASTER_SIZE, BOWCASTER_SIZE );
00150 VectorScale( missile->r.maxs, -1, missile->r.mins );
00151
00152 missile->damage = damage;
00153 missile->dflags = DAMAGE_DEATH_KNOCKBACK;
00154
00155 missile->methodOfDeath = MOD_ROCKET;
00156 missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER;
00157 missile->splashDamage = BOWCASTER_SPLASH_DAMAGE;
00158 missile->splashRadius = BOWCASTER_SPLASH_RADIUS;
00159
00160
00161 missile->bounceCount = 0;
00162
00163 }
00164
00165
00166
00167
00168
00169
00170
00171 void Mark1Dead_FireBlaster (void)
00172 {
00173 vec3_t muzzle1,muzzle_dir;
00174 gentity_t *missile;
00175 mdxaBone_t boltMatrix;
00176 int bolt;
00177
00178 bolt = trap_G2API_AddBolt(NPC->ghoul2, 0, "*flash1");
00179
00180 trap_G2API_GetBoltMatrix( NPC->ghoul2, 0,
00181 bolt,
00182 &boltMatrix, NPC->r.currentAngles, NPC->r.currentOrigin, level.time,
00183 NULL, NPC->modelScale );
00184
00185 BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, muzzle1 );
00186 BG_GiveMeVectorFromMatrix( &boltMatrix, NEGATIVE_Y, muzzle_dir );
00187
00188 G_PlayEffectID( G_EffectIndex("bryar/muzzle_flash"), muzzle1, muzzle_dir );
00189
00190 missile = CreateMissile( muzzle1, muzzle_dir, 1600, 10000, NPC, qfalse );
00191
00192 G_Sound( NPC, CHAN_AUTO, G_SoundIndex("sound/chars/mark1/misc/mark1_fire"));
00193
00194 missile->classname = "bryar_proj";
00195 missile->s.weapon = WP_BRYAR_PISTOL;
00196
00197 missile->damage = 1;
00198 missile->dflags = DAMAGE_DEATH_KNOCKBACK;
00199 missile->methodOfDeath = MOD_BRYAR_PISTOL;
00200 missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER;
00201
00202 }
00203
00204
00205
00206
00207
00208
00209 void Mark1_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod,int dFlags,int hitLoc )
00210 {
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 G_Sound( self, CHAN_AUTO, G_SoundIndex(va("sound/chars/mark1/misc/death%d.wav",Q_irand( 1, 2))));
00233
00234
00235 if (Q_irand( 1, 10) > 5)
00236 {
00237 NPC_SetAnim( self, SETANIM_BOTH, BOTH_DEATH2, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
00238 }
00239 else
00240 {
00241 NPC_SetAnim( self, SETANIM_BOTH, BOTH_DEATH1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
00242 }
00243 }
00244
00245
00246
00247
00248
00249
00250 void Mark1_dying( gentity_t *self )
00251 {
00252 int num,newBolt;
00253
00254 if (self->client->ps.torsoTimer>0)
00255 {
00256 if (TIMER_Done(self,"dyingExplosion"))
00257 {
00258 num = Q_irand( 1, 3);
00259
00260
00261 if (num == 1)
00262 {
00263 num = Q_irand( 8, 10);
00264 newBolt = trap_G2API_AddBolt( self->ghoul2, 0, va("*flash%d",num) );
00265 NPC_Mark1_Part_Explode(self,newBolt);
00266 }
00267 else
00268 {
00269 num = Q_irand( 1, 6);
00270 newBolt = trap_G2API_AddBolt( self->ghoul2, 0, va("*torso_tube%d",num) );
00271 NPC_Mark1_Part_Explode(self,newBolt);
00272 NPC_SetSurfaceOnOff( self, va("torso_tube%d",num), TURN_OFF );
00273 }
00274
00275 TIMER_Set( self, "dyingExplosion", Q_irand( 300, 1000 ) );
00276 }
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288 if (!trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "l_arm" ))
00289 {
00290 if (Q_irand( 1, 5) == 1)
00291 {
00292 SaveNPCGlobals();
00293 SetNPCGlobals( self );
00294 Mark1Dead_FireBlaster();
00295 RestoreNPCGlobals();
00296 }
00297 }
00298
00299
00300 if (!trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "r_arm" ))
00301 {
00302 if (Q_irand( 1, 10) == 1)
00303 {
00304 SaveNPCGlobals();
00305 SetNPCGlobals( self );
00306 Mark1Dead_FireRocket();
00307 RestoreNPCGlobals();
00308 }
00309 }
00310 }
00311
00312 }
00313
00314
00315
00316
00317
00318
00319
00320 void NPC_Mark1_Pain(gentity_t *self, gentity_t *attacker, int damage)
00321 {
00322 int newBolt,i,chance;
00323 int hitLoc = gPainHitLoc;
00324
00325 NPC_Pain( self, attacker, damage );
00326
00327 G_Sound( self, CHAN_AUTO, G_SoundIndex("sound/chars/mark1/misc/mark1_pain"));
00328
00329
00330 if (hitLoc==HL_CHEST)
00331 {
00332 chance = Q_irand( 1, 4);
00333
00334 if ((chance == 1) && (damage > 5))
00335 {
00336 NPC_SetAnim( self, SETANIM_BOTH, BOTH_PAIN1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
00337 }
00338 }
00339
00340 else if ((hitLoc==HL_ARM_LT) && (self->locationDamage[HL_ARM_LT] > LEFT_ARM_HEALTH))
00341 {
00342 if (self->locationDamage[hitLoc] >= LEFT_ARM_HEALTH)
00343 {
00344 newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*flash3" );
00345 if ( newBolt != -1 )
00346 {
00347 NPC_Mark1_Part_Explode(self,newBolt);
00348 }
00349
00350 NPC_SetSurfaceOnOff( self, "l_arm", TURN_OFF );
00351 }
00352 }
00353
00354 else if ((hitLoc==HL_ARM_RT) && (self->locationDamage[HL_ARM_RT] > RIGHT_ARM_HEALTH))
00355 {
00356 if (self->locationDamage[hitLoc] >= RIGHT_ARM_HEALTH)
00357 {
00358 newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*flash4" );
00359 if ( newBolt != -1 )
00360 {
00361
00362 NPC_Mark1_Part_Explode( self, newBolt );
00363 }
00364
00365 NPC_SetSurfaceOnOff( self, "r_arm", TURN_OFF );
00366 }
00367 }
00368
00369 else
00370 {
00371 for (i=0;i<6;i++)
00372 {
00373 if ((hitLoc==HL_GENERIC1+i) && (self->locationDamage[HL_GENERIC1+i] > AMMO_POD_HEALTH))
00374 {
00375 if (self->locationDamage[hitLoc] >= AMMO_POD_HEALTH)
00376 {
00377 newBolt = trap_G2API_AddBolt( self->ghoul2, 0, va("*torso_tube%d",(i+1)) );
00378 if ( newBolt != -1 )
00379 {
00380 NPC_Mark1_Part_Explode(self,newBolt);
00381 }
00382 NPC_SetSurfaceOnOff( self, va("torso_tube%d",(i+1)), TURN_OFF );
00383 NPC_SetAnim( self, SETANIM_BOTH, BOTH_PAIN1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
00384 break;
00385 }
00386 }
00387 }
00388 }
00389
00390
00391 if ((trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "l_arm" )>0) &&
00392 (trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "r_arm" )>0))
00393 {
00394 G_Damage(self,NULL,NULL,NULL,NULL,self->health,0,MOD_UNKNOWN);
00395 }
00396 }
00397
00398
00399
00400
00401
00402
00403
00404 void Mark1_Hunt(void)
00405 {
00406
00407 if ( NPCInfo->goalEntity == NULL )
00408 {
00409 NPCInfo->goalEntity = NPC->enemy;
00410 }
00411
00412 NPC_FaceEnemy( qtrue );
00413
00414 NPCInfo->combatMove = qtrue;
00415 NPC_MoveToGoal( qtrue );
00416 }
00417
00418
00419
00420
00421
00422
00423
00424 void Mark1_FireBlaster(void)
00425 {
00426 vec3_t muzzle1,enemy_org1,delta1,angleToEnemy1;
00427 static vec3_t forward, vright, up;
00428 static vec3_t muzzle;
00429 gentity_t *missile;
00430 mdxaBone_t boltMatrix;
00431 int bolt;
00432
00433
00434 if ((NPCInfo->localState <= LSTATE_FIRED0) || (NPCInfo->localState == LSTATE_FIRED4))
00435 {
00436 NPCInfo->localState = LSTATE_FIRED1;
00437 bolt = trap_G2API_AddBolt(NPC->ghoul2, 0, "*flash1");
00438 }
00439 else if (NPCInfo->localState == LSTATE_FIRED1)
00440 {
00441 NPCInfo->localState = LSTATE_FIRED2;
00442 bolt = trap_G2API_AddBolt(NPC->ghoul2, 0, "*flash2");
00443 }
00444 else if (NPCInfo->localState == LSTATE_FIRED2)
00445 {
00446 NPCInfo->localState = LSTATE_FIRED3;
00447 bolt = trap_G2API_AddBolt(NPC->ghoul2, 0, "*flash3");
00448 }
00449 else
00450 {
00451 NPCInfo->localState = LSTATE_FIRED4;
00452 bolt = trap_G2API_AddBolt(NPC->ghoul2, 0, "*flash4");
00453 }
00454
00455 trap_G2API_GetBoltMatrix( NPC->ghoul2, 0,
00456 bolt,
00457 &boltMatrix, NPC->r.currentAngles, NPC->r.currentOrigin, level.time,
00458 NULL, NPC->modelScale );
00459
00460 BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, muzzle1 );
00461
00462 if (NPC->health)
00463 {
00464 CalcEntitySpot( NPC->enemy, SPOT_HEAD, enemy_org1 );
00465 VectorSubtract (enemy_org1, muzzle1, delta1);
00466 vectoangles ( delta1, angleToEnemy1 );
00467 AngleVectors (angleToEnemy1, forward, vright, up);
00468 }
00469 else
00470 {
00471 AngleVectors (NPC->r.currentAngles, forward, vright, up);
00472 }
00473
00474 G_PlayEffectID( G_EffectIndex("bryar/muzzle_flash"), muzzle1, forward );
00475
00476 G_Sound( NPC, CHAN_AUTO, G_SoundIndex("sound/chars/mark1/misc/mark1_fire"));
00477
00478 missile = CreateMissile( muzzle1, forward, 1600, 10000, NPC, qfalse );
00479
00480 missile->classname = "bryar_proj";
00481 missile->s.weapon = WP_BRYAR_PISTOL;
00482
00483 missile->damage = 1;
00484 missile->dflags = DAMAGE_DEATH_KNOCKBACK;
00485 missile->methodOfDeath = MOD_BRYAR_PISTOL;
00486 missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER;
00487
00488 }
00489
00490
00491
00492
00493
00494
00495 void Mark1_BlasterAttack(qboolean advance )
00496 {
00497 int chance;
00498
00499 if ( TIMER_Done( NPC, "attackDelay" ) )
00500 {
00501 chance = Q_irand( 1, 5);
00502
00503 NPCInfo->burstCount++;
00504
00505 if (NPCInfo->burstCount<3)
00506 {
00507 chance = 2;
00508 }
00509 else if (NPCInfo->burstCount>12)
00510 {
00511 NPCInfo->burstCount = 0;
00512 chance = 1;
00513 }
00514
00515
00516 if (chance == 1)
00517 {
00518 NPCInfo->burstCount = 0;
00519 TIMER_Set( NPC, "attackDelay", Q_irand( 1000, 3000) );
00520 NPC->client->ps.torsoTimer=0;
00521 }
00522 else
00523 {
00524 if (TIMER_Done( NPC, "attackDelay2" ))
00525 {
00526 TIMER_Set( NPC, "attackDelay2", Q_irand( 50, 50) );
00527 Mark1_FireBlaster();
00528 NPC_SetAnim( NPC, SETANIM_BOTH, BOTH_ATTACK1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
00529 }
00530 return;
00531 }
00532 }
00533 else if (advance)
00534 {
00535 if ( NPC->client->ps.torsoAnim == BOTH_ATTACK1 )
00536 {
00537 NPC->client->ps.torsoTimer=0;
00538 }
00539 Mark1_Hunt();
00540 }
00541 else
00542 {
00543 if ( NPC->client->ps.torsoAnim == BOTH_ATTACK1 )
00544 {
00545 NPC->client->ps.torsoTimer=0;
00546 }
00547 }
00548 }
00549
00550
00551
00552
00553
00554
00555 void Mark1_FireRocket(void)
00556 {
00557 mdxaBone_t boltMatrix;
00558 vec3_t muzzle1,enemy_org1,delta1,angleToEnemy1;
00559 static vec3_t forward, vright, up;
00560 int bolt = trap_G2API_AddBolt(NPC->ghoul2, 0, "*flash5");
00561 gentity_t *missile;
00562
00563 int damage = 50;
00564
00565 trap_G2API_GetBoltMatrix( NPC->ghoul2, 0,
00566 bolt,
00567 &boltMatrix, NPC->r.currentAngles, NPC->r.currentOrigin, level.time,
00568 NULL, NPC->modelScale );
00569
00570 BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, muzzle1 );
00571
00572
00573
00574 CalcEntitySpot( NPC->enemy, SPOT_HEAD, enemy_org1 );
00575 VectorSubtract (enemy_org1, muzzle1, delta1);
00576 vectoangles ( delta1, angleToEnemy1 );
00577 AngleVectors (angleToEnemy1, forward, vright, up);
00578
00579 G_Sound( NPC, CHAN_AUTO, G_SoundIndex("sound/chars/mark1/misc/mark1_fire" ));
00580
00581 missile = CreateMissile( muzzle1, forward, BOWCASTER_VELOCITY, 10000, NPC, qfalse );
00582
00583 missile->classname = "bowcaster_proj";
00584 missile->s.weapon = WP_BOWCASTER;
00585
00586 VectorSet( missile->r.maxs, BOWCASTER_SIZE, BOWCASTER_SIZE, BOWCASTER_SIZE );
00587 VectorScale( missile->r.maxs, -1, missile->r.mins );
00588
00589 missile->damage = damage;
00590 missile->dflags = DAMAGE_DEATH_KNOCKBACK;
00591 missile->methodOfDeath = MOD_ROCKET;
00592 missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER;
00593 missile->splashDamage = BOWCASTER_SPLASH_DAMAGE;
00594 missile->splashRadius = BOWCASTER_SPLASH_RADIUS;
00595
00596
00597 missile->bounceCount = 0;
00598
00599 }
00600
00601
00602
00603
00604
00605
00606 void Mark1_RocketAttack( qboolean advance )
00607 {
00608 if ( TIMER_Done( NPC, "attackDelay" ) )
00609 {
00610 TIMER_Set( NPC, "attackDelay", Q_irand( 1000, 3000) );
00611 NPC_SetAnim( NPC, SETANIM_TORSO, BOTH_ATTACK2, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
00612 Mark1_FireRocket();
00613 }
00614 else if (advance)
00615 {
00616 Mark1_Hunt();
00617 }
00618 }
00619
00620
00621
00622
00623
00624
00625 void Mark1_AttackDecision( void )
00626 {
00627 int blasterTest,rocketTest;
00628 float distance;
00629 distance_e distRate;
00630 qboolean visible;
00631 qboolean advance;
00632
00633
00634 if ( TIMER_Done(NPC,"patrolNoise") )
00635 {
00636 if (TIMER_Done(NPC,"angerNoise"))
00637 {
00638
00639 TIMER_Set( NPC, "patrolNoise", Q_irand( 4000, 10000 ) );
00640 }
00641 }
00642
00643
00644 if ((NPC->enemy->health<1) || ( NPC_CheckEnemyExt(qfalse) == qfalse ))
00645 {
00646 NPC->enemy = NULL;
00647 return;
00648 }
00649
00650
00651 distance = (int) DistanceHorizontalSquared( NPC->r.currentOrigin, NPC->enemy->r.currentOrigin );
00652 distRate = ( distance > MIN_MELEE_RANGE_SQR ) ? DIST_LONG : DIST_MELEE;
00653 visible = NPC_ClearLOS4( NPC->enemy );
00654 advance = (qboolean)(distance > MIN_DISTANCE_SQR);
00655
00656
00657 if ((!visible) || (!NPC_FaceEnemy(qtrue)))
00658 {
00659 Mark1_Hunt();
00660 return;
00661 }
00662
00663
00664 blasterTest = trap_G2API_GetSurfaceRenderStatus( NPC->ghoul2, 0, "l_arm" );
00665 rocketTest = trap_G2API_GetSurfaceRenderStatus( NPC->ghoul2, 0, "r_arm" );
00666
00667
00668 if (!blasterTest && !rocketTest)
00669 {
00670 ;
00671 }
00672 else if (blasterTest!=-1
00673 &&blasterTest)
00674 {
00675 distRate = DIST_LONG;
00676 }
00677 else if (rocketTest!=-1
00678 &&rocketTest)
00679 {
00680 distRate = DIST_MELEE;
00681 }
00682 else
00683 {
00684 NPC->health = 0;
00685 NPC->client->ps.stats[STAT_HEALTH] = 0;
00686
00687 if (NPC->die)
00688 {
00689 NPC->die(NPC, NPC, NPC, 100, MOD_UNKNOWN);
00690 }
00691 }
00692
00693
00694 NPC_FaceEnemy( qtrue );
00695
00696 if (distRate == DIST_MELEE)
00697 {
00698 Mark1_BlasterAttack(advance);
00699 }
00700 else if (distRate == DIST_LONG)
00701 {
00702 Mark1_RocketAttack(advance);
00703 }
00704 }
00705
00706
00707
00708
00709
00710
00711 void Mark1_Patrol( void )
00712 {
00713 if ( NPC_CheckPlayerTeamStealth() )
00714 {
00715 G_Sound( NPC, CHAN_AUTO, G_SoundIndex("sound/chars/mark1/misc/mark1_wakeup"));
00716 NPC_UpdateAngles( qtrue, qtrue );
00717 return;
00718 }
00719
00720
00721 if (!NPC->enemy)
00722 {
00723 if ( UpdateGoal() )
00724 {
00725 ucmd.buttons |= BUTTON_WALKING;
00726 NPC_MoveToGoal( qtrue );
00727 NPC_UpdateAngles( qtrue, qtrue );
00728 }
00729
00730
00731
00732
00733
00734
00735
00736
00737 }
00738
00739 }
00740
00741
00742
00743
00744
00745
00746
00747 void NPC_BSMark1_Default( void )
00748 {
00749
00750
00751 if ( NPC->enemy )
00752 {
00753 NPCInfo->goalEntity = NPC->enemy;
00754 Mark1_AttackDecision();
00755 }
00756 else if ( NPCInfo->scriptFlags & SCF_LOOK_FOR_ENEMIES )
00757 {
00758 Mark1_Patrol();
00759 }
00760 else
00761 {
00762 Mark1_Idle();
00763 }
00764 }